1 /***********************************************************************
3 * Copyright (c) 1997-2004, International Business Machines Corporation
4 * and others. All Rights Reserved.
5 ***********************************************************************/
7 #include "unicode/utypes.h"
9 #if !UCONFIG_NO_FORMATTING
11 #include "unicode/timezone.h"
12 #include "unicode/simpletz.h"
13 #include "unicode/calendar.h"
14 #include "unicode/gregocal.h"
15 #include "unicode/resbund.h"
16 #include "unicode/strenum.h"
21 #define CASE(id,test) case id: \
24 logln(#test "---"); logln(""); \
29 // *****************************************************************************
31 // *****************************************************************************
33 void TimeZoneTest::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char* /*par*/ )
35 if (exec
) logln("TestSuite TestTimeZone");
37 CASE(0, TestPRTOffset
);
38 CASE(1, TestVariousAPI518
);
39 CASE(2, TestGetAvailableIDs913
);
40 CASE(3, TestGenericAPI
);
42 CASE(5, TestShortZoneIDs
);
43 CASE(6, TestCustomParse
);
44 CASE(7, TestDisplayName
);
45 CASE(8, TestDSTSavings
);
46 CASE(9, TestAlternateRules
);
47 CASE(10,TestCountries
);
48 CASE(11,TestHistorical
);
49 CASE(12,TestEquivalentIDs
);
50 default: name
= ""; break;
54 const int32_t TimeZoneTest::millisPerHour
= 3600000;
56 // ---------------------------------------------------------------------------------
59 * Generic API testing for API coverage.
62 TimeZoneTest::TestGenericAPI()
64 UnicodeString
id("NewGMT");
65 int32_t offset
= 12345;
67 SimpleTimeZone
*zone
= new SimpleTimeZone(offset
, id
);
68 if (zone
->useDaylightTime()) errln("FAIL: useDaylightTime should return FALSE");
70 TimeZone
* zoneclone
= zone
->clone();
71 if (!(*zoneclone
== *zone
)) errln("FAIL: clone or operator== failed");
72 zoneclone
->setID("abc");
73 if (!(*zoneclone
!= *zone
)) errln("FAIL: clone or operator!= failed");
76 zoneclone
= zone
->clone();
77 if (!(*zoneclone
== *zone
)) errln("FAIL: clone or operator== failed");
78 zoneclone
->setRawOffset(45678);
79 if (!(*zoneclone
!= *zone
)) errln("FAIL: clone or operator!= failed");
81 SimpleTimeZone
copy(*zone
);
82 if (!(copy
== *zone
)) errln("FAIL: copy constructor or operator== failed");
83 copy
= *(SimpleTimeZone
*)zoneclone
;
84 if (!(copy
== *zoneclone
)) errln("FAIL: assignment operator or operator== failed");
86 TimeZone
* saveDefault
= TimeZone::createDefault();
87 logln((UnicodeString
)"TimeZone::createDefault() => " + saveDefault
->getID(id
));
88 //TimeZone* pstZone = TimeZone::createTimeZone("PST");
90 logln("call uprv_timezone() which uses the host");
91 logln("to get the difference in seconds between coordinated universal");
92 logln("time and local time. E.g., -28,800 for PST (GMT-8hrs)");
94 int32_t tzoffset
= uprv_timezone();
95 logln(UnicodeString("Value returned from uprv_timezone = ") + tzoffset
);
96 // Invert sign because UNIX semantics are backwards
99 // --- The following test would fail outside PST now that
100 // --- PST is generally set to be default timezone in format tests
101 //if ((*saveDefault == *pstZone) && (tzoffset != 28800)) {
102 // errln("FAIL: t_timezone may be incorrect. It is not 28800");
105 if (tzoffset
!= 28800) {
106 logln("***** WARNING: If testing in the PST timezone, uprv_timezone should return 28800! *****");
108 if ((tzoffset
% 1800 != 0)) {
109 errln("FAIL: t_timezone may be incorrect. It is not a multiple of 30min. It is %d", tzoffset
);
112 TimeZone::adoptDefault(zone
);
113 TimeZone
* defaultzone
= TimeZone::createDefault();
114 if (defaultzone
== zone
||
115 !(*defaultzone
== *zone
))
116 errln("FAIL: createDefault failed");
117 TimeZone::adoptDefault(saveDefault
);
123 // ---------------------------------------------------------------------------------
126 * Test the setStartRule/setEndRule API calls.
129 TimeZoneTest::TestRuleAPI()
131 UErrorCode status
= U_ZERO_ERROR
;
133 UDate offset
= 60*60*1000*1.75; // Pick a weird offset
134 SimpleTimeZone
*zone
= new SimpleTimeZone((int32_t)offset
, "TestZone");
135 if (zone
->useDaylightTime()) errln("FAIL: useDaylightTime should return FALSE");
137 // Establish our expected transition times. Do this with a non-DST
138 // calendar with the (above) declared local offset.
139 GregorianCalendar
*gc
= new GregorianCalendar(*zone
, status
);
140 if (failure(status
, "new GregorianCalendar")) return;
142 gc
->set(1990, UCAL_MARCH
, 1);
143 UDate marchOneStd
= gc
->getTime(status
); // Local Std time midnight
145 gc
->set(1990, UCAL_JULY
, 1);
146 UDate julyOneStd
= gc
->getTime(status
); // Local Std time midnight
147 if (failure(status
, "GregorianCalendar::getTime")) return;
149 // Starting and ending hours, WALL TIME
150 int32_t startHour
= (int32_t)(2.25 * 3600000);
151 int32_t endHour
= (int32_t)(3.5 * 3600000);
153 zone
->setStartRule(UCAL_MARCH
, 1, 0, startHour
, status
);
154 zone
->setEndRule (UCAL_JULY
, 1, 0, endHour
, status
);
157 gc
= new GregorianCalendar(*zone
, status
);
158 if (failure(status
, "new GregorianCalendar")) return;
160 UDate marchOne
= marchOneStd
+ startHour
;
161 UDate julyOne
= julyOneStd
+ endHour
- 3600000; // Adjust from wall to Std time
163 UDate expMarchOne
= 636251400000.0;
164 if (marchOne
!= expMarchOne
)
166 errln((UnicodeString
)"FAIL: Expected start computed as " + marchOne
+
167 " = " + dateToString(marchOne
));
168 logln((UnicodeString
)" Should be " + expMarchOne
+
169 " = " + dateToString(expMarchOne
));
172 UDate expJulyOne
= 646793100000.0;
173 if (julyOne
!= expJulyOne
)
175 errln((UnicodeString
)"FAIL: Expected start computed as " + julyOne
+
176 " = " + dateToString(julyOne
));
177 logln((UnicodeString
)" Should be " + expJulyOne
+
178 " = " + dateToString(expJulyOne
));
181 testUsingBinarySearch(*zone
, date(90, UCAL_JANUARY
, 1), date(90, UCAL_JUNE
, 15), marchOne
);
182 testUsingBinarySearch(*zone
, date(90, UCAL_JUNE
, 1), date(90, UCAL_DECEMBER
, 31), julyOne
);
184 if (zone
->inDaylightTime(marchOne
- 1000, status
) ||
185 !zone
->inDaylightTime(marchOne
, status
))
186 errln("FAIL: Start rule broken");
187 if (!zone
->inDaylightTime(julyOne
- 1000, status
) ||
188 zone
->inDaylightTime(julyOne
, status
))
189 errln("FAIL: End rule broken");
191 zone
->setStartYear(1991);
192 if (zone
->inDaylightTime(marchOne
, status
) ||
193 zone
->inDaylightTime(julyOne
- 1000, status
))
194 errln("FAIL: Start year broken");
196 failure(status
, "TestRuleAPI");
202 TimeZoneTest::findTransition(const TimeZone
& tz
,
203 UDate min
, UDate max
) {
204 UErrorCode ec
= U_ZERO_ERROR
;
206 UBool startsInDST
= tz
.inDaylightTime(min
, ec
);
207 if (failure(ec
, "TimeZone::inDaylightTime")) return;
208 if (tz
.inDaylightTime(max
, ec
) == startsInDST
) {
209 logln("Error: " + tz
.getID(id
) + ".inDaylightTime(" + dateToString(min
) + ") = " + (startsInDST
?"TRUE":"FALSE") +
210 ", inDaylightTime(" + dateToString(max
) + ") = " + (startsInDST
?"TRUE":"FALSE"));
213 if (failure(ec
, "TimeZone::inDaylightTime")) return;
214 while ((max
- min
) > INTERVAL
) {
215 UDate mid
= (min
+ max
) / 2;
216 if (tz
.inDaylightTime(mid
, ec
) == startsInDST
) {
221 if (failure(ec
, "TimeZone::inDaylightTime")) return;
223 min
= 1000.0 * uprv_floor(min
/1000.0);
224 max
= 1000.0 * uprv_floor(max
/1000.0);
225 logln(tz
.getID(id
) + " Before: " + min
/1000 + " = " +
226 dateToString(min
,s
,tz
));
227 logln(tz
.getID(id
) + " After: " + max
/1000 + " = " +
228 dateToString(max
,s
,tz
));
232 TimeZoneTest::testUsingBinarySearch(const TimeZone
& tz
,
233 UDate min
, UDate max
,
234 UDate expectedBoundary
)
236 UErrorCode status
= U_ZERO_ERROR
;
237 UBool startsInDST
= tz
.inDaylightTime(min
, status
);
238 if (failure(status
, "TimeZone::inDaylightTime")) return;
239 if (tz
.inDaylightTime(max
, status
) == startsInDST
) {
240 logln("Error: inDaylightTime(" + dateToString(max
) + ") != " + ((!startsInDST
)?"TRUE":"FALSE"));
243 if (failure(status
, "TimeZone::inDaylightTime")) return;
244 while ((max
- min
) > INTERVAL
) {
245 UDate mid
= (min
+ max
) / 2;
246 if (tz
.inDaylightTime(mid
, status
) == startsInDST
) {
251 if (failure(status
, "TimeZone::inDaylightTime")) return;
253 logln(UnicodeString("Binary Search Before: ") + uprv_floor(0.5 + min
) + " = " + dateToString(min
));
254 logln(UnicodeString("Binary Search After: ") + uprv_floor(0.5 + max
) + " = " + dateToString(max
));
255 UDate mindelta
= expectedBoundary
- min
;
256 UDate maxdelta
= max
- expectedBoundary
;
258 mindelta
<= INTERVAL
&&
260 maxdelta
<= INTERVAL
)
261 logln(UnicodeString("PASS: Expected bdry: ") + expectedBoundary
+ " = " + dateToString(expectedBoundary
));
263 errln(UnicodeString("FAIL: Expected bdry: ") + expectedBoundary
+ " = " + dateToString(expectedBoundary
));
266 const UDate
TimeZoneTest::INTERVAL
= 100;
268 // ---------------------------------------------------------------------------------
270 // -------------------------------------
273 * Test the offset of the PRT timezone.
276 TimeZoneTest::TestPRTOffset()
278 TimeZone
* tz
= TimeZone::createTimeZone("PRT");
280 errln("FAIL: TimeZone(PRT) is null");
283 int32_t expectedHour
= -4;
284 double expectedOffset
= (((double)expectedHour
) * millisPerHour
);
285 double foundOffset
= tz
->getRawOffset();
286 int32_t foundHour
= (int32_t)foundOffset
/ millisPerHour
;
287 if (expectedOffset
!= foundOffset
) {
288 errln("FAIL: Offset for PRT should be %d, found %d", expectedHour
, foundHour
);
290 logln("PASS: Offset for PRT should be %d, found %d", expectedHour
, foundHour
);
296 // -------------------------------------
299 * Regress a specific bug with a sequence of API calls.
302 TimeZoneTest::TestVariousAPI518()
304 UErrorCode status
= U_ZERO_ERROR
;
305 TimeZone
* time_zone
= TimeZone::createTimeZone("PST");
306 UDate d
= date(97, UCAL_APRIL
, 30);
308 logln("The timezone is " + time_zone
->getID(str
));
309 if (!time_zone
->inDaylightTime(d
, status
)) errln("FAIL: inDaylightTime returned FALSE");
310 if (U_FAILURE(status
)) { errln("FAIL: TimeZone::inDaylightTime failed"); return; }
311 if (!time_zone
->useDaylightTime()) errln("FAIL: useDaylightTime returned FALSE");
312 if (time_zone
->getRawOffset() != - 8 * millisPerHour
) errln("FAIL: getRawOffset returned wrong value");
313 GregorianCalendar
*gc
= new GregorianCalendar(status
);
314 if (U_FAILURE(status
)) { errln("FAIL: Couldn't create GregorianCalendar"); return; }
315 gc
->setTime(d
, status
);
316 if (U_FAILURE(status
)) { errln("FAIL: GregorianCalendar::setTime failed"); return; }
317 if (time_zone
->getOffset(gc
->AD
, gc
->get(UCAL_YEAR
, status
), gc
->get(UCAL_MONTH
, status
),
318 gc
->get(UCAL_DATE
, status
), (uint8_t)gc
->get(UCAL_DAY_OF_WEEK
, status
), 0, status
) != - 7 * millisPerHour
)
319 errln("FAIL: getOffset returned wrong value");
320 if (U_FAILURE(status
)) { errln("FAIL: GregorianCalendar::set failed"); return; }
325 // -------------------------------------
328 * Test the call which retrieves the available IDs.
331 TimeZoneTest::TestGetAvailableIDs913()
333 UErrorCode ec
= U_ZERO_ERROR
;
336 #ifdef U_USE_TIMEZONE_OBSOLETE_2_8
337 // Test legacy API -- remove these tests when the corresponding API goes away (duh)
339 const UnicodeString
** ids
= TimeZone::createAvailableIDs(numIDs
);
340 if (ids
== 0 || numIDs
< 1) {
341 errln("FAIL: createAvailableIDs()");
343 UnicodeString
buf("TimeZone::createAvailableIDs() = { ");
344 for(i
=0; i
<numIDs
; ++i
) {
345 if (i
) buf
.append(", ");
350 // we own the array; the caller owns the contained strings (yuck)
355 ids
= TimeZone::createAvailableIDs(-8*U_MILLIS_PER_HOUR
, numIDs
);
356 if (ids
== 0 || numIDs
< 1) {
357 errln("FAIL: createAvailableIDs(-8:00)");
359 UnicodeString
buf("TimeZone::createAvailableIDs(-8:00) = { ");
360 for(i
=0; i
<numIDs
; ++i
) {
361 if (i
) buf
.append(", ");
366 // we own the array; the caller owns the contained strings (yuck)
370 ids
= TimeZone::createAvailableIDs("US", numIDs
);
371 if (ids
== 0 || numIDs
< 1) {
372 errln("FAIL: createAvailableIDs(US) ids=%d, numIDs=%d", ids
, numIDs
);
374 UnicodeString
buf("TimeZone::createAvailableIDs(US) = { ");
375 for(i
=0; i
<numIDs
; ++i
) {
376 if (i
) buf
.append(", ");
381 // we own the array; the caller owns the contained strings (yuck)
387 UnicodeString
*buf
= new UnicodeString("TimeZone::createEnumeration() = { ");
389 StringEnumeration
* s
= TimeZone::createEnumeration();
390 s_length
= s
->count(ec
);
391 for (i
= 0; i
< s_length
;++i
) {
392 if (i
> 0) *buf
+= ", ";
394 *buf
+= *s
->snext(ec
);
396 *buf
+= UnicodeString(s
->next(NULL
, ec
), "");
400 // replace s with a clone of itself
401 StringEnumeration
*s2
= s
->clone();
402 if(s2
== NULL
|| s_length
!= s2
->count(ec
)) {
403 errln("TimezoneEnumeration.clone() failed");
413 /* Confirm that the following zones can be retrieved: The first
414 * zone, the last zone, and one in-between. This tests the binary
415 * search through the system zone data.
418 int32_t middle
= s_length
/2;
419 for (i
=0; i
<s_length
; ++i
) {
420 const UnicodeString
* id
= s
->snext(ec
);
421 if (i
==0 || i
==middle
|| i
==(s_length
-1)) {
422 TimeZone
*z
= TimeZone::createTimeZone(*id
);
424 errln(UnicodeString("FAIL: createTimeZone(") +
426 } else if (z
->getID(str
) != *id
) {
427 errln(UnicodeString("FAIL: createTimeZone(") +
428 *id
+ ") -> zone " + str
);
430 logln(UnicodeString("OK: createTimeZone(") +
431 *id
+ ") succeeded");
439 *buf
+= "TimeZone::createEnumeration(GMT+01:00) = { ";
441 s
= TimeZone::createEnumeration(1 * U_MILLIS_PER_HOUR
);
442 s_length
= s
->count(ec
);
443 for (i
= 0; i
< s_length
;++i
) {
444 if (i
> 0) *buf
+= ", ";
445 *buf
+= *s
->snext(ec
);
453 *buf
+= "TimeZone::createEnumeration(US) = { ";
455 s
= TimeZone::createEnumeration("US");
456 s_length
= s
->count(ec
);
457 for (i
= 0; i
< s_length
;++i
) {
458 if (i
> 0) *buf
+= ", ";
459 *buf
+= *s
->snext(ec
);
464 TimeZone
*tz
= TimeZone::createTimeZone("PST");
465 if (tz
!= 0) logln("getTimeZone(PST) = " + tz
->getID(str
));
466 else errln("FAIL: getTimeZone(PST) = null");
468 tz
= TimeZone::createTimeZone("America/Los_Angeles");
469 if (tz
!= 0) logln("getTimeZone(America/Los_Angeles) = " + tz
->getID(str
));
470 else errln("FAIL: getTimeZone(PST) = null");
474 tz
= TimeZone::createTimeZone("NON_EXISTENT");
477 errln("FAIL: getTimeZone(NON_EXISTENT) = null");
478 else if (tz
->getID(temp
) != "GMT")
479 errln("FAIL: getTimeZone(NON_EXISTENT) = " + temp
);
488 * NOTE: As of ICU 2.8, this test confirms that the "tz.alias"
489 * file, used to build ICU alias zones, is working. It also
490 * looks at some genuine Olson compatibility IDs. [aliu]
492 * This test is problematic. It should really just confirm that
493 * the list of compatibility zone IDs exist and are somewhat
494 * meaningful (that is, they aren't all aliases of GMT). It goes a
495 * bit further -- it hard-codes expectations about zone behavior,
496 * when in fact zones are redefined quite frequently. ICU's build
497 * process means that it is easy to update ICU to contain the
498 * latest Olson zone data, but if a zone tested here changes, then
499 * this test will fail. I have updated the test for 1999j data,
500 * but further updates will probably be required. Note that some
501 * of the concerts listed below no longer apply -- in particular,
502 * we do NOT overwrite real UNIX zones with 3-letter IDs. There
503 * are two points of overlap as of 1999j: MET and EET. These are
504 * both real UNIX zones, so we just use the official
505 * definition. This test has been updated to reflect this.
508 * [srl - from java - 7/5/1998]
510 * Certain short zone IDs, used since 1.1.x, are incorrect.
512 * The worst of these is:
514 * "CAT" (Central African Time) should be GMT+2:00, but instead returns a
515 * zone at GMT-1:00. The zone at GMT-1:00 should be called EGT, CVT, EGST,
516 * or AZOST, depending on which zone is meant, but in no case is it CAT.
518 * Other wrong zone IDs:
520 * ECT (European Central Time) GMT+1:00: ECT is Ecuador Time,
521 * GMT-5:00. European Central time is abbreviated CEST.
523 * SST (Solomon Island Time) GMT+11:00. SST is actually Samoa Standard Time,
524 * GMT-11:00. Solomon Island time is SBT.
526 * NST (New Zealand Time) GMT+12:00. NST is the abbreviation for
527 * Newfoundland Standard Time, GMT-3:30. New Zealanders use NZST.
529 * AST (Alaska Standard Time) GMT-9:00. [This has already been noted in
530 * another bug.] It should be "AKST". AST is Atlantic Standard Time,
533 * PNT (Phoenix Time) GMT-7:00. PNT usually means Pitcairn Time,
534 * GMT-8:30. There is no standard abbreviation for Phoenix time, as distinct
535 * from MST with daylight savings.
537 * In addition to these problems, a number of zones are FAKE. That is, they
538 * don't match what people use in the real world.
542 * EET (should be EEST)
543 * ART (should be EEST)
544 * MET (should be IRST)
545 * NET (should be AMST)
546 * PLT (should be PKT)
547 * BST (should be BDT)
548 * VST (should be ICT)
549 * CTT (should be CST) +
550 * ACT (should be CST) +
551 * AET (should be EST) +
552 * MIT (should be WST) +
553 * IET (should be EST) +
554 * PRT (should be AST) +
555 * CNT (should be NST)
556 * AGT (should be ARST)
557 * BET (should be EST) +
559 * + A zone with the correct name already exists and means something
560 * else. E.g., EST usually indicates the US Eastern zone, so it cannot be
561 * used for Brazil (BET).
563 void TimeZoneTest::TestShortZoneIDs()
566 // Create a small struct to hold the array
575 {"MIT", -660, FALSE
},
576 {"HST", -600, FALSE
},
579 {"PNT", -420, FALSE
},
580 {"MST", -420, FALSE
}, // updated Aug 2003 aliu
582 {"IET", -300, FALSE
},
583 {"EST", -300, FALSE
}, // updated Aug 2003 aliu
584 {"PRT", -240, FALSE
},
586 {"AGT", -180, FALSE
}, // updated 26 Sep 2000 aliu
588 // "CAT", -60, FALSE, // Wrong:
589 // As of bug 4130885, fix CAT (Central Africa)
590 {"CAT", 120, FALSE
}, // Africa/Harare
592 {"UTC", 0, FALSE
}, // ** srl: seems broken in C++
597 {"MET", 60, TRUE
}, // updated 12/3/99 aliu
598 {"NET", 240, TRUE
}, // updated 12/3/99 aliu
599 {"PLT", 300, FALSE
}, // updated Aug 2003 aliu
603 {"CTT", 480, FALSE
}, // updated Aug 2003 aliu
605 {"ACT", 570, FALSE
}, // updated Aug 2003 aliu
608 // "NST", 720, FALSE,
609 // As of bug 4130885, fix NST (New Zealand)
610 {"NST", 720, TRUE
}, // Pacific/Auckland
615 for(i
=0;kReferenceList
[i
].id
[0];i
++) {
616 UnicodeString
itsID(kReferenceList
[i
].id
);
619 TimeZone
*tz
= TimeZone::createTimeZone(itsID
);
621 errln("FAIL: Time Zone " + itsID
+ " does not exist!");
625 // Check daylight usage.
626 UBool usesDaylight
= tz
->useDaylightTime();
627 if (usesDaylight
!= kReferenceList
[i
].daylight
) {
628 errln("FAIL: Time Zone " + itsID
+ " use daylight is " +
629 (usesDaylight
?"TRUE":"FALSE") +
630 " but it should be " +
631 ((kReferenceList
[i
].daylight
)?"TRUE":"FALSE"));
636 int32_t offsetInMinutes
= tz
->getRawOffset()/60000;
637 if (offsetInMinutes
!= kReferenceList
[i
].offset
) {
638 errln("FAIL: Time Zone " + itsID
+ " raw offset is " +
640 " but it should be " + kReferenceList
[i
].offset
);
645 logln("OK: " + itsID
+
646 " useDaylightTime() & getRawOffset() as expected");
652 // OK now test compat
653 logln("Testing for compatibility zones");
655 const char* compatibilityMap
[] = {
656 // This list is copied from tz.alias. If tz.alias
657 // changes, this list must be updated. Current as of Aug 2003
658 "ACT", "Australia/Darwin",
659 "AET", "Australia/Sydney",
660 "AGT", "America/Buenos_Aires",
661 "ART", "Africa/Cairo",
662 "AST", "America/Anchorage",
663 "BET", "America/Sao_Paulo",
664 "BST", "Asia/Dhaka", // Spelling changed in 2000h
665 "CAT", "Africa/Harare",
666 "CNT", "America/St_Johns",
667 "CST", "America/Chicago",
668 "CTT", "Asia/Shanghai",
669 "EAT", "Africa/Addis_Ababa",
670 "ECT", "Europe/Paris",
671 // EET Europe/Istanbul # EET is a standard UNIX zone
672 // "EST", "America/New_York", # EST is an Olson alias now (2003)
673 "HST", "Pacific/Honolulu",
674 "IET", "America/Indianapolis",
675 "IST", "Asia/Calcutta",
677 // MET Asia/Tehran # MET is a standard UNIX zone
678 "MIT", "Pacific/Apia",
679 // "MST", "America/Denver", # MST is an Olson alias now (2003)
680 "NET", "Asia/Yerevan",
681 "NST", "Pacific/Auckland",
682 "PLT", "Asia/Karachi",
683 "PNT", "America/Phoenix",
684 "PRT", "America/Puerto_Rico",
685 "PST", "America/Los_Angeles",
686 "SST", "Pacific/Guadalcanal",
688 "VST", "Asia/Saigon",
692 for (i
=0;*compatibilityMap
[i
];i
+=2) {
695 const char *zone1
= compatibilityMap
[i
];
696 const char *zone2
= compatibilityMap
[i
+1];
698 TimeZone
*tz1
= TimeZone::createTimeZone(zone1
);
699 TimeZone
*tz2
= TimeZone::createTimeZone(zone2
);
702 errln(UnicodeString("FAIL: Could not find short ID zone ") + zone1
);
705 errln(UnicodeString("FAIL: Could not find long ID zone ") + zone2
);
709 // make NAME same so comparison will only look at the rest
710 tz2
->setID(tz1
->getID(itsID
));
713 errln("FAIL: " + UnicodeString(zone1
) +
714 " != " + UnicodeString(zone2
));
716 logln("OK: " + UnicodeString(zone1
) +
717 " == " + UnicodeString(zone2
));
727 * Utility function for TestCustomParse
729 UnicodeString
& TimeZoneTest::formatMinutes(int32_t min
, UnicodeString
& rv
)
734 if (min
< 0) { sign
= '-'; min
= -min
; }
740 rv
+= UChar(0x0030 + (h
/10));
741 rv
+= UChar(0x0030 + (h%10
));
746 rv
+= UChar(0x0030 + (min
/10));
750 rv
+= UChar(0x0030 + (min%10
));
757 * As part of the VM fix (see CCC approved RFE 4028006, bug
758 * 4044013), TimeZone.getTimeZone() has been modified to recognize
759 * generic IDs of the form GMT[+-]hh:mm, GMT[+-]hhmm, and
760 * GMT[+-]hh. Test this behavior here.
764 void TimeZoneTest::TestCustomParse()
767 const int32_t kUnparseable
= 604800; // the number of seconds in a week. More than any offset should be.
768 const UnicodeString kExpectedCustomID
= "Custom";
772 const char *customId
;
773 int32_t expectedOffset
;
777 // ID Expected offset in minutes
778 //"GMT", kUnparseable, Isn't custom. Can't test it here. [returns normal GMT]
779 {"GMT-YOUR.AD.HERE", kUnparseable
},
780 // {"GMT0", kUnparseable}, // ICU 2.8: An Olson zone ID
781 // {"GMT+0", (0)}, // ICU 2.8: An Olson zone ID
784 {"GMT+15:99", (15*60+99)},
785 {"GMT+", kUnparseable
},
786 {"GMT-", kUnparseable
},
787 {"GMT+0:", kUnparseable
},
788 {"GMT-:", kUnparseable
},
789 {"GMT-YOUR.AD.HERE", kUnparseable
},
790 {"GMT+0010", (10)}, // Interpret this as 00:10
791 {"GMT-10", (-10*60)},
793 {"GMT-3:30", (-(3*60+30))},
794 {"GMT-230", (-(2*60+30))},
798 for (i
=0; kData
[i
].customId
!= 0; i
++)
800 UnicodeString
id(kData
[i
].customId
);
801 int32_t exp
= kData
[i
].expectedOffset
;
803 TimeZone
*zone
= TimeZone::createTimeZone(id
);
804 UnicodeString itsID
, temp
;
807 logln("testing # " + formatMinutes(i
, temp
) + id
);
812 errln("FAIL: Could not createTimeZone(" + id + "). Returned NULL.");
818 if (! zone
->getID(itsID
).compare("GMT"))
821 logln(id
+ " -> generic GMT");
822 // When TimeZone.getTimeZone() can't parse the id, it
823 // returns GMT -- a dubious practice, but required for
824 // backward compatibility.
825 if (exp
!= kUnparseable
) {
826 errln("FAIL: Expected offset of " + formatMinutes(exp
,temp
) +
827 " for " + id
+ ", got parse failure");
833 int32_t ioffset
= zone
->getRawOffset()/60000;
834 UnicodeString offset
;
835 formatMinutes(ioffset
, offset
);
836 logln(id
+ " -> " + itsID
+ " GMT" + offset
);
837 if (exp
== kUnparseable
)
839 errln("FAIL: Expected parse failure for " + id
+
840 ", got offset of " + offset
+
843 else if (ioffset
!= exp
||
844 (itsID
.compare(kExpectedCustomID
) != 0))
846 errln("Expected offset of " + formatMinutes(exp
,temp
) +
847 ", id Custom, for " + id
+
848 ", got offset of " + offset
+
857 * Test the basic functionality of the getDisplayName() API.
862 * See also API change request A41.
864 * 4/21/98 - make smarter, so the test works if the ext resources
865 * are present or not.
868 TimeZoneTest::TestDisplayName()
870 UErrorCode status
= U_ZERO_ERROR
;
872 TimeZone
*zone
= TimeZone::createTimeZone("PST");
874 zone
->getDisplayName(Locale::getEnglish(), name
);
875 logln("PST->" + name
);
876 if (name
.compare("Pacific Standard Time") != 0)
877 errln("Fail: Expected \"Pacific Standard Time\" but got " + name
);
879 //*****************************************************************
880 // THE FOLLOWING LINES MUST BE UPDATED IF THE LOCALE DATA CHANGES
881 // THE FOLLOWING LINES MUST BE UPDATED IF THE LOCALE DATA CHANGES
882 // THE FOLLOWING LINES MUST BE UPDATED IF THE LOCALE DATA CHANGES
883 //*****************************************************************
887 TimeZone::EDisplayType style
;
890 {FALSE
, TimeZone::SHORT
, "PST"},
891 {TRUE
, TimeZone::SHORT
, "PDT"},
892 {FALSE
, TimeZone::LONG
, "Pacific Standard Time"},
893 {TRUE
, TimeZone::LONG
, "Pacific Daylight Time"},
895 {FALSE
, TimeZone::LONG
, ""}
898 for (i
=0; kData
[i
].expect
[0] != '\0'; i
++)
901 name
= zone
->getDisplayName(kData
[i
].useDst
,
903 Locale::getEnglish(), name
);
904 if (name
.compare(kData
[i
].expect
) != 0)
905 errln("Fail: Expected " + UnicodeString(kData
[i
].expect
) + "; got " + name
);
906 logln("PST [with options]->" + name
);
908 for (i
=0; kData
[i
].expect
[0] != '\0'; i
++)
911 name
= zone
->getDisplayName(kData
[i
].useDst
,
912 kData
[i
].style
, name
);
913 if (name
.compare(kData
[i
].expect
) != 0)
914 errln("Fail: Expected " + UnicodeString(kData
[i
].expect
) + "; got " + name
);
915 logln("PST [with options]->" + name
);
919 // Make sure that we don't display the DST name by constructing a fake
920 // PST zone that has DST all year long.
921 SimpleTimeZone
*zone2
= new SimpleTimeZone(0, "PST");
923 zone2
->setStartRule(UCAL_JANUARY
, 1, 0, 0, status
);
924 zone2
->setEndRule(UCAL_DECEMBER
, 31, 0, 0, status
);
926 UnicodeString inDaylight
;
927 if (zone2
->inDaylightTime(UDate(0), status
)) {
928 inDaylight
= UnicodeString("TRUE");
930 inDaylight
= UnicodeString("FALSE");
932 logln(UnicodeString("Modified PST inDaylightTime->") + inDaylight
);
933 if(U_FAILURE(status
))
935 errln("Some sort of error..." + UnicodeString(u_errorName(status
))); // REVISIT
938 name
= zone2
->getDisplayName(Locale::getEnglish(),name
);
939 logln("Modified PST->" + name
);
940 if (name
.compare("Pacific Standard Time") != 0)
941 errln("Fail: Expected \"Pacific Standard Time\"");
943 // Make sure we get the default display format for Locales
944 // with no display name data.
945 Locale
mt_MT("mt_MT");
947 name
= zone
->getDisplayName(mt_MT
,name
);
948 //*****************************************************************
949 // THE FOLLOWING LINE MUST BE UPDATED IF THE LOCALE DATA CHANGES
950 // THE FOLLOWING LINE MUST BE UPDATED IF THE LOCALE DATA CHANGES
951 // THE FOLLOWING LINE MUST BE UPDATED IF THE LOCALE DATA CHANGES
952 //*****************************************************************
953 logln("PST(mt_MT)->" + name
);
955 // *** REVISIT SRL how in the world do I check this? looks java specific.
956 // Now be smart -- check to see if zh resource is even present.
957 // If not, we expect the en fallback behavior.
958 ResourceBundle
enRB(NULL
,
959 Locale::getEnglish(), status
);
960 if(U_FAILURE(status
))
961 errln("Couldn't get ResourceBundle for en");
963 ResourceBundle
mtRB(NULL
,
965 //if(U_FAILURE(status))
966 // errln("Couldn't get ResourceBundle for mt_MT");
968 UBool noZH
= U_FAILURE(status
);
971 logln("Warning: Not testing the mt_MT behavior because resource is absent");
972 if (name
!= "Pacific Standard Time")
973 errln("Fail: Expected Pacific Standard Time");
977 if (name
.compare("GMT-08:00") &&
978 name
.compare("GMT-8:00") &&
979 name
.compare("GMT-0800") &&
980 name
.compare("GMT-800")) {
981 errln(UnicodeString("Fail: Expected GMT-08:00 or something similar for PST in mt_MT but got ") + name
);
982 errln("************************************************************");
983 errln("THE ABOVE FAILURE MAY JUST MEAN THE LOCALE DATA HAS CHANGED");
984 errln("************************************************************");
987 // Now try a non-existent zone
989 zone2
= new SimpleTimeZone(90*60*1000, "xyzzy");
991 name
= zone2
->getDisplayName(Locale::getEnglish(),name
);
992 logln("GMT+90min->" + name
);
993 if (name
.compare("GMT+01:30") &&
994 name
.compare("GMT+1:30") &&
995 name
.compare("GMT+0130") &&
996 name
.compare("GMT+130"))
997 errln("Fail: Expected GMT+01:30 or something similar");
999 zone2
->getDisplayName(name
);
1000 logln("GMT+90min->" + name
);
1001 if (name
.compare("GMT+01:30") &&
1002 name
.compare("GMT+1:30") &&
1003 name
.compare("GMT+0130") &&
1004 name
.compare("GMT+130"))
1005 errln("Fail: Expected GMT+01:30 or something similar");
1015 TimeZoneTest::TestDSTSavings()
1017 UErrorCode status
= U_ZERO_ERROR
;
1018 // It might be better to find a way to integrate this test into the main TimeZone
1019 // tests above, but I don't have time to figure out how to do this (or if it's
1020 // even really a good idea). Let's consider that a future. --rtg 1/27/98
1021 SimpleTimeZone
*tz
= new SimpleTimeZone(-5 * U_MILLIS_PER_HOUR
, "dstSavingsTest",
1022 UCAL_MARCH
, 1, 0, 0, UCAL_SEPTEMBER
, 1, 0, 0,
1023 (int32_t)(0.5 * U_MILLIS_PER_HOUR
), status
);
1024 if(U_FAILURE(status
))
1025 errln("couldn't create TimeZone");
1027 if (tz
->getRawOffset() != -5 * U_MILLIS_PER_HOUR
)
1028 errln(UnicodeString("Got back a raw offset of ") + (tz
->getRawOffset() / U_MILLIS_PER_HOUR
) +
1029 " hours instead of -5 hours.");
1030 if (!tz
->useDaylightTime())
1031 errln("Test time zone should use DST but claims it doesn't.");
1032 if (tz
->getDSTSavings() != 0.5 * U_MILLIS_PER_HOUR
)
1033 errln(UnicodeString("Set DST offset to 0.5 hour, but got back ") + (tz
->getDSTSavings() /
1034 U_MILLIS_PER_HOUR
) + " hours instead.");
1036 int32_t offset
= tz
->getOffset(GregorianCalendar::AD
, 1998, UCAL_JANUARY
, 1,
1037 UCAL_THURSDAY
, 10 * U_MILLIS_PER_HOUR
,status
);
1038 if (offset
!= -5 * U_MILLIS_PER_HOUR
)
1039 errln(UnicodeString("The offset for 10 AM, 1/1/98 should have been -5 hours, but we got ")
1040 + (offset
/ U_MILLIS_PER_HOUR
) + " hours.");
1042 offset
= tz
->getOffset(GregorianCalendar::AD
, 1998, UCAL_JUNE
, 1, UCAL_MONDAY
,
1043 10 * U_MILLIS_PER_HOUR
,status
);
1044 if (offset
!= -4.5 * U_MILLIS_PER_HOUR
)
1045 errln(UnicodeString("The offset for 10 AM, 6/1/98 should have been -4.5 hours, but we got ")
1046 + (offset
/ U_MILLIS_PER_HOUR
) + " hours.");
1048 tz
->setDSTSavings(U_MILLIS_PER_HOUR
, status
);
1049 offset
= tz
->getOffset(GregorianCalendar::AD
, 1998, UCAL_JANUARY
, 1,
1050 UCAL_THURSDAY
, 10 * U_MILLIS_PER_HOUR
,status
);
1051 if (offset
!= -5 * U_MILLIS_PER_HOUR
)
1052 errln(UnicodeString("The offset for 10 AM, 1/1/98 should have been -5 hours, but we got ")
1053 + (offset
/ U_MILLIS_PER_HOUR
) + " hours.");
1055 offset
= tz
->getOffset(GregorianCalendar::AD
, 1998, UCAL_JUNE
, 1, UCAL_MONDAY
,
1056 10 * U_MILLIS_PER_HOUR
,status
);
1057 if (offset
!= -4 * U_MILLIS_PER_HOUR
)
1058 errln(UnicodeString("The offset for 10 AM, 6/1/98 (with a 1-hour DST offset) should have been -4 hours, but we got ")
1059 + (offset
/ U_MILLIS_PER_HOUR
) + " hours.");
1068 TimeZoneTest::TestAlternateRules()
1070 // Like TestDSTSavings, this test should probably be integrated somehow with the main
1071 // test at the top of this class, but I didn't have time to figure out how to do that.
1074 SimpleTimeZone
tz(-5 * U_MILLIS_PER_HOUR
, "alternateRuleTest");
1076 // test the day-of-month API
1077 UErrorCode status
= U_ZERO_ERROR
;
1078 tz
.setStartRule(UCAL_MARCH
, 10, 12 * U_MILLIS_PER_HOUR
, status
);
1079 if(U_FAILURE(status
))
1080 errln("tz.setStartRule failed");
1081 tz
.setEndRule(UCAL_OCTOBER
, 20, 12 * U_MILLIS_PER_HOUR
, status
);
1082 if(U_FAILURE(status
))
1083 errln("tz.setStartRule failed");
1085 int32_t offset
= tz
.getOffset(GregorianCalendar::AD
, 1998, UCAL_MARCH
, 5,
1086 UCAL_THURSDAY
, 10 * U_MILLIS_PER_HOUR
,status
);
1087 if (offset
!= -5 * U_MILLIS_PER_HOUR
)
1088 errln(UnicodeString("The offset for 10AM, 3/5/98 should have been -5 hours, but we got ")
1089 + (offset
/ U_MILLIS_PER_HOUR
) + " hours.");
1091 offset
= tz
.getOffset(GregorianCalendar::AD
, 1998, UCAL_MARCH
, 15,
1092 UCAL_SUNDAY
, 10 * millisPerHour
,status
);
1093 if (offset
!= -4 * U_MILLIS_PER_HOUR
)
1094 errln(UnicodeString("The offset for 10AM, 3/15/98 should have been -4 hours, but we got ")
1095 + (offset
/ U_MILLIS_PER_HOUR
) + " hours.");
1097 offset
= tz
.getOffset(GregorianCalendar::AD
, 1998, UCAL_OCTOBER
, 15,
1098 UCAL_THURSDAY
, 10 * millisPerHour
,status
);
1099 if (offset
!= -4 * U_MILLIS_PER_HOUR
)
1100 errln(UnicodeString("The offset for 10AM, 10/15/98 should have been -4 hours, but we got ") + (offset
/ U_MILLIS_PER_HOUR
) + " hours.");
1102 offset
= tz
.getOffset(GregorianCalendar::AD
, 1998, UCAL_OCTOBER
, 25,
1103 UCAL_SUNDAY
, 10 * millisPerHour
,status
);
1104 if (offset
!= -5 * U_MILLIS_PER_HOUR
)
1105 errln(UnicodeString("The offset for 10AM, 10/25/98 should have been -5 hours, but we got ")
1106 + (offset
/ U_MILLIS_PER_HOUR
) + " hours.");
1108 // test the day-of-week-after-day-in-month API
1109 tz
.setStartRule(UCAL_MARCH
, 10, UCAL_FRIDAY
, 12 * millisPerHour
, TRUE
, status
);
1110 if(U_FAILURE(status
))
1111 errln("tz.setStartRule failed");
1112 tz
.setEndRule(UCAL_OCTOBER
, 20, UCAL_FRIDAY
, 12 * millisPerHour
, FALSE
, status
);
1113 if(U_FAILURE(status
))
1114 errln("tz.setStartRule failed");
1116 offset
= tz
.getOffset(GregorianCalendar::AD
, 1998, UCAL_MARCH
, 11,
1117 UCAL_WEDNESDAY
, 10 * millisPerHour
,status
);
1118 if (offset
!= -5 * U_MILLIS_PER_HOUR
)
1119 errln(UnicodeString("The offset for 10AM, 3/11/98 should have been -5 hours, but we got ")
1120 + (offset
/ U_MILLIS_PER_HOUR
) + " hours.");
1122 offset
= tz
.getOffset(GregorianCalendar::AD
, 1998, UCAL_MARCH
, 14,
1123 UCAL_SATURDAY
, 10 * millisPerHour
,status
);
1124 if (offset
!= -4 * U_MILLIS_PER_HOUR
)
1125 errln(UnicodeString("The offset for 10AM, 3/14/98 should have been -4 hours, but we got ")
1126 + (offset
/ U_MILLIS_PER_HOUR
) + " hours.");
1128 offset
= tz
.getOffset(GregorianCalendar::AD
, 1998, UCAL_OCTOBER
, 15,
1129 UCAL_THURSDAY
, 10 * millisPerHour
,status
);
1130 if (offset
!= -4 * U_MILLIS_PER_HOUR
)
1131 errln(UnicodeString("The offset for 10AM, 10/15/98 should have been -4 hours, but we got ")
1132 + (offset
/ U_MILLIS_PER_HOUR
) + " hours.");
1134 offset
= tz
.getOffset(GregorianCalendar::AD
, 1998, UCAL_OCTOBER
, 17,
1135 UCAL_SATURDAY
, 10 * millisPerHour
,status
);
1136 if (offset
!= -5 * U_MILLIS_PER_HOUR
)
1137 errln(UnicodeString("The offset for 10AM, 10/17/98 should have been -5 hours, but we got ")
1138 + (offset
/ U_MILLIS_PER_HOUR
) + " hours.");
1142 * Test country code support. Jitterbug 776.
1144 void TimeZoneTest::TestCountries() {
1145 // Make sure America/Los_Angeles is in the "US" group, and
1146 // Asia/Tokyo isn't. Vice versa for the "JP" group.
1147 UErrorCode ec
= U_ZERO_ERROR
;
1149 StringEnumeration
* s
= TimeZone::createEnumeration("US");
1151 UBool la
= FALSE
, tokyo
= FALSE
;
1152 UnicodeString
laZone("America/Los_Angeles", "");
1153 UnicodeString
tokyoZone("Asia/Tokyo", "");
1156 if (s
== NULL
|| n
<= 0) {
1157 errln("FAIL: TimeZone::createEnumeration() returned nothing");
1160 for (i
=0; i
<n
; ++i
) {
1161 const UnicodeString
* id
= s
->snext(ec
);
1162 if (*id
== (laZone
)) {
1165 if (*id
== (tokyoZone
)) {
1170 errln("FAIL: " + laZone
+ " in US = " + la
);
1171 errln("FAIL: " + tokyoZone
+ " in US = " + tokyo
);
1175 s
= TimeZone::createEnumeration("JP");
1177 la
= FALSE
; tokyo
= FALSE
;
1179 for (i
=0; i
<n
; ++i
) {
1180 const UnicodeString
* id
= s
->snext(ec
);
1181 if (*id
== (laZone
)) {
1184 if (*id
== (tokyoZone
)) {
1189 errln("FAIL: " + laZone
+ " in JP = " + la
);
1190 errln("FAIL: " + tokyoZone
+ " in JP = " + tokyo
);
1192 StringEnumeration
* s1
= TimeZone::createEnumeration("US");
1193 StringEnumeration
* s2
= TimeZone::createEnumeration("US");
1195 const UnicodeString
* id1
= s1
->snext(ec
);
1196 if(id1
==NULL
|| U_FAILURE(ec
)){
1197 errln("Failed to fetch next from TimeZone enumeration. Length returned : %i Current Index: %i", n
,i
);
1199 TimeZone
* tz1
= TimeZone::createTimeZone(*id1
);
1200 for(int j
=0; j
<n
;++j
){
1201 const UnicodeString
* id2
= s2
->snext(ec
);
1202 if(id2
==NULL
|| U_FAILURE(ec
)){
1203 errln("Failed to fetch next from TimeZone enumeration. Length returned : %i Current Index: %i", n
,i
);
1205 TimeZone
* tz2
= TimeZone::createTimeZone(*id2
);
1206 if(tz1
->hasSameRules(*tz2
)){
1207 logln("ID1 : " + *id1
+" == ID2 : " +*id2
);
1218 void TimeZoneTest::TestHistorical() {
1219 const int32_t H
= U_MILLIS_PER_HOUR
;
1222 int32_t time
; // epoch seconds
1223 int32_t offset
; // total offset (millis)
1225 // Add transition points (before/after) as desired to test historical
1227 {"America/Los_Angeles", 638963999, -8*H
}, // Sun Apr 01 01:59:59 GMT-08:00 1990
1228 {"America/Los_Angeles", 638964000, -7*H
}, // Sun Apr 01 03:00:00 GMT-07:00 1990
1229 {"America/Los_Angeles", 657104399, -7*H
}, // Sun Oct 28 01:59:59 GMT-07:00 1990
1230 {"America/Los_Angeles", 657104400, -8*H
}, // Sun Oct 28 01:00:00 GMT-08:00 1990
1231 {"America/Goose_Bay", -116445601, -4*H
}, // Sun Apr 24 01:59:59 GMT-04:00 1966
1232 {"America/Goose_Bay", -116445600, -3*H
}, // Sun Apr 24 03:00:00 GMT-03:00 1966
1233 {"America/Goose_Bay", -100119601, -3*H
}, // Sun Oct 30 01:59:59 GMT-03:00 1966
1234 {"America/Goose_Bay", -100119600, -4*H
}, // Sun Oct 30 01:00:00 GMT-04:00 1966
1235 {"America/Goose_Bay", -84391201, -4*H
}, // Sun Apr 30 01:59:59 GMT-04:00 1967
1236 {"America/Goose_Bay", -84391200, -3*H
}, // Sun Apr 30 03:00:00 GMT-03:00 1967
1237 {"America/Goose_Bay", -68670001, -3*H
}, // Sun Oct 29 01:59:59 GMT-03:00 1967
1238 {"America/Goose_Bay", -68670000, -4*H
}, // Sun Oct 29 01:00:00 GMT-04:00 1967
1242 for (int32_t i
=0; DATA
[i
].id
!=0; ++i
) {
1243 const char* id
= DATA
[i
].id
;
1244 TimeZone
*tz
= TimeZone::createTimeZone(id
);
1247 errln("FAIL: Cannot create %s", id
);
1248 } else if (tz
->getID(s
) != UnicodeString(id
)) {
1249 errln((UnicodeString
)"FAIL: createTimeZone(" + id
+ ") => " + s
);
1251 UErrorCode ec
= U_ZERO_ERROR
;
1253 UDate when
= (double) DATA
[i
].time
* U_MILLIS_PER_SECOND
;
1254 tz
->getOffset(when
, FALSE
, raw
, dst
, ec
);
1255 if (U_FAILURE(ec
)) {
1256 errln("FAIL: getOffset");
1257 } else if ((raw
+dst
) != DATA
[i
].offset
) {
1258 errln((UnicodeString
)"FAIL: " + DATA
[i
].id
+ ".getOffset(" +
1260 dateToString(when
) + ") => " +
1263 logln((UnicodeString
)"Ok: " + DATA
[i
].id
+ ".getOffset(" +
1265 dateToString(when
) + ") => " +
1273 void TimeZoneTest::TestEquivalentIDs() {
1274 int32_t n
= TimeZone::countEquivalentIDs("PST");
1276 errln((UnicodeString
)"FAIL: countEquivalentIDs(PST) = " + n
);
1278 UBool sawLA
= FALSE
;
1279 for (int32_t i
=0; i
<n
; ++i
) {
1280 UnicodeString id
= TimeZone::getEquivalentID("PST", i
);
1281 logln((UnicodeString
)"" + i
+ " : " + id
);
1282 if (id
== UnicodeString("America/Los_Angeles")) {
1287 errln("FAIL: America/Los_Angeles should be in the list");
1292 #endif /* #if !UCONFIG_NO_FORMATTING */