Skip to content

Timezone

Canonicalizes one IANA time zone mention per call — a zone key (America/New_York), a legacy Link (US/Eastern, Canada/Eastern), a fixed zone (UTC, Etc/GMT+5, Etc/GMT-8), or a POSIX SystemV name (EST5EDT, gated) — to the case-exact IANA key.

In plain language: give it America/New_York, US/Eastern, america/new_york, or Etc/GMT+5 and it hands back the canonical IANA key (US/Eastern → America/New_York) per the vendored IANA Time Zone Database 2026d snapshot. Bare abbreviations (EST, IST, CST) are recognized but refused — never silently resolved — because one abbreviation names many zones and no timestamp is available to disambiguate.


What it recognizes — and what it does not

Section titled “What it recognizes — and what it does not”
RecognizesDoes not recognize
Canonical keys (America/New_York, case folds up: america/new_york, AMERICA/NEW_YORK)Unknown keys (America/Narnia) → MISSING (lexicon over the curated subset claims nothing unlisted)
Legacy Links (US/Eastern, Canada/Eastern, US/PACIFIC, Asia/Calcutta, Australia/ACT — resolve to canonical)Windows names (Eastern Standard Time, territory-sensitive CLDR mapping, deferred) → MISSING
Fixed zones (UTC, GMT, Etc/UTC, Etc/GMT, Etc/GMT+5, Etc/GMT-8 — sign kept as authored, never reinterpreted)Bare abbreviations, carved (EST, MST, HST, CET) → INVALID (refused, never resolved)
POSIX SystemV names (EST5EDT, CST6CDT, MST7MDT, PST8PDT — claimed for shape; INVALID unless include_systemv=True)Bare abbreviations, ambiguous (IST, CST, PST) → INVALID (refused, never a silent pick)
Embedded mentions (visit US/Eastern tomorrow — span covers the key only)Unlisted abbreviations and prose (XYZ, JST, hello world, Zulu) → MISSING
Glued runs and paths (XUS/Eastern, US/EasternX, /usr/share/zoneinfo/America/New_York) → MISSING (slash-aware boundary)

Abbreviation law: identifier equivalence is not lexical abbreviation equivalence. Short-caps backward Links (EST → America/Panama, MST → America/Phoenix, HST → Pacific/Honolulu, CET → Europe/Brussels) are carved out of the name lexicon into the abbreviation family, so the bare token reads as an abbreviation and refuses. The seeker writes the canonical key.


Default output_format is "iana" (identity — the canonical value IS the default format).

output_formatRendersExample
(default) iana / None / "default"Case-exact IANA zone keyAmerica/New_York

Any other value raises ContractError — including abbreviation and link, never offered per ADR-0011 (rendering an abbreviation is a lossy projection; choosing which alias to render is arbitrary policy, not canonicalization).

from paxman.capabilities import Timezone
import paxman
paxman.register_all_shipped()
print(paxman.canonicalize("America/New_York", Timezone.create_contract()).canonicalized_value)
print(paxman.canonicalize("US/Eastern", Timezone.create_contract()).canonicalized_value)
print(paxman.canonicalize("america/new_york", Timezone.create_contract()).canonicalized_value)
print(paxman.canonicalize("Asia/Calcutta", Timezone.create_contract()).canonicalized_value)
print(paxman.canonicalize("EST5EDT", Timezone.create_contract(include_systemv=True)).canonicalized_value)

contract = Timezone.create_contract(
output_format=None, # "iana" (default); None/"default"/"iana" all resolve to "iana"
include_systemv=False, # True admits the POSIX SystemV Zones (EST5EDT and kin)
# plus every common field: suppress_common_words / excluded_rules / pinned_rules / year / extra_grammars
)
  • Two grammars: timezone_name_recognition (case-folded lexicon over identifier keys, Links, fixed zones, SystemV names) and timezone_abbreviation_recognition (UPPER-exact lexicon over carved + ambiguous abbreviations, WORD guards).
  • Four rules: Section zone-key-membership, Section link-resolution, Section systemv-zones (gated on include_systemv via requires_features; dropped rule → INVALID), Section abbreviation-refusal (always refuses).
  • year filters by publication_year; e.g., year=2020 drops the tzdb-2026 rules → America/New_York becomes INVALID.
  • suppress_common_words is a no-op here: no Timezone matcher is suppressible.
  • Deterministic by construction: same input + contract + vendored 2026d snapshot → same output. No clock, no DST-transition evaluation, no environment tzdata — membership and Link resolution only.

InputContractStatusValue / why
America/New_YorkdefaultsSUCCESS"America/New_York"
america/new_yorkdefaultsSUCCESS"America/New_York" (fold restores canonical case)
US/EasterndefaultsSUCCESS"America/New_York" (Link resolution)
Canada/EasterndefaultsSUCCESS"America/Toronto" (Link resolution, Wave-2)
US/PACIFICdefaultsSUCCESS"America/Los_Angeles" (Link resolution, Wave-2)
Asia/CalcuttadefaultsSUCCESS"Asia/Kolkata" (Link resolution)
UTC / GMTdefaultsSUCCESS"UTC" / "GMT" (fixed zones; bare GMT admitted per #161)
Etc/GMT+5defaultsSUCCESS"Etc/GMT+5" (fixed zone; POSIX sign kept as authored, never flipped)
Etc/GMT-8defaultsSUCCESS"Etc/GMT-8" (fixed zone; POSIX sign kept as authored, Wave-2)
EST5EDTdefaultsINVALIDclaimed for shape, rule gated off
EST5EDTinclude_systemv=TrueSUCCESS"EST5EDT" (fixed-rule zone, valid key)
EST / MST / HST / CETanyINVALIDcarved Links read as abbreviations, refused
IST / CST / PSTanyINVALIDambiguous abbreviations, refused — never a silent pick
arrive CET tomorrowdefaultsINVALIDbare abbreviation refused everywhere
XYZ / JST / hello world / ZuluanyMISSINGnothing claimed (JST out of the v1 curated subset by design)
America/NarniaanyMISSINGunlisted key is unclaimable under the lexicon-over-subset design
Eastern Standard TimeanyMISSINGWindows namespace deferred entirely
XUS/Eastern / zoneinfo pathsanyMISSINGslash-aware boundary forbids mid-path extraction
US/Eastern then America/Chicagoanyraises MultipleMentionsErrortwo distinct zones fail fast (single_value=True)
EST then CETdefaultsINVALIDrefused mentions do not compete, so no MultipleMentionsError
America/New_Yorkyear=2020INVALIDrules are 2026, dropped
America/New_Yorkoutput_format="abbreviation"raises ContractErrorlossy projection, never offered

Notebook snippet — normalize a mixed column

Section titled “Notebook snippet — normalize a mixed column”
import paxman
from paxman.capabilities import Timezone
from paxman.core.domain import Resolution
from paxman.core.errors import ContractError
paxman.register_all_shipped()
contract = Timezone.create_contract()
rows = [
"America/New_York",
"US/Eastern",
"Canada/Eastern",
"US/PACIFIC",
"america/new_york",
"Asia/Calcutta",
"Etc/GMT+5",
"Etc/GMT-8",
"EST5EDT",
"EST",
"IST",
"XYZ",
"America/Narnia",
"Eastern Standard Time",
]
for text in rows:
r = paxman.canonicalize(text, contract)
val = r.canonicalized_value if r.status == Resolution.SUCCESS else "—"
rule = r.candidates[0].validation_rule if r.candidates else "—"
print(f"{text!r:28} → {r.status.value:10} {val!r:24} ({rule})")
print(paxman.canonicalize("EST5EDT", Timezone.create_contract(include_systemv=True)).canonicalized_value)
try:
Timezone.create_contract(output_format="abbreviation")
except ContractError as e:
print(f"abbreviation → ContractError: {e}")

  • IANA Time Zone Database 2026d (registry; zone-key membership, Link targets, SystemV Zones) — Section zone-key-membership (zone1970.tab col 3 + backward Links + etcetera, vendored File-Date), Section link-resolution (backward Link TARGET LINK-NAME lines, vendored File-Date 2026d), Section systemv-zones (backward SystemV Zones EST5EDT/CST6CDT/MST7MDT/PST8PDT, vendored File-Date 2026d)
  • IANA Time Zone Database 2026d via theory.html (registry; abbreviation ambiguity plus backward short-caps carve set) — Section abbreviation-refusal (theory.html abbreviation ambiguity: IST/CST/PST + backward short-caps Links carve set, vendored File-Date 2026d)

Each candidate’s validation_rule carries the section, and candidate.provenance[0].publication_year the year.

See also: UtcOffset, Execution Result, Provenance, Segmentation.