OLD | NEW |
| (Empty) |
1 /******************************************************************** | |
2 * Copyright (c) 1997-2013, International Business Machines | |
3 * Corporation and others. All Rights Reserved. | |
4 ********************************************************************/ | |
5 | |
6 #include "unicode/utypes.h" | |
7 | |
8 #if !UCONFIG_NO_FORMATTING | |
9 | |
10 #include "unicode/simpletz.h" | |
11 #include "unicode/smpdtfmt.h" | |
12 #include "unicode/strenum.h" | |
13 #include "tzregts.h" | |
14 #include "calregts.h" | |
15 #include "cmemory.h" | |
16 | |
17 // ***************************************************************************** | |
18 // class TimeZoneRegressionTest | |
19 // ***************************************************************************** | |
20 /* length of an array */ | |
21 #define ARRAY_LENGTH(array) (sizeof(array)/sizeof(array[0])) | |
22 #define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); log
ln((UnicodeString)""); test(); } break | |
23 | |
24 void | |
25 TimeZoneRegressionTest::runIndexedTest( int32_t index, UBool exec, const char* &
name, char* /*par*/ ) | |
26 { | |
27 // if (exec) logln((UnicodeString)"TestSuite NumberFormatRegressionTest"); | |
28 switch (index) { | |
29 | |
30 CASE(0, Test4052967); | |
31 CASE(1, Test4073209); | |
32 CASE(2, Test4073215); | |
33 CASE(3, Test4084933); | |
34 CASE(4, Test4096952); | |
35 CASE(5, Test4109314); | |
36 CASE(6, Test4126678); | |
37 CASE(7, Test4151406); | |
38 CASE(8, Test4151429); | |
39 CASE(9, Test4154537); | |
40 CASE(10, Test4154542); | |
41 CASE(11, Test4154650); | |
42 CASE(12, Test4154525); | |
43 CASE(13, Test4162593); | |
44 CASE(14, TestJ186); | |
45 CASE(15, TestJ449); | |
46 CASE(16, TestJDK12API); | |
47 CASE(17, Test4176686); | |
48 CASE(18, Test4184229); | |
49 default: name = ""; break; | |
50 } | |
51 } | |
52 | |
53 UBool | |
54 TimeZoneRegressionTest::failure(UErrorCode status, const char* msg) | |
55 { | |
56 if(U_FAILURE(status)) { | |
57 errln(UnicodeString("FAIL: ") + msg + " failed, error " + u_errorName(st
atus)); | |
58 return TRUE; | |
59 } | |
60 | |
61 return FALSE; | |
62 } | |
63 | |
64 /** | |
65 * @bug 4052967 | |
66 */ | |
67 void TimeZoneRegressionTest:: Test4052967() { | |
68 // {sfb} not applicable in C++ ? | |
69 /*logln("*** CHECK TIMEZONE AGAINST HOST OS SETTING ***"); | |
70 logln("user.timezone:" + System.getProperty("user.timezone", "<not set>")); | |
71 logln(new Date().toString()); | |
72 logln("*** THE RESULTS OF THIS TEST MUST BE VERIFIED MANUALLY ***");*/ | |
73 } | |
74 | |
75 /** | |
76 * @bug 4073209 | |
77 */ | |
78 void TimeZoneRegressionTest:: Test4073209() { | |
79 TimeZone *z1 = TimeZone::createTimeZone("PST"); | |
80 TimeZone *z2 = TimeZone::createTimeZone("PST"); | |
81 if (z1 == z2) | |
82 errln("Fail: TimeZone should return clones"); | |
83 delete z1; | |
84 delete z2; | |
85 } | |
86 | |
87 UDate TimeZoneRegressionTest::findTransitionBinary(const SimpleTimeZone& tz, UDa
te min, UDate max) { | |
88 UErrorCode status = U_ZERO_ERROR; | |
89 UBool startsInDST = tz.inDaylightTime(min, status); | |
90 if (failure(status, "SimpleTimeZone::inDaylightTime")) return 0; | |
91 if (tz.inDaylightTime(max, status) == startsInDST) { | |
92 logln((UnicodeString)"Error: inDaylightTime() != " + ((!startsInDST)?"TR
UE":"FALSE")); | |
93 return 0; | |
94 } | |
95 if (failure(status, "SimpleTimeZone::inDaylightTime")) return 0; | |
96 while ((max - min) > 100) { // Min accuracy in ms | |
97 UDate mid = (min + max) / 2; | |
98 if (tz.inDaylightTime(mid, status) == startsInDST) { | |
99 min = mid; | |
100 } else { | |
101 max = mid; | |
102 } | |
103 if (failure(status, "SimpleTimeZone::inDaylightTime")) return 0; | |
104 } | |
105 return (min + max) / 2; | |
106 } | |
107 | |
108 UDate TimeZoneRegressionTest::findTransitionStepwise(const SimpleTimeZone& tz, U
Date min, UDate max) { | |
109 UErrorCode status = U_ZERO_ERROR; | |
110 UBool startsInDST = tz.inDaylightTime(min, status); | |
111 if (failure(status, "SimpleTimeZone::inDaylightTime")) return 0; | |
112 while (min < max) { | |
113 if (tz.inDaylightTime(min, status) != startsInDST) { | |
114 return min; | |
115 } | |
116 if (failure(status, "SimpleTimeZone::inDaylightTime")) return 0; | |
117 min += (UDate)24*60*60*1000; // one day | |
118 } | |
119 return 0; | |
120 } | |
121 | |
122 /** | |
123 * @bug 4073215 | |
124 */ | |
125 // {sfb} will this work using a Calendar? | |
126 void TimeZoneRegressionTest:: Test4073215() | |
127 { | |
128 UErrorCode status = U_ZERO_ERROR; | |
129 UnicodeString str, str2; | |
130 SimpleTimeZone *z = new SimpleTimeZone(0, "GMT"); | |
131 if (z->useDaylightTime()) | |
132 errln("Fail: Fix test to start with non-DST zone"); | |
133 z->setStartRule(UCAL_FEBRUARY, 1, UCAL_SUNDAY, 0, status); | |
134 failure(status, "z->setStartRule()"); | |
135 z->setEndRule(UCAL_MARCH, -1, UCAL_SUNDAY, 0, status); | |
136 failure(status, "z->setStartRule()"); | |
137 if (!z->useDaylightTime()) | |
138 errln("Fail: DST not active"); | |
139 | |
140 GregorianCalendar cal(1997, UCAL_JANUARY, 31, status); | |
141 if(U_FAILURE(status)) { | |
142 dataerrln("Error creating calendar %s", u_errorName(status)); | |
143 return; | |
144 } | |
145 failure(status, "new GregorianCalendar"); | |
146 cal.adoptTimeZone(z); | |
147 | |
148 SimpleDateFormat sdf((UnicodeString)"E d MMM yyyy G HH:mm", status); | |
149 if(U_FAILURE(status)) { | |
150 dataerrln("Error creating date format %s", u_errorName(status)); | |
151 return; | |
152 } | |
153 sdf.setCalendar(cal); | |
154 failure(status, "new SimpleDateFormat"); | |
155 | |
156 UDate jan31, mar1, mar31; | |
157 | |
158 UBool indt = z->inDaylightTime(jan31=cal.getTime(status), status); | |
159 failure(status, "inDaylightTime or getTime call on Jan 31"); | |
160 if (indt) { | |
161 errln("Fail: Jan 31 inDaylightTime=TRUE, exp FALSE"); | |
162 } | |
163 cal.set(1997, UCAL_MARCH, 1); | |
164 indt = z->inDaylightTime(mar1=cal.getTime(status), status); | |
165 failure(status, "inDaylightTime or getTime call on Mar 1"); | |
166 if (!indt) { | |
167 UnicodeString str; | |
168 sdf.format(cal.getTime(status), str); | |
169 failure(status, "getTime"); | |
170 errln((UnicodeString)"Fail: " + str + " inDaylightTime=FALSE, exp TRUE")
; | |
171 } | |
172 cal.set(1997, UCAL_MARCH, 31); | |
173 indt = z->inDaylightTime(mar31=cal.getTime(status), status); | |
174 failure(status, "inDaylightTime or getTime call on Mar 31"); | |
175 if (indt) { | |
176 errln("Fail: Mar 31 inDaylightTime=TRUE, exp FALSE"); | |
177 } | |
178 | |
179 /* | |
180 cal.set(1997, Calendar::DECEMBER, 31); | |
181 UDate dec31 = cal.getTime(status); | |
182 failure(status, "getTime"); | |
183 UDate trans = findTransitionStepwise(*z, jan31, dec31); | |
184 logln((UnicodeString)"Stepwise from " + | |
185 sdf.format(jan31, str.remove()) + "; transition at " + | |
186 (trans?sdf.format(trans, str2.remove()):(UnicodeString)"NONE")); | |
187 trans = findTransitionStepwise(*z, mar1, dec31); | |
188 logln((UnicodeString)"Stepwise from " + | |
189 sdf.format(mar1, str.remove()) + "; transition at " + | |
190 (trans?sdf.format(trans, str2.remove()):(UnicodeString)"NONE")); | |
191 trans = findTransitionStepwise(*z, mar31, dec31); | |
192 logln((UnicodeString)"Stepwise from " + | |
193 sdf.format(mar31, str.remove()) + "; transition at " + | |
194 (trans?sdf.format(trans, str2.remove()):(UnicodeString)"NONE")); | |
195 */ | |
196 } | |
197 | |
198 /** | |
199 * @bug 4084933 | |
200 * The expected behavior of TimeZone around the boundaries is: | |
201 * (Assume transition time of 2:00 AM) | |
202 * day of onset 1:59 AM STD = display name 1:59 AM ST | |
203 * 2:00 AM STD = display name 3:00 AM DT | |
204 * day of end 0:59 AM STD = display name 1:59 AM DT | |
205 * 1:00 AM STD = display name 1:00 AM ST | |
206 */ | |
207 void TimeZoneRegressionTest:: Test4084933() { | |
208 UErrorCode status = U_ZERO_ERROR; | |
209 TimeZone *tz = TimeZone::createTimeZone("PST"); | |
210 | |
211 int32_t offset1 = tz->getOffset(1, | |
212 1997, UCAL_OCTOBER, 26, UCAL_SUNDAY, (2*60*60*1000), status); | |
213 int32_t offset2 = tz->getOffset(1, | |
214 1997, UCAL_OCTOBER, 26, UCAL_SUNDAY, (2*60*60*1000)-1, status); | |
215 | |
216 int32_t offset3 = tz->getOffset(1, | |
217 1997, UCAL_OCTOBER, 26, UCAL_SUNDAY, (1*60*60*1000), status); | |
218 int32_t offset4 = tz->getOffset(1, | |
219 1997, UCAL_OCTOBER, 26, UCAL_SUNDAY, (1*60*60*1000)-1, status); | |
220 | |
221 /* | |
222 * The following was added just for consistency. It shows that going *to*
Daylight | |
223 * Savings Time (PDT) does work at 2am. | |
224 */ | |
225 int32_t offset5 = tz->getOffset(1, | |
226 1997, UCAL_APRIL, 6, UCAL_SUNDAY, (2*60*60*1000), status); | |
227 int32_t offset6 = tz->getOffset(1, | |
228 1997, UCAL_APRIL, 6, UCAL_SUNDAY, (2*60*60*1000)-1, status); | |
229 int32_t offset5a = tz->getOffset(1, | |
230 1997, UCAL_APRIL, 6, UCAL_SUNDAY, (3*60*60*1000), status); | |
231 int32_t offset6a = tz->getOffset(1, | |
232 1997, UCAL_APRIL, 6, UCAL_SUNDAY, (3*60*60*1000)-1, status); | |
233 int32_t offset7 = tz->getOffset(1, | |
234 1997, UCAL_APRIL, 6, UCAL_SUNDAY, (1*60*60*1000), status); | |
235 int32_t offset8 = tz->getOffset(1, | |
236 1997, UCAL_APRIL, 6, UCAL_SUNDAY, (1*60*60*1000)-1, status); | |
237 int32_t SToffset = (int32_t)(-8 * 60*60*1000L); | |
238 int32_t DToffset = (int32_t)(-7 * 60*60*1000L); | |
239 | |
240 #define ERR_IF_FAIL(x) if(x) { dataerrln("FAIL: TimeZone misbehaving - %s", #x);
} | |
241 | |
242 ERR_IF_FAIL(U_FAILURE(status)) | |
243 ERR_IF_FAIL(offset1 != SToffset) | |
244 ERR_IF_FAIL(offset2 != SToffset) | |
245 ERR_IF_FAIL(offset3 != SToffset) | |
246 ERR_IF_FAIL(offset4 != DToffset) | |
247 ERR_IF_FAIL(offset5 != DToffset) | |
248 ERR_IF_FAIL(offset6 != SToffset) | |
249 ERR_IF_FAIL(offset5a != DToffset) | |
250 ERR_IF_FAIL(offset6a != DToffset) | |
251 ERR_IF_FAIL(offset7 != SToffset) | |
252 ERR_IF_FAIL(offset8 != SToffset) | |
253 | |
254 #undef ERR_IF_FAIL | |
255 | |
256 delete tz; | |
257 } | |
258 | |
259 /** | |
260 * @bug 4096952 | |
261 */ | |
262 void TimeZoneRegressionTest:: Test4096952() { | |
263 // {sfb} serialization not applicable | |
264 /* | |
265 UnicodeString ZONES [] = { UnicodeString("GMT"), UnicodeString("MET"), Unico
deString("IST") }; | |
266 UBool pass = TRUE; | |
267 //try { | |
268 for (int32_t i=0; i < ZONES.length; ++i) { | |
269 TimeZone *zone = TimeZone::createTimeZone(ZONES[i]); | |
270 UnicodeString id; | |
271 if (zone->getID(id) != ZONES[i]) | |
272 errln("Fail: Test broken; zones not instantiating"); | |
273 | |
274 ByteArrayOutputStream baos; | |
275 ObjectOutputStream ostream = | |
276 new ObjectOutputStream(baos = new | |
277 ByteArrayOutputStream()); | |
278 ostream.writeObject(zone); | |
279 ostream.close(); | |
280 baos.close(); | |
281 ObjectInputStream istream = | |
282 new ObjectInputStream(new | |
283 ByteArrayInputStream(baos.toByteArray())); | |
284 TimeZone frankenZone = (TimeZone) istream.readObject(); | |
285 //logln("Zone: " + zone); | |
286 //logln("FrankenZone: " + frankenZone); | |
287 if (!zone.equals(frankenZone)) { | |
288 logln("TimeZone " + zone.getID() + | |
289 " not equal to serialized/deserialized one"); | |
290 pass = false; | |
291 } | |
292 } | |
293 if (!pass) errln("Fail: TimeZone serialization/equality bug"); | |
294 } | |
295 catch (IOException e) { | |
296 errln("Fail: " + e); | |
297 e.print32_tStackTrace(); | |
298 } | |
299 catch (ClassNotFoundException e) { | |
300 errln("Fail: " + e); | |
301 e.print32_tStackTrace(); | |
302 } | |
303 */ | |
304 } | |
305 | |
306 /** | |
307 * @bug 4109314 | |
308 */ | |
309 void TimeZoneRegressionTest:: Test4109314() { | |
310 UErrorCode status = U_ZERO_ERROR; | |
311 GregorianCalendar *testCal = (GregorianCalendar*)Calendar::createInstance(st
atus); | |
312 if(U_FAILURE(status)) { | |
313 dataerrln("Error creating calendar %s", u_errorName(status)); | |
314 delete testCal; | |
315 return; | |
316 } | |
317 failure(status, "Calendar::createInstance"); | |
318 TimeZone *PST = TimeZone::createTimeZone("PST"); | |
319 /*Object[] testData = { | |
320 PST, new Date(98,Calendar.APRIL,4,22,0), new Date(98, Calendar.APRIL, 5,
6,0), | |
321 PST, new Date(98,Calendar.OCTOBER,24,22,0), new Date(98,Calendar.OCTOBER
,25,6,0), | |
322 };*/ | |
323 UDate testData [] = { | |
324 CalendarRegressionTest::makeDate(98,UCAL_APRIL,4,22,0), | |
325 CalendarRegressionTest::makeDate(98, UCAL_APRIL,5,6,0), | |
326 CalendarRegressionTest::makeDate(98,UCAL_OCTOBER,24,22,0), | |
327 CalendarRegressionTest::makeDate(98,UCAL_OCTOBER,25,6,0) | |
328 }; | |
329 UBool pass = TRUE; | |
330 for (int32_t i = 0; i < 4; i+=2) { | |
331 //testCal->setTimeZone((TimeZone) testData[i]); | |
332 testCal->setTimeZone(*PST); | |
333 UDate t = testData[i]; | |
334 UDate end = testData[i+1]; | |
335 while(testCal->getTime(status) < end) { | |
336 testCal->setTime(t, status); | |
337 if ( ! checkCalendar314(testCal, PST)) | |
338 pass = FALSE; | |
339 t += 60*60*1000.0; | |
340 } | |
341 } | |
342 if ( ! pass) | |
343 errln("Fail: TZ API inconsistent"); | |
344 | |
345 delete testCal; | |
346 delete PST; | |
347 } | |
348 | |
349 UBool | |
350 TimeZoneRegressionTest::checkCalendar314(GregorianCalendar *testCal, TimeZone *t
estTZ) | |
351 { | |
352 UErrorCode status = U_ZERO_ERROR; | |
353 // GregorianCalendar testCal = (GregorianCalendar)aCal.clone(); | |
354 | |
355 int32_t tzOffset, tzRawOffset; | |
356 float tzOffsetFloat,tzRawOffsetFloat; | |
357 // Here is where the user made an error. They were passing in the value of | |
358 // the MILLSECOND field; you need to pass in the millis in the day in STANDA
RD | |
359 // time. | |
360 UDate millis = testCal->get(UCAL_MILLISECOND, status) + | |
361 1000.0 * (testCal->get(UCAL_SECOND, status) + | |
362 60.0 * (testCal->get(UCAL_MINUTE, status) + | |
363 60.0 * (testCal->get(UCAL_HOUR_OF_DAY, status)))) - | |
364 testCal->get(UCAL_DST_OFFSET, status); | |
365 | |
366 /* Fix up millis to be in range. ASSUME THAT WE ARE NOT AT THE | |
367 * BEGINNING OR END OF A MONTH. We must add this code because | |
368 * getOffset() has been changed to be more strict about the parameters | |
369 * it receives -- it turns out that this test was passing in illegal | |
370 * values. */ | |
371 int32_t date = testCal->get(UCAL_DATE, status); | |
372 int32_t dow = testCal->get(UCAL_DAY_OF_WEEK, status); | |
373 while(millis < 0) { | |
374 millis += U_MILLIS_PER_DAY; | |
375 --date; | |
376 dow = UCAL_SUNDAY + ((dow - UCAL_SUNDAY + 6) % 7); | |
377 } | |
378 while (millis >= U_MILLIS_PER_DAY) { | |
379 millis -= U_MILLIS_PER_DAY; | |
380 ++date; | |
381 dow = UCAL_SUNDAY + ((dow - UCAL_SUNDAY + 1) % 7); | |
382 } | |
383 | |
384 tzOffset = testTZ->getOffset((uint8_t)testCal->get(UCAL_ERA, status), | |
385 testCal->get(UCAL_YEAR, status), | |
386 testCal->get(UCAL_MONTH, status), | |
387 date, | |
388 (uint8_t)dow, | |
389 (int32_t)millis, | |
390 status); | |
391 tzRawOffset = testTZ->getRawOffset(); | |
392 tzOffsetFloat = (float)tzOffset/(float)3600000; | |
393 tzRawOffsetFloat = (float)tzRawOffset/(float)3600000; | |
394 | |
395 UDate testDate = testCal->getTime(status); | |
396 | |
397 UBool inDaylightTime = testTZ->inDaylightTime(testDate, status); | |
398 SimpleDateFormat *sdf = new SimpleDateFormat((UnicodeString)"MM/dd/yyyy HH:m
m", status); | |
399 sdf->setCalendar(*testCal); | |
400 UnicodeString inDaylightTimeString; | |
401 | |
402 UBool passed; | |
403 | |
404 if(inDaylightTime) | |
405 { | |
406 inDaylightTimeString = " DST "; | |
407 passed = (tzOffset == (tzRawOffset + 3600000)); | |
408 } | |
409 else | |
410 { | |
411 inDaylightTimeString = " "; | |
412 passed = (tzOffset == tzRawOffset); | |
413 } | |
414 | |
415 UnicodeString output; | |
416 FieldPosition pos(0); | |
417 output = testTZ->getID(output) + " " + sdf->format(testDate, output, pos) + | |
418 " Offset(" + tzOffsetFloat + ")" + | |
419 " RawOffset(" + tzRawOffsetFloat + ")" + | |
420 " " + millis/(float)3600000 + " " + | |
421 inDaylightTimeString; | |
422 | |
423 if (passed) | |
424 output += " "; | |
425 else | |
426 output += "ERROR"; | |
427 | |
428 if (passed) | |
429 logln(output); | |
430 else | |
431 errln(output); | |
432 | |
433 delete sdf; | |
434 return passed; | |
435 } | |
436 | |
437 /** | |
438 * @bug 4126678 | |
439 * CANNOT REPRODUDE | |
440 * | |
441 * Yet another _alleged_ bug in TimeZone::getOffset(), a method that never | |
442 * should have been made public. It's simply too hard to use correctly. | |
443 * | |
444 * The original test code failed to do the following: | |
445 * (1) Call Calendar::setTime() before getting the fields! | |
446 * (2) Use the right millis (as usual) for getOffset(); they were passing | |
447 * in the MILLIS field, instead of the STANDARD MILLIS IN DAY. | |
448 * When you fix these two problems, the test passes, as expected. | |
449 */ | |
450 void TimeZoneRegressionTest:: Test4126678() | |
451 { | |
452 UErrorCode status = U_ZERO_ERROR; | |
453 Calendar *cal = Calendar::createInstance(status); | |
454 if(U_FAILURE(status)) { | |
455 dataerrln("Error creating calendar %s", u_errorName(status)); | |
456 delete cal; | |
457 return; | |
458 } | |
459 failure(status, "Calendar::createInstance"); | |
460 TimeZone *tz = TimeZone::createTimeZone("PST"); | |
461 cal->adoptTimeZone(tz); | |
462 | |
463 cal->set(1998, UCAL_APRIL, 5, 10, 0); | |
464 | |
465 if (! tz->useDaylightTime() || U_FAILURE(status)) | |
466 dataerrln("We're not in Daylight Savings Time and we should be. - %s", u
_errorName(status)); | |
467 | |
468 //cal.setTime(dt); | |
469 int32_t era = cal->get(UCAL_ERA, status); | |
470 int32_t year = cal->get(UCAL_YEAR, status); | |
471 int32_t month = cal->get(UCAL_MONTH, status); | |
472 int32_t day = cal->get(UCAL_DATE, status); | |
473 int32_t dayOfWeek = cal->get(UCAL_DAY_OF_WEEK, status); | |
474 int32_t millis = cal->get(UCAL_MILLISECOND, status) + | |
475 (cal->get(UCAL_SECOND, status) + | |
476 (cal->get(UCAL_MINUTE, status) + | |
477 (cal->get(UCAL_HOUR, status) * 60) * 60) * 1000) - | |
478 cal->get(UCAL_DST_OFFSET, status); | |
479 | |
480 failure(status, "cal->get"); | |
481 int32_t offset = tz->getOffset((uint8_t)era, year, month, day, (uint8_t)dayO
fWeek, millis, status); | |
482 int32_t raw_offset = tz->getRawOffset(); | |
483 | |
484 if (offset == raw_offset) | |
485 dataerrln("Offsets should match"); | |
486 | |
487 delete cal; | |
488 } | |
489 | |
490 /** | |
491 * @bug 4151406 | |
492 * TimeZone::getAvailableIDs(int32_t) throws exception for certain values, | |
493 * due to a faulty constant in TimeZone::java. | |
494 */ | |
495 void TimeZoneRegressionTest:: Test4151406() { | |
496 int32_t max = 0; | |
497 for (int32_t h=-28; h<=30; ++h) { | |
498 // h is in half-hours from GMT; rawoffset is in millis | |
499 int32_t rawoffset = h * 1800000; | |
500 int32_t hh = (h<0) ? -h : h; | |
501 UnicodeString hname = UnicodeString((h<0) ? "GMT-" : "GMT+") + | |
502 ((hh/2 < 10) ? "0" : "") + | |
503 (hh/2) + ':' + | |
504 ((hh%2==0) ? "00" : "30"); | |
505 //try { | |
506 UErrorCode ec = U_ZERO_ERROR; | |
507 int32_t count; | |
508 StringEnumeration* ids = TimeZone::createEnumeration(rawoffset); | |
509 if (ids == NULL) { | |
510 dataerrln("Fail: TimeZone::createEnumeration(rawoffset)"); | |
511 continue; | |
512 } | |
513 count = ids->count(ec); | |
514 if (count> max) | |
515 max = count; | |
516 if (count > 0) { | |
517 logln(hname + ' ' + (UnicodeString)count + (UnicodeString)" e.g.
" + *ids->snext(ec)); | |
518 } else { | |
519 logln(hname + ' ' + count); | |
520 } | |
521 // weiv 11/27/2002: why uprv_free? This should be a delete | |
522 delete ids; | |
523 //delete [] ids; | |
524 //uprv_free(ids); | |
525 /*} catch (Exception e) { | |
526 errln(hname + ' ' + "Fail: " + e); | |
527 }*/ | |
528 } | |
529 logln("Maximum zones per offset = %d", max); | |
530 } | |
531 | |
532 /** | |
533 * @bug 4151429 | |
534 */ | |
535 void TimeZoneRegressionTest:: Test4151429() { | |
536 // {sfb} silly test in C++, since we are using an enum and not an int | |
537 //try { | |
538 /*TimeZone *tz = TimeZone::createTimeZone("GMT"); | |
539 UnicodeString name; | |
540 tz->getDisplayName(TRUE, TimeZone::LONG, | |
541 Locale.getDefault(), name); | |
542 errln("IllegalArgumentException not thrown by TimeZone::getDisplayName()
");*/ | |
543 //} catch(IllegalArgumentException e) {} | |
544 } | |
545 | |
546 /** | |
547 * @bug 4154537 | |
548 * SimpleTimeZone::hasSameRules() doesn't work for zones with no DST | |
549 * and different DST parameters. | |
550 */ | |
551 void TimeZoneRegressionTest:: Test4154537() { | |
552 UErrorCode status = U_ZERO_ERROR; | |
553 // tz1 and tz2 have no DST and different rule parameters | |
554 SimpleTimeZone *tz1 = new SimpleTimeZone(0, "1", 0, 0, 0, 0, 2, 0, 0, 0, sta
tus); | |
555 SimpleTimeZone *tz2 = new SimpleTimeZone(0, "2", 1, 0, 0, 0, 3, 0, 0, 0, sta
tus); | |
556 // tza and tzA have the same rule params | |
557 SimpleTimeZone *tza = new SimpleTimeZone(0, "a", 0, 1, 0, 0, 3, 2, 0, 0, sta
tus); | |
558 SimpleTimeZone *tzA = new SimpleTimeZone(0, "A", 0, 1, 0, 0, 3, 2, 0, 0, sta
tus); | |
559 // tzb differs from tza | |
560 SimpleTimeZone *tzb = new SimpleTimeZone(0, "b", 0, 1, 0, 0, 3, 1, 0, 0, sta
tus); | |
561 | |
562 if(U_FAILURE(status)) | |
563 errln("Couldn't create TimeZones"); | |
564 | |
565 if (tz1->useDaylightTime() || tz2->useDaylightTime() || | |
566 !tza->useDaylightTime() || !tzA->useDaylightTime() || | |
567 !tzb->useDaylightTime()) { | |
568 errln("Test is broken -- rewrite it"); | |
569 } | |
570 if (!tza->hasSameRules(*tzA) || tza->hasSameRules(*tzb)) { | |
571 errln("Fail: hasSameRules() broken for zones with rules"); | |
572 } | |
573 if (!tz1->hasSameRules(*tz2)) { | |
574 errln("Fail: hasSameRules() returns false for zones without rules"); | |
575 //errln("zone 1 = " + tz1); | |
576 //errln("zone 2 = " + tz2); | |
577 } | |
578 | |
579 delete tz1; | |
580 delete tz2; | |
581 delete tza; | |
582 delete tzA; | |
583 delete tzb; | |
584 } | |
585 | |
586 /** | |
587 * @bug 4154542 | |
588 * SimpleTimeZOne constructors, setStartRule(), and setEndRule() don't | |
589 * check for out-of-range arguments. | |
590 */ | |
591 void TimeZoneRegressionTest:: Test4154542() | |
592 { | |
593 const int32_t GOOD = 1; | |
594 const int32_t BAD = 0; | |
595 | |
596 const int32_t GOOD_MONTH = UCAL_JANUARY; | |
597 const int32_t GOOD_DAY = 1; | |
598 const int32_t GOOD_DAY_OF_WEEK = UCAL_SUNDAY; | |
599 const int32_t GOOD_TIME = 0; | |
600 | |
601 int32_t DATA [] = { | |
602 GOOD, INT32_MIN, 0, INT32_MAX, INT32_MIN, | |
603 GOOD, UCAL_JANUARY, -5, UCAL_SUNDAY, 0, | |
604 GOOD, UCAL_DECEMBER, 5, UCAL_SATURDAY, 24*60*60*1000, | |
605 BAD, UCAL_DECEMBER, 5, UCAL_SATURDAY, 24*60*60*1000+1, | |
606 BAD, UCAL_DECEMBER, 5, UCAL_SATURDAY, -1, | |
607 BAD, UCAL_JANUARY, -6, UCAL_SUNDAY, 0, | |
608 BAD, UCAL_DECEMBER, 6, UCAL_SATURDAY, 24*60*60*1000, | |
609 GOOD, UCAL_DECEMBER, 1, 0, 0, | |
610 GOOD, UCAL_DECEMBER, 31, 0, 0, | |
611 BAD, UCAL_APRIL, 31, 0, 0, | |
612 BAD, UCAL_DECEMBER, 32, 0, 0, | |
613 BAD, UCAL_JANUARY-1, 1, UCAL_SUNDAY, 0, | |
614 BAD, UCAL_DECEMBER+1, 1, UCAL_SUNDAY, 0, | |
615 GOOD, UCAL_DECEMBER, 31, -UCAL_SUNDAY, 0, | |
616 GOOD, UCAL_DECEMBER, 31, -UCAL_SATURDAY, 0, | |
617 BAD, UCAL_DECEMBER, 32, -UCAL_SATURDAY, 0, | |
618 BAD, UCAL_DECEMBER, -32, -UCAL_SATURDAY, 0, | |
619 BAD, UCAL_DECEMBER, 31, -UCAL_SATURDAY-1, 0, | |
620 }; | |
621 SimpleTimeZone *zone = new SimpleTimeZone(0, "Z"); | |
622 for (int32_t i=0; i < 18*5; i+=5) { | |
623 UBool shouldBeGood = (DATA[i] == GOOD); | |
624 int32_t month = DATA[i+1]; | |
625 int32_t day = DATA[i+2]; | |
626 int32_t dayOfWeek = DATA[i+3]; | |
627 int32_t time = DATA[i+4]; | |
628 | |
629 UErrorCode status = U_ZERO_ERROR; | |
630 | |
631 //Exception ex = null; | |
632 //try { | |
633 zone->setStartRule(month, day, dayOfWeek, time, status); | |
634 //} catch (IllegalArgumentException e) { | |
635 // ex = e; | |
636 //} | |
637 if (U_SUCCESS(status) != shouldBeGood) { | |
638 errln(UnicodeString("setStartRule(month=") + month + ", day=" + day
+ | |
639 ", dayOfWeek=" + dayOfWeek + ", time=" + time + | |
640 (shouldBeGood ? (") should work") | |
641 : ") should fail but doesn't")); | |
642 } | |
643 | |
644 //ex = null; | |
645 //try { | |
646 status = U_ZERO_ERROR; | |
647 zone->setEndRule(month, day, dayOfWeek, time, status); | |
648 //} catch (IllegalArgumentException e) { | |
649 // ex = e; | |
650 //} | |
651 if (U_SUCCESS(status) != shouldBeGood) { | |
652 errln(UnicodeString("setEndRule(month=") + month + ", day=" + day + | |
653 ", dayOfWeek=" + dayOfWeek + ", time=" + time + | |
654 (shouldBeGood ? (") should work") | |
655 : ") should fail but doesn't")); | |
656 } | |
657 | |
658 //ex = null; | |
659 //try { | |
660 // {sfb} need to look into ctor problems! (UErrorCode vs. dst signature
confusion) | |
661 status = U_ZERO_ERROR; | |
662 SimpleTimeZone *temp = new SimpleTimeZone(0, "Z", | |
663 (int8_t)month, (int8_t)day, (int8_t)dayOfWeek, time, | |
664 (int8_t)GOOD_MONTH, (int8_t)GOOD_DAY, (int8_t)GOOD_DAY_OF_WE
EK, | |
665 GOOD_TIME,status); | |
666 //} catch (IllegalArgumentException e) { | |
667 // ex = e; | |
668 //} | |
669 if (U_SUCCESS(status) != shouldBeGood) { | |
670 errln(UnicodeString("SimpleTimeZone(month=") + month + ", day=" + da
y + | |
671 ", dayOfWeek=" + dayOfWeek + ", time=" + time + | |
672 (shouldBeGood ? (", <end>) should work")// + ex) | |
673 : ", <end>) should fail but doesn't")); | |
674 } | |
675 | |
676 delete temp; | |
677 //ex = null; | |
678 //try { | |
679 status = U_ZERO_ERROR; | |
680 temp = new SimpleTimeZone(0, "Z", | |
681 (int8_t)GOOD_MONTH, (int8_t)GOOD_DAY, (int8_t)GOOD_DAY_OF_WE
EK, | |
682 GOOD_TIME, | |
683 (int8_t)month, (int8_t)day, (int8_t)dayOfWeek, time,status); | |
684 //} catch (IllegalArgumentException e) { | |
685 // ex = e; | |
686 //} | |
687 if (U_SUCCESS(status) != shouldBeGood) { | |
688 errln(UnicodeString("SimpleTimeZone(<start>, month=") + month + ", d
ay=" + day + | |
689 ", dayOfWeek=" + dayOfWeek + ", time=" + time + | |
690 (shouldBeGood ? (") should work")// + ex) | |
691 : ") should fail but doesn't")); | |
692 } | |
693 delete temp; | |
694 } | |
695 delete zone; | |
696 } | |
697 | |
698 | |
699 /** | |
700 * @bug 4154525 | |
701 * SimpleTimeZone accepts illegal DST savings values. These values | |
702 * must be non-zero. There is no upper limit at this time. | |
703 */ | |
704 void | |
705 TimeZoneRegressionTest::Test4154525() | |
706 { | |
707 const int32_t GOOD = 1, BAD = 0; | |
708 | |
709 int32_t DATA [] = { | |
710 1, GOOD, | |
711 0, BAD, | |
712 -1, BAD, | |
713 60*60*1000, GOOD, | |
714 INT32_MIN, BAD, | |
715 // Integer.MAX_VALUE, ?, // no upper limit on DST savings at this time | |
716 }; | |
717 | |
718 UErrorCode status = U_ZERO_ERROR; | |
719 for(int32_t i = 0; i < 10; i+=2) { | |
720 int32_t savings = DATA[i]; | |
721 UBool valid = DATA[i+1] == GOOD; | |
722 UnicodeString method; | |
723 for(int32_t j=0; j < 2; ++j) { | |
724 SimpleTimeZone *z=NULL; | |
725 switch (j) { | |
726 case 0: | |
727 method = "constructor"; | |
728 z = new SimpleTimeZone(0, "id", | |
729 UCAL_JANUARY, 1, 0, 0, | |
730 UCAL_MARCH, 1, 0, 0, | |
731 savings, status); // <- what we're interested in | |
732 break; | |
733 case 1: | |
734 method = "setDSTSavings()"; | |
735 z = new SimpleTimeZone(0, "GMT"); | |
736 z->setDSTSavings(savings, status); | |
737 break; | |
738 } | |
739 | |
740 if(U_FAILURE(status)) { | |
741 if(valid) { | |
742 errln(UnicodeString("Fail: DST savings of ") + savings + " t
o " + method + " gave " + u_errorName(status)); | |
743 } | |
744 else { | |
745 logln(UnicodeString("Pass: DST savings of ") + savings + " t
o " + method + " gave " + u_errorName(status)); | |
746 } | |
747 } | |
748 else { | |
749 if(valid) { | |
750 logln(UnicodeString("Pass: DST savings of ") + savings + " a
ccepted by " + method); | |
751 } | |
752 else { | |
753 errln(UnicodeString("Fail: DST savings of ") + savings + " a
ccepted by " + method); | |
754 } | |
755 } | |
756 status = U_ZERO_ERROR; | |
757 delete z; | |
758 } | |
759 } | |
760 } | |
761 | |
762 /** | |
763 * @bug 4154650 | |
764 * SimpleTimeZone.getOffset accepts illegal arguments. | |
765 */ | |
766 void | |
767 TimeZoneRegressionTest::Test4154650() | |
768 { | |
769 const int32_t GOOD = 1, BAD = 0; | |
770 const int32_t GOOD_ERA = GregorianCalendar::AD, GOOD_YEAR = 1998, GOOD_MONTH
= UCAL_AUGUST; | |
771 const int32_t GOOD_DAY = 2, GOOD_DOW = UCAL_SUNDAY, GOOD_TIME = 16*3600000; | |
772 | |
773 int32_t DATA []= { | |
774 GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, GOOD_TIME, | |
775 | |
776 GOOD, GregorianCalendar::BC, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW,
GOOD_TIME, | |
777 GOOD, GregorianCalendar::AD, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW,
GOOD_TIME, | |
778 BAD, GregorianCalendar::BC-1, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW
, GOOD_TIME, | |
779 BAD, GregorianCalendar::AD+1, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW
, GOOD_TIME, | |
780 | |
781 GOOD, GOOD_ERA, GOOD_YEAR, UCAL_JANUARY, GOOD_DAY, GOOD_DOW, GOOD_TIME, | |
782 GOOD, GOOD_ERA, GOOD_YEAR, UCAL_DECEMBER, GOOD_DAY, GOOD_DOW, GOOD_TIME, | |
783 BAD, GOOD_ERA, GOOD_YEAR, UCAL_JANUARY-1, GOOD_DAY, GOOD_DOW, GOOD_TIME
, | |
784 BAD, GOOD_ERA, GOOD_YEAR, UCAL_DECEMBER+1, GOOD_DAY, GOOD_DOW, GOOD_TIM
E, | |
785 | |
786 GOOD, GOOD_ERA, GOOD_YEAR, UCAL_JANUARY, 1, GOOD_DOW, GOOD_TIME, | |
787 GOOD, GOOD_ERA, GOOD_YEAR, UCAL_JANUARY, 31, GOOD_DOW, GOOD_TIME, | |
788 BAD, GOOD_ERA, GOOD_YEAR, UCAL_JANUARY, 0, GOOD_DOW, GOOD_TIME, | |
789 BAD, GOOD_ERA, GOOD_YEAR, UCAL_JANUARY, 32, GOOD_DOW, GOOD_TIME, | |
790 | |
791 GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, UCAL_SUNDAY, GOOD_TIME, | |
792 GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, UCAL_SATURDAY, GOOD_TIM
E, | |
793 BAD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, UCAL_SUNDAY-1, GOOD_TIM
E, | |
794 BAD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, UCAL_SATURDAY+1, GOOD_T
IME, | |
795 | |
796 GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, 0, | |
797 GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, 24*3600000-1, | |
798 BAD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, -1, | |
799 BAD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, 24*3600000, | |
800 }; | |
801 | |
802 int32_t dataLen = (int32_t)(sizeof(DATA) / sizeof(DATA[0])); | |
803 | |
804 UErrorCode status = U_ZERO_ERROR; | |
805 TimeZone *tz = TimeZone::createDefault(); | |
806 for(int32_t i = 0; i < dataLen; i += 7) { | |
807 UBool good = DATA[i] == GOOD; | |
808 //IllegalArgumentException e = null; | |
809 //try { | |
810 /*int32_t offset = */ | |
811 tz->getOffset((uint8_t)DATA[i+1], DATA[i+2], DATA[i+3], | |
812 DATA[i+4], (uint8_t)DATA[i+5], DATA[i+6], status); | |
813 //} catch (IllegalArgumentException ex) { | |
814 // e = ex; | |
815 //} | |
816 if(good != U_SUCCESS(status)) { | |
817 UnicodeString errMsg; | |
818 if (good) { | |
819 errMsg = (UnicodeString(") threw ") + u_errorName(status)); | |
820 } | |
821 else { | |
822 errMsg = UnicodeString(") accepts invalid args", ""); | |
823 } | |
824 errln(UnicodeString("Fail: getOffset(") + | |
825 DATA[i+1] + ", " + DATA[i+2] + ", " + DATA[i+3] + ", " + | |
826 DATA[i+4] + ", " + DATA[i+5] + ", " + DATA[i+6] + | |
827 errMsg); | |
828 } | |
829 status = U_ZERO_ERROR; // reset | |
830 } | |
831 delete tz; | |
832 } | |
833 | |
834 /** | |
835 * @bug 4162593 | |
836 * TimeZone broken at midnight. The TimeZone code fails to handle | |
837 * transitions at midnight correctly. | |
838 */ | |
839 void | |
840 TimeZoneRegressionTest::Test4162593() | |
841 { | |
842 UErrorCode status = U_ZERO_ERROR; | |
843 SimpleDateFormat *fmt = new SimpleDateFormat("z", Locale::getUS(), status); | |
844 if(U_FAILURE(status)) { | |
845 dataerrln("Error creating calendar %s", u_errorName(status)); | |
846 delete fmt; | |
847 return; | |
848 } | |
849 const int32_t ONE_HOUR = 60*60*1000; | |
850 | |
851 SimpleTimeZone *asuncion = new SimpleTimeZone(-4*ONE_HOUR, "America/Asuncion
" /*PY%sT*/, | |
852 UCAL_OCTOBER, 1, 0 /*DOM*/, 0*ONE_HOUR, | |
853 UCAL_MARCH, 1, 0 /*DOM*/, 0*ONE_HOUR, 1*ONE_HOUR, status); | |
854 | |
855 /* Zone | |
856 * Starting time | |
857 * Transition expected between start+1H and start+2H | |
858 */ | |
859 TimeZone *DATA_TZ [] = { | |
860 0, 0, 0 }; | |
861 | |
862 int32_t DATA_INT [] [5] = { | |
863 // These years must be AFTER the Gregorian cutover | |
864 {1998, UCAL_SEPTEMBER, 30, 22, 0}, | |
865 {2000, UCAL_FEBRUARY, 28, 22, 0}, | |
866 {2000, UCAL_FEBRUARY, 29, 22, 0}, | |
867 }; | |
868 | |
869 UBool DATA_BOOL [] = { | |
870 TRUE, | |
871 FALSE, | |
872 TRUE, | |
873 }; | |
874 | |
875 UnicodeString zone [4];// = new String[4]; | |
876 DATA_TZ[0] = | |
877 new SimpleTimeZone(2*ONE_HOUR, "Asia/Damascus" /*EE%sT*/, | |
878 UCAL_APRIL, 1, 0 /*DOM*/, 0*ONE_HOUR, | |
879 UCAL_OCTOBER, 1, 0 /*DOM*/, 0*ONE_HOUR, 1*ONE_HOUR, status); | |
880 DATA_TZ[1] = asuncion; DATA_TZ[2] = asuncion; | |
881 | |
882 for(int32_t j = 0; j < 3; j++) { | |
883 TimeZone *tz = (TimeZone*)DATA_TZ[j]; | |
884 TimeZone::setDefault(*tz); | |
885 fmt->setTimeZone(*tz); | |
886 | |
887 // Must construct the Date object AFTER setting the default zone | |
888 int32_t *p = (int32_t*)DATA_INT[j]; | |
889 UDate d = CalendarRegressionTest::makeDate(p[0], p[1], p[2], p[3], p[4])
; | |
890 UBool transitionExpected = DATA_BOOL[j]; | |
891 | |
892 UnicodeString temp; | |
893 logln(tz->getID(temp) + ":"); | |
894 for (int32_t i = 0; i < 4; ++i) { | |
895 FieldPosition pos(0); | |
896 zone[i].remove(); | |
897 zone[i] = fmt->format(d+ i*ONE_HOUR, zone[i], pos); | |
898 logln(UnicodeString("") + i + ": " + d + " / " + zone[i]); | |
899 //d += (double) ONE_HOUR; | |
900 } | |
901 if(zone[0] == zone[1] && | |
902 (zone[1] == zone[2]) != transitionExpected && | |
903 zone[2] == zone[3]) { | |
904 logln(UnicodeString("Ok: transition ") + transitionExpected); | |
905 } | |
906 else { | |
907 errln("Fail: boundary transition incorrect"); | |
908 } | |
909 } | |
910 delete fmt; | |
911 delete asuncion; | |
912 delete DATA_TZ[0]; | |
913 } | |
914 | |
915 /** | |
916 * getDisplayName doesn't work with unusual savings/offsets. | |
917 */ | |
918 void TimeZoneRegressionTest::Test4176686() { | |
919 // Construct a zone that does not observe DST but | |
920 // that does have a DST savings (which should be ignored). | |
921 UErrorCode status = U_ZERO_ERROR; | |
922 int32_t offset = 90 * 60000; // 1:30 | |
923 SimpleTimeZone* z1 = new SimpleTimeZone(offset, "_std_zone_"); | |
924 z1->setDSTSavings(45 * 60000, status); // 0:45 | |
925 | |
926 // Construct a zone that observes DST for the first 6 months. | |
927 SimpleTimeZone* z2 = new SimpleTimeZone(offset, "_dst_zone_"); | |
928 z2->setDSTSavings(45 * 60000, status); // 0:45 | |
929 z2->setStartRule(UCAL_JANUARY, 1, 0, status); | |
930 z2->setEndRule(UCAL_JULY, 1, 0, status); | |
931 | |
932 // Also check DateFormat | |
933 DateFormat* fmt1 = new SimpleDateFormat(UnicodeString("z"), status); | |
934 if (U_FAILURE(status)) { | |
935 dataerrln("Failure trying to construct: %s", u_errorName(status)); | |
936 return; | |
937 } | |
938 fmt1->setTimeZone(*z1); // Format uses standard zone | |
939 DateFormat* fmt2 = new SimpleDateFormat(UnicodeString("z"), status); | |
940 if(!assertSuccess("trying to construct", status))return; | |
941 fmt2->setTimeZone(*z2); // Format uses DST zone | |
942 Calendar* tempcal = Calendar::createInstance(status); | |
943 tempcal->clear(); | |
944 tempcal->set(1970, UCAL_FEBRUARY, 1); | |
945 UDate dst = tempcal->getTime(status); // Time in DST | |
946 tempcal->set(1970, UCAL_AUGUST, 1); | |
947 UDate std = tempcal->getTime(status); // Time in standard | |
948 | |
949 // Description, Result, Expected Result | |
950 UnicodeString a,b,c,d,e,f,g,h,i,j,k,l; | |
951 UnicodeString DATA[] = { | |
952 "z1->getDisplayName(false, SHORT)/std zone", | |
953 z1->getDisplayName(FALSE, TimeZone::SHORT, a), "GMT+1:30", | |
954 "z1->getDisplayName(false, LONG)/std zone", | |
955 z1->getDisplayName(FALSE, TimeZone::LONG, b), "GMT+01:30", | |
956 "z1->getDisplayName(true, SHORT)/std zone", | |
957 z1->getDisplayName(TRUE, TimeZone::SHORT, c), "GMT+1:30", | |
958 "z1->getDisplayName(true, LONG)/std zone", | |
959 z1->getDisplayName(TRUE, TimeZone::LONG, d ), "GMT+01:30", | |
960 "z2->getDisplayName(false, SHORT)/dst zone", | |
961 z2->getDisplayName(FALSE, TimeZone::SHORT, e), "GMT+1:30", | |
962 "z2->getDisplayName(false, LONG)/dst zone", | |
963 z2->getDisplayName(FALSE, TimeZone::LONG, f ), "GMT+01:30", | |
964 "z2->getDisplayName(true, SHORT)/dst zone", | |
965 z2->getDisplayName(TRUE, TimeZone::SHORT, g), "GMT+2:15", | |
966 "z2->getDisplayName(true, LONG)/dst zone", | |
967 z2->getDisplayName(TRUE, TimeZone::LONG, h ), "GMT+02:15", | |
968 "DateFormat.format(std)/std zone", fmt1->format(std, i), "GMT+1:30", | |
969 "DateFormat.format(dst)/std zone", fmt1->format(dst, j), "GMT+1:30", | |
970 "DateFormat.format(std)/dst zone", fmt2->format(std, k), "GMT+1:30", | |
971 "DateFormat.format(dst)/dst zone", fmt2->format(dst, l), "GMT+2:15", | |
972 }; | |
973 | |
974 for (int32_t idx=0; idx<(int32_t)ARRAY_LENGTH(DATA); idx+=3) { | |
975 if (DATA[idx+1]!=(DATA[idx+2])) { | |
976 errln("FAIL: " + DATA[idx] + " -> " + DATA[idx+1] + ", exp " + DATA[
idx+2]); | |
977 } | |
978 } | |
979 delete z1; | |
980 delete z2; | |
981 delete fmt1; | |
982 delete fmt2; | |
983 delete tempcal; | |
984 } | |
985 | |
986 /** | |
987 * Make sure setStartRule and setEndRule set the DST savings to nonzero | |
988 * if it was zero. | |
989 */ | |
990 void TimeZoneRegressionTest::TestJ186() { | |
991 UErrorCode status = U_ZERO_ERROR; | |
992 // NOTE: Setting the DST savings to zero is illegal, so we | |
993 // are limited in the testing we can do here. This is why | |
994 // lines marked //~ are commented out. | |
995 SimpleTimeZone z(0, "ID"); | |
996 //~z.setDSTSavings(0, status); // Must do this! | |
997 z.setStartRule(UCAL_FEBRUARY, 1, UCAL_SUNDAY, 0, status); | |
998 failure(status, "setStartRule()"); | |
999 if (z.useDaylightTime()) { | |
1000 errln("Fail: useDaylightTime true with start rule only"); | |
1001 } | |
1002 //~if (z.getDSTSavings() != 0) { | |
1003 //~ errln("Fail: dst savings != 0 with start rule only"); | |
1004 //~} | |
1005 z.setEndRule(UCAL_MARCH, -1, UCAL_SUNDAY, 0, status); | |
1006 failure(status, "setStartRule()"); | |
1007 if (!z.useDaylightTime()) { | |
1008 errln("Fail: useDaylightTime false with rules set"); | |
1009 } | |
1010 if (z.getDSTSavings() == 0) { | |
1011 errln("Fail: dst savings == 0 with rules set"); | |
1012 } | |
1013 } | |
1014 | |
1015 /** | |
1016 * Test to see if DateFormat understands zone equivalency groups. It | |
1017 * might seem that this should be a DateFormat test, but it's really a | |
1018 * TimeZone test -- the changes to DateFormat are minor. | |
1019 * | |
1020 * We use two known, stable zones that shouldn't change much over time | |
1021 * -- America/Vancouver and America/Los_Angeles. However, they MAY | |
1022 * change at some point -- if that happens, replace them with any two | |
1023 * zones in an equivalency group where one zone has localized name | |
1024 * data, and the other doesn't, in some locale. | |
1025 */ | |
1026 void TimeZoneRegressionTest::TestJ449() { | |
1027 UErrorCode status = U_ZERO_ERROR; | |
1028 UnicodeString str; | |
1029 | |
1030 // Modify the following three as necessary. The two IDs must | |
1031 // specify two zones in the same equivalency group. One must have | |
1032 // locale data in 'loc'; the other must not. | |
1033 const char* idWithLocaleData = "America/Los_Angeles"; | |
1034 const char* idWithoutLocaleData = "US/Pacific"; | |
1035 const Locale loc("en", "", ""); | |
1036 | |
1037 TimeZone *zoneWith = TimeZone::createTimeZone(idWithLocaleData); | |
1038 TimeZone *zoneWithout = TimeZone::createTimeZone(idWithoutLocaleData); | |
1039 // Make sure we got valid zones | |
1040 if (zoneWith->getID(str) != UnicodeString(idWithLocaleData) || | |
1041 zoneWithout->getID(str) != UnicodeString(idWithoutLocaleData)) { | |
1042 dataerrln(UnicodeString("Fail: Unable to create zones - wanted ") + idWith
LocaleData + ", got " + zoneWith->getID(str) + ", and wanted " + idWithoutLocale
Data + " but got " + zoneWithout->getID(str)); | |
1043 } else { | |
1044 GregorianCalendar calWith(*zoneWith, status); | |
1045 GregorianCalendar calWithout(*zoneWithout, status); | |
1046 SimpleDateFormat fmt("MMM d yyyy hh:mm a zzz", loc, status); | |
1047 if (U_FAILURE(status)) { | |
1048 errln("Fail: Unable to create GregorianCalendar/SimpleDateFormat"); | |
1049 } else { | |
1050 UDate date = 0; | |
1051 UnicodeString strWith, strWithout; | |
1052 fmt.setCalendar(calWith); | |
1053 fmt.format(date, strWith); | |
1054 fmt.setCalendar(calWithout); | |
1055 fmt.format(date, strWithout); | |
1056 if (strWith == strWithout) { | |
1057 logln((UnicodeString)"Ok: " + idWithLocaleData + " -> " + | |
1058 strWith + "; " + idWithoutLocaleData + " -> " + | |
1059 strWithout); | |
1060 } else { | |
1061 errln((UnicodeString)"FAIL: " + idWithLocaleData + " -> " + | |
1062 strWith + "; " + idWithoutLocaleData + " -> " + | |
1063 strWithout); | |
1064 } | |
1065 } | |
1066 } | |
1067 | |
1068 delete zoneWith; | |
1069 delete zoneWithout; | |
1070 } | |
1071 | |
1072 // test new API for JDK 1.2 8/31 putback | |
1073 void | |
1074 TimeZoneRegressionTest::TestJDK12API() | |
1075 { | |
1076 // TimeZone *pst = TimeZone::createTimeZone("PST"); | |
1077 // TimeZone *cst1 = TimeZone::createTimeZone("CST"); | |
1078 UErrorCode ec = U_ZERO_ERROR; | |
1079 //d,-28800,3,1,-1,120,w,9,-1,1,120,w,60 | |
1080 TimeZone *pst = new SimpleTimeZone(-28800*U_MILLIS_PER_SECOND, | |
1081 "PST", | |
1082 3,1,-1,120*U_MILLIS_PER_MINUTE, | |
1083 SimpleTimeZone::WALL_TIME, | |
1084 9,-1,1,120*U_MILLIS_PER_MINUTE, | |
1085 SimpleTimeZone::WALL_TIME, | |
1086 60*U_MILLIS_PER_MINUTE,ec); | |
1087 //d,-21600,3,1,-1,120,w,9,-1,1,120,w,60 | |
1088 TimeZone *cst1 = new SimpleTimeZone(-21600*U_MILLIS_PER_SECOND, | |
1089 "CST", | |
1090 3,1,-1,120*U_MILLIS_PER_MINUTE, | |
1091 SimpleTimeZone::WALL_TIME, | |
1092 9,-1,1,120*U_MILLIS_PER_MINUTE, | |
1093 SimpleTimeZone::WALL_TIME, | |
1094 60*U_MILLIS_PER_MINUTE,ec); | |
1095 if (U_FAILURE(ec)) { | |
1096 errln("FAIL: SimpleTimeZone constructor"); | |
1097 return; | |
1098 } | |
1099 | |
1100 SimpleTimeZone *cst = dynamic_cast<SimpleTimeZone *>(cst1); | |
1101 | |
1102 if(pst->hasSameRules(*cst)) { | |
1103 errln("FAILURE: PST and CST have same rules"); | |
1104 } | |
1105 | |
1106 UErrorCode status = U_ZERO_ERROR; | |
1107 int32_t offset1 = pst->getOffset(1, | |
1108 1997, UCAL_OCTOBER, 26, UCAL_SUNDAY, (2*60*60*1000), status); | |
1109 failure(status, "getOffset() failed"); | |
1110 | |
1111 | |
1112 int32_t offset2 = cst->getOffset(1, | |
1113 1997, UCAL_OCTOBER, 26, UCAL_SUNDAY, (2*60*60*1000), 31, status); | |
1114 failure(status, "getOffset() failed"); | |
1115 | |
1116 if(offset1 == offset2) | |
1117 errln("FAILURE: Sunday Oct. 26 1997 2:00 has same offset for PST and CST
"); | |
1118 | |
1119 // verify error checking | |
1120 pst->getOffset(1, | |
1121 1997, UCAL_FIELD_COUNT+1, 26, UCAL_SUNDAY, (2*60*60*1000), status); | |
1122 if(U_SUCCESS(status)) | |
1123 errln("FAILURE: getOffset() succeeded with -1 for month"); | |
1124 | |
1125 status = U_ZERO_ERROR; | |
1126 cst->setDSTSavings(60*60*1000, status); | |
1127 failure(status, "setDSTSavings() failed"); | |
1128 | |
1129 int32_t savings = cst->getDSTSavings(); | |
1130 if(savings != 60*60*1000) { | |
1131 errln("setDSTSavings() failed"); | |
1132 } | |
1133 | |
1134 delete pst; | |
1135 delete cst; | |
1136 } | |
1137 /** | |
1138 * SimpleTimeZone allows invalid DOM values. | |
1139 */ | |
1140 void TimeZoneRegressionTest::Test4184229() { | |
1141 SimpleTimeZone* zone = NULL; | |
1142 UErrorCode status = U_ZERO_ERROR; | |
1143 zone = new SimpleTimeZone(0, "A", 0, -1, 0, 0, 0, 0, 0, 0, status); | |
1144 if(U_SUCCESS(status)){ | |
1145 errln("Failed. No exception has been thrown for DOM -1 startDay"); | |
1146 }else{ | |
1147 logln("(a) " + UnicodeString( u_errorName(status))); | |
1148 } | |
1149 status = U_ZERO_ERROR; | |
1150 delete zone; | |
1151 | |
1152 zone = new SimpleTimeZone(0, "A", 0, 0, 0, 0, 0, -1, 0, 0, status); | |
1153 if(U_SUCCESS(status)){ | |
1154 errln("Failed. No exception has been thrown for DOM -1 endDay"); | |
1155 }else{ | |
1156 logln("(b) " + UnicodeString(u_errorName(status))); | |
1157 } | |
1158 status = U_ZERO_ERROR; | |
1159 delete zone; | |
1160 | |
1161 zone = new SimpleTimeZone(0, "A", 0, -1, 0, 0, 0, 0, 0, 1000, status); | |
1162 if(U_SUCCESS(status)){ | |
1163 errln("Failed. No exception has been thrown for DOM -1 startDay+savings"
); | |
1164 }else{ | |
1165 logln("(c) " + UnicodeString(u_errorName(status))); | |
1166 } | |
1167 status = U_ZERO_ERROR; | |
1168 delete zone; | |
1169 zone = new SimpleTimeZone(0, "A", 0, 0, 0, 0, 0, -1, 0, 0, 1000, status); | |
1170 if(U_SUCCESS(status)){ | |
1171 errln("Failed. No exception has been thrown for DOM -1 endDay+ savings")
; | |
1172 }else{ | |
1173 logln("(d) " + UnicodeString(u_errorName(status))); | |
1174 } | |
1175 status = U_ZERO_ERROR; | |
1176 delete zone; | |
1177 // Make a valid constructor call for subsequent tests. | |
1178 zone = new SimpleTimeZone(0, "A", 0, 1, 0, 0, 0, 1, 0, 0, status); | |
1179 | |
1180 zone->setStartRule(0, -1, 0, 0, status); | |
1181 if(U_SUCCESS(status)){ | |
1182 errln("Failed. No exception has been thrown for DOM -1 setStartRule +sav
ings"); | |
1183 } else{ | |
1184 logln("(e) " + UnicodeString(u_errorName(status))); | |
1185 } | |
1186 zone->setStartRule(0, -1, 0, status); | |
1187 if(U_SUCCESS(status)){ | |
1188 errln("Failed. No exception has been thrown for DOM -1 setStartRule"); | |
1189 } else{ | |
1190 logln("(f) " + UnicodeString(u_errorName(status))); | |
1191 } | |
1192 | |
1193 zone->setEndRule(0, -1, 0, 0, status); | |
1194 if(U_SUCCESS(status)){ | |
1195 errln("Failed. No exception has been thrown for DOM -1 setEndRule+saving
s"); | |
1196 } else{ | |
1197 logln("(g) " + UnicodeString(u_errorName(status))); | |
1198 } | |
1199 | |
1200 zone->setEndRule(0, -1, 0, status); | |
1201 if(U_SUCCESS(status)){ | |
1202 errln("Failed. No exception has been thrown for DOM -1 setEndRule"); | |
1203 } else{ | |
1204 logln("(h) " + UnicodeString(u_errorName(status))); | |
1205 } | |
1206 delete zone; | |
1207 } | |
1208 | |
1209 #endif /* #if !UCONFIG_NO_FORMATTING */ | |
OLD | NEW |