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