To calculate the age from a birthdate in Python, use this function:
from datetime import date def age(birthdate): today = date.today() age = today.year - birthdate.year - ((today.month, today.day) < (birthdate.month, birthdate.day)) return age
print(age(date(2000, 1, 1)))
If you have a hard time understanding how the code works, please read along.
The Problem with Leap Years
A year has ~365.25 days. But a calendar year is 365 days in length.
To even this out, every fourth year (except for years divisible by 100 and not by 400) is a leap year.
The uneven number of days in a year causes a problem when calculating ages.
- A person born on Jan 1st, 2000 turns 18 years old 6575 days later on Jan 1st, 2018 (with 5 leap years in between).
- A person born on Jan 1st, 2001 turns 18 only 6574 days later on Jan 1st, 2019 (with only 4 leap years in between).
So, if somebody is 6574 days old, you cannot tell if they are 17 or 18 without knowing more about the birthday’s month/day.
So calculating the age based on the number of days from the birthday is not sufficient.
The correct way to calculate age in Python is using
- Subtract the birth year from the current year.
- Subtract 1 if the current month/day comes before the birth month/day.
Here is the code (you already saw). This time I’ve added helpful refactoring and comments to support understanding:
# Use Python's built-in datetime module from datetime import date def age(birthdate): # Get today's date object today = date.today() # A bool that represents if today's day/month precedes the birth day/month one_or_zero = ((today.month, today.day) < (birthdate.month, birthdate.day)) # Calculate the difference in years from the date object's components year_difference = today.year - birthdate.year # The difference in years is not enough. # To get it right, subtract 1 or 0 based on if today precedes the # birthdate's month/day. # To do this, subtract the 'one_or_zero' boolean # from 'year_difference'. (This converts # True to 1 and False to 0 under the hood.) age = year_difference - one_or_zero return age # Example age check: print(age(date(2000, 1, 1)))
What About Leaplings?
A leapling is someone born on Feb 29st on a leap year.
As you saw, the code subtracts one from the year if today’s month/day precedes the birthday’s month/day.
It does this by comparing tuples of integers:
(today.month, today.day) < (birthday.month, birthday.day)
This works such that it compares the first elements (month numbers) first. If they are equal, it compares the second elements (day numbers).
Let’s run a simple example:
>>> (2, 5) < (2, 9) True >>> (3, 1) < (2, 29) False >>>
- In the first line, you can see how the comparison compares the days with same month number.
- In the second line, you can see how it uses the month number to determine that (29, 2) precedes (3, 1).
For leaplings, this means the birthday is assumed to be on Mar 1st on a non-leap year.
If today was Feb 28th, 2001, a baby born on Feb 29th, 2000 would be still considered 0 years old by our program.
Today you learned how to calculate age with Python’s
More importantly, you learned what is the issue with leap years and how to solve it.
Thanks for reading. Hope you like it.