12d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert// © 2016 and later: Unicode, Inc. and others. 22d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert// License & terms of use: http://www.unicode.org/copyright.html#License 37935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 47935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ******************************************************************************** 5e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer * Copyright (C) 2007-2016, Google, International Business Machines Corporation 6e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer * and others. All Rights Reserved. 77935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ******************************************************************************** 87935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 97935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpackage com.ibm.icu.dev.test.format; 117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 12e7a7efded856b8959849879938d1cb2e8ccab318Markus Schererimport java.text.FieldPosition; 137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.text.ParseException; 147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.text.ParsePosition; 15f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubertimport java.util.ArrayList; 167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Arrays; 172d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubertimport java.util.Collections; 187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Date; 197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.EnumSet; 207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.List; 217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Locale; 222d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubertimport java.util.Random; 237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Set; 247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.TreeSet; 25f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubertimport java.util.concurrent.atomic.AtomicInteger; 267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.regex.Pattern; 277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 282d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubertimport org.junit.Test; 292d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 302d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubertimport com.ibm.icu.dev.test.TestFmwk; 31f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubertimport com.ibm.icu.impl.TZDBTimeZoneNames; 327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.impl.ZoneMeta; 337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.lang.UCharacter; 34e7a7efded856b8959849879938d1cb2e8ccab318Markus Schererimport com.ibm.icu.text.DateFormat; 357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.text.SimpleDateFormat; 367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.text.TimeZoneFormat; 37e7a7efded856b8959849879938d1cb2e8ccab318Markus Schererimport com.ibm.icu.text.TimeZoneFormat.GMTOffsetPatternType; 387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.text.TimeZoneFormat.ParseOption; 397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.text.TimeZoneFormat.Style; 407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.text.TimeZoneFormat.TimeType; 417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.text.TimeZoneNames; 422d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubertimport com.ibm.icu.text.TimeZoneNames.Factory; 43f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubertimport com.ibm.icu.text.TimeZoneNames.NameType; 447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.BasicTimeZone; 457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.Calendar; 467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.Output; 477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.SimpleTimeZone; 487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.TimeZone; 497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.TimeZone.SystemTimeZoneType; 507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.TimeZoneTransition; 517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.ULocale; 527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpublic class TimeZoneFormatTest extends com.ibm.icu.dev.test.TestFmwk { 547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static boolean JDKTZ = (TimeZone.getDefaultTimeZoneType() == TimeZone.TIMEZONE_JDK); 567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static final Pattern EXCL_TZ_PATTERN = Pattern.compile(".*/Riyadh8[7-9]"); 577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static final String[] PATTERNS = { 597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "z", 607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "zzzz", 617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "Z", // equivalent to "xxxx" 627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "ZZZZ", // equivalent to "OOOO" 637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "v", 647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "vvvv", 657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "O", 667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "OOOO", 677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "X", 687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "XX", 697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "XXX", 707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "XXXX", 717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "XXXXX", 727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "x", 737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "xx", 747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "xxx", 757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "xxxx", 767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "xxxxx", 777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "V", 787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "VV", 797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "VVV", 807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "VVVV" 817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }; 827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean REALLY_VERBOSE_LOG = false; 837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /* 857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Test case for checking if a TimeZone is properly set in the result calendar 867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * and if the result TimeZone has the expected behavior. 877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 882d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert @Test 897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void TestTimeZoneRoundTrip() { 907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean TEST_ALL = getBooleanProperty("TimeZoneRoundTripAll", false); 917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeZone unknownZone = new SimpleTimeZone(-31415, "Etc/Unknown"); 937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int badDstOffset = -1234; 947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int badZoneOffset = -2345; 957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int[][] testDateData = { 977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {2007, 1, 15}, 987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {2007, 6, 15}, 997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {1990, 1, 15}, 1007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {1990, 6, 15}, 1017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {1960, 1, 15}, 1027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {1960, 6, 15}, 1037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }; 1047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); 1067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert cal.clear(); 1077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Set up rule equivalency test range 1097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long low, high; 1107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert cal.set(1900, 0, 1); 1117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert low = cal.getTimeInMillis(); 1127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert cal.set(2040, 0, 1); 1137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert high = cal.getTimeInMillis(); 1147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Set up test dates 1167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Date[] DATES = new Date[testDateData.length]; 1177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert cal.clear(); 1187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = 0; i < DATES.length; i++) { 1197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert cal.set(testDateData[i][0], testDateData[i][1], testDateData[i][2]); 1207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert DATES[i] = cal.getTime(); 1217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Set up test locales 1247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ULocale[] LOCALES = null; 1252d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert if (TEST_ALL || TestFmwk.getExhaustiveness() > 5) { 1267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert LOCALES = ULocale.getAvailableLocales(); 1277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 1287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert LOCALES = new ULocale[] {new ULocale("en"), new ULocale("en_CA"), new ULocale("fr"), new ULocale("zh_Hant")}; 1297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String[] tzids; 1327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (JDKTZ) { 1337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert tzids = java.util.TimeZone.getAvailableIDs(); 1347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 1357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert tzids = TimeZone.getAvailableIDs(); 1367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int[] inOffsets = new int[2]; 1387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int[] outOffsets = new int[2]; 1397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Run the roundtrip test 1417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int locidx = 0; locidx < LOCALES.length; locidx++) { 1427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert logln("Locale: " + LOCALES[locidx].toString()); 1437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String localGMTString = TimeZoneFormat.getInstance(LOCALES[locidx]).formatOffsetLocalizedGMT(0); 1457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int patidx = 0; patidx < PATTERNS.length; patidx++) { 1477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert logln(" pattern: " + PATTERNS[patidx]); 1487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert SimpleDateFormat sdf = new SimpleDateFormat(PATTERNS[patidx], LOCALES[locidx]); 1497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int tzidx = 0; tzidx < tzids.length; tzidx++) { 1517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (EXCL_TZ_PATTERN.matcher(tzids[tzidx]).matches()) { 1527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert continue; 1537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeZone tz = TimeZone.getTimeZone(tzids[tzidx]); 1557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int datidx = 0; datidx < DATES.length; datidx++) { 1577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Format 1587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert sdf.setTimeZone(tz); 1597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String tzstr = sdf.format(DATES[datidx]); 1607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Before parse, set unknown zone to SimpleDateFormat instance 1627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // just for making sure that it does not depends on the time zone 1637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // originally set. 1647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert sdf.setTimeZone(unknownZone); 1657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Parse 1677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ParsePosition pos = new ParsePosition(0); 1687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Calendar outcal = Calendar.getInstance(unknownZone); 1697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert outcal.set(Calendar.DST_OFFSET, badDstOffset); 1707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert outcal.set(Calendar.ZONE_OFFSET, badZoneOffset); 1717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert sdf.parse(tzstr, outcal, pos); 1737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Check the result 1757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeZone outtz = outcal.getTimeZone(); 1767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert tz.getOffset(DATES[datidx].getTime(), false, inOffsets); 1787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert outtz.getOffset(DATES[datidx].getTime(), false, outOffsets); 1797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (PATTERNS[patidx].equals("V")) { 1817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Short zone ID - should support roundtrip for canonical CLDR IDs 1827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String canonicalID = TimeZone.getCanonicalID(tzids[tzidx]); 1837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!outtz.getID().equals(canonicalID)) { 1847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (outtz.getID().equals("Etc/Unknown")) { 1857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Note that some zones like Asia/Riyadh87 does not have 1867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // short zone ID and "unk" is used as the fallback 1877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (REALLY_VERBOSE_LOG) { 1887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert logln("Canonical round trip failed (probably as expected); tz=" + tzids[tzidx] 1897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + ", locale=" + LOCALES[locidx] + ", pattern=" + PATTERNS[patidx] 1907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + ", time=" + DATES[datidx].getTime() + ", str=" + tzstr 1917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + ", outtz=" + outtz.getID()); 1927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 1947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert errln("Canonical round trip failed; tz=" + tzids[tzidx] 1957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + ", locale=" + LOCALES[locidx] + ", pattern=" + PATTERNS[patidx] 1967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + ", time=" + DATES[datidx].getTime() + ", str=" + tzstr 1977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + ", outtz=" + outtz.getID()); 1987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (PATTERNS[patidx].equals("VV")) { 2017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Zone ID - full roundtrip support 2027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!outtz.getID().equals(tzids[tzidx])) { 2037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert errln("Zone ID round trip failed; tz=" + tzids[tzidx] 2047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + ", locale=" + LOCALES[locidx] + ", pattern=" + PATTERNS[patidx] 2057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + ", time=" + DATES[datidx].getTime() + ", str=" + tzstr 2067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + ", outtz=" + outtz.getID()); 2077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (PATTERNS[patidx].equals("VVV") || PATTERNS[patidx].equals("VVVV")) { 2097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Location: time zone rule must be preserved except 2107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // zones not actually associated with a specific location. 2117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String canonicalID = TimeZone.getCanonicalID(tzids[tzidx]); 2127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (canonicalID != null && !outtz.getID().equals(canonicalID)) { 2137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Canonical ID did not match - check the rules 2147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean bFailure = false; 2157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if ((tz instanceof BasicTimeZone) && (outtz instanceof BasicTimeZone)) { 2167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean hasNoLocation = TimeZone.getRegion(tzids[tzidx]).equals("001"); 2177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert bFailure = !hasNoLocation 2187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert && !((BasicTimeZone)outtz).hasEquivalentTransitions(tz, low, high); 2197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (bFailure) { 2217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert errln("Canonical round trip failed; tz=" + tzids[tzidx] 2227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + ", locale=" + LOCALES[locidx] + ", pattern=" + PATTERNS[patidx] 2237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + ", time=" + DATES[datidx].getTime() + ", str=" + tzstr 2247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + ", outtz=" + outtz.getID()); 2257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (REALLY_VERBOSE_LOG) { 2267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert logln("Canonical round trip failed (as expected); tz=" + tzids[tzidx] 2277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + ", locale=" + LOCALES[locidx] + ", pattern=" + PATTERNS[patidx] 2287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + ", time=" + DATES[datidx].getTime() + ", str=" + tzstr 2297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + ", outtz=" + outtz.getID()); 2307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 2337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean isOffsetFormat = (PATTERNS[patidx].charAt(0) == 'Z' 2347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert || PATTERNS[patidx].charAt(0) == 'O' 2357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert || PATTERNS[patidx].charAt(0) == 'X' 2367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert || PATTERNS[patidx].charAt(0) == 'x'); 2377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean minutesOffset = false; 2387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (PATTERNS[patidx].charAt(0) == 'X' || PATTERNS[patidx].charAt(0) == 'x') { 2397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert minutesOffset = PATTERNS[patidx].length() <= 3; 2407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!isOffsetFormat) { 2437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Check if localized GMT format is used as a fallback of name styles 2447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int numDigits = 0; 2457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int n = 0; n < tzstr.length(); n++) { 2467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (UCharacter.isDigit(tzstr.charAt(n))) { 2477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert numDigits++; 2487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert isOffsetFormat = (numDigits > 0); 2517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (isOffsetFormat || tzstr.equals(localGMTString)) { 2547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Localized GMT or ISO: total offset (raw + dst) must be preserved. 2557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int inOffset = inOffsets[0] + inOffsets[1]; 2567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int outOffset = outOffsets[0] + outOffsets[1]; 2577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int diff = outOffset - inOffset; 2587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (minutesOffset) { 2597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert diff = (diff / 60000) * 60000; 2607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (diff != 0) { 2627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert errln("Offset round trip failed; tz=" + tzids[tzidx] 2637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + ", locale=" + LOCALES[locidx] + ", pattern=" + PATTERNS[patidx] 2647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + ", time=" + DATES[datidx].getTime() + ", str=" + tzstr 2657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + ", inOffset=" + inOffset + ", outOffset=" + outOffset); 2667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 2687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Specific or generic: raw offset must be preserved. 2697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (inOffsets[0] != outOffsets[0]) { 2707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (JDKTZ && tzids[tzidx].startsWith("SystemV/")) { 2717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // JDK uses rule SystemV for these zones while 2727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // ICU handles these zones as aliases of existing time zones 2737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (REALLY_VERBOSE_LOG) { 2747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert logln("Raw offset round trip failed; tz=" + tzids[tzidx] 2757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + ", locale=" + LOCALES[locidx] + ", pattern=" + PATTERNS[patidx] 2767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + ", time=" + DATES[datidx].getTime() + ", str=" + tzstr 2777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + ", inRawOffset=" + inOffsets[0] + ", outRawOffset=" + outOffsets[0]); 2787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 2817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert errln("Raw offset round trip failed; tz=" + tzids[tzidx] 2827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + ", locale=" + LOCALES[locidx] + ", pattern=" + PATTERNS[patidx] 2837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + ", time=" + DATES[datidx].getTime() + ", str=" + tzstr 2847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + ", inRawOffset=" + inOffsets[0] + ", outRawOffset=" + outOffsets[0]); 2857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /* 2977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Test case of round trip time and text. This test case detects every canonical TimeZone's 2987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * rule transition since 1900 until 2020, then check if time around each transition can 2997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * round trip as expected. 3007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 3012d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert @Test 3027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void TestTimeRoundTrip() { 3037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean TEST_ALL = getBooleanProperty("TimeZoneRoundTripAll", false); 3057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int startYear, endYear; 3077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3082d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert if (TEST_ALL || TestFmwk.getExhaustiveness() > 5) { 3097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert startYear = 1900; 3107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 3117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert startYear = 1990; 3127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); 3157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert endYear = cal.get(Calendar.YEAR) + 3; 3167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert cal.set(startYear, Calendar.JANUARY, 1); 3187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert final long START_TIME = cal.getTimeInMillis(); 3197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert cal.set(endYear, Calendar.JANUARY, 1); 3217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert final long END_TIME = cal.getTimeInMillis(); 3227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // These patterns are ambiguous at DST->STD local time overlap 3247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert List<String> AMBIGUOUS_DST_DECESSION = Arrays.asList("v", "vvvv", "V", "VV", "VVV", "VVVV"); 3257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // These patterns are ambiguous at STD->STD/DST->DST local time overlap 3277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert List<String> AMBIGUOUS_NEGATIVE_SHIFT = Arrays.asList("z", "zzzz", "v", "vvvv", "V", "VV", "VVV", "VVVV"); 3287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // These patterns only support integer minutes offset 3307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert List<String> MINUTES_OFFSET = Arrays.asList("X", "XX", "XXX", "x", "xx", "xxx"); 3317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Regex pattern used for filtering zone IDs without exemplar location 3337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert final Pattern LOC_EXCLUSION_PATTERN = Pattern.compile("Etc/.*|SystemV/.*|.*/Riyadh8[7-9]"); 3347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert final String BASEPATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSS"; 3367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ULocale[] LOCALES = null; 3387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // timer for performance analysis 3407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long[] times = new long[PATTERNS.length]; 3417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long timer; 3427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (TEST_ALL) { 3447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // It may take about an hour for testing all locales 3457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert LOCALES = ULocale.getAvailableLocales(); 3462d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert } else if (TestFmwk.getExhaustiveness() > 5) { 3477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert LOCALES = new ULocale[] { 3487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert new ULocale("ar_EG"), new ULocale("bg_BG"), new ULocale("ca_ES"), new ULocale("da_DK"), new ULocale("de"), 3497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert new ULocale("de_DE"), new ULocale("el_GR"), new ULocale("en"), new ULocale("en_AU"), new ULocale("en_CA"), 3507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert new ULocale("en_US"), new ULocale("es"), new ULocale("es_ES"), new ULocale("es_MX"), new ULocale("fi_FI"), 3517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert new ULocale("fr"), new ULocale("fr_CA"), new ULocale("fr_FR"), new ULocale("he_IL"), new ULocale("hu_HU"), 3527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert new ULocale("it"), new ULocale("it_IT"), new ULocale("ja"), new ULocale("ja_JP"), new ULocale("ko"), 3537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert new ULocale("ko_KR"), new ULocale("nb_NO"), new ULocale("nl_NL"), new ULocale("nn_NO"), new ULocale("pl_PL"), 3547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert new ULocale("pt"), new ULocale("pt_BR"), new ULocale("pt_PT"), new ULocale("ru_RU"), new ULocale("sv_SE"), 3557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert new ULocale("th_TH"), new ULocale("tr_TR"), new ULocale("zh"), new ULocale("zh_Hans"), new ULocale("zh_Hans_CN"), 3567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert new ULocale("zh_Hant"), new ULocale("zh_Hant_HK"), new ULocale("zh_Hant_TW") 3577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }; 3587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 3597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert LOCALES = new ULocale[] { 3607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert new ULocale("en"), 3617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }; 3627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert SimpleDateFormat sdfGMT = new SimpleDateFormat(BASEPATTERN); 3657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert sdfGMT.setTimeZone(TimeZone.getTimeZone("Etc/GMT")); 3667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long testCounts = 0; 3687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long[] testTimes = new long[4]; 3697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean[] expectedRoundTrip = new boolean[4]; 3707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int testLen = 0; 3717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int locidx = 0; locidx < LOCALES.length; locidx++) { 3727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert logln("Locale: " + LOCALES[locidx].toString()); 3737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int patidx = 0; patidx < PATTERNS.length; patidx++) { 3747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert logln(" pattern: " + PATTERNS[patidx]); 3757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String pattern = BASEPATTERN + " " + PATTERNS[patidx]; 3767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert SimpleDateFormat sdf = new SimpleDateFormat(pattern, LOCALES[locidx]); 3777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean minutesOffset = MINUTES_OFFSET.contains(PATTERNS[patidx]); 3787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Set<String> ids = null; 3807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (JDKTZ) { 3817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ids = new TreeSet<String>(); 3827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String[] jdkIDs = java.util.TimeZone.getAvailableIDs(); 3837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (String jdkID : jdkIDs) { 3847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (EXCL_TZ_PATTERN.matcher(jdkID).matches()) { 3857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert continue; 3867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String tmpID = TimeZone.getCanonicalID(jdkID); 3887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (tmpID != null) { 3897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ids.add(tmpID); 3907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 3937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ids = TimeZone.getAvailableIDs(SystemTimeZoneType.CANONICAL, null, null); 3947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (String id : ids) { 3977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (PATTERNS[patidx].equals("V")) { 3987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Some zones do not have short ID assigned, such as Asia/Riyadh87. 3997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // The time roundtrip will fail for such zones with pattern "V" (short zone ID). 4007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // This is expected behavior. 4017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String shortZoneID = ZoneMeta.getShortID(id); 4027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (shortZoneID == null) { 4037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert continue; 4047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (PATTERNS[patidx].equals("VVV")) { 4067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Some zones are not associated with any region, such as Etc/GMT+8. 4077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // The time roundtrip will fail for such zones with pattern "VVV" (exemplar location). 4087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // This is expected behavior. 4097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (id.indexOf('/') < 0 || LOC_EXCLUSION_PATTERN.matcher(id).matches()) { 4107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert continue; 4117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (id.equals("Pacific/Apia") && PATTERNS[patidx].equals("vvvv") 4157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert && logKnownIssue("11052", "Ambiguous zone name - Samoa Time")) { 4167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert continue; 4177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert BasicTimeZone btz = (BasicTimeZone)TimeZone.getTimeZone(id, TimeZone.TIMEZONE_ICU); 4207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeZone tz = TimeZone.getTimeZone(id); 4217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert sdf.setTimeZone(tz); 4227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long t = START_TIME; 4247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeZoneTransition tzt = null; 4257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean middle = true; 4262d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert boolean last = false; 4277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert while (t < END_TIME) { 4287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (tzt == null) { 4297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert testTimes[0] = t; 4307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert expectedRoundTrip[0] = true; 4317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert testLen = 1; 4327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 4337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int fromOffset = tzt.getFrom().getRawOffset() + tzt.getFrom().getDSTSavings(); 4347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int toOffset = tzt.getTo().getRawOffset() + tzt.getTo().getDSTSavings(); 4357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int delta = toOffset - fromOffset; 4367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (delta < 0) { 4377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean isDstDecession = tzt.getFrom().getDSTSavings() > 0 && tzt.getTo().getDSTSavings() == 0; 4387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert testTimes[0] = t + delta - 1; 4397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert expectedRoundTrip[0] = true; 4407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert testTimes[1] = t + delta; 4417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert expectedRoundTrip[1] = isDstDecession ? 4427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert !AMBIGUOUS_DST_DECESSION.contains(PATTERNS[patidx]) : 4437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert !AMBIGUOUS_NEGATIVE_SHIFT.contains(PATTERNS[patidx]); 4447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert testTimes[2] = t - 1; 4457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert expectedRoundTrip[2] = isDstDecession ? 4467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert !AMBIGUOUS_DST_DECESSION.contains(PATTERNS[patidx]) : 4477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert !AMBIGUOUS_NEGATIVE_SHIFT.contains(PATTERNS[patidx]); 4487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert testTimes[3] = t; 4497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert expectedRoundTrip[3] = true; 4507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert testLen = 4; 4517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 4527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert testTimes[0] = t - 1; 4537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert expectedRoundTrip[0] = true; 4547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert testTimes[1] = t; 4557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert expectedRoundTrip[1] = true; 4567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert testLen = 2; 4577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int testidx = 0; testidx < testLen; testidx++) { 4607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert testCounts++; 4617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert timer = System.currentTimeMillis(); 4627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String text = sdf.format(new Date(testTimes[testidx])); 4637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert try { 4647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Date parsedDate = sdf.parse(text); 4657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long restime = parsedDate.getTime(); 4667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long timeDiff = restime - testTimes[testidx]; 4677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean bTimeMatch = minutesOffset ? 4687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert (timeDiff/60000)*60000 == 0 : timeDiff == 0; 4697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!bTimeMatch) { 4707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert StringBuffer msg = new StringBuffer(); 4717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert msg.append("Time round trip failed for ") 4727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert .append("tzid=").append(id) 4737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert .append(", locale=").append(LOCALES[locidx]) 4747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert .append(", pattern=").append(PATTERNS[patidx]) 4757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert .append(", text=").append(text) 4767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert .append(", gmt=").append(sdfGMT.format(new Date(testTimes[testidx]))) 4777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert .append(", time=").append(testTimes[testidx]) 4787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert .append(", restime=").append(restime) 4797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert .append(", diff=").append(timeDiff); 4807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (expectedRoundTrip[testidx] 4817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert && !isSpecialTimeRoundTripCase(LOCALES[locidx], id, PATTERNS[patidx], testTimes[testidx])) { 4827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert errln("FAIL: " + msg.toString()); 4837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (REALLY_VERBOSE_LOG) { 4847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert logln(msg.toString()); 4857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } catch (ParseException pe) { 4887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert errln("FAIL: " + pe.getMessage() + " tzid=" + id + ", locale=" + LOCALES[locidx] + 4897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ", pattern=" + PATTERNS[patidx] + ", text=" + text); 4907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert times[patidx] += System.currentTimeMillis() - timer; 4927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4932d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 4942d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert if (last) { 4957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert break; 4967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4972d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 4982d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert tzt = btz.getNextTransition(t, false); 4992d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert if (tzt == null) { 5002d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert last = true; 5012d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert t = END_TIME - 1; 5022d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert } else if (middle) { 5037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Test the date in the middle of two transitions. 5047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert t += (tzt.getTime() - t)/2; 5057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert middle = false; 5067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert tzt = null; 5077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 5087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert t = tzt.getTime(); 5097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long total = 0; 5167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert logln("### Elapsed time by patterns ###"); 5177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = 0; i < PATTERNS.length; i++) { 5187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert logln(times[i] + "ms (" + PATTERNS[i] + ")"); 5197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert total += times[i]; 5207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert logln("Total: " + total + "ms"); 5227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert logln("Iteration: " + testCounts); 5237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Special exclusions in TestTimeZoneRoundTrip. 5267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // These special cases do not round trip time as designed. 5277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private boolean isSpecialTimeRoundTripCase(ULocale loc, String id, String pattern, long time) { 5287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert final Object[][] EXCLUSIONS = { 5297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {null, "Asia/Chita", "zzzz", Long.valueOf(1414252800000L)}, 5307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {null, "Asia/Chita", "vvvv", Long.valueOf(1414252800000L)}, 5317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {null, "Asia/Srednekolymsk", "zzzz", Long.valueOf(1414241999999L)}, 5327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {null, "Asia/Srednekolymsk", "vvvv", Long.valueOf(1414241999999L)}, 5337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }; 5347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean isExcluded = false; 5357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (Object[] excl : EXCLUSIONS) { 5362d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert if (excl[0] == null || loc.equals(excl[0])) { 5377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (id.equals(excl[1])) { 5382d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert if (excl[2] == null || pattern.equals(excl[2])) { 5397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (excl[3] == null || ((Long)excl[3]).compareTo(time) == 0) { 5407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert isExcluded = true; 5417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert break; 5427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return isExcluded; 5487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5502d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert @Test 5517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void TestParse() { 5527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert final Object[][] DATA = { 5537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // text inpos locale style 5547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // parseOptions expected outpos time type 5557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {"Z", 0, "en_US", Style.ISO_EXTENDED_FULL, 5567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert null, "Etc/GMT", 1, TimeType.UNKNOWN}, 5577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {"Z", 0, "en_US", Style.SPECIFIC_LONG, 5597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert null, "Etc/GMT", 1, TimeType.UNKNOWN}, 5607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {"Zambia time", 0, "en_US", Style.ISO_EXTENDED_FULL, 5627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert EnumSet.of(ParseOption.ALL_STYLES), "Etc/GMT", 1, TimeType.UNKNOWN}, 5637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {"Zambia time", 0, "en_US", Style.GENERIC_LOCATION, 5657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert null, "Africa/Lusaka", 11, TimeType.UNKNOWN}, 5667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {"Zambia time", 0, "en_US", Style.ISO_BASIC_LOCAL_FULL, 5687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert EnumSet.of(ParseOption.ALL_STYLES), "Africa/Lusaka", 11, TimeType.UNKNOWN}, 5697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {"+00:00", 0, "en_US", Style.ISO_EXTENDED_FULL, 5717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert null, "Etc/GMT", 6, TimeType.UNKNOWN}, 5727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {"-01:30:45", 0, "en_US", Style.ISO_EXTENDED_FULL, 5747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert null, "GMT-01:30:45", 9, TimeType.UNKNOWN}, 5757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {"-7", 0, "en_US", Style.ISO_BASIC_LOCAL_FULL, 5777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert null, "GMT-07:00", 2, TimeType.UNKNOWN}, 5787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {"-2222", 0, "en_US", Style.ISO_BASIC_LOCAL_FULL, 5807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert null, "GMT-22:22", 5, TimeType.UNKNOWN}, 5817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {"-3333", 0, "en_US", Style.ISO_BASIC_LOCAL_FULL, 5837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert null, "GMT-03:33", 4, TimeType.UNKNOWN}, 5847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {"XXX+01:30YYY", 3, "en_US", Style.LOCALIZED_GMT, 5867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert null, "GMT+01:30", 9, TimeType.UNKNOWN}, 5877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {"GMT0", 0, "en_US", Style.SPECIFIC_SHORT, 5897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert null, "Etc/GMT", 3, TimeType.UNKNOWN}, 5907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {"EST", 0, "en_US", Style.SPECIFIC_SHORT, 5927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert null, "America/New_York", 3, TimeType.STANDARD}, 5937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {"ESTx", 0, "en_US", Style.SPECIFIC_SHORT, 5957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert null, "America/New_York", 3, TimeType.STANDARD}, 5967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {"EDTx", 0, "en_US", Style.SPECIFIC_SHORT, 5987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert null, "America/New_York", 3, TimeType.DAYLIGHT}, 5997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {"EST", 0, "en_US", Style.SPECIFIC_LONG, 6017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert null, null, 0, TimeType.UNKNOWN}, 6027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {"EST", 0, "en_US", Style.SPECIFIC_LONG, 6047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert EnumSet.of(ParseOption.ALL_STYLES), "America/New_York", 3, TimeType.STANDARD}, 6057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {"EST", 0, "en_CA", Style.SPECIFIC_SHORT, 6077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert null, "America/Toronto", 3, TimeType.STANDARD}, 6087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {"CST", 0, "en_US", Style.SPECIFIC_SHORT, 6107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert null, "America/Chicago", 3, TimeType.STANDARD}, 6117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {"CST", 0, "en_GB", Style.SPECIFIC_SHORT, 6137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert null, null, 0, TimeType.UNKNOWN}, 6147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {"CST", 0, "en_GB", Style.SPECIFIC_SHORT, 6167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert EnumSet.of(ParseOption.TZ_DATABASE_ABBREVIATIONS), "America/Chicago", 3, TimeType.STANDARD}, 6177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {"--CST--", 2, "en_GB", Style.SPECIFIC_SHORT, 6197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert EnumSet.of(ParseOption.TZ_DATABASE_ABBREVIATIONS), "America/Chicago", 5, TimeType.STANDARD}, 6207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {"CST", 0, "zh_CN", Style.SPECIFIC_SHORT, 6227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert EnumSet.of(ParseOption.TZ_DATABASE_ABBREVIATIONS), "Asia/Shanghai", 3, TimeType.STANDARD}, 6237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {"AEST", 0, "en_AU", Style.SPECIFIC_SHORT, 6257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert EnumSet.of(ParseOption.TZ_DATABASE_ABBREVIATIONS), "Australia/Sydney", 4, TimeType.STANDARD}, 6267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {"AST", 0, "ar_SA", Style.SPECIFIC_SHORT, 6287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert EnumSet.of(ParseOption.TZ_DATABASE_ABBREVIATIONS), "Asia/Riyadh", 3, TimeType.STANDARD}, 6297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {"AQTST", 0, "en", Style.SPECIFIC_LONG, 6317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert null, null, 0, TimeType.UNKNOWN}, 6327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {"AQTST", 0, "en", Style.SPECIFIC_LONG, 6347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert EnumSet.of(ParseOption.ALL_STYLES), null, 0, TimeType.UNKNOWN}, 6357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert {"AQTST", 0, "en", Style.SPECIFIC_LONG, 6377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert EnumSet.of(ParseOption.ALL_STYLES, ParseOption.TZ_DATABASE_ABBREVIATIONS), "Asia/Aqtobe", 5, TimeType.DAYLIGHT}, 6382d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 6392d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert {"hora de verano británica", 0, "es", Style.SPECIFIC_LONG, 6402d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert null, "Europe/London", 24, TimeType.DAYLIGHT}, 6417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }; 6427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (Object[] test : DATA) { 6447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String text = (String)test[0]; 6457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int inPos = (Integer)test[1]; 6467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ULocale loc = new ULocale((String)test[2]); 6477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Style style = (Style)test[3]; 6487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert EnumSet<ParseOption> options = (EnumSet<ParseOption>)test[4]; 6497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String expID = (String)test[5]; 6507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int expPos = (Integer)test[6]; 6517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeType expType = (TimeType)test[7]; 6527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeZoneFormat tzfmt = TimeZoneFormat.getInstance(loc); 6547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Output<TimeType> timeType = new Output<TimeType>(TimeType.UNKNOWN); 6557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ParsePosition pos = new ParsePosition(inPos); 6567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeZone tz = tzfmt.parse(style, text, pos, options, timeType); 6577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String errMsg = null; 6597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (tz == null) { 6607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (expID != null) { 6617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert errMsg = "Parse failure - expected: " + expID; 6627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (!tz.getID().equals(expID)) { 6647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert errMsg = "Time zone ID: " + tz.getID() + " - expected: " + expID; 6657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (pos.getIndex() != expPos) { 6667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert errMsg = "Parsed pos: " + pos.getIndex() + " - expected: " + expPos; 6677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (timeType.value != expType) { 6687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert errMsg = "Time type: " + timeType + " - expected: " + expType; 6697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (errMsg != null) { 672bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert errln("Fail: " + errMsg + 673bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert " [text=" + text + ", pos=" + inPos + 674bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert ", locale=" + loc + ", style=" + style + "]"); 6757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6782d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 679e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer // Coverage tests for other versions of the parse() method. All of them end up 680e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer // calling the full parse() method tested on the TestParse() test. 681e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer public void TestParseCoverage() { 6822d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert TimeZone expectedTZ = TimeZone.getTimeZone("America/Los_Angeles"); 683e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer TimeZoneFormat fmt = TimeZoneFormat.getInstance(ULocale.ENGLISH); 6842d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 685e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer // Test parse(String) 686e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer try { 687e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer TimeZone tz1 = fmt.parse("America/Los_Angeles"); 688e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer if (tz1 == null) { 689e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer errln("Parse failure using parse(String) - expected: " + expectedTZ.getID()); 690e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer } else if (!expectedTZ.equals(tz1)) { 691e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer errln("Parsed TimeZone: '" + tz1.getID() + "' using parse(String) - expected: " 692e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer + expectedTZ.getID()); 6932d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert } 694e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer } catch (ParseException e) { 695e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer errln("Parse failure using parse(String) - expected: " + expectedTZ.getID() 696e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer + " exception: " + e.getMessage()); 697e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer } 6982d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 699e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer // Test parse(String, ParsePosition) 700e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer TimeZone tz2 = fmt.parse("++America/Los_Angeles", new ParsePosition(2)); 701e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer if (tz2 == null) { 7022d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert errln("Parse failure using parse(String, ParsePosition) - expected: " 703e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer + expectedTZ.getID()); 704e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer } else if (!expectedTZ.equals(tz2)) { 705e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer errln("Parsed TimeZone: '" + tz2.getID() + "' using parse(String, ParsePosition) - expected: " 706e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer + expectedTZ.getID()); 707e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer } 7082d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 709e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer // Test parseObject(String, ParsePosition) 710e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer Object tz3 = fmt.parseObject("++America/Los_Angeles", new ParsePosition(2)); 711e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer if (tz3 == null) { 7122d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert errln("Parse failure using parseObject(String, ParsePosition) - expected: " 713e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer + expectedTZ.getID()); 714e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer } else if (!expectedTZ.equals(tz3)) { 715e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer errln("Parsed TimeZone: '" + ((TimeZone)tz3).getID() 716e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer + "' using parseObject(String, ParsePosition) - expected: " 717e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer + expectedTZ.getID()); 718e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer } 719e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer } 7207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 7212d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert @Test 7227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void TestISOFormat() { 7237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert final int[] OFFSET = { 7247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 0, // 0 7257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 999, // 0.999s 7267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert -59999, // -59.999s 7277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 60000, // 1m 7287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert -77777, // -1m 17.777s 7297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1800000, // 30m 7307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert -3600000, // -1h 7317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 36000000, // 10h 7327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert -37800000, // -10h 30m 7337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert -37845000, // -10h 30m 45s 7347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 108000000, // 30h 7357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }; 7362d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 7377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert final String[][] ISO_STR = { 7387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // 0 7397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 7407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "Z", "Z", "Z", "Z", "Z", 7417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "+00", "+0000", "+00:00", "+0000", "+00:00", 7427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "+0000" 7437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }, 7447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // 999 7457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 7467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "Z", "Z", "Z", "Z", "Z", 7477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "+00", "+0000", "+00:00", "+0000", "+00:00", 7487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "+0000" 7497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }, 7507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // -59999 7517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 7527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "Z", "Z", "Z", "-000059", "-00:00:59", 7537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "+00", "+0000", "+00:00", "-000059", "-00:00:59", 7547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "-000059" 7557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }, 7567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // 60000 7577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 7587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "+0001", "+0001", "+00:01", "+0001", "+00:01", 7597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "+0001", "+0001", "+00:01", "+0001", "+00:01", 7607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "+0001" 7617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }, 7627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // -77777 7637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 7647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "-0001", "-0001", "-00:01", "-000117", "-00:01:17", 7657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "-0001", "-0001", "-00:01", "-000117", "-00:01:17", 7667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "-000117" 7677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }, 7687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // 1800000 7697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 7707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "+0030", "+0030", "+00:30", "+0030", "+00:30", 7717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "+0030", "+0030", "+00:30", "+0030", "+00:30", 7727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "+0030" 7737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }, 7747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // -3600000 7757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 7767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "-01", "-0100", "-01:00", "-0100", "-01:00", 7777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "-01", "-0100", "-01:00", "-0100", "-01:00", 7787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "-0100" 7797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }, 7807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // 36000000 7817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 7827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "+10", "+1000", "+10:00", "+1000", "+10:00", 7837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "+10", "+1000", "+10:00", "+1000", "+10:00", 7847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "+1000" 7857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }, 7867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // -37800000 7877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 7887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "-1030", "-1030", "-10:30", "-1030", "-10:30", 7897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "-1030", "-1030", "-10:30", "-1030", "-10:30", 7907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "-1030" 7917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }, 7927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // -37845000 7937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 7947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "-1030", "-1030", "-10:30", "-103045", "-10:30:45", 7957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "-1030", "-1030", "-10:30", "-103045", "-10:30:45", 7967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "-103045" 7977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }, 7987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // 108000000 7997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 8007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert null, null, null, null, null, 8017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert null, null, null, null, null, 8027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert null 8037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }; 8057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert final String[] PATTERN = { 8077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "X", "XX", "XXX", "XXXX", "XXXXX", "x", "xx", "xxx", "xxxx", "xxxxx", 8087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "Z", // equivalent to "xxxx" 8097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }; 8107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert final int[] MIN_OFFSET_UNIT = { 8127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 60000, 60000, 60000, 1000, 1000, 60000, 60000, 60000, 1000, 1000, 8137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1000, 8147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }; 8157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Formatting 8177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert SimpleDateFormat sdf = new SimpleDateFormat(); 8187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Date d = new Date(); 8197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = 0; i < OFFSET.length; i++) { 8217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert SimpleTimeZone tz = new SimpleTimeZone(OFFSET[i], "Zone Offset:" + String.valueOf(OFFSET[i]) + "ms"); 8227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert sdf.setTimeZone(tz); 8237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int j = 0; j < PATTERN.length; j++) { 8247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert sdf.applyPattern(PATTERN[j]); 8257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert try { 8267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String result = sdf.format(d); 8277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!result.equals(ISO_STR[i][j])) { 8287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert errln("FAIL: pattern=" + PATTERN[j] + ", offset=" + OFFSET[i] + " -> " 8297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + result + " (expected: " + ISO_STR[i][j] + ")"); 8307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } catch (IllegalArgumentException e) { 8327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (ISO_STR[i][j] != null) { 8337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert errln("FAIL: IAE thrown for pattern=" + PATTERN[j] + ", offset=" + OFFSET[i] 8347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + " (expected: " + ISO_STR[i][j] + ")"); 8357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Parsing 8417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert SimpleTimeZone bogusTZ = new SimpleTimeZone(-1, "Zone Offset: -1ms"); 8427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = 0; i < ISO_STR.length; i++) { 8437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int j = 0; j < ISO_STR[i].length; j++) { 8447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (ISO_STR[i][j] == null) { 8457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert continue; 8467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ParsePosition pos = new ParsePosition(0); 8487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Calendar outcal = Calendar.getInstance(bogusTZ); 8497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert sdf.applyPattern(PATTERN[j]); 8507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert sdf.parse(ISO_STR[i][j], outcal, pos); 8527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (pos.getIndex() != ISO_STR[i][j].length()) { 8547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert errln("FAIL: Failed to parse the entire input string: " + ISO_STR[i][j]); 8557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert continue; 8567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeZone outtz = outcal.getTimeZone(); 8597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int outOffset = outtz.getRawOffset(); 8607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int adjustedOffset = OFFSET[i] / MIN_OFFSET_UNIT[j] * MIN_OFFSET_UNIT[j]; 8617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (outOffset != adjustedOffset) { 8637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert errln("FAIL: Incorrect offset:" + outOffset + "ms for input string: " + ISO_STR[i][j] 8647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + " (expected:" + adjustedOffset + "ms)"); 8657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8702d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert @Test 8717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void TestFormat() { 8727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert final Date dateJan = new Date(1358208000000L); // 2013-01-15T00:00:00Z 8737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert final Date dateJul = new Date(1373846400000L); // 2013-07-15T00:00:00Z 8747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert final Object[][] TESTDATA = { 8767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 8777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "en", 8782d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert "America/Los_Angeles", 8797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert dateJan, 8807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Style.GENERIC_LOCATION, 8817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "Los Angeles Time", 8827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeType.UNKNOWN 8837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }, 8847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 8857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "en", 8867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "America/Los_Angeles", 8877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert dateJan, 8887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Style.GENERIC_LONG, 8897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "Pacific Time", 8907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeType.UNKNOWN 8917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }, 8927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 8937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "en", 8947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "America/Los_Angeles", 8957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert dateJan, 8967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Style.SPECIFIC_LONG, 8977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "Pacific Standard Time", 8987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeType.STANDARD 8997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }, 9007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 9017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "en", 9027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "America/Los_Angeles", 9037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert dateJul, 9047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Style.SPECIFIC_LONG, 9057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "Pacific Daylight Time", 9067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeType.DAYLIGHT 9077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }, 9087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 9097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "ja", 9107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "America/Los_Angeles", 9117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert dateJan, 9127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Style.ZONE_ID, 9137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "America/Los_Angeles", 9147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeType.UNKNOWN 9157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }, 9167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 9177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "fr", 9187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "America/Los_Angeles", 9197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert dateJul, 9207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Style.ZONE_ID_SHORT, 9217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "uslax", 9227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeType.UNKNOWN 9237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }, 9247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 9257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "en", 9267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "America/Los_Angeles", 9277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert dateJan, 9287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Style.EXEMPLAR_LOCATION, 9297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "Los Angeles", 9307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeType.UNKNOWN 9317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }, 9327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 9337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "ja", 9347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "Asia/Tokyo", 9357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert dateJan, 9367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Style.GENERIC_LONG, 9377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "\u65E5\u672C\u6A19\u6E96\u6642", // "日本標準時" 9387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeType.UNKNOWN 9397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }, 9407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }; 9417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 9427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (Object[] testCase : TESTDATA) { 9437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeZone tz = TimeZone.getTimeZone((String)testCase[1]); 9447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Output<TimeType> timeType = new Output<TimeType>(); 9457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 9467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ULocale uloc = new ULocale((String)testCase[0]); 9477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeZoneFormat tzfmt = TimeZoneFormat.getInstance(uloc); 9487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String out = tzfmt.format((Style)testCase[3], tz, ((Date)testCase[2]).getTime(), timeType); 9497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 9502d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert if (!out.equals(testCase[4]) || timeType.value != testCase[5]) { 9517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert errln("Format result for [locale=" + testCase[0] + ",tzid=" + testCase[1] + ",date=" + testCase[2] 9527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + ",style=" + testCase[3] + "]: expected [output=" + testCase[4] + ",type=" + testCase[5] 9537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + "]; actual [output=" + out + ",type=" + timeType.value + "]"); 9547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 9557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 9567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // with equivalent Java Locale 9577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Locale loc = uloc.toLocale(); 9587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert tzfmt = TimeZoneFormat.getInstance(loc); 9597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert out = tzfmt.format((Style)testCase[3], tz, ((Date)testCase[2]).getTime(), timeType); 9607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 9612d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert if (!out.equals(testCase[4]) || timeType.value != testCase[5]) { 9627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert errln("Format result for [locale(Java)=" + testCase[0] + ",tzid=" + testCase[1] + ",date=" + testCase[2] 9637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + ",style=" + testCase[3] + "]: expected [output=" + testCase[4] + ",type=" + testCase[5] 9647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + "]; actual [output=" + out + ",type=" + timeType.value + "]"); 9657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 9667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 9677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 9687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 9692d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert @Test 9707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void TestFormatTZDBNames() { 9717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert final Date dateJan = new Date(1358208000000L); // 2013-01-15T00:00:00Z 9727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert final Date dateJul = new Date(1373846400000L); // 2013-07-15T00:00:00Z 9737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 9747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert final Object[][] TESTDATA = { 9757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 9767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "en", 9772d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert "America/Chicago", 9787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert dateJan, 9797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Style.SPECIFIC_SHORT, 9807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "CST", 9817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeType.STANDARD 9827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }, 9837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 9847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "en", 9852d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert "Asia/Shanghai", 9867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert dateJan, 9877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Style.SPECIFIC_SHORT, 9887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "CST", 9897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeType.STANDARD 9907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }, 9917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 9927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "zh_Hans", 9932d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert "Asia/Shanghai", 9947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert dateJan, 9957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Style.SPECIFIC_SHORT, 9967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "CST", 9977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeType.STANDARD 9987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }, 9997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 10007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "en", 10017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "America/Los_Angeles", 10027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert dateJul, 10037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Style.SPECIFIC_LONG, 10047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "GMT-07:00", // No long display names 10057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeType.DAYLIGHT 10067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }, 10077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 10087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "ja", 10097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "America/Los_Angeles", 10107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert dateJul, 10117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Style.SPECIFIC_SHORT, 10127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "PDT", 10137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeType.DAYLIGHT 10147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }, 10157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 10167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "en", 10177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "Australia/Sydney", 10187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert dateJan, 10197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Style.SPECIFIC_SHORT, 10207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "AEDT", 10217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeType.DAYLIGHT 10227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }, 10237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 10247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "en", 10257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "Australia/Sydney", 10267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert dateJul, 10277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Style.SPECIFIC_SHORT, 10287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert "AEST", 10297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeType.STANDARD 10307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }, 10317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert }; 10327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 10337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (Object[] testCase : TESTDATA) { 10347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ULocale loc = new ULocale((String)testCase[0]); 10357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeZoneFormat tzfmt = TimeZoneFormat.getInstance(loc).cloneAsThawed(); 10367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeZoneNames tzdbNames = TimeZoneNames.getTZDBInstance(loc); 10377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert tzfmt.setTimeZoneNames(tzdbNames); 10387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 10397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert TimeZone tz = TimeZone.getTimeZone((String)testCase[1]); 10407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert Output<TimeType> timeType = new Output<TimeType>(); 10417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String out = tzfmt.format((Style)testCase[3], tz, ((Date)testCase[2]).getTime(), timeType); 10427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 10432d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert if (!out.equals(testCase[4]) || timeType.value != testCase[5]) { 10447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert errln("Format result for [locale=" + testCase[0] + ",tzid=" + testCase[1] + ",date=" + testCase[2] 10457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + ",style=" + testCase[3] + "]: expected [output=" + testCase[4] + ",type=" + testCase[5] 10467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert + "]; actual [output=" + out + ",type=" + timeType.value + "]"); 10477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 10487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 10497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1050f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert 1051e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer // Tests format(Object, StringBuffer, FieldPosition):StringBuffer method 1052e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer // inherited from Format class 1053e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer public void TestInheritedFormat() { 1054e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles"); 1055e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer Calendar cal = Calendar.getInstance(tz); 1056e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer cal.setTimeInMillis(1459187377690L); // Mar 28, 2016 10572d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 1058e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer StringBuffer sb = new StringBuffer(); 1059e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer FieldPosition fp = new FieldPosition(DateFormat.Field.TIME_ZONE); 10602d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 1061e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer TimeZoneFormat fmt = TimeZoneFormat.getInstance(ULocale.ENGLISH); 10622d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 1063e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer // Test formatting a non-timezone related object 1064e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer try { 1065e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer fmt.format(new Object(), sb, fp); 1066e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer errln("ERROR: format non-timezone related object failed"); 1067e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer } catch (IllegalArgumentException e) { /* Expected */ } 10682d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 1069e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer // Test formatting a TimeZone object 1070e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer sb = new StringBuffer(); 1071e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer fmt.format(tz, sb, fp); 1072e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer // When formatting a TimeZone object the formatter uses the current date. 1073e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer String fmtOutput = tz.inDaylightTime(new Date()) ? "GMT-07:00" : "GMT-08:00"; 1074e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer if (!sb.toString().equals(fmtOutput)) { 1075e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer errln("ERROR: format TimerZone object failed. Expected: " + fmtOutput + ", actual: " + sb); 1076e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer } 10772d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 1078e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer // Test formatting a Calendar object 1079e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer sb = new StringBuffer(); 1080e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer fmt.format(cal, sb, fp); 1081e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer if (!sb.toString().equals("GMT-07:00")) { 1082e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer errln("ERROR: format Calendar object failed. Expected: GMT-07:00, actual: " + sb); 1083e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer } 1084e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer } 10852d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 1086f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert // This is a test case of Ticket#11487. 1087f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert // Because the problem is reproduced for the very first time, 1088f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert // the reported problem cannot be reproduced with regular test 1089f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert // execution. Run this test alone reproduced the problem before 1090f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert // the fix was merged. 10912d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert @Test 1092f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert public void TestTZDBNamesThreading() { 1093f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert final TZDBTimeZoneNames names = new TZDBTimeZoneNames(ULocale.ENGLISH); 1094f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert final AtomicInteger found = new AtomicInteger(); 1095f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert List<Thread> threads = new ArrayList<Thread>(); 1096f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert final int numIteration = 1000; 1097f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert 1098f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert try { 1099f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert for (int i = 0; i < numIteration; i++) { 1100f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert Thread thread = new Thread() { 1101f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert @Override 1102f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert public void run() { 1103f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert int resultSize = names.find("GMT", 0, EnumSet.allOf(NameType.class)).size(); 1104f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert if (resultSize > 0) { 1105f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert found.incrementAndGet(); 1106f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert } 1107f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert } 1108f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert }; 1109f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert thread.start(); 1110f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert threads.add(thread); 1111f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert } 1112f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert 1113f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert for(Thread thread: threads) { 1114f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert thread.join(); 1115f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert } 1116f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert } catch (Throwable t) { 1117f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert errln(t.toString()); 1118f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert } 1119f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert 1120f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert if (found.intValue() != numIteration) { 1121f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert errln("Incorrect count: " + found.toString() + ", expected: " + numIteration); 1122f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert } 1123f716bda031dccdec5e47bb40e758c5901d209729Fredrik Roubert } 11242d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 11252d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert @Test 11262d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert public void TestGetDisplayNames() { 11272d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert long date = System.currentTimeMillis(); 11282d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert NameType[] types = new NameType[]{ 11292d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert NameType.LONG_STANDARD, NameType.LONG_DAYLIGHT, 11302d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert NameType.SHORT_STANDARD, NameType.SHORT_DAYLIGHT 11312d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert }; 11322d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert Set<String> zones = ZoneMeta.getAvailableIDs(SystemTimeZoneType.ANY, null, null); 11332d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 11342d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert int casesTested = 0; 11352d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert Random rnd = new Random(2016); 11362d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert for (ULocale uloc : ULocale.getAvailableLocales()) { 11372d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert if (rnd.nextDouble() > 0.01) { continue; } 11382d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert for (String zone : zones) { 11392d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert if (rnd.nextDouble() > 0.01) { continue; } 11402d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert casesTested++; 11412d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 11422d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert // Test default TimeZoneNames (uses an overridden getDisplayNames) 11432d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert { 11442d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert TimeZoneNames tznames = TimeZoneNames.getInstance(uloc); 11452d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert tznames.loadAllDisplayNames(); 11462d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert String[] result = new String[types.length]; 11472d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert tznames.getDisplayNames(zone, types, date, result, 0); 11482d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert for (int i=0; i<types.length; i++) { 11492d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert NameType type = types[i]; 11502d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert String expected = result[i]; 11512d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert String actual = tznames.getDisplayName(zone, type, date); 11522d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert assertEquals("TimeZoneNames: getDisplayNames() returns different result than getDisplayName()" 11532d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert + " for " + zone + " in locale " + uloc, expected, actual); 11542d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert } 11552d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert // Coverage for empty call to getDisplayNames 11562d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert tznames.getDisplayNames(null, null, 0, null, 0); 11572d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert } 11582d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 11592d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert // Test TZDBTimeZoneNames (uses getDisplayNames from abstract class) 11602d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert { 11612d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert TimeZoneNames tznames = new TZDBTimeZoneNames(uloc); 11622d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert tznames.loadAllDisplayNames(); 11632d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert String[] result = new String[types.length]; 11642d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert tznames.getDisplayNames(zone, types, date, result, 0); 11652d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert for (int i=0; i<types.length; i++) { 11662d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert NameType type = types[i]; 11672d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert String expected = result[i]; 11682d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert String actual = tznames.getDisplayName(zone, type, date); 11692d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert assertEquals("TZDBTimeZoneNames: getDisplayNames() returns different result than getDisplayName()" 11702d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert + " for " + zone + " in locale " + uloc, expected, actual); 11712d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert } 11722d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert // Coverage for empty call to getDisplayNames 11732d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert tznames.getDisplayNames(null, null, 0, null, 0); 11742d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert } 11752d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert } 11762d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert } 11772d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 11782d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert assertTrue("No cases were tested", casesTested > 0); 11792d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert } 11802d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 11812d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert class TimeZoneNamesInheriter extends TimeZoneNames { 11822d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert private static final long serialVersionUID = 1L; 11832d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 11842d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert @Override 11852d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert public Set<String> getAvailableMetaZoneIDs() { 11862d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert return null; 11872d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert } 11882d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 11892d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert @Override 11902d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert public Set<String> getAvailableMetaZoneIDs(String tzID) { 11912d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert return null; 11922d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert } 11932d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 11942d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert @Override 11952d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert public String getMetaZoneID(String tzID, long date) { 11962d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert return null; 11972d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert } 11982d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 11992d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert @Override 12002d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert public String getReferenceZoneID(String mzID, String region) { 12012d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert return null; 12022d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert } 12032d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 12042d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert @Override 12052d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert public String getMetaZoneDisplayName(String mzID, NameType type) { 12062d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert return null; 12072d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert } 12082d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 12092d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert @Override 12102d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert public String getTimeZoneDisplayName(String tzID, NameType type) { 12112d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert return null; 12122d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert } 12132d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert } 12142d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 12152d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert // Coverage for default implementation and abstract methods in base class. 12162d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert @Test 12172d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert public void TestDefaultTimeZoneNames() { 12182d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert long date = System.currentTimeMillis(); 12192d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert TimeZoneNames.Factory factory; 12202d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert try { 12212d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert Class cls = Class.forName("com.ibm.icu.text.TimeZoneNames$DefaultTimeZoneNames$FactoryImpl"); 12222d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert factory = (Factory) cls.newInstance(); 12232d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert } catch (Exception e) { 12242d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert errln("Could not create class DefaultTimeZoneNames.FactoryImpl: " + e.getClass() + ": " + e.getMessage()); 12252d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert return; 12262d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert } 12272d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert TimeZoneNames tzn = factory.getTimeZoneNames(ULocale.ENGLISH); 12282d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert assertEquals("Abstract: getAvailableMetaZoneIDs()", 12292d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert tzn.getAvailableMetaZoneIDs(), Collections.emptySet()); 12302d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert assertEquals("Abstract: getAvailableMetaZoneIDs(String tzID)", 12312d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert tzn.getAvailableMetaZoneIDs("America/Chicago"), Collections.emptySet()); 12322d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert assertEquals("Abstract: getMetaZoneID(String tzID, long date)", 12332d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert tzn.getMetaZoneID("America/Chicago", date), null); 12342d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert assertEquals("Abstract: getReferenceZoneID(String mzID, String region)", 12352d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert tzn.getReferenceZoneID("America_Central", "IT"), null); 12362d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert assertEquals("Abstract: getMetaZoneDisplayName(String mzID, NameType type)", 12372d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert tzn.getMetaZoneDisplayName("America_Central", NameType.LONG_DAYLIGHT), null); 12382d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert assertEquals("Abstract: getTimeZoneDisplayName(String mzID, NameType type)", 12392d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert tzn.getTimeZoneDisplayName("America/Chicago", NameType.LONG_DAYLIGHT), null); 12402d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert assertEquals("Abstract: find(CharSequence text, int start, EnumSet<NameType> nameTypes)", 12412d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert tzn.find("foo", 0, EnumSet.noneOf(NameType.class)), Collections.emptyList()); 12422d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 12432d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert // Other abstract-class methods that aren't covered 12442d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert tzn = new TimeZoneNamesInheriter(); 12452d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert try { 12462d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert tzn.find(null, 0, null); 12472d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert } catch (UnsupportedOperationException e) { 12482d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert assertEquals("find() exception", "The method is not implemented in TimeZoneNames base class.", e.getMessage()); 12492d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert } 12502d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert } 12512d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 1252e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer // Basic get/set test for methods not being called otherwise. 12532d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert @Test 1254e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer public void TestAPI() { 1255e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer TimeZoneFormat tzfmtEn = TimeZoneFormat.getInstance(ULocale.ENGLISH); 1256e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer TimeZoneFormat tzfmtAr = TimeZoneFormat.getInstance(new ULocale("ar")).cloneAsThawed(); 12572d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert TimeZoneNames tzn = TimeZoneNames.getInstance(Locale.ENGLISH); 12582d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 1259e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer String digits = tzfmtEn.getGMTOffsetDigits(); 1260e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer tzfmtAr.setGMTOffsetDigits(digits); 1261e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer if (!digits.equals(tzfmtAr.getGMTOffsetDigits())) { 1262e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer errln("ERROR: get/set GMTOffsetDigits failed"); 1263e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer } 12642d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 1265e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer String pattern = tzfmtEn.getGMTOffsetPattern(GMTOffsetPatternType.POSITIVE_H); 1266e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer tzfmtAr.setGMTOffsetPattern(GMTOffsetPatternType.POSITIVE_H, pattern); 1267e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer if (!pattern.equals(tzfmtAr.getGMTOffsetPattern(GMTOffsetPatternType.POSITIVE_H))) { 1268e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer errln("ERROR: get/set GMTOffsetPattern failed"); 1269e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer } 12702d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 1271e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer String zeroFmt = tzfmtEn.getGMTZeroFormat(); 1272e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer tzfmtAr.setGMTZeroFormat(zeroFmt); 1273e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer if (!zeroFmt.equals(tzfmtAr.getGMTZeroFormat())) { 1274e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer errln("ERROR: get/set GMTZeroFormat failed"); 1275e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer } 12762d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 12772d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert Set<String> allAvailableMZIDs = tzn.getAvailableMetaZoneIDs(); 12782d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert if (allAvailableMZIDs.size() < 150 || !allAvailableMZIDs.contains("America_Central")) { 12792d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert errln("ERROR: getAvailableMetaZoneIDs() did not return expected value"); 12802d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert } 12812d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 12822d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert Set<String> kinshasaAvailableMZIDs = tzn.getAvailableMetaZoneIDs("Africa/Kinshasa"); 12832d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert if (!kinshasaAvailableMZIDs.contains("Africa_Western") || kinshasaAvailableMZIDs.contains("America_Central")) { 12842d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert errln("ERROR: getAvailableMetaZoneIDs('Africa/Kinshasa') did not return expected value"); 12852d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert } 12862d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 12872d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert try { 12882d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert new TimeZoneNames.MatchInfo(null, null, null, -1); 12892d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert assertTrue("MatchInfo doesn't throw IllegalArgumentException", false); 12902d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert } catch (IllegalArgumentException e) { 12912d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert assertEquals("MatchInfo constructor exception", "nameType is null", e.getMessage()); 12922d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert } 12932d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 12942d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert try { 12952d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert new TimeZoneNames.MatchInfo(NameType.LONG_GENERIC, null, null, -1); 12962d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert assertTrue("MatchInfo doesn't throw IllegalArgumentException", false); 12972d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert } catch (IllegalArgumentException e) { 12982d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert assertEquals("MatchInfo constructor exception", "Either tzID or mzID must be available", e.getMessage()); 12992d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert } 13002d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert 13012d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert try { 13022d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert new TimeZoneNames.MatchInfo(NameType.LONG_GENERIC, "America/Chicago", null, -1); 13032d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert assertTrue("MatchInfo doesn't throw IllegalArgumentException", false); 13042d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert } catch (IllegalArgumentException e) { 13052d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert assertEquals("MatchInfo constructor exception", "matchLength must be positive value", e.getMessage()); 13062d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert } 1307e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer } 13082d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert} 1309