]> git.saurik.com Git - apple/icu.git/blob - icuSources/test/intltest/caltest.cpp
ICU-551.41.tar.gz
[apple/icu.git] / icuSources / test / intltest / caltest.cpp
1 /************************************************************************
2 * COPYRIGHT:
3 * Copyright (c) 1997-2015, International Business Machines Corporation
4 * and others. All Rights Reserved.
5 ************************************************************************/
6 #include "unicode/utypes.h"
7
8 #if !UCONFIG_NO_FORMATTING
9
10 #include "caltest.h"
11 #include "unicode/dtfmtsym.h"
12 #include "unicode/gregocal.h"
13 #include "unicode/localpointer.h"
14 #include "hebrwcal.h"
15 #include "unicode/smpdtfmt.h"
16 #include "unicode/simpletz.h"
17 #include "dbgutil.h"
18 #include "unicode/udat.h"
19 #include "unicode/ustring.h"
20 #include "cstring.h"
21 #include "unicode/localpointer.h"
22 #include "islamcal.h"
23
24 #define mkcstr(U) u_austrcpy(calloc(8, u_strlen(U) + 1), U)
25
26 #define TEST_CHECK_STATUS { \
27 if (U_FAILURE(status)) { \
28 if (status == U_MISSING_RESOURCE_ERROR) { \
29 dataerrln("%s:%d: Test failure. status=%s", __FILE__, __LINE__, u_errorName(status)); \
30 } else { \
31 errln("%s:%d: Test failure. status=%s", __FILE__, __LINE__, u_errorName(status)); \
32 } return;}}
33
34 #define TEST_CHECK_STATUS_LOCALE(testlocale) { \
35 if (U_FAILURE(status)) { \
36 if (status == U_MISSING_RESOURCE_ERROR) { \
37 dataerrln("%s:%d: Test failure, locale %s. status=%s", __FILE__, __LINE__, testlocale, u_errorName(status)); \
38 } else { \
39 errln("%s:%d: Test failure, locale %s. status=%s", __FILE__, __LINE__, testlocale, u_errorName(status)); \
40 } return;}}
41
42 #define TEST_ASSERT(expr) {if ((expr)==FALSE) {errln("%s:%d: Test failure \n", __FILE__, __LINE__);};}
43
44 // *****************************************************************************
45 // class CalendarTest
46 // *****************************************************************************
47
48 UnicodeString CalendarTest::calToStr(const Calendar & cal)
49 {
50 UnicodeString out;
51 UErrorCode status = U_ZERO_ERROR;
52 int i;
53 UDate d;
54 for(i = 0;i<UCAL_FIELD_COUNT;i++) {
55 out += (UnicodeString("") + fieldName((UCalendarDateFields)i) + "=" + cal.get((UCalendarDateFields)i, status) + UnicodeString(" "));
56 }
57 out += "[" + UnicodeString(cal.getType()) + "]";
58
59 if(cal.inDaylightTime(status)) {
60 out += UnicodeString(" (in DST), zone=");
61 }
62 else {
63 out += UnicodeString(", zone=");
64 }
65
66 UnicodeString str2;
67 out += cal.getTimeZone().getDisplayName(str2);
68 d = cal.getTime(status);
69 out += UnicodeString(" :","") + d;
70
71 return out;
72 }
73
74 void CalendarTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
75 {
76 if (exec) logln("TestSuite TestCalendar");
77 switch (index) {
78 case 0:
79 name = "TestDOW943";
80 if (exec) {
81 logln("TestDOW943---"); logln("");
82 TestDOW943();
83 }
84 break;
85 case 1:
86 name = "TestClonesUnique908";
87 if (exec) {
88 logln("TestClonesUnique908---"); logln("");
89 TestClonesUnique908();
90 }
91 break;
92 case 2:
93 name = "TestGregorianChange768";
94 if (exec) {
95 logln("TestGregorianChange768---"); logln("");
96 TestGregorianChange768();
97 }
98 break;
99 case 3:
100 name = "TestDisambiguation765";
101 if (exec) {
102 logln("TestDisambiguation765---"); logln("");
103 TestDisambiguation765();
104 }
105 break;
106 case 4:
107 name = "TestGMTvsLocal4064654";
108 if (exec) {
109 logln("TestGMTvsLocal4064654---"); logln("");
110 TestGMTvsLocal4064654();
111 }
112 break;
113 case 5:
114 name = "TestAddSetOrder621";
115 if (exec) {
116 logln("TestAddSetOrder621---"); logln("");
117 TestAddSetOrder621();
118 }
119 break;
120 case 6:
121 name = "TestAdd520";
122 if (exec) {
123 logln("TestAdd520---"); logln("");
124 TestAdd520();
125 }
126 break;
127 case 7:
128 name = "TestFieldSet4781";
129 if (exec) {
130 logln("TestFieldSet4781---"); logln("");
131 TestFieldSet4781();
132 }
133 break;
134 case 8:
135 name = "TestSerialize337";
136 if (exec) {
137 logln("TestSerialize337---"); logln("");
138 // TestSerialize337();
139 }
140 break;
141 case 9:
142 name = "TestSecondsZero121";
143 if (exec) {
144 logln("TestSecondsZero121---"); logln("");
145 TestSecondsZero121();
146 }
147 break;
148 case 10:
149 name = "TestAddSetGet0610";
150 if (exec) {
151 logln("TestAddSetGet0610---"); logln("");
152 TestAddSetGet0610();
153 }
154 break;
155 case 11:
156 name = "TestFields060";
157 if (exec) {
158 logln("TestFields060---"); logln("");
159 TestFields060();
160 }
161 break;
162 case 12:
163 name = "TestEpochStartFields";
164 if (exec) {
165 logln("TestEpochStartFields---"); logln("");
166 TestEpochStartFields();
167 }
168 break;
169 case 13:
170 name = "TestDOWProgression";
171 if (exec) {
172 logln("TestDOWProgression---"); logln("");
173 TestDOWProgression();
174 }
175 break;
176 case 14:
177 name = "TestGenericAPI";
178 if (exec) {
179 logln("TestGenericAPI---"); logln("");
180 TestGenericAPI();
181 }
182 break;
183 case 15:
184 name = "TestAddRollExtensive";
185 if (exec) {
186 logln("TestAddRollExtensive---"); logln("");
187 TestAddRollExtensive();
188 }
189 break;
190 case 16:
191 name = "TestDOW_LOCALandYEAR_WOY";
192 if (exec) {
193 logln("TestDOW_LOCALandYEAR_WOY---"); logln("");
194 TestDOW_LOCALandYEAR_WOY();
195 }
196 break;
197 case 17:
198 name = "TestWOY";
199 if (exec) {
200 logln("TestWOY---"); logln("");
201 TestWOY();
202 }
203 break;
204 case 18:
205 name = "TestRog";
206 if (exec) {
207 logln("TestRog---"); logln("");
208 TestRog();
209 }
210 break;
211 case 19:
212 name = "TestYWOY";
213 if (exec) {
214 logln("TestYWOY---"); logln("");
215 TestYWOY();
216 }
217 break;
218 case 20:
219 name = "TestJD";
220 if(exec) {
221 logln("TestJD---"); logln("");
222 TestJD();
223 }
224 break;
225 case 21:
226 name = "TestDebug";
227 if(exec) {
228 logln("TestDebug---"); logln("");
229 TestDebug();
230 }
231 break;
232 case 22:
233 name = "Test6703";
234 if(exec) {
235 logln("Test6703---"); logln("");
236 Test6703();
237 }
238 break;
239 case 23:
240 name = "Test3785";
241 if(exec) {
242 logln("Test3785---"); logln("");
243 Test3785();
244 }
245 break;
246 case 24:
247 name = "Test1624";
248 if(exec) {
249 logln("Test1624---"); logln("");
250 Test1624();
251 }
252 break;
253 case 25:
254 name = "TestTimeStamp";
255 if(exec) {
256 logln("TestTimeStamp---"); logln("");
257 TestTimeStamp();
258 }
259 break;
260 case 26:
261 name = "TestISO8601";
262 if(exec) {
263 logln("TestISO8601---"); logln("");
264 TestISO8601();
265 }
266 break;
267 case 27:
268 name = "TestAmbiguousWallTimeAPIs";
269 if(exec) {
270 logln("TestAmbiguousWallTimeAPIs---"); logln("");
271 TestAmbiguousWallTimeAPIs();
272 }
273 break;
274 case 28:
275 name = "TestRepeatedWallTime";
276 if(exec) {
277 logln("TestRepeatedWallTime---"); logln("");
278 TestRepeatedWallTime();
279 }
280 break;
281 case 29:
282 name = "TestSkippedWallTime";
283 if(exec) {
284 logln("TestSkippedWallTime---"); logln("");
285 TestSkippedWallTime();
286 }
287 break;
288 case 30:
289 name = "TestCloneLocale";
290 if(exec) {
291 logln("TestCloneLocale---"); logln("");
292 TestCloneLocale();
293 }
294 break;
295 case 31:
296 name = "TestIslamicUmAlQura";
297 if(exec) {
298 logln("TestIslamicUmAlQura---"); logln("");
299 TestIslamicUmAlQura();
300 }
301 break;
302 case 32:
303 name = "TestIslamicTabularDates";
304 if(exec) {
305 logln("TestIslamicTabularDates---"); logln("");
306 TestIslamicTabularDates();
307 }
308 break;
309 case 33:
310 name = "TestHebrewMonthValidation";
311 if(exec) {
312 logln("TestHebrewMonthValidation---"); logln("");
313 TestHebrewMonthValidation();
314 }
315 break;
316 case 34:
317 name = "TestWeekData";
318 if(exec) {
319 logln("TestWeekData---"); logln("");
320 TestWeekData();
321 }
322 break;
323 case 35:
324 name = "TestAddAcrossZoneTransition";
325 if(exec) {
326 logln("TestAddAcrossZoneTransition---"); logln("");
327 TestAddAcrossZoneTransition();
328 }
329 break;
330 default: name = ""; break;
331 }
332 }
333
334 // ---------------------------------------------------------------------------------
335
336 UnicodeString CalendarTest::fieldName(UCalendarDateFields f) {
337 switch (f) {
338 #define FIELD_NAME_STR(x) case x: return (#x+5)
339 FIELD_NAME_STR( UCAL_ERA );
340 FIELD_NAME_STR( UCAL_YEAR );
341 FIELD_NAME_STR( UCAL_MONTH );
342 FIELD_NAME_STR( UCAL_WEEK_OF_YEAR );
343 FIELD_NAME_STR( UCAL_WEEK_OF_MONTH );
344 FIELD_NAME_STR( UCAL_DATE );
345 FIELD_NAME_STR( UCAL_DAY_OF_YEAR );
346 FIELD_NAME_STR( UCAL_DAY_OF_WEEK );
347 FIELD_NAME_STR( UCAL_DAY_OF_WEEK_IN_MONTH );
348 FIELD_NAME_STR( UCAL_AM_PM );
349 FIELD_NAME_STR( UCAL_HOUR );
350 FIELD_NAME_STR( UCAL_HOUR_OF_DAY );
351 FIELD_NAME_STR( UCAL_MINUTE );
352 FIELD_NAME_STR( UCAL_SECOND );
353 FIELD_NAME_STR( UCAL_MILLISECOND );
354 FIELD_NAME_STR( UCAL_ZONE_OFFSET );
355 FIELD_NAME_STR( UCAL_DST_OFFSET );
356 FIELD_NAME_STR( UCAL_YEAR_WOY );
357 FIELD_NAME_STR( UCAL_DOW_LOCAL );
358 FIELD_NAME_STR( UCAL_EXTENDED_YEAR );
359 FIELD_NAME_STR( UCAL_JULIAN_DAY );
360 FIELD_NAME_STR( UCAL_MILLISECONDS_IN_DAY );
361 #undef FIELD_NAME_STR
362 default:
363 return UnicodeString("") + ((int32_t)f);
364 }
365 }
366
367 /**
368 * Test various API methods for API completeness.
369 */
370 void
371 CalendarTest::TestGenericAPI()
372 {
373 UErrorCode status = U_ZERO_ERROR;
374 UDate d;
375 UnicodeString str;
376 UBool eq = FALSE,b4 = FALSE,af = FALSE;
377
378 UDate when = date(90, UCAL_APRIL, 15);
379
380 UnicodeString tzid("TestZone");
381 int32_t tzoffset = 123400;
382
383 SimpleTimeZone *zone = new SimpleTimeZone(tzoffset, tzid);
384 Calendar *cal = Calendar::createInstance(zone->clone(), status);
385 if (failure(status, "Calendar::createInstance #1", TRUE)) return;
386
387 if (*zone != cal->getTimeZone()) errln("FAIL: Calendar::getTimeZone failed");
388
389 Calendar *cal2 = Calendar::createInstance(cal->getTimeZone(), status);
390 if (failure(status, "Calendar::createInstance #2")) return;
391 cal->setTime(when, status);
392 cal2->setTime(when, status);
393 if (failure(status, "Calendar::setTime")) return;
394
395 if (!(*cal == *cal2)) errln("FAIL: Calendar::operator== failed");
396 if ((*cal != *cal2)) errln("FAIL: Calendar::operator!= failed");
397 if (!cal->equals(*cal2, status) ||
398 cal->before(*cal2, status) ||
399 cal->after(*cal2, status) ||
400 U_FAILURE(status)) errln("FAIL: equals/before/after failed");
401
402 logln(UnicodeString("cal=") +cal->getTime(status) + UnicodeString(calToStr(*cal)));
403 logln(UnicodeString("cal2=") +cal2->getTime(status) + UnicodeString(calToStr(*cal2)));
404 logln("cal2->setTime(when+1000)");
405 cal2->setTime(when + 1000, status);
406 logln(UnicodeString("cal2=") +cal2->getTime(status) + UnicodeString(calToStr(*cal2)));
407
408 if (failure(status, "Calendar::setTime")) return;
409 if (cal->equals(*cal2, status) ||
410 cal2->before(*cal, status) ||
411 cal->after(*cal2, status) ||
412 U_FAILURE(status)) errln("FAIL: equals/before/after failed after setTime(+1000)");
413
414 logln("cal->roll(UCAL_SECOND)");
415 cal->roll(UCAL_SECOND, (UBool) TRUE, status);
416 logln(UnicodeString("cal=") +cal->getTime(status) + UnicodeString(calToStr(*cal)));
417 cal->roll(UCAL_SECOND, (int32_t)0, status);
418 logln(UnicodeString("cal=") +cal->getTime(status) + UnicodeString(calToStr(*cal)));
419 if (failure(status, "Calendar::roll")) return;
420
421 if (!(eq=cal->equals(*cal2, status)) ||
422 (b4=cal->before(*cal2, status)) ||
423 (af=cal->after(*cal2, status)) ||
424 U_FAILURE(status)) {
425 errln("FAIL: equals[%c]/before[%c]/after[%c] failed after roll 1 second [should be T/F/F]",
426 eq?'T':'F',
427 b4?'T':'F',
428 af?'T':'F');
429 logln(UnicodeString("cal=") +cal->getTime(status) + UnicodeString(calToStr(*cal)));
430 logln(UnicodeString("cal2=") +cal2->getTime(status) + UnicodeString(calToStr(*cal2)));
431 }
432
433 // Roll back to January
434 cal->roll(UCAL_MONTH, (int32_t)(1 + UCAL_DECEMBER - cal->get(UCAL_MONTH, status)), status);
435 if (failure(status, "Calendar::roll")) return;
436 if (cal->equals(*cal2, status) ||
437 cal2->before(*cal, status) ||
438 cal->after(*cal2, status) ||
439 U_FAILURE(status)) errln("FAIL: equals/before/after failed after rollback to January");
440
441 TimeZone *z = cal->orphanTimeZone();
442 if (z->getID(str) != tzid ||
443 z->getRawOffset() != tzoffset)
444 errln("FAIL: orphanTimeZone failed");
445
446 int32_t i;
447 for (i=0; i<2; ++i)
448 {
449 UBool lenient = ( i > 0 );
450 cal->setLenient(lenient);
451 if (lenient != cal->isLenient()) errln("FAIL: setLenient/isLenient failed");
452 // Later: Check for lenient behavior
453 }
454
455 for (i=UCAL_SUNDAY; i<=UCAL_SATURDAY; ++i)
456 {
457 cal->setFirstDayOfWeek((UCalendarDaysOfWeek)i);
458 if (cal->getFirstDayOfWeek() != i) errln("FAIL: set/getFirstDayOfWeek failed");
459 UErrorCode aStatus = U_ZERO_ERROR;
460 if (cal->getFirstDayOfWeek(aStatus) != i || U_FAILURE(aStatus)) errln("FAIL: getFirstDayOfWeek(status) failed");
461 }
462
463 for (i=1; i<=7; ++i)
464 {
465 cal->setMinimalDaysInFirstWeek((uint8_t)i);
466 if (cal->getMinimalDaysInFirstWeek() != i) errln("FAIL: set/getFirstDayOfWeek failed");
467 }
468
469 for (i=0; i<UCAL_FIELD_COUNT; ++i)
470 {
471 if (cal->getMinimum((UCalendarDateFields)i) > cal->getGreatestMinimum((UCalendarDateFields)i))
472 errln(UnicodeString("FAIL: getMinimum larger than getGreatestMinimum for field ") + i);
473 if (cal->getLeastMaximum((UCalendarDateFields)i) > cal->getMaximum((UCalendarDateFields)i))
474 errln(UnicodeString("FAIL: getLeastMaximum larger than getMaximum for field ") + i);
475 if (cal->getMinimum((UCalendarDateFields)i) >= cal->getMaximum((UCalendarDateFields)i))
476 errln(UnicodeString("FAIL: getMinimum not less than getMaximum for field ") + i);
477 }
478
479 cal->adoptTimeZone(TimeZone::createDefault());
480 cal->clear();
481 cal->set(1984, 5, 24);
482 if (cal->getTime(status) != date(84, 5, 24) || U_FAILURE(status))
483 errln("FAIL: Calendar::set(3 args) failed");
484
485 cal->clear();
486 cal->set(1985, 3, 2, 11, 49);
487 if (cal->getTime(status) != date(85, 3, 2, 11, 49) || U_FAILURE(status))
488 errln("FAIL: Calendar::set(5 args) failed");
489
490 cal->clear();
491 cal->set(1995, 9, 12, 1, 39, 55);
492 if (cal->getTime(status) != date(95, 9, 12, 1, 39, 55) || U_FAILURE(status))
493 errln("FAIL: Calendar::set(6 args) failed");
494
495 cal->getTime(status);
496 if (failure(status, "Calendar::getTime")) return;
497 for (i=0; i<UCAL_FIELD_COUNT; ++i)
498 {
499 switch(i) {
500 case UCAL_YEAR: case UCAL_MONTH: case UCAL_DATE:
501 case UCAL_HOUR_OF_DAY: case UCAL_MINUTE: case UCAL_SECOND:
502 case UCAL_EXTENDED_YEAR:
503 if (!cal->isSet((UCalendarDateFields)i)) errln("FAIL: Calendar::isSet F, should be T " + fieldName((UCalendarDateFields)i));
504 break;
505 default:
506 if (cal->isSet((UCalendarDateFields)i)) errln("FAIL: Calendar::isSet = T, should be F " + fieldName((UCalendarDateFields)i));
507 }
508 cal->clear((UCalendarDateFields)i);
509 if (cal->isSet((UCalendarDateFields)i)) errln("FAIL: Calendar::clear/isSet failed " + fieldName((UCalendarDateFields)i));
510 }
511
512 if(cal->getActualMinimum(Calendar::SECOND, status) != 0){
513 errln("Calendar is suppose to return 0 for getActualMinimum");
514 }
515
516 Calendar *cal3 = Calendar::createInstance(status);
517 cal3->roll(Calendar::SECOND, (int32_t)0, status);
518 if (failure(status, "Calendar::roll(EDateFields, int32_t, UErrorCode)")) return;
519
520 delete cal;
521 delete cal2;
522 delete cal3;
523
524 int32_t count;
525 const Locale* loc = Calendar::getAvailableLocales(count);
526 if (count < 1 || loc == 0)
527 {
528 dataerrln("FAIL: getAvailableLocales failed");
529 }
530 else
531 {
532 for (i=0; i<count; ++i)
533 {
534 cal = Calendar::createInstance(loc[i], status);
535 if (U_FAILURE(status)) {
536 errcheckln(status, UnicodeString("FAIL: Calendar::createInstance #3, locale ") + loc[i].getName() + " , error " + u_errorName(status));
537 return;
538 }
539 delete cal;
540 }
541 }
542
543 cal = Calendar::createInstance(TimeZone::createDefault(), Locale::getEnglish(), status);
544 if (failure(status, "Calendar::createInstance #4")) return;
545 delete cal;
546
547 cal = Calendar::createInstance(*zone, Locale::getEnglish(), status);
548 if (failure(status, "Calendar::createInstance #5")) return;
549 delete cal;
550
551 GregorianCalendar *gc = new GregorianCalendar(*zone, status);
552 if (failure(status, "new GregorianCalendar")) return;
553 delete gc;
554
555 gc = new GregorianCalendar(Locale::getEnglish(), status);
556 if (failure(status, "new GregorianCalendar")) return;
557 delete gc;
558
559 gc = new GregorianCalendar(Locale::getEnglish(), status);
560 delete gc;
561
562 gc = new GregorianCalendar(*zone, Locale::getEnglish(), status);
563 if (failure(status, "new GregorianCalendar")) return;
564 delete gc;
565
566 gc = new GregorianCalendar(zone, status);
567 if (failure(status, "new GregorianCalendar")) return;
568 delete gc;
569
570 gc = new GregorianCalendar(1998, 10, 14, 21, 43, status);
571 if (gc->getTime(status) != (d =date(98, 10, 14, 21, 43) )|| U_FAILURE(status))
572 errln("FAIL: new GregorianCalendar(ymdhm) failed with " + UnicodeString(u_errorName(status)) + ", cal=" + gc->getTime(status) + UnicodeString(calToStr(*gc)) + ", d=" + d);
573 else
574 logln(UnicodeString("GOOD: cal=") +gc->getTime(status) + UnicodeString(calToStr(*gc)) + ", d=" + d);
575 delete gc;
576
577 gc = new GregorianCalendar(1998, 10, 14, 21, 43, 55, status);
578 if (gc->getTime(status) != (d=date(98, 10, 14, 21, 43, 55)) || U_FAILURE(status))
579 errln("FAIL: new GregorianCalendar(ymdhms) failed with " + UnicodeString(u_errorName(status)));
580
581 GregorianCalendar gc2(Locale::getEnglish(), status);
582 if (failure(status, "new GregorianCalendar")) return;
583 gc2 = *gc;
584 if (gc2 != *gc || !(gc2 == *gc)) errln("FAIL: GregorianCalendar assignment/operator==/operator!= failed");
585 delete gc;
586 delete z;
587
588 /* Code coverage for Calendar class. */
589 cal = Calendar::createInstance(status);
590 if (failure(status, "Calendar::createInstance #6")) {
591 return;
592 }else {
593 ((Calendar *)cal)->roll(UCAL_HOUR, (int32_t)100, status);
594 ((Calendar *)cal)->clear(UCAL_HOUR);
595 #if !UCONFIG_NO_SERVICE
596 URegistryKey key = cal->registerFactory(NULL, status);
597 cal->unregister(key, status);
598 #endif
599 }
600 delete cal;
601
602 status = U_ZERO_ERROR;
603 cal = Calendar::createInstance(Locale("he_IL@calendar=hebrew"), status);
604 if (failure(status, "Calendar::createInstance #7")) {
605 return;
606 } else {
607 cal->roll(Calendar::MONTH, (int32_t)100, status);
608 }
609
610 LocalPointer<StringEnumeration> values(
611 Calendar::getKeywordValuesForLocale("calendar", Locale("he"), FALSE, status));
612 if (values.isNull() || U_FAILURE(status)) {
613 dataerrln("FAIL: Calendar::getKeywordValuesForLocale(he): %s", u_errorName(status));
614 } else {
615 UBool containsHebrew = FALSE;
616 const char *charValue;
617 int32_t valueLength;
618 while ((charValue = values->next(&valueLength, status)) != NULL) {
619 if (valueLength == 6 && strcmp(charValue, "hebrew") == 0) {
620 containsHebrew = TRUE;
621 }
622 }
623 if (!containsHebrew) {
624 errln("Calendar::getKeywordValuesForLocale(he)->next() does not contain \"hebrew\"");
625 }
626
627 values->reset(status);
628 containsHebrew = FALSE;
629 UnicodeString hebrew = UNICODE_STRING_SIMPLE("hebrew");
630 const UChar *ucharValue;
631 while ((ucharValue = values->unext(&valueLength, status)) != NULL) {
632 UnicodeString value(FALSE, ucharValue, valueLength);
633 if (value == hebrew) {
634 containsHebrew = TRUE;
635 }
636 }
637 if (!containsHebrew) {
638 errln("Calendar::getKeywordValuesForLocale(he)->unext() does not contain \"hebrew\"");
639 }
640
641 values->reset(status);
642 containsHebrew = FALSE;
643 const UnicodeString *stringValue;
644 while ((stringValue = values->snext(status)) != NULL) {
645 if (*stringValue == hebrew) {
646 containsHebrew = TRUE;
647 }
648 }
649 if (!containsHebrew) {
650 errln("Calendar::getKeywordValuesForLocale(he)->snext() does not contain \"hebrew\"");
651 }
652 }
653 delete cal;
654 }
655
656 // -------------------------------------
657
658 /**
659 * This test confirms the correct behavior of add when incrementing
660 * through subsequent days.
661 */
662 void
663 CalendarTest::TestRog()
664 {
665 UErrorCode status = U_ZERO_ERROR;
666 GregorianCalendar* gc = new GregorianCalendar(status);
667 if (failure(status, "new GregorianCalendar", TRUE)) return;
668 int32_t year = 1997, month = UCAL_APRIL, date = 1;
669 gc->set(year, month, date);
670 gc->set(UCAL_HOUR_OF_DAY, 23);
671 gc->set(UCAL_MINUTE, 0);
672 gc->set(UCAL_SECOND, 0);
673 gc->set(UCAL_MILLISECOND, 0);
674 for (int32_t i = 0; i < 9; i++, gc->add(UCAL_DATE, 1, status)) {
675 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
676 if (gc->get(UCAL_YEAR, status) != year ||
677 gc->get(UCAL_MONTH, status) != month ||
678 gc->get(UCAL_DATE, status) != (date + i)) errln("FAIL: Date wrong");
679 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
680 }
681 delete gc;
682 }
683
684 // -------------------------------------
685
686 /**
687 * Test the handling of the day of the week, checking for correctness and
688 * for correct minimum and maximum values.
689 */
690 void
691 CalendarTest::TestDOW943()
692 {
693 dowTest(FALSE);
694 dowTest(TRUE);
695 }
696
697 void CalendarTest::dowTest(UBool lenient)
698 {
699 UErrorCode status = U_ZERO_ERROR;
700 GregorianCalendar* cal = new GregorianCalendar(status);
701 if (failure(status, "new GregorianCalendar", TRUE)) return;
702 logln("cal - Aug 12, 1997\n");
703 cal->set(1997, UCAL_AUGUST, 12);
704 cal->getTime(status);
705 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; }
706 logln((lenient?UnicodeString("LENIENT0: "):UnicodeString("nonlenient0: ")) + UnicodeString(calToStr(*cal)));
707 cal->setLenient(lenient);
708 logln("cal - Dec 1, 1996\n");
709 cal->set(1996, UCAL_DECEMBER, 1);
710 logln((lenient?UnicodeString("LENIENT: "):UnicodeString("nonlenient: ")) + UnicodeString(calToStr(*cal)));
711 int32_t dow = cal->get(UCAL_DAY_OF_WEEK, status);
712 if (U_FAILURE(status)) { errln("Calendar::get failed [%s]", u_errorName(status)); return; }
713 int32_t min = cal->getMinimum(UCAL_DAY_OF_WEEK);
714 int32_t max = cal->getMaximum(UCAL_DAY_OF_WEEK);
715 if (dow < min ||
716 dow > max) errln(UnicodeString("FAIL: Day of week ") + (int32_t)dow + " out of range");
717 if (dow != UCAL_SUNDAY) errln("FAIL: Day of week should be SUNDAY[%d] not %d", UCAL_SUNDAY, dow);
718 if (min != UCAL_SUNDAY ||
719 max != UCAL_SATURDAY) errln("FAIL: Min/max bad");
720 delete cal;
721 }
722
723 // -------------------------------------
724
725 /**
726 * Confirm that cloned Calendar objects do not inadvertently share substructures.
727 */
728 void
729 CalendarTest::TestClonesUnique908()
730 {
731 UErrorCode status = U_ZERO_ERROR;
732 Calendar *c = Calendar::createInstance(status);
733 if (failure(status, "Calendar::createInstance", TRUE)) return;
734 Calendar *d = (Calendar*) c->clone();
735 c->set(UCAL_MILLISECOND, 123);
736 d->set(UCAL_MILLISECOND, 456);
737 if (c->get(UCAL_MILLISECOND, status) != 123 ||
738 d->get(UCAL_MILLISECOND, status) != 456) {
739 errln("FAIL: Clones share fields");
740 }
741 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
742 delete c;
743 delete d;
744 }
745
746 // -------------------------------------
747
748 /**
749 * Confirm that the Gregorian cutoff value works as advertised.
750 */
751 void
752 CalendarTest::TestGregorianChange768()
753 {
754 UBool b;
755 UErrorCode status = U_ZERO_ERROR;
756 UnicodeString str;
757 GregorianCalendar* c = new GregorianCalendar(status);
758 if (failure(status, "new GregorianCalendar", TRUE)) return;
759 logln(UnicodeString("With cutoff ") + dateToString(c->getGregorianChange(), str));
760 b = c->isLeapYear(1800);
761 logln(UnicodeString(" isLeapYear(1800) = ") + (b ? "true" : "false"));
762 logln(UnicodeString(" (should be FALSE)"));
763 if (b) errln("FAIL");
764 c->setGregorianChange(date(0, 0, 1), status);
765 if (U_FAILURE(status)) { errln("GregorianCalendar::setGregorianChange failed"); return; }
766 logln(UnicodeString("With cutoff ") + dateToString(c->getGregorianChange(), str));
767 b = c->isLeapYear(1800);
768 logln(UnicodeString(" isLeapYear(1800) = ") + (b ? "true" : "false"));
769 logln(UnicodeString(" (should be TRUE)"));
770 if (!b) errln("FAIL");
771 delete c;
772 }
773
774 // -------------------------------------
775
776 /**
777 * Confirm the functioning of the field disambiguation algorithm.
778 */
779 void
780 CalendarTest::TestDisambiguation765()
781 {
782 UErrorCode status = U_ZERO_ERROR;
783 Calendar *c = Calendar::createInstance("en_US", status);
784 if (failure(status, "Calendar::createInstance", TRUE)) return;
785 c->setLenient(FALSE);
786 c->clear();
787 c->set(UCAL_YEAR, 1997);
788 c->set(UCAL_MONTH, UCAL_JUNE);
789 c->set(UCAL_DATE, 3);
790 verify765("1997 third day of June = ", c, 1997, UCAL_JUNE, 3);
791 c->clear();
792 c->set(UCAL_YEAR, 1997);
793 c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY);
794 c->set(UCAL_MONTH, UCAL_JUNE);
795 c->set(UCAL_DAY_OF_WEEK_IN_MONTH, 1);
796 verify765("1997 first Tuesday in June = ", c, 1997, UCAL_JUNE, 3);
797 c->clear();
798 c->set(UCAL_YEAR, 1997);
799 c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY);
800 c->set(UCAL_MONTH, UCAL_JUNE);
801 c->set(UCAL_DAY_OF_WEEK_IN_MONTH, - 1);
802 verify765("1997 last Tuesday in June = ", c, 1997, UCAL_JUNE, 24);
803
804 status = U_ZERO_ERROR;
805 c->clear();
806 c->set(UCAL_YEAR, 1997);
807 c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY);
808 c->set(UCAL_MONTH, UCAL_JUNE);
809 c->set(UCAL_DAY_OF_WEEK_IN_MONTH, 0);
810 c->getTime(status);
811 verify765("1997 zero-th Tuesday in June = ", status);
812
813 c->clear();
814 c->set(UCAL_YEAR, 1997);
815 c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY);
816 c->set(UCAL_MONTH, UCAL_JUNE);
817 c->set(UCAL_WEEK_OF_MONTH, 1);
818 verify765("1997 Tuesday in week 1 of June = ", c, 1997, UCAL_JUNE, 3);
819 c->clear();
820 c->set(UCAL_YEAR, 1997);
821 c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY);
822 c->set(UCAL_MONTH, UCAL_JUNE);
823 c->set(UCAL_WEEK_OF_MONTH, 5);
824 verify765("1997 Tuesday in week 5 of June = ", c, 1997, UCAL_JULY, 1);
825
826 status = U_ZERO_ERROR;
827 c->clear();
828 c->set(UCAL_YEAR, 1997);
829 c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY);
830 c->set(UCAL_MONTH, UCAL_JUNE);
831 c->set(UCAL_WEEK_OF_MONTH, 0);
832 c->setMinimalDaysInFirstWeek(1);
833 c->getTime(status);
834 verify765("1997 Tuesday in week 0 of June = ", status);
835
836 /* Note: The following test used to expect YEAR 1997, WOY 1 to
837 * resolve to a date in Dec 1996; that is, to behave as if
838 * YEAR_WOY were 1997. With the addition of a new explicit
839 * YEAR_WOY field, YEAR_WOY must itself be set if that is what is
840 * desired. Using YEAR in combination with WOY is ambiguous, and
841 * results in the first WOY/DOW day of the year satisfying the
842 * given fields (there may be up to two such days). In this case,
843 * it propertly resolves to Tue Dec 30 1997, which has a WOY value
844 * of 1 (for YEAR_WOY 1998) and a DOW of Tuesday, and falls in the
845 * _calendar_ year 1997, as specified. - aliu */
846 c->clear();
847 c->set(UCAL_YEAR_WOY, 1997); // aliu
848 c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY);
849 c->set(UCAL_WEEK_OF_YEAR, 1);
850 verify765("1997 Tuesday in week 1 of yearWOY = ", c, 1996, UCAL_DECEMBER, 31);
851 c->clear(); // - add test for YEAR
852 c->setMinimalDaysInFirstWeek(1);
853 c->set(UCAL_YEAR, 1997);
854 c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY);
855 c->set(UCAL_WEEK_OF_YEAR, 1);
856 verify765("1997 Tuesday in week 1 of year = ", c, 1997, UCAL_DECEMBER, 30);
857 c->clear();
858 c->set(UCAL_YEAR, 1997);
859 c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY);
860 c->set(UCAL_WEEK_OF_YEAR, 10);
861 verify765("1997 Tuesday in week 10 of year = ", c, 1997, UCAL_MARCH, 4);
862 //try {
863
864 // {sfb} week 0 is no longer a valid week of year
865 /*c->clear();
866 c->set(Calendar::YEAR, 1997);
867 c->set(Calendar::DAY_OF_WEEK, Calendar::TUESDAY);
868 //c->set(Calendar::WEEK_OF_YEAR, 0);
869 c->set(Calendar::WEEK_OF_YEAR, 1);
870 verify765("1997 Tuesday in week 0 of year = ", c, 1996, Calendar::DECEMBER, 24);*/
871
872 //}
873 //catch(IllegalArgumentException ex) {
874 // errln("FAIL: Exception seen:");
875 // ex.printStackTrace(log);
876 //}
877 delete c;
878 }
879
880 // -------------------------------------
881
882 void
883 CalendarTest::verify765(const UnicodeString& msg, Calendar* c, int32_t year, int32_t month, int32_t day)
884 {
885 UnicodeString str;
886 UErrorCode status = U_ZERO_ERROR;
887 int32_t y = c->get(UCAL_YEAR, status);
888 int32_t m = c->get(UCAL_MONTH, status);
889 int32_t d = c->get(UCAL_DATE, status);
890 if ( y == year &&
891 m == month &&
892 d == day) {
893 if (U_FAILURE(status)) { errln("FAIL: Calendar::get failed"); return; }
894 logln("PASS: " + msg + dateToString(c->getTime(status), str));
895 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; }
896 }
897 else {
898 errln("FAIL: " + msg + dateToString(c->getTime(status), str) + "; expected " + (int32_t)year + "/" + (int32_t)(month + 1) + "/" + (int32_t)day +
899 "; got " + (int32_t)y + "/" + (int32_t)(m + 1) + "/" + (int32_t)d + " for Locale: " + c->getLocaleID(ULOC_ACTUAL_LOCALE,status));
900 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; }
901 }
902 }
903
904 // -------------------------------------
905
906 void
907 CalendarTest::verify765(const UnicodeString& msg/*, IllegalArgumentException e*/, UErrorCode status)
908 {
909 if (status != U_ILLEGAL_ARGUMENT_ERROR) errln("FAIL: No IllegalArgumentException for " + msg);
910 else logln("PASS: " + msg + "IllegalArgument as expected");
911 }
912
913 // -------------------------------------
914
915 /**
916 * Confirm that the offset between local time and GMT behaves as expected.
917 */
918 void
919 CalendarTest::TestGMTvsLocal4064654()
920 {
921 test4064654(1997, 1, 1, 12, 0, 0);
922 test4064654(1997, 4, 16, 18, 30, 0);
923 }
924
925 // -------------------------------------
926
927 void
928 CalendarTest::test4064654(int32_t yr, int32_t mo, int32_t dt, int32_t hr, int32_t mn, int32_t sc)
929 {
930 UDate date;
931 UErrorCode status = U_ZERO_ERROR;
932 UnicodeString str;
933 Calendar *gmtcal = Calendar::createInstance(status);
934 if (failure(status, "Calendar::createInstance", TRUE)) return;
935 gmtcal->adoptTimeZone(TimeZone::createTimeZone("Africa/Casablanca"));
936 gmtcal->set(yr, mo - 1, dt, hr, mn, sc);
937 gmtcal->set(UCAL_MILLISECOND, 0);
938 date = gmtcal->getTime(status);
939 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; }
940 logln("date = " + dateToString(date, str));
941 Calendar *cal = Calendar::createInstance(status);
942 if (U_FAILURE(status)) { errln("Calendar::createInstance failed"); return; }
943 cal->setTime(date, status);
944 if (U_FAILURE(status)) { errln("Calendar::setTime failed"); return; }
945 int32_t offset = cal->getTimeZone().getOffset((uint8_t)cal->get(UCAL_ERA, status),
946 cal->get(UCAL_YEAR, status),
947 cal->get(UCAL_MONTH, status),
948 cal->get(UCAL_DATE, status),
949 (uint8_t)cal->get(UCAL_DAY_OF_WEEK, status),
950 cal->get(UCAL_MILLISECOND, status), status);
951 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
952 logln("offset for " + dateToString(date, str) + "= " + (offset / 1000 / 60 / 60.0) + "hr");
953 int32_t utc = ((cal->get(UCAL_HOUR_OF_DAY, status) * 60 +
954 cal->get(UCAL_MINUTE, status)) * 60 +
955 cal->get(UCAL_SECOND, status)) * 1000 +
956 cal->get(UCAL_MILLISECOND, status) - offset;
957 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
958 int32_t expected = ((hr * 60 + mn) * 60 + sc) * 1000;
959 if (utc != expected) errln(UnicodeString("FAIL: Discrepancy of ") + (utc - expected) +
960 " millis = " + ((utc - expected) / 1000 / 60 / 60.0) + " hr");
961 delete gmtcal;
962 delete cal;
963 }
964
965 // -------------------------------------
966
967 /**
968 * The operations of adding and setting should not exhibit pathological
969 * dependence on the order of operations. This test checks for this.
970 */
971 void
972 CalendarTest::TestAddSetOrder621()
973 {
974 UDate d = date(97, 4, 14, 13, 23, 45);
975 UErrorCode status = U_ZERO_ERROR;
976 Calendar *cal = Calendar::createInstance(status);
977 if (failure(status, "Calendar::createInstance", TRUE)) return;
978
979 cal->setTime(d, status);
980 if (U_FAILURE(status)) {
981 errln("Calendar::setTime failed");
982 delete cal;
983 return;
984 }
985 cal->add(UCAL_DATE, - 5, status);
986 if (U_FAILURE(status)) {
987 errln("Calendar::add failed");
988 delete cal;
989 return;
990 }
991 cal->set(UCAL_HOUR_OF_DAY, 0);
992 cal->set(UCAL_MINUTE, 0);
993 cal->set(UCAL_SECOND, 0);
994 UnicodeString s;
995 dateToString(cal->getTime(status), s);
996 if (U_FAILURE(status)) {
997 errln("Calendar::getTime failed");
998 delete cal;
999 return;
1000 }
1001 delete cal;
1002
1003 cal = Calendar::createInstance(status);
1004 if (U_FAILURE(status)) {
1005 errln("Calendar::createInstance failed");
1006 delete cal;
1007 return;
1008 }
1009 cal->setTime(d, status);
1010 if (U_FAILURE(status)) {
1011 errln("Calendar::setTime failed");
1012 delete cal;
1013 return;
1014 }
1015 cal->set(UCAL_HOUR_OF_DAY, 0);
1016 cal->set(UCAL_MINUTE, 0);
1017 cal->set(UCAL_SECOND, 0);
1018 cal->add(UCAL_DATE, - 5, status);
1019 if (U_FAILURE(status)) {
1020 errln("Calendar::add failed");
1021 delete cal;
1022 return;
1023 }
1024 UnicodeString s2;
1025 dateToString(cal->getTime(status), s2);
1026 if (U_FAILURE(status)) {
1027 errln("Calendar::getTime failed");
1028 delete cal;
1029 return;
1030 }
1031 if (s == s2)
1032 logln("Pass: " + s + " == " + s2);
1033 else
1034 errln("FAIL: " + s + " != " + s2);
1035 delete cal;
1036 }
1037
1038 // -------------------------------------
1039
1040 /**
1041 * Confirm that adding to various fields works.
1042 */
1043 void
1044 CalendarTest::TestAdd520()
1045 {
1046 int32_t y = 1997, m = UCAL_FEBRUARY, d = 1;
1047 UErrorCode status = U_ZERO_ERROR;
1048 GregorianCalendar *temp = new GregorianCalendar(y, m, d, status);
1049 if (failure(status, "new GregorianCalendar", TRUE)) return;
1050 check520(temp, y, m, d);
1051 temp->add(UCAL_YEAR, 1, status);
1052 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
1053 y++;
1054 check520(temp, y, m, d);
1055 temp->add(UCAL_MONTH, 1, status);
1056 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
1057 m++;
1058 check520(temp, y, m, d);
1059 temp->add(UCAL_DATE, 1, status);
1060 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
1061 d++;
1062 check520(temp, y, m, d);
1063 temp->add(UCAL_DATE, 2, status);
1064 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
1065 d += 2;
1066 check520(temp, y, m, d);
1067 temp->add(UCAL_DATE, 28, status);
1068 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
1069 d = 1;++m;
1070 check520(temp, y, m, d);
1071 delete temp;
1072 }
1073
1074 // -------------------------------------
1075
1076 /**
1077 * Execute adding and rolling in GregorianCalendar extensively,
1078 */
1079 void
1080 CalendarTest::TestAddRollExtensive()
1081 {
1082 int32_t maxlimit = 40;
1083 int32_t y = 1997, m = UCAL_FEBRUARY, d = 1, hr = 1, min = 1, sec = 0, ms = 0;
1084 UErrorCode status = U_ZERO_ERROR;
1085 GregorianCalendar *temp = new GregorianCalendar(y, m, d, status);
1086 if (failure(status, "new GregorianCalendar", TRUE)) return;
1087
1088 temp->set(UCAL_HOUR, hr);
1089 temp->set(UCAL_MINUTE, min);
1090 temp->set(UCAL_SECOND, sec);
1091 temp->set(UCAL_MILLISECOND, ms);
1092 temp->setMinimalDaysInFirstWeek(1);
1093
1094 UCalendarDateFields e;
1095
1096 logln("Testing GregorianCalendar add...");
1097 e = UCAL_YEAR;
1098 while (e < UCAL_FIELD_COUNT) {
1099 int32_t i;
1100 int32_t limit = maxlimit;
1101 status = U_ZERO_ERROR;
1102 for (i = 0; i < limit; i++) {
1103 temp->add(e, 1, status);
1104 if (U_FAILURE(status)) { limit = i; status = U_ZERO_ERROR; }
1105 }
1106 for (i = 0; i < limit; i++) {
1107 temp->add(e, -1, status);
1108 if (U_FAILURE(status)) { errln("GregorianCalendar::add -1 failed"); return; }
1109 }
1110 check520(temp, y, m, d, hr, min, sec, ms, e);
1111
1112 e = (UCalendarDateFields) ((int32_t) e + 1);
1113 }
1114
1115 logln("Testing GregorianCalendar roll...");
1116 e = UCAL_YEAR;
1117 while (e < UCAL_FIELD_COUNT) {
1118 int32_t i;
1119 int32_t limit = maxlimit;
1120 status = U_ZERO_ERROR;
1121 for (i = 0; i < limit; i++) {
1122 logln(calToStr(*temp) + UnicodeString(" " ) + fieldName(e) + UnicodeString("++") );
1123 temp->roll(e, 1, status);
1124 if (U_FAILURE(status)) {
1125 logln("caltest.cpp:%d e=%d, i=%d - roll(+) err %s\n", __LINE__, (int) e, (int) i, u_errorName(status));
1126 logln(calToStr(*temp));
1127 limit = i; status = U_ZERO_ERROR;
1128 }
1129 }
1130 for (i = 0; i < limit; i++) {
1131 logln("caltest.cpp:%d e=%d, i=%d\n", __LINE__, (int) e, (int) i);
1132 logln(calToStr(*temp) + UnicodeString(" " ) + fieldName(e) + UnicodeString("--") );
1133 temp->roll(e, -1, status);
1134 if (U_FAILURE(status)) { errln(UnicodeString("GregorianCalendar::roll ") + CalendarTest::fieldName(e) + " count=" + UnicodeString('@'+i) + " by -1 failed with " + u_errorName(status) ); return; }
1135 }
1136 check520(temp, y, m, d, hr, min, sec, ms, e);
1137
1138 e = (UCalendarDateFields) ((int32_t) e + 1);
1139 }
1140
1141 delete temp;
1142 }
1143
1144 // -------------------------------------
1145 void
1146 CalendarTest::check520(Calendar* c,
1147 int32_t y, int32_t m, int32_t d,
1148 int32_t hr, int32_t min, int32_t sec,
1149 int32_t ms, UCalendarDateFields field)
1150
1151 {
1152 UErrorCode status = U_ZERO_ERROR;
1153 if (c->get(UCAL_YEAR, status) != y ||
1154 c->get(UCAL_MONTH, status) != m ||
1155 c->get(UCAL_DATE, status) != d ||
1156 c->get(UCAL_HOUR, status) != hr ||
1157 c->get(UCAL_MINUTE, status) != min ||
1158 c->get(UCAL_SECOND, status) != sec ||
1159 c->get(UCAL_MILLISECOND, status) != ms) {
1160 errln(UnicodeString("U_FAILURE for field ") + (int32_t)field +
1161 ": Expected y/m/d h:m:s:ms of " +
1162 y + "/" + (m + 1) + "/" + d + " " +
1163 hr + ":" + min + ":" + sec + ":" + ms +
1164 "; got " + c->get(UCAL_YEAR, status) +
1165 "/" + (c->get(UCAL_MONTH, status) + 1) +
1166 "/" + c->get(UCAL_DATE, status) +
1167 " " + c->get(UCAL_HOUR, status) + ":" +
1168 c->get(UCAL_MINUTE, status) + ":" +
1169 c->get(UCAL_SECOND, status) + ":" +
1170 c->get(UCAL_MILLISECOND, status)
1171 );
1172
1173 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
1174 }
1175 else
1176 logln(UnicodeString("Confirmed: ") + y + "/" +
1177 (m + 1) + "/" + d + " " +
1178 hr + ":" + min + ":" + sec + ":" + ms);
1179 }
1180
1181 // -------------------------------------
1182 void
1183 CalendarTest::check520(Calendar* c,
1184 int32_t y, int32_t m, int32_t d)
1185
1186 {
1187 UErrorCode status = U_ZERO_ERROR;
1188 if (c->get(UCAL_YEAR, status) != y ||
1189 c->get(UCAL_MONTH, status) != m ||
1190 c->get(UCAL_DATE, status) != d) {
1191 errln(UnicodeString("FAILURE: Expected y/m/d of ") +
1192 y + "/" + (m + 1) + "/" + d + " " +
1193 "; got " + c->get(UCAL_YEAR, status) +
1194 "/" + (c->get(UCAL_MONTH, status) + 1) +
1195 "/" + c->get(UCAL_DATE, status)
1196 );
1197
1198 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
1199 }
1200 else
1201 logln(UnicodeString("Confirmed: ") + y + "/" +
1202 (m + 1) + "/" + d);
1203 }
1204
1205 // -------------------------------------
1206
1207 /**
1208 * Test that setting of fields works. In particular, make sure that all instances
1209 * of GregorianCalendar don't share a static instance of the fields array.
1210 */
1211 void
1212 CalendarTest::TestFieldSet4781()
1213 {
1214 // try {
1215 UErrorCode status = U_ZERO_ERROR;
1216 GregorianCalendar *g = new GregorianCalendar(status);
1217 if (failure(status, "new GregorianCalendar", TRUE)) return;
1218 GregorianCalendar *g2 = new GregorianCalendar(status);
1219 if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; }
1220 g2->set(UCAL_HOUR, 12, status);
1221 g2->set(UCAL_MINUTE, 0, status);
1222 g2->set(UCAL_SECOND, 0, status);
1223 if (U_FAILURE(status)) { errln("Calendar::set failed"); return; }
1224 if (*g == *g2) logln("Same");
1225 else logln("Different");
1226 //}
1227 //catch(IllegalArgumentException e) {
1228 //errln("Unexpected exception seen: " + e);
1229 //}
1230 delete g;
1231 delete g2;
1232 }
1233
1234 // -------------------------------------
1235
1236 /* We don't support serialization on C++
1237 void
1238 CalendarTest::TestSerialize337()
1239 {
1240 Calendar cal = Calendar::getInstance();
1241 UBool ok = FALSE;
1242 try {
1243 FileOutputStream f = new FileOutputStream(FILENAME);
1244 ObjectOutput s = new ObjectOutputStream(f);
1245 s.writeObject(PREFIX);
1246 s.writeObject(cal);
1247 s.writeObject(POSTFIX);
1248 f.close();
1249 FileInputStream in = new FileInputStream(FILENAME);
1250 ObjectInputStream t = new ObjectInputStream(in);
1251 UnicodeString& pre = (UnicodeString&) t.readObject();
1252 Calendar c = (Calendar) t.readObject();
1253 UnicodeString& post = (UnicodeString&) t.readObject();
1254 in.close();
1255 ok = pre.equals(PREFIX) &&
1256 post.equals(POSTFIX) &&
1257 cal->equals(c);
1258 File fl = new File(FILENAME);
1259 fl.delete();
1260 }
1261 catch(IOException e) {
1262 errln("FAIL: Exception received:");
1263 e.printStackTrace(log);
1264 }
1265 catch(ClassNotFoundException e) {
1266 errln("FAIL: Exception received:");
1267 e.printStackTrace(log);
1268 }
1269 if (!ok) errln("Serialization of Calendar object failed.");
1270 }
1271
1272 UnicodeString& CalendarTest::PREFIX = "abc";
1273
1274 UnicodeString& CalendarTest::POSTFIX = "def";
1275
1276 UnicodeString& CalendarTest::FILENAME = "tmp337.bin";
1277 */
1278
1279 // -------------------------------------
1280
1281 /**
1282 * Verify that the seconds of a Calendar can be zeroed out through the
1283 * expected sequence of operations.
1284 */
1285 void
1286 CalendarTest::TestSecondsZero121()
1287 {
1288 UErrorCode status = U_ZERO_ERROR;
1289 Calendar *cal = new GregorianCalendar(status);
1290 if (failure(status, "new GregorianCalendar", TRUE)) return;
1291 cal->setTime(Calendar::getNow(), status);
1292 if (U_FAILURE(status)) { errln("Calendar::setTime failed"); return; }
1293 cal->set(UCAL_SECOND, 0);
1294 if (U_FAILURE(status)) { errln("Calendar::set failed"); return; }
1295 UDate d = cal->getTime(status);
1296 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; }
1297 UnicodeString s;
1298 dateToString(d, s);
1299 if (s.indexOf("DATE_FORMAT_FAILURE") >= 0) {
1300 dataerrln("Got: \"DATE_FORMAT_FAILURE\".");
1301 } else if (s.indexOf(":00 ") < 0) {
1302 errln("Expected to see :00 in " + s);
1303 }
1304 delete cal;
1305 }
1306
1307 // -------------------------------------
1308
1309 /**
1310 * Verify that a specific sequence of adding and setting works as expected;
1311 * it should not vary depending on when and whether the get method is
1312 * called.
1313 */
1314 void
1315 CalendarTest::TestAddSetGet0610()
1316 {
1317 UnicodeString EXPECTED_0610("1993/0/5", "");
1318 UErrorCode status = U_ZERO_ERROR;
1319 {
1320 Calendar *calendar = new GregorianCalendar(status);
1321 if (failure(status, "new GregorianCalendar", TRUE)) return;
1322 calendar->set(1993, UCAL_JANUARY, 4);
1323 logln("1A) " + value(calendar));
1324 calendar->add(UCAL_DATE, 1, status);
1325 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
1326 UnicodeString v = value(calendar);
1327 logln("1B) " + v);
1328 logln("--) 1993/0/5");
1329 if (!(v == EXPECTED_0610)) errln("Expected " + EXPECTED_0610 + "; saw " + v);
1330 delete calendar;
1331 }
1332 {
1333 Calendar *calendar = new GregorianCalendar(1993, UCAL_JANUARY, 4, status);
1334 if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; }
1335 logln("2A) " + value(calendar));
1336 calendar->add(UCAL_DATE, 1, status);
1337 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
1338 UnicodeString v = value(calendar);
1339 logln("2B) " + v);
1340 logln("--) 1993/0/5");
1341 if (!(v == EXPECTED_0610)) errln("Expected " + EXPECTED_0610 + "; saw " + v);
1342 delete calendar;
1343 }
1344 {
1345 Calendar *calendar = new GregorianCalendar(1993, UCAL_JANUARY, 4, status);
1346 if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; }
1347 logln("3A) " + value(calendar));
1348 calendar->getTime(status);
1349 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; }
1350 calendar->add(UCAL_DATE, 1, status);
1351 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
1352 UnicodeString v = value(calendar);
1353 logln("3B) " + v);
1354 logln("--) 1993/0/5");
1355 if (!(v == EXPECTED_0610)) errln("Expected " + EXPECTED_0610 + "; saw " + v);
1356 delete calendar;
1357 }
1358 }
1359
1360 // -------------------------------------
1361
1362 UnicodeString
1363 CalendarTest::value(Calendar* calendar)
1364 {
1365 UErrorCode status = U_ZERO_ERROR;
1366 return UnicodeString("") + (int32_t)calendar->get(UCAL_YEAR, status) +
1367 "/" + (int32_t)calendar->get(UCAL_MONTH, status) +
1368 "/" + (int32_t)calendar->get(UCAL_DATE, status) +
1369 (U_FAILURE(status) ? " FAIL: Calendar::get failed" : "");
1370 }
1371
1372
1373 // -------------------------------------
1374
1375 /**
1376 * Verify that various fields on a known date are set correctly.
1377 */
1378 void
1379 CalendarTest::TestFields060()
1380 {
1381 UErrorCode status = U_ZERO_ERROR;
1382 int32_t year = 1997;
1383 int32_t month = UCAL_OCTOBER;
1384 int32_t dDate = 22;
1385 GregorianCalendar *calendar = 0;
1386 calendar = new GregorianCalendar(year, month, dDate, status);
1387 if (failure(status, "new GregorianCalendar", TRUE)) return;
1388 for (int32_t i = 0; i < EXPECTED_FIELDS_length;) {
1389 UCalendarDateFields field = (UCalendarDateFields)EXPECTED_FIELDS[i++];
1390 int32_t expected = EXPECTED_FIELDS[i++];
1391 if (calendar->get(field, status) != expected) {
1392 errln(UnicodeString("Expected field ") + (int32_t)field + " to have value " + (int32_t)expected +
1393 "; received " + (int32_t)calendar->get(field, status) + " instead");
1394 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
1395 }
1396 }
1397 delete calendar;
1398 }
1399
1400 int32_t CalendarTest::EXPECTED_FIELDS[] = {
1401 UCAL_YEAR, 1997,
1402 UCAL_MONTH, UCAL_OCTOBER,
1403 UCAL_DATE, 22,
1404 UCAL_DAY_OF_WEEK, UCAL_WEDNESDAY,
1405 UCAL_DAY_OF_WEEK_IN_MONTH, 4,
1406 UCAL_DAY_OF_YEAR, 295
1407 };
1408
1409 const int32_t CalendarTest::EXPECTED_FIELDS_length = (int32_t)(sizeof(CalendarTest::EXPECTED_FIELDS) /
1410 sizeof(CalendarTest::EXPECTED_FIELDS[0]));
1411
1412 // -------------------------------------
1413
1414 /**
1415 * Verify that various fields on a known date are set correctly. In this
1416 * case, the start of the epoch (January 1 1970).
1417 */
1418 void
1419 CalendarTest::TestEpochStartFields()
1420 {
1421 UErrorCode status = U_ZERO_ERROR;
1422 TimeZone *z = TimeZone::createDefault();
1423 Calendar *c = Calendar::createInstance(status);
1424 if (failure(status, "Calendar::createInstance", TRUE)) return;
1425 UDate d = - z->getRawOffset();
1426 GregorianCalendar *gc = new GregorianCalendar(status);
1427 if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; }
1428 gc->setTimeZone(*z);
1429 gc->setTime(d, status);
1430 if (U_FAILURE(status)) { errln("Calendar::setTime failed"); return; }
1431 UBool idt = gc->inDaylightTime(status);
1432 if (U_FAILURE(status)) { errln("GregorianCalendar::inDaylightTime failed"); return; }
1433 if (idt) {
1434 UnicodeString str;
1435 logln("Warning: Skipping test because " + dateToString(d, str) + " is in DST.");
1436 }
1437 else {
1438 c->setTime(d, status);
1439 if (U_FAILURE(status)) { errln("Calendar::setTime failed"); return; }
1440 for (int32_t i = 0; i < UCAL_ZONE_OFFSET;++i) {
1441 if (c->get((UCalendarDateFields)i, status) != EPOCH_FIELDS[i])
1442 dataerrln(UnicodeString("Expected field ") + i + " to have value " + EPOCH_FIELDS[i] +
1443 "; saw " + c->get((UCalendarDateFields)i, status) + " instead");
1444 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
1445 }
1446 if (c->get(UCAL_ZONE_OFFSET, status) != z->getRawOffset())
1447 {
1448 errln(UnicodeString("Expected field ZONE_OFFSET to have value ") + z->getRawOffset() +
1449 "; saw " + c->get(UCAL_ZONE_OFFSET, status) + " instead");
1450 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
1451 }
1452 if (c->get(UCAL_DST_OFFSET, status) != 0)
1453 {
1454 errln(UnicodeString("Expected field DST_OFFSET to have value 0") +
1455 "; saw " + c->get(UCAL_DST_OFFSET, status) + " instead");
1456 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
1457 }
1458 }
1459 delete c;
1460 delete z;
1461 delete gc;
1462 }
1463
1464 int32_t CalendarTest::EPOCH_FIELDS[] = {
1465 1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, - 28800000, 0
1466 };
1467
1468 // -------------------------------------
1469
1470 /**
1471 * Test that the days of the week progress properly when add is called repeatedly
1472 * for increments of 24 days.
1473 */
1474 void
1475 CalendarTest::TestDOWProgression()
1476 {
1477 UErrorCode status = U_ZERO_ERROR;
1478 Calendar *cal = new GregorianCalendar(1972, UCAL_OCTOBER, 26, status);
1479 if (failure(status, "new GregorianCalendar", TRUE)) return;
1480 marchByDelta(cal, 24);
1481 delete cal;
1482 }
1483
1484 // -------------------------------------
1485
1486 void
1487 CalendarTest::TestDOW_LOCALandYEAR_WOY()
1488 {
1489 /* Note: I've commented out the loop_addroll tests for YEAR and
1490 * YEAR_WOY below because these two fields should NOT behave
1491 * identically when adding. YEAR should keep the month/dom
1492 * invariant. YEAR_WOY should keep the woy/dow invariant. I've
1493 * added a new test that checks for this in place of the old call
1494 * to loop_addroll. - aliu */
1495 UErrorCode status = U_ZERO_ERROR;
1496 int32_t times = 20;
1497 Calendar *cal=Calendar::createInstance(Locale::getGermany(), status);
1498 if (failure(status, "Calendar::createInstance", TRUE)) return;
1499 SimpleDateFormat *sdf=new SimpleDateFormat(UnicodeString("YYYY'-W'ww-ee"), Locale::getGermany(), status);
1500 if (U_FAILURE(status)) { dataerrln("Couldn't create SimpleDateFormat - %s", u_errorName(status)); return; }
1501
1502 // ICU no longer use localized date-time pattern characters by default.
1503 // So we set pattern chars using 'J' instead of 'Y'.
1504 DateFormatSymbols *dfs = new DateFormatSymbols(Locale::getGermany(), status);
1505 dfs->setLocalPatternChars(UnicodeString("GyMdkHmsSEDFwWahKzJeugAZvcLQq"));
1506 sdf->adoptDateFormatSymbols(dfs);
1507 sdf->applyLocalizedPattern(UnicodeString("JJJJ'-W'ww-ee"), status);
1508 if (U_FAILURE(status)) { errln("Couldn't apply localized pattern"); return; }
1509
1510 cal->clear();
1511 cal->set(1997, UCAL_DECEMBER, 25);
1512 doYEAR_WOYLoop(cal, sdf, times, status);
1513 //loop_addroll(cal, /*sdf,*/ times, UCAL_YEAR_WOY, UCAL_YEAR, status);
1514 yearAddTest(*cal, status); // aliu
1515 loop_addroll(cal, /*sdf,*/ times, UCAL_DOW_LOCAL, UCAL_DAY_OF_WEEK, status);
1516 if (U_FAILURE(status)) { errln("Error in parse/calculate test for 1997"); return; }
1517
1518 cal->clear();
1519 cal->set(1998, UCAL_DECEMBER, 25);
1520 doYEAR_WOYLoop(cal, sdf, times, status);
1521 //loop_addroll(cal, /*sdf,*/ times, UCAL_YEAR_WOY, UCAL_YEAR, status);
1522 yearAddTest(*cal, status); // aliu
1523 loop_addroll(cal, /*sdf,*/ times, UCAL_DOW_LOCAL, UCAL_DAY_OF_WEEK, status);
1524 if (U_FAILURE(status)) { errln("Error in parse/calculate test for 1998"); return; }
1525
1526 cal->clear();
1527 cal->set(1582, UCAL_OCTOBER, 1);
1528 doYEAR_WOYLoop(cal, sdf, times, status);
1529 //loop_addroll(cal, /*sdf,*/ times, Calendar::YEAR_WOY, Calendar::YEAR, status);
1530 yearAddTest(*cal, status); // aliu
1531 loop_addroll(cal, /*sdf,*/ times, UCAL_DOW_LOCAL, UCAL_DAY_OF_WEEK, status);
1532 if (U_FAILURE(status)) { errln("Error in parse/calculate test for 1582"); return; }
1533 delete sdf;
1534 delete cal;
1535
1536 return;
1537 }
1538
1539 /**
1540 * Confirm that adding a YEAR and adding a YEAR_WOY work properly for
1541 * the given Calendar at its current setting.
1542 */
1543 void CalendarTest::yearAddTest(Calendar& cal, UErrorCode& status) {
1544 /**
1545 * When adding the YEAR, the month and day should remain constant.
1546 * When adding the YEAR_WOY, the WOY and DOW should remain constant. - aliu
1547 * Examples:
1548 * Wed Jan 14 1998 / 1998-W03-03 Add(YEAR_WOY, 1) -> Wed Jan 20 1999 / 1999-W03-03
1549 * Add(YEAR, 1) -> Thu Jan 14 1999 / 1999-W02-04
1550 * Thu Jan 14 1999 / 1999-W02-04 Add(YEAR_WOY, 1) -> Thu Jan 13 2000 / 2000-W02-04
1551 * Add(YEAR, 1) -> Fri Jan 14 2000 / 2000-W02-05
1552 * Sun Oct 31 1582 / 1582-W42-07 Add(YEAR_WOY, 1) -> Sun Oct 23 1583 / 1583-W42-07
1553 * Add(YEAR, 1) -> Mon Oct 31 1583 / 1583-W44-01
1554 */
1555 int32_t y = cal.get(UCAL_YEAR, status);
1556 int32_t mon = cal.get(UCAL_MONTH, status);
1557 int32_t day = cal.get(UCAL_DATE, status);
1558 int32_t ywy = cal.get(UCAL_YEAR_WOY, status);
1559 int32_t woy = cal.get(UCAL_WEEK_OF_YEAR, status);
1560 int32_t dow = cal.get(UCAL_DOW_LOCAL, status);
1561 UDate t = cal.getTime(status);
1562
1563 if(U_FAILURE(status)){
1564 errln(UnicodeString("Failed to create Calendar for locale. Error: ") + UnicodeString(u_errorName(status)));
1565 return;
1566 }
1567 UnicodeString str, str2;
1568 SimpleDateFormat fmt(UnicodeString("EEE MMM dd yyyy / YYYY'-W'ww-ee"), status);
1569 fmt.setCalendar(cal);
1570
1571 fmt.format(t, str.remove());
1572 str += ".add(YEAR, 1) =>";
1573 cal.add(UCAL_YEAR, 1, status);
1574 int32_t y2 = cal.get(UCAL_YEAR, status);
1575 int32_t mon2 = cal.get(UCAL_MONTH, status);
1576 int32_t day2 = cal.get(UCAL_DATE, status);
1577 fmt.format(cal.getTime(status), str);
1578 if (y2 != (y+1) || mon2 != mon || day2 != day) {
1579 str += (UnicodeString)", expected year " +
1580 (y+1) + ", month " + (mon+1) + ", day " + day;
1581 errln((UnicodeString)"FAIL: " + str);
1582 logln( UnicodeString(" -> ") + CalendarTest::calToStr(cal) );
1583 } else {
1584 logln(str);
1585 }
1586
1587 fmt.format(t, str.remove());
1588 str += ".add(YEAR_WOY, 1)=>";
1589 cal.setTime(t, status);
1590 logln( UnicodeString(" <- ") + CalendarTest::calToStr(cal) );
1591 cal.add(UCAL_YEAR_WOY, 1, status);
1592 int32_t ywy2 = cal.get(UCAL_YEAR_WOY, status);
1593 int32_t woy2 = cal.get(UCAL_WEEK_OF_YEAR, status);
1594 int32_t dow2 = cal.get(UCAL_DOW_LOCAL, status);
1595 fmt.format(cal.getTime(status), str);
1596 if (ywy2 != (ywy+1) || woy2 != woy || dow2 != dow) {
1597 str += (UnicodeString)", expected yearWOY " +
1598 (ywy+1) + ", woy " + woy + ", dowLocal " + dow;
1599 errln((UnicodeString)"FAIL: " + str);
1600 logln( UnicodeString(" -> ") + CalendarTest::calToStr(cal) );
1601 } else {
1602 logln(str);
1603 }
1604 }
1605
1606 // -------------------------------------
1607
1608 void CalendarTest::loop_addroll(Calendar *cal, /*SimpleDateFormat *sdf,*/ int times, UCalendarDateFields field, UCalendarDateFields field2, UErrorCode& errorCode) {
1609 Calendar *calclone;
1610 SimpleDateFormat fmt(UnicodeString("EEE MMM dd yyyy / YYYY'-W'ww-ee"), errorCode);
1611 fmt.setCalendar(*cal);
1612 int i;
1613
1614 for(i = 0; i<times; i++) {
1615 calclone = cal->clone();
1616 UDate start = cal->getTime(errorCode);
1617 cal->add(field,1,errorCode);
1618 if (U_FAILURE(errorCode)) { errln("Error in add"); delete calclone; return; }
1619 calclone->add(field2,1,errorCode);
1620 if (U_FAILURE(errorCode)) { errln("Error in add"); delete calclone; return; }
1621 if(cal->getTime(errorCode) != calclone->getTime(errorCode)) {
1622 UnicodeString str("FAIL: Results of add differ. "), str2;
1623 str += fmt.format(start, str2) + " ";
1624 str += UnicodeString("Add(") + fieldName(field) + ", 1) -> " +
1625 fmt.format(cal->getTime(errorCode), str2.remove()) + "; ";
1626 str += UnicodeString("Add(") + fieldName(field2) + ", 1) -> " +
1627 fmt.format(calclone->getTime(errorCode), str2.remove());
1628 errln(str);
1629 delete calclone;
1630 return;
1631 }
1632 delete calclone;
1633 }
1634
1635 for(i = 0; i<times; i++) {
1636 calclone = cal->clone();
1637 cal->roll(field,(int32_t)1,errorCode);
1638 if (U_FAILURE(errorCode)) { errln("Error in roll"); delete calclone; return; }
1639 calclone->roll(field2,(int32_t)1,errorCode);
1640 if (U_FAILURE(errorCode)) { errln("Error in roll"); delete calclone; return; }
1641 if(cal->getTime(errorCode) != calclone->getTime(errorCode)) {
1642 delete calclone;
1643 errln("Results of roll differ!");
1644 return;
1645 }
1646 delete calclone;
1647 }
1648 }
1649
1650 // -------------------------------------
1651
1652 void
1653 CalendarTest::doYEAR_WOYLoop(Calendar *cal, SimpleDateFormat *sdf,
1654 int32_t times, UErrorCode& errorCode) {
1655
1656 UnicodeString us;
1657 UDate tst, original;
1658 Calendar *tstres = new GregorianCalendar(Locale::getGermany(), errorCode);
1659 for(int i=0; i<times; ++i) {
1660 sdf->format(Formattable(cal->getTime(errorCode),Formattable::kIsDate), us, errorCode);
1661 //logln("expected: "+us);
1662 if (U_FAILURE(errorCode)) { errln("Format error"); return; }
1663 tst=sdf->parse(us,errorCode);
1664 if (U_FAILURE(errorCode)) { errln("Parse error"); return; }
1665 tstres->clear();
1666 tstres->setTime(tst, errorCode);
1667 //logln((UnicodeString)"Parsed week of year is "+tstres->get(UCAL_WEEK_OF_YEAR, errorCode));
1668 if (U_FAILURE(errorCode)) { errln("Set time error"); return; }
1669 original = cal->getTime(errorCode);
1670 us.remove();
1671 sdf->format(Formattable(tst,Formattable::kIsDate), us, errorCode);
1672 //logln("got: "+us);
1673 if (U_FAILURE(errorCode)) { errln("Get time error"); return; }
1674 if(original!=tst) {
1675 us.remove();
1676 sdf->format(Formattable(original, Formattable::kIsDate), us, errorCode);
1677 errln("FAIL: Parsed time doesn't match with regular");
1678 logln("expected "+us + " " + calToStr(*cal));
1679 us.remove();
1680 sdf->format(Formattable(tst, Formattable::kIsDate), us, errorCode);
1681 logln("got "+us + " " + calToStr(*tstres));
1682 }
1683 tstres->clear();
1684 tstres->set(UCAL_YEAR_WOY, cal->get(UCAL_YEAR_WOY, errorCode));
1685 tstres->set(UCAL_WEEK_OF_YEAR, cal->get(UCAL_WEEK_OF_YEAR, errorCode));
1686 tstres->set(UCAL_DOW_LOCAL, cal->get(UCAL_DOW_LOCAL, errorCode));
1687 if(cal->get(UCAL_YEAR, errorCode) != tstres->get(UCAL_YEAR, errorCode)) {
1688 errln("FAIL: Different Year!");
1689 logln((UnicodeString)"Expected "+cal->get(UCAL_YEAR, errorCode));
1690 logln((UnicodeString)"Got "+tstres->get(UCAL_YEAR, errorCode));
1691 return;
1692 }
1693 if(cal->get(UCAL_DAY_OF_YEAR, errorCode) != tstres->get(UCAL_DAY_OF_YEAR, errorCode)) {
1694 errln("FAIL: Different Day Of Year!");
1695 logln((UnicodeString)"Expected "+cal->get(UCAL_DAY_OF_YEAR, errorCode));
1696 logln((UnicodeString)"Got "+tstres->get(UCAL_DAY_OF_YEAR, errorCode));
1697 return;
1698 }
1699 //logln(calToStr(*cal));
1700 cal->add(UCAL_DATE, 1, errorCode);
1701 if (U_FAILURE(errorCode)) { errln("Add error"); return; }
1702 us.remove();
1703 }
1704 delete (tstres);
1705 }
1706 // -------------------------------------
1707
1708 void
1709 CalendarTest::marchByDelta(Calendar* cal, int32_t delta)
1710 {
1711 UErrorCode status = U_ZERO_ERROR;
1712 Calendar *cur = (Calendar*) cal->clone();
1713 int32_t initialDOW = cur->get(UCAL_DAY_OF_WEEK, status);
1714 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
1715 int32_t DOW, newDOW = initialDOW;
1716 do {
1717 UnicodeString str;
1718 DOW = newDOW;
1719 logln(UnicodeString("DOW = ") + DOW + " " + dateToString(cur->getTime(status), str));
1720 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; }
1721 cur->add(UCAL_DAY_OF_WEEK, delta, status);
1722 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
1723 newDOW = cur->get(UCAL_DAY_OF_WEEK, status);
1724 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
1725 int32_t expectedDOW = 1 + (DOW + delta - 1) % 7;
1726 if (newDOW != expectedDOW) {
1727 errln(UnicodeString("Day of week should be ") + expectedDOW + " instead of " + newDOW +
1728 " on " + dateToString(cur->getTime(status), str));
1729 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; }
1730 return;
1731 }
1732 }
1733 while (newDOW != initialDOW);
1734 delete cur;
1735 }
1736
1737 #define CHECK(status, msg) \
1738 if (U_FAILURE(status)) { \
1739 errcheckln(status, msg); \
1740 return; \
1741 }
1742
1743 void CalendarTest::TestWOY(void) {
1744 /*
1745 FDW = Mon, MDFW = 4:
1746 Sun Dec 26 1999, WOY 51
1747 Mon Dec 27 1999, WOY 52
1748 Tue Dec 28 1999, WOY 52
1749 Wed Dec 29 1999, WOY 52
1750 Thu Dec 30 1999, WOY 52
1751 Fri Dec 31 1999, WOY 52
1752 Sat Jan 01 2000, WOY 52 ***
1753 Sun Jan 02 2000, WOY 52 ***
1754 Mon Jan 03 2000, WOY 1
1755 Tue Jan 04 2000, WOY 1
1756 Wed Jan 05 2000, WOY 1
1757 Thu Jan 06 2000, WOY 1
1758 Fri Jan 07 2000, WOY 1
1759 Sat Jan 08 2000, WOY 1
1760 Sun Jan 09 2000, WOY 1
1761 Mon Jan 10 2000, WOY 2
1762
1763 FDW = Mon, MDFW = 2:
1764 Sun Dec 26 1999, WOY 52
1765 Mon Dec 27 1999, WOY 1 ***
1766 Tue Dec 28 1999, WOY 1 ***
1767 Wed Dec 29 1999, WOY 1 ***
1768 Thu Dec 30 1999, WOY 1 ***
1769 Fri Dec 31 1999, WOY 1 ***
1770 Sat Jan 01 2000, WOY 1
1771 Sun Jan 02 2000, WOY 1
1772 Mon Jan 03 2000, WOY 2
1773 Tue Jan 04 2000, WOY 2
1774 Wed Jan 05 2000, WOY 2
1775 Thu Jan 06 2000, WOY 2
1776 Fri Jan 07 2000, WOY 2
1777 Sat Jan 08 2000, WOY 2
1778 Sun Jan 09 2000, WOY 2
1779 Mon Jan 10 2000, WOY 3
1780 */
1781
1782 UnicodeString str;
1783 UErrorCode status = U_ZERO_ERROR;
1784 int32_t i;
1785
1786 GregorianCalendar cal(status);
1787 SimpleDateFormat fmt(UnicodeString("EEE MMM dd yyyy', WOY' w"), status);
1788 if (failure(status, "Cannot construct calendar/format", TRUE)) return;
1789
1790 UCalendarDaysOfWeek fdw = (UCalendarDaysOfWeek) 0;
1791
1792 //for (int8_t pass=2; pass<=2; ++pass) {
1793 for (int8_t pass=1; pass<=2; ++pass) {
1794 switch (pass) {
1795 case 1:
1796 fdw = UCAL_MONDAY;
1797 cal.setFirstDayOfWeek(fdw);
1798 cal.setMinimalDaysInFirstWeek(4);
1799 fmt.adoptCalendar(cal.clone());
1800 break;
1801 case 2:
1802 fdw = UCAL_MONDAY;
1803 cal.setFirstDayOfWeek(fdw);
1804 cal.setMinimalDaysInFirstWeek(2);
1805 fmt.adoptCalendar(cal.clone());
1806 break;
1807 }
1808
1809 //for (i=2; i<=6; ++i) {
1810 for (i=0; i<16; ++i) {
1811 UDate t, t2;
1812 int32_t t_y, t_woy, t_dow;
1813 cal.clear();
1814 cal.set(1999, UCAL_DECEMBER, 26 + i);
1815 fmt.format(t = cal.getTime(status), str.remove());
1816 CHECK(status, "Fail: getTime failed");
1817 logln(UnicodeString("* ") + str);
1818 int32_t dow = cal.get(UCAL_DAY_OF_WEEK, status);
1819 int32_t woy = cal.get(UCAL_WEEK_OF_YEAR, status);
1820 int32_t year = cal.get(UCAL_YEAR, status);
1821 int32_t mon = cal.get(UCAL_MONTH, status);
1822 logln(calToStr(cal));
1823 CHECK(status, "Fail: get failed");
1824 int32_t dowLocal = dow - fdw;
1825 if (dowLocal < 0) dowLocal += 7;
1826 dowLocal++;
1827 int32_t yearWoy = year;
1828 if (mon == UCAL_JANUARY) {
1829 if (woy >= 52) --yearWoy;
1830 } else {
1831 if (woy == 1) ++yearWoy;
1832 }
1833
1834 // Basic fields->time check y/woy/dow
1835 // Since Y/WOY is ambiguous, we do a check of the fields,
1836 // not of the specific time.
1837 cal.clear();
1838 cal.set(UCAL_YEAR, year);
1839 cal.set(UCAL_WEEK_OF_YEAR, woy);
1840 cal.set(UCAL_DAY_OF_WEEK, dow);
1841 t_y = cal.get(UCAL_YEAR, status);
1842 t_woy = cal.get(UCAL_WEEK_OF_YEAR, status);
1843 t_dow = cal.get(UCAL_DAY_OF_WEEK, status);
1844 CHECK(status, "Fail: get failed");
1845 if (t_y != year || t_woy != woy || t_dow != dow) {
1846 str = "Fail: y/woy/dow fields->time => ";
1847 fmt.format(cal.getTime(status), str);
1848 errln(str);
1849 logln(calToStr(cal));
1850 logln("[get!=set] Y%d!=%d || woy%d!=%d || dow%d!=%d\n",
1851 t_y, year, t_woy, woy, t_dow, dow);
1852 } else {
1853 logln("y/woy/dow fields->time OK");
1854 }
1855
1856 // Basic fields->time check y/woy/dow_local
1857 // Since Y/WOY is ambiguous, we do a check of the fields,
1858 // not of the specific time.
1859 cal.clear();
1860 cal.set(UCAL_YEAR, year);
1861 cal.set(UCAL_WEEK_OF_YEAR, woy);
1862 cal.set(UCAL_DOW_LOCAL, dowLocal);
1863 t_y = cal.get(UCAL_YEAR, status);
1864 t_woy = cal.get(UCAL_WEEK_OF_YEAR, status);
1865 t_dow = cal.get(UCAL_DOW_LOCAL, status);
1866 CHECK(status, "Fail: get failed");
1867 if (t_y != year || t_woy != woy || t_dow != dowLocal) {
1868 str = "Fail: y/woy/dow_local fields->time => ";
1869 fmt.format(cal.getTime(status), str);
1870 errln(str);
1871 }
1872
1873 // Basic fields->time check y_woy/woy/dow
1874 cal.clear();
1875 cal.set(UCAL_YEAR_WOY, yearWoy);
1876 cal.set(UCAL_WEEK_OF_YEAR, woy);
1877 cal.set(UCAL_DAY_OF_WEEK, dow);
1878 t2 = cal.getTime(status);
1879 CHECK(status, "Fail: getTime failed");
1880 if (t != t2) {
1881 str = "Fail: y_woy/woy/dow fields->time => ";
1882 fmt.format(t2, str);
1883 errln(str);
1884 logln(calToStr(cal));
1885 logln("%.f != %.f\n", t, t2);
1886 } else {
1887 logln("y_woy/woy/dow OK");
1888 }
1889
1890 // Basic fields->time check y_woy/woy/dow_local
1891 cal.clear();
1892 cal.set(UCAL_YEAR_WOY, yearWoy);
1893 cal.set(UCAL_WEEK_OF_YEAR, woy);
1894 cal.set(UCAL_DOW_LOCAL, dowLocal);
1895 t2 = cal.getTime(status);
1896 CHECK(status, "Fail: getTime failed");
1897 if (t != t2) {
1898 str = "Fail: y_woy/woy/dow_local fields->time => ";
1899 fmt.format(t2, str);
1900 errln(str);
1901 }
1902
1903 logln("Testing DOW_LOCAL.. dow%d\n", dow);
1904 // Make sure DOW_LOCAL disambiguates over DOW
1905 int32_t wrongDow = dow - 3;
1906 if (wrongDow < 1) wrongDow += 7;
1907 cal.setTime(t, status);
1908 cal.set(UCAL_DAY_OF_WEEK, wrongDow);
1909 cal.set(UCAL_DOW_LOCAL, dowLocal);
1910 t2 = cal.getTime(status);
1911 CHECK(status, "Fail: set/getTime failed");
1912 if (t != t2) {
1913 str = "Fail: DOW_LOCAL fields->time => ";
1914 fmt.format(t2, str);
1915 errln(str);
1916 logln(calToStr(cal));
1917 logln("%.f : DOW%d, DOW_LOCAL%d -> %.f\n",
1918 t, wrongDow, dowLocal, t2);
1919 }
1920
1921 // Make sure DOW disambiguates over DOW_LOCAL
1922 int32_t wrongDowLocal = dowLocal - 3;
1923 if (wrongDowLocal < 1) wrongDowLocal += 7;
1924 cal.setTime(t, status);
1925 cal.set(UCAL_DOW_LOCAL, wrongDowLocal);
1926 cal.set(UCAL_DAY_OF_WEEK, dow);
1927 t2 = cal.getTime(status);
1928 CHECK(status, "Fail: set/getTime failed");
1929 if (t != t2) {
1930 str = "Fail: DOW fields->time => ";
1931 fmt.format(t2, str);
1932 errln(str);
1933 }
1934
1935 // Make sure YEAR_WOY disambiguates over YEAR
1936 cal.setTime(t, status);
1937 cal.set(UCAL_YEAR, year - 2);
1938 cal.set(UCAL_YEAR_WOY, yearWoy);
1939 t2 = cal.getTime(status);
1940 CHECK(status, "Fail: set/getTime failed");
1941 if (t != t2) {
1942 str = "Fail: YEAR_WOY fields->time => ";
1943 fmt.format(t2, str);
1944 errln(str);
1945 }
1946
1947 // Make sure YEAR disambiguates over YEAR_WOY
1948 cal.setTime(t, status);
1949 cal.set(UCAL_YEAR_WOY, yearWoy - 2);
1950 cal.set(UCAL_YEAR, year);
1951 t2 = cal.getTime(status);
1952 CHECK(status, "Fail: set/getTime failed");
1953 if (t != t2) {
1954 str = "Fail: YEAR fields->time => ";
1955 fmt.format(t2, str);
1956 errln(str);
1957 }
1958 }
1959 }
1960
1961 /*
1962 FDW = Mon, MDFW = 4:
1963 Sun Dec 26 1999, WOY 51
1964 Mon Dec 27 1999, WOY 52
1965 Tue Dec 28 1999, WOY 52
1966 Wed Dec 29 1999, WOY 52
1967 Thu Dec 30 1999, WOY 52
1968 Fri Dec 31 1999, WOY 52
1969 Sat Jan 01 2000, WOY 52
1970 Sun Jan 02 2000, WOY 52
1971 */
1972
1973 // Roll the DOW_LOCAL within week 52
1974 for (i=27; i<=33; ++i) {
1975 int32_t amount;
1976 for (amount=-7; amount<=7; ++amount) {
1977 str = "roll(";
1978 cal.set(1999, UCAL_DECEMBER, i);
1979 UDate t, t2;
1980 fmt.format(cal.getTime(status), str);
1981 CHECK(status, "Fail: getTime failed");
1982 str += UnicodeString(", ") + amount + ") = ";
1983
1984 cal.roll(UCAL_DOW_LOCAL, amount, status);
1985 CHECK(status, "Fail: roll failed");
1986
1987 t = cal.getTime(status);
1988 int32_t newDom = i + amount;
1989 while (newDom < 27) newDom += 7;
1990 while (newDom > 33) newDom -= 7;
1991 cal.set(1999, UCAL_DECEMBER, newDom);
1992 t2 = cal.getTime(status);
1993 CHECK(status, "Fail: getTime failed");
1994 fmt.format(t, str);
1995
1996 if (t != t2) {
1997 str.append(", exp ");
1998 fmt.format(t2, str);
1999 errln(str);
2000 } else {
2001 logln(str);
2002 }
2003 }
2004 }
2005 }
2006
2007 void CalendarTest::TestYWOY()
2008 {
2009 UnicodeString str;
2010 UErrorCode status = U_ZERO_ERROR;
2011
2012 GregorianCalendar cal(status);
2013 if (failure(status, "construct GregorianCalendar", TRUE)) return;
2014
2015 cal.setFirstDayOfWeek(UCAL_SUNDAY);
2016 cal.setMinimalDaysInFirstWeek(1);
2017
2018 logln("Setting: ywoy=2004, woy=1, dow=MONDAY");
2019 cal.clear();
2020 cal.set(UCAL_YEAR_WOY,2004);
2021 cal.set(UCAL_WEEK_OF_YEAR,1);
2022 cal.set(UCAL_DAY_OF_WEEK, UCAL_MONDAY);
2023
2024 logln(calToStr(cal));
2025 if(cal.get(UCAL_YEAR, status) != 2003) {
2026 errln("year not 2003");
2027 }
2028
2029 logln("+ setting DOW to THURSDAY");
2030 cal.clear();
2031 cal.set(UCAL_YEAR_WOY,2004);
2032 cal.set(UCAL_WEEK_OF_YEAR,1);
2033 cal.set(UCAL_DAY_OF_WEEK, UCAL_THURSDAY);
2034
2035 logln(calToStr(cal));
2036 if(cal.get(UCAL_YEAR, status) != 2004) {
2037 errln("year not 2004");
2038 }
2039
2040 logln("+ setting DOW_LOCAL to 1");
2041 cal.clear();
2042 cal.set(UCAL_YEAR_WOY,2004);
2043 cal.set(UCAL_WEEK_OF_YEAR,1);
2044 cal.set(UCAL_DAY_OF_WEEK, UCAL_THURSDAY);
2045 cal.set(UCAL_DOW_LOCAL, 1);
2046
2047 logln(calToStr(cal));
2048 if(cal.get(UCAL_YEAR, status) != 2003) {
2049 errln("year not 2003");
2050 }
2051
2052 cal.setFirstDayOfWeek(UCAL_MONDAY);
2053 cal.setMinimalDaysInFirstWeek(4);
2054 UDate t = 946713600000.;
2055 cal.setTime(t, status);
2056 cal.set(UCAL_DAY_OF_WEEK, 4);
2057 cal.set(UCAL_DOW_LOCAL, 6);
2058 if(cal.getTime(status) != t) {
2059 logln(calToStr(cal));
2060 errln("FAIL: DOW_LOCAL did not take precedence");
2061 }
2062
2063 }
2064
2065 void CalendarTest::TestJD()
2066 {
2067 int32_t jd;
2068 static const int32_t kEpochStartAsJulianDay = 2440588;
2069 UErrorCode status = U_ZERO_ERROR;
2070 GregorianCalendar cal(status);
2071 if (failure(status, "construct GregorianCalendar", TRUE)) return;
2072 cal.setTimeZone(*TimeZone::getGMT());
2073 cal.clear();
2074 jd = cal.get(UCAL_JULIAN_DAY, status);
2075 if(jd != kEpochStartAsJulianDay) {
2076 errln("Wanted JD of %d at time=0, [epoch 1970] but got %d\n", kEpochStartAsJulianDay, jd);
2077 } else {
2078 logln("Wanted JD of %d at time=0, [epoch 1970], got %d\n", kEpochStartAsJulianDay, jd);
2079 }
2080
2081 cal.setTime(Calendar::getNow(), status);
2082 cal.clear();
2083 cal.set(UCAL_JULIAN_DAY, kEpochStartAsJulianDay);
2084 UDate epochTime = cal.getTime(status);
2085 if(epochTime != 0) {
2086 errln("Wanted time of 0 at jd=%d, got %.1lf\n", kEpochStartAsJulianDay, epochTime);
2087 } else {
2088 logln("Wanted time of 0 at jd=%d, got %.1lf\n", kEpochStartAsJulianDay, epochTime);
2089 }
2090
2091 }
2092
2093 // make sure the ctestfw utilities are in sync with the Calendar
2094 void CalendarTest::TestDebug()
2095 {
2096 for(int32_t t=0;t<=UDBG_ENUM_COUNT;t++) {
2097 int32_t count = udbg_enumCount((UDebugEnumType)t);
2098 if(count == -1) {
2099 logln("enumCount(%d) returned -1", count);
2100 continue;
2101 }
2102 for(int32_t i=0;i<=count;i++) {
2103 if(t<=UDBG_HIGHEST_CONTIGUOUS_ENUM && i<count) {
2104 if( i!=udbg_enumArrayValue((UDebugEnumType)t, i)) {
2105 errln("FAIL: udbg_enumArrayValue(%d,%d) returned %d, expected %d", t, i, udbg_enumArrayValue((UDebugEnumType)t,i), i);
2106 }
2107 } else {
2108 logln("Testing count+1:");
2109 }
2110 const char *name = udbg_enumName((UDebugEnumType)t,i);
2111 if(name==NULL) {
2112 if(i==count || t>UDBG_HIGHEST_CONTIGUOUS_ENUM ) {
2113 logln(" null name - expected.\n");
2114 } else {
2115 errln("FAIL: udbg_enumName(%d,%d) returned NULL", t, i);
2116 }
2117 name = "(null)";
2118 }
2119 logln("udbg_enumArrayValue(%d,%d) = %s, returned %d", t, i,
2120 name, udbg_enumArrayValue((UDebugEnumType)t,i));
2121 logln("udbg_enumString = " + udbg_enumString((UDebugEnumType)t,i));
2122 }
2123 if(udbg_enumExpectedCount((UDebugEnumType)t) != count && t<=UDBG_HIGHEST_CONTIGUOUS_ENUM) {
2124 errln("FAIL: udbg_enumExpectedCount(%d): %d, != UCAL_FIELD_COUNT=%d ", t, udbg_enumExpectedCount((UDebugEnumType)t), count);
2125 } else {
2126 logln("udbg_ucal_fieldCount: %d, UCAL_FIELD_COUNT=udbg_enumCount %d ", udbg_enumExpectedCount((UDebugEnumType)t), count);
2127 }
2128 }
2129 }
2130
2131
2132 #undef CHECK
2133
2134 // List of interesting locales
2135 const char *CalendarTest::testLocaleID(int32_t i)
2136 {
2137 switch(i) {
2138 case 0: return "he_IL@calendar=hebrew";
2139 case 1: return "en_US@calendar=hebrew";
2140 case 2: return "fr_FR@calendar=hebrew";
2141 case 3: return "fi_FI@calendar=hebrew";
2142 case 4: return "nl_NL@calendar=hebrew";
2143 case 5: return "hu_HU@calendar=hebrew";
2144 case 6: return "nl_BE@currency=MTL;calendar=islamic";
2145 case 7: return "th_TH_TRADITIONAL@calendar=gregorian";
2146 case 8: return "ar_JO@calendar=islamic-civil";
2147 case 9: return "fi_FI@calendar=islamic";
2148 case 10: return "fr_CH@calendar=islamic-civil";
2149 case 11: return "he_IL@calendar=islamic-civil";
2150 case 12: return "hu_HU@calendar=buddhist";
2151 case 13: return "hu_HU@calendar=islamic";
2152 case 14: return "en_US@calendar=japanese";
2153 default: return NULL;
2154 }
2155 }
2156
2157 int32_t CalendarTest::testLocaleCount()
2158 {
2159 static int32_t gLocaleCount = -1;
2160 if(gLocaleCount < 0) {
2161 int32_t i;
2162 for(i=0;testLocaleID(i) != NULL;i++) {
2163 ;
2164 }
2165 gLocaleCount = i;
2166 }
2167 return gLocaleCount;
2168 }
2169
2170 static UDate doMinDateOfCalendar(Calendar* adopt, UBool &isGregorian, UErrorCode& status) {
2171 if(U_FAILURE(status)) return 0.0;
2172
2173 adopt->clear();
2174 adopt->set(UCAL_EXTENDED_YEAR, adopt->getActualMinimum(UCAL_EXTENDED_YEAR, status));
2175 UDate ret = adopt->getTime(status);
2176 isGregorian = dynamic_cast<GregorianCalendar*>(adopt) != NULL;
2177 delete adopt;
2178 return ret;
2179 }
2180
2181 UDate CalendarTest::minDateOfCalendar(const Locale& locale, UBool &isGregorian, UErrorCode& status) {
2182 if(U_FAILURE(status)) return 0.0;
2183 return doMinDateOfCalendar(Calendar::createInstance(locale, status), isGregorian, status);
2184 }
2185
2186 UDate CalendarTest::minDateOfCalendar(const Calendar& cal, UBool &isGregorian, UErrorCode& status) {
2187 if(U_FAILURE(status)) return 0.0;
2188 return doMinDateOfCalendar(cal.clone(), isGregorian, status);
2189 }
2190
2191 void CalendarTest::Test6703()
2192 {
2193 UErrorCode status = U_ZERO_ERROR;
2194 Calendar *cal;
2195
2196 Locale loc1("en@calendar=fubar");
2197 cal = Calendar::createInstance(loc1, status);
2198 if (failure(status, "Calendar::createInstance", TRUE)) return;
2199 delete cal;
2200
2201 status = U_ZERO_ERROR;
2202 Locale loc2("en");
2203 cal = Calendar::createInstance(loc2, status);
2204 if (failure(status, "Calendar::createInstance")) return;
2205 delete cal;
2206
2207 status = U_ZERO_ERROR;
2208 Locale loc3("en@calendar=roc");
2209 cal = Calendar::createInstance(loc3, status);
2210 if (failure(status, "Calendar::createInstance")) return;
2211 delete cal;
2212
2213 return;
2214 }
2215
2216 void CalendarTest::Test3785()
2217 {
2218 UErrorCode status = U_ZERO_ERROR;
2219 UnicodeString uzone = UNICODE_STRING_SIMPLE("Europe/Paris");
2220 UnicodeString exp1 = UNICODE_STRING_SIMPLE("Mon 30 Jumada II 1433 AH, 01:47:09");
2221 UnicodeString exp2 = UNICODE_STRING_SIMPLE("Mon 1 Rajab 1433 AH, 01:47:10");
2222
2223 LocalUDateFormatPointer df(udat_open(UDAT_NONE, UDAT_NONE, "en@calendar=islamic", uzone.getTerminatedBuffer(),
2224 uzone.length(), NULL, 0, &status));
2225 if (df.isNull() || U_FAILURE(status)) return;
2226
2227 UChar upattern[64];
2228 u_uastrcpy(upattern, "EEE d MMMM y G, HH:mm:ss");
2229 udat_applyPattern(df.getAlias(), FALSE, upattern, u_strlen(upattern));
2230
2231 UChar ubuffer[1024];
2232 UDate ud0 = 1337557629000.0;
2233
2234 status = U_ZERO_ERROR;
2235 udat_format(df.getAlias(), ud0, ubuffer, 1024, NULL, &status);
2236 if (U_FAILURE(status)) {
2237 errln("Error formatting date 1\n");
2238 return;
2239 }
2240 //printf("formatted: '%s'\n", mkcstr(ubuffer));
2241
2242 UnicodeString act1(ubuffer);
2243 if ( act1 != exp1 ) {
2244 errln(UnicodeString("Unexpected result from date 1 format, act1: ") + act1);
2245 }
2246 ud0 += 1000.0; // add one second
2247
2248 status = U_ZERO_ERROR;
2249 udat_format(df.getAlias(), ud0, ubuffer, 1024, NULL, &status);
2250 if (U_FAILURE(status)) {
2251 errln("Error formatting date 2\n");
2252 return;
2253 }
2254 //printf("formatted: '%s'\n", mkcstr(ubuffer));
2255 UnicodeString act2(ubuffer);
2256 if ( act2 != exp2 ) {
2257 errln(UnicodeString("Unexpected result from date 2 format, act2: ") + act2);
2258 }
2259
2260 return;
2261 }
2262
2263 void CalendarTest::Test1624() {
2264 UErrorCode status = U_ZERO_ERROR;
2265 Locale loc("he_IL@calendar=hebrew");
2266 HebrewCalendar hc(loc,status);
2267
2268 for (int32_t year = 5600; year < 5800; year++ ) {
2269
2270 for (int32_t month = HebrewCalendar::TISHRI; month <= HebrewCalendar::ELUL; month++) {
2271 // skip the adar 1 month if year is not a leap year
2272 if (HebrewCalendar::isLeapYear(year) == FALSE && month == HebrewCalendar::ADAR_1) {
2273 continue;
2274 }
2275 int32_t day = 15;
2276 hc.set(year,month,day);
2277 int32_t dayHC = hc.get(UCAL_DATE,status);
2278 int32_t monthHC = hc.get(UCAL_MONTH,status);
2279 int32_t yearHC = hc.get(UCAL_YEAR,status);
2280
2281 if (failure(status, "HebrewCalendar.get()", TRUE)) continue;
2282
2283 if (dayHC != day) {
2284 errln(" ==> day %d incorrect, should be: %d\n",dayHC,day);
2285 break;
2286 }
2287 if (monthHC != month) {
2288 errln(" ==> month %d incorrect, should be: %d\n",monthHC,month);
2289 break;
2290 }
2291 if (yearHC != year) {
2292 errln(" ==> day %d incorrect, should be: %d\n",yearHC,year);
2293 break;
2294 }
2295 }
2296 }
2297 return;
2298 }
2299
2300 void CalendarTest::TestTimeStamp() {
2301 UErrorCode status = U_ZERO_ERROR;
2302 UDate start = 0.0, time;
2303 Calendar *cal;
2304
2305 // Create a new Gregorian Calendar.
2306 cal = Calendar::createInstance("en_US@calender=gregorian", status);
2307 if (U_FAILURE(status)) {
2308 dataerrln("Error creating Gregorian calendar.");
2309 return;
2310 }
2311
2312 for (int i = 0; i < 20000; i++) {
2313 // Set the Gregorian Calendar to a specific date for testing.
2314 cal->set(2009, UCAL_JULY, 3, 0, 49, 46);
2315
2316 time = cal->getTime(status);
2317 if (U_FAILURE(status)) {
2318 errln("Error calling getTime()");
2319 break;
2320 }
2321
2322 if (i == 0) {
2323 start = time;
2324 } else {
2325 if (start != time) {
2326 errln("start and time not equal.");
2327 break;
2328 }
2329 }
2330 }
2331
2332 delete cal;
2333 }
2334
2335 void CalendarTest::TestISO8601() {
2336 const char* TEST_LOCALES[] = {
2337 "en_US@calendar=iso8601",
2338 "en_US@calendar=Iso8601",
2339 "th_TH@calendar=iso8601",
2340 "ar_EG@calendar=iso8601",
2341 NULL
2342 };
2343
2344 int32_t TEST_DATA[][3] = {
2345 {2008, 1, 2008},
2346 {2009, 1, 2009},
2347 {2010, 53, 2009},
2348 {2011, 52, 2010},
2349 {2012, 52, 2011},
2350 {2013, 1, 2013},
2351 {2014, 1, 2014},
2352 {0, 0, 0},
2353 };
2354
2355 for (int i = 0; TEST_LOCALES[i] != NULL; i++) {
2356 UErrorCode status = U_ZERO_ERROR;
2357 Calendar *cal = Calendar::createInstance(TEST_LOCALES[i], status);
2358 if (U_FAILURE(status)) {
2359 errln("Error: Failed to create a calendar for locale: %s", TEST_LOCALES[i]);
2360 continue;
2361 }
2362 if (uprv_strcmp(cal->getType(), "gregorian") != 0) {
2363 errln("Error: Gregorian calendar is not used for locale: %s", TEST_LOCALES[i]);
2364 continue;
2365 }
2366 for (int j = 0; TEST_DATA[j][0] != 0; j++) {
2367 cal->set(TEST_DATA[j][0], UCAL_JANUARY, 1);
2368 int32_t weekNum = cal->get(UCAL_WEEK_OF_YEAR, status);
2369 int32_t weekYear = cal->get(UCAL_YEAR_WOY, status);
2370 if (U_FAILURE(status)) {
2371 errln("Error: Failed to get week of year");
2372 break;
2373 }
2374 if (weekNum != TEST_DATA[j][1] || weekYear != TEST_DATA[j][2]) {
2375 errln("Error: Incorrect week of year on January 1st, %d for locale %s: Returned [weekNum=%d, weekYear=%d], Expected [weekNum=%d, weekYear=%d]",
2376 TEST_DATA[j][0], TEST_LOCALES[i], weekNum, weekYear, TEST_DATA[j][1], TEST_DATA[j][2]);
2377 }
2378 }
2379 delete cal;
2380 }
2381
2382 }
2383
2384 void
2385 CalendarTest::TestAmbiguousWallTimeAPIs(void) {
2386 UErrorCode status = U_ZERO_ERROR;
2387 Calendar* cal = Calendar::createInstance(status);
2388 if (U_FAILURE(status)) {
2389 errln("Fail: Error creating a calendar instance.");
2390 return;
2391 }
2392
2393 if (cal->getRepeatedWallTimeOption() != UCAL_WALLTIME_LAST) {
2394 errln("Fail: Default repeted time option is not UCAL_WALLTIME_LAST");
2395 }
2396 if (cal->getSkippedWallTimeOption() != UCAL_WALLTIME_LAST) {
2397 errln("Fail: Default skipped time option is not UCAL_WALLTIME_LAST");
2398 }
2399
2400 Calendar* cal2 = cal->clone();
2401
2402 if (*cal != *cal2) {
2403 errln("Fail: Cloned calendar != the original");
2404 }
2405 if (!cal->equals(*cal2, status)) {
2406 errln("Fail: The time of cloned calendar is not equal to the original");
2407 } else if (U_FAILURE(status)) {
2408 errln("Fail: Error equals");
2409 }
2410 status = U_ZERO_ERROR;
2411
2412 cal2->setRepeatedWallTimeOption(UCAL_WALLTIME_FIRST);
2413 cal2->setSkippedWallTimeOption(UCAL_WALLTIME_FIRST);
2414
2415 if (*cal == *cal2) {
2416 errln("Fail: Cloned and modified calendar == the original");
2417 }
2418 if (!cal->equals(*cal2, status)) {
2419 errln("Fail: The time of cloned calendar is not equal to the original after changing wall time options");
2420 } else if (U_FAILURE(status)) {
2421 errln("Fail: Error equals after changing wall time options");
2422 }
2423 status = U_ZERO_ERROR;
2424
2425 if (cal2->getRepeatedWallTimeOption() != UCAL_WALLTIME_FIRST) {
2426 errln("Fail: Repeted time option is not UCAL_WALLTIME_FIRST");
2427 }
2428 if (cal2->getSkippedWallTimeOption() != UCAL_WALLTIME_FIRST) {
2429 errln("Fail: Skipped time option is not UCAL_WALLTIME_FIRST");
2430 }
2431
2432 cal2->setRepeatedWallTimeOption(UCAL_WALLTIME_NEXT_VALID);
2433 if (cal2->getRepeatedWallTimeOption() != UCAL_WALLTIME_FIRST) {
2434 errln("Fail: Repeated wall time option was updated other than UCAL_WALLTIME_FIRST");
2435 }
2436
2437 delete cal;
2438 delete cal2;
2439 }
2440
2441 class CalFields {
2442 public:
2443 CalFields(int32_t year, int32_t month, int32_t day, int32_t hour, int32_t min, int32_t sec, int32_t ms = 0);
2444 CalFields(const Calendar& cal, UErrorCode& status);
2445 void setTo(Calendar& cal) const;
2446 char* toString(char* buf, int32_t len) const;
2447 UBool operator==(const CalFields& rhs) const;
2448 UBool operator!=(const CalFields& rhs) const;
2449 UBool isEquivalentTo(const Calendar& cal, UErrorCode& status) const;
2450
2451 private:
2452 int32_t year;
2453 int32_t month;
2454 int32_t day;
2455 int32_t hour;
2456 int32_t min;
2457 int32_t sec;
2458 int32_t ms;
2459 };
2460
2461 CalFields::CalFields(int32_t year, int32_t month, int32_t day, int32_t hour, int32_t min, int32_t sec, int32_t ms)
2462 : year(year), month(month), day(day), hour(hour), min(min), sec(sec), ms(ms) {
2463 }
2464
2465 CalFields::CalFields(const Calendar& cal, UErrorCode& status) {
2466 year = cal.get(UCAL_YEAR, status);
2467 month = cal.get(UCAL_MONTH, status) + 1;
2468 day = cal.get(UCAL_DAY_OF_MONTH, status);
2469 hour = cal.get(UCAL_HOUR_OF_DAY, status);
2470 min = cal.get(UCAL_MINUTE, status);
2471 sec = cal.get(UCAL_SECOND, status);
2472 ms = cal.get(UCAL_MILLISECOND, status);
2473 }
2474
2475 void
2476 CalFields::setTo(Calendar& cal) const {
2477 cal.clear();
2478 cal.set(year, month - 1, day, hour, min, sec);
2479 cal.set(UCAL_MILLISECOND, ms);
2480 }
2481
2482 char*
2483 CalFields::toString(char* buf, int32_t len) const {
2484 char local[32];
2485 sprintf(local, "%04d-%02d-%02d %02d:%02d:%02d.%03d", year, month, day, hour, min, sec, ms);
2486 uprv_strncpy(buf, local, len - 1);
2487 buf[len - 1] = 0;
2488 return buf;
2489 }
2490
2491 UBool
2492 CalFields::operator==(const CalFields& rhs) const {
2493 return year == rhs.year
2494 && month == rhs.month
2495 && day == rhs.day
2496 && hour == rhs.hour
2497 && min == rhs.min
2498 && sec == rhs.sec
2499 && ms == rhs.ms;
2500 }
2501
2502 UBool
2503 CalFields::operator!=(const CalFields& rhs) const {
2504 return !(*this == rhs);
2505 }
2506
2507 UBool
2508 CalFields::isEquivalentTo(const Calendar& cal, UErrorCode& status) const {
2509 return year == cal.get(UCAL_YEAR, status)
2510 && month == cal.get(UCAL_MONTH, status) + 1
2511 && day == cal.get(UCAL_DAY_OF_MONTH, status)
2512 && hour == cal.get(UCAL_HOUR_OF_DAY, status)
2513 && min == cal.get(UCAL_MINUTE, status)
2514 && sec == cal.get(UCAL_SECOND, status)
2515 && ms == cal.get(UCAL_MILLISECOND, status);
2516 }
2517
2518 typedef struct {
2519 const char* tzid;
2520 const CalFields in;
2521 const CalFields expLastGMT;
2522 const CalFields expFirstGMT;
2523 } RepeatedWallTimeTestData;
2524
2525 static const RepeatedWallTimeTestData RPDATA[] =
2526 {
2527 // Time zone Input wall time WALLTIME_LAST in GMT WALLTIME_FIRST in GMT
2528 {"America/New_York", CalFields(2011,11,6,0,59,59), CalFields(2011,11,6,4,59,59), CalFields(2011,11,6,4,59,59)},
2529 {"America/New_York", CalFields(2011,11,6,1,0,0), CalFields(2011,11,6,6,0,0), CalFields(2011,11,6,5,0,0)},
2530 {"America/New_York", CalFields(2011,11,6,1,0,1), CalFields(2011,11,6,6,0,1), CalFields(2011,11,6,5,0,1)},
2531 {"America/New_York", CalFields(2011,11,6,1,30,0), CalFields(2011,11,6,6,30,0), CalFields(2011,11,6,5,30,0)},
2532 {"America/New_York", CalFields(2011,11,6,1,59,59), CalFields(2011,11,6,6,59,59), CalFields(2011,11,6,5,59,59)},
2533 {"America/New_York", CalFields(2011,11,6,2,0,0), CalFields(2011,11,6,7,0,0), CalFields(2011,11,6,7,0,0)},
2534 {"America/New_York", CalFields(2011,11,6,2,0,1), CalFields(2011,11,6,7,0,1), CalFields(2011,11,6,7,0,1)},
2535
2536 {"Australia/Lord_Howe", CalFields(2011,4,3,1,29,59), CalFields(2011,4,2,14,29,59), CalFields(2011,4,2,14,29,59)},
2537 {"Australia/Lord_Howe", CalFields(2011,4,3,1,30,0), CalFields(2011,4,2,15,0,0), CalFields(2011,4,2,14,30,0)},
2538 {"Australia/Lord_Howe", CalFields(2011,4,3,1,45,0), CalFields(2011,4,2,15,15,0), CalFields(2011,4,2,14,45,0)},
2539 {"Australia/Lord_Howe", CalFields(2011,4,3,1,59,59), CalFields(2011,4,2,15,29,59), CalFields(2011,4,2,14,59,59)},
2540 {"Australia/Lord_Howe", CalFields(2011,4,3,2,0,0), CalFields(2011,4,2,15,30,0), CalFields(2011,4,2,15,30,0)},
2541 {"Australia/Lord_Howe", CalFields(2011,4,3,2,0,1), CalFields(2011,4,2,15,30,1), CalFields(2011,4,2,15,30,1)},
2542
2543 {NULL, CalFields(0,0,0,0,0,0), CalFields(0,0,0,0,0,0), CalFields(0,0,0,0,0,0)}
2544 };
2545
2546 void CalendarTest::TestRepeatedWallTime(void) {
2547 UErrorCode status = U_ZERO_ERROR;
2548 GregorianCalendar calGMT((const TimeZone&)*TimeZone::getGMT(), status);
2549 GregorianCalendar calDefault(status);
2550 GregorianCalendar calLast(status);
2551 GregorianCalendar calFirst(status);
2552
2553 if (U_FAILURE(status)) {
2554 errln("Fail: Failed to create a calendar object.");
2555 return;
2556 }
2557
2558 calLast.setRepeatedWallTimeOption(UCAL_WALLTIME_LAST);
2559 calFirst.setRepeatedWallTimeOption(UCAL_WALLTIME_FIRST);
2560
2561 for (int32_t i = 0; RPDATA[i].tzid != NULL; i++) {
2562 char buf[32];
2563 TimeZone *tz = TimeZone::createTimeZone(RPDATA[i].tzid);
2564
2565 // UCAL_WALLTIME_LAST
2566 status = U_ZERO_ERROR;
2567 calLast.setTimeZone(*tz);
2568 RPDATA[i].in.setTo(calLast);
2569 calGMT.setTime(calLast.getTime(status), status);
2570 CalFields outLastGMT(calGMT, status);
2571 if (U_FAILURE(status)) {
2572 errln(UnicodeString("Fail: Failed to get/set time calLast/calGMT (UCAL_WALLTIME_LAST) - ")
2573 + RPDATA[i].in.toString(buf, sizeof(buf)) + "[" + RPDATA[i].tzid + "]");
2574 } else {
2575 if (outLastGMT != RPDATA[i].expLastGMT) {
2576 dataerrln(UnicodeString("Fail: UCAL_WALLTIME_LAST ") + RPDATA[i].in.toString(buf, sizeof(buf)) + "[" + RPDATA[i].tzid + "] is parsed as "
2577 + outLastGMT.toString(buf, sizeof(buf)) + "[GMT]. Expected: " + RPDATA[i].expLastGMT.toString(buf, sizeof(buf)) + "[GMT]");
2578 }
2579 }
2580
2581 // default
2582 status = U_ZERO_ERROR;
2583 calDefault.setTimeZone(*tz);
2584 RPDATA[i].in.setTo(calDefault);
2585 calGMT.setTime(calDefault.getTime(status), status);
2586 CalFields outDefGMT(calGMT, status);
2587 if (U_FAILURE(status)) {
2588 errln(UnicodeString("Fail: Failed to get/set time calLast/calGMT (default) - ")
2589 + RPDATA[i].in.toString(buf, sizeof(buf)) + "[" + RPDATA[i].tzid + "]");
2590 } else {
2591 if (outDefGMT != RPDATA[i].expLastGMT) {
2592 dataerrln(UnicodeString("Fail: (default) ") + RPDATA[i].in.toString(buf, sizeof(buf)) + "[" + RPDATA[i].tzid + "] is parsed as "
2593 + outDefGMT.toString(buf, sizeof(buf)) + "[GMT]. Expected: " + RPDATA[i].expLastGMT.toString(buf, sizeof(buf)) + "[GMT]");
2594 }
2595 }
2596
2597 // UCAL_WALLTIME_FIRST
2598 status = U_ZERO_ERROR;
2599 calFirst.setTimeZone(*tz);
2600 RPDATA[i].in.setTo(calFirst);
2601 calGMT.setTime(calFirst.getTime(status), status);
2602 CalFields outFirstGMT(calGMT, status);
2603 if (U_FAILURE(status)) {
2604 errln(UnicodeString("Fail: Failed to get/set time calLast/calGMT (UCAL_WALLTIME_FIRST) - ")
2605 + RPDATA[i].in.toString(buf, sizeof(buf)) + "[" + RPDATA[i].tzid + "]");
2606 } else {
2607 if (outFirstGMT != RPDATA[i].expFirstGMT) {
2608 dataerrln(UnicodeString("Fail: UCAL_WALLTIME_FIRST ") + RPDATA[i].in.toString(buf, sizeof(buf)) + "[" + RPDATA[i].tzid + "] is parsed as "
2609 + outFirstGMT.toString(buf, sizeof(buf)) + "[GMT]. Expected: " + RPDATA[i].expFirstGMT.toString(buf, sizeof(buf)) + "[GMT]");
2610 }
2611 }
2612 delete tz;
2613 }
2614 }
2615
2616 typedef struct {
2617 const char* tzid;
2618 const CalFields in;
2619 UBool isValid;
2620 const CalFields expLastGMT;
2621 const CalFields expFirstGMT;
2622 const CalFields expNextAvailGMT;
2623 } SkippedWallTimeTestData;
2624
2625 static SkippedWallTimeTestData SKDATA[] =
2626 {
2627 // Time zone Input wall time valid? WALLTIME_LAST in GMT WALLTIME_FIRST in GMT WALLTIME_NEXT_VALID in GMT
2628 {"America/New_York", CalFields(2011,3,13,1,59,59), TRUE, CalFields(2011,3,13,6,59,59), CalFields(2011,3,13,6,59,59), CalFields(2011,3,13,6,59,59)},
2629 {"America/New_York", CalFields(2011,3,13,2,0,0), FALSE, CalFields(2011,3,13,7,0,0), CalFields(2011,3,13,6,0,0), CalFields(2011,3,13,7,0,0)},
2630 {"America/New_York", CalFields(2011,3,13,2,1,0), FALSE, CalFields(2011,3,13,7,1,0), CalFields(2011,3,13,6,1,0), CalFields(2011,3,13,7,0,0)},
2631 {"America/New_York", CalFields(2011,3,13,2,30,0), FALSE, CalFields(2011,3,13,7,30,0), CalFields(2011,3,13,6,30,0), CalFields(2011,3,13,7,0,0)},
2632 {"America/New_York", CalFields(2011,3,13,2,59,59), FALSE, CalFields(2011,3,13,7,59,59), CalFields(2011,3,13,6,59,59), CalFields(2011,3,13,7,0,0)},
2633 {"America/New_York", CalFields(2011,3,13,3,0,0), TRUE, CalFields(2011,3,13,7,0,0), CalFields(2011,3,13,7,0,0), CalFields(2011,3,13,7,0,0)},
2634
2635 {"Pacific/Apia", CalFields(2011,12,29,23,59,59), TRUE, CalFields(2011,12,30,9,59,59), CalFields(2011,12,30,9,59,59), CalFields(2011,12,30,9,59,59)},
2636 {"Pacific/Apia", CalFields(2011,12,30,0,0,0), FALSE, CalFields(2011,12,30,10,0,0), CalFields(2011,12,29,10,0,0), CalFields(2011,12,30,10,0,0)},
2637 {"Pacific/Apia", CalFields(2011,12,30,12,0,0), FALSE, CalFields(2011,12,30,22,0,0), CalFields(2011,12,29,22,0,0), CalFields(2011,12,30,10,0,0)},
2638 {"Pacific/Apia", CalFields(2011,12,30,23,59,59), FALSE, CalFields(2011,12,31,9,59,59), CalFields(2011,12,30,9,59,59), CalFields(2011,12,30,10,0,0)},
2639 {"Pacific/Apia", CalFields(2011,12,31,0,0,0), TRUE, CalFields(2011,12,30,10,0,0), CalFields(2011,12,30,10,0,0), CalFields(2011,12,30,10,0,0)},
2640
2641 {NULL, CalFields(0,0,0,0,0,0), TRUE, CalFields(0,0,0,0,0,0), CalFields(0,0,0,0,0,0), CalFields(0,0,0,0,0,0)}
2642 };
2643
2644
2645 void CalendarTest::TestSkippedWallTime(void) {
2646 UErrorCode status = U_ZERO_ERROR;
2647 GregorianCalendar calGMT((const TimeZone&)*TimeZone::getGMT(), status);
2648 GregorianCalendar calDefault(status);
2649 GregorianCalendar calLast(status);
2650 GregorianCalendar calFirst(status);
2651 GregorianCalendar calNextAvail(status);
2652
2653 if (U_FAILURE(status)) {
2654 errln("Fail: Failed to create a calendar object.");
2655 return;
2656 }
2657
2658 calLast.setSkippedWallTimeOption(UCAL_WALLTIME_LAST);
2659 calFirst.setSkippedWallTimeOption(UCAL_WALLTIME_FIRST);
2660 calNextAvail.setSkippedWallTimeOption(UCAL_WALLTIME_NEXT_VALID);
2661
2662 for (int32_t i = 0; SKDATA[i].tzid != NULL; i++) {
2663 UDate d;
2664 char buf[32];
2665 TimeZone *tz = TimeZone::createTimeZone(SKDATA[i].tzid);
2666
2667 for (int32_t j = 0; j < 2; j++) {
2668 UBool bLenient = (j == 0);
2669
2670 // UCAL_WALLTIME_LAST
2671 status = U_ZERO_ERROR;
2672 calLast.setLenient(bLenient);
2673 calLast.setTimeZone(*tz);
2674 SKDATA[i].in.setTo(calLast);
2675 d = calLast.getTime(status);
2676 if (bLenient || SKDATA[i].isValid) {
2677 calGMT.setTime(d, status);
2678 CalFields outLastGMT(calGMT, status);
2679 if (U_FAILURE(status)) {
2680 errln(UnicodeString("Fail: Failed to get/set time calLast/calGMT (UCAL_WALLTIME_LAST) - ")
2681 + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "]");
2682 } else {
2683 if (outLastGMT != SKDATA[i].expLastGMT) {
2684 dataerrln(UnicodeString("Fail: UCAL_WALLTIME_LAST ") + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "] is parsed as "
2685 + outLastGMT.toString(buf, sizeof(buf)) + "[GMT]. Expected: " + SKDATA[i].expLastGMT.toString(buf, sizeof(buf)) + "[GMT]");
2686 }
2687 }
2688 } else if (U_SUCCESS(status)) {
2689 // strict, invalid wall time - must report an error
2690 dataerrln(UnicodeString("Fail: An error expected (UCAL_WALLTIME_LAST)") +
2691 + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "]");
2692 }
2693
2694 // default
2695 status = U_ZERO_ERROR;
2696 calDefault.setLenient(bLenient);
2697 calDefault.setTimeZone(*tz);
2698 SKDATA[i].in.setTo(calDefault);
2699 d = calDefault.getTime(status);
2700 if (bLenient || SKDATA[i].isValid) {
2701 calGMT.setTime(d, status);
2702 CalFields outDefGMT(calGMT, status);
2703 if (U_FAILURE(status)) {
2704 errln(UnicodeString("Fail: Failed to get/set time calDefault/calGMT (default) - ")
2705 + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "]");
2706 } else {
2707 if (outDefGMT != SKDATA[i].expLastGMT) {
2708 dataerrln(UnicodeString("Fail: (default) ") + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "] is parsed as "
2709 + outDefGMT.toString(buf, sizeof(buf)) + "[GMT]. Expected: " + SKDATA[i].expLastGMT.toString(buf, sizeof(buf)) + "[GMT]");
2710 }
2711 }
2712 } else if (U_SUCCESS(status)) {
2713 // strict, invalid wall time - must report an error
2714 dataerrln(UnicodeString("Fail: An error expected (default)") +
2715 + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "]");
2716 }
2717
2718 // UCAL_WALLTIME_FIRST
2719 status = U_ZERO_ERROR;
2720 calFirst.setLenient(bLenient);
2721 calFirst.setTimeZone(*tz);
2722 SKDATA[i].in.setTo(calFirst);
2723 d = calFirst.getTime(status);
2724 if (bLenient || SKDATA[i].isValid) {
2725 calGMT.setTime(d, status);
2726 CalFields outFirstGMT(calGMT, status);
2727 if (U_FAILURE(status)) {
2728 errln(UnicodeString("Fail: Failed to get/set time calFirst/calGMT (UCAL_WALLTIME_FIRST) - ")
2729 + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "]");
2730 } else {
2731 if (outFirstGMT != SKDATA[i].expFirstGMT) {
2732 dataerrln(UnicodeString("Fail: UCAL_WALLTIME_FIRST ") + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "] is parsed as "
2733 + outFirstGMT.toString(buf, sizeof(buf)) + "[GMT]. Expected: " + SKDATA[i].expFirstGMT.toString(buf, sizeof(buf)) + "[GMT]");
2734 }
2735 }
2736 } else if (U_SUCCESS(status)) {
2737 // strict, invalid wall time - must report an error
2738 dataerrln(UnicodeString("Fail: An error expected (UCAL_WALLTIME_FIRST)") +
2739 + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "]");
2740 }
2741
2742 // UCAL_WALLTIME_NEXT_VALID
2743 status = U_ZERO_ERROR;
2744 calNextAvail.setLenient(bLenient);
2745 calNextAvail.setTimeZone(*tz);
2746 SKDATA[i].in.setTo(calNextAvail);
2747 d = calNextAvail.getTime(status);
2748 if (bLenient || SKDATA[i].isValid) {
2749 calGMT.setTime(d, status);
2750 CalFields outNextAvailGMT(calGMT, status);
2751 if (U_FAILURE(status)) {
2752 errln(UnicodeString("Fail: Failed to get/set time calNextAvail/calGMT (UCAL_WALLTIME_NEXT_VALID) - ")
2753 + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "]");
2754 } else {
2755 if (outNextAvailGMT != SKDATA[i].expNextAvailGMT) {
2756 dataerrln(UnicodeString("Fail: UCAL_WALLTIME_NEXT_VALID ") + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "] is parsed as "
2757 + outNextAvailGMT.toString(buf, sizeof(buf)) + "[GMT]. Expected: " + SKDATA[i].expNextAvailGMT.toString(buf, sizeof(buf)) + "[GMT]");
2758 }
2759 }
2760 } else if (U_SUCCESS(status)) {
2761 // strict, invalid wall time - must report an error
2762 dataerrln(UnicodeString("Fail: An error expected (UCAL_WALLTIME_NEXT_VALID)") +
2763 + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "]");
2764 }
2765 }
2766
2767 delete tz;
2768 }
2769 }
2770
2771 void CalendarTest::TestCloneLocale(void) {
2772 UErrorCode status = U_ZERO_ERROR;
2773 LocalPointer<Calendar> cal(Calendar::createInstance(TimeZone::getGMT()->clone(),
2774 Locale::createFromName("en"), status));
2775 TEST_CHECK_STATUS;
2776 Locale l0 = cal->getLocale(ULOC_VALID_LOCALE, status);
2777 TEST_CHECK_STATUS;
2778 LocalPointer<Calendar> cal2(cal->clone());
2779 Locale l = cal2->getLocale(ULOC_VALID_LOCALE, status);
2780 if(l0!=l) {
2781 errln("Error: cloned locale %s != original locale %s, status %s\n", l0.getName(), l.getName(), u_errorName(status));
2782 }
2783 TEST_CHECK_STATUS;
2784 }
2785
2786 void CalendarTest::setAndTestCalendar(Calendar* cal, int32_t initMonth, int32_t initDay, int32_t initYear, UErrorCode& status) {
2787 cal->clear();
2788 cal->setLenient(FALSE);
2789 cal->set(initYear, initMonth, initDay);
2790 int32_t day = cal->get(UCAL_DAY_OF_MONTH, status);
2791 int32_t month = cal->get(UCAL_MONTH, status);
2792 int32_t year = cal->get(UCAL_YEAR, status);
2793 if(U_FAILURE(status))
2794 return;
2795
2796 if(initDay != day || initMonth != month || initYear != year)
2797 {
2798 errln(" year init values:\tmonth %i\tday %i\tyear %i", initMonth, initDay, initYear);
2799 errln("values post set():\tmonth %i\tday %i\tyear %i",month, day, year);
2800 }
2801 }
2802
2803 void CalendarTest::setAndTestWholeYear(Calendar* cal, int32_t startYear, UErrorCode& status) {
2804 for(int32_t startMonth = 0; startMonth < 12; startMonth++) {
2805 for(int32_t startDay = 1; startDay < 31; startDay++ ) {
2806 setAndTestCalendar(cal, startMonth, startDay, startYear, status);
2807 if(U_FAILURE(status) && startDay == 30) {
2808 status = U_ZERO_ERROR;
2809 continue;
2810 }
2811 TEST_CHECK_STATUS;
2812 }
2813 }
2814 }
2815
2816 // =====================================================================
2817
2818 typedef struct {
2819 int16_t gYear;
2820 int8_t gMon;
2821 int8_t gDay;
2822 int16_t uYear;
2823 int8_t uMon;
2824 int8_t uDay;
2825 } GregoUmmAlQuraMap;
2826
2827 // data from
2828 // Official Umm-al-Qura calendar of SA:
2829 // home, http://www.ummulqura.org.sa/default.aspx
2830 // converter, http://www.ummulqura.org.sa/Index.aspx
2831 static const GregoUmmAlQuraMap guMappings[] = {
2832 // gregorian, ummAlQura
2833 // year mo da, year mo da
2834 // (using 1-based months here)
2835 { 1882,11,12, 1300, 1, 1 },
2836 { 1892, 7,25, 1310, 1, 1 },
2837 { 1896, 6,12, 1314, 1, 1 },
2838 { 1898, 5,22, 1316, 1, 1 },
2839 { 1900, 4,30, 1318, 1, 1 },
2840 { 1901, 4,20, 1319, 1, 1 },
2841 { 1902, 4,10, 1320, 1, 1 },
2842 { 1903, 3,30, 1321, 1, 1 },
2843 { 1904, 3,19, 1322, 1, 1 },
2844 { 1905, 3, 8, 1323, 1, 1 },
2845 { 1906, 2,25, 1324, 1, 1 },
2846 { 1907, 2,14, 1325, 1, 1 },
2847 { 1908, 2, 4, 1326, 1, 1 },
2848 { 1909, 1,23, 1327, 1, 1 },
2849 { 1910, 1,13, 1328, 1, 1 },
2850 { 1911, 1, 2, 1329, 1, 1 },
2851 { 1911,12,22, 1330, 1, 1 },
2852 { 1912,12,10, 1331, 1, 1 },
2853 { 1913,11,30, 1332, 1, 1 },
2854 { 1914,11,19, 1333, 1, 1 },
2855 { 1915,11, 9, 1334, 1, 1 },
2856 { 1916,10,28, 1335, 1, 1 },
2857 { 1917,10,18, 1336, 1, 1 },
2858 { 1918,10, 7, 1337, 1, 1 },
2859 { 1919, 9,26, 1338, 1, 1 },
2860 { 1920, 9,14, 1339, 1, 1 },
2861 { 1921, 9, 4, 1340, 1, 1 },
2862 { 1922, 8,24, 1341, 1, 1 },
2863 { 1923, 8,14, 1342, 1, 1 },
2864 { 1924, 8, 2, 1343, 1, 1 },
2865 { 1925, 7,22, 1344, 1, 1 },
2866 { 1926, 7,11, 1345, 1, 1 },
2867 { 1927, 6,30, 1346, 1, 1 },
2868 { 1928, 6,19, 1347, 1, 1 },
2869 { 1929, 6, 9, 1348, 1, 1 },
2870 { 1930, 5,29, 1349, 1, 1 },
2871 { 1931, 5,19, 1350, 1, 1 },
2872 { 1932, 5, 7, 1351, 1, 1 },
2873 { 1933, 4,26, 1352, 1, 1 },
2874 { 1934, 4,15, 1353, 1, 1 },
2875 { 1935, 4, 5, 1354, 1, 1 },
2876 { 1936, 3,24, 1355, 1, 1 },
2877 { 1937, 3,14, 1356, 1, 1 },
2878 { 1938, 3, 4, 1357, 1, 1 },
2879 { 1939, 2,21, 1358, 1, 1 },
2880 { 1940, 2,10, 1359, 1, 1 },
2881 { 1941, 1,29, 1360, 1, 1 },
2882 { 1942, 1,18, 1361, 1, 1 },
2883 { 1943, 1, 8, 1362, 1, 1 },
2884 { 1943,12,28, 1363, 1, 1 },
2885 { 1944,12,17, 1364, 1, 1 },
2886 { 1945,12, 6, 1365, 1, 1 },
2887 { 1946,11,25, 1366, 1, 1 },
2888 { 1947,11,14, 1367, 1, 1 },
2889 { 1948,11, 3, 1368, 1, 1 },
2890 { 1949,10,23, 1369, 1, 1 },
2891 { 1950,10,13, 1370, 1, 1 },
2892 { 1951,10, 3, 1371, 1, 1 },
2893 { 1952, 9,21, 1372, 1, 1 },
2894 { 1953, 9,10, 1373, 1, 1 },
2895 { 1954, 8,30, 1374, 1, 1 },
2896 { 1955, 8,19, 1375, 1, 1 },
2897 { 1956, 8, 8, 1376, 1, 1 },
2898 { 1957, 7,29, 1377, 1, 1 },
2899 { 1958, 7,18, 1378, 1, 1 },
2900 { 1959, 7, 8, 1379, 1, 1 },
2901 { 1960, 6,26, 1380, 1, 1 },
2902 { 1961, 6,15, 1381, 1, 1 },
2903 { 1962, 6, 4, 1382, 1, 1 },
2904 { 1963, 5,24, 1383, 1, 1 },
2905 { 1964, 5,13, 1384, 1, 1 },
2906 { 1965, 5, 3, 1385, 1, 1 },
2907 { 1966, 4,22, 1386, 1, 1 },
2908 { 1967, 4,11, 1387, 1, 1 },
2909 { 1968, 3,30, 1388, 1, 1 },
2910 { 1969, 3,19, 1389, 1, 1 },
2911 { 1970, 3, 9, 1390, 1, 1 },
2912 { 1971, 2,27, 1391, 1, 1 },
2913 { 1972, 2,16, 1392, 1, 1 },
2914 { 1973, 2, 5, 1393, 1, 1 },
2915 { 1974, 1,25, 1394, 1, 1 },
2916 { 1975, 1,14, 1395, 1, 1 },
2917 { 1976, 1, 3, 1396, 1, 1 },
2918 { 1976,12,22, 1397, 1, 1 },
2919 { 1977,12,12, 1398, 1, 1 },
2920 { 1978,12, 1, 1399, 1, 1 },
2921 { 1979,11,21, 1400, 1, 1 },
2922 { 1980,11, 9, 1401, 1, 1 },
2923 { 1981,10,29, 1402, 1, 1 },
2924 { 1982,10,18, 1403, 1, 1 },
2925 { 1983,10, 8, 1404, 1, 1 },
2926 { 1984, 9,26, 1405, 1, 1 },
2927 { 1985, 9,16, 1406, 1, 1 },
2928 { 1986, 9, 6, 1407, 1, 1 },
2929 { 1987, 8,26, 1408, 1, 1 },
2930 { 1988, 8,14, 1409, 1, 1 },
2931 { 1989, 8, 3, 1410, 1, 1 },
2932 { 1990, 7,23, 1411, 1, 1 },
2933 { 1991, 7,13, 1412, 1, 1 },
2934 { 1992, 7, 2, 1413, 1, 1 },
2935 { 1993, 6,21, 1414, 1, 1 },
2936 { 1994, 6,11, 1415, 1, 1 },
2937 { 1995, 5,31, 1416, 1, 1 },
2938 { 1996, 5,19, 1417, 1, 1 },
2939 { 1997, 5, 8, 1418, 1, 1 },
2940 { 1998, 4,28, 1419, 1, 1 },
2941 { 1999, 4,17, 1420, 1, 1 },
2942 { 1999, 5,16, 1420, 2, 1 },
2943 { 1999, 6,15, 1420, 3, 1 },
2944 { 1999, 7,14, 1420, 4, 1 },
2945 { 1999, 8,12, 1420, 5, 1 },
2946 { 1999, 9,11, 1420, 6, 1 },
2947 { 1999,10,10, 1420, 7, 1 },
2948 { 1999,11, 9, 1420, 8, 1 },
2949 { 1999,12, 9, 1420, 9, 1 },
2950 { 2000, 1, 8, 1420,10, 1 },
2951 { 2000, 2, 7, 1420,11, 1 },
2952 { 2000, 3, 7, 1420,12, 1 },
2953 { 2000, 4, 6, 1421, 1, 1 },
2954 { 2000, 5, 5, 1421, 2, 1 },
2955 { 2000, 6, 3, 1421, 3, 1 },
2956 { 2000, 7, 3, 1421, 4, 1 },
2957 { 2000, 8, 1, 1421, 5, 1 },
2958 { 2000, 8,30, 1421, 6, 1 },
2959 { 2000, 9,28, 1421, 7, 1 },
2960 { 2000,10,28, 1421, 8, 1 },
2961 { 2000,11,27, 1421, 9, 1 },
2962 { 2000,12,27, 1421,10, 1 },
2963 { 2001, 1,26, 1421,11, 1 },
2964 { 2001, 2,24, 1421,12, 1 },
2965 { 2001, 3,26, 1422, 1, 1 },
2966 { 2001, 4,25, 1422, 2, 1 },
2967 { 2001, 5,24, 1422, 3, 1 },
2968 { 2001, 6,22, 1422, 4, 1 },
2969 { 2001, 7,22, 1422, 5, 1 },
2970 { 2001, 8,20, 1422, 6, 1 },
2971 { 2001, 9,18, 1422, 7, 1 },
2972 { 2001,10,17, 1422, 8, 1 },
2973 { 2001,11,16, 1422, 9, 1 },
2974 { 2001,12,16, 1422,10, 1 },
2975 { 2002, 1,15, 1422,11, 1 },
2976 { 2002, 2,13, 1422,12, 1 },
2977 { 2002, 3,15, 1423, 1, 1 },
2978 { 2002, 4,14, 1423, 2, 1 },
2979 { 2002, 5,13, 1423, 3, 1 },
2980 { 2002, 6,12, 1423, 4, 1 },
2981 { 2002, 7,11, 1423, 5, 1 },
2982 { 2002, 8,10, 1423, 6, 1 },
2983 { 2002, 9, 8, 1423, 7, 1 },
2984 { 2002,10, 7, 1423, 8, 1 },
2985 { 2002,11, 6, 1423, 9, 1 },
2986 { 2002,12, 5, 1423,10, 1 },
2987 { 2003, 1, 4, 1423,11, 1 },
2988 { 2003, 2, 2, 1423,12, 1 },
2989 { 2003, 3, 4, 1424, 1, 1 },
2990 { 2003, 4, 3, 1424, 2, 1 },
2991 { 2003, 5, 2, 1424, 3, 1 },
2992 { 2003, 6, 1, 1424, 4, 1 },
2993 { 2003, 7, 1, 1424, 5, 1 },
2994 { 2003, 7,30, 1424, 6, 1 },
2995 { 2003, 8,29, 1424, 7, 1 },
2996 { 2003, 9,27, 1424, 8, 1 },
2997 { 2003,10,26, 1424, 9, 1 },
2998 { 2003,11,25, 1424,10, 1 },
2999 { 2003,12,24, 1424,11, 1 },
3000 { 2004, 1,23, 1424,12, 1 },
3001 { 2004, 2,21, 1425, 1, 1 },
3002 { 2004, 3,22, 1425, 2, 1 },
3003 { 2004, 4,20, 1425, 3, 1 },
3004 { 2004, 5,20, 1425, 4, 1 },
3005 { 2004, 6,19, 1425, 5, 1 },
3006 { 2004, 7,18, 1425, 6, 1 },
3007 { 2004, 8,17, 1425, 7, 1 },
3008 { 2004, 9,15, 1425, 8, 1 },
3009 { 2004,10,15, 1425, 9, 1 },
3010 { 2004,11,14, 1425,10, 1 },
3011 { 2004,12,13, 1425,11, 1 },
3012 { 2005, 1,12, 1425,12, 1 },
3013 { 2005, 2,10, 1426, 1, 1 },
3014 { 2005, 3,11, 1426, 2, 1 },
3015 { 2005, 4,10, 1426, 3, 1 },
3016 { 2005, 5, 9, 1426, 4, 1 },
3017 { 2005, 6, 8, 1426, 5, 1 },
3018 { 2005, 7, 7, 1426, 6, 1 },
3019 { 2005, 8, 6, 1426, 7, 1 },
3020 { 2005, 9, 5, 1426, 8, 1 },
3021 { 2005,10, 4, 1426, 9, 1 },
3022 { 2005,11, 3, 1426,10, 1 },
3023 { 2005,12, 3, 1426,11, 1 },
3024 { 2006, 1, 1, 1426,12, 1 },
3025 { 2006, 1,31, 1427, 1, 1 },
3026 { 2006, 3, 1, 1427, 2, 1 },
3027 { 2006, 3,30, 1427, 3, 1 },
3028 { 2006, 4,29, 1427, 4, 1 },
3029 { 2006, 5,28, 1427, 5, 1 },
3030 { 2006, 6,27, 1427, 6, 1 },
3031 { 2006, 7,26, 1427, 7, 1 },
3032 { 2006, 8,25, 1427, 8, 1 },
3033 { 2006, 9,24, 1427, 9, 1 },
3034 { 2006,10,23, 1427,10, 1 },
3035 { 2006,11,22, 1427,11, 1 },
3036 { 2006,12,22, 1427,12, 1 },
3037 { 2007, 1,20, 1428, 1, 1 },
3038 { 2007, 2,19, 1428, 2, 1 },
3039 { 2007, 3,20, 1428, 3, 1 },
3040 { 2007, 4,18, 1428, 4, 1 },
3041 { 2007, 5,18, 1428, 5, 1 },
3042 { 2007, 6,16, 1428, 6, 1 },
3043 { 2007, 7,15, 1428, 7, 1 },
3044 { 2007, 8,14, 1428, 8, 1 },
3045 { 2007, 9,13, 1428, 9, 1 },
3046 { 2007,10,13, 1428,10, 1 },
3047 { 2007,11,11, 1428,11, 1 },
3048 { 2007,12,11, 1428,12, 1 },
3049 { 2008, 1,10, 1429, 1, 1 },
3050 { 2008, 2, 8, 1429, 2, 1 },
3051 { 2008, 3, 9, 1429, 3, 1 },
3052 { 2008, 4, 7, 1429, 4, 1 },
3053 { 2008, 5, 6, 1429, 5, 1 },
3054 { 2008, 6, 5, 1429, 6, 1 },
3055 { 2008, 7, 4, 1429, 7, 1 },
3056 { 2008, 8, 2, 1429, 8, 1 },
3057 { 2008, 9, 1, 1429, 9, 1 },
3058 { 2008,10, 1, 1429,10, 1 },
3059 { 2008,10,30, 1429,11, 1 },
3060 { 2008,11,29, 1429,12, 1 },
3061 { 2008,12,29, 1430, 1, 1 },
3062 { 2009, 1,27, 1430, 2, 1 },
3063 { 2009, 2,26, 1430, 3, 1 },
3064 { 2009, 3,28, 1430, 4, 1 },
3065 { 2009, 4,26, 1430, 5, 1 },
3066 { 2009, 5,25, 1430, 6, 1 },
3067 { 2009, 6,24, 1430, 7, 1 },
3068 { 2009, 7,23, 1430, 8, 1 },
3069 { 2009, 8,22, 1430, 9, 1 },
3070 { 2009, 9,20, 1430,10, 1 },
3071 { 2009,10,20, 1430,11, 1 },
3072 { 2009,11,18, 1430,12, 1 },
3073 { 2009,12,18, 1431, 1, 1 },
3074 { 2010, 1,16, 1431, 2, 1 },
3075 { 2010, 2,15, 1431, 3, 1 },
3076 { 2010, 3,17, 1431, 4, 1 },
3077 { 2010, 4,15, 1431, 5, 1 },
3078 { 2010, 5,15, 1431, 6, 1 },
3079 { 2010, 6,13, 1431, 7, 1 },
3080 { 2010, 7,13, 1431, 8, 1 },
3081 { 2010, 8,11, 1431, 9, 1 },
3082 { 2010, 9,10, 1431,10, 1 },
3083 { 2010,10, 9, 1431,11, 1 },
3084 { 2010,11, 7, 1431,12, 1 },
3085 { 2010,12, 7, 1432, 1, 1 },
3086 { 2011, 1, 5, 1432, 2, 1 },
3087 { 2011, 2, 4, 1432, 3, 1 },
3088 { 2011, 3, 6, 1432, 4, 1 },
3089 { 2011, 4, 5, 1432, 5, 1 },
3090 { 2011, 5, 4, 1432, 6, 1 },
3091 { 2011, 6, 3, 1432, 7, 1 },
3092 { 2011, 7, 2, 1432, 8, 1 },
3093 { 2011, 8, 1, 1432, 9, 1 },
3094 { 2011, 8,30, 1432,10, 1 },
3095 { 2011, 9,29, 1432,11, 1 },
3096 { 2011,10,28, 1432,12, 1 },
3097 { 2011,11,26, 1433, 1, 1 },
3098 { 2011,12,26, 1433, 2, 1 },
3099 { 2012, 1,24, 1433, 3, 1 },
3100 { 2012, 2,23, 1433, 4, 1 },
3101 { 2012, 3,24, 1433, 5, 1 },
3102 { 2012, 4,22, 1433, 6, 1 },
3103 { 2012, 5,22, 1433, 7, 1 },
3104 { 2012, 6,21, 1433, 8, 1 },
3105 { 2012, 7,20, 1433, 9, 1 },
3106 { 2012, 8,19, 1433,10, 1 },
3107 { 2012, 9,17, 1433,11, 1 },
3108 { 2012,10,17, 1433,12, 1 },
3109 { 2012,11,15, 1434, 1, 1 },
3110 { 2012,12,14, 1434, 2, 1 },
3111 { 2013, 1,13, 1434, 3, 1 },
3112 { 2013, 2,11, 1434, 4, 1 },
3113 { 2013, 3,13, 1434, 5, 1 },
3114 { 2013, 4,11, 1434, 6, 1 },
3115 { 2013, 5,11, 1434, 7, 1 },
3116 { 2013, 6,10, 1434, 8, 1 },
3117 { 2013, 7, 9, 1434, 9, 1 },
3118 { 2013, 8, 8, 1434,10, 1 },
3119 { 2013, 9, 7, 1434,11, 1 },
3120 { 2013,10, 6, 1434,12, 1 },
3121 { 2013,11, 4, 1435, 1, 1 },
3122 { 2013,12, 4, 1435, 2, 1 },
3123 { 2014, 1, 2, 1435, 3, 1 },
3124 { 2014, 2, 1, 1435, 4, 1 },
3125 { 2014, 3, 2, 1435, 5, 1 },
3126 { 2014, 4, 1, 1435, 6, 1 },
3127 { 2014, 4,30, 1435, 7, 1 },
3128 { 2014, 5,30, 1435, 8, 1 },
3129 { 2014, 6,28, 1435, 9, 1 },
3130 { 2014, 7,28, 1435,10, 1 },
3131 { 2014, 8,27, 1435,11, 1 },
3132 { 2014, 9,25, 1435,12, 1 },
3133 { 2014,10,25, 1436, 1, 1 },
3134 { 2014,11,23, 1436, 2, 1 },
3135 { 2014,12,23, 1436, 3, 1 },
3136 { 2015, 1,21, 1436, 4, 1 },
3137 { 2015, 2,20, 1436, 5, 1 },
3138 { 2015, 3,21, 1436, 6, 1 },
3139 { 2015, 4,20, 1436, 7, 1 },
3140 { 2015, 5,19, 1436, 8, 1 },
3141 { 2015, 6,18, 1436, 9, 1 },
3142 { 2015, 7,17, 1436,10, 1 },
3143 { 2015, 8,16, 1436,11, 1 },
3144 { 2015, 9,14, 1436,12, 1 },
3145 { 2015,10,14, 1437, 1, 1 },
3146 { 2015,11,13, 1437, 2, 1 },
3147 { 2015,12,12, 1437, 3, 1 },
3148 { 2016, 1,11, 1437, 4, 1 },
3149 { 2016, 2,10, 1437, 5, 1 },
3150 { 2016, 3,10, 1437, 6, 1 },
3151 { 2016, 4, 8, 1437, 7, 1 },
3152 { 2016, 5, 8, 1437, 8, 1 },
3153 { 2016, 6, 6, 1437, 9, 1 },
3154 { 2016, 7, 6, 1437,10, 1 },
3155 { 2016, 8, 4, 1437,11, 1 },
3156 { 2016, 9, 2, 1437,12, 1 },
3157 { 2016,10, 2, 1438, 1, 1 },
3158 { 2016,11, 1, 1438, 2, 1 },
3159 { 2016,11,30, 1438, 3, 1 },
3160 { 2016,12,30, 1438, 4, 1 },
3161 { 2017, 1,29, 1438, 5, 1 },
3162 { 2017, 2,28, 1438, 6, 1 },
3163 { 2017, 3,29, 1438, 7, 1 },
3164 { 2017, 4,27, 1438, 8, 1 },
3165 { 2017, 5,27, 1438, 9, 1 },
3166 { 2017, 6,25, 1438,10, 1 },
3167 { 2017, 7,24, 1438,11, 1 },
3168 { 2017, 8,23, 1438,12, 1 },
3169 { 2017, 9,21, 1439, 1, 1 },
3170 { 2017,10,21, 1439, 2, 1 },
3171 { 2017,11,19, 1439, 3, 1 },
3172 { 2017,12,19, 1439, 4, 1 },
3173 { 2018, 1,18, 1439, 5, 1 },
3174 { 2018, 2,17, 1439, 6, 1 },
3175 { 2018, 3,18, 1439, 7, 1 },
3176 { 2018, 4,17, 1439, 8, 1 },
3177 { 2018, 5,16, 1439, 9, 1 },
3178 { 2018, 6,15, 1439,10, 1 },
3179 { 2018, 7,14, 1439,11, 1 },
3180 { 2018, 8,12, 1439,12, 1 },
3181 { 2018, 9,11, 1440, 1, 1 },
3182 { 2019, 8,31, 1441, 1, 1 },
3183 { 2020, 8,20, 1442, 1, 1 },
3184 { 2021, 8, 9, 1443, 1, 1 },
3185 { 2022, 7,30, 1444, 1, 1 },
3186 { 2023, 7,19, 1445, 1, 1 },
3187 { 2024, 7, 7, 1446, 1, 1 },
3188 { 2025, 6,26, 1447, 1, 1 },
3189 { 2026, 6,16, 1448, 1, 1 },
3190 { 2027, 6, 6, 1449, 1, 1 },
3191 { 2028, 5,25, 1450, 1, 1 },
3192 { 2029, 5,14, 1451, 1, 1 },
3193 { 2030, 5, 4, 1452, 1, 1 },
3194 { 2031, 4,23, 1453, 1, 1 },
3195 { 2032, 4,11, 1454, 1, 1 },
3196 { 2033, 4, 1, 1455, 1, 1 },
3197 { 2034, 3,22, 1456, 1, 1 },
3198 { 2035, 3,11, 1457, 1, 1 },
3199 { 2036, 2,29, 1458, 1, 1 },
3200 { 2037, 2,17, 1459, 1, 1 },
3201 { 2038, 2, 6, 1460, 1, 1 },
3202 { 2039, 1,26, 1461, 1, 1 },
3203 { 2040, 1,15, 1462, 1, 1 },
3204 { 2041, 1, 4, 1463, 1, 1 },
3205 { 2041,12,25, 1464, 1, 1 },
3206 { 2042,12,14, 1465, 1, 1 },
3207 { 2043,12, 3, 1466, 1, 1 },
3208 { 2044,11,21, 1467, 1, 1 },
3209 { 2045,11,11, 1468, 1, 1 },
3210 { 2046,10,31, 1469, 1, 1 },
3211 { 2047,10,21, 1470, 1, 1 },
3212 { 2048,10, 9, 1471, 1, 1 },
3213 { 2049, 9,29, 1472, 1, 1 },
3214 { 2050, 9,18, 1473, 1, 1 },
3215 { 2051, 9, 7, 1474, 1, 1 },
3216 { 2052, 8,26, 1475, 1, 1 },
3217 { 2053, 8,15, 1476, 1, 1 },
3218 { 2054, 8, 5, 1477, 1, 1 },
3219 { 2055, 7,26, 1478, 1, 1 },
3220 { 2056, 7,14, 1479, 1, 1 },
3221 { 2057, 7, 3, 1480, 1, 1 },
3222 { 2058, 6,22, 1481, 1, 1 },
3223 { 2059, 6,11, 1482, 1, 1 },
3224 { 2061, 5,21, 1484, 1, 1 },
3225 { 2063, 4,30, 1486, 1, 1 },
3226 { 2065, 4, 7, 1488, 1, 1 },
3227 { 2067, 3,17, 1490, 1, 1 },
3228 { 2069, 2,23, 1492, 1, 1 },
3229 { 2071, 2, 2, 1494, 1, 1 },
3230 { 2073, 1,10, 1496, 1, 1 },
3231 { 2074,12,20, 1498, 1, 1 },
3232 { 2076,11,28, 1500, 1, 1 },
3233 { 0, 0, 0, 0, 0, 0 }, // terminator
3234 };
3235
3236 static const UChar zoneSA[] = {0x41,0x73,0x69,0x61,0x2F,0x52,0x69,0x79,0x61,0x64,0x68,0}; // "Asia/Riyadh"
3237
3238 void CalendarTest::TestIslamicUmAlQura() {
3239
3240 UErrorCode status = U_ZERO_ERROR;
3241 Locale umalquraLoc("ar_SA@calendar=islamic-umalqura");
3242 Locale gregoLoc("ar_SA@calendar=gregorian");
3243 TimeZone* tzSA = TimeZone::createTimeZone(UnicodeString(TRUE, zoneSA, -1));
3244 Calendar* tstCal = Calendar::createInstance(*((const TimeZone *)tzSA), umalquraLoc, status);
3245 Calendar* gregCal = Calendar::createInstance(*((const TimeZone *)tzSA), gregoLoc, status);
3246
3247 IslamicCalendar* iCal = (IslamicCalendar*)tstCal;
3248 if(strcmp(iCal->getType(), "islamic-umalqura") != 0) {
3249 errln("wrong type of calendar created - %s", iCal->getType());
3250 }
3251
3252 int32_t firstYear = 1318;
3253 int32_t lastYear = 1368; // just enough to be pretty sure
3254 //int32_t lastYear = 1480; // the whole shootin' match
3255
3256 tstCal->clear();
3257 tstCal->setLenient(FALSE);
3258
3259 int32_t day=0, month=0, year=0, initDay = 27, initMonth = IslamicCalendar::RAJAB, initYear = 1434;
3260
3261 for( int32_t startYear = firstYear; startYear <= lastYear; startYear++) {
3262 setAndTestWholeYear(tstCal, startYear, status);
3263 status = U_ZERO_ERROR;
3264 }
3265
3266 initMonth = IslamicCalendar::RABI_2;
3267 initDay = 5;
3268 int32_t loopCnt = 25;
3269 tstCal->clear();
3270 setAndTestCalendar( tstCal, initMonth, initDay, initYear, status);
3271 TEST_CHECK_STATUS;
3272
3273 for(int x=1; x<=loopCnt; x++) {
3274 day = tstCal->get(UCAL_DAY_OF_MONTH,status);
3275 month = tstCal->get(UCAL_MONTH,status);
3276 year = tstCal->get(UCAL_YEAR,status);
3277 TEST_CHECK_STATUS;
3278 tstCal->roll(UCAL_DAY_OF_MONTH, (UBool)TRUE, status);
3279 TEST_CHECK_STATUS;
3280 }
3281
3282 if(day != (initDay + loopCnt - 1) || month != IslamicCalendar::RABI_2 || year != 1434)
3283 errln("invalid values for RABI_2 date after roll of %d", loopCnt);
3284
3285 status = U_ZERO_ERROR;
3286 tstCal->clear();
3287 initMonth = 2;
3288 initDay = 30;
3289 setAndTestCalendar( tstCal, initMonth, initDay, initYear, status);
3290 if(U_SUCCESS(status)) {
3291 errln("error NOT detected status %i",status);
3292 errln(" init values:\tmonth %i\tday %i\tyear %i", initMonth, initDay, initYear);
3293 int32_t day = tstCal->get(UCAL_DAY_OF_MONTH, status);
3294 int32_t month = tstCal->get(UCAL_MONTH, status);
3295 int32_t year = tstCal->get(UCAL_YEAR, status);
3296 errln("values post set():\tmonth %i\tday %i\tyear %i",month, day, year);
3297 }
3298
3299 status = U_ZERO_ERROR;
3300 tstCal->clear();
3301 initMonth = 3;
3302 initDay = 30;
3303 setAndTestCalendar( tstCal, initMonth, initDay, initYear, status);
3304 TEST_CHECK_STATUS;
3305
3306 SimpleDateFormat* formatter = new SimpleDateFormat("yyyy-MM-dd", Locale::getUS(), status);
3307 UDate date = formatter->parse("1975-05-06", status);
3308 Calendar* is_cal = Calendar::createInstance(umalquraLoc, status);
3309 is_cal->setTime(date, status);
3310 int32_t is_day = is_cal->get(UCAL_DAY_OF_MONTH,status);
3311 int32_t is_month = is_cal->get(UCAL_MONTH,status);
3312 int32_t is_year = is_cal->get(UCAL_YEAR,status);
3313 TEST_CHECK_STATUS;
3314 if(is_day != 24 || is_month != IslamicCalendar::RABI_2 || is_year != 1395)
3315 errln("unexpected conversion date month %i not %i or day %i not 24 or year %i not 1395", is_month, IslamicCalendar::RABI_2, is_day, is_year);
3316
3317 UDate date2 = is_cal->getTime(status);
3318 TEST_CHECK_STATUS;
3319 if(date2 != date) {
3320 errln("before(%f) and after(%f) dates don't match up!",date, date2);
3321 }
3322
3323 // check against data
3324 const GregoUmmAlQuraMap* guMapPtr;
3325 gregCal->clear();
3326 tstCal->clear();
3327 for (guMapPtr = guMappings; guMapPtr->gYear != 0; guMapPtr++) {
3328 status = U_ZERO_ERROR;
3329 gregCal->set(guMapPtr->gYear, guMapPtr->gMon - 1, guMapPtr->gDay, 12, 0);
3330 date = gregCal->getTime(status);
3331 tstCal->setTime(date, status);
3332 int32_t uYear = tstCal->get(UCAL_YEAR, status);
3333 int32_t uMon = tstCal->get(UCAL_MONTH, status) + 1;
3334 int32_t uDay = tstCal->get(UCAL_DATE, status);
3335 if(U_FAILURE(status)) {
3336 errln("For gregorian %4d-%02d-%02d, get status %s",
3337 guMapPtr->gYear, guMapPtr->gMon, guMapPtr->gDay, u_errorName(status) );
3338 } else if (uYear != guMapPtr->uYear || uMon != guMapPtr->uMon || uDay != guMapPtr->uDay) {
3339 errln("For gregorian %4d-%02d-%02d, expect umalqura %4d-%02d-%02d, get %4d-%02d-%02d",
3340 guMapPtr->gYear, guMapPtr->gMon, guMapPtr->gDay,
3341 guMapPtr->uYear, guMapPtr->uMon, guMapPtr->uDay, uYear, uMon, uDay );
3342 }
3343 }
3344
3345 delete is_cal;
3346 delete formatter;
3347 delete gregCal;
3348 delete tstCal;
3349 delete tzSA;
3350 }
3351
3352 void CalendarTest::TestIslamicTabularDates() {
3353 UErrorCode status = U_ZERO_ERROR;
3354 Locale islamicLoc("ar_SA@calendar=islamic-civil");
3355 Locale tblaLoc("ar_SA@calendar=islamic-tbla");
3356 SimpleDateFormat* formatter = new SimpleDateFormat("yyyy-MM-dd", Locale::getUS(), status);
3357 UDate date = formatter->parse("1975-05-06", status);
3358
3359 Calendar* tstCal = Calendar::createInstance(islamicLoc, status);
3360 tstCal->setTime(date, status);
3361 int32_t is_day = tstCal->get(UCAL_DAY_OF_MONTH,status);
3362 int32_t is_month = tstCal->get(UCAL_MONTH,status);
3363 int32_t is_year = tstCal->get(UCAL_YEAR,status);
3364 TEST_CHECK_STATUS;
3365 delete tstCal;
3366
3367 tstCal = Calendar::createInstance(tblaLoc, status);
3368 tstCal->setTime(date, status);
3369 int32_t tbla_day = tstCal->get(UCAL_DAY_OF_MONTH,status);
3370 int32_t tbla_month = tstCal->get(UCAL_MONTH,status);
3371 int32_t tbla_year = tstCal->get(UCAL_YEAR,status);
3372 TEST_CHECK_STATUS;
3373
3374 if(tbla_month != is_month || tbla_year != is_year)
3375 errln("unexpected difference between islamic and tbla month %d : %d and/or year %d : %d",tbla_month,is_month,tbla_year,is_year);
3376
3377 if(tbla_day - is_day != 1)
3378 errln("unexpected day difference between islamic and tbla: %d : %d ",tbla_day,is_day);
3379 delete tstCal;
3380 delete formatter;
3381 }
3382
3383 void CalendarTest::TestHebrewMonthValidation() {
3384 UErrorCode status = U_ZERO_ERROR;
3385 LocalPointer<Calendar> cal(Calendar::createInstance(Locale::createFromName("he_IL@calendar=hebrew"), status));
3386 if (failure(status, "Calendar::createInstance, locale:he_IL@calendar=hebrew", TRUE)) return;
3387 Calendar *pCal = cal.getAlias();
3388
3389 UDate d;
3390 pCal->setLenient(FALSE);
3391
3392 // 5776 is a leap year and has month Adar I
3393 pCal->set(5776, HebrewCalendar::ADAR_1, 1);
3394 d = pCal->getTime(status);
3395 if (U_FAILURE(status)) {
3396 errln("Fail: 5776 Adar I 1 is a valid date.");
3397 }
3398 status = U_ZERO_ERROR;
3399
3400 // 5777 is NOT a lear year and does not have month Adar I
3401 pCal->set(5777, HebrewCalendar::ADAR_1, 1);
3402 d = pCal->getTime(status);
3403 (void)d;
3404 if (status == U_ILLEGAL_ARGUMENT_ERROR) {
3405 logln("Info: U_ILLEGAL_ARGUMENT_ERROR, because 5777 Adar I 1 is not a valid date.");
3406 } else {
3407 errln("Fail: U_ILLEGAL_ARGUMENT_ERROR should be set for input date 5777 Adar I 1.");
3408 }
3409 }
3410
3411 void CalendarTest::TestWeekData() {
3412 // Each line contains two locales using the same set of week rule data.
3413 const char* LOCALE_PAIRS[] = {
3414 "en", "en_US",
3415 "de", "de_DE",
3416 "de_DE", "en_DE",
3417 "en_GB", "und_GB",
3418 "ar_EG", "en_EG",
3419 "ar_SA", "fr_SA",
3420 0
3421 };
3422
3423 UErrorCode status;
3424
3425 for (int32_t i = 0; LOCALE_PAIRS[i] != 0; i += 2) {
3426 status = U_ZERO_ERROR;
3427 LocalPointer<Calendar> cal1(Calendar::createInstance(LOCALE_PAIRS[i], status));
3428 LocalPointer<Calendar> cal2(Calendar::createInstance(LOCALE_PAIRS[i + 1], status));
3429 TEST_CHECK_STATUS_LOCALE(LOCALE_PAIRS[i]);
3430
3431 // First day of week
3432 UCalendarDaysOfWeek dow1 = cal1->getFirstDayOfWeek(status);
3433 UCalendarDaysOfWeek dow2 = cal2->getFirstDayOfWeek(status);
3434 TEST_CHECK_STATUS;
3435 TEST_ASSERT(dow1 == dow2);
3436
3437 // Minimum days in first week
3438 uint8_t minDays1 = cal1->getMinimalDaysInFirstWeek();
3439 uint8_t minDays2 = cal2->getMinimalDaysInFirstWeek();
3440 TEST_ASSERT(minDays1 == minDays2);
3441
3442 // Weekdays and Weekends
3443 for (int32_t d = UCAL_SUNDAY; d <= UCAL_SATURDAY; d++) {
3444 status = U_ZERO_ERROR;
3445 UCalendarWeekdayType wdt1 = cal1->getDayOfWeekType((UCalendarDaysOfWeek)d, status);
3446 UCalendarWeekdayType wdt2 = cal2->getDayOfWeekType((UCalendarDaysOfWeek)d, status);
3447 TEST_CHECK_STATUS;
3448 TEST_ASSERT(wdt1 == wdt2);
3449 }
3450 }
3451 }
3452
3453 typedef struct {
3454 const char* zone;
3455 const CalFields base;
3456 int32_t deltaDays;
3457 UCalendarWallTimeOption skippedWTOpt;
3458 const CalFields expected;
3459 } TestAddAcrossZoneTransitionData;
3460
3461 static const TestAddAcrossZoneTransitionData AAZTDATA[] =
3462 {
3463 // Time zone Base wall time day(s) Skipped time options
3464 // Expected wall time
3465
3466 // Add 1 day, from the date before DST transition
3467 {"America/Los_Angeles", CalFields(2014,3,8,1,59,59,999), 1, UCAL_WALLTIME_FIRST,
3468 CalFields(2014,3,9,1,59,59,999)},
3469
3470 {"America/Los_Angeles", CalFields(2014,3,8,1,59,59,999), 1, UCAL_WALLTIME_LAST,
3471 CalFields(2014,3,9,1,59,59,999)},
3472
3473 {"America/Los_Angeles", CalFields(2014,3,8,1,59,59,999), 1, UCAL_WALLTIME_NEXT_VALID,
3474 CalFields(2014,3,9,1,59,59,999)},
3475
3476
3477 {"America/Los_Angeles", CalFields(2014,3,8,2,0,0,0), 1, UCAL_WALLTIME_FIRST,
3478 CalFields(2014,3,9,1,0,0,0)},
3479
3480 {"America/Los_Angeles", CalFields(2014,3,8,2,0,0,0), 1, UCAL_WALLTIME_LAST,
3481 CalFields(2014,3,9,3,0,0,0)},
3482
3483 {"America/Los_Angeles", CalFields(2014,3,8,2,0,0,0), 1, UCAL_WALLTIME_NEXT_VALID,
3484 CalFields(2014,3,9,3,0,0,0)},
3485
3486
3487 {"America/Los_Angeles", CalFields(2014,3,8,2,30,0,0), 1, UCAL_WALLTIME_FIRST,
3488 CalFields(2014,3,9,1,30,0,0)},
3489
3490 {"America/Los_Angeles", CalFields(2014,3,8,2,30,0,0), 1, UCAL_WALLTIME_LAST,
3491 CalFields(2014,3,9,3,30,0,0)},
3492
3493 {"America/Los_Angeles", CalFields(2014,3,8,2,30,0,0), 1, UCAL_WALLTIME_NEXT_VALID,
3494 CalFields(2014,3,9,3,0,0,0)},
3495
3496
3497 {"America/Los_Angeles", CalFields(2014,3,8,3,0,0,0), 1, UCAL_WALLTIME_FIRST,
3498 CalFields(2014,3,9,3,0,0,0)},
3499
3500 {"America/Los_Angeles", CalFields(2014,3,8,3,0,0,0), 1, UCAL_WALLTIME_LAST,
3501 CalFields(2014,3,9,3,0,0,0)},
3502
3503 {"America/Los_Angeles", CalFields(2014,3,8,3,0,0,0), 1, UCAL_WALLTIME_NEXT_VALID,
3504 CalFields(2014,3,9,3,0,0,0)},
3505
3506 // Subtract 1 day, from one day after DST transition
3507 {"America/Los_Angeles", CalFields(2014,3,10,1,59,59,999), -1, UCAL_WALLTIME_FIRST,
3508 CalFields(2014,3,9,1,59,59,999)},
3509
3510 {"America/Los_Angeles", CalFields(2014,3,10,1,59,59,999), -1, UCAL_WALLTIME_LAST,
3511 CalFields(2014,3,9,1,59,59,999)},
3512
3513 {"America/Los_Angeles", CalFields(2014,3,10,1,59,59,999), -1, UCAL_WALLTIME_NEXT_VALID,
3514 CalFields(2014,3,9,1,59,59,999)},
3515
3516
3517 {"America/Los_Angeles", CalFields(2014,3,10,2,0,0,0), -1, UCAL_WALLTIME_FIRST,
3518 CalFields(2014,3,9,1,0,0,0)},
3519
3520 {"America/Los_Angeles", CalFields(2014,3,10,2,0,0,0), -1, UCAL_WALLTIME_LAST,
3521 CalFields(2014,3,9,3,0,0,0)},
3522
3523 {"America/Los_Angeles", CalFields(2014,3,10,2,0,0,0), -1, UCAL_WALLTIME_NEXT_VALID,
3524 CalFields(2014,3,9,3,0,0,0)},
3525
3526
3527 {"America/Los_Angeles", CalFields(2014,3,10,2,30,0,0), -1, UCAL_WALLTIME_FIRST,
3528 CalFields(2014,3,9,1,30,0,0)},
3529
3530 {"America/Los_Angeles", CalFields(2014,3,10,2,30,0,0), -1, UCAL_WALLTIME_LAST,
3531 CalFields(2014,3,9,3,30,0,0)},
3532
3533 {"America/Los_Angeles", CalFields(2014,3,10,2,30,0,0), -1, UCAL_WALLTIME_NEXT_VALID,
3534 CalFields(2014,3,9,3,0,0,0)},
3535
3536
3537 {"America/Los_Angeles", CalFields(2014,3,10,3,0,0,0), -1, UCAL_WALLTIME_FIRST,
3538 CalFields(2014,3,9,3,0,0,0)},
3539
3540 {"America/Los_Angeles", CalFields(2014,3,10,3,0,0,0), -1, UCAL_WALLTIME_LAST,
3541 CalFields(2014,3,9,3,0,0,0)},
3542
3543 {"America/Los_Angeles", CalFields(2014,3,10,3,0,0,0), -1, UCAL_WALLTIME_NEXT_VALID,
3544 CalFields(2014,3,9,3,0,0,0)},
3545
3546
3547 // Test case for ticket#10544
3548 {"America/Santiago", CalFields(2013,4,27,0,0,0,0), 134, UCAL_WALLTIME_FIRST,
3549 CalFields(2013,9,7,23,0,0,0)},
3550
3551 {"America/Santiago", CalFields(2013,4,27,0,0,0,0), 134, UCAL_WALLTIME_LAST,
3552 CalFields(2013,9,8,1,0,0,0)},
3553
3554 {"America/Santiago", CalFields(2013,4,27,0,0,0,0), 134, UCAL_WALLTIME_NEXT_VALID,
3555 CalFields(2013,9,8,1,0,0,0)},
3556
3557
3558 {"America/Santiago", CalFields(2013,4,27,0,30,0,0), 134, UCAL_WALLTIME_FIRST,
3559 CalFields(2013,9,7,23,30,0,0)},
3560
3561 {"America/Santiago", CalFields(2013,4,27,0,30,0,0), 134, UCAL_WALLTIME_LAST,
3562 CalFields(2013,9,8,1,30,0,0)},
3563
3564 {"America/Santiago", CalFields(2013,4,27,0,30,0,0), 134, UCAL_WALLTIME_NEXT_VALID,
3565 CalFields(2013,9,8,1,0,0,0)},
3566
3567
3568 // Extreme transition - Pacific/Apia completely skips 2011-12-30
3569 {"Pacific/Apia", CalFields(2011,12,29,0,0,0,0), 1, UCAL_WALLTIME_FIRST,
3570 CalFields(2011,12,31,0,0,0,0)},
3571
3572 {"Pacific/Apia", CalFields(2011,12,29,0,0,0,0), 1, UCAL_WALLTIME_LAST,
3573 CalFields(2011,12,31,0,0,0,0)},
3574
3575 {"Pacific/Apia", CalFields(2011,12,29,0,0,0,0), 1, UCAL_WALLTIME_NEXT_VALID,
3576 CalFields(2011,12,31,0,0,0,0)},
3577
3578
3579 {"Pacific/Apia", CalFields(2011,12,31,12,0,0,0), -1, UCAL_WALLTIME_FIRST,
3580 CalFields(2011,12,29,12,0,0,0)},
3581
3582 {"Pacific/Apia", CalFields(2011,12,31,12,0,0,0), -1, UCAL_WALLTIME_LAST,
3583 CalFields(2011,12,29,12,0,0,0)},
3584
3585 {"Pacific/Apia", CalFields(2011,12,31,12,0,0,0), -1, UCAL_WALLTIME_NEXT_VALID,
3586 CalFields(2011,12,29,12,0,0,0)},
3587
3588
3589 // 30 minutes DST - Australia/Lord_Howe
3590 {"Australia/Lord_Howe", CalFields(2013,10,5,2,15,0,0), 1, UCAL_WALLTIME_FIRST,
3591 CalFields(2013,10,6,1,45,0,0)},
3592
3593 {"Australia/Lord_Howe", CalFields(2013,10,5,2,15,0,0), 1, UCAL_WALLTIME_LAST,
3594 CalFields(2013,10,6,2,45,0,0)},
3595
3596 {"Australia/Lord_Howe", CalFields(2013,10,5,2,15,0,0), 1, UCAL_WALLTIME_NEXT_VALID,
3597 CalFields(2013,10,6,2,30,0,0)},
3598
3599 {NULL, CalFields(0,0,0,0,0,0,0), 0, UCAL_WALLTIME_LAST, CalFields(0,0,0,0,0,0,0)}
3600 };
3601
3602 void CalendarTest::TestAddAcrossZoneTransition() {
3603 UErrorCode status = U_ZERO_ERROR;
3604 GregorianCalendar cal(status);
3605 TEST_CHECK_STATUS;
3606
3607 for (int32_t i = 0; AAZTDATA[i].zone; i++) {
3608 status = U_ZERO_ERROR;
3609 TimeZone *tz = TimeZone::createTimeZone(AAZTDATA[i].zone);
3610 cal.adoptTimeZone(tz);
3611 cal.setSkippedWallTimeOption(AAZTDATA[i].skippedWTOpt);
3612 AAZTDATA[i].base.setTo(cal);
3613 cal.add(UCAL_DATE, AAZTDATA[i].deltaDays, status);
3614 TEST_CHECK_STATUS;
3615
3616 if (!AAZTDATA[i].expected.isEquivalentTo(cal, status)) {
3617 CalFields res(cal, status);
3618 TEST_CHECK_STATUS;
3619 char buf[32];
3620 const char *optDisp = AAZTDATA[i].skippedWTOpt == UCAL_WALLTIME_FIRST ? "FIRST" :
3621 AAZTDATA[i].skippedWTOpt == UCAL_WALLTIME_LAST ? "LAST" : "NEXT_VALID";
3622 dataerrln(UnicodeString("Error: base:") + AAZTDATA[i].base.toString(buf, sizeof(buf)) + ", tz:" + AAZTDATA[i].zone
3623 + ", delta:" + AAZTDATA[i].deltaDays + " day(s), opt:" + optDisp
3624 + ", result:" + res.toString(buf, sizeof(buf))
3625 + " - expected:" + AAZTDATA[i].expected.toString(buf, sizeof(buf)));
3626 }
3627 }
3628 }
3629
3630 #endif /* #if !UCONFIG_NO_FORMATTING */
3631
3632 //eof