Subtract today's date from the target date and you get the number of days left. The program also has to handle two other cases: the date is today, or the date has already passed.
The program
from datetime import date def countdown_message(event, target, today): days_left = (target - today).days if days_left > 1: return f"{event}: {days_left} days to go" if days_left == 1: return f"{event}: tomorrow!" if days_left == 0: return f"{event}: today!" return f"{event}: passed {-days_left} days ago" today = date(2026, 10, 22) # fixed so the output matches this page; use date.today() in real use events = [ ("New Year", date(2027, 1, 1)), ("Project deadline", date(2026, 10, 23)), ("Conference talk", date(2026, 10, 22)), ("Summer holiday", date(2026, 8, 3)), ] for event, target in events: print(countdown_message(event, target, today))
New Year: 71 days to go Project deadline: tomorrow! Conference talk: today! Summer holiday: passed 80 days ago
How it works
(target - today).daysis positive when the target is in the future, 0 when it is today, and negative when it has passed.- The checks go from the largest number down, so each case is handled once. "1 days to go" would read badly, so 1 gets its own message.
-days_leftturns a negative number such as-80into80for the "ago" message.todayis passed in as an argument instead of callingdate.today()inside the function. That makes the function easy to test with any date, as this page does.
Countdown to the next birthday
A birthday comes back every year. If this year's birthday has already passed, count to next year's:
from datetime import date def days_to_birthday(birth, today): next_birthday = birth.replace(year=today.year) if next_birthday < today: next_birthday = birth.replace(year=today.year + 1) return (next_birthday - today).days today = date(2026, 10, 22) # fixed so the output matches this page; use date.today() in real use for name, birth in [("Ada", date(1990, 12, 10)), ("Hedy", date(1985, 3, 1)), ("Linus", date(1992, 10, 22))]: print(f"{name}: {days_to_birthday(birth, today)} days")
Ada: 49 days Hedy: 130 days Linus: 0 days
birth.replace(year=...) keeps the month and day and changes the year. One case needs care: for a birthday on 29 February, replace() raises a ValueError in a year that is not a leap year. You can catch that and use 1 March (or 28 February) instead. The age calculator uses the same "has the birthday passed?" idea.