Skip to content

Add absolute anchor and Clock-level timezone#8

Merged
boatmeme merged 1 commit into
mainfrom
absolute-anchor
Jun 28, 2026
Merged

Add absolute anchor and Clock-level timezone#8
boatmeme merged 1 commit into
mainfrom
absolute-anchor

Conversation

@boatmeme

Copy link
Copy Markdown
Owner

What & why

The third and final window anchor from issue #4. { absolute } pins a distortion to a
fixed real-world instant, independent of when the Clock was constructed — and, since
it's plain instant arithmetic, it delivers true multi-day spans (an arbitrarily long
referenceDuration like { hours: 72 }, with none of the ~24h overnight-wrap limit a
time-of-day window has).

Resolving an absolute wall-clock start needs a timezone, so the Clock gains one — which
also closes a latent gap: time-of-day windows were silently UTC-only.

API

  • { absolute: Date | AbsoluteDescriptor } added to DistortionAnchor (bare descriptor
    still defaults to time-of-day; { elapsed } unchanged). Date = an instant;
    AbsoluteDescriptor = { year, month, day, hour?, ... } resolved in the clock's zone.
  • new Clock(distortions, { timeZone })read-only, default 'UTC', plus a timeZone
    getter. Used by time-of-day and absolute windows alike.
  • Exports the AbsoluteDescriptor type.

How it fits

The resolveAt(anchorMs, timeZone?) extension to the window contract absorbed everything —
the offset integrator is unchanged. TimeWindow honors the passed zone (construction-zone
fallback for standalone use); ElapsedWindow ignores it (run-relative).

Design note

The zone is immutable — to run in a different zone, build a new Clock. Mid-run zone changes
are deliberately out of scope: the offset is path-dependent and time-of-day windows refire/skip
ambiguously when local time jumps, so that needs an injectable run-anchor/offset (seeded
successor clock) plus a refire policy — a separable follow-up.

Tests / docs

  • New AbsoluteWindow, AbsoluteAnchor (incl. a 3-day span integrated once across a sparse
    read), and ClockTimezone (same window, different instants per zone) suites — 72 tests,
    coverage thresholds met, tsc + eslint clean.
  • README: { absolute } anchor (multi-day example) and the { timeZone } option.

Not in this PR

Mid-run zone rebasing, daily recurrence, eased distortions, calendar-aware durations. No
version bump (0.2.0 isn't shipped yet).

Refs #4

🤖 Generated with Claude Code

The third and final window anchor (issue #4): { absolute } pins a
distortion to a fixed real-world instant, independent of when the Clock
was constructed. True multi-day spans fall out for free -- AbsoluteWindow
is plain instant arithmetic, so an arbitrarily long referenceDuration
(e.g. { hours: 72 }) has none of the ~24h overnight-wrap limit a
time-of-day window has.

Resolving an absolute wall-clock start needs a zone, so the Clock gains a
read-only timeZone (default 'UTC'), threaded into window resolution and
used by both time-of-day and absolute windows. This also closes a latent
gap: time-of-day windows were silently UTC-only.

- resolveAt(anchorMs) -> resolveAt(anchorMs, timeZone?) across the
  DistortionWindow contract; TimeWindow uses it with construction-zone
  fallback, ElapsedWindow ignores it.
- New AbsoluteWindow; { absolute: Date | AbsoluteDescriptor } added to
  DistortionAnchor (bare descriptor still defaults to time-of-day).
- Clock: new Clock(distortions, { timeZone }) + timeZone getter.
- Export the AbsoluteDescriptor type.

Zone is immutable (construct a new Clock to change it); mid-run zone
changes are deferred -- they need an injectable run-anchor/offset and a
time-of-day refire policy.

Adds AbsoluteWindow, absolute-anchor (incl. a multi-day span across a
sparse read), and Clock-timezone tests. Full suite green (72 tests),
coverage thresholds met, tsc and eslint clean. No version bump.

Refs #4

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@boatmeme boatmeme merged commit cad0747 into main Jun 28, 2026
4 checks passed
@boatmeme boatmeme deleted the absolute-anchor branch June 28, 2026 06:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Generalize the distortion window anchor (unlocks multi-day, stopwatch, and countdown modes)

1 participant