Python Tutorial / Work with Dates, Times and Time Zones
Use date for a calendar day and datetime with zoneinfo when an instant and time zone matter. Distinguish time-zone-aware values from naive ones, and define storage and display conventions explicitly.
Separate dates, durations and instants
date represents a calendar date, datetime combines a date and time, and timedelta represents a duration. A naive datetime has no time-zone information; an aware datetime includes it. A displayed 09:00 in Seoul can represent a different instant from 09:00 UTC.
Parse ISO-style date input with fromisoformat and handle invalid dates as ValueError. Adding 30 days does not mean advancing one calendar month, so month-end behavior requires a separate policy.
For the relevant APIs and platform requirements, see Work with Dates, Times and Time Zones documentation.
Convert a UTC instant to Seoul time
Save the complete code below as dates.py in a separate practice folder, using UTF-8. Run python dates.py in a terminal with your project virtual environment selected. Outside a virtual environment on macOS or Ubuntu, use python3 when that is your interpreter command.
from datetime import date, datetime, timedelta, timezone
from zoneinfo import ZoneInfo
day = date.fromisoformat("2026-10-17")
print(day + timedelta(days=7))
utc = datetime(2026, 10, 17, 0, 0, tzinfo=timezone.utc)
seoul = utc.astimezone(ZoneInfo("Asia/Seoul"))
print(utc.isoformat())
print(seoul.isoformat())
Expected output:
2026-10-24 2026-10-17T00:00:00+00:00 2026-10-17T09:00:00+09:00
Prepare zone data and convert correctly
astimezone changes the representation while preserving the instant. replace(tzinfo=...) keeps the clock fields and assigns a time-zone interpretation; it is not a general substitute for conversion. Without knowing the source time zone, an accurate conversion may be impossible.
zoneinfo uses IANA time-zone data. If a system without that data raises ZoneInfoNotFoundError, install the tzdata package in the project environment with python -m pip install tzdata. Time-zone rules can change, so deployed data also requires maintenance.
Choose a storage rule and test date boundaries
For transaction instants, consider a consistent UTC or offset-aware representation and convert for display. When only the expense’s calendar day matters, storing a date can be clearer than inventing a midnight timestamp.
- Change the UTC hour to 23 and verify that Seoul displays the following date.
- Try parsing 2026-02-30 and verify that it is rejected.
- Compare a naive and aware datetime and explain why subtraction can fail.
Keep the distinction between a business date and an absolute instant visible throughout input, storage and reporting.




