809995b526
Reviewed-by: ihse, joehw
289 lines
7.8 KiB
Perl
289 lines
7.8 KiB
Perl
#
|
|
# Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
|
|
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
#
|
|
# This code is free software; you can redistribute it and/or modify it
|
|
# under the terms of the GNU General Public License version 2 only, as
|
|
# published by the Free Software Foundation.
|
|
#
|
|
# This code is distributed in the hope that it will be useful, but WITHOUT
|
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
# version 2 for more details (a copy is included in the LICENSE file that
|
|
# accompanied this code).
|
|
#
|
|
# You should have received a copy of the GNU General Public License version
|
|
# 2 along with this work; if not, write to the Free Software Foundation,
|
|
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
#
|
|
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
# or visit www.oracle.com if you need additional information or have any
|
|
# questions.
|
|
#
|
|
|
|
#
|
|
#
|
|
#
|
|
# Perl script to generate ZoneData from Olson public time zone data.
|
|
#
|
|
# For J2SE before JDK1.3, see ../../README how to update TimeZone.java
|
|
# static TimeZoneData.
|
|
# For J2SE since JDK1.4, this script is used to generate testdata(reference)
|
|
# for ZoneData.sh which is one of TimeZone Regression test.
|
|
|
|
$continue = 0;
|
|
|
|
# verbose flag
|
|
$verbose = 0;
|
|
|
|
# version of Olson's public zone information (e.g. "tzdata2000g")
|
|
$versionName = "unknown";
|
|
|
|
# Number of testdata files.
|
|
$count = 5;
|
|
|
|
# Display name datafile
|
|
$displayNameFile = "displaynames.txt";
|
|
|
|
# time zone IDs to be generated. If it's empty, then generate all time
|
|
# zone in the tzdata files.
|
|
@javatzids = ();
|
|
|
|
#
|
|
# Parses command-line options
|
|
#
|
|
while ($#ARGV >= 0) {
|
|
if ($ARGV[0] =~ /^-v/) {
|
|
$verbose = 1;
|
|
} elsif ($ARGV[0] =~ /^-V/) {
|
|
$versionName = $ARGV[1];
|
|
shift(@ARGV);
|
|
} else {
|
|
@javatzids = &readIDs($ARGV[0]);
|
|
last;
|
|
}
|
|
shift(@ARGV);
|
|
}
|
|
|
|
# Beginning year of testdata
|
|
($sec, $min, $hour, $mday, $mon, $year, $wday, $ydat, $isdst) = gmtime();
|
|
$baseYear = $year+1900;
|
|
|
|
if ($verbose == 1) {
|
|
print STDERR "baseYear : $baseYear\n";
|
|
print STDERR "versionName : $versionName\n";
|
|
}
|
|
|
|
# Open display name datafile
|
|
open (DNFD, ">$displayNameFile") || die ("$displayNameFile : open error.\n");
|
|
|
|
while(<STDIN>) {
|
|
chop;
|
|
if (/^\#/) { # skip comment line
|
|
next;
|
|
}
|
|
@item = ("foo");
|
|
|
|
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
|
|
if ($continue == 1) {
|
|
s/\#.*//; # chop trailing comments
|
|
s/\s+$//;
|
|
s/^\s+//;
|
|
@item = split(/\s+/, $_);
|
|
@item = ($zname, @item); # push zone name
|
|
} elsif (/^Zone/) {
|
|
s/\#.*//; # chop trailing comments
|
|
s/\s+$//;
|
|
@item = split(/\s+/, $_);
|
|
$zname = $item[1];
|
|
if (defined ($zones{$name})) {
|
|
printf STDERR "WARNING: duplicate definition of zone $name\n";
|
|
}
|
|
shift(@item);
|
|
}
|
|
if (@item[0] ne "foo") {
|
|
if($#item == 3) { # find out no UNTIL line
|
|
$item[3] =~ s/%/%%/;
|
|
$zones{$item[0]} = "Zone $item[0]\t$item[1]\t$item[2]\t$item[3]";
|
|
} else {
|
|
$continue = 1;
|
|
next;
|
|
}
|
|
}
|
|
|
|
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
|
|
if (/^Rule/) {
|
|
($rule, $name, $from, $to, $type, $in, $on, $at, $save, $letter)
|
|
= split(/\s+/, $_);
|
|
|
|
# matches specified year?
|
|
for ($i = 0; $i < $count; $i++) {
|
|
if ($from <= $baseYear+$i && ($to >= $baseYear+$i || $to eq "max")
|
|
|| ($from == $baseYear+$i && $to eq "only")) {
|
|
if ($save ne "0") {
|
|
$rules[$i]{$name . "0"} = $_;
|
|
} else {
|
|
$rules[$i]{$name . "1"} = $_;
|
|
}
|
|
} else {
|
|
if ($from <= $baseYear) {
|
|
if ($save ne "0") {
|
|
$oldRules[0]{$name} = $_;
|
|
} else {
|
|
$oldRules[1]{$name} = $_;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
$continue = 0;
|
|
}
|
|
|
|
#
|
|
# Prepare output files
|
|
#
|
|
for ($i = 0, $fd = 0; $i < $count; $i++, $fd++) {
|
|
$filename = "year".($baseYear+$i);
|
|
open ($fd, ">$filename") || die ("$filename : open error.\n");
|
|
print $fd "# Based on $versionName\n";
|
|
}
|
|
|
|
#
|
|
# If no IDs are specified, produce test data for all zones.
|
|
#
|
|
if ($#javatzids < 0) {
|
|
@javatzids = keys(%zones);
|
|
}
|
|
|
|
foreach $z (@javatzids) {
|
|
#
|
|
# skip any Riyadh zones; ZoneData.java can't handle Riyadh zones
|
|
#
|
|
# Skip these zones for CLDR
|
|
# Africa/Windhoek: Negative DST (throughout year)
|
|
# Korea zones: CLDR metazone shares Seoul/Pyongyang, where TZDB doesn't
|
|
# Adak: CLDR's short names (Hawaii_Aleutian) differ from TZDB, HAST/HADT vs. HST/HDT
|
|
#
|
|
next if ($z =~ /Riyadh|Windhoek|Seoul|Pyongyang|Adak/);
|
|
|
|
for ($i = 0, $fd = 0; $i < $count; $i++, $fd++) {
|
|
if (!defined($zones{$z})) {
|
|
printf $fd "$z ?\n";
|
|
printf STDERR "WARNING: java zone $z not found\n";
|
|
next;
|
|
}
|
|
@item = split(/\s+/, $zones{$z});
|
|
if ($item[3] ne "-") {
|
|
printf $fd "$item[1] $item[2] ";
|
|
if (defined($rules[$i]{$item[3] . "0"})
|
|
&& defined($rules[$i]{$item[3] . "1"})) {
|
|
$rule0 = $rules[$i]{$item[3] . "0"};
|
|
$rule1 = $rules[$i]{$item[3] . "1"};
|
|
@r0 = split(/\s+/, $rule0);
|
|
@r1 = split(/\s+/, $rule1);
|
|
printf $fd "$r0[5] $r0[6] $r0[7] $r1[5] $r1[6] $r1[7] $r0[8]\n";
|
|
printf $fd "$zones{$z}\n";
|
|
printf $fd "$rule0\n";
|
|
printf $fd "$rule1\n";
|
|
if ($i == 0) {
|
|
$std = $dst = $item[4];
|
|
$std =~ s/%%s/$r1[9]/;
|
|
if ($r1[9] eq "-") {
|
|
$std =~ s/-//;
|
|
}
|
|
$dst =~ s/%%s/$r0[9]/;
|
|
if ($r0[9] eq "-") {
|
|
$dst =~ s/-//;
|
|
}
|
|
if ("$std$dst" =~ /[A-Z]/) {
|
|
print DNFD "$item[1] $std $dst\n";
|
|
}
|
|
}
|
|
} else {
|
|
printf $fd "-\n"; # In case we cannot find Rule, assume no DST.
|
|
printf $fd "$zones{$z}\n";
|
|
printf STDERR "WARNING: $z no rules defined for $item[3]\n";
|
|
if ($i == 0) {
|
|
# About 30 time zones (e.g. Asia/Tokyo needs the following
|
|
# recovery.
|
|
if ($item[4] =~ m/%/) {
|
|
@r0 = split(/\s+/, $oldRules[0]{$item[3]});
|
|
@r1 = split(/\s+/, $oldRules[1]{$item[3]});
|
|
if ($i == 0) {
|
|
$std = $dst = $item[4];
|
|
$std =~ s/%%s/$r1[9]/;
|
|
if ($r1[9] eq "-") {
|
|
$std =~ s/-//;
|
|
}
|
|
$dst =~ s/%%s/$r0[9]/;
|
|
if ($r0[9] eq "-") {
|
|
$dst =~ s/-//;
|
|
}
|
|
if ("$std$dst" =~ /[A-Z]/) {
|
|
print DNFD "$item[1] $std $dst\n";
|
|
}
|
|
}
|
|
} else {
|
|
if ("$item[4]" =~ /[A-Z]/) {
|
|
print DNFD "$item[1] $item[4]\n";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
printf $fd "$item[1] $item[2] $item[3]\n";
|
|
printf $fd "$zones{$z}\n";
|
|
if ($i == 0 && "$item[4]" =~ /[A-Z]/) {
|
|
print DNFD "$item[1] $item[4]\n";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#
|
|
# Close all the output files
|
|
#
|
|
close (DNFD);
|
|
for ($i = 0, $fd = 0; $i < $count; $i++, $fd++) {
|
|
close ($fd);
|
|
}
|
|
|
|
#
|
|
# Sort the displaynames.txt file
|
|
#
|
|
open my $fh, '<', $displayNameFile || die ("Can't open $displayNameFile for sorting\n");;
|
|
chomp(my @names = <$fh>);
|
|
close $fh;
|
|
open my $fh, '>', $displayNameFile;
|
|
foreach $line (sort @names) { print $fh $line,"\n"; }
|
|
close $fh;
|
|
|
|
exit(0);
|
|
|
|
sub readIDs {
|
|
local ($file) = @_;
|
|
local (@ids, $i);
|
|
|
|
open(F, $file) || die "Fatal: can't open $file.\n";
|
|
|
|
$i = 0;
|
|
while (<F>) {
|
|
chop;
|
|
if (/^\#/) { # skip comment line
|
|
next;
|
|
}
|
|
|
|
# trim any leading and trailing space
|
|
s/^\s+//;
|
|
s/\s+$//;
|
|
|
|
if (/^\s*$/) { # skip blank line
|
|
next;
|
|
}
|
|
|
|
$ids[$i++] = $_;
|
|
}
|
|
close(F);
|
|
return @ids;
|
|
}
|