From 17056e054ece2ce5f19d9bee63a0b415b04cb1ae Mon Sep 17 00:00:00 2001 From: Magnus Hagander Date: Thu, 15 Apr 2010 11:00:45 +0000 Subject: [PATCH] Add script to enumerate the timezones in the Windows registry and compare it with the list we have in pgtz.c, showing any differences. --- src/timezone/README | 9 ++- src/tools/RELEASE_CHANGES | 3 +- src/tools/win32tzlist.pl | 134 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 144 insertions(+), 2 deletions(-) create mode 100755 src/tools/win32tzlist.pl diff --git a/src/timezone/README b/src/timezone/README index a4ba7053c4..4372ce542b 100644 --- a/src/timezone/README +++ b/src/timezone/README @@ -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. diff --git a/src/tools/RELEASE_CHANGES b/src/tools/RELEASE_CHANGES index 1e1bbe8573..47fa03af93 100644 --- a/src/tools/RELEASE_CHANGES +++ b/src/tools/RELEASE_CHANGES @@ -12,7 +12,8 @@ For All Releases (major, minor, beta, RC) o add SGML markup o check if 'gmake HISTORY.html' works for 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 index 0000000000..083cc08850 --- /dev/null +++ b/src/tools/win32tzlist.pl @@ -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,'; +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; +}