Unable to compile Antarctica/Macquarie
I'm compiling the TZ database using the using the `zic` from the source distributed with the database checked out from GitHub. I'm using the commit that relates to the `tz2013c` release. I'm not able to get an Australian EST timezone offset for dates before October 1916 for Antarctica/Macquarie. I'm using both Ruby 1.9.3p392 and GNU date 8.15. When I compile the TZ database at commit 188b29d966; "Fix times of habitation for Macquarie to agree with Tasmania history" I get the unhabited offset and abbreviation. % TZ="$PWD/build/zoneinfo/Antarctica/Macquarie" date -d "1916/09/30 16:00 UTC" Sun Oct 1 03:00:00 EST 1916 % TZ="$PWD/build/zoneinfo/Antarctica/Macquarie" date -d "1916/09/30 15:59 UTC" Sat Sep 30 15:59:00 zzz 1916 When I compile the TZ database at commit a676f5ad3b; "Macquarie Island is politically part of Australia, not Antarctica" I get the correct offset and abbreviation. % TZ="$PWD/build/zoneinfo/Antarctica/Macquarie" date -d "1916/09/30 16:00 UTC" Sun Oct 1 03:00:00 EST 1916 % TZ="$PWD/build/zoneinfo/Antarctica/Macquarie" date -d "1916/09/30 15:59 UTC" Sun Oct 1 01:59:00 EST 1916 Using this commit, if I change the date of the first line of the Zone from "1899 Nov" back to "1911", it starts to work again. Here is the change set that causes the confusion. https://github.com/eggert/tz/commit/188b29d9664cfcf0384e515c69f94a2dfc27c673 I am on a 32-bit system but in my experience, I'm always able to get a correct timezone offset for dates in 1916 regardless of whether or not the zone begins before the range of a 32-bit POSIX time. -- Alan Gutierrez ~ @bigeasy
I've duplicated the problem. Real fixing involves zic.c (to change the output produced for Macquarie) and to localtime.c (to correctly handle existing binary files). A workaround is to change the Macquarie line that reads... 10:00 Aus EST 1919 Apr ...to read... 10:00 Aus EST 1919 Apr 1 0:00s ...and this change should probably be made to australasia for the benefit of folks who pick up the data files but not the code files. (There might also be a comment about it being a workaround.) --ado On Wed, May 22, 2013 at 10:21 PM, Alan Gutierrez <alan@prettyrobots.com>wrote:
I'm compiling the TZ database using the using the `zic` from the source distributed with the database checked out from GitHub. I'm using the commit that relates to the `tz2013c` release. I'm not able to get an Australian EST timezone offset for dates before October 1916 for Antarctica/Macquarie.
I'm using both Ruby 1.9.3p392 and GNU date 8.15.
When I compile the TZ database at commit 188b29d966; "Fix times of habitation for Macquarie to agree with Tasmania history" I get the unhabited offset and abbreviation.
% TZ="$PWD/build/zoneinfo/**Antarctica/Macquarie" date -d "1916/09/30 16:00 UTC" Sun Oct 1 03:00:00 EST 1916 % TZ="$PWD/build/zoneinfo/**Antarctica/Macquarie" date -d "1916/09/30 15:59 UTC" Sat Sep 30 15:59:00 zzz 1916
When I compile the TZ database at commit a676f5ad3b; "Macquarie Island is politically part of Australia, not Antarctica" I get the correct offset and abbreviation.
% TZ="$PWD/build/zoneinfo/**Antarctica/Macquarie" date -d "1916/09/30 16:00 UTC" Sun Oct 1 03:00:00 EST 1916 % TZ="$PWD/build/zoneinfo/**Antarctica/Macquarie" date -d "1916/09/30 15:59 UTC" Sun Oct 1 01:59:00 EST 1916
Using this commit, if I change the date of the first line of the Zone from "1899 Nov" back to "1911", it starts to work again. Here is the change set that causes the confusion.
https://github.com/eggert/tz/**commit/**188b29d9664cfcf0384e515c69f94a** 2dfc27c673<https://github.com/eggert/tz/commit/188b29d9664cfcf0384e515c69f94a2dfc27c673>
I am on a 32-bit system but in my experience, I'm always able to get a correct timezone offset for dates in 1916 regardless of whether or not the zone begins before the range of a 32-bit POSIX time.
-- Alan Gutierrez ~ @bigeasy
Here are possible changes to australasia, localtime.c, and zic.c to deal with Macquarie. Below, "current" means what's in tzcode2013c and tzdata2013c (and the results of a "make" on those files). australasia is changed so that if it's run through current (and earlier) versions of zic they'll produce a binary file that give correct results when processed by current (and earlier) versions of localtime.c localtime.c is changed to give correct results when processing the current binary Antarctica/Macquarie file. I've compiled zdump using this version of localtime.c and done a "zdump -v" on all the binary files produced by default, using the command cd /top/of/zoneinfo/binary/tree ; zdump -v `find * -type f -print` and compared the results with those produced by compiling zdump with the current localtime.c; other than for pre-1916 Macquarie times, all results are the same. zic.c is changed so that it produces a binary file from the current australasia that the current localtime.c handles correctly. The changes are bulkier than strictly necessary so that the only change to output is for the Antarctica/Macquarie file; I've done the relevant "diff -r" to verify that no other binary output changes. (Basically, the zic changes arrange for Macquarie's "EST" type to appear first in the 32-bit portion of the binary output; since the current localtime uses the first standard-time type for early times, the reordering induces correct behavior.) (The unique-in-the-existing-data aspect of Macquarie: it was "zzz" before 1899, which falls outside the 32-bit time_t window, and re-entered "zzz" in 1948 which is within that's within the 32-bit window.) diff output is attached and also appear below (with tabs manged). A long-term possibility is to change zic to always output pseudo-transition-time data for the lowest possible time_t value; since doing that would change every binary file I did avoided that approach today. And...all this was done in a 32-bit environment; regression testing in a 64-bit environment is prudent. @dashdashado *** /tmp/,aaustralasia 2013-05-23 19:44:48.910652000 +0300 --- /tmp/,baustralasia 2013-05-23 19:44:49.097852300 +0300 *************** *** 230,239 **** # - Macquarie Island will stay on UTC+11 for winter and therefore not # switch back from daylight savings time when other parts of Australia do # on 4 April. Zone Antarctica/Macquarie 0 - zzz 1899 Nov 10:00 - EST 1916 Oct 1 2:00 10:00 1:00 EST 1917 Feb ! 10:00 Aus EST 1919 Apr 0 - zzz 1948 Mar 25 10:00 Aus EST 1967 10:00 AT EST 2010 Apr 4 3:00 --- 230,245 ---- # - Macquarie Island will stay on UTC+11 for winter and therefore not # switch back from daylight savings time when other parts of Australia do # on 4 April. + # + # From Arthur David Olson (2013-05-23): + # The 1919 transition is overspecified below so pre-2013 zics + # will produce a binary file with an EST-type as the first 32-bit type; + # this is required for correct handling of times before 1916 by + # pre-2013 versions of localtime. Zone Antarctica/Macquarie 0 - zzz 1899 Nov 10:00 - EST 1916 Oct 1 2:00 10:00 1:00 EST 1917 Feb ! 10:00 Aus EST 1919 Apr 1 0:00s 0 - zzz 1948 Mar 25 10:00 Aus EST 1967 10:00 AT EST 2010 Apr 4 3:00 *** /tmp/,alocaltime.c 2013-05-23 19:44:49.285052600 +0300 --- /tmp/,blocaltime.c 2013-05-23 19:44:49.363052800 +0300 *************** *** 112,117 **** --- 112,118 ---- char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt), (2 * (MY_TZNAME_MAX + 1)))]; struct lsinfo lsis[TZ_MAX_LEAPS]; + int defaulttype; /* for early times or if no transitions */ }; struct rule { *************** *** 582,587 **** --- 583,622 ---- break; } } + /* + ** If type 0 is is unused in transitions, + ** it's the type to use for early times. + */ + for (i = 0; i < sp->typecnt; ++i) + if (sp->types[i] == 0) + break; + i = (i >= sp->typecnt) ? 0 : -1; + /* + ** Absent the above, + ** if there are transition times + ** and the first transition is to a daylight time + ** find the standard type less than and closest to + ** the type of the first transition. + */ + if (i < 0 && sp->timecnt > 0 && sp->ttis[sp->types[0]].tt_isdst) { + i = sp->types[0]; + while (--i >= 0) + if (!sp->ttis[i].tt_isdst) + break; + } + /* + ** If no result yet, find the first standard type. + ** If there is none, punt to type zero. + */ + if (i < 0) { + i = 0; + while (sp->ttis[i].tt_isdst) + if (++i >= sp->typecnt) { + i = 0; + break; + } + } + sp->defaulttype = i; #ifdef ALL_STATE free(up); #endif /* defined ALL_STATE */ *************** *** 1283,1294 **** return result; } if (sp->timecnt == 0 || t < sp->ats[0]) { ! i = 0; ! while (sp->ttis[i].tt_isdst) ! if (++i >= sp->typecnt) { ! i = 0; ! break; ! } } else { register int lo = 1; register int hi = sp->timecnt; --- 1318,1324 ---- return result; } if (sp->timecnt == 0 || t < sp->ats[0]) { ! i = sp->defaulttype; } else { register int lo = 1; register int hi = sp->timecnt; *** /tmp/,azic.c 2013-05-23 19:44:49.550253100 +0300 --- /tmp/,bzic.c 2013-05-23 19:44:49.643853300 +0300 *************** *** 1414,1421 **** fromi = 0; while (fromi < timecnt && attypes[fromi].at < min_time) ++fromi; ! if (isdsts[0] == 0) ! while (fromi < timecnt && attypes[fromi].type == 0) ++fromi; /* handled by default rule */ for ( ; fromi < timecnt; ++fromi) { if (toi != 0 && ((attypes[fromi].at + --- 1414,1424 ---- fromi = 0; while (fromi < timecnt && attypes[fromi].at < min_time) ++fromi; ! /* ! ** Remember that type 0 is reserved. ! */ ! if (isdsts[1] == 0) ! while (fromi < timecnt && attypes[fromi].type == 1) ++fromi; /* handled by default rule */ for ( ; fromi < timecnt; ++fromi) { if (toi != 0 && ((attypes[fromi].at + *************** *** 1517,1523 **** } thistimelim = thistimei + thistimecnt; thisleaplim = thisleapi + thisleapcnt; ! for (i = 0; i < typecnt; ++i) writetype[i] = thistimecnt == timecnt; if (thistimecnt == 0) { /* --- 1520,1530 ---- } thistimelim = thistimei + thistimecnt; thisleaplim = thisleapi + thisleapcnt; ! /* ! ** Remember that type 0 is reserved. ! */ ! writetype[0] = FALSE; ! for (i = 1; i < typecnt; ++i) writetype[i] = thistimecnt == timecnt; if (thistimecnt == 0) { /* *************** *** 1533,1540 **** /* ** For America/Godthab and Antarctica/Palmer */ if (thistimei == 0) ! writetype[0] = TRUE; } #ifndef LEAVE_SOME_PRE_2011_SYSTEMS_IN_THE_LURCH /* --- 1540,1550 ---- /* ** For America/Godthab and Antarctica/Palmer */ + /* + ** Remember that type 0 is reserved. + */ if (thistimei == 0) ! writetype[1] = TRUE; } #ifndef LEAVE_SOME_PRE_2011_SYSTEMS_IN_THE_LURCH /* *************** *** 1584,1591 **** } #endif /* !defined LEAVE_SOME_PRE_2011_SYSTEMS_IN_THE_LURCH */ thistypecnt = 0; for (i = 0; i < typecnt; ++i) ! typemap[i] = writetype[i] ? thistypecnt++ : -1; for (i = 0; i < sizeof indmap / sizeof indmap[0]; ++i) indmap[i] = -1; thischarcnt = 0; --- 1594,1619 ---- } #endif /* !defined LEAVE_SOME_PRE_2011_SYSTEMS_IN_THE_LURCH */ thistypecnt = 0; + /* + ** Potentially, set type 0 to that of lowest-valued time. + */ + if (thistimei > 0) { + for (i = 1; i < typecnt; ++i) + if (writetype[i] && !isdsts[i]) + break; + if (i != types[thistimei - 1]) { + i = types[thistimei - 1]; + gmtoffs[0] = gmtoffs[i]; + isdsts[0] = isdsts[i]; + ttisstds[0] = ttisstds[i]; + ttisgmts[0] = ttisgmts[i]; + abbrinds[0] = abbrinds[i]; + writetype[0] = TRUE; + writetype[i] = FALSE; + } + } for (i = 0; i < typecnt; ++i) ! typemap[i] = writetype[i] ? thistypecnt++ : 0; for (i = 0; i < sizeof indmap / sizeof indmap[0]; ++i) indmap[i] = -1; thischarcnt = 0; *************** *** 1942,1947 **** --- 1970,1980 ---- updateminmax(leapminyear); updateminmax(leapmaxyear + (leapmaxyear < INT_MAX)); } + /* + ** Reserve type 0. + */ + gmtoffs[0] = isdsts[0] = ttisstds[0] = ttisgmts[0] = abbrinds[0] = -1; + typecnt = 1; for (i = 0; i < zonecount; ++i) { zp = &zpfirst[i]; if (i < zonecount - 1) On Wed, May 22, 2013 at 10:21 PM, Alan Gutierrez <alan@prettyrobots.com>wrote:
I'm compiling the TZ database using the using the `zic` from the source distributed with the database checked out from GitHub. I'm using the commit that relates to the `tz2013c` release. I'm not able to get an Australian EST timezone offset for dates before October 1916 for Antarctica/Macquarie.
I'm using both Ruby 1.9.3p392 and GNU date 8.15.
When I compile the TZ database at commit 188b29d966; "Fix times of habitation for Macquarie to agree with Tasmania history" I get the unhabited offset and abbreviation.
% TZ="$PWD/build/zoneinfo/**Antarctica/Macquarie" date -d "1916/09/30 16:00 UTC" Sun Oct 1 03:00:00 EST 1916 % TZ="$PWD/build/zoneinfo/**Antarctica/Macquarie" date -d "1916/09/30 15:59 UTC" Sat Sep 30 15:59:00 zzz 1916
When I compile the TZ database at commit a676f5ad3b; "Macquarie Island is politically part of Australia, not Antarctica" I get the correct offset and abbreviation.
% TZ="$PWD/build/zoneinfo/**Antarctica/Macquarie" date -d "1916/09/30 16:00 UTC" Sun Oct 1 03:00:00 EST 1916 % TZ="$PWD/build/zoneinfo/**Antarctica/Macquarie" date -d "1916/09/30 15:59 UTC" Sun Oct 1 01:59:00 EST 1916
Using this commit, if I change the date of the first line of the Zone from "1899 Nov" back to "1911", it starts to work again. Here is the change set that causes the confusion.
https://github.com/eggert/tz/**commit/**188b29d9664cfcf0384e515c69f94a** 2dfc27c673<https://github.com/eggert/tz/commit/188b29d9664cfcf0384e515c69f94a2dfc27c673>
I am on a 32-bit system but in my experience, I'm always able to get a correct timezone offset for dates in 1916 regardless of whether or not the zone begins before the range of a 32-bit POSIX time.
-- Alan Gutierrez ~ @bigeasy
Wow, that's *really* backwards compatible: it changes each of three files to do the right thing if it is used with older versions of the other two. I tried it on a 64-bit platform (Fedora 17 x86-64) and it worked just fine, so I pushed it to github as <https://github.com/eggert/tz/commit/fada9b7b05339d848f6fcacb4a1c4fd51b49ec7d>. This includes one minor further change of tabs to spaces to get a source-code line to fit in 80 characters. Thanks!
participants (3)
-
Alan Gutierrez -
Arthur David Olson -
Paul Eggert