12d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert// © 2016 and later: Unicode, Inc. and others.
22d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert// License & terms of use: http://www.unicode.org/copyright.html#License
37935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/**
47935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *******************************************************************************
52d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert * Copyright (C) 2000-2016, International Business Machines Corporation and
62d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert * others. All Rights Reserved.
77935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *******************************************************************************
87935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */
97935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpackage com.ibm.icu.dev.test.timezone;
117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.io.ByteArrayInputStream;
137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.io.ByteArrayOutputStream;
147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.io.IOException;
157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.io.ObjectInputStream;
167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.io.ObjectOutputStream;
177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.lang.reflect.InvocationTargetException;
187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Arrays;
197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Date;
207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.List;
217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Locale;
227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Set;
237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
242d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubertimport org.junit.Test;
252d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert
267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.dev.test.TestFmwk;
272d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubertimport com.ibm.icu.impl.ICUData;
287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.text.SimpleDateFormat;
297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.BasicTimeZone;
307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.Calendar;
317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.DateTimeRule;
327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.GregorianCalendar;
337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.InitialTimeZoneRule;
347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.RuleBasedTimeZone;
357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.SimpleTimeZone;
367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.TimeArrayTimeZoneRule;
377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.TimeZone;
387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.TimeZone.SystemTimeZoneType;
397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.TimeZoneRule;
407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.TimeZoneTransition;
417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.ULocale;
427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.UResourceBundle;
437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.VTimeZone;
447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.VersionInfo;
457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/**
477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @test 1.22 99/09/21
487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @bug 4028006 4044013 4096694 4107276 4107570 4112869 4130885
497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @summary test TimeZone
507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @build TimeZoneTest
517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */
527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpublic class TimeZoneTest extends TestFmwk
537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert{
547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    static final int millisPerHour = 3600000;
557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // Some test case data is current date/tzdata version sensitive and producing errors
577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // when year/rule are changed. Although we want to keep our eyes on test failures
587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // caused by tzdata changes while development, keep maintaining test data in maintenance
597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // stream is a little bit hassle. ICU 49 or later versions are using minor version field
607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // to indicate a development build (0) or official release build (others). For development
617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // builds, a test failure triggers an error, while release builds only report them in
627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // verbose mode with logln.
637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    static final boolean isDevelopmentBuild = (VersionInfo.ICU_VERSION.getMinor() == 0);
647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * NOTE: As of ICU 2.8, the mapping of 3-letter legacy aliases
677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * to `real' Olson IDs is under control of the underlying JDK.
687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * This test may fail on one JDK and pass on another; don't be
697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * too concerned.  Alan
707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Bug 4130885
727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Certain short zone IDs, used since 1.1.x, are incorrect.
737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * The worst of these is:
757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * "CAT" (Central African Time) should be GMT+2:00, but instead returns a
777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * zone at GMT-1:00. The zone at GMT-1:00 should be called EGT, CVT, EGST,
787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * or AZOST, depending on which zone is meant, but in no case is it CAT.
797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Other wrong zone IDs:
817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * ECT (European Central Time) GMT+1:00: ECT is Ecuador Time,
837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * GMT-5:00. European Central time is abbreviated CEST.
847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * SST (Solomon Island Time) GMT+11:00. SST is actually Samoa Standard Time,
867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * GMT-11:00. Solomon Island time is SBT.
877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * NST (New Zealand Time) GMT+12:00. NST is the abbreviation for
897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Newfoundland Standard Time, GMT-3:30. New Zealanders use NZST.
907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * AST (Alaska Standard Time) GMT-9:00. [This has already been noted in
927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * another bug.] It should be "AKST". AST is Atlantic Standard Time,
937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * GMT-4:00.
947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * PNT (Phoenix Time) GMT-7:00. PNT usually means Pitcairn Time,
967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * GMT-8:30. There is no standard abbreviation for Phoenix time, as distinct
977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * from MST with daylight savings.
987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * In addition to these problems, a number of zones are FAKE. That is, they
1007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * don't match what people use in the real world.
1017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
1027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * FAKE zones:
1037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
1047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * EET (should be EEST)
1057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * ART (should be EEST)
1067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * MET (should be IRST)
1077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * NET (should be AMST)
1087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * PLT (should be PKT)
1097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * BST (should be BDT)
1107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * VST (should be ICT)
1117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * CTT (should be CST) +
1127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * ACT (should be CST) +
1137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * AET (should be EST) +
1147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * MIT (should be WST) +
1157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * IET (should be EST) +
1167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * PRT (should be AST) +
1177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * CNT (should be NST)
1187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * AGT (should be ARST)
1197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * BET (should be EST) +
1207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
1217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * + A zone with the correct name already exists and means something
1227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * else. E.g., EST usually indicates the US Eastern zone, so it cannot be
1237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * used for Brazil (BET).
1247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1252d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
1267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestShortZoneIDs() throws Exception {
1277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Note: If the default TimeZone type is JDK, some time zones
1297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // may differ from the test data below.  For example, "MST" on
1307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // IBM JRE is an alias of "America/Denver" for supporting Java 1.1
1317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // backward compatibility, while Olson tzdata (and ICU) treat it
1327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // as -7hour fixed offset/no DST.
1337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        boolean isJDKTimeZone = (TimeZone.getDefaultTimeZoneType() == TimeZone.TIMEZONE_JDK);
1347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (isJDKTimeZone) {
1357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            logln("Warning: Using JDK TimeZone.  Some test cases may not return expected results.");
1367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
1377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ZoneDescriptor[] REFERENCE_LIST = {
1397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("HST", -600, false), // Olson northamerica -10:00
1407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("AST", -540, true),  // ICU Link - America/Anchorage
1417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("PST", -480, true),  // ICU Link - America/Los_Angeles
1427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("PNT", -420, false), // ICU Link - America/Phoenix
1437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("MST", -420, false), // updated Aug 2003 aliu
1447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("CST", -360, true),  // Olson northamerica -7:00
1457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("IET", -300, true),  // ICU Link - America/Indiana/Indianapolis
1467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("EST", -300, false), // Olson northamerica -5:00
1477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("PRT", -240, false), // ICU Link - America/Puerto_Rico
1487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("CNT", -210, true),  // ICU Link - America/St_Johns
1497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("AGT", -180, false), // ICU Link - America/Argentina/Buenos_Aires
1507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("BET", -180, true),  // ICU Link - America/Sao_Paulo
1517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("GMT", 0, false),    // Olson etcetera Link - Etc/GMT
1527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("UTC", 0, false),    // Olson etcetera 0
1537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("ECT", 60, true),    // ICU Link - Europe/Paris
1547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("MET", 60, true),    // Olson europe 1:00 C-Eur
1557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("CAT", 120, false),  // ICU Link - Africa/Harare
156142de1fcdb6266b1058dafa8b51df96be74d044fNeil Fuller            new ZoneDescriptor("ART", 120, false),  // ICU Link - Africa/Cairo
1577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("EET", 120, true),   // Olson europe 2:00 EU
1587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("EAT", 180, false),  // ICU Link - Africa/Addis_Ababa
1597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("NET", 240, false),  // ICU Link - Asia/Yerevan
1607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("PLT", 300, false),  // ICU Link - Asia/Karachi
1617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("IST", 330, false),  // ICU Link - Asia/Kolkata
1627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("BST", 360, false),  // ICU Link - Asia/Dhaka
1637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("VST", 420, false),  // ICU Link - Asia/Ho_Chi_Minh
1647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("CTT", 480, false),  // ICU Link - Asia/Shanghai
1657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("JST", 540, false),  // ICU Link - Asia/Tokyo
1667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("ACT", 570, false),  // ICU Link - Australia/Darwin
1677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("AET", 600, true),   // ICU Link - Australia/Sydney
1687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("SST", 660, false),  // ICU Link - Pacific/Guadalcanal
1697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("NST", 720, true),   // ICU Link - Pacific/Auckland
1707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("MIT", 780, true),   // ICU Link - Pacific/Apia
1717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("Etc/Unknown", 0, false),    // CLDR
1737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("SystemV/AST4ADT", -240, true),
1757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("SystemV/EST5EDT", -300, true),
1767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("SystemV/CST6CDT", -360, true),
1777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("SystemV/MST7MDT", -420, true),
1787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("SystemV/PST8PDT", -480, true),
1797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("SystemV/YST9YDT", -540, true),
1807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("SystemV/AST4", -240, false),
1817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("SystemV/EST5", -300, false),
1827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("SystemV/CST6", -360, false),
1837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("SystemV/MST7", -420, false),
1847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("SystemV/PST8", -480, false),
1857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("SystemV/YST9", -540, false),
1867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ZoneDescriptor("SystemV/HST10", -600, false),
1877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        };
1887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (int i=0; i<REFERENCE_LIST.length; ++i) {
1907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            ZoneDescriptor referenceZone = REFERENCE_LIST[i];
1917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            ZoneDescriptor currentZone = new ZoneDescriptor(TimeZone.getTimeZone(referenceZone.getID()));
1927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (referenceZone.equals(currentZone)) {
1937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                logln("ok " + referenceZone);
1947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
1957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            else {
1967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (!isDevelopmentBuild || isJDKTimeZone) {
1977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    logln("Warning: Expected " + referenceZone +
1987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            "; got " + currentZone);
1997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } else {
2007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln("Fail: Expected " + referenceZone +
2017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            "; got " + currentZone);
2027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
2037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
2047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
2057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
2067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
2087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * A descriptor for a zone; used to regress the short zone IDs.
2097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
2107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    static class ZoneDescriptor {
2117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        String id;
2127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int offset; // In minutes
2137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        boolean daylight;
2147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ZoneDescriptor(TimeZone zone) {
2167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            this.id = zone.getID();
2177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            this.offset = zone.getRawOffset() / 60000;
2187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            this.daylight = zone.useDaylightTime();
2197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
2207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ZoneDescriptor(String id, int offset, boolean daylight) {
2227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            this.id = id;
2237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            this.offset = offset;
2247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            this.daylight = daylight;
2257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
2267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        public String getID() { return id; }
2287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        public boolean equals(Object o) {
2307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            ZoneDescriptor that = (ZoneDescriptor)o;
2317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return that != null &&
2327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                id.equals(that.id) &&
2337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                offset == that.offset &&
2347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                daylight == that.daylight;
2357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
2367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        public String toString() {
2387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int min = offset;
2397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            char sign = '+';
2407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (min < 0) { sign = '-'; min = -min; }
2417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return "Zone[\"" + id + "\", GMT" + sign + (min/60) + ':' +
2437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                (min%60<10?"0":"") + (min%60) + ", " +
2447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                (daylight ? "Daylight" : "Standard") + "]";
2457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
2467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        public static int compare(Object o1, Object o2) {
2487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            ZoneDescriptor i1 = (ZoneDescriptor)o1;
2497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            ZoneDescriptor i2 = (ZoneDescriptor)o2;
2507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (i1.offset > i2.offset) return 1;
2517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (i1.offset < i2.offset) return -1;
2527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (i1.daylight && !i2.daylight) return 1;
2537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (!i1.daylight && i2.daylight) return -1;
2547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return i1.id.compareTo(i2.id);
2557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
2567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
2577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
2597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * As part of the VM fix (see CCC approved RFE 4028006, bug
2607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * 4044013), TimeZone.getTimeZone() has been modified to recognize
2617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * generic IDs of the form GMT[+-]hh:mm, GMT[+-]hhmm, and
2627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * GMT[+-]hh.  Test this behavior here.
2637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
2647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Bug 4044013
2657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
2662d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
2677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestCustomParse() {
2687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        String[] DATA = {
2697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // ID               offset(sec)     output ID
2707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            "GMT",              "0",            "GMT",      // system ID
2717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            "GMT-YOUR.AD.HERE", "0",            TimeZone.UNKNOWN_ZONE_ID,
2727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            "GMT0",             "0",            "GMT0",     // system ID
2737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            "GMT+0",            "0",            "GMT+0",    // system ID
2747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            "GMT+1",            "3600",         "GMT+01:00",
2757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            "GMT-0030",         "-1800",        "GMT-00:30",
2767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            "GMT+15:99",        "0",            TimeZone.UNKNOWN_ZONE_ID,
2777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            "GMT+",             "0",            TimeZone.UNKNOWN_ZONE_ID,
2787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            "GMT-",             "0",            TimeZone.UNKNOWN_ZONE_ID,
2797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            "GMT+0:",           "0",            TimeZone.UNKNOWN_ZONE_ID,
2807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            "GMT-:",            "0",            TimeZone.UNKNOWN_ZONE_ID,
2817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            "GMT+0010",         "600",          "GMT+00:10",
2827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            "GMT-10",           "-36000",       "GMT-10:00",
2837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            "GMT+30",           "0",            TimeZone.UNKNOWN_ZONE_ID,
2847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            "GMT-3:30",         "-12600",       "GMT-03:30",
2857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            "GMT-230",          "-9000",        "GMT-02:30",
2867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            "GMT+05:13:05",     "18785",        "GMT+05:13:05",
2877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            "GMT-71023",        "-25823",       "GMT-07:10:23",
2887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            "GMT+01:23:45:67",  "0",            TimeZone.UNKNOWN_ZONE_ID,
2897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            "GMT+01:234",       "0",            TimeZone.UNKNOWN_ZONE_ID,
2907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            "GMT-2:31:123",     "0",            TimeZone.UNKNOWN_ZONE_ID,
2917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            "GMT+3:75",         "0",            TimeZone.UNKNOWN_ZONE_ID,
2927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            "GMT-01010101",     "0",            TimeZone.UNKNOWN_ZONE_ID,
2937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        };
2947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (int i = 0; i < DATA.length; i += 3) {
2957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            String id = DATA[i];
2967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int offset = Integer.parseInt(DATA[i+1]);
2977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            String expId = DATA[i+2];
2987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            TimeZone zone = TimeZone.getTimeZone(id);
3007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            String gotID = zone.getID();
3017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int gotOffset = zone.getRawOffset()/1000;
3027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            logln(id + " -> " + gotID + " " + gotOffset);
3047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (offset != gotOffset) {
3067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("FAIL: Unexpected offset for " + id + " - returned:" + gotOffset + " expected:" + offset);
3077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
3087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (!expId.equals(gotID)) {
3097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (TimeZone.getDefaultTimeZoneType() != TimeZone.TIMEZONE_ICU) {
3107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    logln("ID for " + id + " - returned:" + gotID + " expected:" + expId);
3117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } else {
3127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln("FAIL: Unexpected ID for " + id + " - returned:" + gotID + " expected:" + expId);
3137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
3147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
3157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
3167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
3177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
3197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Test the basic functionality of the getDisplayName() API.
3207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
3217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Bug 4112869
3227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Bug 4028006
3237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
3247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * See also API change request A41.
3257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     *
3267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * 4/21/98 - make smarter, so the test works if the ext resources
3277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * are present or not.
3287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
3292d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
3307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestDisplayName() {
3317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        TimeZone zone = TimeZone.getTimeZone("PST");
3327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        String name = zone.getDisplayName(Locale.ENGLISH);
3337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        logln("PST->" + name);
3347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // dlf - we now (3.4.1) return generic time
3367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (!name.equals("Pacific Time"))
3377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("Fail: Expected \"Pacific Time\", got " + name +
3387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                  " for " + zone);
3397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        //*****************************************************************
3417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // THE FOLLOWING LINES MUST BE UPDATED IF THE LOCALE DATA CHANGES
3427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // THE FOLLOWING LINES MUST BE UPDATED IF THE LOCALE DATA CHANGES
3437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // THE FOLLOWING LINES MUST BE UPDATED IF THE LOCALE DATA CHANGES
3447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        //*****************************************************************
3457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Test to allow the user to choose to get all the forms
3477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // (z, zzzz, Z, ZZZZ, v, vvvv)
3487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // todo: check to see whether we can test for all of pst, pdt, pt
3497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        Object[] DATA = {
3507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // z and zzzz
3517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Boolean.FALSE, new Integer(TimeZone.SHORT), "PST",
3527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Boolean.TRUE,  new Integer(TimeZone.SHORT), "PDT",
3537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Boolean.FALSE, new Integer(TimeZone.LONG),  "Pacific Standard Time",
3547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Boolean.TRUE,  new Integer(TimeZone.LONG),  "Pacific Daylight Time",
3557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // v and vvvv
3567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Boolean.FALSE, new Integer(TimeZone.SHORT_GENERIC), "PT",
3577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Boolean.TRUE,  new Integer(TimeZone.SHORT_GENERIC), "PT",
3587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Boolean.FALSE, new Integer(TimeZone.LONG_GENERIC),  "Pacific Time",
3597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Boolean.TRUE,  new Integer(TimeZone.LONG_GENERIC),  "Pacific Time",
3607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // z and ZZZZ
3617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Boolean.FALSE, new Integer(TimeZone.SHORT_GMT), "-0800",
3627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Boolean.TRUE,  new Integer(TimeZone.SHORT_GMT), "-0700",
3637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Boolean.FALSE, new Integer(TimeZone.LONG_GMT),  "GMT-08:00",
3647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Boolean.TRUE,  new Integer(TimeZone.LONG_GMT),  "GMT-07:00",
3657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // V and VVVV
3667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Boolean.FALSE, new Integer(TimeZone.SHORT_COMMONLY_USED), "PST",
3677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Boolean.TRUE,  new Integer(TimeZone.SHORT_COMMONLY_USED), "PDT",
3687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Boolean.FALSE, new Integer(TimeZone.GENERIC_LOCATION),  "Los Angeles Time",
3697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Boolean.TRUE,  new Integer(TimeZone.GENERIC_LOCATION),  "Los Angeles Time",
3707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        };
3717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (int i=0; i<DATA.length; i+=3) {
3737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            name = zone.getDisplayName(((Boolean)DATA[i]).booleanValue(),
3747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                       ((Integer)DATA[i+1]).intValue(),
3757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                       Locale.ENGLISH);
3767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (!name.equals(DATA[i+2]))
3777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("Fail: Expected " + DATA[i+2] + "; got " + name);
3787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
3797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Make sure that we don't display the DST name by constructing a fake
3817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // PST zone that has DST all year long.
3827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // dlf - this test is no longer relevant, we display generic time now
3837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        //    so the behavior of the timezone doesn't matter
3847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        SimpleTimeZone zone2 = new SimpleTimeZone(0, "PST");
3857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        zone2.setStartRule(Calendar.JANUARY, 1, 0);
3867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        zone2.setEndRule(Calendar.DECEMBER, 31, 86399999);
3877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        logln("Modified PST inDaylightTime->" + zone2.inDaylightTime(new Date()));
3887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        name = zone2.getDisplayName(Locale.ENGLISH);
3897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        logln("Modified PST->" + name);
3907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (!name.equals("Pacific Time"))
3917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("Fail: Expected \"Pacific Time\"");
3927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Make sure we get the default display format for Locales
3947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // with no display name data.
3957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        Locale mt_MT = new Locale("mt", "MT");
3967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        name = zone.getDisplayName(mt_MT);
3977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        //*****************************************************************
3987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // THE FOLLOWING LINE MUST BE UPDATED IF THE LOCALE DATA CHANGES
3997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // THE FOLLOWING LINE MUST BE UPDATED IF THE LOCALE DATA CHANGES
4007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // THE FOLLOWING LINE MUST BE UPDATED IF THE LOCALE DATA CHANGES
4017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        //*****************************************************************
4027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        logln("PST(mt_MT)->" + name);
4037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Now be smart -- check to see if zh resource is even present.
4057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // If not, we expect the en fallback behavior.
4067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // in icu4j 2.1 we know we have the zh_CN locale data, though it's incomplete
4087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//    /"DateFormatZoneData",
4092d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert        UResourceBundle enRB = UResourceBundle.getBundleInstance(ICUData.ICU_BASE_NAME,Locale.ENGLISH);
4102d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert        UResourceBundle mtRB = UResourceBundle.getBundleInstance(ICUData.ICU_BASE_NAME, mt_MT);
4117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        boolean noZH = enRB == mtRB;
4127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (noZH) {
4147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            logln("Warning: Not testing the mt_MT behavior because resource is absent");
4157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (!name.equals("Pacific Standard Time"))
4167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("Fail: Expected Pacific Standard Time for PST in mt_MT but got ");
4177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
4187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // dlf - we will use generic time, or if unavailable, GMT for standard time in the zone
4197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        //     - we now (3.4.1) have localizations for this zone, so change test string
4207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        else if(!name.equals("\u0126in ta\u2019 Los Angeles") &&
4217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            !name.equals("GMT-08:00") &&
4227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            !name.equals("GMT-8:00") &&
4237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            !name.equals("GMT-0800") &&
4247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            !name.equals("GMT-800")) {
4257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("Fail: got '" + name + "', expected GMT-08:00 or something similar\n" +
4277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                  "************************************************************\n" +
4287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                  "THE ABOVE FAILURE MAY JUST MEAN THE LOCALE DATA HAS CHANGED\n" +
4297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                  "************************************************************");
4307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
4317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Now try a non-existent zone
4337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        zone2 = new SimpleTimeZone(90*60*1000, "xyzzy");
4347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        name = zone2.getDisplayName(Locale.ENGLISH);
4357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        logln("GMT+90min->" + name);
4367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (!name.equals("GMT+01:30") &&
4377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            !name.equals("GMT+1:30") &&
4387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            !name.equals("GMT+0130") &&
4397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            !name.equals("GMT+130"))
4407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("Fail: Expected GMT+01:30 or something similar");
4417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // cover getDisplayName() - null arg
4437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ULocale save = ULocale.getDefault();
4447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ULocale.setDefault(ULocale.US);
4457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        name = zone2.getDisplayName();
4467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        logln("GMT+90min->" + name + "for default display locale");
4477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (!name.equals("GMT+01:30") &&
4487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            !name.equals("GMT+1:30") &&
4497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            !name.equals("GMT+0130") &&
4507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            !name.equals("GMT+130"))
4517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("Fail: Expected GMT+01:30 or something similar");
4527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ULocale.setDefault(save);
4537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
4557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4572d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
4587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestDisplayName2() {
4597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        Date now = new Date();
4607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        String[] timezones = {"America/Chicago", "Europe/Moscow", "Europe/Rome", "Asia/Shanghai", "WET" };
4627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        String[] locales = {"en", "fr", "de", "ja", "zh_TW", "zh_Hans" };
4637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (int j = 0; j < locales.length; ++j) {
4647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            ULocale locale = new ULocale(locales[j]);
4657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            for (int i = 0; i < timezones.length; ++i) {
4667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                TimeZone tz = TimeZone.getTimeZone(timezones[i]);
4677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                String displayName0 = tz.getDisplayName(locale);
4687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                SimpleDateFormat dt = new SimpleDateFormat("vvvv", locale);
4697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                dt.setTimeZone(tz);
4707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                String displayName1 = dt.format(now);  // date value _does_ matter if we fallback to GMT
4717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                logln(locale.getDisplayName() + ", " + tz.getID() + ": " + displayName0);
4727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (!displayName1.equals(displayName0)) {
4737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    // This could happen when the date used is in DST,
4747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    // because TimeZone.getDisplayName(ULocale) may use
4757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    // localized GMT format for the time zone's standard
4767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    // time.
4777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (tz.inDaylightTime(now)) {
4787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        // Try getDisplayName with daylight argument
4797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        displayName0 = tz.getDisplayName(true, TimeZone.LONG_GENERIC, locale);
4807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }
4817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (!displayName1.equals(displayName0)) {
4827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        errln(locale.getDisplayName() + ", " + tz.getID() +
4837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                ": expected " + displayName1 + " but got: " + displayName0);
4847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }
4857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
4867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
4877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
4887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
4897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4902d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
4917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestGenericAPI() {
4927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        String id = "NewGMT";
4937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int offset = 12345;
4947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        SimpleTimeZone zone = new SimpleTimeZone(offset, id);
4967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (zone.useDaylightTime()) errln("FAIL: useDaylightTime should return false");
4977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        TimeZone zoneclone = (TimeZone)zone.clone();
4997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (!zoneclone.equals(zone)) errln("FAIL: clone or operator== failed");
5007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        zoneclone.setID("abc");
5017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (zoneclone.equals(zone)) errln("FAIL: clone or operator!= failed");
5027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // delete zoneclone;
5037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        zoneclone = (TimeZone)zone.clone();
5057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (!zoneclone.equals(zone)) errln("FAIL: clone or operator== failed");
5067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        zoneclone.setRawOffset(45678);
5077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (zoneclone.equals(zone)) errln("FAIL: clone or operator!= failed");
5087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // C++ only
5107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /*
5117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          SimpleTimeZone copy(*zone);
5127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          if (!(copy == *zone)) errln("FAIL: copy constructor or operator== failed");
5137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          copy = *(SimpleTimeZone*)zoneclone;
5147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          if (!(copy == *zoneclone)) errln("FAIL: assignment operator or operator== failed");
5157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert          */
5167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        TimeZone saveDefault = TimeZone.getDefault();
5187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        TimeZone.setDefault(zone);
5197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        TimeZone defaultzone = TimeZone.getDefault();
5207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (defaultzone == zone) errln("FAIL: Default object is identical, not clone");
521c68e86fabf6fe19beaf10a53dce61790fa14de27Joachim Sauer        // Android patch (http://b/28949992) start.
522c68e86fabf6fe19beaf10a53dce61790fa14de27Joachim Sauer        /*
523c68e86fabf6fe19beaf10a53dce61790fa14de27Joachim Sauer         * {icu}TimeZone.setDefault() calls {java}TimeZone.setDefault().
524c68e86fabf6fe19beaf10a53dce61790fa14de27Joachim Sauer         * On Android {java}TimeZone.setDefault() clears the cached ICU default timezone by calling
525c68e86fabf6fe19beaf10a53dce61790fa14de27Joachim Sauer         * {icu}TimeZone.clearCachedDefault().
526c68e86fabf6fe19beaf10a53dce61790fa14de27Joachim Sauer         * Due to this, and some of the logic in {icu}TimeZone.getDefault(), it is not possible to
527c68e86fabf6fe19beaf10a53dce61790fa14de27Joachim Sauer         * guarantee on Android that {icu}TimeZone.getDefault() returns something that is equal to
528c68e86fabf6fe19beaf10a53dce61790fa14de27Joachim Sauer         * the object passed to setDefault().
529c68e86fabf6fe19beaf10a53dce61790fa14de27Joachim Sauer         * {icu}TimeZone.setDefault() is not public / supported on Android.
530c68e86fabf6fe19beaf10a53dce61790fa14de27Joachim Sauer         */
531c68e86fabf6fe19beaf10a53dce61790fa14de27Joachim Sauer        // if (!defaultzone.equals(zone)) errln("FAIL: Default object is not equal");
532c68e86fabf6fe19beaf10a53dce61790fa14de27Joachim Sauer        // Android patch (http://b/28949992) end.
5337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        TimeZone.setDefault(saveDefault);
5347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // delete defaultzone;
5357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // delete zoneclone;
5367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//      // ICU 2.6 Coverage
5387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//      logln(zone.toString());
5397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//      logln(zone.getDisplayName());
5407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//      SimpleTimeZoneAdapter stza = new SimpleTimeZoneAdapter((SimpleTimeZone) TimeZone.getTimeZone("GMT"));
5417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//      stza.setID("Foo");
5427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//      if (stza.hasSameRules(java.util.TimeZone.getTimeZone("GMT"))) {
5437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//          errln("FAIL: SimpleTimeZoneAdapter.hasSameRules");
5447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//      }
5457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//      stza.setRawOffset(3000);
5467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//      offset = stza.getOffset(GregorianCalendar.BC, 2001, Calendar.DECEMBER,
5477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//                              25, Calendar.TUESDAY, 12*60*60*1000);
5487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//      if (offset != 3000) {
5497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//          errln("FAIL: SimpleTimeZoneAdapter.getOffset");
5507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//      }
5517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//      SimpleTimeZoneAdapter dup = (SimpleTimeZoneAdapter) stza.clone();
5527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//      if (stza.hashCode() != dup.hashCode()) {
5537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//          errln("FAIL: SimpleTimeZoneAdapter.hashCode");
5547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//      }
5557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//      if (!stza.equals(dup)) {
5567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//          errln("FAIL: SimpleTimeZoneAdapter.equals");
5577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//      }
5587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//      logln(stza.toString());
5597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        String tzver = TimeZone.getTZDataVersion();
5617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (tzver.length() != 5 /* 4 digits + 1 letter */) {
5627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("FAIL: getTZDataVersion returned " + tzver);
5637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        } else {
5647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            logln("PASS: tzdata version: " + tzver);
5657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
5667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
5677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5682d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
5697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestRuleAPI()
5707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    {
5717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // ErrorCode status = ZERO_ERROR;
5727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int offset = (int)(60*60*1000*1.75); // Pick a weird offset
5747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        SimpleTimeZone zone = new SimpleTimeZone(offset, "TestZone");
5757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (zone.useDaylightTime()) errln("FAIL: useDaylightTime should return false");
5767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Establish our expected transition times.  Do this with a non-DST
5787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // calendar with the (above) declared local offset.
5797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        GregorianCalendar gc = new GregorianCalendar(zone);
5807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        gc.clear();
5817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        gc.set(1990, Calendar.MARCH, 1);
5827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        long marchOneStd = gc.getTime().getTime(); // Local Std time midnight
5837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        gc.clear();
5847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        gc.set(1990, Calendar.JULY, 1);
5857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        long julyOneStd = gc.getTime().getTime(); // Local Std time midnight
5867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Starting and ending hours, WALL TIME
5887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int startHour = (int)(2.25 * 3600000);
5897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int endHour   = (int)(3.5  * 3600000);
5907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        zone.setStartRule(Calendar.MARCH, 1, 0, startHour);
5927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        zone.setEndRule  (Calendar.JULY,  1, 0, endHour);
5937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        gc = new GregorianCalendar(zone);
5957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // if (failure(status, "new GregorianCalendar")) return;
5967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        long marchOne = marchOneStd + startHour;
5987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        long julyOne = julyOneStd + endHour - 3600000; // Adjust from wall to Std time
5997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        long expMarchOne = 636251400000L;
6017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (marchOne != expMarchOne)
6027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
6037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("FAIL: Expected start computed as " + marchOne +
6047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                  " = " + new Date(marchOne));
6057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            logln("      Should be                  " + expMarchOne +
6067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                  " = " + new Date(expMarchOne));
6077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
6087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        long expJulyOne = 646793100000L;
6107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (julyOne != expJulyOne)
6117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
6127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("FAIL: Expected start computed as " + julyOne +
6137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                  " = " + new Date(julyOne));
6147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            logln("      Should be                  " + expJulyOne +
6157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                  " = " + new Date(expJulyOne));
6167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
6177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        Calendar cal1 = Calendar.getInstance();
6197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        cal1.set(1990, Calendar.JANUARY, 1);
6207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        Calendar cal2 = Calendar.getInstance();
6217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        cal2.set(1990, Calendar.JUNE, 1);
6227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        _testUsingBinarySearch(zone, cal1.getTimeInMillis(),
6237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                               cal2.getTimeInMillis(), marchOne);
6247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        cal1.set(1990, Calendar.JUNE, 1);
6257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        cal2.set(1990, Calendar.DECEMBER, 31);
6267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        _testUsingBinarySearch(zone, cal1.getTimeInMillis(),
6277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                               cal2.getTimeInMillis(), julyOne);
6287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (zone.inDaylightTime(new Date(marchOne - 1000)) ||
6307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            !zone.inDaylightTime(new Date(marchOne)))
6317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("FAIL: Start rule broken");
6327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (!zone.inDaylightTime(new Date(julyOne - 1000)) ||
6337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            zone.inDaylightTime(new Date(julyOne)))
6347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("FAIL: End rule broken");
6357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        zone.setStartYear(1991);
6377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (zone.inDaylightTime(new Date(marchOne)) ||
6387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            zone.inDaylightTime(new Date(julyOne - 1000)))
6397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("FAIL: Start year broken");
6407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // failure(status, "TestRuleAPI");
6427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // delete gc;
6437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // delete zone;
6447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
6457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    void _testUsingBinarySearch(SimpleTimeZone tz, long min, long max, long expectedBoundary)
6477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    {
6487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // ErrorCode status = ZERO_ERROR;
6497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        boolean startsInDST = tz.inDaylightTime(new Date(min));
6507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // if (failure(status, "SimpleTimeZone::inDaylightTime")) return;
6517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (tz.inDaylightTime(new Date(max)) == startsInDST) {
6527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            logln("Error: inDaylightTime(" + new Date(max) + ") != " + (!startsInDST));
6537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return;
6547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
6557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // if (failure(status, "SimpleTimeZone::inDaylightTime")) return;
6567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        while ((max - min) > INTERVAL) {
6577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            long mid = (min + max) / 2;
6587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (tz.inDaylightTime(new Date(mid)) == startsInDST) {
6597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                min = mid;
6607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
6617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            else {
6627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                max = mid;
6637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
6647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // if (failure(status, "SimpleTimeZone::inDaylightTime")) return;
6657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
6667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        logln("Binary Search Before: " + min + " = " + new Date(min));
6677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        logln("Binary Search After:  " + max + " = " + new Date(max));
6687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        long mindelta = expectedBoundary - min;
6697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // not used long maxdelta = max - expectedBoundary;
6707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (mindelta >= 0 &&
6717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            mindelta <= INTERVAL &&
6727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            mindelta >= 0 &&
6737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            mindelta <= INTERVAL)
6747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            logln("PASS: Expected bdry:  " + expectedBoundary + " = " + new Date(expectedBoundary));
6757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        else
6767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("FAIL: Expected bdry:  " + expectedBoundary + " = " + new Date(expectedBoundary));
6777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
6787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    static final int INTERVAL = 100;
6807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // Bug 006; verify the offset for a specific zone.
6822d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
6837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestPRTOffset()
6847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    {
6857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        TimeZone tz = TimeZone.getTimeZone( "PRT" );
6867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if( tz == null ) {
6877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln( "FAIL: TimeZone(PRT) is null" );
6887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
6897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        else{
6907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (tz.getRawOffset() != (-4*millisPerHour))
6917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                warnln("FAIL: Offset for PRT should be -4, got " +
6927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                      tz.getRawOffset() / (double)millisPerHour);
6937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
6947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
6967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // Test various calls
6982d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
6997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestVariousAPI518()
7007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    {
7017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        TimeZone time_zone = TimeZone.getTimeZone("PST");
7027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        Calendar cal = Calendar.getInstance();
7037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        cal.set(1997, Calendar.APRIL, 30);
7047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        Date d = cal.getTime();
7057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        logln("The timezone is " + time_zone.getID());
7077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (time_zone.inDaylightTime(d) != true)
7097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("FAIL: inDaylightTime returned false");
7107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (time_zone.useDaylightTime() != true)
7127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("FAIL: useDaylightTime returned false");
7137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (time_zone.getRawOffset() != -8*millisPerHour)
7157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln( "FAIL: getRawOffset returned wrong value");
7167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        GregorianCalendar gc = new GregorianCalendar();
7187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        gc.setTime(d);
7197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (time_zone.getOffset(GregorianCalendar.AD, gc.get(GregorianCalendar.YEAR), gc.get(GregorianCalendar.MONTH),
7207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                gc.get(GregorianCalendar.DAY_OF_MONTH),
7217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                gc.get(GregorianCalendar.DAY_OF_WEEK), 0)
7227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            != -7*millisPerHour)
7237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("FAIL: getOffset returned wrong value");
7247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
7257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // Test getAvailableID API
7272d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
7287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestGetAvailableIDs913()
7297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    {
7307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        StringBuffer buf = new StringBuffer("TimeZone.getAvailableIDs() = { ");
7317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        String[] s = TimeZone.getAvailableIDs();
7327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (int i=0; i<s.length; ++i)
7337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
7347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (i > 0) buf.append(", ");
7357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            buf.append(s[i]);
7367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
7377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        buf.append(" };");
7387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        logln(buf.toString());
7397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        buf.setLength(0);
7417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        buf.append("TimeZone.getAvailableIDs(GMT+02:00) = { ");
7427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        s = TimeZone.getAvailableIDs(+2 * 60 * 60 * 1000);
7437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (int i=0; i<s.length; ++i)
7447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
7457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (i > 0) buf.append(", ");
7467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            buf.append(s[i]);
7477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
7487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        buf.append(" };");
7497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        logln(buf.toString());
7507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        TimeZone tz = TimeZone.getTimeZone("PST");
7527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (tz != null)
7537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            logln("getTimeZone(PST) = " + tz.getID());
7547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        else
7557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("FAIL: getTimeZone(PST) = null");
7567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        tz = TimeZone.getTimeZone("America/Los_Angeles");
7587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (tz != null)
7597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            logln("getTimeZone(America/Los_Angeles) = " + tz.getID());
7607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        else
7617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("FAIL: getTimeZone(PST) = null");
7627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Bug 4096694
7647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        tz = TimeZone.getTimeZone("NON_EXISTENT");
7657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (tz == null)
7667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("FAIL: getTimeZone(NON_EXISTENT) = null");
7677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        else if (!tz.getID().equals(TimeZone.UNKNOWN_ZONE_ID))
7687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("FAIL: getTimeZone(NON_EXISTENT) = " + tz.getID());
7697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
7707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7712d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
7727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestGetAvailableIDsNew() {
7737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        Set<String> any = TimeZone.getAvailableIDs(SystemTimeZoneType.ANY, null, null);
7747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        Set<String> canonical = TimeZone.getAvailableIDs(SystemTimeZoneType.CANONICAL, null, null);
7757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        Set<String> canonicalLoc = TimeZone.getAvailableIDs(SystemTimeZoneType.CANONICAL_LOCATION, null, null);
7767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        checkContainsAll(any, "ANY", canonical, "CANONICAL");
7787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        checkContainsAll(canonical, "CANONICAL", canonicalLoc, "CANONICALLOC");
7797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        Set<String> any_US = TimeZone.getAvailableIDs(SystemTimeZoneType.ANY, "US", null);
7817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        Set<String> canonical_US = TimeZone.getAvailableIDs(SystemTimeZoneType.CANONICAL, "US", null);
7827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        Set<String> canonicalLoc_US = TimeZone.getAvailableIDs(SystemTimeZoneType.CANONICAL_LOCATION, "US", null);
7837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        checkContainsAll(any, "ANY", any_US, "ANY_US");
7857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        checkContainsAll(canonical, "CANONICAL", canonical_US, "CANONICAL_US");
7867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        checkContainsAll(canonicalLoc, "CANONICALLOC", canonicalLoc_US, "CANONICALLOC_US");
7877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        checkContainsAll(any_US, "ANY_US", canonical_US, "CANONICAL_US");
7897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        checkContainsAll(canonical_US, "CANONICAL_US", canonicalLoc_US, "CANONICALLOC_US");
7907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        final int HOUR = 60*60*1000;
7927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        Set<String> any_W5 = TimeZone.getAvailableIDs(SystemTimeZoneType.ANY, null, -5 * HOUR);
7937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        Set<String> any_CA_W5 = TimeZone.getAvailableIDs(SystemTimeZoneType.ANY, "CA", -5 * HOUR);
7947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        checkContainsAll(any, "ANY", any_W5, "ANY_W5");
7967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        checkContainsAll(any_W5, "ANY_W5", any_CA_W5, "ANY_CA_W5");
7977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        boolean[] isSystemID = new boolean[1];
7997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
8007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // An ID in any set, but not in canonical set must not be a canonical ID
8017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (String id : any) {
8027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (canonical.contains(id)) {
8037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                continue;
8047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
8057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            String cid = TimeZone.getCanonicalID(id, isSystemID);
8067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (id.equals(cid)) {
8077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("FAIL: canonical ID [" + id + "] is not in CANONICAL");
8087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
8097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (!isSystemID[0]) {
8107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("FAIL: ANY contains non-system ID: " + id);
8117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
8127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
8137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
8147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // canonical set must contains only canonical IDs
8157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (String id : canonical) {
8167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            String cid = TimeZone.getCanonicalID(id, isSystemID);
8177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (!id.equals(cid)) {
8187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("FAIL: CANONICAL contains non-canonical ID: " + id);
8197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
8207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (!isSystemID[0]) {
8217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("FAIL: CANONICAL contains non-system ID: " + id);
8227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
8237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
8247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
8257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // canonicalLoc set must contains only canonical location IDs
8267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (String id : canonicalLoc) {
8277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            String cid = TimeZone.getCanonicalID(id, isSystemID);
8287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (!id.equals(cid)) {
8297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("FAIL: CANONICAL contains non-canonical ID: " + id);
8307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
8317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (!isSystemID[0]) {
8327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("FAIL: CANONICAL contains non-system ID: " + id);
8337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
8347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            String region = TimeZone.getRegion(id);
8357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (region.equals("001")) {
8367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("FAIL: CANONICALLOC contains non location zone: " + id);
8377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
8387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
8397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
8407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // any_US must contain only US zones
8417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (String id : any_US) {
8427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            String region = TimeZone.getRegion(id);
8437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (!region.equals("US")) {
8447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("FAIL: ANY_US contains non-US zone ID: " + id);
8457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
8467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
8477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
8487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // any_W5 must contain only GMT-05:00 zones
8497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (String id : any_W5) {
8507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            TimeZone tz = TimeZone.getTimeZone(id);
8517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (tz.getRawOffset() != -5 * HOUR) {
8527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("FAIL: ANY_W5 contains a zone whose offset is not -5:00: " + id);
8537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
8547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
8557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
8567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // No US zones with GMT+14:00
8577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        Set<String> any_US_E14 = TimeZone.getAvailableIDs(SystemTimeZoneType.ANY, "US", 14 * HOUR);
8587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (!any_US_E14.isEmpty()) {
8597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("FAIL: ANY_US_E14 must be empty");
8607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
8617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
8627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
8637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private void checkContainsAll(Set<String> set1, String name1, Set<String> set2, String name2) {
8647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (!set1.containsAll(set2)) {
8657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            StringBuilder buf = new StringBuilder();
8667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            for (String s : set2) {
8677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (!set1.contains(s)) {
8687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (buf.length() != 0) {
8697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        buf.append(",");
8707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }
8717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    buf.append(s);
8727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
8737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
8747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("FAIL: " + name1 + " does not contain all of " + name2 + " - missing: {" + buf + "}");
8757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
8767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
8777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
8787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
8797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Bug 4107276
8807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
8812d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
8827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestDSTSavings() {
8837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // It might be better to find a way to integrate this test into the main TimeZone
8847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // tests above, but I don't have time to figure out how to do this (or if it's
8857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // even really a good idea).  Let's consider that a future.  --rtg 1/27/98
8867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        SimpleTimeZone tz = new SimpleTimeZone(-5 * millisPerHour, "dstSavingsTest",
8877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                               Calendar.MARCH, 1, 0, 0, Calendar.SEPTEMBER, 1, 0, 0,
8887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                               (int)(0.5 * millisPerHour));
8897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
8907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (tz.getRawOffset() != -5 * millisPerHour)
8917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("Got back a raw offset of " + (tz.getRawOffset() / millisPerHour) +
8927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                  " hours instead of -5 hours.");
8937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (!tz.useDaylightTime())
8947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("Test time zone should use DST but claims it doesn't.");
8957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (tz.getDSTSavings() != 0.5 * millisPerHour)
8967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("Set DST offset to 0.5 hour, but got back " + (tz.getDSTSavings() /
8977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                                 millisPerHour) + " hours instead.");
8987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
8997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.JANUARY, 1,
9007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                  Calendar.THURSDAY, 10 * millisPerHour);
9017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (offset != -5 * millisPerHour)
9027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("The offset for 10 AM, 1/1/98 should have been -5 hours, but we got "
9037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                  + (offset / millisPerHour) + " hours.");
9047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.JUNE, 1, Calendar.MONDAY,
9067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                              10 * millisPerHour);
9077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (offset != -4.5 * millisPerHour)
9087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("The offset for 10 AM, 6/1/98 should have been -4.5 hours, but we got "
9097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                  + (offset / millisPerHour) + " hours.");
9107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        tz.setDSTSavings(millisPerHour);
9127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.JANUARY, 1,
9137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                              Calendar.THURSDAY, 10 * millisPerHour);
9147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (offset != -5 * millisPerHour)
9157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("The offset for 10 AM, 1/1/98 should have been -5 hours, but we got "
9167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                  + (offset / millisPerHour) + " hours.");
9177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.JUNE, 1, Calendar.MONDAY,
9197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                              10 * millisPerHour);
9207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (offset != -4 * millisPerHour)
9217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("The offset for 10 AM, 6/1/98 (with a 1-hour DST offset) should have been -4 hours, but we got "
9227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                  + (offset / millisPerHour) + " hours.");
9237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
9247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
9267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Bug 4107570
9277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
9282d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
9297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestAlternateRules() {
9307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Like TestDSTSavings, this test should probably be integrated somehow with the main
9317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // test at the top of this class, but I didn't have time to figure out how to do that.
9327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        //                      --rtg 1/28/98
9337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        SimpleTimeZone tz = new SimpleTimeZone(-5 * millisPerHour, "alternateRuleTest");
9357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // test the day-of-month API
9377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        tz.setStartRule(Calendar.MARCH, 10, 12 * millisPerHour);
9387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        tz.setEndRule(Calendar.OCTOBER, 20, 12 * millisPerHour);
9397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.MARCH, 5,
9417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                  Calendar.THURSDAY, 10 * millisPerHour);
9427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (offset != -5 * millisPerHour)
9437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("The offset for 10AM, 3/5/98 should have been -5 hours, but we got "
9447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                  + (offset / millisPerHour) + " hours.");
9457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.MARCH, 15,
9477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                              Calendar.SUNDAY, 10 * millisPerHour);
9487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (offset != -4 * millisPerHour)
9497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("The offset for 10AM, 3/15/98 should have been -4 hours, but we got "
9507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                  + (offset / millisPerHour) + " hours.");
9517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.OCTOBER, 15,
9537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                              Calendar.THURSDAY, 10 * millisPerHour);
9547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (offset != -4 * millisPerHour)
9557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("The offset for 10AM, 10/15/98 should have been -4 hours, but we got "
9567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                  + (offset / millisPerHour) + " hours.");
9577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.OCTOBER, 25,
9597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                              Calendar.SUNDAY, 10 * millisPerHour);
9607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (offset != -5 * millisPerHour)
9617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("The offset for 10AM, 10/25/98 should have been -5 hours, but we got "
9627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                  + (offset / millisPerHour) + " hours.");
9637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // test the day-of-week-after-day-in-month API
9657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        tz.setStartRule(Calendar.MARCH, 10, Calendar.FRIDAY, 12 * millisPerHour, true);
9667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        tz.setEndRule(Calendar.OCTOBER, 20, Calendar.FRIDAY, 12 * millisPerHour, false);
9677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.MARCH, 11,
9697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                              Calendar.WEDNESDAY, 10 * millisPerHour);
9707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (offset != -5 * millisPerHour)
9717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("The offset for 10AM, 3/11/98 should have been -5 hours, but we got "
9727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                  + (offset / millisPerHour) + " hours.");
9737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.MARCH, 14,
9757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                              Calendar.SATURDAY, 10 * millisPerHour);
9767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (offset != -4 * millisPerHour)
9777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("The offset for 10AM, 3/14/98 should have been -4 hours, but we got "
9787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                  + (offset / millisPerHour) + " hours.");
9797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.OCTOBER, 15,
9817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                              Calendar.THURSDAY, 10 * millisPerHour);
9827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (offset != -4 * millisPerHour)
9837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("The offset for 10AM, 10/15/98 should have been -4 hours, but we got "
9847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                  + (offset / millisPerHour) + " hours.");
9857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.OCTOBER, 17,
9877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                              Calendar.SATURDAY, 10 * millisPerHour);
9887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (offset != -5 * millisPerHour)
9897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("The offset for 10AM, 10/17/98 should have been -5 hours, but we got "
9907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                  + (offset / millisPerHour) + " hours.");
9917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
9927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
9932d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
9947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestEquivalencyGroups() {
9957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        String id = "America/Los_Angeles";
9967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int n = TimeZone.countEquivalentIDs(id);
9977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (n < 2) {
9987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("FAIL: countEquivalentIDs(" + id + ") returned " + n +
9997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                  ", expected >= 2");
10007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
10017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (int i=0; i<n; ++i) {
10027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            String s = TimeZone.getEquivalentID(id, i);
10037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (s.length() == 0) {
10047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("FAIL: getEquivalentID(" + id + ", " + i +
10057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                      ") returned \"" + s + "\", expected valid ID");
10067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } else {
10077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                logln("" + i + ":" + s);
10087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
10097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
10107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
10117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // JB#5480 - equivalent IDs should not be empty within range
10127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        String[] ids = TimeZone.getAvailableIDs();
10137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (int i = 0; i < ids.length; i++) {
10147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int nEquiv = TimeZone.countEquivalentIDs(ids[i]);
10157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // Each equivalent ID must not be empty
10167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            for (int j = 0; j < nEquiv; j++) {
10177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                String equivID = TimeZone.getEquivalentID(ids[i], j);
10187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (equivID.length() == 0) {
10197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln("FAIL: getEquivalentID(" + ids[i] + ", " + i +
10207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            ") returned \"" + equivID + "\", expected valid ID");
10217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
10227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
10237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // equivalent ID out of range must be empty
10247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            String outOfRangeID = TimeZone.getEquivalentID(ids[i], nEquiv);
10257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (outOfRangeID.length() != 0) {
10267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("FAIL: getEquivalentID(" + ids[i] + ", " + i +
10277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        ") returned \"" + outOfRangeID + "\", expected empty string");
10287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
10297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
10307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
10317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Ticket#8927 invalid system ID
10327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        final String[] invaldIDs = {"GMT-05:00", "Hello World!", ""};
10337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (String invld : invaldIDs) {
10347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int nEquiv = TimeZone.countEquivalentIDs(invld);
10357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (nEquiv != 0) {
10367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("FAIL: countEquivalentIDs(" + invld + ") returned: " + nEquiv
10377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        + ", expected: 0");
10387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
10397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            String sEquiv0 = TimeZone.getEquivalentID(invld, 0);
10407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (sEquiv0.length() > 0) {
10417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("FAIL: getEquivalentID(" + invld + ", 0) returned \"" + sEquiv0
10427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        + "\", expected empty string");
10437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
10447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
10457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
10467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
10472d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
10487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestCountries() {
10497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Make sure America/Los_Angeles is in the "US" group, and
10507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Asia/Tokyo isn't.  Vice versa for the "JP" group.
10517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
10527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        String[] s = TimeZone.getAvailableIDs("US");
10537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        boolean la = false, tokyo = false;
10547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        String laZone = "America/Los_Angeles", tokyoZone = "Asia/Tokyo";
10557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
10567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (int i=0; i<s.length; ++i) {
10577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (s[i].equals(laZone)) {
10587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                la = true;
10597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
10607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (s[i].equals(tokyoZone)) {
10617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                tokyo = true;
10627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
10637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
10647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (!la ) {
10657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("FAIL: " + laZone + " in US = " + la);
10667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
10677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (tokyo) {
10687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("FAIL: " + tokyoZone + " in US = " + tokyo);
10697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
10707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        s = TimeZone.getAvailableIDs("JP");
10717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        la = false; tokyo = false;
10727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
10737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (int i=0; i<s.length; ++i) {
10747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (s[i].equals(laZone)) {
10757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                la = true;
10767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
10777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (s[i].equals(tokyoZone)) {
10787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                tokyo = true;
10797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
10807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
10817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (la) {
10827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("FAIL: " + laZone + " in JP = " + la);
10837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
10847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (!tokyo) {
10857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("FAIL: " + tokyoZone + " in JP = " + tokyo);
10867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
10877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
10887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
10892d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
10907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestFractionalDST() {
10917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        String tzName = "Australia/Lord_Howe"; // 30 min offset
10927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        java.util.TimeZone tz_java = java.util.TimeZone.getTimeZone(tzName);
10937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int dst_java = 0;
10947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        try {
10957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // hack so test compiles and runs in both JDK 1.3 and JDK 1.4
10967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            final Object[] args = new Object[0];
10977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            final Class[] argtypes = new Class[0];
10987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            java.lang.reflect.Method m = tz_java.getClass().getMethod("getDSTSavings", argtypes);
10997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            dst_java = ((Integer) m.invoke(tz_java, args)).intValue();
11007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (dst_java <= 0 || dst_java >= 3600000) { // didn't get the fractional time zone we wanted
11017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("didn't get fractional time zone!");
11027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
11037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        } catch (NoSuchMethodException e) {
11047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // see JDKTimeZone for the reason for this code
11057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            dst_java = 3600000;
11067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        } catch (IllegalAccessException e) {
11077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // see JDKTimeZone for the reason for this code
11087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln(e.getMessage());
11097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            dst_java = 3600000;
11107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        } catch (InvocationTargetException e) {
11117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // see JDKTimeZone for the reason for this code
11127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln(e.getMessage());
11137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            dst_java = 3600000;
11147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        } catch (SecurityException e) {
11157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            warnln(e.getMessage());
11167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return;
11177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
11187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
11197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        com.ibm.icu.util.TimeZone tz_icu = com.ibm.icu.util.TimeZone.getTimeZone(tzName);
11207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int dst_icu = tz_icu.getDSTSavings();
11217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
11227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (dst_java != dst_icu) {
11237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            warnln("java reports dst savings of " + dst_java +
11247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert              " but icu reports " + dst_icu +
11257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert              " for tz " + tz_icu.getID());
11267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        } else {
11277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            logln("both java and icu report dst savings of " + dst_java + " for tz " + tz_icu.getID());
11287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
11297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
11307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
11312d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
11327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestGetOffsetDate() {
11337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        Calendar cal = Calendar.getInstance();
11347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        cal.set(1997, Calendar.JANUARY, 30);
11357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        long date = cal.getTimeInMillis();
11367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
11377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    TimeZone tz_icu = TimeZone.getTimeZone("America/Los_Angeles");
11387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    int offset = tz_icu.getOffset(date);
11397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    if (offset != -28800000) {
11407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        errln("expected offset -28800000, got: " + offset);
11417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
11427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
11437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    cal.set(1997, Calendar.JULY, 30);
11447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    date = cal.getTimeInMillis();
11457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    offset = tz_icu.getOffset(date);
11467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    if (offset != -25200000) {
11477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        errln("expected offset -25200000, got: " + offset);
11487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
11497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
11507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
11517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // jb4484
11522d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
11537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestSimpleTimeZoneSerialization()
11547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    {
11557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        SimpleTimeZone stz0 = new SimpleTimeZone(32400000, "MyTimeZone");
11567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        SimpleTimeZone stz1 = new SimpleTimeZone(32400000, "Asia/Tokyo");
11577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        SimpleTimeZone stz2 = new SimpleTimeZone(32400000, "Asia/Tokyo");
11587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        stz2.setRawOffset(0);
11597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        SimpleTimeZone stz3 = new SimpleTimeZone(32400000, "Asia/Tokyo");
11607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        stz3.setStartYear(100);
11617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        SimpleTimeZone stz4 = new SimpleTimeZone(32400000, "Asia/Tokyo");
11627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        stz4.setStartYear(1000);
11637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        stz4.setDSTSavings(1800000);
11647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        stz4.setStartRule(3, 4, 180000);
11657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        stz4.setEndRule(6, 3, 4, 360000);
11667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        SimpleTimeZone stz5 = new SimpleTimeZone(32400000, "Asia/Tokyo");
11677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        stz5.setStartRule(2, 3, 4, 360000);
11687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        stz5.setEndRule(6, 3, 4, 360000);
11697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
11707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        SimpleTimeZone[] stzs = { stz0, stz1, stz2, stz3, stz4, stz5, };
11717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
11727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (int i = 0; i < stzs.length; ++i) {
11737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            SimpleTimeZone stz = stzs[i];
11747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            try {
11757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                ByteArrayOutputStream baos = new ByteArrayOutputStream();
11767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                ObjectOutputStream oos = new ObjectOutputStream(baos);
11777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                oos.writeObject(stz);
11787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                oos.close();
11797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                byte[] bytes = baos.toByteArray();
11807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                logln("id: " + stz.getID() + " length: " + bytes.length);
11817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
11827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
11837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                ObjectInputStream ois = new ObjectInputStream(bais);
11847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
11857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                SimpleTimeZone stzDeserialized = (SimpleTimeZone)ois.readObject();
11867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                ois.close();
11877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
11887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                assertEquals("time zones", stz, stzDeserialized);
11897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
11907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            catch (ClassCastException cce) {
11917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                cce.printStackTrace();
11927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("could not deserialize SimpleTimeZone");
11937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
11947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            catch (IOException ioe) {
11957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln(ioe.getMessage());
11967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
11977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            catch (ClassNotFoundException cnfe) {
11987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln(cnfe.getMessage());
11997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
12007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
12017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
12027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
12037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // jb4175
12047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /* Generated by org.unicode.cldr.tool.CountItems */
12057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final String[] timeZoneTestNames = {
12067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "America/Argentina/Buenos_Aires", "America/Buenos_Aires",
12077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "America/Argentina/Catamarca", "America/Catamarca",
12087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "America/Argentina/Cordoba", "America/Cordoba",
12097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "America/Argentina/Jujuy", "America/Jujuy",
12107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "America/Argentina/Mendoza", "America/Mendoza",
12117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "America/Atka", "America/Adak",
12127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "America/Ensenada", "America/Tijuana",
12137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "America/Fort_Wayne", "America/Indianapolis",
12147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "America/Indiana/Indianapolis", "America/Indianapolis",
12157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "America/Kentucky/Louisville", "America/Louisville",
12167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "America/Knox_IN", "America/Indiana/Knox",
12177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "America/Porto_Acre", "America/Rio_Branco",
12187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "America/Rosario", "America/Cordoba",
12197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "America/Virgin", "America/St_Thomas",
12207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Asia/Ashkhabad", "Asia/Ashgabat",
12217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Asia/Chungking", "Asia/Chongqing",
12227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Asia/Dacca", "Asia/Dhaka",
12237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Asia/Istanbul", "Europe/Istanbul",
12247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Asia/Macao", "Asia/Macau",
12257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Asia/Tel_Aviv", "Asia/Jerusalem",
12267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Asia/Thimbu", "Asia/Thimphu",
12277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Asia/Ujung_Pandang", "Asia/Makassar",
12287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Asia/Ulan_Bator", "Asia/Ulaanbaatar",
12297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Australia/ACT", "Australia/Sydney",
12307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Australia/Canberra", "Australia/Sydney",
12317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Australia/LHI", "Australia/Lord_Howe",
12327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Australia/NSW", "Australia/Sydney",
12337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Australia/North", "Australia/Darwin",
12347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Australia/Queensland", "Australia/Brisbane",
12357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Australia/South", "Australia/Adelaide",
12367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Australia/Tasmania", "Australia/Hobart",
12377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Australia/Victoria", "Australia/Melbourne",
12387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Australia/West", "Australia/Perth",
12397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Australia/Yancowinna", "Australia/Broken_Hill",
12407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Brazil/Acre", "America/Rio_Branco",
12417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Brazil/DeNoronha", "America/Noronha",
12427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Brazil/East", "America/Sao_Paulo",
12437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Brazil/West", "America/Manaus",
12447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "CST6CDT", "America/Chicago",
12457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Canada/Atlantic", "America/Halifax",
12467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Canada/Central", "America/Winnipeg",
12477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Canada/East-Saskatchewan", "America/Regina",
12487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Canada/Eastern", "America/Toronto",
12497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Canada/Mountain", "America/Edmonton",
12507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Canada/Newfoundland", "America/St_Johns",
12517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Canada/Pacific", "America/Vancouver",
12527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Canada/Saskatchewan", "America/Regina",
12537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Canada/Yukon", "America/Whitehorse",
12547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Chile/Continental", "America/Santiago",
12557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Chile/EasterIsland", "Pacific/Easter",
12567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Cuba", "America/Havana",
12577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "EST", "America/Indianapolis",
12587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "EST5EDT", "America/New_York",
12597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Egypt", "Africa/Cairo",
12607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Eire", "Europe/Dublin",
12617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Etc/GMT+0", "Etc/GMT",
12627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Etc/GMT-0", "Etc/GMT",
12637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Etc/GMT0", "Etc/GMT",
12647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Etc/Greenwich", "Etc/GMT",
12657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Etc/UCT", "Etc/GMT",
12667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Etc/UTC", "Etc/GMT",
12677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Etc/Universal", "Etc/GMT",
12687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Etc/Zulu", "Etc/GMT",
12697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Europe/Nicosia", "Asia/Nicosia",
12707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Europe/Tiraspol", "Europe/Chisinau",
12717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "GB", "Europe/London",
12727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "GB-Eire", "Europe/London",
12737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "GMT", "Etc/GMT",
12747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "GMT+0", "Etc/GMT",
12757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "GMT-0", "Etc/GMT",
12767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "GMT0", "Etc/GMT",
12777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Greenwich", "Etc/GMT",
12787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "HST", "Pacific/Honolulu",
12797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Hongkong", "Asia/Hong_Kong",
12807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Iceland", "Atlantic/Reykjavik",
12817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Iran", "Asia/Tehran",
12827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Israel", "Asia/Jerusalem",
12837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Jamaica", "America/Jamaica",
12847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Japan", "Asia/Tokyo",
12857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Kwajalein", "Pacific/Kwajalein",
12867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Libya", "Africa/Tripoli",
12877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "MST", "America/Phoenix",
12887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "MST7MDT", "America/Denver",
12897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Mexico/BajaNorte", "America/Tijuana",
12907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Mexico/BajaSur", "America/Mazatlan",
12917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Mexico/General", "America/Mexico_City",
12927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "NZ", "Pacific/Auckland",
12937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "NZ-CHAT", "Pacific/Chatham",
12947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Navajo", "America/Shiprock", /* fixed from Mark's original */
12957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "PRC", "Asia/Shanghai",
12967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "PST8PDT", "America/Los_Angeles",
12977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Pacific/Samoa", "Pacific/Pago_Pago",
12987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Poland", "Europe/Warsaw",
12997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Portugal", "Europe/Lisbon",
13007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "ROC", "Asia/Taipei",
13017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "ROK", "Asia/Seoul",
13027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Singapore", "Asia/Singapore",
13037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "SystemV/AST4", "America/Puerto_Rico",
13047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "SystemV/AST4ADT", "America/Halifax",
13057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "SystemV/CST6", "America/Regina",
13067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "SystemV/CST6CDT", "America/Chicago",
13077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "SystemV/EST5", "America/Indianapolis",
13087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "SystemV/EST5EDT", "America/New_York",
13097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "SystemV/HST10", "Pacific/Honolulu",
13107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "SystemV/MST7", "America/Phoenix",
13117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "SystemV/MST7MDT", "America/Denver",
13127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "SystemV/PST8", "Pacific/Pitcairn",
13137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "SystemV/PST8PDT", "America/Los_Angeles",
13147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "SystemV/YST9", "Pacific/Gambier",
13157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "SystemV/YST9YDT", "America/Anchorage",
13167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Turkey", "Europe/Istanbul",
13177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "UCT", "Etc/GMT",
13187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "US/Alaska", "America/Anchorage",
13197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "US/Aleutian", "America/Adak",
13207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "US/Arizona", "America/Phoenix",
13217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "US/Central", "America/Chicago",
13227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "US/East-Indiana", "America/Indianapolis",
13237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "US/Eastern", "America/New_York",
13247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "US/Hawaii", "Pacific/Honolulu",
13257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "US/Indiana-Starke", "America/Indiana/Knox",
13267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "US/Michigan", "America/Detroit",
13277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "US/Mountain", "America/Denver",
13287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "US/Pacific", "America/Los_Angeles",
13297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "US/Pacific-New", "America/Los_Angeles",
13307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "US/Samoa", "Pacific/Pago_Pago",
13317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "UTC", "Etc/GMT",
13327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Universal", "Etc/GMT",
13337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "W-SU", "Europe/Moscow",
13347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        "Zulu", "Etc/GMT",
13357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    };
13367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
13372d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
13387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestOddTimeZoneNames() {
13397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (int i = 0; i < timeZoneTestNames.length; i += 2) {
13407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            String funkyName = timeZoneTestNames[i];
13417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            String correctName = timeZoneTestNames[i+1];
13427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
13437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            TimeZone ftz = TimeZone.getTimeZone(funkyName);
13447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            TimeZone ctz = TimeZone.getTimeZone(correctName);
13457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
13467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            String fdn = ftz.getDisplayName();
13477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            long fro = ftz.getRawOffset();
13487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            long fds = ftz.getDSTSavings();
13497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            boolean fdy = ftz.useDaylightTime();
13507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
13517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            String cdn = ctz.getDisplayName();
13527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            long cro = ctz.getRawOffset();
13537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            long cds = ctz.getDSTSavings();
13547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            boolean cdy = ctz.useDaylightTime();
13557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
13567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (!fdn.equals(cdn)) {
13577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                logln("display name (" + funkyName + ", " + correctName + ") expected: " + cdn + " but got: " + fdn);
13587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } else if (fro != cro) {
13597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                logln("offset (" + funkyName + ", " + correctName + ") expected: " + cro + " but got: " + fro);
13607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } else if (fds != cds) {
13617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                logln("daylight (" + funkyName + ", " + correctName + ") expected: " + cds + " but got: " + fds);
13627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } else if (fdy != cdy) {
13637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                logln("uses daylight (" + funkyName + ", " + correctName + ") expected: " + cdy + " but got: " + fdy);
13647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } else {
13657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // no error, assume we're referencing the same internal java object
13667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
13677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
13687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
13697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
13702d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
13717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestCoverage(){
13727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        class StubTimeZone extends TimeZone{
13737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            /**
13747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             * For serialization
13757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert             */
13767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            private static final long serialVersionUID = 8658654217433379343L;
13777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            public int getOffset(int era, int year, int month, int day, int dayOfWeek, int milliseconds) {return 0;}
13787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            public void setRawOffset(int offsetMillis) {}
13797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            public int getRawOffset() {return 0;}
13807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            public boolean useDaylightTime() {return false;}
13817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            public boolean inDaylightTime(Date date) {return false;}
13827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
13837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        StubTimeZone stub = new StubTimeZone();
13847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        StubTimeZone stub2 = (StubTimeZone) stub.clone();
13857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (stub.getDSTSavings() != 0){
13867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("TimeZone.getDSTSavings() should return 0");
13877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
13887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (!stub.hasSameRules(stub2)){
13897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("TimeZone.clone() object should hasSameRules");
13907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
13917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
13927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
13932d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
13947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestMark(){
13957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        String tzid = "America/Argentina/ComodRivadavia";
13967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        TimeZone tz = TimeZone.getTimeZone(tzid);
13977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int offset = tz.getOffset(new Date().getTime());
13987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        logln(tzid + ":\t" + offset);
13997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        List list = Arrays.asList(TimeZone.getAvailableIDs());
14007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if(!list.contains(tzid)){
14017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("Could create the time zone but it is not in getAvailableIDs");
14027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
14037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
14042d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
14057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestZoneMeta() {
14067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        java.util.TimeZone save = java.util.TimeZone.getDefault();
14077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        java.util.TimeZone newZone = java.util.TimeZone.getTimeZone("GMT-08:00");
14087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        com.ibm.icu.util.TimeZone.setDefault(null);
14097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        java.util.TimeZone.setDefault(newZone);
14107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        SimpleTimeZone zone = new SimpleTimeZone(0, "GMT");
14117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        com.ibm.icu.util.TimeZone defaultZone = com.ibm.icu.util.TimeZone.getDefault();
14127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if(defaultZone==null){
14137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("TimeZone.getDefault() failed for GMT-08:00");
14147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
14157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if(zone==null){
14167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("SimpleTimeZone(0, GMT-08:00) failed for GMT-08:00");
14177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
14187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        //reset
14197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        java.util.TimeZone.setDefault(save);
14207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
14217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
14227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    // Copied from the protected constant in TimeZone.
14237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static final int MILLIS_PER_HOUR = 60*60*1000;
14247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
14257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    //  Test that a transition at the end of February is handled correctly.
14262d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
14277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestFebruary() {
14287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Time zone with daylight savings time from the first Sunday in November
14297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // to the last Sunday in February.
14307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Similar to the new rule for Brazil (Sao Paulo) in tzdata2006n.
14317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        //
14327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Note: In tzdata2007h, the rule had changed, so no actual zones uses
14337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // lastSun in Feb anymore.
14347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        SimpleTimeZone tz1 = new SimpleTimeZone(
14357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                           -3 * MILLIS_PER_HOUR,                    // raw offset: 3h before (west of) GMT
14367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                           "nov-feb",
14377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                           Calendar.NOVEMBER, 1, Calendar.SUNDAY,   // start: November, first, Sunday
14387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                           0,                                       //        midnight wall time
14397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                           Calendar.FEBRUARY, -1, Calendar.SUNDAY,  // end:   February, last, Sunday
14407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                           0);                                      //        midnight wall time
14417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
14427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Now hardcode the same rules as for Brazil in tzdata 2006n, so that
14437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // we cover the intended code even when in the future zoneinfo hardcodes
14447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // these transition dates.
14457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        SimpleTimeZone tz2= new SimpleTimeZone(
14467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                           -3 * MILLIS_PER_HOUR,                    // raw offset: 3h before (west of) GMT
14477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                           "nov-feb2",
14487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                           Calendar.NOVEMBER, 1, -Calendar.SUNDAY,  // start: November, 1 or after, Sunday
14497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                           0,                                       //        midnight wall time
14507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                           Calendar.FEBRUARY, -29, -Calendar.SUNDAY,// end:   February, 29 or before, Sunday
14517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                           0);                                      //        midnight wall time
14527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
14537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Gregorian calendar with the UTC time zone for getting sample test date/times.
14547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        GregorianCalendar gc = new GregorianCalendar(TimeZone.getTimeZone("Etc/GMT"));
14557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // "Unable to create the UTC calendar: %s"
14567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
14577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int[] data = {
14587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // UTC time (6 fields) followed by
14597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // expected time zone offset in hours after GMT (negative=before GMT).
14607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // int year, month, day, hour, minute, second, offsetHours
14617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            2006, Calendar.NOVEMBER,  5, 02, 59, 59, -3,
14627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            2006, Calendar.NOVEMBER,  5, 03, 00, 00, -2,
14637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            2007, Calendar.FEBRUARY, 25, 01, 59, 59, -2,
14647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            2007, Calendar.FEBRUARY, 25, 02, 00, 00, -3,
14657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
14667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            2007, Calendar.NOVEMBER,  4, 02, 59, 59, -3,
14677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            2007, Calendar.NOVEMBER,  4, 03, 00, 00, -2,
14687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            2008, Calendar.FEBRUARY, 24, 01, 59, 59, -2,
14697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            2008, Calendar.FEBRUARY, 24, 02, 00, 00, -3,
14707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
14717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            2008, Calendar.NOVEMBER,  2, 02, 59, 59, -3,
14727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            2008, Calendar.NOVEMBER,  2, 03, 00, 00, -2,
14737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            2009, Calendar.FEBRUARY, 22, 01, 59, 59, -2,
14747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            2009, Calendar.FEBRUARY, 22, 02, 00, 00, -3,
14757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
14767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            2009, Calendar.NOVEMBER,  1, 02, 59, 59, -3,
14777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            2009, Calendar.NOVEMBER,  1, 03, 00, 00, -2,
14787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            2010, Calendar.FEBRUARY, 28, 01, 59, 59, -2,
14797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            2010, Calendar.FEBRUARY, 28, 02, 00, 00, -3
14807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        };
14817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
14827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        TimeZone timezones[] = { tz1, tz2 };
14837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
14847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        TimeZone tz;
14857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        Date dt;
14867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int t, i, raw, dst;
14877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int[] offsets = new int[2]; // raw = offsets[0], dst = offsets[1]
14887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (t = 0; t < timezones.length; ++t) {
14897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            tz = timezones[t];
14907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            for (i = 0; i < data.length; i+=7) {
14917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                gc.set(data[i], data[i+1], data[i+2],
14927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                       data[i+3], data[i+4], data[i+5]);
14937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                dt = gc.getTime();
14947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                tz.getOffset(dt.getTime(), false, offsets);
14957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                raw = offsets[0];
14967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                dst = offsets[1];
14977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if ((raw + dst) != data[i+6] * MILLIS_PER_HOUR) {
14987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln("test case " + t + "." + (i/7) + ": " +
14997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                          "tz.getOffset(" + data[i] + "-" + (data[i+1] + 1) + "-" + data[i+2] + " " +
15007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                          data[i+3] + ":" + data[i+4] + ":" + data[i+5] +
15017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                          ") returns " + raw + "+" + dst + " != " + data[i+6] * MILLIS_PER_HOUR);
15027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
15037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
15047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
15057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
15067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
15072d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
15087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestCanonicalID() {
15097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Some canonical IDs in CLDR are defined as "Link"
15107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // in Olson tzdata.
15117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        final String[][] excluded1 = {
151228d9287dbcd4cb6cd7ff9c72ac69b1d1b3084701Yoshito Umaoka                {"Africa/Addis_Ababa", "Africa/Nairobi"},
151328d9287dbcd4cb6cd7ff9c72ac69b1d1b3084701Yoshito Umaoka                {"Africa/Asmera", "Africa/Nairobi"},
15147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Africa/Bamako", "Africa/Abidjan"},
15157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Africa/Bangui", "Africa/Lagos"},
15167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Africa/Banjul", "Africa/Abidjan"},
15177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Africa/Blantyre", "Africa/Maputo"},
15187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Africa/Brazzaville", "Africa/Lagos"},
15197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Africa/Bujumbura", "Africa/Maputo"},
15207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Africa/Conakry", "Africa/Abidjan"},
15217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Africa/Dakar", "Africa/Abidjan"},
152228d9287dbcd4cb6cd7ff9c72ac69b1d1b3084701Yoshito Umaoka                {"Africa/Dar_es_Salaam", "Africa/Nairobi"},
152328d9287dbcd4cb6cd7ff9c72ac69b1d1b3084701Yoshito Umaoka                {"Africa/Djibouti", "Africa/Nairobi"},
15247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Africa/Douala", "Africa/Lagos"},
15257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Africa/Freetown", "Africa/Abidjan"},
15267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Africa/Gaborone", "Africa/Maputo"},
15277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Africa/Harare", "Africa/Maputo"},
152828d9287dbcd4cb6cd7ff9c72ac69b1d1b3084701Yoshito Umaoka                {"Africa/Kampala", "Africa/Nairobi"},
15297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Africa/Khartoum", "Africa/Juba"},
15307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Africa/Kigali", "Africa/Maputo"},
15317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Africa/Kinshasa", "Africa/Lagos"},
15327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Africa/Libreville", "Africa/Lagos"},
15337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Africa/Lome", "Africa/Abidjan"},
15347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Africa/Luanda", "Africa/Lagos"},
15357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Africa/Lubumbashi", "Africa/Maputo"},
15367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Africa/Lusaka", "Africa/Maputo"},
15377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Africa/Maseru", "Africa/Johannesburg"},
15387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Africa/Malabo", "Africa/Lagos"},
15397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Africa/Mbabane", "Africa/Johannesburg"},
154028d9287dbcd4cb6cd7ff9c72ac69b1d1b3084701Yoshito Umaoka                {"Africa/Mogadishu", "Africa/Nairobi"},
15417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Africa/Niamey", "Africa/Lagos"},
15427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Africa/Nouakchott", "Africa/Abidjan"},
15437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Africa/Ouagadougou", "Africa/Abidjan"},
15447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Africa/Porto-Novo", "Africa/Lagos"},
15457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Africa/Sao_Tome", "Africa/Abidjan"},
15466963bf5ae7372c8c504dcc268534520ef3abc08dNeil Fuller                {"America/Antigua", "America/Port_of_Spain"},
15476963bf5ae7372c8c504dcc268534520ef3abc08dNeil Fuller                {"America/Anguilla", "America/Port_of_Spain"},
15487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"America/Curacao", "America/Aruba"},
15496963bf5ae7372c8c504dcc268534520ef3abc08dNeil Fuller                {"America/Dominica", "America/Port_of_Spain"},
15506963bf5ae7372c8c504dcc268534520ef3abc08dNeil Fuller                {"America/Grenada", "America/Port_of_Spain"},
15516963bf5ae7372c8c504dcc268534520ef3abc08dNeil Fuller                {"America/Guadeloupe", "America/Port_of_Spain"},
15527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"America/Kralendijk", "America/Aruba"},
15537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"America/Lower_Princes", "America/Aruba"},
15546963bf5ae7372c8c504dcc268534520ef3abc08dNeil Fuller                {"America/Marigot", "America/Port_of_Spain"},
15556963bf5ae7372c8c504dcc268534520ef3abc08dNeil Fuller                {"America/Montserrat", "America/Port_of_Spain"},
15566963bf5ae7372c8c504dcc268534520ef3abc08dNeil Fuller                {"America/Panama", "America/Cayman"},
1557dfda36fc57967f7b7f0e5166ed5fd2d5fc47298cNeil Fuller                {"America/Santa_Isabel", "America/Tijuana"},
15586963bf5ae7372c8c504dcc268534520ef3abc08dNeil Fuller                {"America/Shiprock", "America/Denver"},
15596963bf5ae7372c8c504dcc268534520ef3abc08dNeil Fuller                {"America/St_Barthelemy", "America/Port_of_Spain"},
15606963bf5ae7372c8c504dcc268534520ef3abc08dNeil Fuller                {"America/St_Kitts", "America/Port_of_Spain"},
15616963bf5ae7372c8c504dcc268534520ef3abc08dNeil Fuller                {"America/St_Lucia", "America/Port_of_Spain"},
15626963bf5ae7372c8c504dcc268534520ef3abc08dNeil Fuller                {"America/St_Thomas", "America/Port_of_Spain"},
15636963bf5ae7372c8c504dcc268534520ef3abc08dNeil Fuller                {"America/St_Vincent", "America/Port_of_Spain"},
1564636d086f127a5e3da0ac774b77a1fcc2b9baf22eNeil Fuller                {"America/Toronto", "America/Montreal"},
15656963bf5ae7372c8c504dcc268534520ef3abc08dNeil Fuller                {"America/Tortola", "America/Port_of_Spain"},
15666963bf5ae7372c8c504dcc268534520ef3abc08dNeil Fuller                {"America/Virgin", "America/Port_of_Spain"},
15677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Antarctica/South_Pole", "Antarctica/McMurdo"},
156828d9287dbcd4cb6cd7ff9c72ac69b1d1b3084701Yoshito Umaoka                {"Arctic/Longyearbyen", "Europe/Oslo"},
1569471449c1abb71c045005f0eca3c8968f27e0d072Yoshito Umaoka                {"Asia/Kuwait", "Asia/Aden"},
1570471449c1abb71c045005f0eca3c8968f27e0d072Yoshito Umaoka                {"Asia/Muscat", "Asia/Dubai"},
15716d64a87e9d77f6538c95e127c160d9813444cb40Yoshito Umaoka                {"Asia/Phnom_Penh", "Asia/Bangkok"},
1572471449c1abb71c045005f0eca3c8968f27e0d072Yoshito Umaoka                {"Asia/Qatar", "Asia/Bahrain"},
1573471449c1abb71c045005f0eca3c8968f27e0d072Yoshito Umaoka                {"Asia/Riyadh", "Asia/Aden"},
15746d64a87e9d77f6538c95e127c160d9813444cb40Yoshito Umaoka                {"Asia/Vientiane", "Asia/Bangkok"},
15757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Atlantic/Jan_Mayen", "Europe/Oslo"},
15767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Atlantic/St_Helena", "Africa/Abidjan"},
15777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Europe/Bratislava", "Europe/Prague"},
15787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Europe/Busingen", "Europe/Zurich"},
15797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Europe/Guernsey", "Europe/London"},
15807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Europe/Isle_of_Man", "Europe/London"},
15817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Europe/Jersey", "Europe/London"},
15827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Europe/Ljubljana", "Europe/Belgrade"},
15837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Europe/Mariehamn", "Europe/Helsinki"},
15847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Europe/Podgorica", "Europe/Belgrade"},
15857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Europe/San_Marino", "Europe/Rome"},
15867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Europe/Sarajevo", "Europe/Belgrade"},
15877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Europe/Skopje", "Europe/Belgrade"},
15887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Europe/Vaduz", "Europe/Zurich"},
15897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Europe/Vatican", "Europe/Rome"},
15907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Europe/Zagreb", "Europe/Belgrade"},
159128d9287dbcd4cb6cd7ff9c72ac69b1d1b3084701Yoshito Umaoka                {"Indian/Antananarivo", "Africa/Nairobi"},
159228d9287dbcd4cb6cd7ff9c72ac69b1d1b3084701Yoshito Umaoka                {"Indian/Comoro", "Africa/Nairobi"},
159328d9287dbcd4cb6cd7ff9c72ac69b1d1b3084701Yoshito Umaoka                {"Indian/Mayotte", "Africa/Nairobi"},
15947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Pacific/Auckland", "Antarctica/McMurdo"},
15957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Pacific/Johnston", "Pacific/Honolulu"},
15966963bf5ae7372c8c504dcc268534520ef3abc08dNeil Fuller                {"Pacific/Midway", "Pacific/Pago_Pago"},
15976963bf5ae7372c8c504dcc268534520ef3abc08dNeil Fuller                {"Pacific/Saipan", "Pacific/Guam"},
15987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        };
15997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
16007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Following IDs are aliases of Etc/GMT in CLDR,
16017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // but Olson tzdata has 3 independent definitions
16027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // for Etc/GMT, Etc/UTC, Etc/UCT.
16037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Until we merge them into one equivalent group
16047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // in zoneinfo.res, we exclude them in the test
16057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // below.
16067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        final String[] excluded2 = {
16077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                "Etc/UCT", "UCT",
16087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                "Etc/UTC", "UTC",
16097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                "Etc/Universal", "Universal",
16107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                "Etc/Zulu", "Zulu",
16117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        };
16127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
16137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Walk through equivalency groups
16147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        String[] ids = TimeZone.getAvailableIDs();
16157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (int i = 0; i < ids.length; i++) {
16167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int nEquiv = TimeZone.countEquivalentIDs(ids[i]);
16177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (nEquiv == 0) {
16187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                continue;
16197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
16207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            String canonicalID = null;
16217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            boolean bFoundCanonical = false;
16227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // Make sure getCanonicalID returns the exact same result
16237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // for all entries within a same equivalency group with some
16247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // exceptions listed in exluded1.
16257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // Also, one of them must be canonical id.
16267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            for (int j = 0; j < nEquiv; j++) {
16277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                String tmp = TimeZone.getEquivalentID(ids[i], j);
16287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                String tmpCanonical = TimeZone.getCanonicalID(tmp);
16297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (tmpCanonical == null) {
16307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln("FAIL: getCanonicalID(\"" + tmp + "\") returned null");
16317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    continue;
16327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
16337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // Some exceptional cases
16347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                for (int k = 0; k < excluded1.length; k++) {
16357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (tmpCanonical.equals(excluded1[k][0])) {
16367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        tmpCanonical = excluded1[k][1];
16377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }
16387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
16397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
16407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (j == 0) {
16417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    canonicalID = tmpCanonical;
16427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } else if (!canonicalID.equals(tmpCanonical)) {
16437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln("FAIL: getCanonicalID(\"" + tmp + "\") returned " + tmpCanonical + " expected:" + canonicalID);
16447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
16457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
16467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (canonicalID.equals(tmp)) {
16477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    bFoundCanonical = true;
16487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
16497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
16507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // At least one ID in an equvalency group must match the
16517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // canonicalID
16527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (!bFoundCanonical) {
16537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // test exclusion because of differences between Olson tzdata and CLDR
16547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                boolean isExcluded = false;
16557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                for (int k = 0; k < excluded1.length; k++) {
16567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (ids[i].equals(excluded2[k])) {
16577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        isExcluded = true;
16587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        break;
16597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }
16607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
16617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (isExcluded) {
16627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    continue;
16637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
16647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
16657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("FAIL: No timezone ids match the canonical ID " + canonicalID);
16667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
16677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
16687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Testing some special cases
16697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        final String[][] data = {
16707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"GMT-03", "GMT-03:00", null},
16717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"GMT+4", "GMT+04:00", null},
16727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"GMT-055", "GMT-00:55", null},
16737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"GMT+430", "GMT+04:30", null},
16747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"GMT-12:15", "GMT-12:15", null},
16757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"GMT-091015", "GMT-09:10:15", null},
16767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"GMT+1:90", null, null},
16777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"America/Argentina/Buenos_Aires", "America/Buenos_Aires", "true"},
16787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Etc/Unknown", "Etc/Unknown", null},
16797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"bogus", null, null},
16807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"", null, null},
16817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"America/Marigot", "America/Marigot", "true"},     // Olson link, but CLDR canonical (#8953)
16827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {"Europe/Bratislava", "Europe/Bratislava", "true"}, // Same as above
16837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                {null, null, null},
16847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        };
16857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        boolean[] isSystemID = new boolean[1];
16867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (int i = 0; i < data.length; i++) {
16877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            String canonical = TimeZone.getCanonicalID(data[i][0], isSystemID);
16887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (canonical != null && !canonical.equals(data[i][1])
16897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    || canonical == null && data[i][1] != null) {
16907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("FAIL: getCanonicalID(\"" + data[i][0] + "\") returned " + canonical
16917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        + " - expected: " + data[i][1]);
16927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
16937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if ("true".equalsIgnoreCase(data[i][2]) != isSystemID[0]) {
16947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("FAIL: getCanonicalID(\"" + data[i][0] + "\") set " + isSystemID[0]
16957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        + " to isSystemID");
16967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
16977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
16987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
16997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
17002d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
17017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestSetDefault() {
17027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        java.util.TimeZone save = java.util.TimeZone.getDefault();
17037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
17047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        /*
17057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         * America/Caracs (Venezuela) changed the base offset from -4:00 to
17067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         * -4:30 on Dec 9, 2007.
17077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         */
17087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
17097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        TimeZone icuCaracas = TimeZone.getTimeZone("America/Caracas", TimeZone.TIMEZONE_ICU);
17107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        java.util.TimeZone jdkCaracas = java.util.TimeZone.getTimeZone("America/Caracas");
17117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
17127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Set JDK America/Caracas as the default
17137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        java.util.TimeZone.setDefault(jdkCaracas);
17147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
17157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        java.util.Calendar jdkCal = java.util.Calendar.getInstance();
17167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        jdkCal.clear();
17177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        jdkCal.set(2007, java.util.Calendar.JANUARY, 1);
17187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
17197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int rawOffset = jdkCal.get(java.util.Calendar.ZONE_OFFSET);
17207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int dstSavings = jdkCal.get(java.util.Calendar.DST_OFFSET);
17217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
17227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int[] offsets = new int[2];
17237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        icuCaracas.getOffset(jdkCal.getTime().getTime()/*jdkCal.getTimeInMillis()*/, false, offsets);
17247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
17257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        boolean isTimeZoneSynchronized = true;
17267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
17277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (rawOffset != offsets[0] || dstSavings != offsets[1]) {
17287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // JDK time zone rule is out of sync...
17297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            logln("Rule for JDK America/Caracas is not same with ICU.  Skipping the rest.");
17307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            isTimeZoneSynchronized = false;
17317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
17327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
17337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (isTimeZoneSynchronized) {
17347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // If JDK America/Caracas uses the same rule with ICU,
17357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // the following code should work well.
17367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            TimeZone.setDefault(icuCaracas);
17377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
17387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // Create a new JDK calendar instance again.
17397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // This calendar should reflect the new default
17407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // set by ICU TimeZone#setDefault.
17417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            jdkCal = java.util.Calendar.getInstance();
17427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            jdkCal.clear();
17437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            jdkCal.set(2007, java.util.Calendar.JANUARY, 1);
17447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
17457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            rawOffset = jdkCal.get(java.util.Calendar.ZONE_OFFSET);
17467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            dstSavings = jdkCal.get(java.util.Calendar.DST_OFFSET);
17477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
17487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (rawOffset != offsets[0] || dstSavings != offsets[1]) {
17497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("ERROR: Got offset [raw:" + rawOffset + "/dst:" + dstSavings
17507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                          + "] Expected [raw:" + offsets[0] + "/dst:" + offsets[1] + "]");
17517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
17527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
17537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
17547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Restore the original JDK time zone
17557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        java.util.TimeZone.setDefault(save);
17567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
17577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
17587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /*
17597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Test Display Names, choosing zones and lcoales where there are multiple
17607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * meta-zones defined.
17617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
17622d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
17637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestDisplayNamesMeta() {
17647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        final Integer TZSHORT = new Integer(TimeZone.SHORT);
17657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        final Integer TZLONG = new Integer(TimeZone.LONG);
17667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
17677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        final Object[][] zoneDisplayTestData = {
17687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            //  zone id             locale  summer          format      expected display name
17697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"Europe/London",       "en",   Boolean.FALSE,  TZSHORT,    "GMT"},
17707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"Europe/London",       "en",   Boolean.FALSE,  TZLONG,     "Greenwich Mean Time"},
17717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"Europe/London",       "en",   Boolean.TRUE,   TZSHORT,    "GMT+1" /*"BST"*/},
17727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"Europe/London",       "en",   Boolean.TRUE,   TZLONG,     "British Summer Time"},
17737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
17747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"America/Anchorage",   "en",   Boolean.FALSE,  TZSHORT,    "AKST"},
17757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"America/Anchorage",   "en",   Boolean.FALSE,  TZLONG,     "Alaska Standard Time"},
17767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"America/Anchorage",   "en",   Boolean.TRUE,   TZSHORT,    "AKDT"},
17777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"America/Anchorage",   "en",   Boolean.TRUE,   TZLONG,     "Alaska Daylight Time"},
17787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
17797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // Southern Hemisphere, all data from meta:Australia_Western
17807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"Australia/Perth",     "en",   Boolean.FALSE,  TZSHORT,    "GMT+8"/*"AWST"*/},
17817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"Australia/Perth",     "en",   Boolean.FALSE,  TZLONG,     "Australian Western Standard Time"},
17827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // Note: Perth does not observe DST currently. When display name is missing,
17837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // the localized GMT format with the current offset is used even daylight name was
17847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // requested. See #9350.
17857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"Australia/Perth",     "en",   Boolean.TRUE,   TZSHORT,    "GMT+8"/*"AWDT"*/},
17867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"Australia/Perth",     "en",   Boolean.TRUE,   TZLONG,     "Australian Western Daylight Time"},
17877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
17887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"America/Sao_Paulo",   "en",   Boolean.FALSE,  TZSHORT,    "GMT-3"/*"BRT"*/},
17897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"America/Sao_Paulo",   "en",   Boolean.FALSE,  TZLONG,     "Brasilia Standard Time"},
17907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"America/Sao_Paulo",   "en",   Boolean.TRUE,   TZSHORT,    "GMT-2"/*"BRST"*/},
17917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"America/Sao_Paulo",   "en",   Boolean.TRUE,   TZLONG,     "Brasilia Summer Time"},
17927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
17937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // No Summer Time, but had it before 1983.
17947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"Pacific/Honolulu",    "en",   Boolean.FALSE,  TZSHORT,    "HST"},
17957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"Pacific/Honolulu",    "en",   Boolean.FALSE,  TZLONG,     "Hawaii-Aleutian Standard Time"},
17967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"Pacific/Honolulu",    "en",   Boolean.TRUE,   TZSHORT,    "HDT"},
17977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"Pacific/Honolulu",    "en",   Boolean.TRUE,   TZLONG,     "Hawaii-Aleutian Daylight Time"},
17987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
17997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // Northern, has Summer, not commonly used.
18007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"Europe/Helsinki",     "en",   Boolean.FALSE,  TZSHORT,    "GMT+2"/*"EET"*/},
18017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"Europe/Helsinki",     "en",   Boolean.FALSE,  TZLONG,     "Eastern European Standard Time"},
18027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"Europe/Helsinki",     "en",   Boolean.TRUE,   TZSHORT,    "GMT+3"/*"EEST"*/},
18037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"Europe/Helsinki",     "en",   Boolean.TRUE,   TZLONG,     "Eastern European Summer Time"},
18047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
18057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // Repeating the test data for DST.  The test data below trigger the problem reported
18067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // by Ticket#6644
18077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"Europe/London",       "en",   Boolean.TRUE,   TZSHORT,    "GMT+1" /*"BST"*/},
18087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"Europe/London",       "en",   Boolean.TRUE,   TZLONG,     "British Summer Time"},
18097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        };
18107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
18117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        boolean isICUTimeZone = (TimeZone.getDefaultTimeZoneType() == TimeZone.TIMEZONE_ICU);
18127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
18137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        boolean sawAnError = false;
18147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (int testNum = 0; testNum < zoneDisplayTestData.length; testNum++) {
18157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            ULocale locale = new ULocale((String)zoneDisplayTestData[testNum][1]);
18167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            TimeZone zone = TimeZone.getTimeZone((String)zoneDisplayTestData[testNum][0]);
18177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            String displayName = zone.getDisplayName(((Boolean)zoneDisplayTestData[testNum][2]).booleanValue(),
18187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    ((Integer)zoneDisplayTestData[testNum][3]).intValue());
18197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (!displayName.equals(zoneDisplayTestData[testNum][4])) {
18207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (isDevelopmentBuild
18217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        && (isICUTimeZone || !((Boolean)zoneDisplayTestData[testNum][2]).booleanValue())) {
18227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    sawAnError = true;
18237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln("Incorrect time zone display name.  zone = "
18247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            + zoneDisplayTestData[testNum][0] + ",\n"
18257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            + "   locale = " + locale
18267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            + ",   style = " + (zoneDisplayTestData[testNum][3] == TZSHORT ? "SHORT" : "LONG")
18277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            + ",   Summertime = " + zoneDisplayTestData[testNum][2] + "\n"
18287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            + "   Expected " + zoneDisplayTestData[testNum][4]
18297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            + ",   Got " + displayName);
18307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } else {
18317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    logln("Incorrect time zone display name.  zone = "
18327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            + zoneDisplayTestData[testNum][0] + ",\n"
18337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            + "   locale = " + locale
18347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            + ",   style = " + (zoneDisplayTestData[testNum][3] == TZSHORT ? "SHORT" : "LONG")
18357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            + ",   Summertime = " + zoneDisplayTestData[testNum][2] + "\n"
18367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            + "   Expected " + zoneDisplayTestData[testNum][4]
18377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                            + ",   Got " + displayName);
18387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
18397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
18407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
18417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (sawAnError) {
18427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            logln("Note: Errors could be the result of changes to zoneStrings locale data");
18437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
18447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
18457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
18467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /*
18477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Test case for hashCode problem reported by ticket#7690 OlsonTimeZone.hashCode() throws NPE.
18487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
18492d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
18507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestHashCode() {
18517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        String[] ids = TimeZone.getAvailableIDs();
18527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
18537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (String id: ids) {
18547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            TimeZone tz1 = TimeZone.getTimeZone(id);
18557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            TimeZone tz2 = TimeZone.getTimeZone(id);
18567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
18577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // hash code are same for the same time zone
18587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (tz1.hashCode() != tz2.hashCode()) {
18597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("Fail: Two time zone instances for " + id + " have different hash values.");
18607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
18617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // string representation should be also same
18627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (!tz1.toString().equals(tz2.toString())) {
18637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("Fail: Two time zone instances for " + id + " have different toString() values.");
18647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
18657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
18667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
18677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
18687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /*
18697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Test case for getRegion
18707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
18712d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
18727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestGetRegion() {
18737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        final String[][] TEST_DATA = {
18747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"America/Los_Angeles",             "US"},
18757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"America/Indianapolis",            "US"},  // CLDR canonical, Olson backward
18767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"America/Indiana/Indianapolis",    "US"},  // CLDR alias
18777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"Mexico/General",                  "MX"},  // Link America/Mexico_City, Olson backward
18787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"Etc/UTC",                         "001"},
18797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"EST5EDT",                         "001"},
18807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"PST",                             "US"},  // Link America/Los_Angeles
18817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"Europe/Helsinki",                 "FI"},
18827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"Europe/Mariehamn",                "AX"},  // Link Europe/Helsinki, but in zone.tab
18837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"Asia/Riyadh",                     "SA"},
18847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // tz file solar87 was removed from tzdata2013i
18857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // {"Asia/Riyadh87",                   "001"}, // this should be "SA" actually, but not in zone.tab
18867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"Etc/Unknown",                     null},  // CLDR canonical, but not a sysmte zone ID
18877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"bogus",                           null},  // bogus
18887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"GMT+08:00",                       null},  // a custom ID, not a system zone ID
18897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        };
18907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
18917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (String[] test : TEST_DATA) {
18927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            try {
18937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                String region = TimeZone.getRegion(test[0]);
18947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (!region.equals(test[1])) {
18957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (test[1] == null) {
18967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        errln("Fail: getRegion(\"" + test[0] + "\") returns "
18977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                + region + " [expected: IllegalArgumentException]");
18987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    } else {
18997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        errln("Fail: getRegion(\"" + test[0] + "\") returns "
19007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                + region + " [expected: " + test[1] + "]");
19017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }
19027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
19037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } catch (IllegalArgumentException e) {
19047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (test[1] != null) {
19057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln("Fail: getRegion(\"" + test[0]
19067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                + "\") throws IllegalArgumentException [expected: " + test[1] + "]");
19077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
19087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
19097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
19107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
19117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
19122d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
19137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestZoneFields() {
19147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        assertEquals("UNKNOWN_ZONE wrong ID", "Etc/Unknown", TimeZone.UNKNOWN_ZONE.getID());
19157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        assertEquals("UNKNOWN_ZONE wrong offset", 0, TimeZone.UNKNOWN_ZONE.getRawOffset());
19167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        assertFalse("UNKNOWN_ZONE uses DST", TimeZone.UNKNOWN_ZONE.useDaylightTime());
19177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
19187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        assertEquals("GMT_ZONE wrong ID", "Etc/GMT", TimeZone.GMT_ZONE.getID());
19197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        assertEquals("GMT_ZONE wrong offset", 0, TimeZone.GMT_ZONE.getRawOffset());
19207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        assertFalse("GMT_ZONE uses DST", TimeZone.GMT_ZONE.useDaylightTime());
19217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
19227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
19237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /*
19247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Test case for Freezable
19257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
19262d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
19277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestFreezable() {
19287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Test zones - initially thawed
19297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        TimeZone[] ZA1 = {
19307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            TimeZone.getDefault(),
19317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            TimeZone.getTimeZone("America/Los_Angeles", TimeZone.TIMEZONE_ICU),
19327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            TimeZone.getTimeZone("America/Los_Angeles", TimeZone.TIMEZONE_JDK),
19337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new SimpleTimeZone(0, "stz"),
19347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new RuleBasedTimeZone("rbtz", new InitialTimeZoneRule("rbtz0", 0, 0)),
19357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            VTimeZone.create("America/New_York"),
19367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        };
19377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
19387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        checkThawed(ZA1, "ZA1");
19397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // freeze
19407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (int i = 0; i < ZA1.length; i++) {
19417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            ZA1[i].freeze();
19427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
19437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        checkFrozen(ZA1, "ZA1(frozen)");
19447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
19457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Test zones - initially frozen
19467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        final TimeZone[] ZA2 = {
19477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            TimeZone.GMT_ZONE,
19487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            TimeZone.UNKNOWN_ZONE,
19497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            TimeZone.getFrozenTimeZone("America/Los_Angeles"),
19507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new SimpleTimeZone(3600000, "frz_stz").freeze(),
19517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new RuleBasedTimeZone("frz_rbtz", new InitialTimeZoneRule("frz_rbtz0", 3600000, 0)).freeze(),
19527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            VTimeZone.create("Asia/Tokyo").freeze(),
19537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        };
19547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
19557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        checkFrozen(ZA2, "ZA2");
19567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        TimeZone[] ZA2_thawed = new TimeZone[ZA2.length];
19577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // create thawed clone
19587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (int i = 0; i < ZA2_thawed.length; i++) {
19597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            ZA2_thawed[i] = ZA2[i].cloneAsThawed();
19607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
19617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        checkThawed(ZA2_thawed, "ZA2(thawed)");
19627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
19637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
19647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
19657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private void checkThawed(TimeZone[] thawedZones, String zaName) {
19667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (int i = 0; i < thawedZones.length; i++) {
19677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (thawedZones[i].isFrozen()) {
19687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("Fail: " + zaName + "[" + i + "] is frozen.");
19697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
19707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
19717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // clone
19727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            TimeZone copy = (TimeZone)thawedZones[i].clone();
19737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (thawedZones[i] == copy || !thawedZones[i].equals(copy)) {
19747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("Fail: " + zaName + "[" + i + "] - clone does not work.");
19757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
19767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
19777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // cloneAsThawed
19787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            TimeZone thawed = (TimeZone)thawedZones[i].cloneAsThawed();
19797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (thawed.isFrozen() || !thawedZones[i].equals(thawed)) {
19807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("Fail: " + zaName + "[" + i + "] - cloneAsThawed does not work.");
19817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
19827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
19837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // setID
19847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            try {
19857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                String newID = "foo";
19867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                thawedZones[i].setID(newID);
19877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (!thawedZones[i].getID().equals(newID)) {
19887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln("Fail: " + zaName + "[" + i + "] - setID(\"" + newID + "\") does not work.");
19897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
19907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } catch (UnsupportedOperationException e) {
19917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("Fail: " + zaName + "[" + i + "] - setID throws UnsupportedOperationException.");
19927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
19937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
19947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // setRawOffset
19957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (!(thawedZones[i] instanceof RuleBasedTimeZone)) {    // RuleBasedTimeZone does not supprot setRawOffset
19967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                try {
19977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    int newOffset = -3600000;
19987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    thawedZones[i].setRawOffset(newOffset);
19997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (thawedZones[i].getRawOffset() != newOffset) {
20007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        errln("Fail: " + zaName + "[" + i + "] - setRawOffset(" + newOffset + ") does not work.");
20017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }
20027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } catch (UnsupportedOperationException e) {
20037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln("Fail: " + zaName + "[" + i + "] - setRawOffset throws UnsupportedOperationException.");
20047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
20057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
20067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
20077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (thawedZones[i] instanceof SimpleTimeZone) {
20087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                SimpleTimeZone stz = (SimpleTimeZone)thawedZones[i];
20097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // setDSTSavings
20107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                try {
20117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    int newDSTSavings = 1800000;
20127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    stz.setDSTSavings(newDSTSavings);
20137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (stz.getDSTSavings() != newDSTSavings) {
20147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        errln("Fail: (SimpleTimeZone)" + zaName + "[" + i + "] - setDSTSavings(" + newDSTSavings + ") does not work.");
20157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }
20167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } catch (UnsupportedOperationException e) {
20177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln("Fail: (SimpleTimeZone)" + zaName + "[" + i + "] - setDSTSavings throws UnsupportedOperationException.");
20187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
20197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // setStartRule
20207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                try {
20217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    stz.setStartRule(Calendar.JANUARY, -1, Calendar.SUNDAY, 0);
20227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } catch (UnsupportedOperationException e) {
20237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln("Fail: (SimpleTimeZone)" + zaName + "[" + i + "] - setStartRule throws UnsupportedOperationException.");
20247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
20257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // setEndRule
20267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                try {
20277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    stz.setEndRule(Calendar.DECEMBER, 1, Calendar.SUNDAY, 0);
20287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } catch (UnsupportedOperationException e) {
20297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln("Fail: (SimpleTimeZone)" + zaName + "[" + i + "] - setEndRule throws UnsupportedOperationException.");
20307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
20317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // setStartYear
20327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                try {
20337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    stz.setStartYear(2000);
20347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } catch (UnsupportedOperationException e) {
20357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln("Fail: (SimpleTimeZone)" + zaName + "[" + i + "] - setStartYear throws UnsupportedOperationException.");
20367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
20377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } else if (thawedZones[i] instanceof RuleBasedTimeZone) {
20387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                RuleBasedTimeZone rbtz = (RuleBasedTimeZone)thawedZones[i];
20397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // addTransitionRule
20407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                try {
20417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    TimeArrayTimeZoneRule tr1 = new TimeArrayTimeZoneRule("tr1", 7200000, 0, new long[] {0}, DateTimeRule.UTC_TIME);
20427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    rbtz.addTransitionRule(tr1);
20437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } catch (UnsupportedOperationException e) {
20447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln("Fail: (RuleBasedTimeZone)" + zaName + "[" + i + "] - addTransitionRule throws UnsupportedOperationException.");
20457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
20467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } else if (thawedZones[i] instanceof VTimeZone) {
20477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                VTimeZone vtz = (VTimeZone)thawedZones[i];
20487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // setTZURL
20497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                try {
20507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    String tzUrl = "http://icu-project.org/timezone";
20517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    vtz.setTZURL(tzUrl);
20527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (!vtz.getTZURL().equals(tzUrl)) {
20537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        errln("Fail: (VTimeZone)" + zaName + "[" + i + "] - setTZURL does not work.");
20547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }
20557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } catch (UnsupportedOperationException e) {
20567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln("Fail: (VTimeZone)" + zaName + "[" + i + "] - setTZURL throws UnsupportedOperationException.");
20577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
20587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // setLastModified
20597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                try {
20607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    Date d = new Date();
20617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    vtz.setLastModified(d);
20627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    if (!vtz.getLastModified().equals(d)) {
20637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                        errln("Fail: (VTimeZone)" + zaName + "[" + i + "] - setLastModified does not work.");
20647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    }
20657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } catch (UnsupportedOperationException e) {
20667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln("Fail: (VTimeZone)" + zaName + "[" + i + "] - setLastModified throws UnsupportedOperationException.");
20677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
20687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
20697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
20707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
20717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
20727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private void checkFrozen(TimeZone[] frozenZones, String zaName) {
20737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (int i = 0; i < frozenZones.length; i++) {
20747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (!frozenZones[i].isFrozen()) {
20757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("Fail: " + zaName + "[" + i + "] is not frozen.");
20767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
20777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
20787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // clone
20797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            TimeZone copy = (TimeZone)frozenZones[i].clone();
20807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (frozenZones[i] != copy) {
20817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("Fail: " + zaName + "[" + i + "] - clone does not return the object itself.");
20827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
20837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
20847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // cloneAsThawed
20857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            TimeZone thawed = (TimeZone)frozenZones[i].cloneAsThawed();
20867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (thawed.isFrozen() || !frozenZones[i].equals(thawed)) {
20877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("Fail: " + zaName + "[" + i + "] - cloneAsThawed does not work.");
20887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
20897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
20907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // setID
20917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            try {
20927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                String newID = "foo";
20937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                frozenZones[i].setID(newID);
20947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("Fail: " + zaName + "[" + i + "] - setID must throw UnsupportedOperationException.");
20957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } catch (UnsupportedOperationException e) {
20967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // OK
20977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
20987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
20997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // setRawOffset
21007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (!(frozenZones[i] instanceof RuleBasedTimeZone)) {    // RuleBasedTimeZone does not supprot setRawOffset
21017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                try {
21027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    int newOffset = -3600000;
21037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    frozenZones[i].setRawOffset(newOffset);
21047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln("Fail: " + zaName + "[" + i + "] - setRawOffset must throw UnsupportedOperationException.");
21057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } catch (UnsupportedOperationException e) {
21067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    // OK
21077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
21087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
21097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
21107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (frozenZones[i] instanceof SimpleTimeZone) {
21117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                SimpleTimeZone stz = (SimpleTimeZone)frozenZones[i];
21127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // setDSTSavings
21137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                try {
21147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    int newDSTSavings = 1800000;
21157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    stz.setDSTSavings(newDSTSavings);
21167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln("Fail: (SimpleTimeZone)" + zaName + "[" + i + "] - setDSTSavings must throw UnsupportedOperationException.");
21177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } catch (UnsupportedOperationException e) {
21187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    // OK
21197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
21207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // setStartRule
21217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                try {
21227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    stz.setStartRule(Calendar.JANUARY, -1, Calendar.SUNDAY, 0);
21237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln("Fail: (SimpleTimeZone)" + zaName + "[" + i + "] - setStartRule must throw UnsupportedOperationException.");
21247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } catch (UnsupportedOperationException e) {
21257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    // OK
21267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
21277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // setEndRule
21287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                try {
21297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    stz.setEndRule(Calendar.DECEMBER, 1, Calendar.SUNDAY, 0);
21307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln("Fail: (SimpleTimeZone)" + zaName + "[" + i + "] - setEndRule must throw UnsupportedOperationException.");
21317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } catch (UnsupportedOperationException e) {
21327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    // OK
21337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
21347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // setStartYear
21357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                try {
21367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    stz.setStartYear(2000);
21377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln("Fail: (SimpleTimeZone)" + zaName + "[" + i + "] - setStartYear must throw UnsupportedOperationException.");
21387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } catch (UnsupportedOperationException e) {
21397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    // OK
21407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
21417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } else if (frozenZones[i] instanceof RuleBasedTimeZone) {
21427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                RuleBasedTimeZone rbtz = (RuleBasedTimeZone)frozenZones[i];
21437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // addTransitionRule
21447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                try {
21457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    TimeArrayTimeZoneRule tr1 = new TimeArrayTimeZoneRule("tr1", 7200000, 0, new long[] {0}, DateTimeRule.UTC_TIME);
21467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    rbtz.addTransitionRule(tr1);
21477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln("Fail: (RuleBasedTimeZone)" + zaName + "[" + i + "] - addTransitionRule must throw UnsupportedOperationException.");
21487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } catch (UnsupportedOperationException e) {
21497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    // OK
21507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
21517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } else if (frozenZones[i] instanceof VTimeZone) {
21527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                VTimeZone vtz = (VTimeZone)frozenZones[i];
21537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // setTZURL
21547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                try {
21557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    String tzUrl = "http://icu-project.org/timezone";
21567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    vtz.setTZURL(tzUrl);
21577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln("Fail: (VTimeZone)" + zaName + "[" + i + "] - setTZURL must throw UnsupportedOperationException.");
21587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } catch (UnsupportedOperationException e) {
21597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    // OK
21607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
21617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                // setLastModified
21627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                try {
21637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    Date d = new Date();
21647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    vtz.setLastModified(d);
21657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln("Fail: (VTimeZone)" + zaName + "[" + i + "] - setLastModified must throw UnsupportedOperationException.");
21667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } catch (UnsupportedOperationException e) {
21677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    // OK
21687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
21697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
21707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
21717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
21727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
21732d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
21747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestObservesDaylightTime() {
21757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        boolean observesDaylight;
21767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        long current = System.currentTimeMillis();
21777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
21787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        String[] tzids = TimeZone.getAvailableIDs();
21797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (String tzid : tzids) {
21807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // OlsonTimeZone
21817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            TimeZone tz = TimeZone.getTimeZone(tzid, TimeZone.TIMEZONE_ICU);
21827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            observesDaylight = tz.observesDaylightTime();
21837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (observesDaylight != isDaylightTimeAvailable(tz, current)) {
21847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("Fail: [OlsonTimeZone] observesDaylightTime() returned " + observesDaylight + " for " + tzid);
21857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
21867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
21877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // RuleBasedTimeZone
21887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            RuleBasedTimeZone rbtz = createRBTZ((BasicTimeZone)tz, current);
21897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            boolean observesDaylightRBTZ = rbtz.observesDaylightTime();
21907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (observesDaylightRBTZ != isDaylightTimeAvailable(rbtz, current)) {
21917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("Fail: [RuleBasedTimeZone] observesDaylightTime() returned " + observesDaylightRBTZ + " for " + rbtz.getID());
21927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } else if (observesDaylight != observesDaylightRBTZ) {
21937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("Fail: RuleBasedTimeZone " + rbtz.getID() + " returns " + observesDaylightRBTZ + ", but different from match OlsonTimeZone");
21947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
21957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
21967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // JavaTimeZone
21977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            tz = TimeZone.getTimeZone(tzid, TimeZone.TIMEZONE_JDK);
21987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            observesDaylight = tz.observesDaylightTime();
21997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (observesDaylight != isDaylightTimeAvailable(tz, current)) {
22007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("Fail: [JavaTimeZone] observesDaylightTime() returned " + observesDaylight + " for " + tzid);
22017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
22027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
22037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // VTimeZone
22047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            tz = VTimeZone.getTimeZone(tzid);
22057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            observesDaylight = tz.observesDaylightTime();
22067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (observesDaylight != isDaylightTimeAvailable(tz, current)) {
22077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("Fail: [VTimeZone] observesDaylightTime() returned " + observesDaylight + " for " + tzid);
22087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
22097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
22107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
22117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // SimpleTimeZone
22127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        SimpleTimeZone[] stzs = {
22137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new SimpleTimeZone(0, "STZ0"),
22147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new SimpleTimeZone(-5*60*60*1000, "STZ-5D", Calendar.MARCH, 2, Calendar.SUNDAY, 2*60*60*1000,
22157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2*60*60*1000),
22167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        };
22177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (SimpleTimeZone stz : stzs) {
22187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            observesDaylight = stz.observesDaylightTime();
22197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (observesDaylight != isDaylightTimeAvailable(stz, current)) {
22207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("Fail: [SimpleTimeZone] observesDaylightTime() returned " + observesDaylight + " for " + stz.getID());
22217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
22227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
22237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
222487255a3fc79cc94374b5b8adc76a86e251ac7d3eFredrik Roubert
22252d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
222687255a3fc79cc94374b5b8adc76a86e251ac7d3eFredrik Roubert    public void Test11619_UnrecognizedTimeZoneID() {
222787255a3fc79cc94374b5b8adc76a86e251ac7d3eFredrik Roubert        VTimeZone vzone = VTimeZone.create("ABadTimeZoneId");
22282d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert        TestFmwk.assertNull("", vzone);
222987255a3fc79cc94374b5b8adc76a86e251ac7d3eFredrik Roubert    }
22307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
22317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static boolean isDaylightTimeAvailable(TimeZone tz, long start) {
22327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (tz.inDaylightTime(new Date(start))) {
22337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            return true;
22347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
22357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
22367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        long date;
22377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (tz instanceof BasicTimeZone) {
22387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            BasicTimeZone btz = (BasicTimeZone)tz;
22397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // check future transitions, up to 100
22407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            date = start;
22417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            for (int i = 0; i < 100; i++) {
22427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                TimeZoneTransition tzt = btz.getNextTransition(date, false);
22437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (tzt == null) {
22447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    // no more transitions
22457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    break;
22467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
22477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (tzt.getTo().getDSTSavings() != 0) {
22487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    return true;
22497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
22507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                date = tzt.getTime();
22517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
22527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        } else {
22537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // check future times by incrementing 30 days, up to 200 times (about 16 years)
22547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            final long inc = 30L * 24 * 60 * 60 * 1000;
22557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int[] offsets = new int[2];
22567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            date = start + inc;
22577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            for (int i = 0; i < 200; i++, date += inc) {
22587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                tz.getOffset(date, false, offsets);
22597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (offsets[1] != 0) {
22607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    return true;
22617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
22627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
22637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
22647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return false;
22657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
22667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
22677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    private static RuleBasedTimeZone createRBTZ(BasicTimeZone btz, long start) {
22687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        TimeZoneRule[] rules = btz.getTimeZoneRules(start);
22697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        RuleBasedTimeZone rbtz = new RuleBasedTimeZone("RBTZ:btz.getID()", (InitialTimeZoneRule)rules[0]);
22707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (int i = 1; i < rules.length; i++) {
22717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            rbtz.addTransitionRule(rules[i]);
22727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
22737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return rbtz;
22747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     }
22757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
22762d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
22777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestGetWindowsID() {
22787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        String[][] TESTDATA = {
22797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"America/New_York",        "Eastern Standard Time"},
22807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"America/Montreal",        "Eastern Standard Time"},
22817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"America/Los_Angeles",     "Pacific Standard Time"},
22827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"America/Vancouver",       "Pacific Standard Time"},
22837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"Asia/Shanghai",           "China Standard Time"},
22847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"Asia/Chongqing",          "China Standard Time"},
22857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"America/Indianapolis",    "US Eastern Standard Time"},            // CLDR canonical name
22867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"America/Indiana/Indianapolis",    "US Eastern Standard Time"},    // tzdb canonical name
22877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"Asia/Khandyga",           "Yakutsk Standard Time"},
22882d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert            {"Australia/Eucla",         "Aus Central W. Standard Time"}, // Now Windows does have a mapping
22897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"Bogus",                   null},
22907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        };
22917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
22927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (String[] data : TESTDATA) {
22937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            String winID = TimeZone.getWindowsID(data[0]);
22947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            assertEquals("Fail: ID=" + data[0], data[1], winID);
22957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
22967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
22977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
22982d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
22997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestGetIDForWindowsID() {
23007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        final String[][] TESTDATA = {
23017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"Eastern Standard Time",   null,   "America/New_York"},
23027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"Eastern Standard Time",   "US",   "America/New_York"},
23037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"Eastern Standard Time",   "CA",   "America/Toronto"},
23047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"Eastern Standard Time",   "CN",   "America/New_York"},
23057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"China Standard Time",     null,   "Asia/Shanghai"},
23067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"China Standard Time",     "CN",   "Asia/Shanghai"},
23077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"China Standard Time",     "HK",   "Asia/Hong_Kong"},
23087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"Mid-Atlantic Standard Time",  null,   null}, // No tz database mapping
23097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {"Bogus",                   null,   null},
23107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        };
23117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
23127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (String[] data : TESTDATA) {
23137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            String id = TimeZone.getIDForWindowsID(data[0], data[1]);
23147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            assertEquals("Fail: Windows ID=" + data[0] + ", Region=" + data[1],
23157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    data[2], id);
23167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
23177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
23187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert}
23197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
23207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//eof
2321