[tz] Unable to compile Antarctica/Macquarie
Arthur David Olson
arthurdavidolson at gmail.com
Thu May 23 17:41:40 UTC 2013
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 at 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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mm.icann.org/pipermail/tz/attachments/20130523/fe361bb8/attachment.htm>
-------------- next part --------------
*** /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)
More information about the tz
mailing list