Age Calculator in Python
Intermediate · Useful tools · about 45 minutes to build · 100 lines
Type a date of birth and get the exact age in years, months and days on any date, with the weekday of birth and the next birthday.
The program
Press Run and answer its questions in the box that appears under the code.
Open it in the full editor to save it, share it and keep building.
Sample run
What the program printed, and what was typed (in yellow).
Age calculator Date of birth (DD-MM-YYYY): 16-06-2009 Age on which date? (DD-MM-YYYY, Enter for today): 22-10-2026 Age: 17 years, 4 months and 6 days That is 6,337 days (905 weeks and 2 days). Born on a Tuesday. Next birthday: 16-06-2027, a Wednesday, in 237 days (turning 18). Check another date? (y/n): y Date of birth (DD-MM-YYYY): 31-02-2010 Please type a real date like 16-06-2009. Date of birth (DD-MM-YYYY): 05/01/2001 Age on which date? (DD-MM-YYYY, Enter for today): 01-04-2026 Age: 25 years, 2 months and 27 days That is 9,217 days (1,316 weeks and 5 days). Born on a Friday. Next birthday: 05-01-2027, a Tuesday, in 279 days (turning 26). Check another date? (y/n): y Date of birth (DD-MM-YYYY): 01-01-2030 Age on which date? (DD-MM-YYYY, Enter for today): 01-04-2026 The date of birth must come before the other date. Check another date? (y/n): n Goodbye.
How it is built
1. Reading a date
datetime.strptime reads the text with the format %d-%m-%Y and raises ValueError for impossible dates such as 31-02-2010. Slashes and dots become dashes first, so 05/01/2001 works too.
def read_date(prompt, blank_is_today=False): """Ask for a date like 16-06-2009 (/ or . also work).""" while True: text = input(prompt).strip().replace("/", "-").replace(".", "-") if text == "" and blank_is_today: return date.today() try: return datetime.strptime(text, DATE_FORMAT).date() except ValueError: print(" Please type a real date like 16-06-2009.")
2. Adding months
Moving 31 January forward one month must land on the last day of February, so the day is capped with calendar.monthrange. This small function is the key to exact ages.
def add_months(day, months): """Move a date forward by whole months; 31 Jan + 1 month gives 28 or 29 Feb.""" total = day.month - 1 + months year, month = day.year + total // 12, total % 12 + 1 last_day = calendar.monthrange(year, month)[1] return date(year, month, min(day.day, last_day))
3. The exact age
Count the whole months between the dates, step back one if this month's birthday day has not come yet, then count the days left over. months // 12 and months % 12 split the months into years and months.
def exact_age(born, on): """Return the age as (years, months, days) on the date `on`.""" months = (on.year - born.year) * 12 + (on.month - born.month) if add_months(born, months) > on: months -= 1 # This month's "birthday day" has not come yet days = (on - add_months(born, months)).days return months // 12, months % 12, days
4. The next birthday
This year's birthday is used if it has not passed, otherwise next year's. Going through add_months means a 29 February birthday falls on 28 February in other years.
def next_birthday(born, on): """Return the date of the next birthday, counting `on` itself.""" years = on.year - born.year birthday = add_months(born, years * 12) if birthday < on: birthday = add_months(born, (years + 1) * 12) return birthday
5. Putting it together
Subtracting the dates gives the total days, and divmod(total_days, 7) splits them into weeks and days. strftime('%A') names the weekday.
def show_age(born, on): """Print the exact age and some facts about the dates.""" if born == on: print(" That is the day of birth itself: 0 days old.") return years, months, days = exact_age(born, on) print(f" Age: {plural(years, 'year')}, {plural(months, 'month')} " f"and {plural(days, 'day')}") total_days = (on - born).days weeks, extra_days = divmod(total_days, 7) print(f" That is {plural(total_days, 'day')} " f"({plural(weeks, 'week')} and {plural(extra_days, 'day')}).") print(f" Born on a {born.strftime('%A')}.") birthday = next_birthday(born, on) turning = birthday.year - born.year if birthday == on: print(f" Happy birthday. Turning {turning} today.") else: wait = plural((birthday - on).days, "day") print(f" Next birthday: {birthday.strftime(DATE_FORMAT)}, " f"a {birthday.strftime('%A')}, in {wait} (turning {turning}).")
Make it bigger
- Compare two dates of birth and say who is older and by how much.
- Count down the hours and minutes to the next birthday with
datetime.now(). - Read a list of names and birthdays and print them in birthday order.
- Accept dates written as words, like
5 January 2001, with a second format.
What it practises
- datetime and strptime
- calendar.monthrange
- integer division and remainder
- divmod
- functions