tzdata
named time zones (IANA)
use tzdataThe IANA tzdata base that plugs into the core’s
time.Zone.timecarries on withUtc/Local/Offset(mechanism, tier 0); this is the layer of names ("America/Sao_Paulo") on top: mutable data (the base changes with the countries’ policy), loaded on demand, weighing only on whoever imports it. Tier 1; it is the canonical example of the mechanism-vs-data split (§1).
fn named(name: string) -> Result[Zone, error{UnknownZone}] // "America/Sao_Paulo" to time.Zonefn (z: Zone) offset_at(t: DateTime) -> i32 // offset (min) AT THAT instant (resolves DST)fn (z: Zone) abbreviation_at(t: DateTime) -> string // "-03" / "BRST"fn (t: DateTime) in_zone(name: string) -> Result[DateTime, error{UnknownZone}] // converts to the named zonefn list_zones() -> Iterator[string] // all available namesfn version() -> string // version of the embedded tzdata base ("2026a")use tzdata
sp := tzdata.named("America/Sao_Paulo") catch |e| { return e }agora_sp := time.now_utc().to_zone(sp) // uses the time.Zone resolved by the baseCuration
Section titled “Curation”- Plugs into the existing
time.Zone: it is not a parallel clock; it is the resolution of name to offset (with DST). The coretimedoes not change. - Loaded on demand: the base is large and churns (annual tzdata releases); it only enters the binary of whoever
does
use tzdata. The common case (UTC/offset) never pays. - Offset is resolved at the instant (
offset_at) because DST makes a zone’s offset vary over time: there is no “the offset of São Paulo”, there is the offset on a date.