By Ether DataRequest data sample
All sections

Cycle vs Interval

An hour-of-week slot is a position in a repeating weekly cycle; a UTC window is a concrete dated interval. They look interchangeable and are not — every conversion result declares which one it is via temporal_kind.

stable3 min read
Source time
hour_of_week_slot, daypart
Destination time
utc_window, instant, iso_week

Two temporal objects in this KB look alike and behave completely differently. An hour-of-week slot (0–167) is a position in a repeating weekly cycle: slot 45 is "Tuesday 21:00 UTC" in every week, forever. A UTC window like [2026-11-01T05:00Z, 06:00Z) is a concrete interval: it happens once. Confusing the two is the temporal version of mixing a cell system with a cell id — the values type-check as numbers and strings, so nothing complains until a set operation quietly returns the wrong answer.

Every conversion result in this KB therefore carries a temporal_kind discriminator: cycle or interval.

The two kinds

cycle
A position in the repeating weekly cycle: an hour-of-week slot (0–167) or a daypart. Recurs every week; has no year. Answers 'when in a typical week.'
interval
A concrete dated span or instant: a UTC window, an epoch instant, an ISO (year × week) coordinate. Happens once. Answers 'which actual hour in history.'

A cycle value is incomplete on its own the way an H3 resolution is incomplete without a cell id: "slot 45" is not a moment until you pair it with an ISO week. An interval value is fully grounded — it names a specific hour that already has (or will have) happened.

Why the distinction is load-bearing

The two kinds support different operations, and mixing them silently corrupts the result:

  • Set algebra only closes within one kind. You can intersect or subtract two intervals (concrete UTC spans) exactly. You can intersect two cycles (slot-sets) exactly. You cannot subtract a cycle from an interval without first binding the cycle to a specific week — the temporal analog of the geo rule that set operations must stay inside one cell system.
  • Binding is where DST enters. Turning a cycle into an interval — "slot 2 of this week, in this zone" — is exactly where a 23- or 25-hour day, a skipped local hour, or a repeated local hour appears. A cycle has no DST; the interval it binds to does. See Requested vs executed time.
  • Projecting the other way is lossy. Dropping the week from an interval to get "just the slot" is fine for an ordinary week and wrong for a DST-variant one, because the skipped/repeated local hour has no stable cyclic home. That is why coarsening is a declared step, never a default (no silent temporal rollup).
The join hazard

Joining a table keyed by hour-of-week slot (a cycle) to one keyed by a UTC timestamp (an interval) on the bare integer is the single most common temporal interoperability bug. The slot repeats every week; the timestamp does not. Bind the slot to each week — or aggregate the timestamp to a (week × slot) key — before the join. Never join a cycle to an interval on the raw number.

What every tool declares

The live conversion tools tag each result so a consumer never has to infer the kind from the field names:

time_to_canonical
cycle — the product is the hour-of-week slot; executed.weekSlotKey is its interval realization in one week
time_instant_to_slot
cycle — a bare slot 0–167
time_daypart_to_slots
cycle — a weekly slot-set
time_slot_uncertainty
cycle — candidate slots a ± window touches
time_now
interval — a concrete instant
time_week_slot_key
interval — a concrete (year × week × slot) key
time_parse_week_slot_key
interval — same, parsed back
time_slot_to_utc_window
interval — the concrete UTC hour a slot occupies in a stated week
time_iso_week_of
interval — a concrete ISO week
time_broadcast_day_slots
interval — a specific dated broadcast day (23/24/25 UTC hours)
time_holidays_for
interval — concrete dated holidays

The rule of thumb: if the result would be identical next week, it is a cycle; if it names a specific year and week, it is an interval. The time_slot_to_utc_window and time_to_canonical pair is the canonical bridge between them — bind a cycle to a week to get an interval, and read an interval's slot to get back the cycle.

Edge cases affecting this page

The 168 AxisConceptual modelResolution and GrainConceptual modelRequested vs. Executed TimeConceptual model