2

I recently wrote some code to parse the binary timezone data from the Olson zoneinfo database. As far as I can tell, my code is correct and matches the spec as written in C.

However, I get different results when comparing the results of my tool to the output of standard zdump tool! This is strange, because it seems to me that we are working from the data. Here's what my tool produces:

$ ./mytool /usr/share/zoneinfo/Pacific/Honolulu
3137684296: name:HDT   offset:-34200 DST:true  type:Wall
3139531096: name:HST   offset:-37800 DST:false type:Wall
3414769096: name:HDT   offset:-34200 DST:true  type:Wall
3529591096: name:HST   offset:-37800 DST:false type:Wall
3582817096: name:HST   offset:-36000 DST:false type:Wall

And here's what zdump gives me:

$ zdump -v /usr/share/zoneinfo/Pacific/Honolulu
/usr/share/zoneinfo/Pacific/Honolulu  Fri Dec 13 20:45:52 1901 UTC = Fri Dec 13 10:15:52 1901 HST isdst=0
/usr/share/zoneinfo/Pacific/Honolulu  Sat Dec 14 20:45:52 1901 UTC = Sat Dec 14 10:15:52 1901 HST isdst=0
/usr/share/zoneinfo/Pacific/Honolulu  Sun Apr 30 12:29:59 1933 UTC = Sun Apr 30 01:59:59 1933 HST isdst=0
/usr/share/zoneinfo/Pacific/Honolulu  Sun Apr 30 12:30:00 1933 UTC = Sun Apr 30 03:00:00 1933 HDT isdst=1
/usr/share/zoneinfo/Pacific/Honolulu  Sun May 21 21:29:59 1933 UTC = Sun May 21 11:59:59 1933 HDT isdst=1
/usr/share/zoneinfo/Pacific/Honolulu  Sun May 21 21:30:00 1933 UTC = Sun May 21 11:00:00 1933 HST isdst=0
/usr/share/zoneinfo/Pacific/Honolulu  Mon Feb  9 12:29:59 1942 UTC = Mon Feb  9 01:59:59 1942 HST isdst=0
/usr/share/zoneinfo/Pacific/Honolulu  Mon Feb  9 12:30:00 1942 UTC = Mon Feb  9 03:00:00 1942 HDT isdst=1
/usr/share/zoneinfo/Pacific/Honolulu  Sun Sep 30 11:29:59 1945 UTC = Sun Sep 30 01:59:59 1945 HDT isdst=1
/usr/share/zoneinfo/Pacific/Honolulu  Sun Sep 30 11:30:00 1945 UTC = Sun Sep 30 01:00:00 1945 HST isdst=0
/usr/share/zoneinfo/Pacific/Honolulu  Sun Jun  8 12:29:59 1947 UTC = Sun Jun  8 01:59:59 1947 HST isdst=0
/usr/share/zoneinfo/Pacific/Honolulu  Sun Jun  8 12:30:00 1947 UTC = Sun Jun  8 02:30:00 1947 HST isdst=0
/usr/share/zoneinfo/Pacific/Honolulu  Mon Jan 18 03:14:07 2038 UTC = Sun Jan 17 17:14:07 2038 HST isdst=0
/usr/share/zoneinfo/Pacific/Honolulu  Tue Jan 19 03:14:07 2038 UTC = Mon Jan 18 17:14:07 2038 HST isdst=0

There's a lot more data there! And 14 lines isn't a multiple of 5 lines, so I have really have to ask - where is it getting all this data? Does zdump query some other data source that I'm not aware of?

The strange thing is, for some zoneinfo files, the results seem more or less correct. But what's weird to me is that all the Unix timestamps I'm reporting are all in the future. Could someone who knows the tz database better than I do explain this strange behaviour?

Ben S
  • 119

1 Answers1

3

Zdump reports an extra fake "transition" at the beginning and end of the range of 32-bit time_t. This explains the 1901 and 2038 values, and why it would show 7 transitions rather than 5. It also reports time translations in pairs - one immediately before and one immediately after each transition. Therefore you get 14 rather than only 7.

Incidentally, you should be aware that zdump does not work by iterating directly over the content of the zoneinfo files, but rather by trying various time_t values with the localtime function. In this way, it works just as well with POSIX-style TZ specifiers as with actual zoneinfo files. (I also once modified it to report transitions for native Windows timezones, so it's not dependent on any zoneinfo internals at all)

The reason that all of your tool's timestamps are "in the future" is because you are misinterpreting negative values (all of Pacific/Honolulu's transitions are before 1970) as unsigned values.

Random832
  • 10,666
  • Thank you, thank you! In the tzfile man page it says that it outputs multiple times per transition, but I took this to mean four per transition, rather than two plus two more at each end. Reading your comment, everything clicked, and it all makes sense now. (And you are correct that I was reading unsigned values. Changing them to signed puts them in the right time span.)

    Please could you elaborate on your middle paragraph - how does it read the zoneinfo files, if not by iterating over them?

    – Ben S Jun 04 '15 at 10:36
  • @BenS It uses them to support the C library's implementation of e.g. tzset and localtime, the same as any other program. But my point was that it does not use the transition table in the file as a guide to what transition times to print; it searches for transition times the hard way, by trying different values with the localtime function. – Random832 Jun 04 '15 at 13:07
  • I had to come back to it, and this is the second time your answer helped me. Thanks again! – Ben S Nov 18 '15 at 00:44