[tz] Bad 32 bit data in 2018f

Daniel Fischer daniel.fischer at oracle.com
Wed Oct 24 12:47:36 UTC 2018


I'm getting bad data in the 32 bit section of some of the compiled files in zoneinfo-leaps.

The affected time zones are zones that only transition before 1901, usually from LMT to some UTC offset:


The files in zoneinfo-leaps contain no transitions, and only the offset used before the transition. This causes applications that only read the 32 bit section to use LMT for these zones.

The 64 bit section, and both sections in the zoneinfo version of these files, contain >=2 transitions and offsets (e.g. one real transition and one in 2038). 

For example, zdump with a break added after /old file/ in localtime.c:

$ ./zdump $PWD/TZ/usr/share/zoneinfo*/Atlantic/South_Georgia 
.../TZ/usr/share/zoneinfo/Atlantic/South_Georgia        Tue Oct 23 12:31:33 2018 -02
.../TZ/usr/share/zoneinfo-leaps/Atlantic/South_Georgia  Tue Oct 23 12:04:58 2018 LMT

$ ./zdump -V $PWD/TZ/usr/share/zoneinfo-leaps/Atlantic/South_Georgia 
.../TZ/usr/share/zoneinfo-leaps/Atlantic/South_Georgia  Sat Jul  1 00:00:00 1972 UT = Fri Jun 30 21:33:52 1972 LMT isdst=0 gmtoff=-8768
.../TZ/usr/share/zoneinfo-leaps/Atlantic/South_Georgia  Sat Jul  1 00:00:01 1972 UT = Fri Jun 30 21:33:52 1972 LMT isdst=0 gmtoff=-8768
.../TZ/usr/share/zoneinfo-leaps/Atlantic/South_Georgia  Sun Jan  1 00:00:27 2017 UT = Sat Dec 31 21:33:52 2016 LMT isdst=0 gmtoff=-8768

I found that before commit 83c119f4d ("Remove Big Bang hack"), the one offset present in the leaps version was the correct one. The structural difference is older; it just didn't affect my application because the offset was the one currently in use.

The cause appears to be this sequence of events starting at zic.c /Work around QTBUG-53071/:

1) y2038_boundary-1 transition is added (== INT32_MAX)

2) leap seconds are added to all times, pushing the 2038 transition above INT32_MAX

3) affected zones again only have transition times outside the 32 bit range => timecnt32 is 0

4) because timecnt32 is 0, timei32 is also 0, and the INT32_MIN transition isn't output either

5) because of omittype[defaulttype] = false, the oldest offset is always output regardless of the above

The workaround could probably be moved to after the leap seconds are added, especially if it's supposed to apply to the 32 bit leaps files.

This will also fix this bug, because the code that determines the 32 bit limits assumes there's at least one time after 1901, and the workaround provides one. (This is why the non-leaps version is correct.)

I'm unfortunately not familiar enough with the tz database to suggest a complete fix.


Daniel Fischer
ORACLE Deutschland B.V. & Co. KG, Riesstr. 25, 80992 München - HRA MUC 95603
Komplementaer: ORACLE DE Verw.B.V., Hertogswetering 163/167, 3543 AS Utrecht
Geschaeftsfuehrer: Alexander van der Ven, Jan Schultheiss, Val Maher      NL

More information about the tz mailing list