7c72306a

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

Committer: Tom Sydney Kerckhove <NorfairKing@users.noreply.github.com>

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 10m11s 1s 1s 10m12s 10m11s
Eval 10m18s 18s 18s 10m37s 5s
Build 10m36s 6m49s 33m42s 44m19s 29m14s
Suite 10m11s 7m09s 34m07s 44m19s 39m32s

Timeline

0s10m20s40m40m20s40m40s41m41m20s41m40s42m42m20s42m40s43m43m20s43m40s44m