008. Versioned Time-Zone Profiles

  • Status: Accepted
  • Author: @ornew
  • Date: 2026-10-11

Summary

Named time zones use caller-supplied, versioned TZif data captured when a local filter is built. UTC and fixed offsets remain available without zone data. Matching uses the filter's immutable snapshot and never discovers zone files from the machine or reads environment settings.

Motivation

Timestamp component extraction and rendering must be deterministic across machines and over time. Calling time.LoadLocation during matching can make results depend on whichever files happen to be installed and may perform filesystem access. Capturing the versioned data during Build lets the application choose the data release and keeps Match pure and reusable.

Goals

  • Resolve UTC and fixed offsets without an external time-zone database.
  • Let the application supply exactly the named-zone data and aliases it needs.
  • Copy and parse profile data at Build so filter behavior is immutable.
  • Expose the chosen data version for compatibility discovery.
  • Keep named-zone matching independent of OS files and environment settings.

Design

Public behavior and contracts

local.TimeZoneProfile contains a nonempty version label, a map from zone names to TZif byte slices, and an optional alias map. local.WithTimeZones and local.Config.TimeZones provide the profile to local.Build. Build copies the TZif bytes and parses them into private locations; mutation of the caller's maps or buffers after Build does not change the filter. Filter.TimeZoneVersion returns the supplied version label, or an empty string when the filter uses only built-in zones.

UTC and fixed offsets from -23:59 through +23:59 are always available and cannot be overridden. Named zones must exist in the supplied profile. An alias must point directly to one of the profile's zone keys or to UTC; aliases cannot form chains. Invalid, empty-version, conflicting, or unresolved profiles are configuration errors. A valid query name that is absent from the profile yields null at runtime. Profile version labels identify the data selected by the application; HFF does not infer or verify the publisher's release name.

Timestamp component methods use UTC when their optional zone argument is omitted. The timestamp string method requires an explicit zone. If the selected zone's historical offset has seconds, or formatting would leave the supported RFC 3339 year/offset range, formatting returns null rather than lose information.

Implementation and invariants

The profile is validated and snapshotted during Build. Each zone's TZif bytes are copied before parsing. Aliases resolve only against original zone entries or UTC, preventing order-dependent alias chains. Match resolves names only in the immutable snapshot plus the built-in UTC/fixed-offset paths. It performs no zone-file discovery or environment lookup.

Compatibility and backend support

The time-zone profile is a local-backend configuration contract. A different backend must report its own supported zone data and cannot claim equivalent results unless it uses a compatible version and name mapping. The version label and supported aliases are part of an engine's portability profile.

Testing

Tests verify copied ownership, profile version reporting, direct aliases, reserved names, invalid TZif and alias targets, unknown-name null behavior, concurrent reuse, and stable results from a hand-built TZif fixture without reading host zone data.

Alternatives considered

Load named zones from the operating system during Match

This needs no service configuration, but makes results depend on machine state and may perform I/O during evaluation. It is not selected.

Capture the operating system's time-zone database during Build

Capturing system data once avoids per-match lookup but still makes the chosen version implicit and complicates reproducing results. The caller-supplied profile makes the version and input data explicit.

Bundle one time-zone database in HFF

A bundled database makes defaults convenient but increases binary size and forces the library to choose when services receive data updates. Services instead select a versioned profile appropriate to their deployment.

Limitations and open questions

The application supplies and labels the profile data; HFF validates its TZif structure but does not attest to its provenance. Backends other than the local evaluator must define their own profile and execution contracts.

Explore HFF
Search documentation

Search the language specification and guides.