Subtracting the birth year from this year is not enough. If the birthday has not come yet this year, the person is one year younger. The program checks that.
The program
python
from datetime import date def age_in_years(birth, today): years = today.year - birth.year birthday_not_reached = (today.month, today.day) < (birth.month, birth.day) if birthday_not_reached: years -= 1 return years today = date(2026, 10, 22) # fixed so the output matches this page; use date.today() in real use people = { "Ada": date(1990, 3, 15), "Linus": date(1990, 12, 1), "Grace": date(2004, 10, 22), "Alan": date(2008, 2, 29), } for name, birth in people.items(): print(f"{name:<6} born {birth}: {age_in_years(birth, today)} years old")
output
Ada born 1990-03-15: 36 years old Linus born 1990-12-01: 35 years old Grace born 2004-10-22: 22 years old Alan born 2008-02-29: 18 years old
How it works
today.year - birth.yeargives 36 for both Ada and Linus. Ada's birthday (15 March) has passed this year. Linus's birthday (1 December) has not, so he is still 35.(today.month, today.day) < (birth.month, birth.day)compares two tuples. Python compares the months first, and the days only if the months are equal. So(10, 22) < (12, 1)isTrue.- Grace's birthday is today.
(10, 22) < (10, 22)isFalse, so her new age counts from today. - Alan was born on 29 February. The tuple comparison needs no special rule: in years without 29 February, his age goes up on 1 March.
Years, months and days
For an exact age such as "36 years, 7 months and 7 days", count the whole months first. Then count the days since the last month anniversary:
python
import calendar from datetime import date def add_months(start, months): month_index = start.month - 1 + months year = start.year + month_index // 12 month = month_index % 12 + 1 last_day = calendar.monthrange(year, month)[1] return date(year, month, min(start.day, last_day)) def exact_age(birth, today): months = (today.year - birth.year) * 12 + today.month - birth.month if today.day < birth.day: months -= 1 days = (today - add_months(birth, months)).days years, months = divmod(months, 12) return years, months, days today = date(2026, 10, 22) # fixed so the output matches this page; use date.today() in real use birth = date(1990, 3, 15) years, months, days = exact_age(birth, today) print(f"{years} years, {months} months and {days} days") print(f"That is {(today - birth).days:,} days in total.")
output
36 years, 7 months and 7 days That is 13,370 days in total.
add_months()moves a date forward by whole months.min(start.day, last_day)handles short months: one month after 31 January is 28 February (or 29 in a leap year), not an error.divmod(months, 12)splits the total months into years and the months left over.today - birthgives atimedelta, and.daysis the total number of days between the two dates. The days between dates program shows more of this.