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