Dates and Times
Dates look simple until you do arithmetic with them. How many days until the rent is due? What date is thirty days from today? Was this receipt from last month? Months have different lengths, and leap years add a day every four years, mostly. The datetime module does this arithmetic correctly, so you never have to count days on your fingers.
Think of a wall calendar that does its own counting. You point at two days and it tells you the gap, leap years and all. That is what datetime gives your programs.
Today
The date type from the datetime module represents a calendar date. date.today() gives today's date, which will of course be different when you run it. A date has a year, a month and a day, each available by name.
from datetime import date today = date.today() print(today) print(today.year, today.month, today.day)
2026-10-05 2026 10 5
From Text and Back
Dates in files and on the internet usually arrive as text in the ISO format, year, month and day separated by dashes, like the dates in your bank statement. date.fromisoformat turns that text into a date. Going the other way, strftime formats a date for people, using codes that start with a percent sign: %d is the day, %B the month's name and %Y the four-digit year.
from datetime import date paid = date.fromisoformat("2026-09-01") print(paid.strftime("%d %B %Y")) print(paid.strftime("%A"))
01 September 2026 Tuesday
The second line asks for %A, the name of the weekday. The first of September 2026 is a Tuesday, and Python knows without being told.
Differences in Days
Subtract one date from another and you get a timedelta: a length of time, rather than a point in time. Its days attribute is the number of whole days between the two. The rent below is due on the first of October; on the twenty-third of September there are eight days to go.
from datetime import date today = date(2026, 9, 23) rent_due = date(2026, 10, 1) gap = rent_due - today print(f"{gap.days} days until the rent is due")
8 days until the rent is due
Adding Time
To move a date forward, add a timedelta. Thirty days after the last day of January lands on the second of March in 2026, because February has twenty-eight days that year. The module handles that; you would have to remember it.
from datetime import date, timedelta start = date(2026, 1, 31) print(start + timedelta(days=30))
2026-03-02
Notice that timedelta works in days, weeks, hours and smaller units, but not months. That is deliberate. "One month after the thirty-first of January" has no single right answer, since February has no thirty-first, and the standard library refuses to guess. If a program needs month arithmetic, it has to decide what that means for itself.
Dates and Times Together
The datetime type, from the same module, holds a date and a time of day together, and datetime.now() gives the current moment. Times bring one more complication, time zones, which make "the same moment" read differently in different places. This book stops at the edge of that; it is a subject for later books.
- "Dates in a file are dates." They are text until parsed with date.fromisoformat.
- "A month is thirty days." Months vary, and timedelta deliberately has no months. Decide what month arithmetic should mean before you write it.
- "2026-9-1 and 2026-09-01 are the same to Python." fromisoformat expects the padded form, with two digits for the month and the day.
- Deadlines, reminders and "days since" logic appear in almost every useful script, and datetime gets them right.
- ISO dates sort correctly even as text, which is why files and web services use them.
Knowledge Check
What does subtracting one date from another give?
- A timedelta, whose days is the gap in days
- A new date, exactly halfway between the two dates
- A whole number, the gap measured in weeks
- An error, because dates cannot be subtracted
How do you turn the text "2026-09-01" into a date?
int("2026-09-01"), which reads the digitsdate("2026-09-01"), with the text passed indate.fromisoformat("2026-09-01")str("2026-09-01"), which converts it to a date
Why does timedelta have no months?
- Months were added to it as a new feature in Python 3.15
- Because a month is always exactly thirty days long, so it is not needed
- Because dates cannot be added to or moved at all
- A month's length varies, so "one month later" is ambiguous
What does date(2026, 1, 31) + timedelta(days=30) give?
- 2026-02-28, the last day of February
- 2026-03-01, exactly one month later
- 2026-03-02, thirty days on
- An error, because February has no 31st
You got correct