By Ether DataRequest data sample
All sections

The Temporal Interoperability Model

A timestamp with a zone is a request; the pipeline resolves it to a UTC instant, buckets it into a slot 0-167, and keys it to an ISO week before anything is measured or reported.

stable5 min read
Source time
timestamp, iana_zone
Destination time
hour_of_week_slot, week_slot_key

Every temporal fact this knowledge base handles enters as a local observation and leaves as a canonical coordinate. The path between those two states is fixed, ordered, and — this is the point of the KB — never skipped or collapsed. This page names the four stages and states why collapsing them produces silent, systematic errors rather than obviously broken output.

The four stages

01
Timestamp + zone (requested)
The raw input is a wall-clock reading — 2026-07-29 14:30 — paired with an IANA zone identifier, America/Chicago. Neither number nor string alone means anything; a wall time without a zone is not a moment in time, it is a pattern that could match any of roughly forty distinct instants depending on which zone resolves it.
02
Resolve to a UTC instant (DST-correct)
The (wall, zone) pair is resolved through the IANA time zone database to a single point on the UTC timeline — an epoch millisecond value. This step is where daylight saving time lives: most wall times resolve to exactly one instant, but twice a year a local clock either skips an hour (spring-forward gap, the wall time never occurs) or repeats one (fall-back fold, the wall time occurs twice). Both hazards are resolved by a declared policy, not a default — see Requested vs. executed time.
03
Hour-of-week slot 0–167
The UTC instant is bucketed into one of 168 hour-of-week slots, where slot 0 is Monday 00:00 UTC and the slot is a pure function of the instant: weekdayMon0 * 24 + hourUTC. This is the canonical unit of the whole KB — see The 168 axis. A slot alone repeats every week; it identifies a position in the cycle, not a moment.
04
(ISO week x slot) key
Pairing the repeating slot with an ISO 8601 week number produces a unique, sortable key — 2026-W29-S045 — that identifies exactly one hour, once, forever. This is the join key every downstream table, model feature, and report is built on.
05
Executed / reported grain
Only at the very last step does the canonical key get rolled up or annotated for a specific consumer: a broadcast day, a daypart label, a weekly aggregate for an MMM model. That rollup is a declared, requested operation — never a silent default — as covered in Resolution and grain.
The pipeline, stage by stage
01
Local timestamp + IANA zone
REQUESTED
02
Resolve to UTC instant
DST gap or fold: declared policy
03
Hour-of-week slot 0-167
instantToSlot(epochMs)
04
ISO week × slot key
2026-W29-S045 · weekSlotKey(epochMs)
05
Executed / reported grain
EXECUTED
Local time is a request; the UTC slot is the execution

This is the direct temporal analog of the geo KB's requested-vs-executed geography doctrine. A buyer asks for "8pm local in Chicago." The system executes a UTC instant. Those are two different facts about the same event, and the record should carry both rather than pretending the second derives losslessly from the first.

Why the stages must stay distinct

Collapsing stages 1 and 3 — treating a local hour as if it were the slot — breaks the moment a dataset spans more than one time zone, because "2pm" in New York and "2pm" in Los Angeles are three slots apart. Collapsing stages 3 and 4 — reporting a bare slot without its ISO week — breaks the moment a report spans more than one week, because slot 45 recurs 52 or 53 times a year and a bare slot cannot distinguish this Tuesday from next Tuesday. Collapsing stage 5 into stage 4 — silently rolling a time slot up to a day or week grain — breaks any consumer that asked for hourly delivery and received a coarser one without being told, which is why no-silent-temporal-rollup is one of the two edge cases this page flags explicitly.

Each stage also has its own, non-overlapping failure mode, which is the practical reason to keep them separate in code and in schema rather than fusing them into one "parse the timestamp" function: stage 2 fails on DST ambiguity, stage 3 fails on origin-convention mismatches (a Sunday-start week is off by 24 slots), and stage 4 fails on ISO week-year boundary bugs. A pipeline that fuses all three into one opaque conversion cannot report which stage produced a wrong answer.

Doctrine

Nate's doctrine from the geo side of this KB ports over unchanged: the free converter canonicalizes the key; everything indexed by it is the product. A single (ISO week x slot) key is cheap to compute and free to expose — the conversion in stages 1 through 4 above. What is valuable is everything built on top of that key once it is trustworthy: demand curves keyed by slot, causal tests that hold the slot fixed across markets, attribution windows measured in slots, and audience models trained on slot-indexed features. The KB gives away the coordinate system for free and monetizes the models that are indexed by it — exactly as the geo KB gives away H3 cell math and monetizes the audience layer built on H3.

Edge cases affecting this page

The UTC-canonical-vs-local-experience tension — that "primetime" is a local concept while the canonical unit is UTC — is the single most common source of misapplied comparisons across this pipeline, and is discussed in full in Measurement semantics. Tzdb-vintage mismatch affects stage 2 specifically: two systems on different IANA tz database releases can resolve the identical (wall, zone) pair to different UTC instants near a changed transition, so the tz database version belongs in the provenance record alongside the resolved instant, not just in a changelog somewhere.

Edge cases affecting this page

The 168 AxisConceptual modelRequested vs. Executed TimeConceptual modelTimestamp to SlotCanonical slot