On Wed, Mar 18, 2026 at 12:12 PM Jonathan Wakely <[email protected]> wrote:
> 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. > > Yes, I searched further and found Pacific/Apia, which involves rules.
