[tz] zdump no longer reports gmtoff
Phil Pennock
tz-list+phil.pennock at spodhuis.org
Thu Jan 31 04:26:16 UTC 2013
On 2013-01-30 at 20:46 +0000, Marvel, Jim (CPCOE) wrote:
> Using ubuntu 12.04 LTS
> Using tz 2012 j code/data
>
> Tested each timezone mentioned in zone.tab, by zdump-ing each one.
> Observed that each timezone had two lines that reported NULL, then a bunch of nice-looking pairs-of-lines, then two lines that reported "NULL"
>
> I understand that this could be caused if you are using a 64 bit ubuntu on a 32-bit machine....
> ...I may have !!! migrated to a 32-bit ubuntu on a 32-bit machine...
It happens on any platform where time_t is 64-bit but regular ints are
32-bit, which is what most things have settled on.
It happens, AFAICT, because gmtime()/localtime() can't handle extreme
64-bit values; it's triggered by the attempt to print the time on the
lowest time value and one day later, and one day before max time value
and max time, per the man-page.
Which is why you see these even if you enter a year range with a start
that comes after the end.
% ./zdump -c 2017,2010 -v America/New_York
America/New_York -9223372036854775808 = NULL
America/New_York -9223372036854689408 = NULL
America/New_York 9223372036854689407 = NULL
America/New_York 9223372036854775807 = NULL
The long number is from gmtime() failing, so the number is printed as
raw. Then my_localtime() is called to supply what comes after the "=";
"tmp = localtime(tp);" results in NULL from the failure, all the
decoding logic is skipped, and the NULL is returned; that's passed to
dumptime(), which detects the NULL, prints "NULL" and returns.
For the negative case, localtime.c:timesub() returns at line 1472 in
current git; with an added fprintf():
----------------------------8< cut here >8------------------------------
while (tdays < 0 || tdays >= year_lengths[isleap(y)]) {
int newy;
register time_t tdelta;
register int idelta;
register int leapdays;
tdelta = tdays / DAYSPERLYEAR;
idelta = tdelta;
if (tdelta - idelta >= 1 || idelta - tdelta >= 1) {
fprintf(stderr, "frobnozz out a tdelta=%ld idelta=%d\n", tdelta, idelta);
return NULL;
}
----------------------------8< cut here >8------------------------------
result is then:
----------------------------8< cut here >8------------------------------
frobnozz out a tdelta=-291672107014 idelta=385669114
----------------------------8< cut here >8------------------------------
The positive case is from localtime.c:localsub() returning at line 1281
in current git; with an added fprintf():
----------------------------8< cut here >8------------------------------
if (result == tmp) {
register time_t newy;
newy = tmp->tm_year;
if (t < sp->ats[0])
newy -= icycles * YEARSPERREPEAT;
else newy += icycles * YEARSPERREPEAT;
tmp->tm_year = newy;
if (tmp->tm_year != newy) {
fprintf(stderr, "frobnozz b out 4 result=%p tmp=%p tmp->tm_year=%d newy=%ld newy-as-int=%d\n",
result, tmp, tmp->tm_year, newy, newy);
return NULL;
}
}
----------------------------8< cut here >8------------------------------
result is then:
----------------------------8< cut here >8------------------------------
frobnozz b out 4 result=0x513180 tmp=0x513180 tmp->tm_year=219248568 newy=292277024696 newy-as-int=219248568
----------------------------8< cut here >8------------------------------
I'm not familiar enough with all the architecture-size testing going
around and what the correct approach for this code-base is, but I can at
least do the above and isolate where things are failing right now.
Hopefully of use to someone?
-Phil
More information about the tz
mailing list