]> granicus.if.org Git - postgresql/commitdiff
Add script to enumerate the timezones in the Windows registry and compare
authorMagnus Hagander <magnus@hagander.net>
Thu, 15 Apr 2010 11:00:45 +0000 (11:00 +0000)
committerMagnus Hagander <magnus@hagander.net>
Thu, 15 Apr 2010 11:00:45 +0000 (11:00 +0000)
it with the list we have in pgtz.c, showing any differences.

src/timezone/README
src/tools/RELEASE_CHANGES
src/tools/win32tzlist.pl [new file with mode: 0755]

index a4ba7053c4eef8d3e6d36dc4911a730f134bc116..4372ce542b8bd5e210d93b8a89264f434fe3a683 100644 (file)
@@ -1,4 +1,4 @@
-$PostgreSQL: pgsql/src/timezone/README,v 1.8 2010/03/11 18:43:24 tgl Exp $
+$PostgreSQL: pgsql/src/timezone/README,v 1.9 2010/04/15 11:00:45 mha Exp $
 
 Timezone
 ========
@@ -24,3 +24,10 @@ 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.
+
+When there has been a new release of Windows (probably including Service
+Packs), the list of matching timezones need to be updated. Run the
+script in src/tools/win32tzlist.pl on a Windows machine running this new
+release and apply any new timezones that it detects. Never remove any
+mappings in case they are removed in Windows, since we still need to
+match properly on the old version.
index 1e1bbe8573808e88ce1d16286bdcbab9811f3186..47fa03af93dd15180af13fc5ea380d6be6ec7a6c 100644 (file)
@@ -12,7 +12,8 @@ For All Releases (major, minor, beta, RC)
        o add SGML markup
        o check if 'gmake HISTORY.html' works for <link>s
 
-* Update timezone data to match latest zic database (see src/timezone/README)
+* Update timezone data to match latest zic database and new
+  Windows releases, if any (see src/timezone/README)
 
 * Translation updates
        Translations are kept in the project "pgtranslation" on PgFoundry.
diff --git a/src/tools/win32tzlist.pl b/src/tools/win32tzlist.pl
new file mode 100755 (executable)
index 0000000..083cc08
--- /dev/null
@@ -0,0 +1,134 @@
+#################################################################
+#
+# win32tzlist.pl -- compare Windows timezone information
+#
+# Copyright (c) 2008-2010, PostgreSQL Global Development Group
+#
+# $PostgreSQL: pgsql/src/tools/win32tzlist.pl,v 1.1 2010/04/15 11:00:45 mha Exp $
+#################################################################
+
+#
+# This script compares the timezone information in the Windows
+# registry with that in pgtz.c. A list of changes will be written
+# to stdout - no attempt is made to automatically edit the file.
+#
+# Run the script from the src/timezone directory.
+#
+
+use strict;
+use warnings;
+
+use Win32::Registry;
+
+#
+# Fetch all timezones in the registry
+#
+my $basekey;
+$HKEY_LOCAL_MACHINE->Open("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones", $basekey)
+  or die $!;
+
+my @subkeys;
+$basekey->GetKeys(\@subkeys);
+
+my @system_zones;
+
+foreach my $keyname (@subkeys)
+{
+    my $subkey;
+    my %vals;
+
+    $basekey->Open($keyname, $subkey) or die $!;
+    $subkey->GetValues(\%vals) or die $!;
+    $subkey->Close();
+
+    die "Incomplete timezone data for $keyname!\n"
+      unless ($vals{Std} && $vals{Dlt} && $vals{Display});
+    push @system_zones,
+      {
+        'std'=>$vals{Std}->[2],
+        'dlt'=>$vals{Dlt}->[2],
+        'display'=>clean_displayname($vals{Display}->[2]),
+      };
+}
+
+$basekey->Close();
+
+#
+# Fetch all timezones currently in the file
+#
+my @file_zones;
+open(PGTZ,'<pgtz.c') or die "Could not open pgtz.c!\n";
+my $t = $/;
+undef $/;
+my $pgtz = <PGTZ>;
+close(PGTZ);
+$/ = $t;
+
+# Attempt to locate and extract the complete win32_tzmap struct
+$pgtz =~ /win32_tzmap\[\] =\s+{\s+\/\*[^\/]+\*\/\s+(.+?)};/gs
+  or die "Could not locate struct win32_tzmap in pgtz.c!";
+$pgtz = $1;
+
+# Extract each individual record from the struct
+while ($pgtz =~ m/{\s+"([^"]+)",\s+"([^"]+)",\s+"([^"]+)",?\s+},\s+\/\*(.+?)\*\//gs)
+{
+    push @file_zones,
+      {
+        'std'=>$1,
+        'dlt'=>$2,
+        'match'=>$3,
+        'display'=>clean_displayname($4),
+      };
+}
+
+#
+# Look for anything that has changed
+#
+my @add;
+
+for my $sys (@system_zones)
+{
+    my $match = 0;
+    for my $file (@file_zones)
+    {
+        if ($sys->{std} eq $file->{std})
+        {
+            $match=1;
+            if ($sys->{dlt} ne $file->{dlt})
+            {
+                print "Timezone $sys->{std}, changed name of daylight zone!\n";
+            }
+            if ($sys->{display} ne $file->{display})
+            {
+                print
+"Timezone $sys->{std} changed displayname ('$sys->{display}' from '$file->{display}')!\n";
+            }
+            last;
+        }
+    }
+    unless ($match)
+    {
+        push @add, $sys;
+    }
+}
+
+if (@add)
+{
+    print "\n\nOther than that, add the following timezones:\n";
+    for my $z (@add)
+    {
+        print
+"\t{\n\t\t\"$z->{std}\", \"$z->{dlt}\",\n\t\t\"FIXME\"\n\t},\t\t\t\t\t\t\t/* $z->{display} */\n";
+    }
+}
+
+sub clean_displayname
+{
+    my $dn = shift;
+
+    $dn =~ s/\s+/ /gs;
+    $dn =~ s/\*//gs;
+    $dn =~ s/^\s+//gs;
+    $dn =~ s/\s+$//gs;
+    return $dn;
+}