Commit 17056e05 authored by Magnus Hagander's avatar Magnus Hagander

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

it with the list we have in pgtz.c, showing any differences.
parent 7a7663f6
$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.
......@@ -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.
......
#################################################################
#
# 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment