datetime
Five value types do the work: date, time, datetime, timedelta and timezone. The traps are naive vs aware datetimes, the formatting directives, and timedelta.seconds not meaning what it says.
import datetime from datetime import date, time, datetime, timedelta, timezone, UTC
Demo
from datetime import datetime, timedelta start = datetime.fromisoformat('2026-09-29T14:30') (start + timedelta(days=30, hours=12)).isoformat()
All three tabs start from fromisoformat, the reliable way to get a datetime from text. Adding a timedelta keeps the UTC offset you started with (+01:00 stays +01:00 — a fixed offset never changes for daylight saving), a negative difference prints as "-271 days, 0:00:00" rather than "-271 days", and %z only has something to print when the datetime carries an offset.
Members
Common patterns
from datetime import datetime, UTC now = datetime.now(UTC) stamp = now.isoformat() # 2026-09-29T12:00:00.123456+00:00
from datetime import datetime, timedelta due = datetime.fromisoformat('2026-09-29T09:00') + timedelta(days=14) print(due.strftime('%d %b %Y'))
from datetime import date age_days = (date.today() - created_on).days
from datetime import datetime, timedelta, timezone ist = timezone(timedelta(hours=5, minutes=30)) local = utc_dt.astimezone(ist)
Examples
Pitfalls
import datetime datetime.fromisoformat("2026-09-29")
import datetime datetime.datetime.fromisoformat("2026-09-29")
from datetime import datetime, UTC datetime(2026, 9, 29) < datetime.now(UTC)
from datetime import datetime, UTC datetime(2026, 9, 29, tzinfo=UTC) < datetime(2026, 9, 30, tzinfo=UTC)
from datetime import timedelta timedelta(days=2, hours=1).seconds
from datetime import timedelta timedelta(days=2, hours=1).total_seconds()
When to use
- Calendar dates, timestamps and durations in application code
- Parsing and producing ISO 8601 text (APIs, logs, JSON)
- Date arithmetic: deadlines, ages, "N days from now", differences
- Named time zones with daylight saving rules → zoneinfo (3.9+)
- Monotonic timing of code → time.perf_counter()
- Calendars and month-length tables → the calendar module
- Adding months or years → there is no timedelta(months=…); use replace() or a third-party library
Notes
FAQ
import datetime binds the module, so the class is datetime.datetime and the date class is datetime.date. from datetime import datetime binds the class itself under the same name — after that, datetime.date is the method that extracts the date part, not the date class. Pick one style per file.