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