You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
ADR-0053 Phase 2 D1. today()/daysFromNow()/daysAgo() become calendar-day
functions resolved in a reference timezone (threaded ExecutionContext.timezone
-> EvalContext.timezone -> CEL stdlib). Each returns the reference-tz calendar
day as a UTC-midnight Date — the representation consistent with Field.date
hydration, the SQL driver's date-filter normalization, and Phase 1 storage —
so `record.date == daysFromNow(n)` matches in-memory too. Timezone math uses
Intl.DateTimeFormat (DST-safe).
BEHAVIOR CHANGE: daysFromNow(n)/daysAgo(n) previously kept now's wall-clock
time; they now drop it and return the calendar day at midnight (the ADR
"defect #3" fix). today() is unchanged at UTC. Sub-day offsets: now() +
duration("Nh").
objectql threads execCtx.timezone into applyFormulaPlan (read-time formula
fields) and applyFieldDefaults (default-value expressions). With no reference
tz configured the zone is UTC.
Tests: tz-aware today()/daysFromNow()/daysAgo() (America/New_York day
boundary); daysFromNow midnight semantics; existing wall-clock assertions
updated to calendar-day. formula 121 green, objectql 639 green.
Part of #1980.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
These are now **calendar-day** functions resolved in a reference timezone, threaded from `ExecutionContext.timezone` (#1978) through `EvalContext.timezone` into the CEL stdlib. Each returns the reference-tz calendar day expressed as a **UTC-midnight `Date`** (ADR-0053 decision D1) — the one representation consistent with how `Field.date` strings hydrate, how the SQL driver normalizes date filters, and how Phase 1 stores dates. So `record.close_date == daysFromNow(30)` now matches in-memory too, not just at the storage boundary. The timezone calculation uses `Intl.DateTimeFormat` (DST-safe; no hand-rolled offset math).
9
+
10
+
**⚠️ Behavior change:**`daysFromNow(n)` / `daysAgo(n)` previously kept the wall-clock time of `now` (e.g. `daysFromNow(30)` at `10:00Z` → `…T10:00:00Z`). They now drop the time and return the calendar day at **midnight** (`…T00:00:00Z`) — the ADR-0053 "defect #3" fix. `today()` is unchanged at UTC (it already truncated to start-of-day). For a genuine sub-day offset use the documented escape hatch `now() + duration("Nh")`.
11
+
12
+
With no reference timezone configured the zone resolves to `UTC`, so `today()` is byte-for-byte unchanged; only the `daysFromNow`/`daysAgo` midnight-truncation differs from before. `objectql` threads `execCtx.timezone` into read-time formula evaluation (`applyFormulaPlan`) and default-value expressions (`applyFieldDefaults`).
13
+
14
+
Part of #1980. (Consuming a non-UTC reference timezone end-to-end also needs the `localization` settings manifest noted in #1978.)
0 commit comments