tznext 64-bit timezones - Comments
Olson, Arthur David (NIH/NCI)
olsona at dc37a.nci.nih.gov
Tue Sep 27 21:22:17 UTC 2005
> Invoking zdump -v...showed many timezones with behavior differences in the
early transitions. For example Africa/Addis_Ababa and US/Pacific:
Good catch! This happens because, when dealing with instants before the
first transition time recorded in a time zone file, "localtime" assumes that
the time type to use is the first type that's a "standard time" type. When
we're running on a 64-bit system we can deal with instants prior to 1901,
but we want to ignore such information when writing the 32-bit portion of
the data file to avoid having localtime make the wrong assumption.
I've attached a change to the "experimental" version of zic.c (sent around
in June on the time zone mailing list) that should address the problem.
Note that we end up with very slightly smaller time zone binary files with
the change in place.
> It might be nice to add an option to zdump to print out the POSIX TZ
equivalent for the timezone.
Nice yes; not so straightforward. Recall that zdump (very deliberately)
knows nothing about the format of time zone data files; it simply makes
repeated calls to localtime, looks for unexpected shifts in the return
values, and prints information about the instants at which shifts occur.
With the "experimental" time zone data files, it is possible to use a script
such as...
#! /bin/sh
ZONEINFODIR=$HOME/src/tzexp2/tmp/etc/zoneinfo
for file in `find $ZONEINFODIR -type f -print`
do
tail -1 $file | sed "s@^@$file: @"
done
...to print the equivalents.
--ado
------- zic.c -------
*** /tmp/geta7744 Tue Sep 27 16:52:10 2005
--- /tmp/getb7744 Tue Sep 27 16:52:10 2005
***************
*** 1,4 ****
! static char elsieid[] = "@(#)zic.c 7.149";
#include "private.h"
#include "locale.h"
--- 1,4 ----
! static char elsieid[] = "@(#)zic.c 7.150";
#include "private.h"
#include "locale.h"
***************
*** 1584,1589 ****
--- 1584,1592 ----
register int thistimei, thistimecnt;
register int thisleapi, thisleapcnt;
register int thistimelim, thisleaplim;
+ int writetype[TZ_MAX_TIMES];
+ int typemap[TZ_MAX_TYPES];
+ register int thistypecnt;
if (pass == 1) {
thistimei = timei32;
***************
*** 1598,1613 ****
}
thistimelim = thistimei + thistimecnt;
thisleaplim = thisleapi + thisleapcnt;
#define DO(field) (void) fwrite((void *) tzh.field, \
(size_t) sizeof tzh.field, (size_t) 1, fp)
tzh = tzh0;
(void) strncpy(tzh.tzh_magic, TZ_MAGIC, sizeof
tzh.tzh_magic);
tzh.tzh_version[0] = ZIC_VERSION;
! convert(eitol(typecnt), tzh.tzh_ttisgmtcnt);
! convert(eitol(typecnt), tzh.tzh_ttisstdcnt);
convert(eitol(thisleapcnt), tzh.tzh_leapcnt);
convert(eitol(thistimecnt), tzh.tzh_timecnt);
! convert(eitol(typecnt), tzh.tzh_typecnt);
convert(eitol(charcnt), tzh.tzh_charcnt);
DO(tzh_magic);
DO(tzh_version);
--- 1601,1624 ----
}
thistimelim = thistimei + thistimecnt;
thisleaplim = thisleapi + thisleapcnt;
+ for (i = 0; i < typecnt; ++i)
+ writetype[i] = FALSE;
+ for (i = thistimei - 1; i < thistimelim; ++i)
+ if (i >= 0)
+ writetype[types[i]] = TRUE;
+ thistypecnt = 0;
+ for (i = 0; i < typecnt; ++i)
+ typemap[i] = writetype[i] ? thistypecnt++ : -1;
#define DO(field) (void) fwrite((void *) tzh.field, \
(size_t) sizeof tzh.field, (size_t) 1, fp)
tzh = tzh0;
(void) strncpy(tzh.tzh_magic, TZ_MAGIC, sizeof
tzh.tzh_magic);
tzh.tzh_version[0] = ZIC_VERSION;
! convert(eitol(thistypecnt), tzh.tzh_ttisgmtcnt);
! convert(eitol(thistypecnt), tzh.tzh_ttisstdcnt);
convert(eitol(thisleapcnt), tzh.tzh_leapcnt);
convert(eitol(thistimecnt), tzh.tzh_timecnt);
! convert(eitol(thistypecnt), tzh.tzh_typecnt);
convert(eitol(charcnt), tzh.tzh_charcnt);
DO(tzh_magic);
DO(tzh_version);
***************
*** 1623,1638 ****
if (pass == 1)
puttzcode((long) ats[i], fp);
else puttzcode64(ats[i], fp);
! if (thistimecnt > 0)
! (void) fwrite((void *) &types[thistimei],
! (size_t) sizeof types[0],
! (size_t) thistimecnt,
fp);
- for (i = 0; i < typecnt; ++i) {
- puttzcode(gmtoffs[i], fp);
- (void) putc(isdsts[i], fp);
- (void) putc(abbrinds[i], fp);
}
if (charcnt != 0)
(void) fwrite((void *) chars, (size_t) sizeof
chars[0],
(size_t) charcnt, fp);
--- 1634,1654 ----
if (pass == 1)
puttzcode((long) ats[i], fp);
else puttzcode64(ats[i], fp);
! for (i = thistimei; i < thistimelim; ++i) {
! unsigned char uc;
!
! uc = typemap[types[thistimei]];
! (void) fwrite((void *) &uc,
! (size_t) sizeof uc,
! (size_t) 1,
fp);
}
+ for (i = 0; i < typecnt; ++i)
+ if (writetype[i]) {
+ puttzcode(gmtoffs[i], fp);
+ (void) putc(isdsts[i], fp);
+ (void) putc(abbrinds[i], fp);
+ }
if (charcnt != 0)
(void) fwrite((void *) chars, (size_t) sizeof
chars[0],
(size_t) charcnt, fp);
***************
*** 1662,1670 ****
puttzcode(corr[i], fp);
}
for (i = 0; i < typecnt; ++i)
! (void) putc(ttisstds[i], fp);
for (i = 0; i < typecnt; ++i)
! (void) putc(ttisgmts[i], fp);
}
(void) fprintf(fp, "\n%s\n", string);
if (ferror(fp) || fclose(fp)) {
--- 1678,1688 ----
puttzcode(corr[i], fp);
}
for (i = 0; i < typecnt; ++i)
! if (writetype[i])
! (void) putc(ttisstds[i], fp);
for (i = 0; i < typecnt; ++i)
! if (writetype[i])
! (void) putc(ttisgmts[i], fp);
}
(void) fprintf(fp, "\n%s\n", string);
if (ferror(fp) || fclose(fp)) {
More information about the tz
mailing list