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