Skip to content

feat(analytics): datetime date-bucket drill uses reference-tz midnight instants (#1752 follow-up) - #3272

Merged
os-zhuang merged 1 commit into
mainfrom
claude/report-drill-down-range-filter-lxt859
Jul 19, 2026
Merged

feat(analytics): datetime date-bucket drill uses reference-tz midnight instants (#1752 follow-up)#3272
os-zhuang merged 1 commit into
mainfrom
claude/report-drill-down-range-filter-lxt859

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Why

Follow-up to #3256 (which landed #1752). That change deliberately left one gap: a datetime date dimension bucketed under a non-UTC reference timezone fell back to a superset drill. A datetime bucket's boundary is that timezone's midnight instant, which the YYYY-MM-DD calendar bounds couldn't express — so rather than emit a wrong (tz-offset) bound, it emitted none. This closes that gap.

What

  • @objectstack/core — add zonedDateStartToUtcMs(ymd, tz): the UTC instant at which calendar day ymdbegins in reference timezone tz (the inverse of calendarPartsInTz). DST-safe — the offset is read from the platform tz database via Intl.DateTimeFormat, with a two-pass resolution for the rare offset-boundary case; an unset / 'UTC' / invalid zone returns plain UTC midnight.
  • @objectstack/service-analytics — emit drillRanges bounds per the field's temporal type (ADR-0053):
    • datetime → ISO instant bounds at the reference tz's midnight (works under any tz, including DST);
    • dateYYYY-MM-DD calendar bounds (tz-naive, exact under any tz);
    • unknown field type → still emitted only under UTC, omitted (superset) under a non-UTC tz.

No objectui change — the client already forwards whatever bound values the server sends into the drill filter and the filter[field][gte|lt] URL contract, so ISO-instant bounds flow through unchanged.

Testing

  • zonedDateStartToUtcMs (9 cases): fixed offset (Asia/Shanghai +08), DST zone summer/winter (America/New_York EDT/EST), DST-transition days, unknown zone → UTC, unparseable → NaN, plus a round-trip that proves the instant lands exactly on the day boundary in the zone.
  • Analytics emission: a datetime dim under America/New_York now drills 2026-06-01T04:00:00.000Z → 2026-07-01T04:00:00.000Z (EDT midnight = 04:00 UTC).
  • Green: @objectstack/service-analytics 170/170, @objectstack/objectql date-bucket-range 49/49 (regression), core datetime 9/9; type-check clean (DTS build).

🤖 Generated with Claude Code

https://claude.ai/code/session_01RCXBnmMQTwjmFkjtpEe11f


Generated by Claude Code

…t instants (#1752 follow-up)
A `datetime` date dimension bucketed under a non-UTC reference tz previously fell
back to a superset drill (its bucket boundary is that tz's midnight instant, which
YYYY-MM-DD calendar bounds can't express). Emit those instants instead, closing the
last gap from the initial #1752 change.
- core: add `zonedDateStartToUtcMs(ymd, tz)` — the UTC instant a calendar day
begins in a reference tz (inverse of calendarPartsInTz). DST-safe via Intl with a
two-pass offset resolution; unset/UTC/invalid zone → plain UTC midnight.
- service-analytics: emit drillRanges bounds by field temporal type (ADR-0053) —
datetime → ISO instant at the tz's midnight (any tz, incl. DST); date →
YYYY-MM-DD calendar (tz-naive). Unknown type stays UTC-only.
objectui needs no change — the client already forwards arbitrary bound values into
the drill filter and the filter[field][gte|lt] URL.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RCXBnmMQTwjmFkjtpEe11f
@vercel

vercelBot commented Jul 19, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
specReadyReadyPreview, CommentJul 19, 2026 12:02pm

Request Review

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation tests tooling labels Jul 19, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 2 package(s): @objectstack/core, packages/services.

26 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/ai/actions-as-tools.mdx(via @objectstack/core)
  • content/docs/ai/knowledge-rag.mdx(via @objectstack/core)
  • content/docs/ai/natural-language-queries.mdx(via @objectstack/core)
  • content/docs/automation/webhooks.mdx(via @objectstack/core, packages/services)
  • content/docs/concepts/north-star.mdx(via packages/core)
  • content/docs/deployment/migration-from-objectql.mdx(via @objectstack/core)
  • content/docs/kernel/contracts/index.mdx(via @objectstack/core)
  • content/docs/kernel/runtime-services/audit-service.mdx(via packages/services)
  • content/docs/kernel/runtime-services/examples.mdx(via @objectstack/core)
  • content/docs/kernel/runtime-services/index.mdx(via packages/services)
  • content/docs/kernel/runtime-services/settings-service.mdx(via packages/services)
  • content/docs/kernel/services-checklist.mdx(via @objectstack/core)
  • content/docs/kernel/services.mdx(via @objectstack/core)
  • content/docs/permissions/authentication.mdx(via @objectstack/core)
  • content/docs/permissions/authorization.mdx(via packages/core)
  • content/docs/plugins/anatomy.mdx(via @objectstack/core)
  • content/docs/plugins/development.mdx(via @objectstack/core)
  • content/docs/plugins/index.mdx(via @objectstack/core)
  • content/docs/plugins/packages.mdx(via @objectstack/core, packages/services)
  • content/docs/protocol/kernel/config-resolution.mdx(via @objectstack/core)
  • content/docs/protocol/kernel/i18n-standard.mdx(via packages/services)
  • content/docs/protocol/kernel/index.mdx(via @objectstack/core)
  • content/docs/protocol/kernel/lifecycle.mdx(via @objectstack/core)
  • content/docs/protocol/kernel/plugin-spec.mdx(via @objectstack/core)
  • content/docs/releases/implementation-status.mdx(via @objectstack/core)
  • content/docs/releases/v15.mdx(via @objectstack/core)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

@os-zhuang
os-zhuang marked this pull request as ready for review July 19, 2026 12:10
@os-zhuang
os-zhuang merged commit dd9f223 into mainJul 19, 2026
16 checks passed
@os-zhuang
os-zhuang deleted the claude/report-drill-down-range-filter-lxt859 branch July 19, 2026 12:10
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/mteststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@os-zhuang@claude