fix(caldav): use toJSDate instead of toString to prevent timezone double-conversion#28796
fix(caldav): use toJSDate instead of toString to prevent timezone double-conversion#28796pmartin-dev wants to merge 1 commit intocalcom:mainfrom
Conversation
📝 WalkthroughWalkthroughThe changes update CalDAV event timestamp parsing in the calendar service to improve timezone handling accuracy. The production code in 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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.
🧹 Nitpick comments (1)
packages/lib/CalendarService.test.ts (1)
768-780: Minor: Clarify the comment refers to the old buggy code.The comment on line 769 says "Current code in getEvents()" but after this PR merges, this is no longer current—it's the previous/buggy implementation. Consider updating for clarity:
if (strategy === "buggy") { - // Current code in getEvents() — double conversion + // OLD code in getEvents() — double conversion bug🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/lib/CalendarService.test.ts` around lines 768 - 780, The inline comment "Current code in getEvents()" is misleading because this block under strategy === "buggy" is the old/previous buggy implementation; update the comment to clearly indicate it is the previous/buggy implementation (e.g., "Previous/buggy implementation of getEvents — double conversion") so reviewers understand this branch is intentionally kept for comparison; ensure the comment references getEvents and the strategy === "buggy" branch to make the intent explicit.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@packages/lib/CalendarService.test.ts`:
- Around line 768-780: The inline comment "Current code in getEvents()" is
misleading because this block under strategy === "buggy" is the old/previous
buggy implementation; update the comment to clearly indicate it is the
previous/buggy implementation (e.g., "Previous/buggy implementation of getEvents
— double conversion") so reviewers understand this branch is intentionally kept
for comparison; ensure the comment references getEvents and the strategy ===
"buggy" branch to make the intent explicit.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: f33b1025-7bf8-472c-87ee-47575e8b2f38
📒 Files selected for processing (2)
packages/lib/CalendarService.test.tspackages/lib/CalendarService.ts
What does this PR do?
The
getEvents()method inCalendarService.tsdouble-converts timezone offsetswhen parsing CalDAV events that include a VTIMEZONE component.
event.startDate.toString()returns a UTC time without theZsuffix, thendayjs.tz(string, timezone)re-interprets it as local time — applying the offsettwice. This causes events synced from Zimbra (and potentially other CalDAV servers)
to display end times before start times (negative duration).
The fix aligns
getEvents()with the existing correct pattern ingetAvailability()(same file):Register the VTIMEZONE with ical.js via
convertToZone()Use
toJSDate()instead oftoString()+dayjs.tz()to avoiddouble-conversion
Fixes Events synced via CalDAV from Zimbra have end time before start time #27877
Fixes CAL-7198
Visual Demo (For contributors especially)
N/A — this is a backend data parsing fix with no UI changes. The effect is that
CalDAV events from Zimbra now display correct start/end times instead of negative
durations.
Mandatory Tasks (DO NOT REMOVE)
How should this be tested?
TZ=UTC yarn vitest run packages/lib/CalendarService.test.tsparsing" describe block:
the old code produces incorrect absolute timestamps
proves the fix resolves the Zimbra UTC case
proves non-UTC timezone references still work
regression on the simple case
with UTC times (DTSTART/DTEND with Z suffix) where the calendar also includes a
VTIMEZONE component, then sync via CalDAV and check that end time is after start
time.
Checklist