[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