Datetime basics¶
Python's datetime module gives you four types to represent moments and durations: date, time, datetime, and timedelta. This notebook covers all four — how to build them, extract parts from them, do arithmetic with them, and compare them.
Everything here is naive — no time zones. Time zones come in the third notebook; the basics first.
date — a calendar date with no time¶
Just a year, month, and day. Useful when you don't care what time of day something happened.
from datetime import date
birthday = date(2026, 4, 21)
print(birthday)
print(date.today())
date(year, month, day) takes integers. date.today() returns today's date according to the system clock.
Dates expose their parts as attributes:
d = date(2026, 4, 21)
print(d.year, d.month, d.day)
print(d.weekday()) # Monday is 0, Sunday is 6
print(d.isoformat()) # canonical YYYY-MM-DD string
time — a clock time with no date¶
A time-of-day: hour, minute, second, microsecond. Far less commonly useful than date or datetime, but occasionally the right shape for "opening hours" or "daily alarm".
from datetime import time
t = time(14, 30, 0)
print(t, t.hour, t.minute)
datetime — a date and a time¶
The one you'll use most. A specific moment, precise to the microsecond.
from datetime import datetime
moment = datetime(2026, 4, 21, 14, 30, 0)
print(moment)
now = datetime.now()
print(now)
A datetime has everything a date has plus everything a time has — .year, .month, .day, .hour, .minute, .second, .microsecond. You can extract the calendar or clock portion separately:
print(moment.date()) # date(2026, 4, 21)
print(moment.time()) # time(14, 30)
timedelta — a duration¶
A span of time: days, seconds, microseconds (and for your convenience, hours, minutes, weeks on construction). This is what you get back when you subtract two datetimes, and what you add to shift a datetime by an interval.
from datetime import timedelta
one_week = timedelta(weeks=1)
ninety_minutes = timedelta(minutes=90)
print(one_week)
print(ninety_minutes)
print(one_week.total_seconds())
Arithmetic. A datetime plus a timedelta is a datetime:
start = datetime(2026, 4, 21, 9, 0)
print(start + timedelta(hours=8))
print(start + timedelta(days=7))
A datetime minus a datetime is a timedelta:
a = datetime(2026, 4, 21, 17, 30)
b = datetime(2026, 4, 21, 9, 0)
gap = a - b
print(gap)
print(gap.total_seconds(), "seconds")
Two things that don't work on timedelta:
- Months and years. A "month" isn't a fixed number of days.
timedelta(months=1)raises. For calendar-based arithmetic ("one month from today") reach fordateutil.relativedeltaor compute the target date directly. - Comparing a
timedeltawith a number.timedelta(hours=1) > 30raises. Compare to anothertimedeltaor use.total_seconds().
Comparing dates and datetimes¶
All the comparison operators work on same-type values:
d1 = date(2026, 4, 21)
d2 = date(2026, 5, 1)
print(d1 < d2)
print(d1 == date(2026, 4, 21))
dates = [date(2026, 1, 1), date(2025, 12, 31), date(2026, 4, 21)]
print(sorted(dates))
Mixing types won't work — date(2026, 4, 21) < datetime(2026, 4, 21, 0, 0) raises. Convert one to the other first, or compare dates against dates and datetimes against datetimes.
Exercise¶
Given a list of datetimes representing user login times across a week, write code that:
- Filters to the logins that happened on a Monday.
- Finds the time range between the earliest and latest login.
- Counts how many logins happened in the afternoon (13:00 onwards).
Use the logins list provided below.
from datetime import datetime
logins = [
datetime(2026, 4, 20, 9, 15), # Mon
datetime(2026, 4, 20, 14, 0), # Mon
datetime(2026, 4, 21, 8, 30), # Tue
datetime(2026, 4, 22, 16, 45), # Wed
datetime(2026, 4, 23, 11, 0), # Thu
datetime(2026, 4, 24, 10, 30), # Fri
datetime(2026, 4, 27, 15, 20), # Mon
]
# Your code here
Solution
# 1. Monday-only logins (weekday() == 0)
mondays = [dt for dt in logins if dt.weekday() == 0]
# 2. Range between earliest and latest
span = max(logins) - min(logins)
# 3. Afternoon logins (hour >= 13)
afternoon = sum(1 for dt in logins if dt.hour >= 13)
print(f"Mondays: {len(mondays)}")
print(f"Span: {span}")
print(f"Afternoon logins: {afternoon}")
Recap¶
datefor calendar dates,timefor clock times,datetimefor both.timedeltafor durations.datetime.now()anddate.today()give you the current moment.- Datetime arithmetic:
datetime + timedeltais a datetime;datetime - datetimeis a timedelta. timedeltadoesn't understand months or years — they're not fixed durations.- You can't mix
dateanddatetimein comparisons; convert first.
Next: Parsing and formatting, turning strings into datetimes and back.