Timezone Architecture¶
Timezone contract
Timezone logic must preserve event meaning across three zones: source timezone (event authority), display timezone (user view), and system timezone (runtime host). Any drift between these boundaries is a correctness bug.
Core model¶
| Zone | Ownership | Usage |
|---|---|---|
| SourceTZ | Provider/event payload | Persisted event meaning and recurrence authority. |
| DisplayTZ | User setting | Calendar rendering and user-facing edits. |
| SystemTZ | Host environment | Runtime baseline and fallback behavior only. |
EventEnhancer applies read-path normalization (enhance) and write-path reversal (prepareForStorage) so core state stays canonical while providers receive source-appropriate payloads.
RRULE patch architecture¶
The codebase includes a non-trivial recurrence patch path to compensate for timezone detection weaknesses in upstream FullCalendar RRULE handling.
Patch intent
The patch avoids system-timezone leakage and preserves source-zone recurrence semantics by reconstructing recurrence expansion with UTC-safe operations.
For root cause details, fix strategy, and regression coverage, see the dedicated devlog: RRULE Timezone Date-Shift Fix.
This behavior exists to prevent day/weekday drift around DST and timezone boundary transitions when DTSTART;TZID=... forms are not correctly handled upstream.
ICS and timezone normalization¶
Timezone handling includes normalization of IANA, UTC, and common Windows timezone identifiers during ICS ingestion. Parsing and fallback logic are intentionally defensive to avoid malformed payload breakage.
Invariants for contributors¶
- Never mix local date getters into UTC reconstruction steps for patched recurrence output.
- Keep source-zone authority for recurring interpretation.
- Validate changes against timezone and DST-focused tests before merging.
- Update architecture docs for any timezone-path behavior change.
Integration anchors¶
src/features/timezone/Timezone.tssrc/core/EventEnhancer.tssrc/core/interop.tssrc/providers/ics/ics.tssrc/providers/caldav/CalDAVProvider.ts