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