Dates and times
A value for a day: today, thirty days from now, and the two ways to write a date — for people and for machines.
A module for time
Dates are a kind of value Python keeps in the standard library. from datetime import date brings the type in, and date.today() gives today as a date object — not text, but a value you can compare and do arithmetic with.
That difference matters. Text like "2026-10-07" cannot be added to anything; a date can be given thirty days, subtracted from another date, and printed in whichever format the reader needs.
Today, and thirty days later
from datetime import date, timedelta
today = date.today()
print(today)
print(today + timedelta(days=30))
print(today.strftime("%A, %d %B %Y"))Two ways to write a date
The plain print shows the ISO format: 2026-10-07. Year first, then month, then day — the one ordering that sorts correctly as text, and the one machines and databases expect.
strftime writes a date for a person, using letters that stand for its parts: %A is the weekday name, %d the day of the month, %B the month name. "%A, %d %B %Y" becomes "Wednesday, 07 October 2026".
Counting days
Subtract one date from another and you get a timedelta — a length of time, with .days for the whole days it contains. It is the answer to questions a program is asked constantly: how long since the last order, how many days until the deadline.
timedelta(days=30) works the other way round: add it to a date and you have the date thirty days later, with the month lengths and leap years handled for you.
Today, in words and in thirty days
Print today in words — the weekday, the day and the month — and then print the date exactly thirty days from now.
A date and a moment are different
date holds a day; datetime holds a day and a time; timedelta holds a length. Mixing them is a common source of TypeError, because a day cannot be compared with a moment without deciding which part of the day is meant. Pick the type that matches the question and stay with it.
A due date is a date. A log entry is a datetime. A reminder that fires at 09:00 needs a time as well, and the code that stores it should say so rather than appending a time to text.
Time zones are a separate problem
A naive datetime has no zone, so it means whatever the reader assumes. Two machines in different places can disagree about when it happened. Python keeps zone-aware values in the same module, and the rule is to convert at the edge — when reading input or showing output — and keep one consistent zone inside.
For a course program, a fixed date with no zone is fine. For anything that records when something happened, store UTC and convert for display; the arithmetic then stays correct across daylight-saving changes, which are exactly the days a hand-rolled offset gets wrong.
Store and compare dates in ISO form; change to words only when printing. A date written as "07/10/2026" is ambiguous across countries, and that ambiguity reaches production more often than anyone expects.
A date is a value, not a label
date(2026, 10, 7) builds a date from three numbers, and date.fromisoformat("2026-10-07") reads one from text. Once built, dates compare with < and > and subtract from each other, which text cannot do reliably.
Adding a timedelta gives a new date and leaves the old one alone, the same way adding a number to an integer gives a new integer. That is why deadline = start + timedelta(days=30) needs the result stored: the original start does not move.
Dates compare directly because they are values of the same kind: start < deadline is true or false without converting either to text. That makes a due-date check a comparison, not a string exercise.
Formatting and parsing are opposites
strftime turns a date into text; datetime.strptime, from the same module, turns text into a datetime. They take the same percent letters, and confusing them is a common afternoon.
Parsing needs the text to match the pattern exactly, including separators. datetime.strptime("07/10/2026", "%d/%m/%Y") reads day first; the same text with %m/%d/%Y reads July 10. The pattern is the only thing that decides.
Three date mistakes: ordering a date against text raises TypeError; strftime writes a date out while datetime.strptime reads text in, and they are easy to swap; and a date built from numbers is unambiguous, while "07/10/2026" means different days in different countries.
Try these next
- Build
date(2026, 1, 1)and print it in ISO form and in words. - Subtract two dates and print
.days; then add the same number of days back to the earlier one. - Parse
"2026-12-25"withfromisoformatand print the weekday with%A.
Days until the deadline
Two fixed dates are ready. Print how many days lie between them and the deadline in words. Then add 30 days to the deadline and print the new date. Do not use today’s date — the answer should be the same on every run.
Check what you learned
One question at a time. A wrong answer explains itself — take another go.
Part 1 of 5
What is a timedelta?
