dbae39b0

By: Tom Sydney Kerckhove <syd@cs-syd.eu>

ical-recurrence: ignore a generated leap second whatever DTSTART is

GREEN for the tests in the previous commit.

'localTimeExists' answered 'const True' for anything that was not a zoned
DATE-TIME, because the resolve/unresolve round trip it uses needs a time
zone.  A leap second needs no time zone to rule out, so it is now ruled
out in every branch, and BYSECOND=60 produces no instance whatever
DTSTART's value type is.

The predicate is a syntactic check on the local time:

    isLeapSecond = (>= 60) . Time.todSec . Time.localTimeOfDay

Honouring second 60 was never coherent.  Whether such a local time
survives resolving and unresolving depends on the time of day and on the
offset -- 23:59:60 at a zero offset survives, 00:59:60 does in a +01:00
zone, everything else normalises into the following minute -- so the
recurrence set came to depend on facts about neither the rule nor the
calendar.  The cost is that BYSECOND=60 never generates an instance, which
is the honest outcome: real leap seconds are announced for particular
dates and nothing here knows which.

'ICal.Recurrence.TimeZoneSpec' had its own copy of this predicate as a
let-binding, added when that property was revived.  It now uses the
exported one, so the concept has one definition.  That does not make the
property tautological: 'isLeapSecond' is a syntactic check, not something
derived from the round trip, and the three concrete cases in that file
still pin what actually happens to a leap second independently.

Suite timing

Time to Start Worker time Duration Time to finish Idle
Config 21s 1s 1s 23s 21s
Eval 26s 10s 10s 37s 2s
Build 36s 0s 1h12m31s 1h13m08s 1h12m30s
Suite 21s 12s 1h12m46s 1h13m08s 1h12m55s

Timeline

0s30s