Registry / serialization / pytz
library2026.3.post1pypypi✓ verified 27d ago

pytz brings the IANA/Olson timezone database into Python, enabling accurate cross-platform timezone calculations and daylight-saving-time-aware datetime handling. Current version is 2026.1.post1, released March 2026; versions track IANA tz database releases (typically several times per year). The pytz maintainer explicitly states that projects on Python 3.9+ should prefer the stdlib zoneinfo module (PEP 615) with the tzdata package instead — pytz is now in maintenance mode for backwards compatibility only.

pip install pytz
INSTALL
IMPORT
SIG · PYTZ
P
pytz
serializationpythonv2026.3.post1
Install
1.8s avg
Import
10ms
Disk
43MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v2026.3.post1 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.910 runs
installs and imports cleanly · install 0.0s · import 0.010s · 68.7MB
glibc
py 3.103.910 runs
installs and imports cleanly · install 1.8s · import 0.010s · 21MB
43MB installed
● package 43MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

timezone
from pytz import timezone
Returns a pytz tzinfo object; must be used with .localize() — NOT with datetime(..., tzinfo=tz)
utc / UTC
import pytz; tz = pytz.utc
pytz.utc, pytz.UTC, and pytz.timezone('UTC') are all the same singleton; 'GMT' is a different object and will not compare equal
all_timezones / common_timezones
from pytz import all_timezones, common_timezones
all_timezones is the exhaustive IANA list; common_timezones omits deprecated/historical zones
UnknownTimeZoneError
from pytz.exceptions import UnknownTimeZoneError
Raised by timezone() for unrecognised IANA keys; also importable directly as pytz.exceptions.UnknownTimeZoneError

Canonical pytz usage: always store in UTC, convert to local only for display. Use localize() to attach a tz to a naive datetime; use normalize() after any arithmetic on a local datetime to fix DST offsets.

from datetime import datetime, timedelta import pytz # --- Correct: build a UTC-aware datetime --- utc = pytz.utc utc_dt = datetime(2024, 3, 10, 7, 0, 0, tzinfo=utc) print("UTC:", utc_dt) # --- Correct: convert UTC -> local via astimezone --- eastern = pytz.timezone('US/Eastern') loc_dt = utc_dt.astimezone(eastern) print("Eastern:", loc_dt.strftime('%Y-%m-%d %H:%M:%S %Z%z')) # --- Correct: localize a naive datetime --- naive = datetime(2024, 11, 3, 1, 30) # ambiguous wall-clock time aware = eastern.localize(naive, is_dst=True) # explicitly choose EDT side print("Localized (EDT):", aware) # --- Correct: arithmetic on local times MUST be followed by normalize --- before_dst_end = eastern.localize(datetime(2024, 11, 3, 1, 50)) result = eastern.normalize(before_dst_end + timedelta(minutes=20)) print("After normalize:", result.strftime('%Y-%m-%d %H:%M:%S %Z%z')) # --- WRONG (do not do this) --- # wrong = datetime(2024, 11, 3, 1, 30, tzinfo=eastern) # returns LMT, not EST/EDT! # --- Preferred modern alternative (Python 3.9+) --- # from zoneinfo import ZoneInfo # aware_modern = datetime(2024, 11, 3, 1, 30, tzinfo=ZoneInfo('US/Eastern'))
Debug
Known issues
breakingDo NOT pass a pytz timezone directly to the datetime constructor via tzinfo=. For non-UTC zones this silently attaches the zone's historical LMT (Local Mean Time) offset, not the correct current offset, producing wrong results with a 50% chance of being off by an hour around DST transitions.
fix
Always use tz.localize(naive_dt) to attach a pytz timezone to a naive datetime. Only pytz.utc is safe to pass directly to the constructor.
affects: all
breakingAfter any timedelta arithmetic on a pytz-aware local datetime, the UTC offset can become stale if the operation crossed a DST boundary. The offset is not automatically recalculated.
fix
Wrap every arithmetic result with tz.normalize(result) to correct the offset. Or work exclusively in UTC and convert only for display.
affects: all
deprecatedThe pytz maintainer and PyPI page explicitly state that projects on Python 3.9+ should use stdlib zoneinfo (PEP 615) + tzdata instead. pytz receives no new features; only IANA DB updates are applied.
fix
New code: use 'from zoneinfo import ZoneInfo' with 'pip install tzdata'. For gradual migration use the pytz-deprecation-shim package.
affects: all (Python 3.9+)
gotchapytz.utc / pytz.UTC is NOT the same object as pytz.timezone('GMT'), pytz.timezone('Greenwich'), or datetime.timezone.utc. Identity/equality checks between these will return False.
fix
Standardise on pytz.utc throughout pytz code, or use datetime.timezone.utc when mixing with stdlib. Never assume UTC aliases are interchangeable.
affects: all
gotchalocalize() raises ValueError if the datetime already has tzinfo set. Calling localize() on an already-aware datetime is a common mistake when re-processing data.
fix
Check dt.tzinfo is None before calling localize(). For already-aware datetimes use astimezone() to convert zones.
affects: all
gotchaDST disambiguation via is_dst=None raises pytz.exceptions.AmbiguousTimeError or NonExistentTimeError instead of silently picking one, but only if you opt in. The default (is_dst=False) silently chooses standard time, which may surprise callers.
fix
Pass is_dst=None to localize() in production scheduling code so ambiguous or non-existent wall-clock times raise an exception rather than silently producing a wrong result.
affects: all
gotchapytz timezone objects are not compatible with the standard Python tzinfo interface expected by PEP 495 consumers (fold attribute). Passing pytz zones to libraries expecting stdlib-compatible tzinfo (e.g. Django 4.0+ defaults, zoneinfo consumers) can produce incorrect offsets.
fix
When interfacing with PEP 495-aware code, convert: use zoneinfo.ZoneInfo(str(pytz_zone)) to obtain an equivalent stdlib zone object.
affects: all
Upgrade
Version history
2026.3.post1latest on PyPI · released Jul 25, 2026
Audit
Dependencies

No dependency data recorded yet.

Agent activity
22 hits · last 30 days
node
16
Meta
1
Resources
pytz — pip install pytz · libregistry