On Wed, 18 Mar 2026 at 07:42, Tomasz Kaminski <[email protected]> wrote:
>
>
>
> On Tue, Mar 17, 2026 at 6:16 PM Jonathan Wakely <[email protected]> wrote:
>>
>> On Tue, 17 Mar 2026 at 13:18, Tomasz Kaminski <[email protected]> wrote:
>> >
>> >
>> >
>> > On Mon, Mar 16, 2026 at 11:55 PM Jonathan Wakely <[email protected]>
>> > wrote:
>> >>
>> >> The Australia/Broken_Hill example in PR libstdc++/116110 demonstrates a
>> >> bug in the time zone code. The current code gives incorrect results when
>> >> a zone changes from one named Rule to another during DST, e.g. the
>> >> Broken_Hill time zone uses:
>> >>
>> >> Zone Australia/Broken_Hill 9:25:48 - LMT 1895 Feb
>> >> 10 - AEST 1896 Aug 23
>> >> 9 - ACST 1899 May
>> >> 9:30 AU AC%sT 1971
>> >> 9:30 AN AC%sT 2000
>> >> 9:30 AS AC%sT
>> >>
>> >> So the AN Rules take effect on 2000 Jan 1 which is during DST (which
>> >> runs from October to March).
>> >
>> > Now, I understand the problem: the end of AS 2000 Jan 1, which according
>> > to the application is:
>> > R AS 1987 2007 - O lastSu 2s 1 D
>> > However, we seem to be searching the wrong rule list because we are using
>> > the "AN" rules to find previous value of DST, not the AS. This still
>> > gives us
>> > expected save value, as I assume the rule switch is not meant to cause
>> > abrupt
>> > changes to the actual wall time, and the changes in wall clock happen
>> > accordingly
>> > to DST.
>>
>> Right.
>>
>> >
>> > I.e. we make assumption that at the time of the rule change, the save value
>> > is same according to new and old rules.
>> >
>> > So I think the code is technically incorrect, but practically correct. To
>> > be exact,
>> > we would need look use the rule set from previous iterator in that case.
>>
>> I think we're handling this case wrong, but with the patch we give the
>> right result for this time zone.
>>
>> The zic(8) man page says:
>>
>> A zone or continuation line L with a named rule set starts with
>> standard
>> time by default: that is, any of L's timestamps preceding L's
>> earliest
>> rule use the rule in effect after L's first transition into
>> standard
>> time.
>
> I think that describes how the rule is interpreted for dates before its first
> entry, i.e. 1971 for both AN and AS:
> R AN 1971 1985 - O lastSu 2s 1 D
> R AN 1972 o - F 27 2s 0 S
> R AN 1973 1981 - Mar Su>=1 2s 0 S
> R AS 1971 1985 - O lastSu 2s 1 D
> R AS 1986 o - O 19 2s 1 D
> R AS 1987 2007 - O lastSu 2s 1 D
> R AS 1972 o - F 27 2s 0 S
> R AS 1973 1985 - Mar Su>=1 2s 0 S
>
>>
>> I think that means that we should not actually change from the AN rule
>> to the AS rule on Jan 1st 2001, we should continue using the AN rule
>> until the first transition to standard time of the AS rule.
>
> Given that the entries may also switch the offset, I think they meant to apply
> until the end date, for example, the Kirimiti zone that switched between sides
> o International Day Line:
> Z Pacific/Kiritimati -10:29:20 - LMT 1901
> -10:40 - %z 1979 O
> -10 - %z 1994 D 31
> 14 - %z
> Switch happened on 23:59:59 21th December of 1994.
This case is different from Australia/Broken_Hill and much simpler to
handle. There's no Rule involved here, just Zone lines and
continuation lines. Switches from one Zone line to another definitely
happen at the UNTIL time (but I also agree with your conclusion that
the cases involving a named Rule switch at the UNTIL time too). For
these cases I think we have ZoneInfo::m_expanded == true and so we
return early from _M_get_sys_info:
if (i->to(info)) // We already know a sys_info for this time.
return info;
But I'll add tests for Pacific/Kiritimati and Pacific/Apia, thanks for
finding them.