Semi-automatically detect changes in timezone abbreviations.
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 23 Mar 2013 22:47:22 +0000 (18:47 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 23 Mar 2013 23:17:44 +0000 (19:17 -0400)
Add an option to zic.c to dump out all non-obsolete timezone abbreviations
defined in the Olson database.  Comparing this list to its previous state
will clue us in when something happens that we may need to account for in
the tznames/ time zone abbreviation lists.  The README file's previous
exhortation to "just grep for differences" was completely useless advice,
in my now-considerable experience; but maybe this will be a bit more
useful.  As a starting point I built the same list from the tzdata files
as they existed in 2006, which is committed here as known_abbrevs.txt.
Comparison indeed turned up quite a few changes we had neglected to account
for, which I will commit separately.

src/timezone/.gitignore
src/timezone/Makefile
src/timezone/README
src/timezone/known_abbrevs.txt [new file with mode: 0644]
src/timezone/zic.c

index f844c9fcf19db5f02bb248c1d9240eb8900248ff..673f864b4386f3449f44938ed9156df775540d78 100644 (file)
@@ -1 +1,2 @@
 /zic
+/abbrevs.txt
index 2cecaec5e63bd9a9b759670382890f41a16ed2c2..6cfe95019b8acdec372a23fb0d9105d8515a0740 100644 (file)
@@ -55,6 +55,11 @@ ifeq (,$(with_system_tzdata))
 endif
    $(MAKE) -C tznames $@
 
+abbrevs.txt: zic $(TZDATAFILES)
+   mkdir junkdir
+   $(ZIC) -P -d junkdir -p '$(POSIXRULES)' $(TZDATAFILES) | LANG=C sort | uniq >abbrevs.txt
+   rm -rf junkdir
+
 installdirs:
    $(MKDIR_P) '$(DESTDIR)$(datadir)'
 
@@ -65,4 +70,4 @@ endif
    $(MAKE) -C tznames $@
 
 clean distclean maintainer-clean:
-   rm -f zic$(X) $(ZICOBJS)
+   rm -f zic$(X) $(ZICOBJS) abbrevs.txt
index 201b2938814d37556e0b05bfcb2f1c18e80b21ee..d09b8854a09feabcc37c386d3b9181ac7d3eec52 100644 (file)
@@ -22,11 +22,17 @@ Since time zone rules change frequently in some parts of the world,
 we should endeavor to update the data files before each PostgreSQL
 release.
 
-At each update, we should check if time zone offsets have changed.
-Just search for the current or previous year and see what has changed.
-Sometimes a country changes its time zone offsets, for example Georgia
-in 2004.  Just grepping in the zic database files for 2004 is enough to
-spot such a change.  Then the files under tznames/ should be updated.
+While the files under data/ can just be duplicated when updating, manual
+effort is needed to update the time zone abbreviation lists under tznames/.
+These need to be changed whenever new abbreviations are invented or the
+UTC offset associated with an existing abbreviation changes.  To detect
+if this has happened, after installing new files under data/ do
+   gmake abbrevs.txt
+which will produce a file showing all abbreviations that are in current
+use according to the data/ files.  Compare this to known_abbrevs.txt,
+which is the list that existed last time the tznames/ files were updated.
+Update tznames/ as seems appropriate, then replace known_abbrevs.txt
+in the same commit.
 
 When there has been a new release of Windows (probably including Service
 Packs), the list of matching timezones need to be updated. Run the
diff --git a/src/timezone/known_abbrevs.txt b/src/timezone/known_abbrevs.txt
new file mode 100644 (file)
index 0000000..d2c490b
--- /dev/null
@@ -0,0 +1,200 @@
+ACT    -18000
+ADDT   -7200   D
+ADT    -10800  D
+ADT    14400   D
+AFT    16200
+AKST   -32400
+ALMST  25200   D
+AMT    -14400
+AMT    14400
+ANAT   39600
+APT    -10800  D
+AQTT   14400
+AQTT   18000
+ART    -10800
+AST    -14400
+AST    10800
+AWT    -10800  D
+AZOT   -3600
+AZST   18000   D
+BDT    21600
+BEAT   9000
+BEAUT  9885
+BNT    28800
+BOT    -14400
+BRT    -10800
+BTT    21600
+CAST   10800   D
+CAT    7200
+CCT    23400
+CDT    -14400  D
+CDT    -18000  D
+CDT    32400   D
+CEST   7200    D
+CET    3600
+CHAST  45900
+CHOST  36000   D
+CIT    28800
+CKHST  -34200  D
+CLT    -14400
+COT    -18000
+CPT    -18000  D
+CST    -21600
+CST    28800
+CST    34200
+CVT    -3600
+CWT    -18000  D
+CXT    25200
+ChST   36000
+DAVT   25200
+DDUT   36000
+EAST   -21600
+EAT    10800
+ECT    -18000
+EDT    -14400  D
+EEST   10800   D
+EET    7200
+EGST   0   D
+EPT    -14400  D
+EST    -18000
+EST    36000
+FJT    43200
+FKT    -10800
+FNT    -7200
+GALT   -21600
+GAMT   -32400
+GEST   14400   D
+GFT    -10800
+GILT   43200
+GMT    0
+GMT+1  -3600
+GMT+10 -36000
+GMT+11 -39600
+GMT+12 -43200
+GMT+2  -7200
+GMT+3  -10800
+GMT+4  -14400
+GMT+5  -18000
+GMT+6  -21600
+GMT+7  -25200
+GMT+8  -28800
+GMT+9  -32400
+GMT-1  3600
+GMT-10 36000
+GMT-11 39600
+GMT-12 43200
+GMT-13 46800
+GMT-14 50400
+GMT-2  7200
+GMT-3  10800
+GMT-4  14400
+GMT-5  18000
+GMT-6  21600
+GMT-7  25200
+GMT-8  28800
+GMT-9  32400
+GST    -7200
+GST    14400
+GYT    -14400
+HAST   -36000
+HKT    28800
+HOVST  28800   D
+HST    -36000
+ICT    25200
+ICT    28800
+IDDT   14400   D
+IOT    21600
+IRDT   16200   D
+IRKT   25200
+IST    23400   D
+JST    32400
+KDT    36000   D
+KGST   21600   D
+KOST   43200
+KRAT   21600
+KST    28800
+LHST   39600   D
+LINT   50400
+LKT    21600
+MAGT   36000
+MART   -34200
+MAWT   21600
+MDDT   -18000  D
+MDT    -21600  D
+MET    3600
+MHT    43200
+MMT    23400
+MPT    -21600  D
+MST    -25200
+MUT    14400
+MVT    18000
+MWT    -21600  D
+MYT    28800
+NCT    39600
+NDDT   -5400   D
+NFT    41400
+NOVST  25200   D
+NPT    20700
+NRT    43200
+NUT    -39600
+NZST   43200
+OMST   18000
+ORAT   18000
+PET    -18000
+PETT   39600
+PGT    36000
+PHOT   46800
+PKT    18000
+PMDT   -7200   D
+PONT   39600
+PPT    -25200  D
+PST    -28800
+PWT    -25200  D
+PWT    32400
+PYST   -10800  D
+QYZT   21600
+RET    14400
+ROTT   -10800
+SAKT   36000
+SAMT   14400
+SAST   10800   D
+SAST   7200
+SBT    39600
+SCT    14400
+SGT    28800
+SRT    -10800
+SST    -39600
+SYOT   10800
+TAHT   -36000
+TFT    18000
+TJT    18000
+TKT    -36000
+TMT    18000
+TOST   50400   D
+TRUT   36000
+TVT    43200
+UCT    0
+ULAST  32400   D
+UTC    0
+UYHST  -9000   D
+UZT    18000
+VET    -14400
+VLAST  32400
+VOST   21600
+VUT    39600
+WAKT   43200
+WARST  -10800  D
+WART   -14400
+WAST   7200    D
+WAT    -3600
+WAT    0
+WAT    3600
+WEST   3600    D
+WET    0
+WFT    43200
+WGST   -7200   D
+WIT    25200
+WST    -39600
+WST    28800
+YAKT   28800
+YEKT   18000
index 0aa90ebfca1b25ad2100f4856ed635fe8aea9792..2c34b874e3c730f9822df95854d696dc183d31cd 100644 (file)
@@ -181,6 +181,8 @@ static int  max_year;
 static zic_t min_time;
 static int min_year;
 static int noise;
+static int print_abbrevs;
+static zic_t print_cutoff;
 static const char *rfilename;
 static int rlinenum;
 static const char *progname;
@@ -457,7 +459,7 @@ static void
 usage(FILE *stream, int status)
 {
    (void) fprintf(stream, _("%s: usage is %s \
-[ --version ] [ --help ] [ -v ] [ -l localtime ] [ -p posixrules ] \\\n\
+[ --version ] [ --help ] [ -v ] [ -P ] [ -l localtime ] [ -p posixrules ] \\\n\
 \t[ -d directory ] [ -L leapseconds ] [ -y yearistype ] [ filename ... ]\n\
 \n\
 Report bugs to tz@elsie.nci.nih.gov.\n"),
@@ -498,7 +500,7 @@ main(int argc, char *argv[])
        {
            usage(stdout, EXIT_SUCCESS);
        }
-   while ((c = getopt(argc, argv, "d:l:p:L:vsy:")) != EOF && c != -1)
+   while ((c = getopt(argc, argv, "d:l:p:L:vPsy:")) != EOF && c != -1)
        switch (c)
        {
            default:
@@ -561,6 +563,10 @@ main(int argc, char *argv[])
            case 'v':
                noise = TRUE;
                break;
+           case 'P':
+               print_abbrevs = TRUE;
+               print_cutoff = time(NULL);
+               break;
            case 's':
                (void) printf("%s: -s ignored\n", progname);
                break;
@@ -1780,6 +1786,21 @@ writezone(const char *name, const char *string)
                puttzcode(gmtoffs[i], fp);
                (void) putc(isdsts[i], fp);
                (void) putc((unsigned char) indmap[abbrinds[i]], fp);
+
+               /* Print current timezone abbreviations if requested */
+               if (print_abbrevs && pass == 2 &&
+                   (ats[i] >= print_cutoff || i == typecnt - 1))
+               {
+                   char *thisabbrev = &thischars[indmap[abbrinds[i]]];
+
+                   /* filter out assorted junk entries */
+                   if (strcmp(thisabbrev, GRANDPARENTED) != 0 &&
+                       strcmp(thisabbrev, "zzz") != 0)
+                       fprintf(stdout, "%s\t%ld%s\n",
+                               thisabbrev,
+                               gmtoffs[i],
+                               isdsts[i] ? "\tD" : "");
+               }
            }
        if (thischarcnt != 0)
            (void) fwrite((void *) thischars,