POSIX-TZ-environment-variable-style string rules
The tzfile.5 manual page describes the TZ string found at the end of the version 2+ tzfiles as follows: "After the second header and data comes a newline-enclosed, POSIX-TZ-environment-variable-style string for use in handling instants after the last transition time stored in the file." Consider the case when the last transition time (T) stored in the file comes a few weeks before the first POSIX rule transition P > T. What local time type should be used for the the times after T, but before P? The strict reading of the manual page suggests that one should use the the local time type derived from the POSIX rule for all times t >= T, but it would be more reasonable to continue using the type that corresponds to T for times T <= t < P. It turns out the two alternative logics are implemented in real life. The glibc library switches [1] to the POSIX rule when t >= P, while the tzcode implementation uses POSIX rule to supply additional transitions with the first POSIX-derived transition at P. This leads to a discrepancy between glibc and tzcode results that is best described on the Ubuntu bug tracker (bug #1587128 [2]). While tzcode behavior is more logical, glibc code seems to better match the documentation and it will probably be an uphill battle to get a fix into glibc. [3] I think a better solution would be to make zic add a redundant transition when the local time type corresponding to the last transition does not match the POSIX rule. This will ensure that tzcode and glibc produces the same results and systems affected by this issue can be fixed by simply upgrading the zoneinfo database. [1]: https://sourceware.org/git/?p=glibc.git;a=blob;f=time/tzfile.c;h=90498783993... [2]: https://bugs.launchpad.net/ubuntu/+source/glibc/+bug/1587128 [3]: https://sourceware.org/ml/libc-help/2016-04/msg00000.html
Alexander Belopolsky wrote:
While tzcode behavior is more logical, glibc code seems to better match the documentation and it will probably be an uphill battle to get a fix into glibc. [3]
I think a better solution would be to make zic add a redundant transition when the local time type corresponding to the last transition does not match the POSIX rule.
Thanks for the bug report. How about a belt-and-suspenders approach? That is, add the redundant transition, but also fix localtime.c to implement the documented behavor.
On Thu, Jul 28, 2016 at 1:23 AM, Paul Eggert <eggert@cs.ucla.edu> wrote:
I think a better solution would be to make zic add a redundant transition when the local time type corresponding to the last transition does not match the POSIX rule.
... How about a belt-and-suspenders approach? That is, add the redundant transition, but also fix localtime.c to implement the documented behavior.
I am not sure I would go that far. Note that the glibc behavior on the current Africa/Casablanca tzfile is puzzling: the 2037-10-04 transition does not show in the zdump output even though it is present in the tzfile. Furthermore, there are projects other than tzcode that implement tzcode behavior for example Ruby's TZInfo::Data project decided [1] that they would follow tzcode logic. I think the best way forward would be to document the fact that a tzfile with the last explicit transition not matching a POSIX rule transition is invalid and the behavior of localtime with such file is undefined. I suggest fixing the issue in two steps: 1. Add 2038-03-28 transition to the Morocco rules in the raw africa file. 2. Modify zic to warn about raw files where the last explicit transition does not match the rule from the POSIX string and add an appropriate transition in the binary file. Note that the first step will be sufficient to fix the current issue while the second step will prevent a similar issue from occurring in the future. [1] https://github.com/tzinfo/tzinfo-data/issues/10
Alexander Belopolsky wrote:
I think the best way forward would be to document the fact that a tzfile with the last explicit transition not matching a POSIX rule transition is invalid and the behavior of localtime with such file is undefined.
Thanks for thinking it through. I implemented that in the attached patches, which also change zic.c to obey the new restriction on tzfile format. I installed these patches into the experimental repository on GitHub.
I suggest fixing the issue in two steps:
1. Add 2038-03-28 transition to the Morocco rules in the raw africa file.
I don't see how that would work for 32-bit data, since 2038-03-28 is outside the 32-bit window. Another possibility would be to remove Morocco's 2037 transitions to cater to now-buggy zic implementations like zic 2016f, but I'm not sure it's worth the hassle.
2. Modify zic to warn about raw files where the last explicit transition does not match the rule from the POSIX string and add an appropriate transition in the binary file.
The attached patch merely adds the appropriate transition without warning. If someone wants to change zic.c to emit such a warning, that'd be OK too.
On Thu, Aug 4, 2016 at 10:02 PM, Paul Eggert <eggert@cs.ucla.edu> wrote:
I implemented that in the attached patches, which also change zic.c to obey the new restriction on tzfile format.
Thanks. I regenerated the tz files on a 64-bit Fedora and a 32-bit CentOS with your new code and now system zdump reports correct transitions: [a@veertu-fedora tz]$ git describe 2016f-7-ge0a7616 [a@veertu-fedora tz]$ zdump -v `pwd`/etc/zoneinfo/Africa/Casablanca|grep 2037 /home/a/tz/etc/zoneinfo/Africa/Casablanca Sun Mar 29 01:59:59 2037 UT = Sun Mar 29 01:59:59 2037 WET isdst=0 gmtoff=0 /home/a/tz/etc/zoneinfo/Africa/Casablanca Sun Mar 29 02:00:00 2037 UT = Sun Mar 29 03:00:00 2037 WEST isdst=1 gmtoff=3600 /home/a/tz/etc/zoneinfo/Africa/Casablanca Sun Oct 4 01:59:59 2037 UT = Sun Oct 4 02:59:59 2037 WEST isdst=1 gmtoff=3600 /home/a/tz/etc/zoneinfo/Africa/Casablanca Sun Oct 4 02:00:00 2037 UT = Sun Oct 4 02:00:00 2037 WET isdst=0 gmtoff=0
participants (2)
-
Alexander Belopolsky -
Paul Eggert