Any user-facing time, schedule or report must follow real time zone rules, including DST changes.
Real places don't have fixed offsets: Berlin is UTC+1 in winter and UTC+2 in summer, and the rules change by law. The zoneinfo module (3.9+) provides ZoneInfo, a tzinfo backed by the IANA time zone database:
from zoneinfo import ZoneInfo
berlin = ZoneInfo("Europe/Berlin")Use IANA names ("America/New_York", "Asia/Kolkata"), never abbreviations like "EST" or "CET", which are ambiguous and ignore DST.
datetime(2025, 7, 1, 9, tzinfo=berlin)means 9:00 local time in Berlin on that date; itsutcoffset()is+2:00in July and+1:00in January.dt.astimezone(ZoneInfo("Asia/Tokyo"))shows the same instant in another zone.zoneinfo.available_timezones()lists all known names.
Where the data comes from: on Linux and macOS, the system's tz database; on Windows (or slim containers) there is none, so install the tzdata package from PyPI, which zoneinfo uses automatically as a fallback. Missing data raises ZoneInfoNotFoundError.
ZoneInfo objects are cached: ZoneInfo("UTC") is ZoneInfo("UTC"). Prefer the stdlib zoneinfo over the older third-party pytz, whose localize() API is easy to misuse.
Example
from datetime import UTC, datetime
from zoneinfo import ZoneInfo
berlin = ZoneInfo("Europe/Berlin")
winter = datetime(2025, 1, 15, 9, 0, tzinfo=berlin)
summer = datetime(2025, 7, 15, 9, 0, tzinfo=berlin)
print(winter.utcoffset(), summer.utcoffset()) # 1:00:00 2:00:00
print(summer.tzname()) # CEST
meeting = datetime(2025, 7, 15, 15, 0, tzinfo=UTC)
for zone in ["America/New_York", "Asia/Kolkata", "Australia/Sydney"]:
local = meeting.astimezone(ZoneInfo(zone))
print(f"{zone:18} {local:%a %H:%M %Z}")
# America/New_York Tue 11:00 EDT
# Asia/Kolkata Tue 20:30 IST
# Australia/Sydney Wed 01:00 AEST
print(ZoneInfo("Europe/Berlin") is berlin) # TrueRemember
ZoneInfo('Area/City')gives real zones with DST rules- Use IANA names, never abbreviations like EST
- Install
tzdatawhere the OS has no time zone database (Windows, slim images)
Watch out for
- Using a fixed
timezone(timedelta(hours=1))for a real place that observes DST.