feat(frontend): show local timezone alongside UTC in schedule displays#1564
feat(frontend): show local timezone alongside UTC in schedule displays#1564machadovilaca wants to merge 5 commits into
Conversation
✅ Deploy Preview for cheerful-kitten-f556a0 canceled.
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Enterprise Run ID: 📒 Files selected for processing (6)
✅ Files skipped from review due to trivial changes (2)
🚧 Files skipped from review as they are similar to previous changes (4)
📝 WalkthroughWalkthroughA new helper, ChangesCron Description Localization
sequenceDiagram
participant Browser
participant Component as Details/Form/Tab
participant CronLib as cron.ts:getCronDescriptionWithLocal
participant Runner as getNextRuns
participant Formatter as formatTimeLocal
Browser->>Component: render scheduled session UI
Component->>CronLib: getCronDescriptionWithLocal(cronExpr)
CronLib->>Runner: getNextRuns(cronExpr, 2)
Runner-->>CronLib: nextRun1, nextRun2
alt interval < 24h (sub-daily)
CronLib-->>Component: base cronstrue description
else daily-or-longer
CronLib->>Formatter: formatTimeLocal(nextRun1)
Formatter-->>CronLib: localTimeStr
CronLib-->>Component: "UTC-labeled description" or "UTC-labeled description (localTimeStr)"
end
Component-->>Browser: render description + raw cron string
Possibly related PRs
Important Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional. ❌ Failed checks (1 error, 1 warning)
✅ Passed checks (6 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
✨ Simplify code
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@components/frontend/src/lib/__tests__/cron.test.ts`:
- Around line 42-45: The test for getCronDescriptionWithLocal is wrong: it
claims "when not UTC" but only checks for "UTC", so it doesn't validate the
local parenthesized suffix; update the test to mock/stub the local timezone
formatter to return a non-UTC timezone (e.g. override
Intl.DateTimeFormat.prototype.resolvedOptions or the formatter used by
getCronDescriptionWithLocal to return timeZone: 'America/Los_Angeles'), call
getCronDescriptionWithLocal('0 9 * * *'), and assert explicitly that the
returned string contains the parenthesized local annotation (for example assert
it matches a regex like /\([^)]+\)$/ and contains the mocked timezone
identifier).
In `@components/frontend/src/lib/cron.ts`:
- Around line 42-49: The current sub-daily detection uses a calendar-date
equality check (sameDay) on runs[0] and runs[1], which misclassifies schedules
near UTC day boundaries; change the logic to compute the time interval between
runs (e.g., runs[1].getTime() - runs[0].getTime()) and treat it as sub-daily if
that difference is strictly less than 24 * 60 * 60 * 1000 ms, replacing the
sameDay check so the code paths that return description for sub-daily schedules
use the interval comparison instead.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 5296c7ea-9610-42f9-b188-1d0b1be869e9
📒 Files selected for processing (5)
components/frontend/src/app/projects/[name]/scheduled-sessions/[scheduledSessionName]/_components/scheduled-session-details-card.tsxcomponents/frontend/src/app/projects/[name]/scheduled-sessions/_components/scheduled-session-form.tsxcomponents/frontend/src/components/workspace-sections/scheduled-sessions-tab.tsxcomponents/frontend/src/lib/__tests__/cron.test.tscomponents/frontend/src/lib/cron.ts
16977f0 to
ac518f2
Compare
|
/cc @jsell-rh |
jsell-rh
left a comment
There was a problem hiding this comment.
cron.ts:52 — the regex (\d{1,2}:\d{2}\s*[AP]M) assumes 12-hour format. cronstrue can return 24-hour time (e.g. 14:30) in non-English locales, so the regex won't match and the "UTC" label silently disappears. Not a crash, just no annotation.
Consider matching 24h as well: (\d{1,2}:\d{2}(\s*[AP]M)?).
|
@machadovilaca thank you! Review bot found one nit, and I've got one more request: We're moving towards a spec-driven workflow for ambient. Could you use the We don't have full spec coverage at this point, but I do want to make sure this change is captured in the specs. Feel free to include those spec changes in this PR. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@components/frontend/src/lib/cron.ts`:
- Around line 52-60: The regex replacement that creates withUtc can fail
silently and lead to inconsistent dual-timezone strings; update the logic in
this block to first run const match =
description.match(/(\d{1,2}:\d{2}\s*[AP]M)/) and only build withUtc and append
the local time when match is truthy—i.e., if match exists set withUtc =
description.replace(... ) (or explicitly `${match[1]} UTC`) and then apply the
existing local.endsWith("UTC") check; if no match, return description (or
`${description} (${formatTimeLocal(runs[0])})` only if you intend to always
include local) to ensure you don't append a local time when the UTC label wasn't
inserted.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 8479b18c-fe95-4aeb-9c91-e81d308dd4d3
📒 Files selected for processing (5)
components/frontend/src/app/projects/[name]/scheduled-sessions/[scheduledSessionName]/_components/scheduled-session-details-card.tsxcomponents/frontend/src/app/projects/[name]/scheduled-sessions/_components/scheduled-session-form.tsxcomponents/frontend/src/components/workspace-sections/scheduled-sessions-tab.tsxcomponents/frontend/src/lib/__tests__/cron.test.tscomponents/frontend/src/lib/cron.ts
🚧 Files skipped from review as they are similar to previous changes (4)
- components/frontend/src/app/projects/[name]/scheduled-sessions/[scheduledSessionName]/_components/scheduled-session-details-card.tsx
- components/frontend/src/lib/tests/cron.test.ts
- components/frontend/src/app/projects/[name]/scheduled-sessions/_components/scheduled-session-form.tsx
- components/frontend/src/components/workspace-sections/scheduled-sessions-tab.tsx
Formalizes the frontend behavior for displaying cron schedule times: UTC label on daily-or-longer schedules, local timezone parenthetical for non-UTC browsers, sub-daily omission, interval-based detection, graceful fallback, and 12h/24h format support. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add getCronDescriptionWithLocal() that enriches cron descriptions with the user's local timezone. "At 05:30 AM, Monday through Friday" becomes "At 05:30 AM UTC, Monday through Friday (6:30 AM GMT+1)". Sub-daily schedules (every hour, every 15 min) skip the annotation since the local offset adds no value. Applied consistently across: - Scheduled sessions list (Schedule column) - Scheduled session detail card - Create/edit form preview Follows up on ambient-code#1496 which fixed cron parsing to use UTC. We chose UTC input with local display (rather than local-first input) to avoid DST drift, fractional offset conversion bugs, and day-of-week wrapping edge cases documented in the design spec. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ec0d103 to
6d44002
Compare
|
LGTM |
|
@machadovilaca looks like lint might be failing |
Summary
Follows up on #1496. Shows the user's local timezone alongside UTC in all schedule-related displays, so users don't have to mentally convert UTC times.
getCronDescriptionWithLocal()that inserts "UTC" after the time in cron descriptions and appends the local equivalent in parenthesesBefore:
At 05:30 AM, Monday through FridayAfter:
At 05:30 AM UTC, Monday through Friday (6:30 AM GMT+1)Edit

List

Show

Why UTC input (not local-first input)
We considered letting users input cron schedules in their local timezone and converting to UTC behind the scenes, but rejected it:
getTimezoneOffset()returns the offset at input time, not execution time. A user in London (UTC+0 winter, UTC+1 summer) who sets "9 AM local" in January gets0 9 * * *UTC — which silently becomes 10 AM local in summer1-5must become0-4or2-6, with modular wrapping on each elementUTC input avoids all of these. Showing the local equivalent next to it gives users the "when does this fire for me?" answer without any conversion complexity or correctness risks.
Test plan
getCronDescriptionWithLocal()— daily, weekly, monthly schedules include UTC + local; sub-daily schedules return plain description; invalid cron falls back gracefullySummary by CodeRabbit
New Features
Tests
Documentation