Topic 03

Dates and Times

Hands-on

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.

today.py
from datetime import date

today = date.today()
print(today)
print(today.year, today.month, today.day)
One possible output
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.

parse.py
from datetime import date

paid = date.fromisoformat("2026-09-01")
print(paid.strftime("%d %B %Y"))
print(paid.strftime("%A"))
Output
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.

rent.py
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")
Output
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.

later.py
from datetime import date, timedelta

start = date(2026, 1, 31)
print(start + timedelta(days=30))
Output
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.

From text to arithmetic and back
Text"2026-09-01"
→
A datedate(2026, 9, 1)
→
Arithmetic+ timedelta(days=30)
→
Text again"01 October 2026"
Common Confusions
  • "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.
Why It Matters
  • 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 digits
  • date("2026-09-01"), with the text passed in
  • date.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