FW: zdump /zoneinfo question

John Reynolds is not on the time zone mailing list; be sure to direct any replies to John. --ado -----Original Message----- From: Reynolds, John [SMTP:John.Reynolds@sciatl.com] Sent: Friday, November 19, 1999 4:16 PM To: 'tz@elsie.nci.nih.gov' Subject: zdump /zoneinfo question Hello, Please excuse the intrusion. I found this email address in some documents I downloaded from elsie.nci.nih.gov. I'm looking for some information or perhaps an online reference that can help me relate the output from the zdump utility to the changes for daylight savings for a particulat timezone. I've read the zic, zdump, ctime and localtime man pages. The zic manpage explains the format of the tz data files I found your name in. The output of zdump tells me when there is a change in the rules for a timezone but it doesn't seem to tell me what the rules are. In other words, given a particular zoneinfo file, how can I determine the zone and rules that were used to create it? My reason for asking is, how can I tell if the curent zoneinfo file is accurate given that governments can change the rules at any time. I've tried some experiments creating my own zoneinfo files then using zdump to display information about it but I see no way of determining the rules. Thanks for any help! John Reynolds john.reynolds@sciatl.com

From: Reynolds, John [SMTP:John.Reynolds@sciatl.com] Sent: Friday, November 19, 1999 4:16 PM To: 'tz@elsie.nci.nih.gov' Subject: zdump /zoneinfo question
The output of zdump tells me when there is a change in the rules for a timezone but it doesn't seem to tell me what the rules are. In other words, given a particular zoneinfo file, how can I determine the zone and rules that were used to create it?
The compiled zoneinfo file which zdump is reading does not maintain a record of what file was compiled to generate it, nor does it maintain a record of the rules used to generate the transitions that it contains. Your best bet is to download the latest tzdata files from elsie, check that the rule(s) of interest is correct in the appropriate file, and install the zic'ed version of the file if it looks good, overwriting any old zoneinfo file whose rules you are questioning. --Ken Pizzini

John Reynolds wrote:
My reason for asking is, how can I tell if the curent zoneinfo file is accurate given that governments can change the rules at any time. I've tried some experiments creating my own zoneinfo files then using zdump to display information about it but I see no way of determining the rules.
This seems as good a time as any to release the "zrd" utility: it is public domain, and allows reading a binary timezone file. It is written in very portable C, and does not depend on any part of the tz library except the timezone files themselves. I developed it in order to help me interpret timezone files from Java, rather than redoing all of zic in Java. I hope it is helpful to you. If the tz tribal elders wish to make this part of the regular tz distribution (perhaps in a "contrib" directory?) I certainly have no objection. There is no readme or man page: the command line syntax is "zrd continent/city". -----------------cut here------------------------------- /* zrd - a routine to dump the contents of a binary timezone file * Define ZONEINFO to be the directory where the timezone files are, * typically "/usr/share/zoneinfo". * This program requires only stdio and "gmtime". * Public domain source by John Cowan <cowan@ccil.org> */ # define ZONEINFO "/usr/share/zoneinfo/" # include <stdio.h> # include <time.h> /* A handy routine that converts from network order * (big-endian) 32-bit values to local order. * It tests what local order is, and is not the most * efficient conceivable routine, but works OK * for this application. */ long my_ntohl(long s) { long r; char *ps; char *pr; long test = 0x01020304; if ((char *)&test == "\0x01\0x02\0x03\0x04") return s; ps = (char *) &s; pr = (char *) &r; pr[0] = ps[3]; pr[1] = ps[2]; pr[2] = ps[1]; pr[3] = ps[0]; return r; } /* The header of a timezone file. * After the header, the following objects may be found: * tzh_timecnt 32-bit values representing time transitions; * tzh_timecnt 1-byte indexes into the time type table; * the time type table, containing tzh_typecnt "struct ttinfo" elements; * the leap-second table, containing tzh_leapcnt "struct ttleap" elements; * tzh.isstdcnt 1-byte flags indicating if transitions are * based on local standard time or local current ("wall") time * tz.isgmtcnt 1-byte flags indicating if transitions are * based on UTC or local time */ struct tzhead { char tzh_magic[4]; /* magic number */ char tzh_reserved[16]; /* reserved for future use */ long tzh_ttisgmtcnt; /* coded number of trans. time flags */ long tzh_ttisstdcnt; /* coded number of trans. time flags */ long tzh_leapcnt; /* coded number of leap seconds */ long tzh_timecnt; /* coded number of transition times */ long tzh_typecnt; /* coded number of local time types */ long tzh_charcnt; /* coded number of abbr. chars */ }; /* A time type object */ struct ttinfo { long tt_gmtoff; /* offset of this time type from UTC */ char tt_isdst; /* whether this is a DST time type */ char tt_abbrind; /* index into the timezone name abbreviations */ }; /* A leap second object */ struct ttleap { long tt_time; /* The leap second */ long tt_seconds; /* New value of TAI - UTC - 10 */ }; char tzfilename[1024]; /* Filename of the timezone file */ FILE *tz; /* File stream for reading the file */ struct tzhead t; /* The file's header */ char tzdata[4096]; /* The rest of the file */ long tzsize; /* Size of tzdata in use */ /* Pointers to different parts of tzdata */ long *timep; char *timetypep; char *xtypep; struct ttinfo *typep; char *charp; struct ttleap *leapp; char *stdp; char *gmtp; main(argc, argv) int argc; char *argv[]; { int i; long gmtoff; int gmtsign; long clock; struct tm *d; char magic[5]; /* Validate command line and load header */ if (argc != 2) { fprintf(stderr, "usage: %s continent/location\n", argv[0]); exit(1); } strcpy(tzfilename, ZONEINFO); strcat(tzfilename, argv[1]); tz = fopen(tzfilename, "rb"); if (!tz) { fprintf(stderr, "%s: %s unknown\n", argv[0], argv[1]); exit(1); } fread(&t, sizeof(t), 1, tz); /* Localize values in the header */ strncpy(magic, t.tzh_magic, 4); magic[4] = 0; t.tzh_ttisgmtcnt = my_ntohl(t.tzh_ttisgmtcnt); t.tzh_ttisstdcnt = my_ntohl(t.tzh_ttisstdcnt); t.tzh_leapcnt = my_ntohl(t.tzh_leapcnt); t.tzh_typecnt = my_ntohl(t.tzh_typecnt); t.tzh_timecnt = my_ntohl(t.tzh_timecnt); t.tzh_charcnt = my_ntohl(t.tzh_charcnt); /* Read the rest of the file */ tzsize = fread(&tzdata, 1, sizeof(tzdata), tz); fclose(tz); /* Set up pointers to various sections */ timep = (long *)tzdata; timetypep = (char *)(timep + t.tzh_timecnt); xtypep = timetypep + t.tzh_timecnt; charp = xtypep + 6 * t.tzh_typecnt; /* alignment problem */ leapp = (struct ttleap *)(charp + t.tzh_charcnt); stdp = (char *)(leapp + t.tzh_leapcnt); gmtp = stdp + t.tzh_ttisstdcnt; /* Check for invalid file size */ if (tzdata + tzsize != gmtp + t.tzh_ttisgmtcnt) fprintf(stderr, "Warning: file is %ld bytes, expected %ld\n", tzsize + sizeof(t), (gmtp + t.tzh_ttisgmtcnt) - tzdata); /* Print magic number */ if (magic[0]) printf("TZ magic number is \"%s\" (normally \"TZif\")\n", magic); /* Print transition time table */ printf("%ld transition times:\n", t.tzh_timecnt); for (i = 0; i < t.tzh_timecnt; i++) { clock = my_ntohl(timep[i]); /* printf("\tat %ld use type %d\n", clock, timetypep[i]); */ d = gmtime(&clock); printf("\tat %4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d UTC (%ld) use type %d\n", d->tm_year + 1900, d->tm_mon, d->tm_mday, d->tm_hour, d->tm_min, d->tm_sec, clock, timetypep[i]); } /* Print time types table */ printf("%ld local time types:\n", t.tzh_typecnt); for (i = 0; i < t.tzh_typecnt; i++) { typep = (struct ttinfo *)(xtypep + i * 6); gmtoff = my_ntohl(typep->tt_gmtoff); if (gmtoff < 0) { gmtsign = -1; gmtoff = -gmtoff; } else if (gmtoff > 0) gmtsign = 1; else gmtsign = 0; printf("\ttype %d offset %2.2ld:%2.2ld:%2.2ld %s name (%d) %s", i, gmtsign*(gmtoff/3600), (gmtoff%3600)/60, gmtoff%60, typep->tt_isdst ? "isdst " : "notdst", typep->tt_abbrind, charp + typep->tt_abbrind); if (i < t.tzh_ttisstdcnt) printf(" %s", stdp[i] ? "std" : "wall"); if (i < t.tzh_ttisgmtcnt) printf(" %s", gmtp[i] ? "gmt" : "local"); printf("\n"); } /* Print time zone abbreviations */ printf("%ld bytes of abbreviations: [", t.tzh_charcnt); for (i = 0; i < t.tzh_charcnt; i++) if (charp[i]) putchar(charp[i]); else if (i != t.tzh_charcnt - 1) putchar('|'); printf("]\n"); /* Print leap second table */ printf("%ld leap second entries:\n", t.tzh_leapcnt); for (i = 0; i < t.tzh_leapcnt; i++) printf("\tat %ld, TAI - UTC = %ld seconds\n", my_ntohl(leapp[i].tt_time), my_ntohl(leapp[i].tt_seconds) + 10); /* Print counts of gmt/local and std/wall flags (contents * have already been printed) */ printf("%ld std/wall flags\n", t.tzh_ttisstdcnt); printf("%ld gmt/local flags\n", t.tzh_ttisgmtcnt); exit(0); } -----------------cut here------------------------------- -- John Cowan http://www.reutershealth.com jcowan@reutershealth.com Schlingt dreifach einen Kreis vom dies! / Schliess eurer Aug vor heiliger Schau Den er genoss vom Honig-Tau / Und trank die Milch vom Paradies. -- Coleridge (tr. Politzer)
participants (3)
-
John Cowan
-
Ken Pizzini
-
Olson, Arthur David (NCI)