2 *******************************************************************************
\r
3 * Copyright (C) 2000-2009, International Business Machines Corporation and *
\r
4 * others. All Rights Reserved. *
\r
5 *******************************************************************************
\r
8 package com.ibm.icu.dev.test.timezone;
\r
10 import java.io.ByteArrayInputStream;
\r
11 import java.io.ByteArrayOutputStream;
\r
12 import java.io.IOException;
\r
13 import java.io.ObjectInputStream;
\r
14 import java.io.ObjectOutputStream;
\r
15 import java.lang.reflect.InvocationTargetException;
\r
16 import java.util.Arrays;
\r
17 import java.util.Date;
\r
18 import java.util.List;
\r
19 import java.util.Locale;
\r
21 import com.ibm.icu.dev.test.TestFmwk;
\r
22 import com.ibm.icu.impl.ICUResourceBundle;
\r
23 import com.ibm.icu.text.SimpleDateFormat;
\r
24 import com.ibm.icu.util.Calendar;
\r
25 import com.ibm.icu.util.GregorianCalendar;
\r
26 import com.ibm.icu.util.SimpleTimeZone;
\r
27 import com.ibm.icu.util.TimeZone;
\r
28 import com.ibm.icu.util.ULocale;
\r
29 import com.ibm.icu.util.UResourceBundle;
\r
32 * @test 1.22 99/09/21
\r
33 * @bug 4028006 4044013 4096694 4107276 4107570 4112869 4130885
\r
34 * @summary test TimeZone
\r
35 * @build TimeZoneTest
\r
37 public class TimeZoneTest extends TestFmwk
\r
39 static final int millisPerHour = 3600000;
\r
41 // TODO: We should probably read following data at runtime, so we can update
\r
42 // the these values every release with necessary data changes.
\r
44 // Some test case data is current date/tzdata version sensitive and producing errors
\r
45 // when year/rule are changed.
\r
46 static final int REFERENCE_YEAR = 2009;
\r
47 static final String REFERENCE_DATA_VERSION = "2009d";
\r
51 public static void main(String[] args) throws Exception {
\r
52 new TimeZoneTest().run(args);
\r
56 * NOTE: As of ICU 2.8, the mapping of 3-letter legacy aliases
\r
57 * to `real' Olson IDs is under control of the underlying JDK.
\r
58 * This test may fail on one JDK and pass on another; don't be
\r
59 * too concerned. Alan
\r
62 * Certain short zone IDs, used since 1.1.x, are incorrect.
\r
64 * The worst of these is:
\r
66 * "CAT" (Central African Time) should be GMT+2:00, but instead returns a
\r
67 * zone at GMT-1:00. The zone at GMT-1:00 should be called EGT, CVT, EGST,
\r
68 * or AZOST, depending on which zone is meant, but in no case is it CAT.
\r
70 * Other wrong zone IDs:
\r
72 * ECT (European Central Time) GMT+1:00: ECT is Ecuador Time,
\r
73 * GMT-5:00. European Central time is abbreviated CEST.
\r
75 * SST (Solomon Island Time) GMT+11:00. SST is actually Samoa Standard Time,
\r
76 * GMT-11:00. Solomon Island time is SBT.
\r
78 * NST (New Zealand Time) GMT+12:00. NST is the abbreviation for
\r
79 * Newfoundland Standard Time, GMT-3:30. New Zealanders use NZST.
\r
81 * AST (Alaska Standard Time) GMT-9:00. [This has already been noted in
\r
82 * another bug.] It should be "AKST". AST is Atlantic Standard Time,
\r
85 * PNT (Phoenix Time) GMT-7:00. PNT usually means Pitcairn Time,
\r
86 * GMT-8:30. There is no standard abbreviation for Phoenix time, as distinct
\r
87 * from MST with daylight savings.
\r
89 * In addition to these problems, a number of zones are FAKE. That is, they
\r
90 * don't match what people use in the real world.
\r
94 * EET (should be EEST)
\r
95 * ART (should be EEST)
\r
96 * MET (should be IRST)
\r
97 * NET (should be AMST)
\r
98 * PLT (should be PKT)
\r
99 * BST (should be BDT)
\r
100 * VST (should be ICT)
\r
101 * CTT (should be CST) +
\r
102 * ACT (should be CST) +
\r
103 * AET (should be EST) +
\r
104 * MIT (should be WST) +
\r
105 * IET (should be EST) +
\r
106 * PRT (should be AST) +
\r
107 * CNT (should be NST)
\r
108 * AGT (should be ARST)
\r
109 * BET (should be EST) +
\r
111 * + A zone with the correct name already exists and means something
\r
112 * else. E.g., EST usually indicates the US Eastern zone, so it cannot be
\r
113 * used for Brazil (BET).
\r
115 public void TestShortZoneIDs() throws Exception {
\r
117 // This test case is tzdata version sensitive.
\r
118 boolean isNonReferenceTzdataVersion = false;
\r
119 String tzdataVer = TimeZone.getTZDataVersion();
\r
120 if (!tzdataVer.equals(REFERENCE_DATA_VERSION)) {
\r
121 // Note: We want to display a warning message here if
\r
122 // REFERENCE_DATA_VERSION is out of date - so we
\r
123 // do not forget to update the value before GA.
\r
124 isNonReferenceTzdataVersion = true;
\r
125 logln("Warning: Active tzdata version (" + tzdataVer +
\r
126 ") does not match the reference tzdata version ("
\r
127 + REFERENCE_DATA_VERSION + ") for this test case data.");
\r
130 // Note: If the default TimeZone type is JDK, some time zones
\r
131 // may differ from the test data below. For example, "MST" on
\r
132 // IBM JRE is an alias of "America/Denver" for supporting Java 1.1
\r
133 // backward compatibility, while Olson tzdata (and ICU) treat it
\r
134 // as -7hour fixed offset/no DST.
\r
135 boolean isJDKTimeZone = (TimeZone.getDefaultTimeZoneType() == TimeZone.TIMEZONE_JDK);
\r
136 if (isJDKTimeZone) {
\r
137 logln("Warning: Using JDK TimeZone. Some test cases may not return expected results.");
\r
140 // Note: useDaylightTime returns true if DST is observed
\r
141 // in the time zone in the current calendar year. The test
\r
142 // data is valid for the date after the reference year below.
\r
143 // If system clock is before the year, some test cases may
\r
145 GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("Etc/GMT"));
\r
146 cal.set(REFERENCE_YEAR, Calendar.JANUARY, 2); // day 2 in GMT
\r
148 boolean isDateBeforeReferenceYear = System.currentTimeMillis() < cal.getTimeInMillis();
\r
149 if (isDateBeforeReferenceYear) {
\r
150 logln("Warning: Past time is set to the system clock. Some test cases may not return expected results.");
\r
153 ZoneDescriptor[] REFERENCE_LIST = {
\r
154 new ZoneDescriptor("MIT", -660, false),
\r
155 new ZoneDescriptor("HST", -600, false),
\r
156 new ZoneDescriptor("AST", -540, true),
\r
157 new ZoneDescriptor("PST", -480, true),
\r
158 new ZoneDescriptor("PNT", -420, false),
\r
159 new ZoneDescriptor("MST", -420, false),// updated Aug 2003 aliu
\r
160 new ZoneDescriptor("CST", -360, true),
\r
161 new ZoneDescriptor("IET", -300, true), // updated Feb 2006 srl
\r
162 new ZoneDescriptor("EST", -300, false),// updated Aug 2003 aliu
\r
163 new ZoneDescriptor("PRT", -240, false),
\r
164 new ZoneDescriptor("CNT", -210, true),
\r
165 new ZoneDescriptor("AGT", -180, true), // updated by tzdata 2007k
\r
166 new ZoneDescriptor("BET", -180, true),
\r
167 new ZoneDescriptor("GMT", 0, false),
\r
168 new ZoneDescriptor("UTC", 0, false),
\r
169 new ZoneDescriptor("ECT", 60, true),
\r
170 new ZoneDescriptor("MET", 60, true),
\r
171 new ZoneDescriptor("CAT", 120, false), // Africa/Harare
\r
172 new ZoneDescriptor("ART", 120, true),
\r
173 new ZoneDescriptor("EET", 120, true),
\r
174 new ZoneDescriptor("EAT", 180, false),
\r
175 new ZoneDescriptor("NET", 240, true),
\r
176 new ZoneDescriptor("PLT", 300, false), // updated by tzdata 2008c - no DST after 2008
\r
177 new ZoneDescriptor("IST", 330, false),
\r
178 new ZoneDescriptor("BST", 360, false),
\r
179 new ZoneDescriptor("VST", 420, false),
\r
180 new ZoneDescriptor("CTT", 480, false), // updated Oct 2003 aliu
\r
181 new ZoneDescriptor("JST", 540, false),
\r
182 new ZoneDescriptor("ACT", 570, false), // updated Oct 2003 aliu
\r
183 new ZoneDescriptor("AET", 600, true),
\r
184 new ZoneDescriptor("SST", 660, false),
\r
185 new ZoneDescriptor("NST", 720, true), // Pacific/Auckland
\r
187 new ZoneDescriptor("Etc/Unknown", 0, false),
\r
188 new ZoneDescriptor("SystemV/AST4ADT", -240, true),
\r
189 new ZoneDescriptor("SystemV/EST5EDT", -300, true),
\r
190 new ZoneDescriptor("SystemV/CST6CDT", -360, true),
\r
191 new ZoneDescriptor("SystemV/MST7MDT", -420, true),
\r
192 new ZoneDescriptor("SystemV/PST8PDT", -480, true),
\r
193 new ZoneDescriptor("SystemV/YST9YDT", -540, true),
\r
194 new ZoneDescriptor("SystemV/AST4", -240, false),
\r
195 new ZoneDescriptor("SystemV/EST5", -300, false),
\r
196 new ZoneDescriptor("SystemV/CST6", -360, false),
\r
197 new ZoneDescriptor("SystemV/MST7", -420, false),
\r
198 new ZoneDescriptor("SystemV/PST8", -480, false),
\r
199 new ZoneDescriptor("SystemV/YST9", -540, false),
\r
200 new ZoneDescriptor("SystemV/HST10", -600, false),
\r
203 for (int i=0; i<REFERENCE_LIST.length; ++i) {
\r
204 ZoneDescriptor referenceZone = REFERENCE_LIST[i];
\r
205 ZoneDescriptor currentZone = new ZoneDescriptor(TimeZone.getTimeZone(referenceZone.getID()));
\r
206 if (referenceZone.equals(currentZone)) {
\r
207 logln("ok " + referenceZone);
\r
210 if (isNonReferenceTzdataVersion
\r
211 || isJDKTimeZone || isDateBeforeReferenceYear) {
\r
212 logln("Warning: Expected " + referenceZone +
\r
213 "; got " + currentZone);
\r
215 errln("Fail: Expected " + referenceZone +
\r
216 "; got " + currentZone);
\r
223 * A descriptor for a zone; used to regress the short zone IDs.
\r
225 static class ZoneDescriptor {
\r
227 int offset; // In minutes
\r
230 ZoneDescriptor(TimeZone zone) {
\r
231 this.id = zone.getID();
\r
232 this.offset = zone.getRawOffset() / 60000;
\r
233 this.daylight = zone.useDaylightTime();
\r
236 ZoneDescriptor(String id, int offset, boolean daylight) {
\r
238 this.offset = offset;
\r
239 this.daylight = daylight;
\r
242 public String getID() { return id; }
\r
244 public boolean equals(Object o) {
\r
245 ZoneDescriptor that = (ZoneDescriptor)o;
\r
246 return that != null &&
\r
247 id.equals(that.id) &&
\r
248 offset == that.offset &&
\r
249 daylight == that.daylight;
\r
252 public String toString() {
\r
255 if (min < 0) { sign = '-'; min = -min; }
\r
257 return "Zone[\"" + id + "\", GMT" + sign + (min/60) + ':' +
\r
258 (min%60<10?"0":"") + (min%60) + ", " +
\r
259 (daylight ? "Daylight" : "Standard") + "]";
\r
262 public static int compare(Object o1, Object o2) {
\r
263 ZoneDescriptor i1 = (ZoneDescriptor)o1;
\r
264 ZoneDescriptor i2 = (ZoneDescriptor)o2;
\r
265 if (i1.offset > i2.offset) return 1;
\r
266 if (i1.offset < i2.offset) return -1;
\r
267 if (i1.daylight && !i2.daylight) return 1;
\r
268 if (!i1.daylight && i2.daylight) return -1;
\r
269 return i1.id.compareTo(i2.id);
\r
274 * As part of the VM fix (see CCC approved RFE 4028006, bug
\r
275 * 4044013), TimeZone.getTimeZone() has been modified to recognize
\r
276 * generic IDs of the form GMT[+-]hh:mm, GMT[+-]hhmm, and
\r
277 * GMT[+-]hh. Test this behavior here.
\r
281 public void TestCustomParse() {
\r
283 // ID offset(sec) output ID
\r
284 "GMT", "0", "GMT", // system ID
\r
285 "GMT-YOUR.AD.HERE", "0", "GMT",
\r
286 "GMT0", "0", "GMT0", // system ID
\r
287 "GMT+0", "0", "GMT+0", // system ID
\r
288 "GMT+1", "3600", "GMT+01:00",
\r
289 "GMT-0030", "-1800", "GMT-00:30",
\r
290 "GMT+15:99", "0", "GMT",
\r
291 "GMT+", "0", "GMT",
\r
292 "GMT-", "0", "GMT",
\r
293 "GMT+0:", "0", "GMT",
\r
294 "GMT-:", "0", "GMT",
\r
295 "GMT+0010", "600", "GMT+00:10",
\r
296 "GMT-10", "-36000", "GMT-10:00",
\r
297 "GMT+30", "0", "GMT",
\r
298 "GMT-3:30", "-12600", "GMT-03:30",
\r
299 "GMT-230", "-9000", "GMT-02:30",
\r
300 "GMT+05:13:05", "18785", "GMT+05:13:05",
\r
301 "GMT-71023", "-25823", "GMT-07:10:23",
\r
302 "GMT+01:23:45:67", "0", "GMT",
\r
303 "GMT+01:234", "0", "GMT",
\r
304 "GMT-2:31:123", "0", "GMT",
\r
305 "GMT+3:75", "0", "GMT",
\r
306 "GMT-01010101", "0", "GMT",
\r
308 for (int i = 0; i < DATA.length; i += 3) {
\r
309 String id = DATA[i];
\r
310 int offset = Integer.parseInt(DATA[i+1]);
\r
311 String expId = DATA[i+2];
\r
313 TimeZone zone = TimeZone.getTimeZone(id);
\r
314 String gotID = zone.getID();
\r
315 int gotOffset = zone.getRawOffset()/1000;
\r
317 logln(id + " -> " + gotID + " " + gotOffset);
\r
319 if (offset != gotOffset) {
\r
320 errln("FAIL: Unexpected offset for " + id + " - returned:" + gotOffset + " expected:" + offset);
\r
322 if (!expId.equals(gotID)) {
\r
323 if (TimeZone.getDefaultTimeZoneType() != TimeZone.TIMEZONE_ICU) {
\r
324 logln("ID for " + id + " - returned:" + gotID + " expected:" + expId);
\r
326 errln("FAIL: Unexpected ID for " + id + " - returned:" + gotID + " expected:" + expId);
\r
333 * Test the basic functionality of the getDisplayName() API.
\r
338 * See also API change request A41.
\r
340 * 4/21/98 - make smarter, so the test works if the ext resources
\r
341 * are present or not.
\r
343 public void TestDisplayName() {
\r
344 TimeZone zone = TimeZone.getTimeZone("PST");
\r
345 String name = zone.getDisplayName(Locale.ENGLISH);
\r
346 logln("PST->" + name);
\r
348 // dlf - we now (3.4.1) return generic time
\r
349 if (!name.equals("Pacific Time"))
\r
350 errln("Fail: Expected \"Pacific Time\", got " + name +
\r
353 //*****************************************************************
\r
354 // THE FOLLOWING LINES MUST BE UPDATED IF THE LOCALE DATA CHANGES
\r
355 // THE FOLLOWING LINES MUST BE UPDATED IF THE LOCALE DATA CHANGES
\r
356 // THE FOLLOWING LINES MUST BE UPDATED IF THE LOCALE DATA CHANGES
\r
357 //*****************************************************************
\r
359 // todo: check to see whether we can test for all of pst, pdt, pt
\r
361 Boolean.FALSE, new Integer(TimeZone.SHORT), "PST",
\r
362 Boolean.TRUE, new Integer(TimeZone.SHORT), "PDT",
\r
363 Boolean.FALSE, new Integer(TimeZone.LONG), "Pacific Standard Time",
\r
364 Boolean.TRUE, new Integer(TimeZone.LONG), "Pacific Daylight Time",
\r
367 for (int i=0; i<DATA.length; i+=3) {
\r
368 name = zone.getDisplayName(((Boolean)DATA[i]).booleanValue(),
\r
369 ((Integer)DATA[i+1]).intValue(),
\r
371 if (!name.equals(DATA[i+2]))
\r
372 errln("Fail: Expected " + DATA[i+2] + "; got " + name);
\r
375 // Make sure that we don't display the DST name by constructing a fake
\r
376 // PST zone that has DST all year long.
\r
377 // dlf - this test is no longer relevant, we display generic time now
\r
378 // so the behavior of the timezone doesn't matter
\r
379 SimpleTimeZone zone2 = new SimpleTimeZone(0, "PST");
\r
380 zone2.setStartRule(Calendar.JANUARY, 1, 0);
\r
381 zone2.setEndRule(Calendar.DECEMBER, 31, 86399999);
\r
382 logln("Modified PST inDaylightTime->" + zone2.inDaylightTime(new Date()));
\r
383 name = zone2.getDisplayName(Locale.ENGLISH);
\r
384 logln("Modified PST->" + name);
\r
385 if (!name.equals("Pacific Time"))
\r
386 errln("Fail: Expected \"Pacific Time\"");
\r
388 // Make sure we get the default display format for Locales
\r
389 // with no display name data.
\r
390 Locale mt_MT = new Locale("mt", "MT");
\r
391 name = zone.getDisplayName(mt_MT);
\r
392 //*****************************************************************
\r
393 // THE FOLLOWING LINE MUST BE UPDATED IF THE LOCALE DATA CHANGES
\r
394 // THE FOLLOWING LINE MUST BE UPDATED IF THE LOCALE DATA CHANGES
\r
395 // THE FOLLOWING LINE MUST BE UPDATED IF THE LOCALE DATA CHANGES
\r
396 //*****************************************************************
\r
397 logln("PST(mt_MT)->" + name);
\r
399 // Now be smart -- check to see if zh resource is even present.
\r
400 // If not, we expect the en fallback behavior.
\r
402 // in icu4j 2.1 we know we have the zh_CN locale data, though it's incomplete
\r
403 // /"DateFormatZoneData",
\r
404 UResourceBundle enRB = UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME,Locale.ENGLISH);
\r
405 UResourceBundle mtRB = UResourceBundle.getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, mt_MT);
\r
406 boolean noZH = enRB == mtRB;
\r
409 logln("Warning: Not testing the mt_MT behavior because resource is absent");
\r
410 if (!name.equals("Pacific Standard Time"))
\r
411 errln("Fail: Expected Pacific Standard Time for PST in mt_MT but got ");
\r
413 // dlf - we will use generic time, or if unavailable, GMT for standard time in the zone
\r
414 // - we now (3.4.1) have localizations for this zone, so change test string
\r
415 else if(!name.equals("Stati Uniti (Los Angeles)") &&
\r
416 !name.equals("GMT-08:00") &&
\r
417 !name.equals("GMT-8:00") &&
\r
418 !name.equals("GMT-0800") &&
\r
419 !name.equals("GMT-800")) {
\r
421 errln("Fail: got '" + name + "', expected GMT-08:00 or something similar\n" +
\r
422 "************************************************************\n" +
\r
423 "THE ABOVE FAILURE MAY JUST MEAN THE LOCALE DATA HAS CHANGED\n" +
\r
424 "************************************************************");
\r
427 // Now try a non-existent zone
\r
428 zone2 = new SimpleTimeZone(90*60*1000, "xyzzy");
\r
429 name = zone2.getDisplayName(Locale.ENGLISH);
\r
430 logln("GMT+90min->" + name);
\r
431 if (!name.equals("GMT+01:30") &&
\r
432 !name.equals("GMT+1:30") &&
\r
433 !name.equals("GMT+0130") &&
\r
434 !name.equals("GMT+130"))
\r
435 errln("Fail: Expected GMT+01:30 or something similar");
\r
437 // cover getDisplayName() - null arg
\r
438 ULocale save = ULocale.getDefault();
\r
439 ULocale.setDefault(ULocale.US);
\r
440 name = zone2.getDisplayName();
\r
441 logln("GMT+90min->" + name + "for default display locale");
\r
442 if (!name.equals("GMT+01:30") &&
\r
443 !name.equals("GMT+1:30") &&
\r
444 !name.equals("GMT+0130") &&
\r
445 !name.equals("GMT+130"))
\r
446 errln("Fail: Expected GMT+01:30 or something similar");
\r
447 ULocale.setDefault(save);
\r
451 public void TestDisplayName2() {
\r
452 Date now = new Date();
\r
454 String[] timezones = {"America/Chicago", "Europe/Moscow", "Europe/Rome", "Asia/Shanghai", "WET" };
\r
455 String[] locales = {"en", "fr", "de", "ja", "zh_TW", "zh_Hans" };
\r
456 for (int j = 0; j < locales.length; ++j) {
\r
457 ULocale locale = new ULocale(locales[j]);
\r
458 for (int i = 0; i < timezones.length; ++i) {
\r
459 TimeZone tz = TimeZone.getTimeZone(timezones[i]);
\r
460 String displayName0 = tz.getDisplayName(locale); // doesn't work???
\r
461 SimpleDateFormat dt = new SimpleDateFormat("vvvv", locale);
\r
462 dt.setTimeZone(tz);
\r
463 String displayName1 = dt.format(now); // date value _does_ matter if we fallback to GMT
\r
464 logln(locale.getDisplayName() + ", " + tz.getID() + ": " + displayName0);
\r
465 if (!displayName1.equals(displayName0)) {
\r
466 errln(locale.getDisplayName() + ", " + tz.getID() +
\r
467 ": expected " + displayName1 + " but got: " + displayName0);
\r
473 public void TestGenericAPI() {
\r
474 String id = "NewGMT";
\r
475 int offset = 12345;
\r
477 SimpleTimeZone zone = new SimpleTimeZone(offset, id);
\r
478 if (zone.useDaylightTime()) errln("FAIL: useDaylightTime should return false");
\r
480 TimeZone zoneclone = (TimeZone)zone.clone();
\r
481 if (!zoneclone.equals(zone)) errln("FAIL: clone or operator== failed");
\r
482 zoneclone.setID("abc");
\r
483 if (zoneclone.equals(zone)) errln("FAIL: clone or operator!= failed");
\r
484 // delete zoneclone;
\r
486 zoneclone = (TimeZone)zone.clone();
\r
487 if (!zoneclone.equals(zone)) errln("FAIL: clone or operator== failed");
\r
488 zoneclone.setRawOffset(45678);
\r
489 if (zoneclone.equals(zone)) errln("FAIL: clone or operator!= failed");
\r
493 SimpleTimeZone copy(*zone);
\r
494 if (!(copy == *zone)) errln("FAIL: copy constructor or operator== failed");
\r
495 copy = *(SimpleTimeZone*)zoneclone;
\r
496 if (!(copy == *zoneclone)) errln("FAIL: assignment operator or operator== failed");
\r
499 TimeZone saveDefault = TimeZone.getDefault();
\r
500 TimeZone.setDefault(zone);
\r
501 TimeZone defaultzone = TimeZone.getDefault();
\r
502 if (defaultzone == zone) errln("FAIL: Default object is identical, not clone");
\r
503 if (!defaultzone.equals(zone)) errln("FAIL: Default object is not equal");
\r
504 TimeZone.setDefault(saveDefault);
\r
505 // delete defaultzone;
\r
506 // delete zoneclone;
\r
508 // // ICU 2.6 Coverage
\r
509 // logln(zone.toString());
\r
510 // logln(zone.getDisplayName());
\r
511 // SimpleTimeZoneAdapter stza = new SimpleTimeZoneAdapter((SimpleTimeZone) TimeZone.getTimeZone("GMT"));
\r
512 // stza.setID("Foo");
\r
513 // if (stza.hasSameRules(java.util.TimeZone.getTimeZone("GMT"))) {
\r
514 // errln("FAIL: SimpleTimeZoneAdapter.hasSameRules");
\r
516 // stza.setRawOffset(3000);
\r
517 // offset = stza.getOffset(GregorianCalendar.BC, 2001, Calendar.DECEMBER,
\r
518 // 25, Calendar.TUESDAY, 12*60*60*1000);
\r
519 // if (offset != 3000) {
\r
520 // errln("FAIL: SimpleTimeZoneAdapter.getOffset");
\r
522 // SimpleTimeZoneAdapter dup = (SimpleTimeZoneAdapter) stza.clone();
\r
523 // if (stza.hashCode() != dup.hashCode()) {
\r
524 // errln("FAIL: SimpleTimeZoneAdapter.hashCode");
\r
526 // if (!stza.equals(dup)) {
\r
527 // errln("FAIL: SimpleTimeZoneAdapter.equals");
\r
529 // logln(stza.toString());
\r
531 String tzver = TimeZone.getTZDataVersion();
\r
532 if (tzver.length() != 5 /* 4 digits + 1 letter */) {
\r
533 errln("FAIL: getTZDataVersion returned " + tzver);
\r
535 logln("PASS: tzdata version: " + tzver);
\r
539 public void TestRuleAPI()
\r
541 // ErrorCode status = ZERO_ERROR;
\r
543 int offset = (int)(60*60*1000*1.75); // Pick a weird offset
\r
544 SimpleTimeZone zone = new SimpleTimeZone(offset, "TestZone");
\r
545 if (zone.useDaylightTime()) errln("FAIL: useDaylightTime should return false");
\r
547 // Establish our expected transition times. Do this with a non-DST
\r
548 // calendar with the (above) declared local offset.
\r
549 GregorianCalendar gc = new GregorianCalendar(zone);
\r
551 gc.set(1990, Calendar.MARCH, 1);
\r
552 long marchOneStd = gc.getTime().getTime(); // Local Std time midnight
\r
554 gc.set(1990, Calendar.JULY, 1);
\r
555 long julyOneStd = gc.getTime().getTime(); // Local Std time midnight
\r
557 // Starting and ending hours, WALL TIME
\r
558 int startHour = (int)(2.25 * 3600000);
\r
559 int endHour = (int)(3.5 * 3600000);
\r
561 zone.setStartRule(Calendar.MARCH, 1, 0, startHour);
\r
562 zone.setEndRule (Calendar.JULY, 1, 0, endHour);
\r
564 gc = new GregorianCalendar(zone);
\r
565 // if (failure(status, "new GregorianCalendar")) return;
\r
567 long marchOne = marchOneStd + startHour;
\r
568 long julyOne = julyOneStd + endHour - 3600000; // Adjust from wall to Std time
\r
570 long expMarchOne = 636251400000L;
\r
571 if (marchOne != expMarchOne)
\r
573 errln("FAIL: Expected start computed as " + marchOne +
\r
574 " = " + new Date(marchOne));
\r
575 logln(" Should be " + expMarchOne +
\r
576 " = " + new Date(expMarchOne));
\r
579 long expJulyOne = 646793100000L;
\r
580 if (julyOne != expJulyOne)
\r
582 errln("FAIL: Expected start computed as " + julyOne +
\r
583 " = " + new Date(julyOne));
\r
584 logln(" Should be " + expJulyOne +
\r
585 " = " + new Date(expJulyOne));
\r
588 Calendar cal1 = Calendar.getInstance();
\r
589 cal1.set(1990, Calendar.JANUARY, 1);
\r
590 Calendar cal2 = Calendar.getInstance();
\r
591 cal2.set(1990, Calendar.JUNE, 1);
\r
592 _testUsingBinarySearch(zone, cal1.getTimeInMillis(),
\r
593 cal2.getTimeInMillis(), marchOne);
\r
594 cal1.set(1990, Calendar.JUNE, 1);
\r
595 cal2.set(1990, Calendar.DECEMBER, 31);
\r
596 _testUsingBinarySearch(zone, cal1.getTimeInMillis(),
\r
597 cal2.getTimeInMillis(), julyOne);
\r
599 if (zone.inDaylightTime(new Date(marchOne - 1000)) ||
\r
600 !zone.inDaylightTime(new Date(marchOne)))
\r
601 errln("FAIL: Start rule broken");
\r
602 if (!zone.inDaylightTime(new Date(julyOne - 1000)) ||
\r
603 zone.inDaylightTime(new Date(julyOne)))
\r
604 errln("FAIL: End rule broken");
\r
606 zone.setStartYear(1991);
\r
607 if (zone.inDaylightTime(new Date(marchOne)) ||
\r
608 zone.inDaylightTime(new Date(julyOne - 1000)))
\r
609 errln("FAIL: Start year broken");
\r
611 // failure(status, "TestRuleAPI");
\r
616 void _testUsingBinarySearch(SimpleTimeZone tz, long min, long max, long expectedBoundary)
\r
618 // ErrorCode status = ZERO_ERROR;
\r
619 boolean startsInDST = tz.inDaylightTime(new Date(min));
\r
620 // if (failure(status, "SimpleTimeZone::inDaylightTime")) return;
\r
621 if (tz.inDaylightTime(new Date(max)) == startsInDST) {
\r
622 logln("Error: inDaylightTime(" + new Date(max) + ") != " + (!startsInDST));
\r
625 // if (failure(status, "SimpleTimeZone::inDaylightTime")) return;
\r
626 while ((max - min) > INTERVAL) {
\r
627 long mid = (min + max) / 2;
\r
628 if (tz.inDaylightTime(new Date(mid)) == startsInDST) {
\r
634 // if (failure(status, "SimpleTimeZone::inDaylightTime")) return;
\r
636 logln("Binary Search Before: " + min + " = " + new Date(min));
\r
637 logln("Binary Search After: " + max + " = " + new Date(max));
\r
638 long mindelta = expectedBoundary - min;
\r
639 // not used long maxdelta = max - expectedBoundary;
\r
640 if (mindelta >= 0 &&
\r
641 mindelta <= INTERVAL &&
\r
643 mindelta <= INTERVAL)
\r
644 logln("PASS: Expected bdry: " + expectedBoundary + " = " + new Date(expectedBoundary));
\r
646 errln("FAIL: Expected bdry: " + expectedBoundary + " = " + new Date(expectedBoundary));
\r
649 static final int INTERVAL = 100;
\r
651 // Bug 006; verify the offset for a specific zone.
\r
652 public void TestPRTOffset()
\r
654 TimeZone tz = TimeZone.getTimeZone( "PRT" );
\r
656 errln( "FAIL: TimeZone(PRT) is null" );
\r
659 if (tz.getRawOffset() != (-4*millisPerHour))
\r
660 warnln("FAIL: Offset for PRT should be -4, got " +
\r
661 tz.getRawOffset() / (double)millisPerHour);
\r
666 // Test various calls
\r
667 public void TestVariousAPI518()
\r
669 TimeZone time_zone = TimeZone.getTimeZone("PST");
\r
670 Calendar cal = Calendar.getInstance();
\r
671 cal.set(1997, Calendar.APRIL, 30);
\r
672 Date d = cal.getTime();
\r
674 logln("The timezone is " + time_zone.getID());
\r
676 if (time_zone.inDaylightTime(d) != true)
\r
677 errln("FAIL: inDaylightTime returned false");
\r
679 if (time_zone.useDaylightTime() != true)
\r
680 errln("FAIL: useDaylightTime returned false");
\r
682 if (time_zone.getRawOffset() != -8*millisPerHour)
\r
683 errln( "FAIL: getRawOffset returned wrong value");
\r
685 GregorianCalendar gc = new GregorianCalendar();
\r
687 if (time_zone.getOffset(GregorianCalendar.AD, gc.get(GregorianCalendar.YEAR), gc.get(GregorianCalendar.MONTH),
\r
688 gc.get(GregorianCalendar.DAY_OF_MONTH),
\r
689 gc.get(GregorianCalendar.DAY_OF_WEEK), 0)
\r
690 != -7*millisPerHour)
\r
691 errln("FAIL: getOffset returned wrong value");
\r
694 // Test getAvailableID API
\r
695 public void TestGetAvailableIDs913()
\r
697 StringBuffer buf = new StringBuffer("TimeZone.getAvailableIDs() = { ");
\r
698 String[] s = TimeZone.getAvailableIDs();
\r
699 for (int i=0; i<s.length; ++i)
\r
701 if (i > 0) buf.append(", ");
\r
705 logln(buf.toString());
\r
708 buf.append("TimeZone.getAvailableIDs(GMT+02:00) = { ");
\r
709 s = TimeZone.getAvailableIDs(+2 * 60 * 60 * 1000);
\r
710 for (int i=0; i<s.length; ++i)
\r
712 if (i > 0) buf.append(", ");
\r
716 logln(buf.toString());
\r
718 TimeZone tz = TimeZone.getTimeZone("PST");
\r
720 logln("getTimeZone(PST) = " + tz.getID());
\r
722 errln("FAIL: getTimeZone(PST) = null");
\r
724 tz = TimeZone.getTimeZone("America/Los_Angeles");
\r
726 logln("getTimeZone(America/Los_Angeles) = " + tz.getID());
\r
728 errln("FAIL: getTimeZone(PST) = null");
\r
731 tz = TimeZone.getTimeZone("NON_EXISTENT");
\r
733 errln("FAIL: getTimeZone(NON_EXISTENT) = null");
\r
734 else if (!tz.getID().equals("GMT"))
\r
735 errln("FAIL: getTimeZone(NON_EXISTENT) = " + tz.getID());
\r
741 public void TestDSTSavings() {
\r
742 // It might be better to find a way to integrate this test into the main TimeZone
\r
743 // tests above, but I don't have time to figure out how to do this (or if it's
\r
744 // even really a good idea). Let's consider that a future. --rtg 1/27/98
\r
745 SimpleTimeZone tz = new SimpleTimeZone(-5 * millisPerHour, "dstSavingsTest",
\r
746 Calendar.MARCH, 1, 0, 0, Calendar.SEPTEMBER, 1, 0, 0,
\r
747 (int)(0.5 * millisPerHour));
\r
749 if (tz.getRawOffset() != -5 * millisPerHour)
\r
750 errln("Got back a raw offset of " + (tz.getRawOffset() / millisPerHour) +
\r
751 " hours instead of -5 hours.");
\r
752 if (!tz.useDaylightTime())
\r
753 errln("Test time zone should use DST but claims it doesn't.");
\r
754 if (tz.getDSTSavings() != 0.5 * millisPerHour)
\r
755 errln("Set DST offset to 0.5 hour, but got back " + (tz.getDSTSavings() /
\r
756 millisPerHour) + " hours instead.");
\r
758 int offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.JANUARY, 1,
\r
759 Calendar.THURSDAY, 10 * millisPerHour);
\r
760 if (offset != -5 * millisPerHour)
\r
761 errln("The offset for 10 AM, 1/1/98 should have been -5 hours, but we got "
\r
762 + (offset / millisPerHour) + " hours.");
\r
764 offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.JUNE, 1, Calendar.MONDAY,
\r
765 10 * millisPerHour);
\r
766 if (offset != -4.5 * millisPerHour)
\r
767 errln("The offset for 10 AM, 6/1/98 should have been -4.5 hours, but we got "
\r
768 + (offset / millisPerHour) + " hours.");
\r
770 tz.setDSTSavings(millisPerHour);
\r
771 offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.JANUARY, 1,
\r
772 Calendar.THURSDAY, 10 * millisPerHour);
\r
773 if (offset != -5 * millisPerHour)
\r
774 errln("The offset for 10 AM, 1/1/98 should have been -5 hours, but we got "
\r
775 + (offset / millisPerHour) + " hours.");
\r
777 offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.JUNE, 1, Calendar.MONDAY,
\r
778 10 * millisPerHour);
\r
779 if (offset != -4 * millisPerHour)
\r
780 errln("The offset for 10 AM, 6/1/98 (with a 1-hour DST offset) should have been -4 hours, but we got "
\r
781 + (offset / millisPerHour) + " hours.");
\r
787 public void TestAlternateRules() {
\r
788 // Like TestDSTSavings, this test should probably be integrated somehow with the main
\r
789 // test at the top of this class, but I didn't have time to figure out how to do that.
\r
792 SimpleTimeZone tz = new SimpleTimeZone(-5 * millisPerHour, "alternateRuleTest");
\r
794 // test the day-of-month API
\r
795 tz.setStartRule(Calendar.MARCH, 10, 12 * millisPerHour);
\r
796 tz.setEndRule(Calendar.OCTOBER, 20, 12 * millisPerHour);
\r
798 int offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.MARCH, 5,
\r
799 Calendar.THURSDAY, 10 * millisPerHour);
\r
800 if (offset != -5 * millisPerHour)
\r
801 errln("The offset for 10AM, 3/5/98 should have been -5 hours, but we got "
\r
802 + (offset / millisPerHour) + " hours.");
\r
804 offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.MARCH, 15,
\r
805 Calendar.SUNDAY, 10 * millisPerHour);
\r
806 if (offset != -4 * millisPerHour)
\r
807 errln("The offset for 10AM, 3/15/98 should have been -4 hours, but we got "
\r
808 + (offset / millisPerHour) + " hours.");
\r
810 offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.OCTOBER, 15,
\r
811 Calendar.THURSDAY, 10 * millisPerHour);
\r
812 if (offset != -4 * millisPerHour)
\r
813 errln("The offset for 10AM, 10/15/98 should have been -4 hours, but we got "
\r
814 + (offset / millisPerHour) + " hours.");
\r
816 offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.OCTOBER, 25,
\r
817 Calendar.SUNDAY, 10 * millisPerHour);
\r
818 if (offset != -5 * millisPerHour)
\r
819 errln("The offset for 10AM, 10/25/98 should have been -5 hours, but we got "
\r
820 + (offset / millisPerHour) + " hours.");
\r
822 // test the day-of-week-after-day-in-month API
\r
823 tz.setStartRule(Calendar.MARCH, 10, Calendar.FRIDAY, 12 * millisPerHour, true);
\r
824 tz.setEndRule(Calendar.OCTOBER, 20, Calendar.FRIDAY, 12 * millisPerHour, false);
\r
826 offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.MARCH, 11,
\r
827 Calendar.WEDNESDAY, 10 * millisPerHour);
\r
828 if (offset != -5 * millisPerHour)
\r
829 errln("The offset for 10AM, 3/11/98 should have been -5 hours, but we got "
\r
830 + (offset / millisPerHour) + " hours.");
\r
832 offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.MARCH, 14,
\r
833 Calendar.SATURDAY, 10 * millisPerHour);
\r
834 if (offset != -4 * millisPerHour)
\r
835 errln("The offset for 10AM, 3/14/98 should have been -4 hours, but we got "
\r
836 + (offset / millisPerHour) + " hours.");
\r
838 offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.OCTOBER, 15,
\r
839 Calendar.THURSDAY, 10 * millisPerHour);
\r
840 if (offset != -4 * millisPerHour)
\r
841 errln("The offset for 10AM, 10/15/98 should have been -4 hours, but we got "
\r
842 + (offset / millisPerHour) + " hours.");
\r
844 offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.OCTOBER, 17,
\r
845 Calendar.SATURDAY, 10 * millisPerHour);
\r
846 if (offset != -5 * millisPerHour)
\r
847 errln("The offset for 10AM, 10/17/98 should have been -5 hours, but we got "
\r
848 + (offset / millisPerHour) + " hours.");
\r
851 public void TestEquivalencyGroups() {
\r
852 String id = "America/Los_Angeles";
\r
853 int n = TimeZone.countEquivalentIDs(id);
\r
855 errln("FAIL: countEquivalentIDs(" + id + ") returned " + n +
\r
856 ", expected >= 2");
\r
858 for (int i=0; i<n; ++i) {
\r
859 String s = TimeZone.getEquivalentID(id, i);
\r
860 if (s.length() == 0) {
\r
861 errln("FAIL: getEquivalentID(" + id + ", " + i +
\r
862 ") returned \"" + s + "\", expected valid ID");
\r
864 logln("" + i + ":" + s);
\r
868 // JB#5480 - equivalent IDs should not be empty within range
\r
869 String[] ids = TimeZone.getAvailableIDs();
\r
870 for (int i = 0; i < ids.length; i++) {
\r
871 int nEquiv = TimeZone.countEquivalentIDs(ids[i]);
\r
872 // Each equivalent ID must not be empty
\r
873 for (int j = 0; j < nEquiv; j++) {
\r
874 String equivID = TimeZone.getEquivalentID(ids[i], j);
\r
875 if (equivID.length() == 0) {
\r
876 errln("FAIL: getEquivalentID(" + ids[i] + ", " + i +
\r
877 ") returned \"" + equivID + "\", expected valid ID");
\r
880 // equivalent ID out of range must be empty
\r
881 String outOfRangeID = TimeZone.getEquivalentID(ids[i], nEquiv);
\r
882 if (outOfRangeID.length() != 0) {
\r
883 errln("FAIL: getEquivalentID(" + ids[i] + ", " + i +
\r
884 ") returned \"" + outOfRangeID + "\", expected empty string");
\r
889 public void TestCountries() {
\r
890 // Make sure America/Los_Angeles is in the "US" group, and
\r
891 // Asia/Tokyo isn't. Vice versa for the "JP" group.
\r
893 String[] s = TimeZone.getAvailableIDs("US");
\r
894 boolean la = false, tokyo = false;
\r
895 String laZone = "America/Los_Angeles", tokyoZone = "Asia/Tokyo";
\r
897 for (int i=0; i<s.length; ++i) {
\r
898 if (s[i].equals(laZone)) {
\r
901 if (s[i].equals(tokyoZone)) {
\r
906 errln("FAIL: " + laZone + " in US = " + la);
\r
909 errln("FAIL: " + tokyoZone + " in US = " + tokyo);
\r
911 s = TimeZone.getAvailableIDs("JP");
\r
912 la = false; tokyo = false;
\r
914 for (int i=0; i<s.length; ++i) {
\r
915 if (s[i].equals(laZone)) {
\r
918 if (s[i].equals(tokyoZone)) {
\r
923 errln("FAIL: " + laZone + " in JP = " + la);
\r
926 errln("FAIL: " + tokyoZone + " in JP = " + tokyo);
\r
930 public void TestFractionalDST() {
\r
931 String tzName = "Australia/Lord_Howe"; // 30 min offset
\r
932 java.util.TimeZone tz_java = java.util.TimeZone.getTimeZone(tzName);
\r
935 // hack so test compiles and runs in both JDK 1.3 and JDK 1.4
\r
936 final Object[] args = new Object[0];
\r
937 final Class[] argtypes = new Class[0];
\r
938 java.lang.reflect.Method m = tz_java.getClass().getMethod("getDSTSavings", argtypes);
\r
939 dst_java = ((Integer) m.invoke(tz_java, args)).intValue();
\r
940 if (dst_java <= 0 || dst_java >= 3600000) { // didn't get the fractional time zone we wanted
\r
941 errln("didn't get fractional time zone!");
\r
943 } catch (NoSuchMethodException e) {
\r
944 // see JDKTimeZone for the reason for this code
\r
945 dst_java = 3600000;
\r
946 } catch (IllegalAccessException e) {
\r
947 // see JDKTimeZone for the reason for this code
\r
948 errln(e.getMessage());
\r
949 dst_java = 3600000;
\r
950 } catch (InvocationTargetException e) {
\r
951 // see JDKTimeZone for the reason for this code
\r
952 errln(e.getMessage());
\r
953 dst_java = 3600000;
\r
954 } catch (SecurityException e) {
\r
955 warnln(e.getMessage());
\r
959 com.ibm.icu.util.TimeZone tz_icu = com.ibm.icu.util.TimeZone.getTimeZone(tzName);
\r
960 int dst_icu = tz_icu.getDSTSavings();
\r
962 if (dst_java != dst_icu) {
\r
963 warnln("java reports dst savings of " + dst_java +
\r
964 " but icu reports " + dst_icu +
\r
965 " for tz " + tz_icu.getID());
\r
967 logln("both java and icu report dst savings of " + dst_java + " for tz " + tz_icu.getID());
\r
971 public void TestGetOffsetDate() {
\r
972 Calendar cal = Calendar.getInstance();
\r
973 cal.set(1997, Calendar.JANUARY, 30);
\r
974 long date = cal.getTimeInMillis();
\r
976 TimeZone tz_icu = TimeZone.getTimeZone("America/Los_Angeles");
\r
977 int offset = tz_icu.getOffset(date);
\r
978 if (offset != -28800000) {
\r
979 errln("expected offset -28800000, got: " + offset);
\r
982 cal.set(1997, Calendar.JULY, 30);
\r
983 date = cal.getTimeInMillis();
\r
984 offset = tz_icu.getOffset(date);
\r
985 if (offset != -25200000) {
\r
986 errln("expected offset -25200000, got: " + offset);
\r
991 public void TestSimpleTimeZoneSerialization()
\r
993 SimpleTimeZone stz0 = new SimpleTimeZone(32400000, "MyTimeZone");
\r
994 SimpleTimeZone stz1 = new SimpleTimeZone(32400000, "Asia/Tokyo");
\r
995 SimpleTimeZone stz2 = new SimpleTimeZone(32400000, "Asia/Tokyo");
\r
996 stz2.setRawOffset(0);
\r
997 SimpleTimeZone stz3 = new SimpleTimeZone(32400000, "Asia/Tokyo");
\r
998 stz3.setStartYear(100);
\r
999 SimpleTimeZone stz4 = new SimpleTimeZone(32400000, "Asia/Tokyo");
\r
1000 stz4.setStartYear(1000);
\r
1001 stz4.setDSTSavings(1800000);
\r
1002 stz4.setStartRule(3, 4, 180000);
\r
1003 stz4.setEndRule(6, 3, 4, 360000);
\r
1004 SimpleTimeZone stz5 = new SimpleTimeZone(32400000, "Asia/Tokyo");
\r
1005 stz5.setStartRule(2, 3, 4, 360000);
\r
1006 stz5.setEndRule(6, 3, 4, 360000);
\r
1008 SimpleTimeZone[] stzs = { stz0, stz1, stz2, stz3, stz4, stz5, };
\r
1010 for (int i = 0; i < stzs.length; ++i) {
\r
1011 SimpleTimeZone stz = stzs[i];
\r
1013 ByteArrayOutputStream baos = new ByteArrayOutputStream();
\r
1014 ObjectOutputStream oos = new ObjectOutputStream(baos);
\r
1015 oos.writeObject(stz);
\r
1017 byte[] bytes = baos.toByteArray();
\r
1018 logln("id: " + stz.getID() + " length: " + bytes.length);
\r
1020 ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
\r
1021 ObjectInputStream ois = new ObjectInputStream(bais);
\r
1023 SimpleTimeZone stzDeserialized = (SimpleTimeZone)ois.readObject();
\r
1026 assertEquals("time zones", stz, stzDeserialized);
\r
1028 catch (ClassCastException cce) {
\r
1029 cce.printStackTrace();
\r
1030 errln("could not deserialize SimpleTimeZone");
\r
1032 catch (IOException ioe) {
\r
1033 errln(ioe.getMessage());
\r
1035 catch (ClassNotFoundException cnfe) {
\r
1036 errln(cnfe.getMessage());
\r
1042 /* Generated by org.unicode.cldr.tool.CountItems */
\r
1043 private static final String[] timeZoneTestNames = {
\r
1044 "America/Argentina/Buenos_Aires", "America/Buenos_Aires",
\r
1045 "America/Argentina/Catamarca", "America/Catamarca",
\r
1046 "America/Argentina/Cordoba", "America/Cordoba",
\r
1047 "America/Argentina/Jujuy", "America/Jujuy",
\r
1048 "America/Argentina/Mendoza", "America/Mendoza",
\r
1049 "America/Atka", "America/Adak",
\r
1050 "America/Ensenada", "America/Tijuana",
\r
1051 "America/Fort_Wayne", "America/Indianapolis",
\r
1052 "America/Indiana/Indianapolis", "America/Indianapolis",
\r
1053 "America/Kentucky/Louisville", "America/Louisville",
\r
1054 "America/Knox_IN", "America/Indiana/Knox",
\r
1055 "America/Porto_Acre", "America/Rio_Branco",
\r
1056 "America/Rosario", "America/Cordoba",
\r
1057 "America/Virgin", "America/St_Thomas",
\r
1058 "Asia/Ashkhabad", "Asia/Ashgabat",
\r
1059 "Asia/Chungking", "Asia/Chongqing",
\r
1060 "Asia/Dacca", "Asia/Dhaka",
\r
1061 "Asia/Istanbul", "Europe/Istanbul",
\r
1062 "Asia/Macao", "Asia/Macau",
\r
1063 "Asia/Tel_Aviv", "Asia/Jerusalem",
\r
1064 "Asia/Thimbu", "Asia/Thimphu",
\r
1065 "Asia/Ujung_Pandang", "Asia/Makassar",
\r
1066 "Asia/Ulan_Bator", "Asia/Ulaanbaatar",
\r
1067 "Australia/ACT", "Australia/Sydney",
\r
1068 "Australia/Canberra", "Australia/Sydney",
\r
1069 "Australia/LHI", "Australia/Lord_Howe",
\r
1070 "Australia/NSW", "Australia/Sydney",
\r
1071 "Australia/North", "Australia/Darwin",
\r
1072 "Australia/Queensland", "Australia/Brisbane",
\r
1073 "Australia/South", "Australia/Adelaide",
\r
1074 "Australia/Tasmania", "Australia/Hobart",
\r
1075 "Australia/Victoria", "Australia/Melbourne",
\r
1076 "Australia/West", "Australia/Perth",
\r
1077 "Australia/Yancowinna", "Australia/Broken_Hill",
\r
1078 "Brazil/Acre", "America/Rio_Branco",
\r
1079 "Brazil/DeNoronha", "America/Noronha",
\r
1080 "Brazil/East", "America/Sao_Paulo",
\r
1081 "Brazil/West", "America/Manaus",
\r
1082 "CST6CDT", "America/Chicago",
\r
1083 "Canada/Atlantic", "America/Halifax",
\r
1084 "Canada/Central", "America/Winnipeg",
\r
1085 "Canada/East-Saskatchewan", "America/Regina",
\r
1086 "Canada/Eastern", "America/Toronto",
\r
1087 "Canada/Mountain", "America/Edmonton",
\r
1088 "Canada/Newfoundland", "America/St_Johns",
\r
1089 "Canada/Pacific", "America/Vancouver",
\r
1090 "Canada/Saskatchewan", "America/Regina",
\r
1091 "Canada/Yukon", "America/Whitehorse",
\r
1092 "Chile/Continental", "America/Santiago",
\r
1093 "Chile/EasterIsland", "Pacific/Easter",
\r
1094 "Cuba", "America/Havana",
\r
1095 "EST", "America/Indianapolis",
\r
1096 "EST5EDT", "America/New_York",
\r
1097 "Egypt", "Africa/Cairo",
\r
1098 "Eire", "Europe/Dublin",
\r
1099 "Etc/GMT+0", "Etc/GMT",
\r
1100 "Etc/GMT-0", "Etc/GMT",
\r
1101 "Etc/GMT0", "Etc/GMT",
\r
1102 "Etc/Greenwich", "Etc/GMT",
\r
1103 "Etc/UCT", "Etc/GMT",
\r
1104 "Etc/UTC", "Etc/GMT",
\r
1105 "Etc/Universal", "Etc/GMT",
\r
1106 "Etc/Zulu", "Etc/GMT",
\r
1107 "Europe/Nicosia", "Asia/Nicosia",
\r
1108 "Europe/Tiraspol", "Europe/Chisinau",
\r
1109 "GB", "Europe/London",
\r
1110 "GB-Eire", "Europe/London",
\r
1112 "GMT+0", "Etc/GMT",
\r
1113 "GMT-0", "Etc/GMT",
\r
1114 "GMT0", "Etc/GMT",
\r
1115 "Greenwich", "Etc/GMT",
\r
1116 "HST", "Pacific/Honolulu",
\r
1117 "Hongkong", "Asia/Hong_Kong",
\r
1118 "Iceland", "Atlantic/Reykjavik",
\r
1119 "Iran", "Asia/Tehran",
\r
1120 "Israel", "Asia/Jerusalem",
\r
1121 "Jamaica", "America/Jamaica",
\r
1122 "Japan", "Asia/Tokyo",
\r
1123 "Kwajalein", "Pacific/Kwajalein",
\r
1124 "Libya", "Africa/Tripoli",
\r
1125 "MST", "America/Phoenix",
\r
1126 "MST7MDT", "America/Denver",
\r
1127 "Mexico/BajaNorte", "America/Tijuana",
\r
1128 "Mexico/BajaSur", "America/Mazatlan",
\r
1129 "Mexico/General", "America/Mexico_City",
\r
1130 "NZ", "Pacific/Auckland",
\r
1131 "NZ-CHAT", "Pacific/Chatham",
\r
1132 "Navajo", "America/Shiprock", /* fixed from Mark's original */
\r
1133 "PRC", "Asia/Shanghai",
\r
1134 "PST8PDT", "America/Los_Angeles",
\r
1135 "Pacific/Samoa", "Pacific/Pago_Pago",
\r
1136 "Poland", "Europe/Warsaw",
\r
1137 "Portugal", "Europe/Lisbon",
\r
1138 "ROC", "Asia/Taipei",
\r
1139 "ROK", "Asia/Seoul",
\r
1140 "Singapore", "Asia/Singapore",
\r
1141 "SystemV/AST4", "America/Puerto_Rico",
\r
1142 "SystemV/AST4ADT", "America/Halifax",
\r
1143 "SystemV/CST6", "America/Regina",
\r
1144 "SystemV/CST6CDT", "America/Chicago",
\r
1145 "SystemV/EST5", "America/Indianapolis",
\r
1146 "SystemV/EST5EDT", "America/New_York",
\r
1147 "SystemV/HST10", "Pacific/Honolulu",
\r
1148 "SystemV/MST7", "America/Phoenix",
\r
1149 "SystemV/MST7MDT", "America/Denver",
\r
1150 "SystemV/PST8", "Pacific/Pitcairn",
\r
1151 "SystemV/PST8PDT", "America/Los_Angeles",
\r
1152 "SystemV/YST9", "Pacific/Gambier",
\r
1153 "SystemV/YST9YDT", "America/Anchorage",
\r
1154 "Turkey", "Europe/Istanbul",
\r
1156 "US/Alaska", "America/Anchorage",
\r
1157 "US/Aleutian", "America/Adak",
\r
1158 "US/Arizona", "America/Phoenix",
\r
1159 "US/Central", "America/Chicago",
\r
1160 "US/East-Indiana", "America/Indianapolis",
\r
1161 "US/Eastern", "America/New_York",
\r
1162 "US/Hawaii", "Pacific/Honolulu",
\r
1163 "US/Indiana-Starke", "America/Indiana/Knox",
\r
1164 "US/Michigan", "America/Detroit",
\r
1165 "US/Mountain", "America/Denver",
\r
1166 "US/Pacific", "America/Los_Angeles",
\r
1167 "US/Pacific-New", "America/Los_Angeles",
\r
1168 "US/Samoa", "Pacific/Pago_Pago",
\r
1170 "Universal", "Etc/GMT",
\r
1171 "W-SU", "Europe/Moscow",
\r
1172 "Zulu", "Etc/GMT",
\r
1175 public void TestOddTimeZoneNames() {
\r
1176 for (int i = 0; i < timeZoneTestNames.length; i += 2) {
\r
1177 String funkyName = timeZoneTestNames[i];
\r
1178 String correctName = timeZoneTestNames[i+1];
\r
1180 TimeZone ftz = TimeZone.getTimeZone(funkyName);
\r
1181 TimeZone ctz = TimeZone.getTimeZone(correctName);
\r
1183 String fdn = ftz.getDisplayName();
\r
1184 long fro = ftz.getRawOffset();
\r
1185 long fds = ftz.getDSTSavings();
\r
1186 boolean fdy = ftz.useDaylightTime();
\r
1188 String cdn = ctz.getDisplayName();
\r
1189 long cro = ctz.getRawOffset();
\r
1190 long cds = ctz.getDSTSavings();
\r
1191 boolean cdy = ctz.useDaylightTime();
\r
1193 if (!fdn.equals(cdn)) {
\r
1194 logln("display name (" + funkyName + ", " + correctName + ") expected: " + cdn + " but got: " + fdn);
\r
1195 } else if (fro != cro) {
\r
1196 logln("offset (" + funkyName + ", " + correctName + ") expected: " + cro + " but got: " + fro);
\r
1197 } else if (fds != cds) {
\r
1198 logln("daylight (" + funkyName + ", " + correctName + ") expected: " + cds + " but got: " + fds);
\r
1199 } else if (fdy != cdy) {
\r
1200 logln("uses daylight (" + funkyName + ", " + correctName + ") expected: " + cdy + " but got: " + fdy);
\r
1202 // no error, assume we're referencing the same internal java object
\r
1207 public void TestCoverage(){
\r
1208 class StubTimeZone extends TimeZone{
\r
1210 * For serialization
\r
1212 private static final long serialVersionUID = 8658654217433379343L;
\r
1213 public int getOffset(int era, int year, int month, int day, int dayOfWeek, int milliseconds) {return 0;}
\r
1214 public void setRawOffset(int offsetMillis) {}
\r
1215 public int getRawOffset() {return 0;}
\r
1216 public boolean useDaylightTime() {return false;}
\r
1217 public boolean inDaylightTime(Date date) {return false;}
\r
1219 StubTimeZone stub = new StubTimeZone();
\r
1220 StubTimeZone stub2 = (StubTimeZone) stub.clone();
\r
1221 if (stub.getDSTSavings() != 0){
\r
1222 errln("TimeZone.getDSTSavings() should return 0");
\r
1224 if (!stub.hasSameRules(stub2)){
\r
1225 errln("TimeZone.clone() object should hasSameRules");
\r
1229 public void TestMark(){
\r
1230 String tzid = "America/Argentina/ComodRivadavia";
\r
1231 TimeZone tz = TimeZone.getTimeZone(tzid);
\r
1232 int offset = tz.getOffset(new Date().getTime());
\r
1233 logln(tzid + ":\t" + offset);
\r
1234 List list = Arrays.asList(TimeZone.getAvailableIDs());
\r
1235 if(!list.contains(tzid)){
\r
1236 errln("Could create the time zone but it is not in getAvailableIDs");
\r
1239 public void TestZoneMeta() {
\r
1240 java.util.TimeZone save = java.util.TimeZone.getDefault();
\r
1241 java.util.TimeZone newZone = java.util.TimeZone.getTimeZone("GMT-08:00");
\r
1242 com.ibm.icu.util.TimeZone.setDefault(null);
\r
1243 java.util.TimeZone.setDefault(newZone);
\r
1244 SimpleTimeZone zone = new SimpleTimeZone(0, "GMT");
\r
1245 com.ibm.icu.util.TimeZone defaultZone = com.ibm.icu.util.TimeZone.getDefault();
\r
1246 if(defaultZone==null){
\r
1247 errln("TimeZone.getDefault() failed for GMT-08:00");
\r
1250 errln("SimpleTimeZone(0, GMT-08:00) failed for GMT-08:00");
\r
1253 java.util.TimeZone.setDefault(save);
\r
1256 // Copied from the protected constant in TimeZone.
\r
1257 private static final int MILLIS_PER_HOUR = 60*60*1000;
\r
1259 // Test that a transition at the end of February is handled correctly.
\r
1260 public void TestFebruary() {
\r
1261 // Time zone with daylight savings time from the first Sunday in November
\r
1262 // to the last Sunday in February.
\r
1263 // Similar to the new rule for Brazil (Sao Paulo) in tzdata2006n.
\r
1265 // Note: In tzdata2007h, the rule had changed, so no actual zones uses
\r
1266 // lastSun in Feb anymore.
\r
1267 SimpleTimeZone tz1 = new SimpleTimeZone(
\r
1268 -3 * MILLIS_PER_HOUR, // raw offset: 3h before (west of) GMT
\r
1270 Calendar.NOVEMBER, 1, Calendar.SUNDAY, // start: November, first, Sunday
\r
1271 0, // midnight wall time
\r
1272 Calendar.FEBRUARY, -1, Calendar.SUNDAY, // end: February, last, Sunday
\r
1273 0); // midnight wall time
\r
1275 // Now hardcode the same rules as for Brazil in tzdata 2006n, so that
\r
1276 // we cover the intended code even when in the future zoneinfo hardcodes
\r
1277 // these transition dates.
\r
1278 SimpleTimeZone tz2= new SimpleTimeZone(
\r
1279 -3 * MILLIS_PER_HOUR, // raw offset: 3h before (west of) GMT
\r
1281 Calendar.NOVEMBER, 1, -Calendar.SUNDAY, // start: November, 1 or after, Sunday
\r
1282 0, // midnight wall time
\r
1283 Calendar.FEBRUARY, -29, -Calendar.SUNDAY,// end: February, 29 or before, Sunday
\r
1284 0); // midnight wall time
\r
1286 // Gregorian calendar with the UTC time zone for getting sample test date/times.
\r
1287 GregorianCalendar gc = new GregorianCalendar(TimeZone.getTimeZone("Etc/GMT"));
\r
1288 // "Unable to create the UTC calendar: %s"
\r
1291 // UTC time (6 fields) followed by
\r
1292 // expected time zone offset in hours after GMT (negative=before GMT).
\r
1293 // int year, month, day, hour, minute, second, offsetHours
\r
1294 2006, Calendar.NOVEMBER, 5, 02, 59, 59, -3,
\r
1295 2006, Calendar.NOVEMBER, 5, 03, 00, 00, -2,
\r
1296 2007, Calendar.FEBRUARY, 25, 01, 59, 59, -2,
\r
1297 2007, Calendar.FEBRUARY, 25, 02, 00, 00, -3,
\r
1299 2007, Calendar.NOVEMBER, 4, 02, 59, 59, -3,
\r
1300 2007, Calendar.NOVEMBER, 4, 03, 00, 00, -2,
\r
1301 2008, Calendar.FEBRUARY, 24, 01, 59, 59, -2,
\r
1302 2008, Calendar.FEBRUARY, 24, 02, 00, 00, -3,
\r
1304 2008, Calendar.NOVEMBER, 2, 02, 59, 59, -3,
\r
1305 2008, Calendar.NOVEMBER, 2, 03, 00, 00, -2,
\r
1306 2009, Calendar.FEBRUARY, 22, 01, 59, 59, -2,
\r
1307 2009, Calendar.FEBRUARY, 22, 02, 00, 00, -3,
\r
1309 2009, Calendar.NOVEMBER, 1, 02, 59, 59, -3,
\r
1310 2009, Calendar.NOVEMBER, 1, 03, 00, 00, -2,
\r
1311 2010, Calendar.FEBRUARY, 28, 01, 59, 59, -2,
\r
1312 2010, Calendar.FEBRUARY, 28, 02, 00, 00, -3
\r
1315 TimeZone timezones[] = { tz1, tz2 };
\r
1319 int t, i, raw, dst;
\r
1320 int[] offsets = new int[2]; // raw = offsets[0], dst = offsets[1]
\r
1321 for (t = 0; t < timezones.length; ++t) {
\r
1322 tz = timezones[t];
\r
1323 for (i = 0; i < data.length; i+=7) {
\r
1324 gc.set(data[i], data[i+1], data[i+2],
\r
1325 data[i+3], data[i+4], data[i+5]);
\r
1326 dt = gc.getTime();
\r
1327 tz.getOffset(dt.getTime(), false, offsets);
\r
1330 if ((raw + dst) != data[i+6] * MILLIS_PER_HOUR) {
\r
1331 errln("test case " + t + "." + (i/7) + ": " +
\r
1332 "tz.getOffset(" + data[i] + "-" + (data[i+1] + 1) + "-" + data[i+2] + " " +
\r
1333 data[i+3] + ":" + data[i+4] + ":" + data[i+5] +
\r
1334 ") returns " + raw + "+" + dst + " != " + data[i+6] * MILLIS_PER_HOUR);
\r
1340 public void TestCanonicalID() {
\r
1341 // Some canonical IDs in CLDR are defined as "Link"
\r
1342 // in Olson tzdata.
\r
1343 final String[][] excluded1 = {
\r
1344 {"America/Shiprock", "America/Denver"}, // America/Shiprock is defined as a Link to America/Denver in tzdata
\r
1345 {"America/Marigot", "America/Guadeloupe"},
\r
1346 {"America/St_Barthelemy", "America/Guadeloupe"},
\r
1347 {"Antarctica/South_Pole", "Antarctica/McMurdo"},
\r
1348 {"Atlantic/Jan_Mayen", "Europe/Oslo"},
\r
1349 {"Arctic/Longyearbyen", "Europe/Oslo"},
\r
1350 {"Europe/Guernsey", "Europe/London"},
\r
1351 {"Europe/Isle_of_Man", "Europe/London"},
\r
1352 {"Europe/Jersey", "Europe/London"},
\r
1353 {"Europe/Ljubljana", "Europe/Belgrade"},
\r
1354 {"Europe/Podgorica", "Europe/Belgrade"},
\r
1355 {"Europe/Sarajevo", "Europe/Belgrade"},
\r
1356 {"Europe/Skopje", "Europe/Belgrade"},
\r
1357 {"Europe/Zagreb", "Europe/Belgrade"},
\r
1358 {"Europe/Bratislava", "Europe/Prague"},
\r
1359 {"Europe/Mariehamn", "Europe/Helsinki"},
\r
1360 {"Europe/San_Marino", "Europe/Rome"},
\r
1361 {"Europe/Vatican", "Europe/Rome"},
\r
1364 // Following IDs are aliases of Etc/GMT in CLDR,
\r
1365 // but Olson tzdata has 3 independent definitions
\r
1366 // for Etc/GMT, Etc/UTC, Etc/UCT.
\r
1367 // Until we merge them into one equivalent group
\r
1368 // in zoneinfo.res, we exclude them in the test
\r
1370 final String[] excluded2 = {
\r
1373 "Etc/Universal", "Universal",
\r
1374 "Etc/Zulu", "Zulu",
\r
1377 // Walk through equivalency groups
\r
1378 String[] ids = TimeZone.getAvailableIDs();
\r
1379 for (int i = 0; i < ids.length; i++) {
\r
1380 int nEquiv = TimeZone.countEquivalentIDs(ids[i]);
\r
1381 if (nEquiv == 0) {
\r
1384 String canonicalID = null;
\r
1385 boolean bFoundCanonical = false;
\r
1386 // Make sure getCanonicalID returns the exact same result
\r
1387 // for all entries within a same equivalency group with some
\r
1388 // exceptions listed in exluded1.
\r
1389 // Also, one of them must be canonical id.
\r
1390 for (int j = 0; j < nEquiv; j++) {
\r
1391 String tmp = TimeZone.getEquivalentID(ids[i], j);
\r
1392 String tmpCanonical = TimeZone.getCanonicalID(tmp);
\r
1393 if (tmpCanonical == null) {
\r
1394 errln("FAIL: getCanonicalID(\"" + tmp + "\") returned null");
\r
1397 // Some exceptional cases
\r
1398 for (int k = 0; k < excluded1.length; k++) {
\r
1399 if (tmpCanonical.equals(excluded1[k][0])) {
\r
1400 tmpCanonical = excluded1[k][1];
\r
1405 canonicalID = tmpCanonical;
\r
1406 } else if (!canonicalID.equals(tmpCanonical)) {
\r
1407 errln("FAIL: getCanonicalID(\"" + tmp + "\") returned " + tmpCanonical + " expected:" + canonicalID);
\r
1410 if (canonicalID.equals(tmp)) {
\r
1411 bFoundCanonical = true;
\r
1414 // At least one ID in an equvalency group must match the
\r
1416 if (!bFoundCanonical) {
\r
1417 // test exclusion because of differences between Olson tzdata and CLDR
\r
1418 boolean isExcluded = false;
\r
1419 for (int k = 0; k < excluded1.length; k++) {
\r
1420 if (ids[i].equals(excluded2[k])) {
\r
1421 isExcluded = true;
\r
1429 errln("FAIL: No timezone ids match the canonical ID " + canonicalID);
\r
1432 // Testing some special cases
\r
1433 final String[][] data = {
\r
1434 {"GMT-03", "GMT-03:00", null},
\r
1435 {"GMT+4", "GMT+04:00", null},
\r
1436 {"GMT-055", "GMT-00:55", null},
\r
1437 {"GMT+430", "GMT+04:30", null},
\r
1438 {"GMT-12:15", "GMT-12:15", null},
\r
1439 {"GMT-091015", "GMT-09:10:15", null},
\r
1440 {"GMT+1:90", null, null},
\r
1441 {"America/Argentina/Buenos_Aires", "America/Buenos_Aires", "true"},
\r
1442 {"bogus", null, null},
\r
1444 {null, null, null},
\r
1446 boolean[] isSystemID = new boolean[1];
\r
1447 for (int i = 0; i < data.length; i++) {
\r
1448 String canonical = TimeZone.getCanonicalID(data[i][0], isSystemID);
\r
1449 if (canonical != null && !canonical.equals(data[i][1])
\r
1450 || canonical == null && data[i][1] != null) {
\r
1451 errln("FAIL: getCanonicalID(\"" + data[i][0] + "\") returned " + canonical
\r
1452 + " - expected: " + data[i][1]);
\r
1454 if ("true".equalsIgnoreCase(data[i][2]) != isSystemID[0]) {
\r
1455 errln("FAIL: getCanonicalID(\"" + data[i][0] + "\") set " + isSystemID[0]
\r
1456 + " to isSystemID");
\r
1461 public void TestSetDefault() {
\r
1462 java.util.TimeZone save = java.util.TimeZone.getDefault();
\r
1465 * America/Caracs (Venezuela) changed the base offset from -4:00 to
\r
1466 * -4:30 on Dec 9, 2007.
\r
1469 TimeZone icuCaracas = TimeZone.getTimeZone("America/Caracas", TimeZone.TIMEZONE_ICU);
\r
1470 java.util.TimeZone jdkCaracas = java.util.TimeZone.getTimeZone("America/Caracas");
\r
1472 // Set JDK America/Caracas as the default
\r
1473 java.util.TimeZone.setDefault(jdkCaracas);
\r
1475 java.util.Calendar jdkCal = java.util.Calendar.getInstance();
\r
1477 jdkCal.set(2007, java.util.Calendar.JANUARY, 1);
\r
1479 int rawOffset = jdkCal.get(java.util.Calendar.ZONE_OFFSET);
\r
1480 int dstSavings = jdkCal.get(java.util.Calendar.DST_OFFSET);
\r
1482 int[] offsets = new int[2];
\r
1483 icuCaracas.getOffset(jdkCal.getTime().getTime()/*jdkCal.getTimeInMillis()*/, false, offsets);
\r
1485 boolean isTimeZoneSynchronized = true;
\r
1487 if (rawOffset != offsets[0] || dstSavings != offsets[1]) {
\r
1488 // JDK time zone rule is out of sync...
\r
1489 logln("Rule for JDK America/Caracas is not same with ICU. Skipping the rest.");
\r
1490 isTimeZoneSynchronized = false;
\r
1493 if (isTimeZoneSynchronized) {
\r
1494 // If JDK America/Caracas uses the same rule with ICU,
\r
1495 // the following code should work well.
\r
1496 TimeZone.setDefault(icuCaracas);
\r
1498 // Create a new JDK calendar instance again.
\r
1499 // This calendar should reflect the new default
\r
1500 // set by ICU TimeZone#setDefault.
\r
1501 jdkCal = java.util.Calendar.getInstance();
\r
1503 jdkCal.set(2007, java.util.Calendar.JANUARY, 1);
\r
1505 rawOffset = jdkCal.get(java.util.Calendar.ZONE_OFFSET);
\r
1506 dstSavings = jdkCal.get(java.util.Calendar.DST_OFFSET);
\r
1508 if (rawOffset != offsets[0] || dstSavings != offsets[1]) {
\r
1509 errln("ERROR: Got offset [raw:" + rawOffset + "/dst:" + dstSavings
\r
1510 + "] Expected [raw:" + offsets[0] + "/dst:" + offsets[1] + "]");
\r
1514 // Restore the original JDK time zone
\r
1515 java.util.TimeZone.setDefault(save);
\r
1519 * Test Display Names, choosing zones and lcoales where there are multiple
\r
1520 * meta-zones defined.
\r
1522 public void TestDisplayNamesMeta() {
\r
1523 final Integer TZSHORT = new Integer(TimeZone.SHORT);
\r
1524 final Integer TZLONG = new Integer(TimeZone.LONG);
\r
1526 final Object[][] zoneDisplayTestData = {
\r
1527 // zone id locale summer format expected display name
\r
1528 {"Europe/London", "en", Boolean.FALSE, TZSHORT, "GMT"},
\r
1529 {"Europe/London", "en", Boolean.FALSE, TZLONG, "Greenwich Mean Time"},
\r
1530 {"Europe/London", "en", Boolean.TRUE, TZSHORT, "GMT+01:00" /*"BST"*/},
\r
1531 {"Europe/London", "en", Boolean.TRUE, TZLONG, "British Summer Time"},
\r
1533 {"America/Anchorage", "en", Boolean.FALSE, TZSHORT, "AKST"},
\r
1534 {"America/Anchorage", "en", Boolean.FALSE, TZLONG, "Alaska Standard Time"},
\r
1535 {"America/Anchorage", "en", Boolean.TRUE, TZSHORT, "AKDT"},
\r
1536 {"America/Anchorage", "en", Boolean.TRUE, TZLONG, "Alaska Daylight Time"},
\r
1538 // Southern Hemisphere, all data from meta:Australia_Western
\r
1539 {"Australia/Perth", "en", Boolean.FALSE, TZSHORT, "GMT+08:00"/*"AWST"*/},
\r
1540 {"Australia/Perth", "en", Boolean.FALSE, TZLONG, "Australian Western Standard Time"},
\r
1541 {"Australia/Perth", "en", Boolean.TRUE, TZSHORT, "GMT+09:00"/*"AWDT"*/},
\r
1542 {"Australia/Perth", "en", Boolean.TRUE, TZLONG, "Australian Western Daylight Time"},
\r
1544 {"America/Sao_Paulo", "en", Boolean.FALSE, TZSHORT, "GMT-03:00"/*"BRT"*/},
\r
1545 {"America/Sao_Paulo", "en", Boolean.FALSE, TZLONG, "Brasilia Time"},
\r
1546 {"America/Sao_Paulo", "en", Boolean.TRUE, TZSHORT, "GMT-02:00"/*"BRST"*/},
\r
1547 {"America/Sao_Paulo", "en", Boolean.TRUE, TZLONG, "Brasilia Summer Time"},
\r
1549 // No Summer Time, but had it before 1983.
\r
1550 {"Pacific/Honolulu", "en", Boolean.FALSE, TZSHORT, "HST"},
\r
1551 {"Pacific/Honolulu", "en", Boolean.FALSE, TZLONG, "Hawaii-Aleutian Standard Time"},
\r
1552 {"Pacific/Honolulu", "en", Boolean.TRUE, TZSHORT, "HST"},
\r
1553 {"Pacific/Honolulu", "en", Boolean.TRUE, TZLONG, "Hawaii-Aleutian Standard Time"},
\r
1555 // Northern, has Summer, not commonly used.
\r
1556 {"Europe/Helsinki", "en", Boolean.FALSE, TZSHORT, "GMT+02:00"/*"EET"*/},
\r
1557 {"Europe/Helsinki", "en", Boolean.FALSE, TZLONG, "Eastern European Time"},
\r
1558 {"Europe/Helsinki", "en", Boolean.TRUE, TZSHORT, "GMT+03:00"/*"EEST"*/},
\r
1559 {"Europe/Helsinki", "en", Boolean.TRUE, TZLONG, "Eastern European Summer Time"},
\r
1561 // Repeating the test data for DST. The test data below trigger the problem reported
\r
1563 {"Europe/London", "en", Boolean.TRUE, TZSHORT, "GMT+01:00" /*"BST"*/},
\r
1564 {"Europe/London", "en", Boolean.TRUE, TZLONG, "British Summer Time"},
\r
1567 boolean isReferenceYear = true;
\r
1568 GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("Etc/GMT"));
\r
1569 if (cal.get(Calendar.YEAR) != REFERENCE_YEAR) {
\r
1570 isReferenceYear = false;
\r
1572 boolean isICUTimeZone = (TimeZone.getDefaultTimeZoneType() == TimeZone.TIMEZONE_ICU);
\r
1574 boolean sawAnError = false;
\r
1575 for (int testNum = 0; testNum < zoneDisplayTestData.length; testNum++) {
\r
1576 ULocale locale = new ULocale((String)zoneDisplayTestData[testNum][1]);
\r
1577 TimeZone zone = TimeZone.getTimeZone((String)zoneDisplayTestData[testNum][0]);
\r
1578 String displayName = zone.getDisplayName(((Boolean)zoneDisplayTestData[testNum][2]).booleanValue(),
\r
1579 ((Integer)zoneDisplayTestData[testNum][3]).intValue());
\r
1580 if (!displayName.equals(zoneDisplayTestData[testNum][4])) {
\r
1581 if (isReferenceYear
\r
1582 && (isICUTimeZone || !((Boolean)zoneDisplayTestData[testNum][2]).booleanValue())) {
\r
1583 sawAnError = true;
\r
1584 errln("Incorrect time zone display name. zone = "
\r
1585 + zoneDisplayTestData[testNum][0] + ",\n"
\r
1586 + " locale = " + locale
\r
1587 + ", style = " + (zoneDisplayTestData[testNum][3] == TZSHORT ? "SHORT" : "LONG")
\r
1588 + ", Summertime = " + zoneDisplayTestData[testNum][2] + "\n"
\r
1589 + " Expected " + zoneDisplayTestData[testNum][4]
\r
1590 + ", Got " + displayName);
\r
1592 logln("Incorrect time zone display name. zone = "
\r
1593 + zoneDisplayTestData[testNum][0] + ",\n"
\r
1594 + " locale = " + locale
\r
1595 + ", style = " + (zoneDisplayTestData[testNum][3] == TZSHORT ? "SHORT" : "LONG")
\r
1596 + ", Summertime = " + zoneDisplayTestData[testNum][2] + "\n"
\r
1597 + " Expected " + zoneDisplayTestData[testNum][4]
\r
1598 + ", Got " + displayName);
\r
1603 logln("Note: Errors could be the result of changes to zoneStrings locale data");
\r