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