date, datetime and timedelta
16 min · Intermediate
Need help? Ask a tutor on WhatsApp (opens in a new tab)Invoices fall due, tickets expire and reports cover a month. Working these out with plain numbers goes wrong fast. The datetime module gives dates their own types and does the calendar maths for you.
date, time and datetime
datetime is a type from the datetime module that holds a date and a time of day together. Its parts are year, month, day, hour, minute, second and microsecond.
A date holds year, month and day. A time holds hours, minutes and seconds. A datetime holds both. All three are immutable, so a change always makes a new object.
from datetime import date, datetime
d = date(2026, 11, 8)stamp = datetime(2026, 11, 8, 9, 30)print(d.year, d.month, d.day)print(stamp.hour, stamp.minute)Example 1 · Build and read dates
from datetime import date, datetime
d = date(2026, 11, 8)stamp = datetime(2026, 11, 8, 9, 30, 15)print(d)print(stamp)print(stamp.date(), stamp.time())print(d.weekday(), d.isoweekday())2026-11-08 2026-11-08 09:30:15 2026-11-08 09:30:15 6 7
What this code does
printshows ISO style text: year, month, day.stamp.date()andstamp.time()split a datetime back into its two parts.weekday()counts from 0 for Monday, so Sunday is 6.isoweekday()counts from 1.
In examples and tests, write fixed dates such as date(2026, 11, 8). now() changes every run, so a test using it can pass today and fail tomorrow.
timedelta: a length of time
timedelta is a length of time, not a point in time. It adds to or subtracts from a date or datetime, and it is what you get when you subtract two dates.
A timedelta is a duration, such as 14 days or 36 hours. Add it to a date to move forward, subtract it to move back. Weeks, days, hours, minutes and seconds are all accepted.
from datetime import date, timedelta
due = date(2026, 11, 8) + timedelta(days=14)print(due)Example 2 · Add a timedelta
from datetime import date, datetime, timedelta
invoice = date(2026, 11, 8)print(invoice + timedelta(days=45))print(invoice - timedelta(weeks=2))print(timedelta(hours=36))print(datetime(2026, 11, 8, 22, 0) + timedelta(hours=5))2026-12-23 2026-10-25 1 day, 12:00:00 2026-11-09 03:00:00
What this code does
- 45 days after 8 November lands in late December.
- A
timedeltaof 36 hours is shown as 1 day and 12 hours. - A datetime crosses midnight into the next day on its own.
The calendar is handled for you: months of different lengths and leap years just work.
The gap between two dates
Subtract one date from another to get a timedelta. Its .days is whole days. For a datetime gap use total_seconds(), which counts the whole duration; .seconds holds only the part after the days.
from datetime import date
gap = date(2026, 3, 1) - date(2026, 1, 15)print(gap.days)Example 3 · Measure a gap
from datetime import date, datetime
start = datetime(2026, 11, 8, 9, 15)end = datetime(2026, 11, 8, 17, 45)worked = end - startprint(worked)print(worked.total_seconds() / 3600)print((date(2026, 12, 25) - date(2026, 11, 8)).days)8:30:00 8.5 47
What this code does
- Subtracting two datetimes gives a
timedeltaof 8:30:00. total_seconds()converts the whole gap to seconds, so dividing by 3600 gives hours.- For dates only,
.daysis enough.
Dates compare with <, == and >, so if today > due: reads naturally.
replace, weekday and month ends
replace returns a copy with some parts changed. weekday() gives 0 for Monday up to 6 for Sunday. To find the last day of a month, take the first day of the next month and subtract one day.
from datetime import date, timedelta
first_next = date(2026, 12, 1)print(first_next - timedelta(days=1))print(date(2026, 11, 8).replace(day=1))Example 4 · Month end and weekday names
from datetime import date, timedelta
NAMES = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]d = date(2028, 2, 10)last = date(2028, 3, 1) - timedelta(days=1)print(last, NAMES[last.weekday()])print(d.replace(day=1), d)2028-02-29 Tue 2028-02-01 2028-02-10
What this code does
- 2028 is a leap year, and subtracting one day from 1 March gives 29 February.
replacemade a new date; the originalddid not change.
This avoids a table of month lengths and handles leap years for free.
Next step
Check your understanding
11 quick questions