diff --git a/lib/events/tests/ical.sx b/lib/events/tests/ical.sx index e12e3135..9f96554c 100644 --- a/lib/events/tests/ical.sx +++ b/lib/events/tests/ical.sx @@ -335,6 +335,17 @@ (do (ev-ic-check! "Paris DAYLIGHT goes to +0200 (CEST)" (ev-ic-find vtz "TZOFFSETTO:+0200") "TZOFFSETTO:+0200") (ev-ic-check! "Paris STANDARD goes to +0100 (CET)" (ev-ic-find vtz "TZOFFSETTO:+0100") "TZOFFSETTO:+0100"))) + ;; southern hemisphere exports a valid VTIMEZONE too: reversed offsets, + ;; first-Sunday rules, and the -480 rule time folds back to local 02:00/03:00 + (let + ((vtz (ev-ical-vtimezone ev-tz-sydney))) + (do + (ev-ic-check! "Sydney VTIMEZONE names the zone" (ev-ic-find vtz "TZID") "TZID:Australia/Sydney") + (ev-ic-check! "Sydney DAYLIGHT goes to +1100 (AEDT)" (ev-ic-find vtz "TZOFFSETTO:+1100") "TZOFFSETTO:+1100") + (ev-ic-check! "Sydney STANDARD goes to +1000 (AEST)" (ev-ic-find vtz "TZOFFSETTO:+1000") "TZOFFSETTO:+1000") + (ev-ic-check! "Sydney DAYLIGHT rule is first Sunday of October" (ev-ic-find vtz "RRULE:FREQ=YEARLY;BYMONTH=10") "RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU") + (ev-ic-check! "Sydney STANDARD rule is first Sunday of April" (ev-ic-find vtz "RRULE:FREQ=YEARLY;BYMONTH=4") "RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SU") + (ev-ic-check! "Sydney DAYLIGHT begins 02:00 local (AEST std, -480 folded)" (ev-ic-find vtz "DTSTART") "DTSTART:19701004T020000"))) ;; ---- VCALENDAR carries one VTIMEZONE per distinct zone ---- (let @@ -371,7 +382,13 @@ (get (ev/ical-lines->event (ev/event->ical-lines (ev-event-tz (quote a) (ev-dt 2026 7 15 18 0) 60 nil 1 ev-tz-london))) :dtstart) - (ev-dt 2026 7 15 18 0))))) + (ev-dt 2026 7 15 18 0)) + (ev-ic-check! + "import parses a southern-zone DTSTART;TZID local time" + (get + (ev/ical-lines->event (ev/event->ical-lines (ev-event-tz (quote a) (ev-dt 2026 1 15 18 0) 60 nil 1 ev-tz-sydney))) + :dtstart) + (ev-dt 2026 1 15 18 0))))) (define ev-ical-tests-run! diff --git a/plans/events-on-sx.md b/plans/events-on-sx.md index d0a695e8..e4397425 100644 --- a/plans/events-on-sx.md +++ b/plans/events-on-sx.md @@ -18,7 +18,7 @@ capacity rules, transactional booking, and a flow-driven notification dispatcher ## Status (rolling) -`bash lib/events/conformance.sh` → **384/384** (Phases 1-4 + 14 ext + tz iCal export via TZID + VTIMEZONE + southern-hemisphere DST) +`bash lib/events/conformance.sh` → **391/391** (Phases 1-4 + 14 ext + tz iCal export via TZID + VTIMEZONE + southern-hemisphere DST incl. iCal round-trip) ## Ground rules @@ -88,6 +88,13 @@ lib/events/api.sx ── (events/schedule) (events/book) (events/agenda) ── ## Progress log +- 2026-06-10 — Harden southern-hemisphere DST: explicit iCal coverage for the + previous commit's unverified claim that "southern zones round-trip through + iCal unchanged". Added a Sydney VTIMEZONE export block (TZID:Australia/Sydney, + DAYLIGHT→+1100/STANDARD→+1000, first-Sunday rules BYMONTH=10/4 BYDAY=1SU, and + DAYLIGHT DTSTART:19701004T020000 — proving the −480 rule time folds back to + local 02:00 AEST) and a southern-zone DTSTART;TZID export→import round-trip. + +7 tests (ical 63). 391/391 green. - 2026-06-10 — Southern-hemisphere DST. The `:dst` zone model assumed northern ordering (dst-start < dst-end, DST = [start, end)); southern zones (DST begins ~Oct, ends ~Apr) have dst-start > dst-end and so silently never entered DST —