undefect. CWE-407 — 63 sites patched across 27 ecosystems
Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com Patches, unit tests, benchmarks, whitepaper, and outreach briefs. Public domain — no copyright claimed. Use freely.
This commit is contained in:
commit
0a580b313d
70422 changed files with 17213626 additions and 0 deletions
53
test/jdk/java/util/TimeZone/AssureTzdataVersion.java
Normal file
53
test/jdk/java/util/TimeZone/AssureTzdataVersion.java
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2022, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8060126
|
||||
* @summary Make sure that the tzdata version matches between the run-time and tests.
|
||||
*/
|
||||
import java.time.zone.ZoneRules;
|
||||
import java.time.zone.ZoneRulesProvider;
|
||||
import java.util.NavigableMap;
|
||||
|
||||
public class AssureTzdataVersion {
|
||||
public static void main(String... args) throws Exception {
|
||||
// get the tzdata version for the run-time
|
||||
NavigableMap<String, ZoneRules> map;
|
||||
map = ZoneRulesProvider.getVersions("America/Los_Angeles");
|
||||
if (map.isEmpty()) {
|
||||
throw new RuntimeException("Unknown runtime tzdata version");
|
||||
}
|
||||
String runtime = map.lastEntry().getKey();
|
||||
|
||||
// get the tzdata version for regression tests
|
||||
String testdata = null;
|
||||
try (TextFileReader textreader = new TextFileReader("VERSION")) {
|
||||
testdata = textreader.getLine().substring("tzdata".length());
|
||||
}
|
||||
if (!testdata.equals(runtime)) {
|
||||
throw new RuntimeException("tzdata versions don't match: run-time=" + runtime
|
||||
+ ", tests=" + testdata);
|
||||
}
|
||||
}
|
||||
}
|
||||
59
test/jdk/java/util/TimeZone/AvailableIDsTest.java
Normal file
59
test/jdk/java/util/TimeZone/AvailableIDsTest.java
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (c) 2025, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8347955
|
||||
* @summary Ensure underlying element equality of available tz ID methods
|
||||
* @run junit AvailableIDsTest
|
||||
*/
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
|
||||
public class AvailableIDsTest {
|
||||
|
||||
// Validate the equality of the array and stream of available IDs
|
||||
@Test
|
||||
public void streamEqualsArrayTest() {
|
||||
String[] tzs = TimeZone.getAvailableIDs();
|
||||
assertArrayEquals(tzs, TimeZone.availableIDs().toArray(String[]::new),
|
||||
"availableIDs() and getAvailableIDs() do not have the same elements");
|
||||
}
|
||||
|
||||
// Validate the equality of the array and stream of available IDs
|
||||
// when passed an offset. Tests various offsets.
|
||||
@ParameterizedTest
|
||||
@ValueSource(ints = {21600000, 25200000, 28800000}) // 6:00, 7:00, 8:00
|
||||
public void streamEqualsArrayWithOffsetTest(int offset) {
|
||||
String[] tzs = TimeZone.getAvailableIDs(offset);
|
||||
assertArrayEquals(tzs, TimeZone.availableIDs(offset).toArray(String[]::new),
|
||||
"availableIDs(int) and getAvailableIDs(int) do not have the same elements");
|
||||
}
|
||||
}
|
||||
230
test/jdk/java/util/TimeZone/Bug4322313.java
Normal file
230
test/jdk/java/util/TimeZone/Bug4322313.java
Normal file
|
|
@ -0,0 +1,230 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4322313
|
||||
* @summary Make sure that new implementation of custom time zone
|
||||
* support for TimeZone.getTimeZone() works correctly and the
|
||||
* getDisplayName() methods are locale independent.
|
||||
* @run junit Bug4322313
|
||||
*/
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
public class Bug4322313 {
|
||||
private static final int MPM = 60 * 1000; /* Milliseconds per minute */
|
||||
private static final Object[][] VALIDS = {
|
||||
/* given ID rawOffset normalized ID */
|
||||
{"GMT+00:00", 0, "GMT+00:00"},
|
||||
{"GMT+3:04", 184 * MPM, "GMT+03:04"},
|
||||
{"GMT+03:04", 184 * MPM, "GMT+03:04"},
|
||||
{"GMT+13:42", 822 * MPM, "GMT+13:42"},
|
||||
/* ISO-LATIN-1 digits */
|
||||
{"GMT+\u0030\u0031:\u0032\u0033", 83 * MPM, "GMT+01:23"},
|
||||
|
||||
{"GMT+0", 0, "GMT+00:00"},
|
||||
{"GMT+3", 180 * MPM, "GMT+03:00"},
|
||||
{"GMT+13", 780 * MPM, "GMT+13:00"},
|
||||
{"GMT+034", 34 * MPM, "GMT+00:34"},
|
||||
{"GMT+1034", 634 * MPM, "GMT+10:34"},
|
||||
|
||||
{"GMT-00:00", 0, "GMT-00:00"},
|
||||
{"GMT-3:04", -184 * MPM, "GMT-03:04"},
|
||||
{"GMT-03:04", -184 * MPM, "GMT-03:04"},
|
||||
{"GMT-13:42", -822 * MPM, "GMT-13:42"},
|
||||
/* ISO-LATIN-1 digits */
|
||||
{"GMT-\u0030\u0031:\u0032\u0033", -83 * MPM, "GMT-01:23"},
|
||||
|
||||
{"GMT-0", 0, "GMT-00:00"},
|
||||
{"GMT-3", -180 * MPM, "GMT-03:00"},
|
||||
{"GMT-13", -780 * MPM, "GMT-13:00"},
|
||||
{"GMT-034", -34 * MPM, "GMT-00:34"},
|
||||
{"GMT-1034", -634 * MPM, "GMT-10:34"},
|
||||
};
|
||||
|
||||
private static final String[] INVALIDS = {
|
||||
"GMT+5:8", "GMT+11:1", "GMT+23:60", "GMT+24:13",
|
||||
"GMT+0a:0A", "GMT +13:42", "GMT+ 13:42", "GMT+13 :42",
|
||||
"GMT+13: 42", "GMT+421:950", "GMT+-13:42", "GMT+!13:42",
|
||||
"GMT+a", "GMT+24", "GMT+060", "GMT+3003",
|
||||
"GMT+42195", "GMT+-1", "GMT+-15", " GMT",
|
||||
|
||||
"GMT-5:8", "GMT-11:1", "GMT-23:60", "GMT-24:13",
|
||||
"GMT-0a:0A", "GMT -13:42", "GMT- 13:42", "GMT-13 :42",
|
||||
"GMT-13: 42", "GMT-421:950", "GMT-+13:42", "GMT-#13:42",
|
||||
"GMT-a", "GMT-24", "GMT-060", "GMT-2403",
|
||||
"GMT-42195", "GMT-+1", "GMT-+15", "G M T",
|
||||
"GMT+09:00 ",
|
||||
};
|
||||
|
||||
@Test
|
||||
void Test4322313() {
|
||||
Locale savedLocale = Locale.getDefault();
|
||||
TimeZone savedTimeZone = TimeZone.getDefault();
|
||||
boolean err = false;
|
||||
|
||||
Locale[] locs = Locale.getAvailableLocales();
|
||||
try {
|
||||
TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
|
||||
|
||||
for (int i = 0; i < locs.length; i++) {
|
||||
Locale locale = locs[i];
|
||||
Locale.setDefault(locale);
|
||||
|
||||
|
||||
/* Okay case */
|
||||
for (int k = 0; k < VALIDS.length; k++) {
|
||||
TimeZone tz = TimeZone.getTimeZone((String)VALIDS[k][0]);
|
||||
int offset;
|
||||
|
||||
if (!tz.getID().equals(VALIDS[k][2])) {
|
||||
err = true;
|
||||
System.err.println("\tFailed [Locale=" +
|
||||
locale + ", \"" + VALIDS[k][0] +
|
||||
"\"] Invalid TimeZone ID, expected:" +
|
||||
VALIDS[k][2] + ", got:" + tz.getID() + ", " + tz);
|
||||
} else {
|
||||
System.out.println("\tPassed [Locale=" +
|
||||
locale + ", \"" + VALIDS[k][0] +
|
||||
"\"] Valid TimeZone ID, got:" + VALIDS[k][2]);
|
||||
}
|
||||
|
||||
offset = tz.getRawOffset();
|
||||
if (offset != (int)VALIDS[k][1]) {
|
||||
err = true;
|
||||
System.err.println("\tFailed [Locale=" +
|
||||
locale + ", \"" + VALIDS[k][0] +
|
||||
"\"] Invalid RawOffset, expected:" + VALIDS[k][1] +
|
||||
", got:" + offset + ", " + tz);
|
||||
} else {
|
||||
System.out.println("\tPassed [Locale=" +
|
||||
locale + ", \"" + VALIDS[k][0] +
|
||||
"\"] Vaild RawOffset, got:" + offset);
|
||||
}
|
||||
|
||||
offset = tz.getDSTSavings();
|
||||
if (offset != 0) {
|
||||
err = true;
|
||||
System.err.println("\tFailed [Locale=" +
|
||||
locale + ", \"" + VALIDS[k][0] +
|
||||
"\"] DSTSavings should be zero, got:" + offset +
|
||||
", " + tz);
|
||||
} else {
|
||||
System.out.println("\tPassed [Locale=" +
|
||||
locale + ", \"" + VALIDS[k][0] +
|
||||
"\"] DSTSavings is zero.");
|
||||
}
|
||||
}
|
||||
|
||||
/* Error case */
|
||||
for (int k=0; k < INVALIDS.length; k++) {
|
||||
TimeZone tz = TimeZone.getTimeZone(INVALIDS[k]);
|
||||
int offset;
|
||||
|
||||
if (!tz.getID().equals("GMT")) {
|
||||
err = true;
|
||||
System.err.println("\tFailed [Locale=" +
|
||||
locale + ", \"" + INVALIDS[k] +
|
||||
"\"] Invalid TimeZone ID, expected:GMT, got:" +
|
||||
tz.getID() + ", " + tz);
|
||||
} else {
|
||||
System.out.println("\tPassed [Locale=" +
|
||||
locale + ", \"" + INVALIDS[k] +
|
||||
"\"] Valid TimeZone ID, got:" + tz.getID());
|
||||
}
|
||||
|
||||
offset = tz.getRawOffset();
|
||||
if (offset != 0) {
|
||||
err = true;
|
||||
System.err.println("\tFailed [Locale=" +
|
||||
locale + ", \"" + INVALIDS[k] +
|
||||
"\"] RawOffset should be zero, got:" + offset +
|
||||
", " + tz);
|
||||
} else {
|
||||
System.out.println("\tPassed [Locale=" +
|
||||
locale + ", \"" + INVALIDS[k] +
|
||||
"\"] RawOffset is zero.");
|
||||
}
|
||||
|
||||
offset = tz.getDSTSavings();
|
||||
if (offset != 0) {
|
||||
err = true;
|
||||
System.err.println("\tFailed [Locale=" +
|
||||
locale + ", \"" + INVALIDS[k] +
|
||||
"\"] DSTSavings should be zero, got:" + offset +
|
||||
", " + tz);
|
||||
} else {
|
||||
System.out.println("\tPassed [Locale=" +
|
||||
locale + ", \"" + INVALIDS[k] +
|
||||
"\"] DSTSavings is zero.");
|
||||
}
|
||||
}
|
||||
|
||||
// getDisplayName() tests
|
||||
{
|
||||
String normalizedID = "GMT-08:00";
|
||||
TimeZone tz = TimeZone.getTimeZone("GMT-8");
|
||||
String s;
|
||||
s = tz.getDisplayName(true, tz.LONG);
|
||||
if (!normalizedID.equals(s)) {
|
||||
err = true;
|
||||
System.err.println("getDisplayName returned unexpected name: " + s +
|
||||
" in " + locale);
|
||||
}
|
||||
s = tz.getDisplayName(true, tz.SHORT);
|
||||
if (!normalizedID.equals(s)) {
|
||||
err = true;
|
||||
System.err.println("getDisplayName returned unexpected name: " + s +
|
||||
" in " + locale);
|
||||
}
|
||||
s = tz.getDisplayName(false, tz.LONG);
|
||||
if (!normalizedID.equals(s)) {
|
||||
err = true;
|
||||
System.err.println("getDisplayName returned unexpected name: " + s +
|
||||
" in " + locale);
|
||||
}
|
||||
s = tz.getDisplayName(false, tz.SHORT);
|
||||
if (!normalizedID.equals(s)) {
|
||||
err = true;
|
||||
System.err.println("getDisplayName returned unexpected name: " + s +
|
||||
" in " + locale);
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
Locale.setDefault(savedLocale);
|
||||
TimeZone.setDefault(savedTimeZone);
|
||||
}
|
||||
if (err) {
|
||||
fail("TimeZone.getTimeZone() test failed");
|
||||
} else {
|
||||
System.out.println("TimeZone.getTimeZone() test passed");
|
||||
}
|
||||
}
|
||||
}
|
||||
66
test/jdk/java/util/TimeZone/Bug5097350.java
Normal file
66
test/jdk/java/util/TimeZone/Bug5097350.java
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright (c) 2004, 2025, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 5097350 8347841 8347955
|
||||
* @summary Make sure that TimeZone.getTimeZone returns a clone of a cached TimeZone instance.
|
||||
*/
|
||||
|
||||
import java.time.ZoneId;
|
||||
import java.util.*;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class Bug5097350 {
|
||||
public static void main(String[] args) {
|
||||
String[] tzids = TimeZone.availableIDs()
|
||||
.filter(Predicate.not(ZoneId.SHORT_IDS::containsKey))
|
||||
.toArray(String[]::new);
|
||||
List<String> ids = new ArrayList<>(tzids.length + 10);
|
||||
ids.addAll(Arrays.asList(tzids));
|
||||
// add some custom ids
|
||||
ids.add("GMT+1");
|
||||
ids.add("GMT-7:00");
|
||||
ids.add("GMT+10:20");
|
||||
ids.add("GMT-00:00");
|
||||
ids.add("GMT+00:00");
|
||||
|
||||
for (String id : ids) {
|
||||
test(id);
|
||||
}
|
||||
}
|
||||
|
||||
private static void test(String id) {
|
||||
TimeZone tz1 = TimeZone.getTimeZone(id);
|
||||
int offset1 = tz1.getRawOffset();
|
||||
tz1.setRawOffset(offset1 + 13 * 60 * 60 * 1000);
|
||||
|
||||
TimeZone tz2 = TimeZone.getTimeZone(id);
|
||||
if (tz1 == tz2) {
|
||||
throw new RuntimeException("TimeZones are identical: " + id);
|
||||
}
|
||||
if (offset1 != tz2.getRawOffset()) {
|
||||
throw new RuntimeException("Offset changed through aliasing: " + id);
|
||||
}
|
||||
}
|
||||
}
|
||||
256
test/jdk/java/util/TimeZone/Bug6329116.java
Normal file
256
test/jdk/java/util/TimeZone/Bug6329116.java
Normal file
|
|
@ -0,0 +1,256 @@
|
|||
/*
|
||||
* Copyright (c) 2005, 2025, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6329116 6756569 6757131 6758988 6764308 6796489 6834474 6609737 6507067
|
||||
* 7039469 7090843 7103108 7103405 7158483 8008577 8059206 8064560 8072042
|
||||
* 8077685 8151876 8166875 8169191 8170316 8176044 8174269 8347841 8347955
|
||||
* @summary Make sure that timezone short display names are identical to Olson's data.
|
||||
* @run junit Bug6329116
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.time.ZoneId;
|
||||
import java.util.*;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
public class Bug6329116 {
|
||||
|
||||
// Do not test all locales, as some locales have localized
|
||||
// short names in CLDR. Test only for the US locale
|
||||
|
||||
// static Locale[] locales = Locale.getAvailableLocales();
|
||||
static Locale[] locales = {Locale.US};
|
||||
static String[] timezones = TimeZone.availableIDs()
|
||||
.filter(Predicate.not(ZoneId.SHORT_IDS::containsKey))
|
||||
.toArray(String[]::new);
|
||||
|
||||
@Test
|
||||
public void bug6329116() throws IOException {
|
||||
boolean err = false;
|
||||
|
||||
HashMap<String, String> aliasTable = new HashMap<>();
|
||||
HashSet<String> timezoneTable = new HashSet<>();
|
||||
for (String t : timezones) {
|
||||
timezoneTable.add(t);
|
||||
}
|
||||
|
||||
String line, key, value;
|
||||
StringTokenizer st;
|
||||
|
||||
try (TextFileReader in = new TextFileReader("aliases.txt")) {
|
||||
while ((line = in.readLine()) != null) {
|
||||
st = new StringTokenizer(line);
|
||||
st.nextToken();
|
||||
key = st.nextToken();
|
||||
value = st.nextToken();
|
||||
|
||||
if (!value.equals("ROC")) {
|
||||
if (aliasTable.containsKey(key)) {
|
||||
aliasTable.put(key, aliasTable.get(key) + " " + value);
|
||||
} else {
|
||||
aliasTable.put(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try (TextFileReader in = new TextFileReader("displaynames.txt")) {
|
||||
String timezoneID, expected, expected_DST, got;
|
||||
String[] aliases, tzs;
|
||||
TimeZone tz;
|
||||
while ((line = in.readLine()) != null) {
|
||||
st = new StringTokenizer(line);
|
||||
timezoneID = st.nextToken();
|
||||
expected = st.nextToken();
|
||||
if (st.hasMoreTokens()) {
|
||||
expected_DST = st.nextToken();
|
||||
} else {
|
||||
expected_DST = null;
|
||||
}
|
||||
|
||||
if (aliasTable.containsKey(timezoneID)) {
|
||||
aliases = aliasTable.get(timezoneID).split(" ");
|
||||
tzs = new String[1 + aliases.length];
|
||||
System.arraycopy(aliases, 0, tzs, 1, aliases.length);
|
||||
aliasTable.remove(timezoneID);
|
||||
} else {
|
||||
tzs = new String[1];
|
||||
}
|
||||
tzs[0] = timezoneID;
|
||||
|
||||
for (int j = 0; j < tzs.length; j++) {
|
||||
if (ZoneId.SHORT_IDS.containsKey(tzs[j])) {
|
||||
continue;
|
||||
}
|
||||
tz = TimeZone.getTimeZone(tzs[j]);
|
||||
|
||||
if (!tzs[j].equals(tz.getID())) {
|
||||
System.err.println(tzs[j] + " may not be a valid Timezone ID and \"" + tz.getID() + "\" was returned. Please check it.");
|
||||
err = true;
|
||||
}
|
||||
|
||||
timezoneTable.remove(tzs[j]);
|
||||
|
||||
for (int i = 0; i < locales.length; i++) {
|
||||
got = tz.getDisplayName(false, TimeZone.SHORT, locales[i]);
|
||||
if (!expected.equals(got) &&
|
||||
!expected.startsWith(got + "/") &&
|
||||
!expected.endsWith("/" + got)) {
|
||||
if (useLocalizedShortDisplayName(tz, locales[i], got, false)) {
|
||||
/*
|
||||
System.out.println(tzs[j] +
|
||||
((j > 0) ? "(Alias of \"" + tzs[0] + "\")" : "") +
|
||||
" seems to use a localized short display name" +
|
||||
": original: " + expected +
|
||||
": got: " + got + " for non-DST in " +
|
||||
locales[i] + " locale.");
|
||||
*/
|
||||
} else {
|
||||
System.err.println(tzs[j] +
|
||||
((j > 0) ? "(Alias of \"" + tzs[0] + "\")" : "") +
|
||||
": expected: " + expected +
|
||||
": got: " + got + " for non-DST in " +
|
||||
locales[i] + " locale.");
|
||||
err = true;
|
||||
}
|
||||
}
|
||||
|
||||
got = tz.getDisplayName(true, TimeZone.SHORT, locales[i]);
|
||||
if (expected_DST != null) {
|
||||
if (!expected_DST.equals(got) &&
|
||||
!expected_DST.startsWith(got + "/") &&
|
||||
!expected_DST.endsWith("/" + got)) {
|
||||
if (tzs[j].equals("Europe/London") &&
|
||||
locales[i].equals(new Locale("en", "IE"))) {
|
||||
continue;
|
||||
} else if (useLocalizedShortDisplayName(tz, locales[i], got, true)) {
|
||||
/*
|
||||
System.out.println(tzs[j] +
|
||||
((j > 0) ? "(Alias of \"" + tzs[0] + "\")" : "") +
|
||||
" seems to use a localized short display name" +
|
||||
": original: " + expected_DST +
|
||||
": got: " + got + " for DST in " +
|
||||
locales[i] + " locale.");
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
System.err.println(tzs[j] +
|
||||
((j > 0) ? "(Alias of \"" + tzs[0] + "\")" : "") +
|
||||
": expected: " + expected_DST +
|
||||
": got: " + got + " for DST in " +
|
||||
locales[i] + " locale.");
|
||||
err = true;
|
||||
}
|
||||
} else {
|
||||
// Some timezones don't have DST display names in Olson's data,
|
||||
// and we created them ourselves based on non-DST display names
|
||||
// to prepare potential use in the future.
|
||||
// Because there's no expected name, we don't judge if these
|
||||
// DST display names are correct but just compare them with
|
||||
// non-DST diplay names for checking with our eyes .
|
||||
if (!expected.equals(got) &&
|
||||
!expected.startsWith(got + "/") &&
|
||||
!expected.endsWith("/" + got)) {
|
||||
/*
|
||||
System.out.println("## " + tzs[j] +
|
||||
((j > 0) ? "(Alias of \"" + tzs[0] + "\")" : "") +
|
||||
": expected: " + expected +
|
||||
": got: " + got + " for DST in " +
|
||||
locales[i] + " locale.");
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!timezoneTable.isEmpty()) {
|
||||
System.out.println("# Timezone(s) valid in JRE but untested in this test program:");
|
||||
Iterator<String> it = timezoneTable.iterator();
|
||||
while (it.hasNext()) {
|
||||
System.out.println(it.next());
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
if (!aliasTable.isEmpty()) {
|
||||
System.out.println("# Timezone(s) exists in Olson's data as Link but unused in JRE:");
|
||||
for (Map.Entry<String, String> entry : aliasTable.entrySet()) {
|
||||
System.out.println(entry);
|
||||
}
|
||||
}
|
||||
|
||||
if (err) {
|
||||
fail("At least one timezone display name is incorrect.");
|
||||
}
|
||||
}
|
||||
|
||||
static boolean useLocalizedShortDisplayName(TimeZone tz,
|
||||
Locale locale,
|
||||
String got,
|
||||
boolean inDST) {
|
||||
// if (locale.getLanguage().equals("de")) {
|
||||
// String name = tz.getDisplayName(inDST, TimeZone.LONG, locale);
|
||||
// if (inDST) {
|
||||
// if (("Mitteleurop\u00e4ische Sommerzeit".equals(name) && "MESZ".equals(got)) ||
|
||||
// ("Osteurop\u00e4ische Sommerzeit".equals(name) && "OESZ".equals(got)) ||
|
||||
// ("Westeurop\u00e4ische Sommerzeit".equals(name) && "WESZ".equals(got))) {
|
||||
// return true;
|
||||
// }
|
||||
// } else {
|
||||
// if (("Mitteleurop\u00e4ische Zeit".equals(name) && "MEZ".equals(got)) ||
|
||||
// ("Osteurop\u00e4ische Zeit".equals(name) && "OEZ".equals(got)) ||
|
||||
// ("Westeurop\u00e4ische Zeit".equals(name) && "WEZ".equals(got))) {
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// } else if (locale.getLanguage().equals("zh") &&
|
||||
// (locale.getCountry().equals("TW") || locale.getCountry().equals("HK"))) {
|
||||
// String name = tz.getDisplayName(inDST, TimeZone.LONG, locale);
|
||||
// if (inDST) {
|
||||
// if (("\u53f0\u7063\u590f\u4ee4\u6642\u9593".equals(name) && "TDT".equals(got))) {
|
||||
// return true;
|
||||
// }
|
||||
// } else {
|
||||
// if (("\u53f0\u7063\u6a19\u6e96\u6642\u9593".equals(name) && "TST".equals(got))) {
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// If we get a TimeZone with GMT+hh:mm format, we can ignore the offset value
|
||||
if (tz.getDisplayName(Locale.ENGLISH).startsWith("GMT+") || tz.getDisplayName(Locale.ENGLISH).startsWith("GMT-")) {
|
||||
return tz.getDisplayName().substring(0, 3).equals(got.substring(0, 3));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
95
test/jdk/java/util/TimeZone/Bug6772689.java
Normal file
95
test/jdk/java/util/TimeZone/Bug6772689.java
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright (c) 2011, 2025, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6772689 8347841 8347955
|
||||
* @summary Test for standard-to-daylight transitions at midnight:
|
||||
* date stays on the given day.
|
||||
*/
|
||||
|
||||
import java.time.ZoneId;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.TimeZone;
|
||||
import java.util.function.Predicate;
|
||||
import static java.util.GregorianCalendar.*;
|
||||
|
||||
public class Bug6772689 {
|
||||
private static final int BEGIN_YEAR = 2035;
|
||||
private static final int END_YEAR = BEGIN_YEAR + 28;
|
||||
|
||||
public static void main(String[] args) {
|
||||
TimeZone defaultTimeZone = TimeZone.getDefault();
|
||||
int errors = 0;
|
||||
|
||||
Calendar cal = new GregorianCalendar(BEGIN_YEAR, MARCH, 1);
|
||||
String[] tzids = TimeZone.availableIDs()
|
||||
.filter(Predicate.not(ZoneId.SHORT_IDS::containsKey))
|
||||
.toArray(String[]::new);
|
||||
try {
|
||||
for (String id : tzids) {
|
||||
TimeZone tz = TimeZone.getTimeZone(id);
|
||||
if (!tz.useDaylightTime()) {
|
||||
continue;
|
||||
}
|
||||
TimeZone.setDefault(tz);
|
||||
|
||||
dateloop:
|
||||
// Use future dates because sun.util.calendar.ZoneInfo
|
||||
// delegates offset transition calculations to a SimpleTimeZone
|
||||
// (after 2038 as of JDK7).
|
||||
for (int year = BEGIN_YEAR; year < END_YEAR; year++) {
|
||||
for (int month = MARCH; month <= NOVEMBER; month++) {
|
||||
cal.set(year, month, 1, 15, 0, 0);
|
||||
int maxDom = cal.getActualMaximum(DAY_OF_MONTH);
|
||||
for (int dom = 1; dom <= maxDom; dom++) {
|
||||
Date date = new Date(year - 1900, month, dom);
|
||||
if (date.getYear()+1900 != year
|
||||
|| date.getMonth() != month
|
||||
|| date.getDate() != dom) {
|
||||
System.err.printf("%s: got %04d-%02d-%02d, expected %04d-%02d-%02d%n",
|
||||
id,
|
||||
date.getYear() + 1900,
|
||||
date.getMonth() + 1,
|
||||
date.getDate(),
|
||||
year,
|
||||
month + 1,
|
||||
dom);
|
||||
errors++;
|
||||
break dateloop;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
// Restore the default TimeZone.
|
||||
TimeZone.setDefault(defaultTimeZone);
|
||||
}
|
||||
if (errors > 0) {
|
||||
throw new RuntimeException("Transition test failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
57
test/jdk/java/util/TimeZone/Bug8066652.java
Normal file
57
test/jdk/java/util/TimeZone/Bug8066652.java
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 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.
|
||||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.TimeZone;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
public class Bug8066652 {
|
||||
|
||||
public static void main(String args[]) {
|
||||
ExecutorService executor = Executors.newFixedThreadPool(10);
|
||||
Callable<TimeZone> calTimeZone = () -> TimeZone.getDefault();
|
||||
List<Callable<TimeZone>> tasks = new ArrayList<>();
|
||||
for (int j = 1; j < 10; j++) {
|
||||
tasks.add(calTimeZone);
|
||||
}
|
||||
try {
|
||||
List<Future<TimeZone>> results = executor.invokeAll(tasks);
|
||||
for (Future<TimeZone> f : results) {
|
||||
TimeZone tz = f.get();
|
||||
if (! tz.getID().equals("GMT")) {
|
||||
throw new RuntimeException("wrong Time zone ID: " + tz.getID()
|
||||
+ ", It should be GMT");
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
throw new RuntimeException("Execution interrupted or Execution Exception occurred", e);
|
||||
} finally {
|
||||
executor.shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
68
test/jdk/java/util/TimeZone/Bug8066652Run.java
Normal file
68
test/jdk/java/util/TimeZone/Bug8066652Run.java
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2019, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8066652
|
||||
* @requires os.family == "mac"
|
||||
* @summary tests thread safe native function localtime_r is accessed by multiple
|
||||
* threads at same time and zone id should not be "GMT+00:00"
|
||||
* if default timezone is "GMT" and user specifies a fake timezone.
|
||||
* @library /test/lib
|
||||
* @build Bug8066652
|
||||
* @run main Bug8066652Run
|
||||
*/
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import jdk.test.lib.JDKToolLauncher;
|
||||
import jdk.test.lib.Utils;
|
||||
import jdk.test.lib.process.ProcessTools;
|
||||
|
||||
public class Bug8066652Run {
|
||||
private static String cp = Utils.TEST_CLASSES;
|
||||
private static ProcessBuilder pb = new ProcessBuilder();
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
//set system TimeZone to GMT using environment variable TZ
|
||||
Map<String, String> env = pb.environment();
|
||||
env.put("TZ", "GMT");
|
||||
System.out.println("Current TimeZone:" + pb.environment().get("TZ"));
|
||||
JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("java");
|
||||
//Setting invalid TimeZone using VM option
|
||||
launcher.addToolArg("-Duser.timezone=Foo/Bar")
|
||||
.addToolArg("-ea")
|
||||
.addToolArg("-esa")
|
||||
.addToolArg("-cp")
|
||||
.addToolArg(cp)
|
||||
.addToolArg("Bug8066652");
|
||||
|
||||
pb.command(launcher.getCommand());
|
||||
int exitCode = ProcessTools.executeCommand(pb)
|
||||
.getExitValue();
|
||||
if (exitCode != 0) {
|
||||
throw new RuntimeException("Unexpected exit code: " + exitCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
60
test/jdk/java/util/TimeZone/Bug8149452.java
Normal file
60
test/jdk/java/util/TimeZone/Bug8149452.java
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2018, 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.
|
||||
*/
|
||||
/*
|
||||
* @test
|
||||
* @bug 8149452 8151876 8181157 8206965
|
||||
* @modules java.base/sun.util.calendar
|
||||
* @run main/othervm -Duser.language=de -Duser.country=DE Bug8149452
|
||||
* @run main/othervm -Duser.language=ja -Duser.country=JP Bug8149452
|
||||
* @run main/othervm -Duser.language=en -Duser.country=US Bug8149452
|
||||
* @summary Check the missing time zone names for English, German and Japanese locales.
|
||||
*/
|
||||
import java.text.DateFormatSymbols;
|
||||
import java.util.ArrayList;
|
||||
import java.util.TimeZone;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class Bug8149452 {
|
||||
|
||||
public static void main(String[] args) {
|
||||
List<String> listNotFound = new ArrayList<>();
|
||||
String[][] zoneStrings = DateFormatSymbols.getInstance()
|
||||
.getZoneStrings();
|
||||
for (String tzID : TimeZone.getAvailableIDs()) {
|
||||
if (!Arrays.stream(zoneStrings)
|
||||
.anyMatch(zone -> tzID.equalsIgnoreCase(zone[0]))) {
|
||||
// to ignore names for Etc/GMT[+-][0-9]+ which are not supported
|
||||
if (!tzID.startsWith("Etc/GMT")
|
||||
&& !tzID.startsWith("GMT")) {
|
||||
listNotFound.add(tzID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!listNotFound.isEmpty()) {
|
||||
throw new RuntimeException("Test Failed: Time Zone Strings for "
|
||||
+ listNotFound + " not found");
|
||||
}
|
||||
}
|
||||
}
|
||||
257
test/jdk/java/util/TimeZone/Bug8167143.java
Normal file
257
test/jdk/java/util/TimeZone/Bug8167143.java
Normal file
|
|
@ -0,0 +1,257 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2025, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8167143 8174269 8358170
|
||||
* @summary Test
|
||||
* Timezone parsing works for all locales for default providers preference
|
||||
* CLDR implicit locales are correctly reflected,
|
||||
* th_TH bundle is not wrongly cached in DateFormatSymbols,
|
||||
* correct candidate locale list is retrieved for
|
||||
* zh_Hant and zh_Hans and
|
||||
* Implicit FALLBACK Locales nn-NO, nb-NO are reflected in available locales
|
||||
* @modules java.base/sun.util.locale.provider
|
||||
* java.base/sun.util.spi
|
||||
* jdk.localedata
|
||||
* @run main Bug8167143 testTimeZone
|
||||
* @run main Bug8167143 testCldr
|
||||
* @run main Bug8167143 testCache
|
||||
* @run main Bug8167143 testCandidateLocales
|
||||
* @run main Bug8167143 testFallback
|
||||
*/
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import sun.util.locale.provider.LocaleProviderAdapter;
|
||||
import sun.util.locale.provider.LocaleProviderAdapter.Type;
|
||||
|
||||
public class Bug8167143 {
|
||||
|
||||
private static final TimeZone REYKJAVIK = TimeZone.getTimeZone("Atlantic/Reykjavik");
|
||||
private static final TimeZone NEW_YORK = TimeZone.getTimeZone("America/New_York");
|
||||
private static final TimeZone GMT = TimeZone.getTimeZone("GMT");
|
||||
|
||||
private static final List<Locale> CLDR_IMPLICIT_LOCS = List.of(Locale.forLanguageTag("zh-Hans-CN"),
|
||||
Locale.forLanguageTag("zh-Hans-SG"),
|
||||
Locale.forLanguageTag("zh-Hant-HK"),
|
||||
Locale.forLanguageTag("zh-Hant-TW"),
|
||||
Locale.forLanguageTag("zh-Hant-MO"));
|
||||
|
||||
private static final List<Locale> FALLBACK_IMPLICIT_LOCS = List.of(Locale.forLanguageTag("nn-NO"),
|
||||
Locale.forLanguageTag("nb-NO"));
|
||||
/**
|
||||
* List of candidate locales for zh_Hant
|
||||
*/
|
||||
private static final List<Locale> ZH_HANT_CANDLOCS = List.of(
|
||||
Locale.forLanguageTag("zh-Hant"),
|
||||
Locale.forLanguageTag("zh-TW"),
|
||||
Locale.forLanguageTag("zh"),
|
||||
Locale.ROOT);
|
||||
/**
|
||||
* List of candidate locales for zh_Hans
|
||||
*/
|
||||
private static final List<Locale> ZH_HANS_CANDLOCS = List.of(
|
||||
Locale.forLanguageTag("zh-Hans"),
|
||||
Locale.forLanguageTag("zh-CN"),
|
||||
Locale.forLanguageTag("zh"),
|
||||
Locale.ROOT);
|
||||
|
||||
public static void main(String[] args) {
|
||||
switch (args[0]) {
|
||||
case "testTimeZone":
|
||||
testTimeZoneParsing();
|
||||
break;
|
||||
case "testCldr":
|
||||
testImplicitCldrLocales();
|
||||
break;
|
||||
case "testCache":
|
||||
testDateFormatSymbolsCache();
|
||||
break;
|
||||
case "testCandidateLocales":
|
||||
testCandidateLocales();
|
||||
break;
|
||||
case "testFallback":
|
||||
testImplicitFallbackLocales();
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("no test was specified.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that if Locale Provider Preference list is Default, or if Locale
|
||||
* Provider Preference List is COMPAT,CLDR SimplDateFormat parsing works for
|
||||
* all Available Locales.
|
||||
*/
|
||||
private static void testTimeZoneParsing() {
|
||||
Set<Locale> locales = Set.of(Locale.forLanguageTag("zh-hant"), Locale.of("no", "NO", "NY"));
|
||||
// Set<Locale> locales = Set.of(Locale.getAvailableLocales());
|
||||
locales.forEach((locale) -> {
|
||||
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd z", locale);
|
||||
for (final TimeZone tz : new TimeZone[]{REYKJAVIK, GMT, NEW_YORK}) {
|
||||
try {
|
||||
sdf.parse("2000/02/10 " + tz.getDisplayName(locale));
|
||||
} catch (ParseException e) {
|
||||
throw new RuntimeException("TimeZone Parsing failed with Locale "
|
||||
+ locale + " for TimeZone " + tz.getDisplayName(), e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that locales implicitly supported from CLDR are reflected in output
|
||||
* from getAvailbleLocales() for each bundle.
|
||||
*
|
||||
*/
|
||||
private static void testImplicitCldrLocales() {
|
||||
LocaleProviderAdapter cldr = LocaleProviderAdapter.forType(Type.CLDR);
|
||||
checkPresenceCldr("CurrencyNameProvider",
|
||||
cldr.getCurrencyNameProvider().getAvailableLocales());
|
||||
checkPresenceCldr("LocaleNameProvider",
|
||||
cldr.getLocaleNameProvider().getAvailableLocales());
|
||||
checkPresenceCldr("TimeZoneNameProvider",
|
||||
cldr.getTimeZoneNameProvider().getAvailableLocales());
|
||||
checkPresenceCldr("CalendarDataProvider",
|
||||
cldr.getCalendarDataProvider().getAvailableLocales());
|
||||
checkPresenceCldr("CalendarNameProvider",
|
||||
cldr.getCalendarProvider().getAvailableLocales());
|
||||
}
|
||||
|
||||
private static void checkPresenceCldr(String testName, Locale[] got) {
|
||||
List<Locale> gotLocalesList = Arrays.asList(got);
|
||||
List<Locale> gotList = new ArrayList<>(gotLocalesList);
|
||||
if (!testName.equals("TimeZoneNameProvider")) {
|
||||
if (!gotList.removeAll(CLDR_IMPLICIT_LOCS)) {
|
||||
// check which locale are not present in retrievedLocales List.
|
||||
List<Locale> expectedLocales = new ArrayList<>(CLDR_IMPLICIT_LOCS);
|
||||
expectedLocales.removeAll(gotList);
|
||||
throw new RuntimeException("Locales those not correctly reflected are "
|
||||
+ expectedLocales + " for test " + testName);
|
||||
}
|
||||
} else {
|
||||
// check one extra locale zh_HK for TimeZoneNameProvider
|
||||
Locale zh_HK = Locale.forLanguageTag("zh-HK");
|
||||
if (!gotList.removeAll(CLDR_IMPLICIT_LOCS) && gotList.remove(zh_HK)) {
|
||||
//check which locale are not present in retrievedLocales List
|
||||
List<Locale> expectedLocales = new ArrayList<>(CLDR_IMPLICIT_LOCS);
|
||||
expectedLocales.add(zh_HK);
|
||||
expectedLocales.removeAll(gotList);
|
||||
throw new RuntimeException("Locales those not correctly reflected are "
|
||||
+ expectedLocales + " for test " + testName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that if Locale Provider Preference list is default and if
|
||||
* SimpleDateFormat instance for th-TH-TH is created first, then JRE bundle
|
||||
* for th-TH should not be cached in cache of DateFormatSymbols class.
|
||||
*/
|
||||
private static void testDateFormatSymbolsCache() {
|
||||
Locale th_TH_TH = Locale.of("th", "TH", "TH");
|
||||
Locale th_TH = Locale.of("th", "TH");
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd z", th_TH_TH);
|
||||
String[][] thTHTHZoneStrings = sdf.getDateFormatSymbols().getZoneStrings();
|
||||
String[][] thTHZoneStrings = sdf.getDateFormatSymbols().getZoneStrings();
|
||||
if (Arrays.equals(thTHTHZoneStrings, thTHZoneStrings)) {
|
||||
throw new RuntimeException("th_TH bundle still cached with DateFormatSymbols"
|
||||
+ "cache for locale " + th_TH
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that candidate locales list retrieved for zh__Hant and for zh__Hans
|
||||
* do not have first candidate locale as zh_TW_Hant and zh_CN_Hans
|
||||
* respectively.
|
||||
*/
|
||||
private static void testCandidateLocales() {
|
||||
ResourceBundle.Control Control = ResourceBundle.Control.getControl(ResourceBundle.Control.FORMAT_DEFAULT);
|
||||
Locale zh_Hant = Locale.forLanguageTag("zh-Hant");
|
||||
Locale zh_Hans = Locale.forLanguageTag("zh-Hans");
|
||||
List<Locale> zhHantCandidateLocs = Control.getCandidateLocales("", zh_Hant);
|
||||
List<Locale> zhHansCandidateLocs = Control.getCandidateLocales("", zh_Hans);
|
||||
if (!zhHantCandidateLocs.equals(ZH_HANT_CANDLOCS)) {
|
||||
reportDifference(zhHantCandidateLocs, ZH_HANT_CANDLOCS, "zh_Hant");
|
||||
|
||||
}
|
||||
if (!zhHansCandidateLocs.equals(ZH_HANS_CANDLOCS)) {
|
||||
reportDifference(zhHansCandidateLocs, ZH_HANS_CANDLOCS, "zh_Hans");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static void reportDifference(List<Locale> got, List<Locale> expected, String locale) {
|
||||
List<Locale> retrievedList = new ArrayList<>(got);
|
||||
List<Locale> expectedList = new ArrayList<>(expected);
|
||||
retrievedList.removeAll(expectedList);
|
||||
expectedList.removeAll(retrievedList);
|
||||
if ((retrievedList.size() > 0) && (expectedList.size() > 0)) {
|
||||
throw new RuntimeException(" retrievedList contain extra candidate locales " + retrievedList
|
||||
+ " and missing candidate locales " + expectedList
|
||||
+ "for locale " + locale);
|
||||
}
|
||||
if ((retrievedList.size() > 0)) {
|
||||
throw new RuntimeException(" retrievedList contain extra candidate locales " + retrievedList
|
||||
+ "for locale " + locale);
|
||||
}
|
||||
if ((expectedList.size() > 0)) {
|
||||
throw new RuntimeException(" retrievedList contain extra candidate locales " + expectedList
|
||||
+ "for locale " + locale);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that locales (nn-NO and nb-NO) implicitly supported in FALLBACK
|
||||
* provider should be present in output of getAvailableLocales() for
|
||||
* BreakIteratorProvider and CollatorProvider.
|
||||
*/
|
||||
private static void testImplicitFallbackLocales() {
|
||||
LocaleProviderAdapter fallback = LocaleProviderAdapter.forType(Type.FALLBACK);
|
||||
checkPresenceFallback("BreakIteratorProvider",
|
||||
fallback.getBreakIteratorProvider().getAvailableLocales());
|
||||
checkPresenceFallback("CollatorProvider",
|
||||
fallback.getCollatorProvider().getAvailableLocales());
|
||||
}
|
||||
|
||||
private static void checkPresenceFallback(String testName, Locale[] got) {
|
||||
List<Locale> gotLocalesList = Arrays.asList(got);
|
||||
List<Locale> gotList = new ArrayList<>(gotLocalesList);
|
||||
if (!gotList.removeAll(FALLBACK_IMPLICIT_LOCS)) {
|
||||
// check which Implicit locale are not present in retrievedLocales List.
|
||||
List<Locale> implicitLocales = new ArrayList<>(FALLBACK_IMPLICIT_LOCS);
|
||||
implicitLocales.removeAll(gotList);
|
||||
throw new RuntimeException("Locale(s) not correctly reflected are "
|
||||
+ implicitLocales + " for test " + testName);
|
||||
}
|
||||
}
|
||||
}
|
||||
170
test/jdk/java/util/TimeZone/CLDRDisplayNamesTest.java
Normal file
170
test/jdk/java/util/TimeZone/CLDRDisplayNamesTest.java
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
* Copyright (c) 2012, 2025, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8005471 8008577 8129881 8130845 8136518 8181157 8210490 8220037
|
||||
* 8234347 8236548 8317979 8354548
|
||||
* @modules jdk.localedata
|
||||
* @run main CLDRDisplayNamesTest
|
||||
* @summary Make sure that localized time zone names of CLDR are used
|
||||
* if specified.
|
||||
*/
|
||||
|
||||
import java.text.*;
|
||||
import java.util.*;
|
||||
import static java.util.TimeZone.*;
|
||||
|
||||
public class CLDRDisplayNamesTest {
|
||||
/*
|
||||
* The first element is a language tag. The rest are localized
|
||||
* display names of America/Los_Angeles copied from the CLDR
|
||||
* resources data. If data change in CLDR, test data below will
|
||||
* need to be changed accordingly.
|
||||
*
|
||||
* Generic names are NOT tested (until they are supported by API).
|
||||
*/
|
||||
static final String[][] CLDR_DATA = {
|
||||
{
|
||||
"ja-JP",
|
||||
"米国太平洋標準時",
|
||||
"PST",
|
||||
"米国太平洋夏時間",
|
||||
"PDT",
|
||||
},
|
||||
{
|
||||
"zh-CN",
|
||||
"北美太平洋标准时间",
|
||||
"PST",
|
||||
"北美太平洋夏令时间",
|
||||
"PDT",
|
||||
},
|
||||
{
|
||||
"de-DE",
|
||||
"Nordamerikanische Westküsten-Normalzeit",
|
||||
"PST",
|
||||
"Nordamerikanische Westküsten-Sommerzeit",
|
||||
"PDT",
|
||||
},
|
||||
};
|
||||
|
||||
private static final String NO_INHERITANCE_MARKER = "∅∅∅";
|
||||
|
||||
public static void main(String[] args) {
|
||||
// Make sure that localized time zone names of CLDR are used
|
||||
// if specified.
|
||||
TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
|
||||
int errors = 0;
|
||||
for (String[] data : CLDR_DATA) {
|
||||
Locale locale = Locale.forLanguageTag(data[0]);
|
||||
for (int i = 1; i < data.length; i++) {
|
||||
int style = ((i % 2) == 1) ? LONG : SHORT;
|
||||
boolean daylight = (i == 3 || i == 4);
|
||||
String name = tz.getDisplayName(daylight, style, locale);
|
||||
if (!data[i].equals(name)) {
|
||||
System.err.printf("error: got '%s' expected '%s' (style=%d, daylight=%s, locale=%s)%n",
|
||||
name, data[i], style, daylight, locale);
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// for 8129881
|
||||
/* 8234347: CLDR Converter will not pre-fill short display names from COMPAT anymore.
|
||||
tz = TimeZone.getTimeZone("Europe/Vienna");
|
||||
String name = tz.getDisplayName(false, SHORT, Locale.ENGLISH);
|
||||
if (!"CET".equals(name)) {
|
||||
System.err.printf("error: got '%s' expected 'CET' %n", name);
|
||||
errors++;
|
||||
}
|
||||
*/
|
||||
|
||||
// for 8130845
|
||||
SimpleDateFormat fmtROOT = new SimpleDateFormat("EEE MMM d hh:mm:ss z yyyy", Locale.ROOT);
|
||||
SimpleDateFormat fmtUS = new SimpleDateFormat("EEE MMM d hh:mm:ss z yyyy", Locale.US);
|
||||
SimpleDateFormat fmtUK = new SimpleDateFormat("EEE MMM d hh:mm:ss z yyyy", Locale.UK);
|
||||
Locale originalLocale = Locale.getDefault();
|
||||
try {
|
||||
Locale.setDefault(Locale.ROOT);
|
||||
fmtROOT.parse("Thu Nov 13 04:35:51 GMT-09:00 2008");
|
||||
fmtUS.parse("Thu Nov 13 04:35:51 AKST 2008");
|
||||
fmtUK.parse("Thu Nov 13 04:35:51 GMT-09:00 2008");
|
||||
} catch (ParseException pe) {
|
||||
System.err.println(pe);
|
||||
errors++;
|
||||
} finally {
|
||||
Locale.setDefault(originalLocale);
|
||||
}
|
||||
|
||||
// for 8210490
|
||||
// Check that TimeZone.getDisplayName should honor passed locale parameter,
|
||||
// even if default locale is set to some other locale.
|
||||
Locale.setDefault(Locale.forLanguageTag("ar-PK"));
|
||||
TimeZone zi = TimeZone.getTimeZone("Etc/GMT-5");
|
||||
String displayName = zi.getDisplayName(false, TimeZone.SHORT, Locale.US);
|
||||
Locale.setDefault(originalLocale);
|
||||
if (!displayName.equals("GMT+05:00")) {
|
||||
System.err.println("Wrong display name for timezone Etc/GMT-5 : expected GMT+05:00, Actual " + displayName);
|
||||
errors++;
|
||||
}
|
||||
|
||||
// 8217366: No "no inheritance marker" should be left in the returned array
|
||||
// from DateFormatSymbols.getZoneStrings()
|
||||
errors += List.of(Locale.ROOT,
|
||||
Locale.CHINA,
|
||||
Locale.GERMANY,
|
||||
Locale.JAPAN,
|
||||
Locale.UK,
|
||||
Locale.US,
|
||||
Locale.forLanguageTag("hi-IN"),
|
||||
Locale.forLanguageTag("es-419")).stream()
|
||||
.peek(System.out::println)
|
||||
.map(l -> DateFormatSymbols.getInstance(l).getZoneStrings())
|
||||
.flatMap(zoneStrings -> Arrays.stream(zoneStrings))
|
||||
.filter(namesArray -> Arrays.stream(namesArray)
|
||||
.anyMatch(aName -> aName.equals(NO_INHERITANCE_MARKER)))
|
||||
.peek(marker -> {
|
||||
System.err.println("No-inheritance-marker is detected with tzid: "
|
||||
+ marker[0]);
|
||||
})
|
||||
.count();
|
||||
|
||||
// 8220037: Make sure CLDRConverter uniquely produces bundles, regardless of the
|
||||
// source file enumeration order.
|
||||
/* 8234347: CLDR Converter will not pre-fill short display names from COMPAT anymore.
|
||||
tz = TimeZone.getTimeZone("America/Argentina/La_Rioja");
|
||||
if (!"ARST".equals(tz.getDisplayName(true, TimeZone.SHORT,
|
||||
new Locale.Builder()
|
||||
.setLanguage("en")
|
||||
.setRegion("CA")
|
||||
.build()))) {
|
||||
System.err.println("Short display name of \"" + tz.getID() + "\" was not \"ARST\"");
|
||||
errors++;
|
||||
}
|
||||
*/
|
||||
|
||||
if (errors > 0) {
|
||||
throw new RuntimeException("test failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
95
test/jdk/java/util/TimeZone/CustomTzIDCheckDST.java
Normal file
95
test/jdk/java/util/TimeZone/CustomTzIDCheckDST.java
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright (c) 2022, 2023, 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.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @bug 8285838
|
||||
* @library /test/lib
|
||||
* @summary This test will ensure that daylight savings rules are followed
|
||||
* appropriately when setting a custom timezone ID via the TZ env variable.
|
||||
* @requires os.family != "windows"
|
||||
* @run main/othervm CustomTzIDCheckDST
|
||||
*/
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.SimpleTimeZone;
|
||||
import java.util.TimeZone;
|
||||
import java.time.DayOfWeek;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.temporal.TemporalAdjusters;
|
||||
|
||||
import jdk.test.lib.process.ProcessTools;
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
|
||||
public class CustomTzIDCheckDST {
|
||||
// Northern Hemisphere
|
||||
private static String CUSTOM_TZ = "MEZ-1MESZ,M3.5.0,M10.5.0/3";
|
||||
// Simulate Southern Hemisphere
|
||||
private static String CUSTOM_TZ2 = "MEZ-1MESZ,M10.5.0,M3.5.0/3";
|
||||
public static void main(String args[]) throws Throwable {
|
||||
if (args.length == 0) {
|
||||
ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder("CustomTzIDCheckDST", "runTZTest");
|
||||
pb.environment().put("TZ", CUSTOM_TZ);
|
||||
OutputAnalyzer output = ProcessTools.executeProcess(pb);
|
||||
output.shouldHaveExitValue(0);
|
||||
pb.environment().put("TZ", CUSTOM_TZ2);
|
||||
output = ProcessTools.executeProcess(pb);
|
||||
output.shouldHaveExitValue(0);
|
||||
} else {
|
||||
runTZTest();
|
||||
}
|
||||
}
|
||||
|
||||
/* TZ is set to "MEZ-1MESZ,M3.5.0,M10.5.0/3", it will be the northern hemisphere.
|
||||
* This ensures the transition periods for Daylights Savings should be at March's last
|
||||
* Sunday and October's last Sunday.
|
||||
*/
|
||||
private static void runTZTest() {
|
||||
Date time = new Date();
|
||||
String tzStr = System.getenv("TZ");
|
||||
if (tzStr == null)
|
||||
throw new RuntimeException("Got unexpected timezone information: TZ is null");
|
||||
boolean nor = CUSTOM_TZ.equals(tzStr);
|
||||
TimeZone tz = new SimpleTimeZone(3600000, tzStr,
|
||||
nor ? Calendar.MARCH : Calendar.OCTOBER, -1,
|
||||
Calendar.SUNDAY, 3600000, SimpleTimeZone.UTC_TIME,
|
||||
nor ? Calendar.OCTOBER : Calendar.MARCH, -1,
|
||||
Calendar.SUNDAY, 3600000, SimpleTimeZone.UTC_TIME,
|
||||
3600000);
|
||||
if (tz.inDaylightTime(time)) {
|
||||
// We are in Daylight savings period.
|
||||
if (time.toString().endsWith("GMT+02:00 " + Integer.toString(time.getYear() + 1900)))
|
||||
return;
|
||||
} else {
|
||||
if (time.toString().endsWith("GMT+01:00 " + Integer.toString(time.getYear() + 1900)))
|
||||
return;
|
||||
}
|
||||
|
||||
// Reaching here means time zone did not match up as expected.
|
||||
throw new RuntimeException("Got unexpected timezone information: " + tzStr + " " + time);
|
||||
}
|
||||
|
||||
private static ZonedDateTime getLastSundayOfMonth(ZonedDateTime date) {
|
||||
return date.with(TemporalAdjusters.lastInMonth(DayOfWeek.SUNDAY));
|
||||
}
|
||||
}
|
||||
107
test/jdk/java/util/TimeZone/DaylightTimeTest.java
Normal file
107
test/jdk/java/util/TimeZone/DaylightTimeTest.java
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* Copyright (c) 2011, 2025, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6936350 8347841 8347955
|
||||
* @summary Test case for TimeZone.observesDaylightTime()
|
||||
*/
|
||||
|
||||
import java.time.ZoneId;
|
||||
import java.util.*;
|
||||
import java.util.function.Predicate;
|
||||
import static java.util.GregorianCalendar.*;
|
||||
|
||||
public class DaylightTimeTest {
|
||||
private static final int ONE_HOUR = 60 * 60 * 1000; // one hour
|
||||
private static final int INTERVAL = 24 * ONE_HOUR; // one day
|
||||
private static final String[] ZONES = TimeZone.availableIDs()
|
||||
.filter(Predicate.not(ZoneId.SHORT_IDS::containsKey))
|
||||
.toArray(String[]::new);
|
||||
private static int errors = 0;
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
// Test default TimeZone
|
||||
for (String id : ZONES) {
|
||||
TimeZone tz = TimeZone.getTimeZone(id);
|
||||
long now = System.currentTimeMillis();
|
||||
boolean observes = tz.observesDaylightTime();
|
||||
boolean found = findDSTTransition(tz, now);
|
||||
if (observes != found) {
|
||||
// There's a critical section. If DST ends after the
|
||||
// System.currentTimeMills() call, there should be
|
||||
// inconsistency in the determination. Try the same
|
||||
// thing again to see the inconsistency was due to the
|
||||
// critical section.
|
||||
now = System.currentTimeMillis();
|
||||
observes = tz.observesDaylightTime();
|
||||
found = findDSTTransition(tz, now);
|
||||
if (observes != found) {
|
||||
System.err.printf("%s: observesDaylightTime() should return %s at %d%n",
|
||||
tz.getID(), found, now);
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test SimpleTimeZone in which observesDaylightTime() is
|
||||
// equivalent to useDaylightTime().
|
||||
testSimpleTimeZone(new SimpleTimeZone(-8*ONE_HOUR, "X",
|
||||
APRIL, 1, -SUNDAY, 2*ONE_HOUR,
|
||||
OCTOBER, -1, SUNDAY, 2*ONE_HOUR,
|
||||
1*ONE_HOUR));
|
||||
testSimpleTimeZone(new SimpleTimeZone(-8*ONE_HOUR, "Y"));
|
||||
|
||||
if (errors > 0) {
|
||||
throw new RuntimeException("DaylightTimeTest: failed");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if it's `now' in DST or there's any
|
||||
* standard-to-daylight transition within 50 years after `now'.
|
||||
*/
|
||||
private static boolean findDSTTransition(TimeZone tz, long now) {
|
||||
GregorianCalendar cal = new GregorianCalendar(tz, Locale.US);
|
||||
cal.setTimeInMillis(now);
|
||||
cal.add(YEAR, 50);
|
||||
long end = cal.getTimeInMillis();
|
||||
|
||||
for (long t = now; t < end; t += INTERVAL) {
|
||||
cal.setTimeInMillis(t);
|
||||
if (cal.get(DST_OFFSET) > 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void testSimpleTimeZone(SimpleTimeZone stz) {
|
||||
if (stz.useDaylightTime() != stz.observesDaylightTime()) {
|
||||
System.err.printf("Failed: useDaylightTime=%b, observesDaylightTime()=%b%n\t%s%n",
|
||||
stz.useDaylightTime(),stz.observesDaylightTime(), stz);
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
}
|
||||
141
test/jdk/java/util/TimeZone/DefaultTimeZoneTest.java
Normal file
141
test/jdk/java/util/TimeZone/DefaultTimeZoneTest.java
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* Copyright (c) 2005, 2025, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4296930 5033603 7092679
|
||||
* @summary Ensure that Java detects the platform time zone correctly, even
|
||||
* if changed during runtime. Also ensure that the system time zone detection code
|
||||
* detects the "Automatically adjust clock for daylight saving changes" setting
|
||||
* correctly on Windows. This is a manual test dependent on making changes to
|
||||
* the platform setting of the machine and thus cannot be automated.
|
||||
* @library /java/awt/regtesthelpers
|
||||
* @build PassFailJFrame
|
||||
* @run main/manual DefaultTimeZoneTest
|
||||
*/
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.Box;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Component;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Window;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
public class DefaultTimeZoneTest {
|
||||
|
||||
private static final SimpleDateFormat SDF =
|
||||
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss zzzz (XXX)");
|
||||
private static final String INSTRUCTIONS =
|
||||
"""
|
||||
Tests the platform time zone detection on all platforms.
|
||||
(Part I) and on/off of DST adjustment on Windows (Part II).
|
||||
|
||||
Part I:
|
||||
Observe the displayed Time zone ID and the local time.
|
||||
Change the platform time zone setting, then click the
|
||||
"Update Time Zone" button. If the ID and local time
|
||||
update correctly, part I passes, otherwise press fail. Note that
|
||||
some time zone IDs have their aliases that may be displayed.
|
||||
For example, "US/Pacific" is an alias of "America/Los_Angeles".
|
||||
If this platform is Windows, proceed to Part II. Otherwise, press
|
||||
the Pass button to complete this test.
|
||||
|
||||
Part II:
|
||||
Note that Part II may require the Administrator privilege to change
|
||||
Windows setting.
|
||||
|
||||
1. Open the Settings app and navigate to Time & Language > Date & Time
|
||||
2. Select any time zone where daylight saving time is *currently*
|
||||
in effect, such as "(GMT-08:00) Pacific Time (US & Canada);
|
||||
Tijuana", "(GMT+10:00) Canberra, Melbourne, Sydney", and Apply.
|
||||
3. After pressing "Update Time Zone" button, observe that the local
|
||||
time on the Settings app and the test local time are the same (daylight time).
|
||||
4. Turn off "Adjust for daylight saving time automatically"
|
||||
5. Observe the two local times should be the same (standard time).
|
||||
6. Turn on "Adjust for daylight saving time automatically"
|
||||
|
||||
If the local time in the Settings app and test window are always the same,
|
||||
then this test passes. Press the Pass or Fail button based on the Part II
|
||||
result and complete the test.
|
||||
""";
|
||||
|
||||
public static void main(String[] args)
|
||||
throws InterruptedException, InvocationTargetException {
|
||||
// Force platform time zone as default time zone
|
||||
TimeZone.setDefault(null);
|
||||
System.setProperty("user.timezone", "");
|
||||
// Construct test window
|
||||
PassFailJFrame.builder()
|
||||
.title("DefaultTimeZoneTest Instructions")
|
||||
.testUI(createTest())
|
||||
.instructions(INSTRUCTIONS)
|
||||
.build().awaitAndCheck();
|
||||
}
|
||||
|
||||
private static Window createTest() {
|
||||
var contents = new JFrame("DefaultTimeZoneTest");
|
||||
contents.setSize(350, 250);
|
||||
// Panel with vertical layout
|
||||
var panel = new JPanel();
|
||||
panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
|
||||
// Time zone ID label
|
||||
var timeZoneID = new JLabel("Time zone ID: " + SDF.getTimeZone().getID(), SwingConstants.CENTER);
|
||||
timeZoneID.setAlignmentX(Component.CENTER_ALIGNMENT);
|
||||
// Time label
|
||||
var label = new JLabel(SDF.format(new Date()), SwingConstants.CENTER);
|
||||
label.setAlignmentX(Component.CENTER_ALIGNMENT);
|
||||
// Update button
|
||||
var button = new JButton("Update Time Zone");
|
||||
button.setAlignmentX(Component.CENTER_ALIGNMENT);
|
||||
// Add components with spacing
|
||||
panel.add(Box.createRigidArea(new Dimension(0, 10)));
|
||||
panel.add(timeZoneID);
|
||||
panel.add(Box.createRigidArea(new Dimension(0, 5)));
|
||||
panel.add(label);
|
||||
panel.add(Box.createRigidArea(new Dimension(0, 10)));
|
||||
panel.add(button);
|
||||
contents.add(panel);
|
||||
|
||||
// Update default time zone on button click
|
||||
button.addActionListener(e -> {
|
||||
// Clear JVM cached timezone and force reload from OS
|
||||
TimeZone.setDefault(null);
|
||||
System.setProperty("user.timezone", "");
|
||||
TimeZone tz = TimeZone.getDefault();
|
||||
SDF.setTimeZone(tz);
|
||||
timeZoneID.setText("Time zone ID: " + tz.getID());
|
||||
label.setText(SDF.format(new Date()));
|
||||
contents.repaint();
|
||||
});
|
||||
return contents;
|
||||
}
|
||||
}
|
||||
67
test/jdk/java/util/TimeZone/HongKong.java
Normal file
67
test/jdk/java/util/TimeZone/HongKong.java
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4487276 8008577 8174269
|
||||
* @modules jdk.localedata
|
||||
* @summary Verify that Hong Kong locale uses traditional Chinese names.
|
||||
* @run main/othervm HongKong
|
||||
*/
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
public class HongKong {
|
||||
public static void main(String[] args) {
|
||||
Locale reservedLocale = Locale.getDefault();
|
||||
try {
|
||||
Locale.setDefault(Locale.of("zh", "HK"));
|
||||
checkCountry(Locale.GERMANY, "\u5fb7\u570b");
|
||||
checkCountry(Locale.FRANCE, "\u6cd5\u570b");
|
||||
checkCountry(Locale.ITALY, "\u610f\u5927\u5229");
|
||||
checkTimeZone("Asia/Shanghai",
|
||||
"\u4e2d\u570b\u6a19\u6e96\u6642\u9593");
|
||||
} finally {
|
||||
// restore the reserved locale
|
||||
Locale.setDefault(reservedLocale);
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkCountry(Locale country, String expected) {
|
||||
String actual = country.getDisplayCountry();
|
||||
if (!expected.equals(actual)) {
|
||||
throw new RuntimeException("Failed. actual: %s, expected: %s"
|
||||
.formatted(actual, expected));
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkTimeZone(String timeZoneID, String expected) {
|
||||
TimeZone timeZone = TimeZone.getTimeZone(timeZoneID);
|
||||
String actual = timeZone.getDisplayName();
|
||||
if (!expected.equals(actual)) {
|
||||
throw new RuntimeException("Failed. actual: %s, expected: %s"
|
||||
.formatted(actual, expected));
|
||||
}
|
||||
}
|
||||
}
|
||||
131
test/jdk/java/util/TimeZone/IDTest.java
Normal file
131
test/jdk/java/util/TimeZone/IDTest.java
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* Copyright (c) 2002, 2025, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4509255 5055567 6176318 7090844 8347841 8347955
|
||||
* @summary Tests consistencies of time zone IDs.
|
||||
*/
|
||||
|
||||
import java.time.ZoneId;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
import java.util.TreeMap;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class IDTest {
|
||||
public static void main(String[] args) {
|
||||
Set<String> ids = new HashSet<>();
|
||||
Map<Integer, Set<String>> tree = new TreeMap<>();
|
||||
|
||||
String[] tzs = TimeZone.availableIDs()
|
||||
.filter(Predicate.not(ZoneId.SHORT_IDS::containsKey))
|
||||
.toArray(String[]::new);
|
||||
String[] tzs2 = TimeZone.availableIDs()
|
||||
.filter(Predicate.not(ZoneId.SHORT_IDS::containsKey))
|
||||
.toArray(String[]::new);
|
||||
if (tzs.length != tzs2.length) {
|
||||
throw new RuntimeException("tzs.length(" + tzs.length
|
||||
+ ") != tzs2.length(" + tzs2.length + ")");
|
||||
}
|
||||
for (int i = 0; i < tzs.length; i++) {
|
||||
if (tzs[i] != tzs2[i]) {
|
||||
throw new RuntimeException(i + ": " + tzs[i] + " != " + tzs2[i]);
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("Total: " + tzs.length + " time zone IDs");
|
||||
for (String id : tzs) {
|
||||
ids.add(id);
|
||||
TimeZone tz = TimeZone.getTimeZone(id);
|
||||
Integer offset = tz.getRawOffset();
|
||||
Set<String> s = tree.get(offset);
|
||||
if (s == null) {
|
||||
s = new HashSet<>();
|
||||
tree.put(offset, s);
|
||||
}
|
||||
s.add(id);
|
||||
}
|
||||
|
||||
for (Integer key : tree.keySet()) {
|
||||
Set<String> s1 = tree.get(key);
|
||||
|
||||
// Make sure no duplicates in the other sets
|
||||
for (Integer k : tree.keySet()) {
|
||||
if (k.equals(key)) {
|
||||
continue;
|
||||
}
|
||||
Set<String> s2 = new HashSet<>(tree.get(k));
|
||||
s2.retainAll(s1);
|
||||
if (!s2.isEmpty()) {
|
||||
throw new RuntimeException("s1 included in the subset for " + (k.intValue()/60000) +
|
||||
" (" + s2 + " shouldn't be in s1)");
|
||||
}
|
||||
}
|
||||
|
||||
// Check the getAvailableIDs(int) call to return the same
|
||||
// set of IDs
|
||||
int offset = key.intValue();
|
||||
tzs = TimeZone.availableIDs(offset)
|
||||
.filter(Predicate.not(ZoneId.SHORT_IDS::containsKey))
|
||||
.toArray(String[]::new);
|
||||
tzs2 = TimeZone.availableIDs(offset)
|
||||
.filter(Predicate.not(ZoneId.SHORT_IDS::containsKey))
|
||||
.toArray(String[]::new);
|
||||
if (!Arrays.equals(tzs, tzs2)) {
|
||||
throw new RuntimeException("inconsistent tzs from getAvailableIDs("+offset+")");
|
||||
}
|
||||
Set<String> s2 = new HashSet<>();
|
||||
s2.addAll(Arrays.asList(tzs));
|
||||
if (!s1.equals(s2)) {
|
||||
throw new RuntimeException("s1 != s2 for " + offset/60000 +
|
||||
" (diff=" + getDiff(s1, s2) + ")");
|
||||
}
|
||||
if (!ids.containsAll(s2)) {
|
||||
throw new RuntimeException("s2 isn't a subset of ids (" + getDiff(s2, ids) +
|
||||
" not in ids)");
|
||||
}
|
||||
}
|
||||
|
||||
for (Integer key : tree.keySet()) {
|
||||
Set<String> s1 = tree.get(key);
|
||||
ids.removeAll(s1);
|
||||
}
|
||||
if (!ids.isEmpty()) {
|
||||
throw new RuntimeException("ids didn't become empty. (" + ids + ")");
|
||||
}
|
||||
}
|
||||
|
||||
private static String getDiff(Set<String> set1, Set<String> set2) {
|
||||
Set<String> s1 = new HashSet<>(set1);
|
||||
s1.removeAll(set2);
|
||||
|
||||
Set<String> s2 = new HashSet<>(set2);
|
||||
s2.removeAll(set1);
|
||||
s2.addAll(s1);
|
||||
return s2.toString();
|
||||
}
|
||||
}
|
||||
47
test/jdk/java/util/TimeZone/ListTimeZones.java
Normal file
47
test/jdk/java/util/TimeZone/ListTimeZones.java
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2009, 2025, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 6851214 8347841 8347955
|
||||
* @summary Allow 24:00 as a valid end/start DST time stamp
|
||||
* @run main ListTimeZones
|
||||
*/
|
||||
|
||||
import java.time.ZoneId;
|
||||
import java.util.*;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class ListTimeZones{
|
||||
public static void main(String[] args){
|
||||
Date date = new Date();
|
||||
String[] TimeZoneIds = TimeZone.availableIDs()
|
||||
.filter(Predicate.not(ZoneId.SHORT_IDS::containsKey))
|
||||
.toArray(String[]::new);
|
||||
for(int i = 0; i < TimeZoneIds.length; i++){
|
||||
TimeZone tz = TimeZone.getTimeZone(TimeZoneIds[i]);
|
||||
Calendar calendar = new GregorianCalendar(tz);
|
||||
String calString = calendar.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
98
test/jdk/java/util/TimeZone/NegativeDSTTest.java
Normal file
98
test/jdk/java/util/TimeZone/NegativeDSTTest.java
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (c) 2019, 2025, 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.
|
||||
*/
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8212970 8324065
|
||||
* @summary Test whether the savings are positive in time zones that have
|
||||
* negative savings in the source TZ files.
|
||||
* @run junit NegativeDSTTest
|
||||
*/
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
public class NegativeDSTTest {
|
||||
|
||||
private static final TimeZone DUBLIN = TimeZone.getTimeZone("Europe/Dublin");
|
||||
private static final TimeZone PRAGUE = TimeZone.getTimeZone("Europe/Prague");
|
||||
private static final TimeZone WINDHOEK = TimeZone.getTimeZone("Africa/Windhoek");
|
||||
private static final TimeZone CASABLANCA = TimeZone.getTimeZone("Africa/Casablanca");
|
||||
private static final int ONE_HOUR = 3600_000;
|
||||
|
||||
private Object[][] negativeDST () {
|
||||
return new Object[][] {
|
||||
// TimeZone, localDate, offset, isDaylightSavings
|
||||
// Europe/Dublin for the Rule "Eire"
|
||||
{DUBLIN, LocalDate.of(1970, 6, 23), ONE_HOUR, true},
|
||||
{DUBLIN, LocalDate.of(1971, 6, 23), ONE_HOUR, true},
|
||||
{DUBLIN, LocalDate.of(1971, 11, 1), 0, false},
|
||||
{DUBLIN, LocalDate.of(2019, 6, 23), ONE_HOUR, true},
|
||||
{DUBLIN, LocalDate.of(2019, 12, 23), 0, false},
|
||||
|
||||
// Europe/Prague which contains fixed negative savings (not a named Rule)
|
||||
{PRAGUE, LocalDate.of(1946, 9, 30), 2 * ONE_HOUR, true},
|
||||
{PRAGUE, LocalDate.of(1946, 10, 10), ONE_HOUR, false},
|
||||
{PRAGUE, LocalDate.of(1946, 12, 3), 0, false},
|
||||
{PRAGUE, LocalDate.of(1947, 2, 25), ONE_HOUR, false},
|
||||
{PRAGUE, LocalDate.of(1947, 4, 30), 2 * ONE_HOUR, true},
|
||||
|
||||
// Africa/Windhoek for the Rule "Namibia"
|
||||
{WINDHOEK, LocalDate.of(1994, 3, 23), ONE_HOUR, false},
|
||||
{WINDHOEK, LocalDate.of(2016, 9, 23), 2 * ONE_HOUR, true},
|
||||
|
||||
// Africa/Casablanca for the Rule "Morocco" Defines negative DST till 2037 as of 2019a.
|
||||
{CASABLANCA, LocalDate.of(1939, 9, 13), ONE_HOUR, true},
|
||||
{CASABLANCA, LocalDate.of(1939, 11, 20), 0, false},
|
||||
{CASABLANCA, LocalDate.of(2018, 6, 18), ONE_HOUR, true},
|
||||
{CASABLANCA, LocalDate.of(2019, 1, 1), ONE_HOUR, true},
|
||||
{CASABLANCA, LocalDate.of(2019, 5, 6), 0, false},
|
||||
{CASABLANCA, LocalDate.of(2037, 10, 5), 0, false},
|
||||
{CASABLANCA, LocalDate.of(2037, 11, 16), ONE_HOUR, true},
|
||||
{CASABLANCA, LocalDate.of(2038, 9, 27), 0, false},
|
||||
{CASABLANCA, LocalDate.of(2038, 11, 1), ONE_HOUR, true},
|
||||
{CASABLANCA, LocalDate.of(2087, 3, 31), 0, false},
|
||||
{CASABLANCA, LocalDate.of(2087, 5, 12), ONE_HOUR, true},
|
||||
};
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("negativeDST")
|
||||
public void test_NegativeDST(TimeZone tz, LocalDate ld, int offset, boolean isDST) {
|
||||
Date d = Date.from(Instant.from(ZonedDateTime.of(ld, LocalTime.MIN, tz.toZoneId())));
|
||||
assertEquals(offset, tz.getOffset(d.getTime()));
|
||||
assertEquals(isDST, tz.inDaylightTime(d));
|
||||
}
|
||||
}
|
||||
137
test/jdk/java/util/TimeZone/SimpleTimeZoneCloneRaceTest.java
Normal file
137
test/jdk/java/util/TimeZone/SimpleTimeZoneCloneRaceTest.java
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* Copyright (c) 2017, 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.
|
||||
*/
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
import java.util.SimpleTimeZone;
|
||||
import java.util.TimeZone;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8191216
|
||||
* @summary test that provokes race between cloning and lazily initializing
|
||||
* SimpleTimeZone cache fields
|
||||
*/
|
||||
public class SimpleTimeZoneCloneRaceTest {
|
||||
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
|
||||
// shared TZ user repeatedly samples sharedTZ and calculates offset
|
||||
// using the shared instance
|
||||
TimeZoneUser sharedTZuser = new TimeZoneUser(() -> sharedTZ);
|
||||
|
||||
// cloned TZ user repeatedly samples sharedTZ then clones it and
|
||||
// calculates offset using the clone...
|
||||
TimeZoneUser clonedTZuser = new TimeZoneUser(() -> {
|
||||
// sample shared TZ
|
||||
TimeZone tz = sharedTZ;
|
||||
// do some computation that takes roughly the same time as it takes
|
||||
// sharedTZUser to start changing cache fields in shared TZ
|
||||
cpuHogTZ.getOffset(time);
|
||||
// now clone the sampled TZ and return it, hoping the clone is done
|
||||
// at about the right time....
|
||||
return (TimeZone) tz.clone();
|
||||
});
|
||||
|
||||
// start threads
|
||||
Thread t1 = new Thread(sharedTZuser);
|
||||
Thread t2 = new Thread(clonedTZuser);
|
||||
t1.start();
|
||||
t2.start();
|
||||
|
||||
// plant new SimpleTimeZone instances for 2 seconds
|
||||
long t0 = System.currentTimeMillis();
|
||||
do {
|
||||
TimeZone tz1 = createSTZ();
|
||||
TimeZone tz2 = createSTZ();
|
||||
cpuHogTZ = tz1;
|
||||
sharedTZ = tz2;
|
||||
} while (System.currentTimeMillis() - t0 < 2000L);
|
||||
|
||||
sharedTZuser.stop = true;
|
||||
clonedTZuser.stop = true;
|
||||
t1.join();
|
||||
t2.join();
|
||||
|
||||
System.out.println(
|
||||
String.format("shared TZ: %d correct, %d incorrect calculations",
|
||||
sharedTZuser.correctCount, sharedTZuser.incorrectCount)
|
||||
);
|
||||
System.out.println(
|
||||
String.format("cloned TZ: %d correct, %d incorrect calculations",
|
||||
clonedTZuser.correctCount, clonedTZuser.incorrectCount)
|
||||
);
|
||||
if (clonedTZuser.incorrectCount > 0) {
|
||||
throw new RuntimeException(clonedTZuser.incorrectCount +
|
||||
" fatal data races detected");
|
||||
}
|
||||
}
|
||||
|
||||
static SimpleTimeZone createSTZ() {
|
||||
return new SimpleTimeZone(-28800000,
|
||||
"America/Los_Angeles",
|
||||
Calendar.APRIL, 1, -Calendar.SUNDAY,
|
||||
7200000,
|
||||
Calendar.OCTOBER, -1, Calendar.SUNDAY,
|
||||
7200000,
|
||||
3600000);
|
||||
}
|
||||
|
||||
static volatile TimeZone cpuHogTZ = createSTZ();
|
||||
static volatile TimeZone sharedTZ = createSTZ();
|
||||
static final long time;
|
||||
static final long correctOffset;
|
||||
|
||||
static {
|
||||
TimeZone tz = createSTZ();
|
||||
Calendar cal = Calendar.getInstance(tz, Locale.ROOT);
|
||||
cal.set(2000, Calendar.MAY, 1, 0, 0, 0);
|
||||
time = cal.getTimeInMillis();
|
||||
correctOffset = tz.getOffset(time);
|
||||
}
|
||||
|
||||
static class TimeZoneUser implements Runnable {
|
||||
private final Supplier<? extends TimeZone> tzSupplier;
|
||||
|
||||
TimeZoneUser(Supplier<? extends TimeZone> tzSupplier) {
|
||||
this.tzSupplier = tzSupplier;
|
||||
}
|
||||
|
||||
volatile boolean stop;
|
||||
int correctCount, incorrectCount;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (!stop) {
|
||||
TimeZone tz = tzSupplier.get();
|
||||
int offset = tz.getOffset(time);
|
||||
if (offset == correctOffset) {
|
||||
correctCount++;
|
||||
} else {
|
||||
incorrectCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Copyright (c) 2025, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8369184
|
||||
* @summary Checks if equals()/hashCode() of SimpleTimeZone works correctly
|
||||
* @run junit SimpleTimeZoneEqualsHashCodeTest
|
||||
*/
|
||||
|
||||
import java.util.SimpleTimeZone;
|
||||
import static java.util.Calendar.MARCH;
|
||||
import static java.util.Calendar.NOVEMBER;
|
||||
import static java.util.Calendar.SUNDAY;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class SimpleTimeZoneEqualsHashCodeTest {
|
||||
private static final SimpleTimeZone STZ_WITH_DST =
|
||||
new SimpleTimeZone(-288_000_000, "America/Los_Angeles",
|
||||
MARCH, 8, -SUNDAY, 7_200_000,
|
||||
NOVEMBER, 1, -SUNDAY, 7_200_000);
|
||||
private static final SimpleTimeZone STZ_WITHOUT_DST =
|
||||
new SimpleTimeZone(0, "foo");
|
||||
|
||||
@Test
|
||||
void withDSTTest() {
|
||||
var stz = (SimpleTimeZone)STZ_WITH_DST.clone();
|
||||
assertEquals(STZ_WITH_DST, stz);
|
||||
assertEquals(STZ_WITH_DST.hashCode(), stz.hashCode());
|
||||
|
||||
stz.setEndRule(NOVEMBER, 8, -SUNDAY, 7_200_000);
|
||||
assertNotEquals(STZ_WITH_DST, stz);
|
||||
// From the contract point, hash codes may be the same.
|
||||
// This tests the implementation which considers DST
|
||||
// related fields for calculating the hash code.
|
||||
assertNotEquals(STZ_WITH_DST.hashCode(), stz.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
void withoutDSTTest() {
|
||||
var stz = (SimpleTimeZone)STZ_WITHOUT_DST.clone();
|
||||
|
||||
// Only setting start rule. Still considered non-DST zone
|
||||
stz.setStartRule(MARCH, 8, -SUNDAY, 7_200_000);
|
||||
assertTrue(!stz.useDaylightTime());
|
||||
assertEquals(STZ_WITHOUT_DST, stz);
|
||||
assertEquals(STZ_WITHOUT_DST.hashCode(), stz.hashCode());
|
||||
|
||||
// Setting end rule as well. Now it is considered DST zone
|
||||
stz.setEndRule(NOVEMBER, 8, -SUNDAY, 7_200_000);
|
||||
assertTrue(stz.useDaylightTime());
|
||||
assertNotEquals(STZ_WITHOUT_DST, stz);
|
||||
// From the contract point, hash codes may be the same.
|
||||
// This tests the implementation which considers DST
|
||||
// related fields for calculating the hash code.
|
||||
assertNotEquals(STZ_WITHOUT_DST.hashCode(), stz.hashCode());
|
||||
}
|
||||
}
|
||||
94
test/jdk/java/util/TimeZone/TextFileReader.java
Normal file
94
test/jdk/java/util/TimeZone/TextFileReader.java
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright (c) 2008, 2022, 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.
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
|
||||
// This class is public so that tools can invoke.
|
||||
public class TextFileReader implements AutoCloseable {
|
||||
private BufferedReader reader;
|
||||
private int lineNo;
|
||||
|
||||
public TextFileReader(String filename) throws IOException {
|
||||
this(new File(new File(System.getProperty("test.src", "."),
|
||||
"TimeZoneData"),
|
||||
filename));
|
||||
}
|
||||
|
||||
public TextFileReader(File file) throws IOException {
|
||||
InputStream is = new FileInputStream(file);
|
||||
reader = new BufferedReader(new InputStreamReader(is, "utf-8"));
|
||||
}
|
||||
|
||||
public String readLine() throws IOException {
|
||||
return getLine();
|
||||
}
|
||||
|
||||
public String getLine() throws IOException {
|
||||
checkReader();
|
||||
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
lineNo++;
|
||||
line = line.trim();
|
||||
// Skip blank and comment lines.
|
||||
if (line.length() == 0) {
|
||||
continue;
|
||||
}
|
||||
int x = line.indexOf('#');
|
||||
if (x == 0) {
|
||||
continue;
|
||||
}
|
||||
if (x > 0) {
|
||||
line = line.substring(0, x).trim();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
public String getRawLine() throws IOException {
|
||||
checkReader();
|
||||
|
||||
String line = reader.readLine();
|
||||
if (line != null) {
|
||||
lineNo++;
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
private void checkReader() throws IOException {
|
||||
if (reader == null) {
|
||||
throw new IOException("This TextFileReader has been closed.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
reader.close();
|
||||
reader = null;
|
||||
}
|
||||
|
||||
int getLineNo() {
|
||||
return lineNo;
|
||||
}
|
||||
}
|
||||
59
test/jdk/java/util/TimeZone/ThreeLetterZoneID.java
Normal file
59
test/jdk/java/util/TimeZone/ThreeLetterZoneID.java
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (c) 2025, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8342550 8349873
|
||||
* @summary Three-letter time zone IDs should output a deprecated warning
|
||||
* message.
|
||||
* @library /test/lib
|
||||
* @build jdk.test.lib.process.ProcessTools
|
||||
* @run junit ThreeLetterZoneID
|
||||
*/
|
||||
import java.util.TimeZone;
|
||||
import jdk.test.lib.process.ProcessTools;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class ThreeLetterZoneID {
|
||||
private static final String WARNING =
|
||||
"WARNING: Use of the three-letter time zone ID \"PST\" is deprecated and it will be removed in a future release";
|
||||
|
||||
public static void main(String... args) {
|
||||
if (args.length > 0) {
|
||||
TimeZone.getTimeZone("PST");
|
||||
} else {
|
||||
TimeZone.getDefault();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExplicitGetTimeZone() throws Exception {
|
||||
ProcessTools.executeTestJava("ThreeLetterZoneID", "dummy").stderrShouldMatch(WARNING);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSysProp() throws Exception {
|
||||
ProcessTools.executeTestJava("-Duser.timezone=PST", "ThreeLetterZoneID").stderrShouldMatch(WARNING);
|
||||
}
|
||||
}
|
||||
424
test/jdk/java/util/TimeZone/TimeZoneBoundaryTest.java
Normal file
424
test/jdk/java/util/TimeZone/TimeZoneBoundaryTest.java
Normal file
|
|
@ -0,0 +1,424 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2025, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8347841
|
||||
* @summary test Time Zone Boundary
|
||||
* @run junit TimeZoneBoundaryTest
|
||||
*/
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.SimpleTimeZone;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
/**
|
||||
* A test which discovers the boundaries of DST programmatically and verifies
|
||||
* that they are correct.
|
||||
*/
|
||||
public class TimeZoneBoundaryTest
|
||||
{
|
||||
static final int ONE_SECOND = 1000;
|
||||
static final int ONE_MINUTE = 60*ONE_SECOND;
|
||||
static final int ONE_HOUR = 60*ONE_MINUTE;
|
||||
static final long ONE_DAY = 24*ONE_HOUR;
|
||||
static final long ONE_YEAR = (long)(365.25 * ONE_DAY);
|
||||
static final long SIX_MONTHS = ONE_YEAR / 2;
|
||||
|
||||
static final int MONTH_LENGTH[] = {31,29,31,30,31,30,31,31,30,31,30,31};
|
||||
|
||||
// These values are empirically determined to be correct
|
||||
static final long PST_1997_BEG = 860320800000L;
|
||||
static final long PST_1997_END = 877856400000L;
|
||||
|
||||
// Minimum interval for binary searches in ms; should be no larger
|
||||
// than 1000.
|
||||
static final long INTERVAL = 10; // Milliseconds
|
||||
|
||||
static final String AUSTRALIA = "Australia/Adelaide";
|
||||
static final long AUSTRALIA_1997_BEG = 877797000000L;
|
||||
static final long AUSTRALIA_1997_END = 859653000000L;
|
||||
|
||||
/**
|
||||
* Date.toString().substring() Boundary Test
|
||||
* Look for a DST changeover to occur within 6 months of the given Date.
|
||||
* The initial Date.toString() should yield a string containing the
|
||||
* startMode as a SUBSTRING. The boundary will be tested to be
|
||||
* at the expectedBoundary value.
|
||||
*/
|
||||
void findDaylightBoundaryUsingDate(Date d, String startMode, long expectedBoundary)
|
||||
{
|
||||
// Given a date with a year start, find the Daylight onset
|
||||
// and end. The given date should be 1/1/xx in some year.
|
||||
|
||||
if (d.toString().indexOf(startMode) == -1)
|
||||
{
|
||||
System.out.println("Error: " + startMode + " not present in " + d);
|
||||
}
|
||||
|
||||
// Use a binary search, assuming that we have a Standard
|
||||
// time at the midpoint.
|
||||
long min = d.getTime();
|
||||
long max = min + SIX_MONTHS;
|
||||
|
||||
while ((max - min) > INTERVAL)
|
||||
{
|
||||
long mid = (min + max) >> 1;
|
||||
String s = new Date(mid).toString();
|
||||
// logln(s);
|
||||
if (s.indexOf(startMode) != -1)
|
||||
{
|
||||
min = mid;
|
||||
}
|
||||
else
|
||||
{
|
||||
max = mid;
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("Date Before: " + showDate(min));
|
||||
System.out.println("Date After: " + showDate(max));
|
||||
long mindelta = expectedBoundary - min;
|
||||
long maxdelta = max - expectedBoundary;
|
||||
if (mindelta >= 0 && mindelta <= INTERVAL &&
|
||||
mindelta >= 0 && mindelta <= INTERVAL)
|
||||
System.out.println("PASS: Expected boundary at " + expectedBoundary);
|
||||
else
|
||||
fail("FAIL: Expected boundary at " + expectedBoundary);
|
||||
}
|
||||
|
||||
void findDaylightBoundaryUsingTimeZone(Date d, boolean startsInDST, long expectedBoundary)
|
||||
{
|
||||
findDaylightBoundaryUsingTimeZone(d, startsInDST, expectedBoundary,
|
||||
TimeZone.getDefault());
|
||||
}
|
||||
|
||||
void findDaylightBoundaryUsingTimeZone(Date d, boolean startsInDST,
|
||||
long expectedBoundary, TimeZone tz)
|
||||
{
|
||||
// Given a date with a year start, find the Daylight onset
|
||||
// and end. The given date should be 1/1/xx in some year.
|
||||
|
||||
// Use a binary search, assuming that we have a Standard
|
||||
// time at the midpoint.
|
||||
long min = d.getTime();
|
||||
long max = min + SIX_MONTHS;
|
||||
|
||||
if (tz.inDaylightTime(d) != startsInDST)
|
||||
{
|
||||
fail("FAIL: " + tz.getID() + " inDaylightTime(" +
|
||||
d + ") != " + startsInDST);
|
||||
startsInDST = !startsInDST; // Flip over; find the apparent value
|
||||
}
|
||||
|
||||
if (tz.inDaylightTime(new Date(max)) == startsInDST)
|
||||
{
|
||||
fail("FAIL: " + tz.getID() + " inDaylightTime(" +
|
||||
(new Date(max)) + ") != " + (!startsInDST));
|
||||
return;
|
||||
}
|
||||
|
||||
while ((max - min) > INTERVAL)
|
||||
{
|
||||
long mid = (min + max) >> 1;
|
||||
boolean isIn = tz.inDaylightTime(new Date(mid));
|
||||
if (isIn == startsInDST)
|
||||
{
|
||||
min = mid;
|
||||
}
|
||||
else
|
||||
{
|
||||
max = mid;
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println(tz.getID() + " Before: " + showDate(min, tz));
|
||||
System.out.println(tz.getID() + " After: " + showDate(max, tz));
|
||||
|
||||
long mindelta = expectedBoundary - min;
|
||||
long maxdelta = max - expectedBoundary;
|
||||
if (mindelta >= 0 && mindelta <= INTERVAL &&
|
||||
mindelta >= 0 && mindelta <= INTERVAL)
|
||||
System.out.println("PASS: Expected boundary at " + expectedBoundary);
|
||||
else
|
||||
fail("FAIL: Expected boundary at " + expectedBoundary);
|
||||
}
|
||||
|
||||
private static String showDate(long l)
|
||||
{
|
||||
return showDate(new Date(l));
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private static String showDate(Date d)
|
||||
{
|
||||
return "" + d.getYear() + "/" + showNN(d.getMonth()+1) + "/" + showNN(d.getDate()) +
|
||||
" " + showNN(d.getHours()) + ":" + showNN(d.getMinutes()) +
|
||||
" \"" + d + "\" = " +
|
||||
d.getTime();
|
||||
}
|
||||
|
||||
private static String showDate(long l, TimeZone z)
|
||||
{
|
||||
return showDate(new Date(l), z);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private static String showDate(Date d, TimeZone zone)
|
||||
{
|
||||
DateFormat fmt = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
|
||||
fmt.setTimeZone(zone);
|
||||
return "" + d.getYear() + "/" + showNN(d.getMonth()+1) + "/" + showNN(d.getDate()) +
|
||||
" " + showNN(d.getHours()) + ":" + showNN(d.getMinutes()) +
|
||||
" \"" + d + "\" = " +
|
||||
fmt.format(d);
|
||||
}
|
||||
|
||||
private static String showNN(int n)
|
||||
{
|
||||
return ((n < 10) ? "0" : "") + n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a date, a TimeZone, and expected values for inDaylightTime,
|
||||
* useDaylightTime, zone and DST offset, verify that this is the case.
|
||||
*/
|
||||
void verifyDST(Date d, TimeZone time_zone,
|
||||
boolean expUseDaylightTime, boolean expInDaylightTime,
|
||||
int expZoneOffset, int expDSTOffset)
|
||||
{
|
||||
System.out.println("-- Verifying time " + d +
|
||||
" in zone " + time_zone.getID());
|
||||
|
||||
if (time_zone.inDaylightTime(d) == expInDaylightTime)
|
||||
System.out.println("PASS: inDaylightTime = " + time_zone.inDaylightTime(d));
|
||||
else
|
||||
fail("FAIL: inDaylightTime = " + time_zone.inDaylightTime(d));
|
||||
|
||||
if (time_zone.useDaylightTime() == expUseDaylightTime)
|
||||
System.out.println("PASS: useDaylightTime = " + time_zone.useDaylightTime());
|
||||
else
|
||||
fail("FAIL: useDaylightTime = " + time_zone.useDaylightTime());
|
||||
|
||||
if (time_zone.getRawOffset() == expZoneOffset)
|
||||
System.out.println("PASS: getRawOffset() = " + expZoneOffset/(double)ONE_HOUR);
|
||||
else
|
||||
fail("FAIL: getRawOffset() = " + time_zone.getRawOffset()/(double)ONE_HOUR +
|
||||
"; expected " + expZoneOffset/(double)ONE_HOUR);
|
||||
|
||||
GregorianCalendar gc = new GregorianCalendar(time_zone);
|
||||
gc.setTime(d);
|
||||
int offset = time_zone.getOffset(gc.get(gc.ERA), gc.get(gc.YEAR), gc.get(gc.MONTH),
|
||||
gc.get(gc.DAY_OF_MONTH), gc.get(gc.DAY_OF_WEEK),
|
||||
((gc.get(gc.HOUR_OF_DAY) * 60 +
|
||||
gc.get(gc.MINUTE)) * 60 +
|
||||
gc.get(gc.SECOND)) * 1000 +
|
||||
gc.get(gc.MILLISECOND));
|
||||
if (offset == expDSTOffset)
|
||||
System.out.println("PASS: getOffset() = " + offset/(double)ONE_HOUR);
|
||||
else
|
||||
fail("FAIL: getOffset() = " + offset/(double)ONE_HOUR +
|
||||
"; expected " + expDSTOffset/(double)ONE_HOUR);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Test
|
||||
public void TestBoundaries()
|
||||
{
|
||||
TimeZone pst = TimeZone.getTimeZone("America/Los_Angeles");
|
||||
TimeZone save = TimeZone.getDefault();
|
||||
try {
|
||||
TimeZone.setDefault(pst);
|
||||
|
||||
// DST changeover for PST is 4/6/1997 at 2 hours past midnight
|
||||
Date d = new Date(97,Calendar.APRIL,6);
|
||||
|
||||
// i is minutes past midnight standard time
|
||||
for (int i=60; i<=180; i+=15)
|
||||
{
|
||||
boolean inDST = (i >= 120);
|
||||
Date e = new Date(d.getTime() + i*60*1000);
|
||||
verifyDST(e, pst, true, inDST, -8*ONE_HOUR,
|
||||
inDST ? -7*ONE_HOUR : -8*ONE_HOUR);
|
||||
}
|
||||
|
||||
System.out.println("========================================");
|
||||
findDaylightBoundaryUsingDate(new Date(97,0,1), "PST", PST_1997_BEG);
|
||||
System.out.println("========================================");
|
||||
findDaylightBoundaryUsingDate(new Date(97,6,1), "PDT", PST_1997_END);
|
||||
|
||||
// Southern hemisphere test
|
||||
System.out.println("========================================");
|
||||
TimeZone z = TimeZone.getTimeZone(AUSTRALIA);
|
||||
findDaylightBoundaryUsingTimeZone(new Date(97,0,1), true, AUSTRALIA_1997_END, z);
|
||||
|
||||
System.out.println("========================================");
|
||||
findDaylightBoundaryUsingTimeZone(new Date(97,0,1), false, PST_1997_BEG);
|
||||
System.out.println("========================================");
|
||||
findDaylightBoundaryUsingTimeZone(new Date(97,6,1), true, PST_1997_END);
|
||||
} finally {
|
||||
TimeZone.setDefault(save);
|
||||
}
|
||||
}
|
||||
|
||||
void testUsingBinarySearch(SimpleTimeZone tz, Date d, long expectedBoundary)
|
||||
{
|
||||
// Given a date with a year start, find the Daylight onset
|
||||
// and end. The given date should be 1/1/xx in some year.
|
||||
|
||||
// Use a binary search, assuming that we have a Standard
|
||||
// time at the midpoint.
|
||||
long min = d.getTime();
|
||||
long max = min + (long)(365.25 / 2 * ONE_DAY);
|
||||
|
||||
// First check the boundaries
|
||||
boolean startsInDST = tz.inDaylightTime(d);
|
||||
|
||||
if (tz.inDaylightTime(new Date(max)) == startsInDST)
|
||||
{
|
||||
System.out.println("Error: inDaylightTime(" + (new Date(max)) + ") != " + (!startsInDST));
|
||||
}
|
||||
|
||||
while ((max - min) > INTERVAL)
|
||||
{
|
||||
long mid = (min + max) >> 1;
|
||||
if (tz.inDaylightTime(new Date(mid)) == startsInDST)
|
||||
{
|
||||
min = mid;
|
||||
}
|
||||
else
|
||||
{
|
||||
max = mid;
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("Binary Search Before: " + showDate(min));
|
||||
System.out.println("Binary Search After: " + showDate(max));
|
||||
|
||||
long mindelta = expectedBoundary - min;
|
||||
long maxdelta = max - expectedBoundary;
|
||||
if (mindelta >= 0 && mindelta <= INTERVAL &&
|
||||
mindelta >= 0 && mindelta <= INTERVAL)
|
||||
System.out.println("PASS: Expected boundary at " + expectedBoundary);
|
||||
else
|
||||
fail("FAIL: Expected boundary at " + expectedBoundary);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test new rule formats.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@Test
|
||||
public void TestNewRules() {
|
||||
// Doesn't matter what the default TimeZone is here, since we
|
||||
// are creating our own TimeZone objects.
|
||||
|
||||
SimpleTimeZone tz;
|
||||
|
||||
System.out.println("-----------------------------------------------------------------");
|
||||
System.out.println("Aug 2ndTues .. Mar 15");
|
||||
tz = new SimpleTimeZone(-8*ONE_HOUR, "Test_1",
|
||||
Calendar.AUGUST, 2, Calendar.TUESDAY, 2*ONE_HOUR,
|
||||
Calendar.MARCH, 15, 0, 2*ONE_HOUR);
|
||||
System.out.println("========================================");
|
||||
testUsingBinarySearch(tz, new Date(97,0,1), 858416400000L);
|
||||
System.out.println("========================================");
|
||||
testUsingBinarySearch(tz, new Date(97,6,1), 871380000000L);
|
||||
|
||||
System.out.println("-----------------------------------------------------------------");
|
||||
System.out.println("Apr Wed>=14 .. Sep Sun<=20");
|
||||
tz = new SimpleTimeZone(-8*ONE_HOUR, "Test_2",
|
||||
Calendar.APRIL, 14, -Calendar.WEDNESDAY, 2*ONE_HOUR,
|
||||
Calendar.SEPTEMBER, -20, -Calendar.SUNDAY, 2*ONE_HOUR);
|
||||
System.out.println("========================================");
|
||||
testUsingBinarySearch(tz, new Date(97,0,1), 861184800000L);
|
||||
System.out.println("========================================");
|
||||
testUsingBinarySearch(tz, new Date(97,6,1), 874227600000L);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find boundaries by stepping.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
void findBoundariesStepwise(int year, long interval, TimeZone z, int expectedChanges)
|
||||
{
|
||||
Date d = new Date(year - 1900, Calendar.JANUARY, 1);
|
||||
long time = d.getTime(); // ms
|
||||
long limit = time + ONE_YEAR + ONE_DAY;
|
||||
boolean lastState = z.inDaylightTime(d);
|
||||
int changes = 0;
|
||||
System.out.println("-- Zone " + z.getID() + " starts in " + year + " with DST = " + lastState);
|
||||
System.out.println("useDaylightTime = " + z.useDaylightTime());
|
||||
while (time < limit)
|
||||
{
|
||||
d.setTime(time);
|
||||
boolean state = z.inDaylightTime(d);
|
||||
if (state != lastState)
|
||||
{
|
||||
System.out.println((state ? "Entry " : "Exit ") +
|
||||
"at " + d);
|
||||
lastState = state;
|
||||
++changes;
|
||||
}
|
||||
time += interval;
|
||||
}
|
||||
if (changes == 0)
|
||||
{
|
||||
if (!lastState && !z.useDaylightTime()) System.out.println("No DST");
|
||||
else fail("FAIL: Timezone<" + z.getID() + "> DST all year, or no DST with true useDaylightTime");
|
||||
}
|
||||
else if (changes != 2)
|
||||
{
|
||||
fail("FAIL: Timezone<" + z.getID() + "> " + changes + " changes seen; should see 0 or 2");
|
||||
}
|
||||
else if (!z.useDaylightTime())
|
||||
{
|
||||
fail("FAIL: Timezone<" + z.getID() + "> useDaylightTime false but 2 changes seen");
|
||||
}
|
||||
if (changes != expectedChanges)
|
||||
{
|
||||
fail("FAIL: Timezone<" + z.getID() + "> " + changes + " changes seen; expected " + expectedChanges);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void TestStepwise()
|
||||
{
|
||||
findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("Australia/Darwin"), 0);
|
||||
findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("Pacific/Honolulu"), 0);
|
||||
findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("PST8PDT"), 2);
|
||||
findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("SystemV/PST"), 0);
|
||||
findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("SystemV/PST8PDT"), 2);
|
||||
findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("Japan"), 0);
|
||||
findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("Europe/Paris"), 2);
|
||||
findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("America/Los_Angeles"), 2);
|
||||
findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone(AUSTRALIA), 2);
|
||||
}
|
||||
}
|
||||
1
test/jdk/java/util/TimeZone/TimeZoneData/VERSION
Normal file
1
test/jdk/java/util/TimeZone/TimeZoneData/VERSION
Normal file
|
|
@ -0,0 +1 @@
|
|||
tzdata2026a
|
||||
256
test/jdk/java/util/TimeZone/TimeZoneData/aliases.txt
Normal file
256
test/jdk/java/util/TimeZone/TimeZoneData/aliases.txt
Normal file
|
|
@ -0,0 +1,256 @@
|
|||
Link Australia/Sydney Australia/ACT #= Australia/Canberra
|
||||
Link Australia/Lord_Howe Australia/LHI
|
||||
Link Australia/Sydney Australia/NSW
|
||||
Link Australia/Darwin Australia/North
|
||||
Link Australia/Brisbane Australia/Queensland
|
||||
Link Australia/Adelaide Australia/South
|
||||
Link Australia/Hobart Australia/Tasmania
|
||||
Link Australia/Melbourne Australia/Victoria
|
||||
Link Australia/Perth Australia/West
|
||||
Link Australia/Broken_Hill Australia/Yancowinna
|
||||
Link America/Rio_Branco Brazil/Acre #= America/Porto_Acre
|
||||
Link America/Noronha Brazil/DeNoronha
|
||||
Link America/Sao_Paulo Brazil/East
|
||||
Link America/Manaus Brazil/West
|
||||
Link Europe/Brussels CET
|
||||
Link America/Chicago CST6CDT
|
||||
Link America/Halifax Canada/Atlantic
|
||||
Link America/Winnipeg Canada/Central
|
||||
Link America/Toronto Canada/Eastern
|
||||
Link America/Edmonton Canada/Mountain
|
||||
Link America/St_Johns Canada/Newfoundland
|
||||
Link America/Vancouver Canada/Pacific
|
||||
Link America/Regina Canada/Saskatchewan
|
||||
Link America/Whitehorse Canada/Yukon
|
||||
Link America/Santiago Chile/Continental
|
||||
Link Pacific/Easter Chile/EasterIsland
|
||||
Link America/Havana Cuba
|
||||
Link Europe/Athens EET
|
||||
Link America/Panama EST
|
||||
Link America/New_York EST5EDT
|
||||
Link Africa/Cairo Egypt
|
||||
Link Europe/Dublin Eire
|
||||
Link Etc/GMT Etc/GMT+0
|
||||
Link Etc/GMT Etc/GMT-0
|
||||
Link Etc/GMT Etc/GMT0
|
||||
Link Etc/GMT Etc/Greenwich
|
||||
Link Etc/UTC Etc/UCT
|
||||
Link Etc/UTC Etc/Universal
|
||||
Link Etc/UTC Etc/Zulu
|
||||
Link Europe/London GB
|
||||
Link Europe/London GB-Eire
|
||||
Link Etc/GMT GMT+0
|
||||
Link Etc/GMT GMT-0
|
||||
Link Etc/GMT GMT0
|
||||
Link Etc/GMT Greenwich
|
||||
Link Asia/Hong_Kong Hongkong
|
||||
Link Africa/Abidjan Iceland #= Atlantic/Reykjavik
|
||||
Link Asia/Tehran Iran
|
||||
Link Asia/Jerusalem Israel
|
||||
Link America/Jamaica Jamaica
|
||||
Link Asia/Tokyo Japan
|
||||
Link Pacific/Kwajalein Kwajalein
|
||||
Link Africa/Tripoli Libya
|
||||
Link Europe/Brussels MET
|
||||
Link America/Phoenix MST
|
||||
Link America/Denver MST7MDT
|
||||
Link America/Tijuana Mexico/BajaNorte
|
||||
Link America/Mazatlan Mexico/BajaSur
|
||||
Link America/Mexico_City Mexico/General
|
||||
Link Pacific/Auckland NZ
|
||||
Link Pacific/Chatham NZ-CHAT
|
||||
Link America/Denver Navajo #= America/Shiprock
|
||||
Link Asia/Shanghai PRC
|
||||
Link Europe/Warsaw Poland
|
||||
Link Europe/Lisbon Portugal
|
||||
Link Asia/Taipei ROC
|
||||
Link Asia/Seoul ROK
|
||||
Link Asia/Singapore Singapore
|
||||
Link Europe/Istanbul Turkey
|
||||
Link Etc/UTC UCT
|
||||
Link America/Anchorage US/Alaska
|
||||
Link America/Adak US/Aleutian
|
||||
Link America/Phoenix US/Arizona
|
||||
Link America/Chicago US/Central
|
||||
Link America/Indiana/Indianapolis US/East-Indiana
|
||||
Link America/New_York US/Eastern
|
||||
Link Pacific/Honolulu US/Hawaii
|
||||
Link America/Indiana/Knox US/Indiana-Starke
|
||||
Link America/Detroit US/Michigan
|
||||
Link America/Denver US/Mountain
|
||||
Link America/Los_Angeles US/Pacific
|
||||
Link Pacific/Pago_Pago US/Samoa
|
||||
Link Etc/UTC UTC
|
||||
Link Etc/UTC Universal
|
||||
Link Europe/Moscow W-SU
|
||||
Link Etc/UTC Zulu
|
||||
Link America/Argentina/Buenos_Aires America/Buenos_Aires
|
||||
Link America/Argentina/Catamarca America/Catamarca
|
||||
Link America/Argentina/Cordoba America/Cordoba
|
||||
Link America/Indiana/Indianapolis America/Indianapolis
|
||||
Link America/Argentina/Jujuy America/Jujuy
|
||||
Link America/Indiana/Knox America/Knox_IN
|
||||
Link America/Kentucky/Louisville America/Louisville
|
||||
Link America/Argentina/Mendoza America/Mendoza
|
||||
Link America/Puerto_Rico America/Virgin #= America/St_Thomas
|
||||
Link Pacific/Pago_Pago Pacific/Samoa
|
||||
Link Africa/Abidjan Africa/Accra
|
||||
Link Africa/Nairobi Africa/Addis_Ababa
|
||||
Link Africa/Nairobi Africa/Asmara
|
||||
Link Africa/Abidjan Africa/Bamako
|
||||
Link Africa/Lagos Africa/Bangui
|
||||
Link Africa/Abidjan Africa/Banjul
|
||||
Link Africa/Maputo Africa/Blantyre
|
||||
Link Africa/Lagos Africa/Brazzaville
|
||||
Link Africa/Maputo Africa/Bujumbura
|
||||
Link Africa/Abidjan Africa/Conakry
|
||||
Link Africa/Abidjan Africa/Dakar
|
||||
Link Africa/Nairobi Africa/Dar_es_Salaam
|
||||
Link Africa/Nairobi Africa/Djibouti
|
||||
Link Africa/Lagos Africa/Douala
|
||||
Link Africa/Abidjan Africa/Freetown
|
||||
Link Africa/Maputo Africa/Gaborone
|
||||
Link Africa/Maputo Africa/Harare
|
||||
Link Africa/Nairobi Africa/Kampala
|
||||
Link Africa/Maputo Africa/Kigali
|
||||
Link Africa/Lagos Africa/Kinshasa
|
||||
Link Africa/Lagos Africa/Libreville
|
||||
Link Africa/Abidjan Africa/Lome
|
||||
Link Africa/Lagos Africa/Luanda
|
||||
Link Africa/Maputo Africa/Lubumbashi
|
||||
Link Africa/Maputo Africa/Lusaka
|
||||
Link Africa/Lagos Africa/Malabo
|
||||
Link Africa/Johannesburg Africa/Maseru
|
||||
Link Africa/Johannesburg Africa/Mbabane
|
||||
Link Africa/Nairobi Africa/Mogadishu
|
||||
Link Africa/Lagos Africa/Niamey
|
||||
Link Africa/Abidjan Africa/Nouakchott
|
||||
Link Africa/Abidjan Africa/Ouagadougou
|
||||
Link Africa/Lagos Africa/Porto-Novo
|
||||
Link America/Puerto_Rico America/Anguilla
|
||||
Link America/Puerto_Rico America/Antigua
|
||||
Link America/Puerto_Rico America/Aruba
|
||||
Link America/Panama America/Atikokan
|
||||
Link America/Puerto_Rico America/Blanc-Sablon
|
||||
Link America/Panama America/Cayman
|
||||
Link America/Phoenix America/Creston
|
||||
Link America/Puerto_Rico America/Curacao
|
||||
Link America/Puerto_Rico America/Dominica
|
||||
Link America/Puerto_Rico America/Grenada
|
||||
Link America/Puerto_Rico America/Guadeloupe
|
||||
Link America/Puerto_Rico America/Kralendijk
|
||||
Link America/Puerto_Rico America/Lower_Princes
|
||||
Link America/Puerto_Rico America/Marigot
|
||||
Link America/Puerto_Rico America/Montserrat
|
||||
Link America/Toronto America/Nassau
|
||||
Link America/Puerto_Rico America/Port_of_Spain
|
||||
Link America/Puerto_Rico America/St_Barthelemy
|
||||
Link America/Puerto_Rico America/St_Kitts
|
||||
Link America/Puerto_Rico America/St_Lucia
|
||||
Link America/Puerto_Rico America/St_Thomas
|
||||
Link America/Puerto_Rico America/St_Vincent
|
||||
Link America/Puerto_Rico America/Tortola
|
||||
Link Pacific/Port_Moresby Antarctica/DumontDUrville
|
||||
Link Pacific/Auckland Antarctica/McMurdo
|
||||
Link Asia/Riyadh Antarctica/Syowa
|
||||
Link Europe/Berlin Arctic/Longyearbyen
|
||||
Link Asia/Riyadh Asia/Aden
|
||||
Link Asia/Qatar Asia/Bahrain
|
||||
Link Asia/Kuching Asia/Brunei
|
||||
Link Asia/Singapore Asia/Kuala_Lumpur
|
||||
Link Asia/Riyadh Asia/Kuwait
|
||||
Link Asia/Dubai Asia/Muscat
|
||||
Link Asia/Bangkok Asia/Phnom_Penh
|
||||
Link Asia/Bangkok Asia/Vientiane
|
||||
Link Africa/Abidjan Atlantic/Reykjavik
|
||||
Link Africa/Abidjan Atlantic/St_Helena
|
||||
Link Europe/Brussels Europe/Amsterdam
|
||||
Link Europe/Prague Europe/Bratislava
|
||||
Link Europe/Zurich Europe/Busingen
|
||||
Link Europe/Berlin Europe/Copenhagen
|
||||
Link Europe/London Europe/Guernsey
|
||||
Link Europe/London Europe/Isle_of_Man
|
||||
Link Europe/London Europe/Jersey
|
||||
Link Europe/Belgrade Europe/Ljubljana
|
||||
Link Europe/Brussels Europe/Luxembourg
|
||||
Link Europe/Helsinki Europe/Mariehamn
|
||||
Link Europe/Paris Europe/Monaco
|
||||
Link Europe/Berlin Europe/Oslo
|
||||
Link Europe/Belgrade Europe/Podgorica
|
||||
Link Europe/Rome Europe/San_Marino
|
||||
Link Europe/Belgrade Europe/Sarajevo
|
||||
Link Europe/Belgrade Europe/Skopje
|
||||
Link Europe/Berlin Europe/Stockholm
|
||||
Link Europe/Zurich Europe/Vaduz
|
||||
Link Europe/Rome Europe/Vatican
|
||||
Link Europe/Belgrade Europe/Zagreb
|
||||
Link Africa/Nairobi Indian/Antananarivo
|
||||
Link Asia/Bangkok Indian/Christmas
|
||||
Link Asia/Yangon Indian/Cocos
|
||||
Link Africa/Nairobi Indian/Comoro
|
||||
Link Indian/Maldives Indian/Kerguelen
|
||||
Link Asia/Dubai Indian/Mahe
|
||||
Link Africa/Nairobi Indian/Mayotte
|
||||
Link Asia/Dubai Indian/Reunion
|
||||
Link Pacific/Port_Moresby Pacific/Chuuk
|
||||
Link Pacific/Tarawa Pacific/Funafuti
|
||||
Link Pacific/Tarawa Pacific/Majuro
|
||||
Link Pacific/Pago_Pago Pacific/Midway
|
||||
Link Pacific/Guadalcanal Pacific/Pohnpei
|
||||
Link Pacific/Guam Pacific/Saipan
|
||||
Link Pacific/Tarawa Pacific/Wake
|
||||
Link Pacific/Tarawa Pacific/Wallis
|
||||
Link Africa/Abidjan Africa/Timbuktu
|
||||
Link America/Argentina/Catamarca America/Argentina/ComodRivadavia
|
||||
Link America/Adak America/Atka
|
||||
Link America/Panama America/Coral_Harbour
|
||||
Link America/Tijuana America/Ensenada
|
||||
Link America/Indiana/Indianapolis America/Fort_Wayne
|
||||
Link America/Toronto America/Montreal
|
||||
Link America/Toronto America/Nipigon
|
||||
Link America/Iqaluit America/Pangnirtung
|
||||
Link America/Rio_Branco America/Porto_Acre
|
||||
Link America/Winnipeg America/Rainy_River
|
||||
Link America/Argentina/Cordoba America/Rosario
|
||||
Link America/Tijuana America/Santa_Isabel
|
||||
Link America/Denver America/Shiprock
|
||||
Link America/Toronto America/Thunder_Bay
|
||||
Link America/Edmonton America/Yellowknife
|
||||
Link Pacific/Auckland Antarctica/South_Pole
|
||||
Link Asia/Ulaanbaatar Asia/Choibalsan
|
||||
Link Asia/Shanghai Asia/Chongqing
|
||||
Link Asia/Shanghai Asia/Harbin
|
||||
Link Asia/Urumqi Asia/Kashgar
|
||||
Link Asia/Jerusalem Asia/Tel_Aviv
|
||||
Link Europe/Berlin Atlantic/Jan_Mayen
|
||||
Link Australia/Sydney Australia/Canberra
|
||||
Link Australia/Hobart Australia/Currie
|
||||
Link Europe/London Europe/Belfast
|
||||
Link Europe/Chisinau Europe/Tiraspol
|
||||
Link Europe/Kyiv Europe/Uzhgorod
|
||||
Link Europe/Kyiv Europe/Zaporozhye
|
||||
Link Pacific/Kanton Pacific/Enderbury
|
||||
Link Pacific/Honolulu Pacific/Johnston
|
||||
Link Pacific/Port_Moresby Pacific/Yap
|
||||
Link Europe/Lisbon WET
|
||||
Link Africa/Nairobi Africa/Asmera #= Africa/Asmara
|
||||
Link America/Nuuk America/Godthab
|
||||
Link Asia/Ashgabat Asia/Ashkhabad
|
||||
Link Asia/Kolkata Asia/Calcutta
|
||||
Link Asia/Shanghai Asia/Chungking #= Asia/Chongqing
|
||||
Link Asia/Dhaka Asia/Dacca
|
||||
Link Europe/Istanbul Asia/Istanbul
|
||||
Link Asia/Kathmandu Asia/Katmandu
|
||||
Link Asia/Macau Asia/Macao
|
||||
Link Asia/Yangon Asia/Rangoon
|
||||
Link Asia/Ho_Chi_Minh Asia/Saigon
|
||||
Link Asia/Thimphu Asia/Thimbu
|
||||
Link Asia/Makassar Asia/Ujung_Pandang
|
||||
Link Asia/Ulaanbaatar Asia/Ulan_Bator
|
||||
Link Atlantic/Faroe Atlantic/Faeroe
|
||||
Link Europe/Kyiv Europe/Kiev
|
||||
Link Asia/Nicosia Europe/Nicosia
|
||||
Link Pacific/Honolulu HST
|
||||
Link America/Los_Angeles PST8PDT
|
||||
Link Pacific/Guadalcanal Pacific/Ponape #= Pacific/Pohnpei
|
||||
Link Pacific/Port_Moresby Pacific/Truk #= Pacific/Chuuk
|
||||
160
test/jdk/java/util/TimeZone/TimeZoneData/displaynames.txt
Normal file
160
test/jdk/java/util/TimeZone/TimeZoneData/displaynames.txt
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
Africa/Abidjan GMT
|
||||
Africa/Algiers CET
|
||||
Africa/Bissau GMT
|
||||
Africa/Cairo EET EEST
|
||||
Africa/Ceuta CET CEST
|
||||
Africa/Johannesburg SAST
|
||||
Africa/Juba CAT
|
||||
Africa/Khartoum CAT
|
||||
Africa/Lagos WAT
|
||||
Africa/Maputo CAT
|
||||
Africa/Monrovia GMT
|
||||
Africa/Nairobi EAT
|
||||
Africa/Ndjamena WAT
|
||||
Africa/Sao_Tome GMT
|
||||
Africa/Tripoli EET
|
||||
Africa/Tunis CET CEST
|
||||
America/Anchorage AKST AKDT
|
||||
America/Bahia_Banderas CST CDT
|
||||
America/Barbados AST ADT
|
||||
America/Belize CST CDT
|
||||
America/Boise MST MDT
|
||||
America/Cambridge_Bay MST MDT
|
||||
America/Cancun EST
|
||||
America/Chicago CST CDT
|
||||
America/Chihuahua CST
|
||||
America/Ciudad_Juarez MST MDT
|
||||
America/Costa_Rica CST CDT
|
||||
America/Danmarkshavn GMT
|
||||
America/Dawson MST
|
||||
America/Dawson_Creek MST
|
||||
America/Denver MST MDT
|
||||
America/Detroit EST EDT
|
||||
America/Edmonton MST MDT
|
||||
America/El_Salvador CST CDT
|
||||
America/Fort_Nelson MST
|
||||
America/Glace_Bay AST ADT
|
||||
America/Goose_Bay AST ADT
|
||||
America/Grand_Turk EST EDT
|
||||
America/Guatemala CST CDT
|
||||
America/Halifax AST ADT
|
||||
America/Havana CST CDT
|
||||
America/Hermosillo MST
|
||||
America/Indiana/Indianapolis EST EDT
|
||||
America/Indiana/Knox CST CDT
|
||||
America/Indiana/Marengo EST EDT
|
||||
America/Indiana/Petersburg EST EDT
|
||||
America/Indiana/Tell_City CST CDT
|
||||
America/Indiana/Vevay EST EDT
|
||||
America/Indiana/Vincennes EST EDT
|
||||
America/Indiana/Winamac EST EDT
|
||||
America/Inuvik MST MDT
|
||||
America/Iqaluit EST EDT
|
||||
America/Jamaica EST
|
||||
America/Juneau AKST AKDT
|
||||
America/Kentucky/Louisville EST EDT
|
||||
America/Kentucky/Monticello EST EDT
|
||||
America/Los_Angeles PST PDT
|
||||
America/Managua CST CDT
|
||||
America/Martinique AST
|
||||
America/Matamoros CST CDT
|
||||
America/Mazatlan MST MDT
|
||||
America/Menominee CST CDT
|
||||
America/Merida CST CDT
|
||||
America/Metlakatla AKST AKDT
|
||||
America/Mexico_City CST CDT
|
||||
America/Moncton AST ADT
|
||||
America/Monterrey CST CDT
|
||||
America/New_York EST EDT
|
||||
America/Nome AKST AKDT
|
||||
America/North_Dakota/Beulah CST CDT
|
||||
America/North_Dakota/Center CST CDT
|
||||
America/North_Dakota/New_Salem CST CDT
|
||||
America/Ojinaga CST CDT
|
||||
America/Panama EST
|
||||
America/Phoenix MST
|
||||
America/Port-au-Prince EST EDT
|
||||
America/Puerto_Rico AST
|
||||
America/Rankin_Inlet CST CDT
|
||||
America/Regina CST
|
||||
America/Resolute CST CDT
|
||||
America/Santo_Domingo AST
|
||||
America/Sitka AKST AKDT
|
||||
America/St_Johns NST NDT
|
||||
America/Swift_Current CST
|
||||
America/Tegucigalpa CST CDT
|
||||
America/Thule AST ADT
|
||||
America/Tijuana PST PDT
|
||||
America/Toronto EST EDT
|
||||
America/Vancouver PST PDT
|
||||
America/Whitehorse MST
|
||||
America/Winnipeg CST CDT
|
||||
America/Yakutat AKST AKDT
|
||||
Antarctica/Macquarie AEST AEDT
|
||||
Asia/Beirut EET EEST
|
||||
Asia/Famagusta EET EEST
|
||||
Asia/Gaza EET EEST
|
||||
Asia/Hebron EET EEST
|
||||
Asia/Hong_Kong HKT HKST
|
||||
Asia/Jakarta WIB
|
||||
Asia/Jayapura WIT
|
||||
Asia/Jerusalem IST IDT
|
||||
Asia/Karachi PKT PKST
|
||||
Asia/Kolkata IST
|
||||
Asia/Macau CST CDT
|
||||
Asia/Makassar WITA
|
||||
Asia/Manila PST PDT
|
||||
Asia/Nicosia EET EEST
|
||||
Asia/Pontianak WIB
|
||||
Asia/Shanghai CST CDT
|
||||
Asia/Taipei CST CDT
|
||||
Asia/Tokyo JST JDT
|
||||
Atlantic/Bermuda AST ADT
|
||||
Atlantic/Canary WET WEST
|
||||
Atlantic/Faroe WET WEST
|
||||
Atlantic/Madeira WET WEST
|
||||
Australia/Adelaide ACST ACDT
|
||||
Australia/Brisbane AEST AEDT
|
||||
Australia/Broken_Hill ACST ACDT
|
||||
Australia/Darwin ACST ACDT
|
||||
Australia/Hobart AEST AEDT
|
||||
Australia/Lindeman AEST AEDT
|
||||
Australia/Melbourne AEST AEDT
|
||||
Australia/Perth AWST AWDT
|
||||
Australia/Sydney AEST AEDT
|
||||
Europe/Andorra CET CEST
|
||||
Europe/Athens EET EEST
|
||||
Europe/Belgrade CET CEST
|
||||
Europe/Berlin CET CEST
|
||||
Europe/Brussels CET CEST
|
||||
Europe/Bucharest EET EEST
|
||||
Europe/Budapest CET CEST
|
||||
Europe/Chisinau EET EEST
|
||||
Europe/Dublin IST/GMT IST/GMT
|
||||
Europe/Gibraltar CET CEST
|
||||
Europe/Helsinki EET EEST
|
||||
Europe/Kaliningrad EET
|
||||
Europe/Kirov MSK
|
||||
Europe/Kyiv EET EEST
|
||||
Europe/Lisbon WET WEST
|
||||
Europe/London GMT/BST GMT/BST
|
||||
Europe/Madrid CET CEST
|
||||
Europe/Malta CET CEST
|
||||
Europe/Moscow MSK
|
||||
Europe/Paris CET CEST
|
||||
Europe/Prague CET CEST
|
||||
Europe/Riga EET EEST
|
||||
Europe/Rome CET CEST
|
||||
Europe/Simferopol MSK
|
||||
Europe/Sofia EET EEST
|
||||
Europe/Tallinn EET EEST
|
||||
Europe/Tirane CET CEST
|
||||
Europe/Vienna CET CEST
|
||||
Europe/Vilnius EET EEST
|
||||
Europe/Volgograd MSK
|
||||
Europe/Warsaw CET CEST
|
||||
Europe/Zurich CET CEST
|
||||
Pacific/Auckland NZST NZDT
|
||||
Pacific/Guam ChST
|
||||
Pacific/Honolulu HST
|
||||
Pacific/Pago_Pago SST
|
||||
1012
test/jdk/java/util/TimeZone/TimeZoneRegression.java
Normal file
1012
test/jdk/java/util/TimeZone/TimeZoneRegression.java
Normal file
File diff suppressed because it is too large
Load diff
758
test/jdk/java/util/TimeZone/TimeZoneTest.java
Normal file
758
test/jdk/java/util/TimeZone/TimeZoneTest.java
Normal file
|
|
@ -0,0 +1,758 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4028006 4044013 4096694 4107276 4107570 4112869 4130885 7039469 7126465 7158483
|
||||
* 8008577 8077685 8098547 8133321 8138716 8148446 8151876 8159684 8166875 8181157
|
||||
* 8228469 8274407 8285844 8305113 8174269
|
||||
* @modules java.base/sun.util.resources
|
||||
* @summary test TimeZone
|
||||
* @run junit TimeZoneTest
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.text.*;
|
||||
import java.util.*;
|
||||
import sun.util.resources.LocaleData;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
public class TimeZoneTest
|
||||
{
|
||||
static final int millisPerHour = 3600000;
|
||||
|
||||
/**
|
||||
* Bug 4130885
|
||||
* Certain short zone IDs, used since 1.1.x, are incorrect.
|
||||
*
|
||||
* The worst of these is:
|
||||
*
|
||||
* "CAT" (Central African Time) should be GMT+2:00, but instead returns a
|
||||
* zone at GMT-1:00. The zone at GMT-1:00 should be called EGT, CVT, EGST,
|
||||
* or AZOST, depending on which zone is meant, but in no case is it CAT.
|
||||
*
|
||||
* Other wrong zone IDs:
|
||||
*
|
||||
* ECT (European Central Time) GMT+1:00: ECT is Ecuador Time,
|
||||
* GMT-5:00. European Central time is abbreviated CEST.
|
||||
*
|
||||
* SST (Solomon Island Time) GMT+11:00. SST is actually Samoa Standard Time,
|
||||
* GMT-11:00. Solomon Island time is SBT.
|
||||
*
|
||||
* NST (New Zealand Time) GMT+12:00. NST is the abbreviation for
|
||||
* Newfoundland Standard Time, GMT-3:30. New Zealanders use NZST.
|
||||
*
|
||||
* AST (Alaska Standard Time) GMT-9:00. [This has already been noted in
|
||||
* another bug.] It should be "AKST". AST is Atlantic Standard Time,
|
||||
* GMT-4:00.
|
||||
*
|
||||
* PNT (Phoenix Time) GMT-7:00. PNT usually means Pitcairn Time,
|
||||
* GMT-8:30. There is no standard abbreviation for Phoenix time, as distinct
|
||||
* from MST with daylight savings.
|
||||
*
|
||||
* In addition to these problems, a number of zones are FAKE. That is, they
|
||||
* don't match what people use in the real world.
|
||||
*
|
||||
* FAKE zones:
|
||||
*
|
||||
* EET (should be EEST)
|
||||
* ART (should be EET)
|
||||
* MET (should be IRST)
|
||||
* NET (should be AMST)
|
||||
* PLT (should be PKT)
|
||||
* BST (should be BDT)
|
||||
* VST (should be ICT)
|
||||
* CTT (should be CST) +
|
||||
* ACT (should be CST) +
|
||||
* AET (should be EST) +
|
||||
* MIT (should be WST) +
|
||||
* IET (should be EST) +
|
||||
* PRT (should be AST) +
|
||||
* CNT (should be NST)
|
||||
* AGT (should be ARST)
|
||||
* BET (should be EST) +
|
||||
*
|
||||
* + A zone with the correct name already exists and means something
|
||||
* else. E.g., EST usually indicates the US Eastern zone, so it cannot be
|
||||
* used for Brazil (BET).
|
||||
*/
|
||||
@Test
|
||||
public void TestShortZoneIDs() throws Exception {
|
||||
|
||||
ZoneDescriptor[] JDK_116_REFERENCE_LIST = {
|
||||
new ZoneDescriptor("MIT", 780, false), // Samoa no longer observes DST starting 2021b
|
||||
new ZoneDescriptor("HST", -600, false),
|
||||
new ZoneDescriptor("AST", -540, true),
|
||||
new ZoneDescriptor("PST", -480, true),
|
||||
new ZoneDescriptor("PNT", -420, false),
|
||||
new ZoneDescriptor("MST", -420, false),
|
||||
new ZoneDescriptor("CST", -360, true),
|
||||
new ZoneDescriptor("IET", -300, true),
|
||||
new ZoneDescriptor("EST", -300, false),
|
||||
new ZoneDescriptor("PRT", -240, false),
|
||||
new ZoneDescriptor("CNT", -210, true),
|
||||
new ZoneDescriptor("AGT", -180, false),
|
||||
new ZoneDescriptor("BET", -180, false),
|
||||
// new ZoneDescriptor("CAT", -60, false), // Wrong:
|
||||
// As of bug 4130885, fix CAT (Central Africa)
|
||||
new ZoneDescriptor("CAT", 120, false), // Africa/Harare
|
||||
new ZoneDescriptor("GMT", 0, false),
|
||||
new ZoneDescriptor("UTC", 0, false),
|
||||
new ZoneDescriptor("ECT", 60, true),
|
||||
new ZoneDescriptor("ART", 120, true),
|
||||
new ZoneDescriptor("EET", 120, true),
|
||||
new ZoneDescriptor("EAT", 180, false),
|
||||
new ZoneDescriptor("MET", 60, true),
|
||||
new ZoneDescriptor("NET", 240, false),
|
||||
new ZoneDescriptor("PLT", 300, false),
|
||||
new ZoneDescriptor("IST", 330, false),
|
||||
new ZoneDescriptor("BST", 360, false),
|
||||
new ZoneDescriptor("VST", 420, false),
|
||||
new ZoneDescriptor("CTT", 480, false),
|
||||
new ZoneDescriptor("JST", 540, false),
|
||||
new ZoneDescriptor("ACT", 570, false),
|
||||
new ZoneDescriptor("AET", 600, true),
|
||||
new ZoneDescriptor("SST", 660, false),
|
||||
// new ZoneDescriptor("NST", 720, false),
|
||||
// As of bug 4130885, fix NST (New Zealand)
|
||||
new ZoneDescriptor("NST", 720, true), // Pacific/Auckland
|
||||
};
|
||||
|
||||
Map<String, ZoneDescriptor> hash = new HashMap<>();
|
||||
|
||||
String[] ids = TimeZone.getAvailableIDs();
|
||||
for (String id : ids) {
|
||||
if (id.length() == 3) {
|
||||
hash.put(id, new ZoneDescriptor(TimeZone.getTimeZone(id)));
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < JDK_116_REFERENCE_LIST.length; ++i) {
|
||||
ZoneDescriptor referenceZone = JDK_116_REFERENCE_LIST[i];
|
||||
ZoneDescriptor currentZone = hash.get(referenceZone.getID());
|
||||
if (referenceZone.equals(currentZone)) {
|
||||
System.out.println("ok " + referenceZone);
|
||||
}
|
||||
else {
|
||||
fail("Fail: Expected " + referenceZone +
|
||||
"; got " + currentZone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A descriptor for a zone; used to regress the short zone IDs.
|
||||
*/
|
||||
static class ZoneDescriptor {
|
||||
String id;
|
||||
int offset; // In minutes
|
||||
boolean daylight;
|
||||
|
||||
ZoneDescriptor(TimeZone zone) {
|
||||
this.id = zone.getID();
|
||||
this.offset = zone.getRawOffset() / 60000;
|
||||
this.daylight = zone.useDaylightTime();
|
||||
}
|
||||
|
||||
ZoneDescriptor(String id, int offset, boolean daylight) {
|
||||
this.id = id;
|
||||
this.offset = offset;
|
||||
this.daylight = daylight;
|
||||
}
|
||||
|
||||
public String getID() { return id; }
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
ZoneDescriptor that = (ZoneDescriptor)o;
|
||||
return that != null &&
|
||||
id.equals(that.id) &&
|
||||
offset == that.offset &&
|
||||
daylight == that.daylight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return id.hashCode() ^ offset | (daylight ? 1 : 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
int min = offset;
|
||||
char sign = '+';
|
||||
if (min < 0) { sign = '-'; min = -min; }
|
||||
|
||||
return "Zone[\"" + id + "\", GMT" + sign + (min/60) + ':' +
|
||||
(min%60<10?"0":"") + (min%60) + ", " +
|
||||
(daylight ? "Daylight" : "Standard") + "]";
|
||||
}
|
||||
|
||||
public static int compare(Object o1, Object o2) {
|
||||
ZoneDescriptor i1 = (ZoneDescriptor)o1;
|
||||
ZoneDescriptor i2 = (ZoneDescriptor)o2;
|
||||
if (i1.offset > i2.offset) return 1;
|
||||
if (i1.offset < i2.offset) return -1;
|
||||
if (i1.daylight && !i2.daylight) return 1;
|
||||
if (!i1.daylight && i2.daylight) return -1;
|
||||
return i1.id.compareTo(i2.id);
|
||||
}
|
||||
}
|
||||
|
||||
static final String formatSeconds(int sec) {
|
||||
char sign = '+';
|
||||
if (sec < 0) { sign = '-'; sec = -sec; }
|
||||
int h = sec / 3_600;
|
||||
int m = sec % 3_600 / 60;
|
||||
sec = sec % 60;
|
||||
return "" + sign + h + ":" + ((m<10) ? "0" : "") + m +
|
||||
(sec > 0 ? ":" + ((sec < 10) ? "0" : "") + sec : "");
|
||||
}
|
||||
/**
|
||||
* As part of the VM fix (see CCC approved RFE 4028006, bug
|
||||
* 4044013), TimeZone.getTimeZone() has been modified to recognize
|
||||
* generic IDs of the form GMT[+-]hh:mm, GMT[+-]hhmm, and
|
||||
* GMT[+-]hh. Test this behavior here.
|
||||
*
|
||||
* Bug 4044013
|
||||
*
|
||||
* ID "Custom" is no longer used for TimeZone objects created with
|
||||
* a custom time zone ID, such as "GMT-8". See 4322313.
|
||||
*/
|
||||
@Test
|
||||
public void TestCustomParse() throws Exception {
|
||||
Object[] DATA = {
|
||||
// ID Expected offset in seconds
|
||||
"GMT", null,
|
||||
"GMT+0", 0,
|
||||
"GMT+1", 60 * 60,
|
||||
"GMT-0030", -30 * 60,
|
||||
"GMT+15:99", null,
|
||||
"GMT+", null,
|
||||
"GMT-", null,
|
||||
"GMT+0:", null,
|
||||
"GMT-:", null,
|
||||
"GMT+0010", 10 * 60, // Interpret this as 00:10
|
||||
"GMT-10", -10 * 60 * 60,
|
||||
"GMT+30", null,
|
||||
"GMT-3:30", -(3 * 60 + 30) * 60,
|
||||
"GMT-230", -(2 * 60 + 30) * 60,
|
||||
"GMT+00:00:01", 1,
|
||||
"GMT-00:00:01", -1,
|
||||
"GMT+00000", null,
|
||||
"GMT+00:00:01:", null,
|
||||
"GMT+00:00:012", null,
|
||||
"GMT+00:00:0", null,
|
||||
"GMT+00:00:", null,
|
||||
};
|
||||
for (int i=0; i<DATA.length; i+=2) {
|
||||
String id = (String)DATA[i];
|
||||
Integer exp = (Integer)DATA[i+1];
|
||||
TimeZone zone = TimeZone.getTimeZone(id);
|
||||
if (zone.getID().equals("GMT")) {
|
||||
System.out.println(id + " -> generic GMT");
|
||||
// When TimeZone.getTimeZone() can't parse the id, it
|
||||
// returns GMT -- a dubious practice, but required for
|
||||
// backward compatibility.
|
||||
if (exp != null) {
|
||||
throw new Exception("Expected offset of " + formatSeconds(exp.intValue()) +
|
||||
" for " + id + ", got parse failure");
|
||||
}
|
||||
}
|
||||
else {
|
||||
int ioffset = zone.getRawOffset() / 1_000;
|
||||
String offset = formatSeconds(ioffset);
|
||||
System.out.println(id + " -> " + zone.getID() + " GMT" + offset);
|
||||
if (exp == null) {
|
||||
throw new Exception("Expected parse failure for " + id +
|
||||
", got offset of " + offset +
|
||||
", id " + zone.getID());
|
||||
}
|
||||
else if (ioffset != exp.intValue()) {
|
||||
throw new Exception("Expected offset of " + formatSeconds(exp.intValue()) +
|
||||
", id Custom, for " + id +
|
||||
", got offset of " + offset +
|
||||
", id " + zone.getID());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the basic functionality of the getDisplayName() API.
|
||||
*
|
||||
* Bug 4112869
|
||||
* Bug 4028006
|
||||
*
|
||||
* See also API change request A41.
|
||||
*
|
||||
* 4/21/98 - make smarter, so the test works if the ext resources
|
||||
* are present or not.
|
||||
*/
|
||||
@Test
|
||||
public void TestDisplayName() {
|
||||
TimeZone zone = TimeZone.getTimeZone("PST");
|
||||
String name = zone.getDisplayName(Locale.ENGLISH);
|
||||
System.out.println("PST->" + name);
|
||||
if (!name.equals("Pacific Standard Time"))
|
||||
fail("Fail: Expected \"Pacific Standard Time\"");
|
||||
|
||||
//*****************************************************************
|
||||
// THE FOLLOWING LINES MUST BE UPDATED IF THE LOCALE DATA CHANGES
|
||||
// THE FOLLOWING LINES MUST BE UPDATED IF THE LOCALE DATA CHANGES
|
||||
// THE FOLLOWING LINES MUST BE UPDATED IF THE LOCALE DATA CHANGES
|
||||
//*****************************************************************
|
||||
Object[] DATA = {
|
||||
new Boolean(false), new Integer(TimeZone.SHORT), "PST",
|
||||
new Boolean(true), new Integer(TimeZone.SHORT), "PDT",
|
||||
new Boolean(false), new Integer(TimeZone.LONG), "Pacific Standard Time",
|
||||
new Boolean(true), new Integer(TimeZone.LONG), "Pacific Daylight Time",
|
||||
};
|
||||
|
||||
for (int i=0; i<DATA.length; i+=3) {
|
||||
name = zone.getDisplayName(((Boolean)DATA[i]).booleanValue(),
|
||||
((Integer)DATA[i+1]).intValue(),
|
||||
Locale.ENGLISH);
|
||||
if (!name.equals(DATA[i+2]))
|
||||
fail("Fail: Expected " + DATA[i+2] + "; got " + name);
|
||||
}
|
||||
|
||||
// Make sure that we don't display the DST name by constructing a fake
|
||||
// PST zone that has DST all year long.
|
||||
SimpleTimeZone zone2 = new SimpleTimeZone(0, "PST");
|
||||
zone2.setStartRule(Calendar.JANUARY, 1, 0);
|
||||
zone2.setEndRule(Calendar.DECEMBER, 31, 0);
|
||||
System.out.println("Modified PST inDaylightTime->" + zone2.inDaylightTime(new Date()));
|
||||
name = zone2.getDisplayName(Locale.ENGLISH);
|
||||
System.out.println("Modified PST->" + name);
|
||||
if (!name.equals("Pacific Standard Time"))
|
||||
fail("Fail: Expected \"Pacific Standard Time\"");
|
||||
|
||||
// Make sure we get the default display format for Locales
|
||||
// with no display name data.
|
||||
Locale zh_CN = Locale.SIMPLIFIED_CHINESE;
|
||||
name = zone.getDisplayName(zh_CN);
|
||||
//*****************************************************************
|
||||
// THE FOLLOWING LINE MUST BE UPDATED IF THE LOCALE DATA CHANGES
|
||||
// THE FOLLOWING LINE MUST BE UPDATED IF THE LOCALE DATA CHANGES
|
||||
// THE FOLLOWING LINE MUST BE UPDATED IF THE LOCALE DATA CHANGES
|
||||
//*****************************************************************
|
||||
System.out.println("PST(zh_CN)->" + name);
|
||||
|
||||
// Now be smart -- check to see if zh resource is even present.
|
||||
// If not, we expect the en fallback behavior.
|
||||
ResourceBundle enRB = LocaleData.getBundle("sun.util.resources.cldr.TimeZoneNames",
|
||||
Locale.ENGLISH);
|
||||
ResourceBundle zhRB = LocaleData.getBundle("sun.util.resources.cldr.TimeZoneNames",
|
||||
zh_CN);
|
||||
|
||||
boolean noZH = enRB == zhRB;
|
||||
|
||||
if (noZH) {
|
||||
System.out.println("Warning: Not testing the zh_CN behavior because resource is absent");
|
||||
if (!name.equals("Pacific Standard Time"))
|
||||
fail("Fail: Expected Pacific Standard Time");
|
||||
}
|
||||
else if (!name.equals("Pacific Standard Time") &&
|
||||
!name.equals("\u592a\u5e73\u6d0b\u6807\u51c6\u65f6\u95f4") &&
|
||||
!name.equals("\u5317\u7f8e\u592a\u5e73\u6d0b\u6807\u51c6\u65f6\u95f4") &&
|
||||
!name.equals("GMT-08:00") &&
|
||||
!name.equals("GMT-8:00") &&
|
||||
!name.equals("GMT-0800") &&
|
||||
!name.equals("GMT-800")) {
|
||||
fail("Fail: Expected GMT-08:00 or something similar\n"
|
||||
+ "************************************************************\n"
|
||||
+ "THE ABOVE FAILURE MAY JUST MEAN THE LOCALE DATA HAS CHANGED\n"
|
||||
+ "************************************************************\n");
|
||||
}
|
||||
|
||||
// Now try a non-existent zone
|
||||
zone2 = new SimpleTimeZone(90*60*1000, "xyzzy");
|
||||
name = zone2.getDisplayName(Locale.ENGLISH);
|
||||
System.out.println("GMT+90min->" + name);
|
||||
if (!name.equals("GMT+01:30") &&
|
||||
!name.equals("GMT+1:30") &&
|
||||
!name.equals("GMT+0130") &&
|
||||
!name.equals("GMT+130"))
|
||||
fail("Fail: Expected GMT+01:30 or something similar");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void TestGenericAPI() {
|
||||
String id = "NewGMT";
|
||||
int offset = 12345;
|
||||
|
||||
SimpleTimeZone zone = new SimpleTimeZone(offset, id);
|
||||
if (zone.useDaylightTime()) {
|
||||
fail("FAIL: useDaylightTime should return false");
|
||||
}
|
||||
|
||||
TimeZone zoneclone = (TimeZone)zone.clone();
|
||||
if (!zoneclone.equals(zone)) {
|
||||
fail("FAIL: clone or operator== failed");
|
||||
}
|
||||
zoneclone.setID("abc");
|
||||
if (zoneclone.equals(zone)) {
|
||||
fail("FAIL: clone or operator!= failed");
|
||||
}
|
||||
|
||||
zoneclone = (TimeZone)zone.clone();
|
||||
if (!zoneclone.equals(zone)) {
|
||||
fail("FAIL: clone or operator== failed");
|
||||
}
|
||||
zoneclone.setRawOffset(45678);
|
||||
if (zoneclone.equals(zone)) {
|
||||
fail("FAIL: clone or operator!= failed");
|
||||
}
|
||||
|
||||
TimeZone saveDefault = TimeZone.getDefault();
|
||||
try {
|
||||
TimeZone.setDefault(zone);
|
||||
TimeZone defaultzone = TimeZone.getDefault();
|
||||
if (defaultzone == zone) {
|
||||
fail("FAIL: Default object is identical, not clone");
|
||||
}
|
||||
if (!defaultzone.equals(zone)) {
|
||||
fail("FAIL: Default object is not equal");
|
||||
}
|
||||
}
|
||||
finally {
|
||||
TimeZone.setDefault(saveDefault);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Test
|
||||
public void TestRuleAPI()
|
||||
{
|
||||
// ErrorCode status = ZERO_ERROR;
|
||||
|
||||
int offset = (int)(60*60*1000*1.75); // Pick a weird offset
|
||||
SimpleTimeZone zone = new SimpleTimeZone(offset, "TestZone");
|
||||
if (zone.useDaylightTime()) fail("FAIL: useDaylightTime should return false");
|
||||
|
||||
// Establish our expected transition times. Do this with a non-DST
|
||||
// calendar with the (above) declared local offset.
|
||||
GregorianCalendar gc = new GregorianCalendar(zone);
|
||||
gc.clear();
|
||||
gc.set(1990, Calendar.MARCH, 1);
|
||||
long marchOneStd = gc.getTime().getTime(); // Local Std time midnight
|
||||
gc.clear();
|
||||
gc.set(1990, Calendar.JULY, 1);
|
||||
long julyOneStd = gc.getTime().getTime(); // Local Std time midnight
|
||||
|
||||
// Starting and ending hours, WALL TIME
|
||||
int startHour = (int)(2.25 * 3600000);
|
||||
int endHour = (int)(3.5 * 3600000);
|
||||
|
||||
zone.setStartRule(Calendar.MARCH, 1, 0, startHour);
|
||||
zone.setEndRule (Calendar.JULY, 1, 0, endHour);
|
||||
|
||||
gc = new GregorianCalendar(zone);
|
||||
// if (failure(status, "new GregorianCalendar")) return;
|
||||
|
||||
long marchOne = marchOneStd + startHour;
|
||||
long julyOne = julyOneStd + endHour - 3600000; // Adjust from wall to Std time
|
||||
|
||||
long expMarchOne = 636251400000L;
|
||||
if (marchOne != expMarchOne)
|
||||
{
|
||||
fail("FAIL: Expected start computed as " + marchOne +
|
||||
" = " + new Date(marchOne));
|
||||
System.out.println(" Should be " + expMarchOne +
|
||||
" = " + new Date(expMarchOne));
|
||||
}
|
||||
|
||||
long expJulyOne = 646793100000L;
|
||||
if (julyOne != expJulyOne)
|
||||
{
|
||||
fail("FAIL: Expected start computed as " + julyOne +
|
||||
" = " + new Date(julyOne));
|
||||
System.out.println(" Should be " + expJulyOne +
|
||||
" = " + new Date(expJulyOne));
|
||||
}
|
||||
|
||||
testUsingBinarySearch(zone, new Date(90, Calendar.JANUARY, 1).getTime(),
|
||||
new Date(90, Calendar.JUNE, 15).getTime(), marchOne);
|
||||
testUsingBinarySearch(zone, new Date(90, Calendar.JUNE, 1).getTime(),
|
||||
new Date(90, Calendar.DECEMBER, 31).getTime(), julyOne);
|
||||
|
||||
if (zone.inDaylightTime(new Date(marchOne - 1000)) ||
|
||||
!zone.inDaylightTime(new Date(marchOne)))
|
||||
fail("FAIL: Start rule broken");
|
||||
if (!zone.inDaylightTime(new Date(julyOne - 1000)) ||
|
||||
zone.inDaylightTime(new Date(julyOne)))
|
||||
fail("FAIL: End rule broken");
|
||||
|
||||
zone.setStartYear(1991);
|
||||
if (zone.inDaylightTime(new Date(marchOne)) ||
|
||||
zone.inDaylightTime(new Date(julyOne - 1000)))
|
||||
fail("FAIL: Start year broken");
|
||||
|
||||
// failure(status, "TestRuleAPI");
|
||||
// delete gc;
|
||||
// delete zone;
|
||||
}
|
||||
|
||||
void testUsingBinarySearch(SimpleTimeZone tz, long min, long max, long expectedBoundary)
|
||||
{
|
||||
// ErrorCode status = ZERO_ERROR;
|
||||
boolean startsInDST = tz.inDaylightTime(new Date(min));
|
||||
// if (failure(status, "SimpleTimeZone::inDaylightTime")) return;
|
||||
if (tz.inDaylightTime(new Date(max)) == startsInDST) {
|
||||
System.out.println("Error: inDaylightTime(" + new Date(max) + ") != " + (!startsInDST));
|
||||
return;
|
||||
}
|
||||
// if (failure(status, "SimpleTimeZone::inDaylightTime")) return;
|
||||
while ((max - min) > INTERVAL) {
|
||||
long mid = (min + max) / 2;
|
||||
if (tz.inDaylightTime(new Date(mid)) == startsInDST) {
|
||||
min = mid;
|
||||
}
|
||||
else {
|
||||
max = mid;
|
||||
}
|
||||
// if (failure(status, "SimpleTimeZone::inDaylightTime")) return;
|
||||
}
|
||||
System.out.println("Binary Search Before: " + min + " = " + new Date(min));
|
||||
System.out.println("Binary Search After: " + max + " = " + new Date(max));
|
||||
long mindelta = expectedBoundary - min;
|
||||
long maxdelta = max - expectedBoundary;
|
||||
if (mindelta >= 0 &&
|
||||
mindelta <= INTERVAL &&
|
||||
mindelta >= 0 &&
|
||||
mindelta <= INTERVAL)
|
||||
System.out.println("PASS: Expected bdry: " + expectedBoundary + " = " + new Date(expectedBoundary));
|
||||
else
|
||||
fail("FAIL: Expected bdry: " + expectedBoundary + " = " + new Date(expectedBoundary));
|
||||
}
|
||||
|
||||
static final int INTERVAL = 100;
|
||||
|
||||
// Bug 006; verify the offset for a specific zone.
|
||||
@Test
|
||||
public void TestPRTOffset()
|
||||
{
|
||||
TimeZone tz = TimeZone.getTimeZone( "PRT" );
|
||||
if( tz == null ) {
|
||||
fail( "FAIL: TimeZone(PRT) is null" );
|
||||
}
|
||||
else{
|
||||
if (tz.getRawOffset() != (-4*millisPerHour))
|
||||
fail("FAIL: Offset for PRT should be -4");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Test various calls
|
||||
@SuppressWarnings("deprecation")
|
||||
@Test
|
||||
public void TestVariousAPI518()
|
||||
{
|
||||
TimeZone time_zone = TimeZone.getTimeZone("PST");
|
||||
Date d = new Date(97, Calendar.APRIL, 30);
|
||||
|
||||
System.out.println("The timezone is " + time_zone.getID());
|
||||
|
||||
if (time_zone.inDaylightTime(d) != true)
|
||||
fail("FAIL: inDaylightTime returned false");
|
||||
|
||||
if (time_zone.useDaylightTime() != true)
|
||||
fail("FAIL: useDaylightTime returned false");
|
||||
|
||||
if (time_zone.getRawOffset() != -8*millisPerHour)
|
||||
fail( "FAIL: getRawOffset returned wrong value");
|
||||
|
||||
GregorianCalendar gc = new GregorianCalendar();
|
||||
gc.setTime(d);
|
||||
if (time_zone.getOffset(gc.AD, gc.get(gc.YEAR), gc.get(gc.MONTH),
|
||||
gc.get(gc.DAY_OF_MONTH),
|
||||
gc.get(gc.DAY_OF_WEEK), 0)
|
||||
!= -7*millisPerHour)
|
||||
fail("FAIL: getOffset returned wrong value");
|
||||
}
|
||||
|
||||
// Test getAvailableID API
|
||||
@Test
|
||||
public void TestGetAvailableIDs913()
|
||||
{
|
||||
StringBuffer buf = new StringBuffer("TimeZone.getAvailableIDs() = { ");
|
||||
String[] s = TimeZone.getAvailableIDs();
|
||||
for (int i=0; i<s.length; ++i)
|
||||
{
|
||||
if (i > 0) buf.append(", ");
|
||||
buf.append(s[i]);
|
||||
}
|
||||
buf.append(" };");
|
||||
System.out.println(buf.toString());
|
||||
|
||||
buf.setLength(0);
|
||||
buf.append("TimeZone.getAvailableIDs(GMT+02:00) = { ");
|
||||
s = TimeZone.getAvailableIDs(+2 * 60 * 60 * 1000);
|
||||
for (int i=0; i<s.length; ++i)
|
||||
{
|
||||
if (i > 0) buf.append(", ");
|
||||
buf.append(s[i]);
|
||||
}
|
||||
buf.append(" };");
|
||||
System.out.println(buf.toString());
|
||||
|
||||
TimeZone tz = TimeZone.getTimeZone("PST");
|
||||
if (tz != null)
|
||||
System.out.println("getTimeZone(PST) = " + tz.getID());
|
||||
else
|
||||
fail("FAIL: getTimeZone(PST) = null");
|
||||
|
||||
tz = TimeZone.getTimeZone("America/Los_Angeles");
|
||||
if (tz != null)
|
||||
System.out.println("getTimeZone(America/Los_Angeles) = " + tz.getID());
|
||||
else
|
||||
fail("FAIL: getTimeZone(PST) = null");
|
||||
|
||||
// Bug 4096694
|
||||
tz = TimeZone.getTimeZone("NON_EXISTENT");
|
||||
if (tz == null)
|
||||
fail("FAIL: getTimeZone(NON_EXISTENT) = null");
|
||||
else if (!tz.getID().equals("GMT"))
|
||||
fail("FAIL: getTimeZone(NON_EXISTENT) = " + tz.getID());
|
||||
}
|
||||
|
||||
/**
|
||||
* Bug 4107276
|
||||
*/
|
||||
@Test
|
||||
public void TestDSTSavings() {
|
||||
// It might be better to find a way to integrate this test into the main TimeZone
|
||||
// tests above, but I don't have time to figure out how to do this (or if it's
|
||||
// even really a good idea). Let's consider that a future. --rtg 1/27/98
|
||||
SimpleTimeZone tz = new SimpleTimeZone(-5 * millisPerHour, "dstSavingsTest",
|
||||
Calendar.MARCH, 1, 0, 0, Calendar.SEPTEMBER, 1, 0, 0,
|
||||
(int)(0.5 * millisPerHour));
|
||||
|
||||
if (tz.getRawOffset() != -5 * millisPerHour)
|
||||
fail("Got back a raw offset of " + (tz.getRawOffset() / millisPerHour) +
|
||||
" hours instead of -5 hours.");
|
||||
if (!tz.useDaylightTime())
|
||||
fail("Test time zone should use DST but claims it doesn't.");
|
||||
if (tz.getDSTSavings() != 0.5 * millisPerHour)
|
||||
fail("Set DST offset to 0.5 hour, but got back " + (tz.getDSTSavings() /
|
||||
millisPerHour) + " hours instead.");
|
||||
|
||||
int offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.JANUARY, 1,
|
||||
Calendar.THURSDAY, 10 * millisPerHour);
|
||||
if (offset != -5 * millisPerHour)
|
||||
fail("The offset for 10 AM, 1/1/98 should have been -5 hours, but we got "
|
||||
+ (offset / millisPerHour) + " hours.");
|
||||
|
||||
offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.JUNE, 1, Calendar.MONDAY,
|
||||
10 * millisPerHour);
|
||||
if (offset != -4.5 * millisPerHour)
|
||||
fail("The offset for 10 AM, 6/1/98 should have been -4.5 hours, but we got "
|
||||
+ (offset / millisPerHour) + " hours.");
|
||||
|
||||
tz.setDSTSavings(millisPerHour);
|
||||
offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.JANUARY, 1,
|
||||
Calendar.THURSDAY, 10 * millisPerHour);
|
||||
if (offset != -5 * millisPerHour)
|
||||
fail("The offset for 10 AM, 1/1/98 should have been -5 hours, but we got "
|
||||
+ (offset / millisPerHour) + " hours.");
|
||||
|
||||
offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.JUNE, 1, Calendar.MONDAY,
|
||||
10 * millisPerHour);
|
||||
if (offset != -4 * millisPerHour)
|
||||
fail("The offset for 10 AM, 6/1/98 (with a 1-hour DST offset) should have been -4 hours, but we got "
|
||||
+ (offset / millisPerHour) + " hours.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Bug 4107570
|
||||
*/
|
||||
@Test
|
||||
public void TestAlternateRules() {
|
||||
// Like TestDSTSavings, this test should probably be integrated somehow with the main
|
||||
// test at the top of this class, but I didn't have time to figure out how to do that.
|
||||
// --rtg 1/28/98
|
||||
|
||||
SimpleTimeZone tz = new SimpleTimeZone(-5 * millisPerHour, "alternateRuleTest");
|
||||
|
||||
// test the day-of-month API
|
||||
tz.setStartRule(Calendar.MARCH, 10, 12 * millisPerHour);
|
||||
tz.setEndRule(Calendar.OCTOBER, 20, 12 * millisPerHour);
|
||||
|
||||
int offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.MARCH, 5,
|
||||
Calendar.THURSDAY, 10 * millisPerHour);
|
||||
if (offset != -5 * millisPerHour)
|
||||
fail("The offset for 10AM, 3/5/98 should have been -5 hours, but we got "
|
||||
+ (offset / millisPerHour) + " hours.");
|
||||
|
||||
offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.MARCH, 15,
|
||||
Calendar.SUNDAY, 10 * millisPerHour);
|
||||
if (offset != -4 * millisPerHour)
|
||||
fail("The offset for 10AM, 3/15/98 should have been -4 hours, but we got "
|
||||
+ (offset / millisPerHour) + " hours.");
|
||||
|
||||
offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.OCTOBER, 15,
|
||||
Calendar.THURSDAY, 10 * millisPerHour);
|
||||
if (offset != -4 * millisPerHour)
|
||||
fail("The offset for 10AM, 10/15/98 should have been -4 hours, but we got "
|
||||
+ (offset / millisPerHour) + " hours.");
|
||||
|
||||
offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.OCTOBER, 25,
|
||||
Calendar.SUNDAY, 10 * millisPerHour);
|
||||
if (offset != -5 * millisPerHour)
|
||||
fail("The offset for 10AM, 10/25/98 should have been -5 hours, but we got "
|
||||
+ (offset / millisPerHour) + " hours.");
|
||||
|
||||
// test the day-of-week-after-day-in-month API
|
||||
tz.setStartRule(Calendar.MARCH, 10, Calendar.FRIDAY, 12 * millisPerHour, true);
|
||||
tz.setEndRule(Calendar.OCTOBER, 20, Calendar.FRIDAY, 12 * millisPerHour, false);
|
||||
|
||||
offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.MARCH, 11,
|
||||
Calendar.WEDNESDAY, 10 * millisPerHour);
|
||||
if (offset != -5 * millisPerHour)
|
||||
fail("The offset for 10AM, 3/11/98 should have been -5 hours, but we got "
|
||||
+ (offset / millisPerHour) + " hours.");
|
||||
|
||||
offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.MARCH, 14,
|
||||
Calendar.SATURDAY, 10 * millisPerHour);
|
||||
if (offset != -4 * millisPerHour)
|
||||
fail("The offset for 10AM, 3/14/98 should have been -4 hours, but we got "
|
||||
+ (offset / millisPerHour) + " hours.");
|
||||
|
||||
offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.OCTOBER, 15,
|
||||
Calendar.THURSDAY, 10 * millisPerHour);
|
||||
if (offset != -4 * millisPerHour)
|
||||
fail("The offset for 10AM, 10/15/98 should have been -4 hours, but we got "
|
||||
+ (offset / millisPerHour) + " hours.");
|
||||
|
||||
offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.OCTOBER, 17,
|
||||
Calendar.SATURDAY, 10 * millisPerHour);
|
||||
if (offset != -5 * millisPerHour)
|
||||
fail("The offset for 10AM, 10/17/98 should have been -5 hours, but we got "
|
||||
+ (offset / millisPerHour) + " hours.");
|
||||
}
|
||||
}
|
||||
|
||||
//eof
|
||||
289
test/jdk/java/util/TimeZone/TransitionTest.java
Normal file
289
test/jdk/java/util/TimeZone/TransitionTest.java
Normal file
|
|
@ -0,0 +1,289 @@
|
|||
/*
|
||||
* Copyright (c) 2002, 2023, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4278609 4761696
|
||||
* @summary Make sure to handle DST transition ending at 0:00 January 1.
|
||||
* @run junit TransitionTest
|
||||
*/
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.Locale;
|
||||
import java.util.SimpleTimeZone;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
public class TransitionTest {
|
||||
|
||||
@Test
|
||||
public void Test4278609() {
|
||||
SimpleTimeZone tz = new SimpleTimeZone(0, "MyTimeZone",
|
||||
/* DST start day: August, 1, 0:00 */
|
||||
Calendar.AUGUST, 1, 0, 0,
|
||||
/* DST end day: January, 1, 0:00 (wall-clock)*/
|
||||
Calendar.JANUARY, 1, 0, 0,
|
||||
60 * 60 * 1000);
|
||||
|
||||
Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
|
||||
|
||||
// setting a date using GMT zone just after the end rule of tz zone
|
||||
cal.clear();
|
||||
cal.set(Calendar.ERA, GregorianCalendar.AD);
|
||||
cal.set(1998, Calendar.DECEMBER, 31, 23, 01, 00);
|
||||
|
||||
Date date = cal.getTime();
|
||||
|
||||
int millis = cal.get(Calendar.HOUR_OF_DAY) * 3600000
|
||||
+ cal.get(Calendar.MINUTE) * 60000
|
||||
+ cal.get(Calendar.SECOND) * 1000
|
||||
+ cal.get(Calendar.MILLISECOND);
|
||||
/* we must use standard local time */
|
||||
millis += tz.getRawOffset();
|
||||
|
||||
int offset = tz.getOffset(cal.get(Calendar.ERA),
|
||||
cal.get(Calendar.YEAR),
|
||||
cal.get(Calendar.MONTH),
|
||||
cal.get(Calendar.DATE),
|
||||
cal.get(Calendar.DAY_OF_WEEK),
|
||||
millis);
|
||||
|
||||
if (offset != 0) {
|
||||
SimpleDateFormat format = new SimpleDateFormat("dd MMM HH:mm:ss zzz",
|
||||
Locale.US);
|
||||
format.setTimeZone(tz);
|
||||
fail("Wrong DST transition: " + tz
|
||||
+ "\na date just after DST = " + format.format(date)
|
||||
+ "\ngetOffset = " + offset);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 4761696: Rewrite SimpleTimeZone to support correct DST transitions
|
||||
*
|
||||
* Derived from JCK test cases some of which specify wrong day of week values.
|
||||
*/
|
||||
@Test
|
||||
public void Test4761696() {
|
||||
GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
|
||||
|
||||
// test#1
|
||||
int rawOffset = -43200000;
|
||||
int saving = 1800000;
|
||||
int timeOfDay = 84600001;
|
||||
SimpleTimeZone tz = new SimpleTimeZone(rawOffset, "stz",
|
||||
Calendar.JULY, 1, 0, 0,
|
||||
Calendar.JANUARY, 1, 0, 0,
|
||||
saving);
|
||||
int year = Integer.MIN_VALUE;
|
||||
tz.setStartYear(year);
|
||||
int offset = tz.getOffset(GregorianCalendar.AD,
|
||||
year,
|
||||
Calendar.DECEMBER,
|
||||
31,
|
||||
1, // should be SATURDAY
|
||||
timeOfDay);
|
||||
int y = (int) mod((long)year, 28L); // 28-year cycle
|
||||
cal.clear();
|
||||
cal.set(cal.ERA, cal.AD);
|
||||
cal.set(y, Calendar.DECEMBER, 31);
|
||||
cal.set(cal.MILLISECOND, timeOfDay);
|
||||
long localtime = cal.getTimeInMillis() + rawOffset; // local standard time
|
||||
|
||||
cal.clear();
|
||||
cal.set(cal.ERA, cal.AD);
|
||||
cal.set(y + 1, Calendar.JANUARY, 1);
|
||||
cal.set(cal.MILLISECOND, -saving);
|
||||
long endTime = cal.getTimeInMillis() + rawOffset;
|
||||
long expectedOffset = (localtime < endTime) ? rawOffset + saving : rawOffset;
|
||||
if (offset != expectedOffset) {
|
||||
fail("test#1: wrong offset: got "+offset+", expected="+expectedOffset);
|
||||
}
|
||||
|
||||
// test#2
|
||||
saving = 1;
|
||||
timeOfDay = 0;
|
||||
tz = new SimpleTimeZone(rawOffset, "stz",
|
||||
Calendar.JULY, 1, 0, 0,
|
||||
Calendar.JANUARY, 1, 0, 0,
|
||||
saving);
|
||||
tz.setStartYear(year);
|
||||
offset = tz.getOffset(GregorianCalendar.AD,
|
||||
year,
|
||||
Calendar.AUGUST,
|
||||
15,
|
||||
1, // should be MONDAY
|
||||
timeOfDay);
|
||||
y = (int) mod((long)year, 28L); // 28-year cycle
|
||||
cal.clear();
|
||||
cal.set(y, Calendar.AUGUST, 15);
|
||||
cal.set(cal.MILLISECOND, timeOfDay);
|
||||
localtime = cal.getTimeInMillis() + rawOffset; // local standard time
|
||||
|
||||
cal.clear();
|
||||
cal.set(y + 1, Calendar.JANUARY, 1);
|
||||
cal.set(cal.MILLISECOND, -saving);
|
||||
endTime = cal.getTimeInMillis() + rawOffset;
|
||||
expectedOffset = (localtime < endTime) ? rawOffset + saving : rawOffset;
|
||||
if (offset != expectedOffset) {
|
||||
fail("Wrong offset: got "+offset+", expected="+expectedOffset);
|
||||
}
|
||||
|
||||
rawOffset = 43200000;
|
||||
saving = 1;
|
||||
timeOfDay = 3599998;
|
||||
tz = new SimpleTimeZone(rawOffset, "stz",
|
||||
Calendar.JULY, 1, 0, 3600000,
|
||||
Calendar.JANUARY, 1, 0, 3600000,
|
||||
saving);
|
||||
tz.setStartYear(year);
|
||||
offset = tz.getOffset(GregorianCalendar.AD,
|
||||
year,
|
||||
Calendar.JANUARY,
|
||||
1,
|
||||
1,
|
||||
timeOfDay);
|
||||
y = (int) mod((long)year, 28L); // 28-year cycle
|
||||
cal.clear();
|
||||
cal.set(y, Calendar.JANUARY, 1);
|
||||
cal.set(cal.MILLISECOND, timeOfDay);
|
||||
localtime = cal.getTimeInMillis() + rawOffset; // local standard time
|
||||
|
||||
cal.clear();
|
||||
cal.set(y + 1, Calendar.JANUARY, 1);
|
||||
cal.set(cal.MILLISECOND, 3600000-saving);
|
||||
endTime = cal.getTimeInMillis() + rawOffset;
|
||||
expectedOffset = (localtime < endTime) ? rawOffset + saving : rawOffset;
|
||||
if (offset != expectedOffset) {
|
||||
fail("test#2: wrong offset: got "+offset+", expected="+expectedOffset);
|
||||
}
|
||||
|
||||
// test#3
|
||||
rawOffset = -43200000;
|
||||
saving = 1800000;
|
||||
timeOfDay = 84600001;
|
||||
tz = new SimpleTimeZone(rawOffset, "stz",
|
||||
Calendar.SEPTEMBER, 1, 0, 0,
|
||||
Calendar.MARCH, 1, 0, 0,
|
||||
saving);
|
||||
tz.setStartYear(year);
|
||||
offset = tz.getOffset(GregorianCalendar.AD,
|
||||
year,
|
||||
Calendar.FEBRUARY,
|
||||
28,
|
||||
1,
|
||||
timeOfDay);
|
||||
y = (int) mod((long)year, 28L); // 28-year cycle
|
||||
cal.clear();
|
||||
cal.set(y, Calendar.FEBRUARY, 28);
|
||||
cal.set(cal.MILLISECOND, timeOfDay);
|
||||
localtime = cal.getTimeInMillis() + rawOffset; // local standard time
|
||||
|
||||
cal.clear();
|
||||
cal.set(y, Calendar.MARCH, 1);
|
||||
cal.set(cal.MILLISECOND, -saving);
|
||||
endTime = cal.getTimeInMillis() + rawOffset;
|
||||
expectedOffset = (localtime < endTime) ? rawOffset + saving : rawOffset;
|
||||
if (offset != expectedOffset) {
|
||||
fail("test#3: wrong offset: got "+offset+", expected="+expectedOffset);
|
||||
}
|
||||
|
||||
// test#4
|
||||
rawOffset = -43200000;
|
||||
saving = 1;
|
||||
timeOfDay = 0;
|
||||
tz = new SimpleTimeZone(rawOffset, "stz",
|
||||
Calendar.JANUARY, -4, 1, 3600000,
|
||||
Calendar.JULY, -4, 1, 3600000,
|
||||
saving);
|
||||
tz.setStartYear(year);
|
||||
offset = tz.getOffset(GregorianCalendar.AD,
|
||||
year,
|
||||
Calendar.JANUARY,
|
||||
10,
|
||||
2, // should be 1 (SUNDAY)
|
||||
timeOfDay);
|
||||
y = (int) mod((long)year, 28L); // 28-year cycle
|
||||
cal.clear();
|
||||
cal.set(y, Calendar.JANUARY, 10);
|
||||
cal.set(cal.MILLISECOND, timeOfDay);
|
||||
localtime = cal.getTimeInMillis() + rawOffset; // local standard time
|
||||
|
||||
cal.clear();
|
||||
cal.set(cal.YEAR, y);
|
||||
cal.set(cal.MONTH, Calendar.JANUARY);
|
||||
cal.set(cal.DAY_OF_MONTH, 8);
|
||||
cal.set(cal.WEEK_OF_MONTH, cal.getActualMaximum(cal.WEEK_OF_MONTH)-4+1);
|
||||
cal.set(cal.DAY_OF_WEEK, 1);
|
||||
cal.set(cal.MILLISECOND, 3600000-saving);
|
||||
long startTime = cal.getTimeInMillis() + rawOffset;
|
||||
expectedOffset = (localtime >= startTime) ? rawOffset + saving : rawOffset;
|
||||
if (offset != expectedOffset) {
|
||||
fail("test#4: wrong offset: got "+offset+", expected="+expectedOffset);
|
||||
}
|
||||
|
||||
// test#5
|
||||
rawOffset = 0;
|
||||
saving = 3600000;
|
||||
timeOfDay = 7200000;
|
||||
year = 1982;
|
||||
tz = new SimpleTimeZone(rawOffset, "stz",
|
||||
Calendar.APRIL, 1, 0, 7200000,
|
||||
Calendar.OCTOBER, 10, 0, 7200000,
|
||||
saving);
|
||||
offset = tz.getOffset(GregorianCalendar.AD,
|
||||
year,
|
||||
Calendar.OCTOBER,
|
||||
10,
|
||||
1,
|
||||
timeOfDay);
|
||||
cal.clear();
|
||||
cal.set(year, Calendar.OCTOBER, 10);
|
||||
cal.set(cal.MILLISECOND, timeOfDay);
|
||||
localtime = cal.getTimeInMillis() + rawOffset; // local standard time
|
||||
|
||||
cal.clear();
|
||||
cal.set(year, Calendar.OCTOBER, 10);
|
||||
cal.set(cal.MILLISECOND, 7200000-saving);
|
||||
endTime = cal.getTimeInMillis() + rawOffset;
|
||||
expectedOffset = (localtime < endTime) ? rawOffset + saving : rawOffset;
|
||||
if (offset != expectedOffset) {
|
||||
fail("test#5: wrong offset: got "+offset+", expected="+expectedOffset);
|
||||
}
|
||||
}
|
||||
|
||||
public static final long floorDivide(long n, long d) {
|
||||
return ((n >= 0) ?
|
||||
(n / d) : (((n + 1L) / d) - 1L));
|
||||
}
|
||||
|
||||
public static final long mod(long x, long y) {
|
||||
return (x - y * floorDivide(x, y));
|
||||
}
|
||||
}
|
||||
53
test/jdk/java/util/TimeZone/UTCAliasTest.java
Normal file
53
test/jdk/java/util/TimeZone/UTCAliasTest.java
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 2005, 2017, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6282072
|
||||
* @summary Make sure that "UTC" is an alias of "Etc/UTC" as defined in the tzdata backward.
|
||||
* @modules java.base/sun.util.calendar
|
||||
* @compile -XDignore.symbol.file UTCAliasTest.java
|
||||
* @run main UTCAliasTest
|
||||
*/
|
||||
|
||||
import java.util.*;
|
||||
import sun.util.calendar.ZoneInfo;
|
||||
|
||||
public class UTCAliasTest {
|
||||
public static void main(String[] args) {
|
||||
Map<String,String> map = ZoneInfo.getAliasTable();
|
||||
String alias = map.get("UTC");
|
||||
if (!alias.equals("Etc/UTC")) {
|
||||
throw new RuntimeException("got " + alias + ", expected Etc/UTC");
|
||||
}
|
||||
TimeZone GMT = TimeZone.getTimeZone("GMT");
|
||||
TimeZone UTC = TimeZone.getTimeZone("UTC");
|
||||
if (!GMT.hasSameRules(UTC)) {
|
||||
throw new RuntimeException("GMT and UTC have different rules");
|
||||
}
|
||||
TimeZone EtcUTC = TimeZone.getTimeZone("Etc/UTC");
|
||||
if (!UTC.hasSameRules(EtcUTC)) {
|
||||
throw new RuntimeException("UTC and Etc/UTC have different rules");
|
||||
}
|
||||
}
|
||||
}
|
||||
71
test/jdk/java/util/TimeZone/ZoneIdRoundTripTest.java
Normal file
71
test/jdk/java/util/TimeZone/ZoneIdRoundTripTest.java
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (c) 2022, 2025, 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.
|
||||
*/
|
||||
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8285844
|
||||
* @summary Checks round-trips between TimeZone and ZoneId are consistent
|
||||
* @run junit ZoneIdRoundTripTest
|
||||
*/
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
public class ZoneIdRoundTripTest {
|
||||
|
||||
private Object[][] testZoneIds() {
|
||||
return new Object[][] {
|
||||
{ZoneId.of("Z"), 0},
|
||||
{ZoneId.of("UT"), 0},
|
||||
{ZoneId.of("UTC"), 0},
|
||||
{ZoneId.of("GMT"), 0},
|
||||
{ZoneId.of("+00:01"), 60_000},
|
||||
{ZoneId.of("-00:01"), -60_000},
|
||||
{ZoneId.of("+00:00:01"), 1_000},
|
||||
{ZoneId.of("-00:00:01"), -1_000},
|
||||
{ZoneId.of("UT+00:00:01"), 1_000},
|
||||
{ZoneId.of("UT-00:00:01"), -1_000},
|
||||
{ZoneId.of("UTC+00:00:01"), 1_000},
|
||||
{ZoneId.of("UTC-00:00:01"), -1_000},
|
||||
{ZoneId.of("GMT+00:00:01"), 1_000},
|
||||
{ZoneId.of("GMT-00:00:01"), -1_000},
|
||||
{ZoneOffset.of("+00:00:01"), 1_000},
|
||||
{ZoneOffset.of("-00:00:01"), -1_000},
|
||||
};
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("testZoneIds")
|
||||
public void test_ZoneIdRoundTrip(ZoneId zid, int offset) {
|
||||
var tz = TimeZone.getTimeZone(zid);
|
||||
assertEquals(offset, tz.getRawOffset());
|
||||
assertEquals(zid.normalized(), tz.toZoneId().normalized());
|
||||
}
|
||||
}
|
||||
|
||||
67
test/jdk/java/util/TimeZone/bug4096952.java
Normal file
67
test/jdk/java/util/TimeZone/bug4096952.java
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2025, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4096952 8347841
|
||||
* @summary simple serialization/deserialization test
|
||||
*/
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.util.TimeZone;
|
||||
|
||||
public class bug4096952 {
|
||||
|
||||
public static void main(String[] args) {
|
||||
int errors = 0;
|
||||
String[] ZONES = { "GMT", "MET", "Asia/Kolkata" };
|
||||
for (String id : ZONES) {
|
||||
TimeZone zone = TimeZone.getTimeZone(id);
|
||||
try {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
try (ObjectOutputStream ostream = new ObjectOutputStream(baos)) {
|
||||
ostream.writeObject(zone);
|
||||
}
|
||||
try (ObjectInputStream istream
|
||||
= new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()))) {
|
||||
if (!zone.equals(istream.readObject())) {
|
||||
errors++;
|
||||
System.out.println("Time zone " + id + " are not equal to serialized/deserialized one.");
|
||||
} else {
|
||||
System.out.println("Time zone " + id + " ok.");
|
||||
}
|
||||
}
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
errors++;
|
||||
System.out.println(e);
|
||||
}
|
||||
}
|
||||
if (errors > 0) {
|
||||
throw new RuntimeException("test failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
84
test/jdk/java/util/TimeZone/tools/share/CompareYearData.pl
Normal file
84
test/jdk/java/util/TimeZone/tools/share/CompareYearData.pl
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
#
|
||||
# Copyright (c) 2008, 2022, 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.
|
||||
#
|
||||
|
||||
#
|
||||
# Compares two year* test data files
|
||||
# Typical usage:
|
||||
# perl CompareYearData.pl ../../TimeZoneData/year2008 year2008
|
||||
#
|
||||
|
||||
%oldData = &readData($ARGV[0]);
|
||||
%newData = &readData($ARGV[1]);
|
||||
|
||||
foreach $key (sort(keys(%oldData))) {
|
||||
if (defined($newData{$key})) {
|
||||
if ($oldData{$key} ne $newData{$key}) {
|
||||
print "Changed:\n";
|
||||
print "$oldData{$key}";
|
||||
print "---\n";
|
||||
print "$newData{$key}";
|
||||
}
|
||||
delete $newData{$key};
|
||||
} else {
|
||||
print "Deleted:\n";
|
||||
print "$oldData{$key}";
|
||||
}
|
||||
}
|
||||
foreach $key (sort(keys(%newData))) {
|
||||
print "Added:\n";
|
||||
print "$newData{$key}";
|
||||
}
|
||||
|
||||
sub readData {
|
||||
local($file) = @_;
|
||||
|
||||
open(F, $file) || die "Can't open $file\n";
|
||||
my %data = ();
|
||||
my $line = 0;
|
||||
my $id = "";
|
||||
|
||||
while (<F>) {
|
||||
$line++;
|
||||
s/^\s*\d+ //;
|
||||
if (/tzdata\d+/) {
|
||||
$data{" version"} = $_;
|
||||
next;
|
||||
}
|
||||
if (/(\s*#.*$)/) {
|
||||
$data{" comments"} .= $_;
|
||||
next;
|
||||
}
|
||||
if (/^(Zone|Rule)/) {
|
||||
die "No id at line: $line\n" if ($id eq "");
|
||||
$data{$id} .= $_;
|
||||
} elsif (/^(\S+)\s+\S+/) {
|
||||
$id = $1;
|
||||
$data{$id} = $_;
|
||||
$flag = 1;
|
||||
} else {
|
||||
die "Unknown format at line: $line: $file\n";
|
||||
}
|
||||
}
|
||||
close(F);
|
||||
return %data;
|
||||
}
|
||||
57
test/jdk/java/util/TimeZone/tools/share/Makefile
Normal file
57
test/jdk/java/util/TimeZone/tools/share/Makefile
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
#
|
||||
# Copyright (c) 2008, 2025, 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.
|
||||
#
|
||||
|
||||
#
|
||||
#
|
||||
# This makefile is used to update the time zone tests data: aliases.txt displaynames.txt
|
||||
# and VERSION. After switching to new build system in JDK8 the following make
|
||||
# command should be used for test data updates:
|
||||
# make JDK_HOME=<path to built JDK with latest tzdata>
|
||||
# make install
|
||||
#
|
||||
|
||||
TZDATA = ../../../../../../../src/java.base/share/data/tzdata
|
||||
TZDATA_VER = `grep '^tzdata' $(TZDATA)/VERSION`
|
||||
TZNAME = africa antarctica asia australasia europe northamerica \
|
||||
southamerica backward
|
||||
TZFILES = $(addprefix $(TZDATA)/, $(TZNAME))
|
||||
ALIASLIST = aliases.txt
|
||||
DISPLAYNAMES = displaynames.txt
|
||||
|
||||
all: $(DISPLAYNAMES) VERSION $(ALIASLIST)
|
||||
|
||||
$(DISPLAYNAMES): $(TZFILES) makeZoneData.pl
|
||||
(cat $(TZFILES) | perl makeZoneData.pl -v -V "$(TZDATA_VER)") 2>errors
|
||||
|
||||
VERSION: $(TZDATA)/VERSION
|
||||
echo "$(TZDATA_VER)" > VERSION
|
||||
|
||||
$(ALIASLIST): $(TZFILES)
|
||||
rm -f $(ALIASLIST)
|
||||
grep -h "^Link" $(TZFILES) >> $(ALIASLIST)
|
||||
|
||||
clean:
|
||||
rm -f $(DISPLAYNAMES) errors year???? VERSION $(ALIASLIST)
|
||||
|
||||
install:
|
||||
cp $(ALIASLIST) $(DISPLAYNAMES) VERSION ../../TimeZoneData/
|
||||
288
test/jdk/java/util/TimeZone/tools/share/makeZoneData.pl
Normal file
288
test/jdk/java/util/TimeZone/tools/share/makeZoneData.pl
Normal file
|
|
@ -0,0 +1,288 @@
|
|||
#
|
||||
# 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;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue