On 2024-01-07 16:51, Guy Harris wrote:
https://datatracker.ietf.org/doc/html/rfc8536
describes TZif format (to use the capitalization in the RFC) up to version 3 (version 4 is not documented in the RFC, but it's a small change to leap second handling, documented in the tzfile man page).
According to it, the local time type records contain a field named utoff (presumably changed from gmtoff)
Yes, that's right.
Zic also sets the isdst flag:
670373999 1991-03-31 01:59:59 isdst 0 gmtoff 10800 stdoff 10800 MSK 670374000 1991-03-31 02:00:00 isdst 1 gmtoff 10800 stdoff 10800 EEST
...which means that the isdst flag also changed, further making it not a "no-op" transition from pic's point of view.
However, it reports "EEST", not "EEDT", so *that's* probably a bug.
The Rule line says "S" so I think "EEST" is correct there. It is part of an EET/EEST pair.
tzname[] is set to { "MSK", "EEST" } after localtime() is called on 670374000, so the timezone code in macOS 13.6, at least, has this bug in it. It should probably have been set to { "EEST", "EEDT" }. This is an area where current POSIX, though self-consistent, is a poor match for TZDB. POSIX assumes that there is just one standard time and at most one DST, so there are at most two abbreviations and they can be put into tzname[0] and tzname[1]. This assumption is incorrect for TZDB, where there can be many abbreviations for standard time (for different timestamps of course), and likewise for DST.
If memory serves, tzcode addresses this by putting the most recently-used standard-time abbreviation into tzname[0], and the most recently-used DST abbreviation into tzname[1]. That's consistent with the macOS behavior you reported. For timezones specified by POSIX TZ strings this conforms to POSIX. But for timezones like Europe/Moscow, this is a thread-unsafe mess -- which is partly why tm_zone was invented and it's also why theory.html advises against the use of tzname. I suspect that the draft next POSIX doesn't address this issue, though it should.