diff --git a/.changeset/local-event-times.md b/.changeset/local-event-times.md new file mode 100644 index 0000000..07c72c2 --- /dev/null +++ b/.changeset/local-event-times.md @@ -0,0 +1,6 @@ +--- +'@cal-sdk/provider-utils': patch +'@cal-sdk/mock': patch +--- + +Event times without an offset, such as `{ dateTime: '2026-11-09T10:00:00', timeZone: 'Europe/Berlin' }`, are read in their own time zone instead of the machine's. This fixes busy times, listing windows and recurrence expansion in the mock calendar. diff --git a/packages/provider-utils/src/time/event-time.ts b/packages/provider-utils/src/time/event-time.ts index 644c21b..f44edcc 100644 --- a/packages/provider-utils/src/time/event-time.ts +++ b/packages/provider-utils/src/time/event-time.ts @@ -10,11 +10,16 @@ export function isAllDay(time: EventTimeV1): time is Extract { expect(eventTimeToInstant({ date: '2026-11-03' })).toBe(Date.parse('2026-11-03T00:00:00Z')); }); + it('reads a date-time without an offset in its own time zone, not the host zone', () => { + expect(eventTimeToInstant({ dateTime: '2026-11-09T10:00:00', timeZone: 'Europe/Berlin' })).toBe( + Date.parse('2026-11-09T09:00:00Z'), + ); + // Daylight saving time in New York. + expect(eventTimeToInstant({ dateTime: '2026-07-01T09:30', timeZone: 'America/New_York' })).toBe( + Date.parse('2026-07-01T13:30:00Z'), + ); + }); + it('adds days across month and year ends', () => { expect(addDaysToDate('2026-12-31', 1)).toBe('2027-01-01'); expect(addDaysToDate('2028-03-01', -1)).toBe('2028-02-29');