Add script to enumerate the timezones in the Windows registry and compare

it with the list we have in pgtz.c, showing any differences.
This commit is contained in:
Magnus Hagander 2010-04-15 11:00:45 +00:00
parent 7a7663f61a
commit 17056e054e
3 changed files with 144 additions and 2 deletions

View 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.

View 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.

134
src/tools/win32tzlist.pl Executable file
View File

@ -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;
}