1 /************************************************************************
3 * Copyright (c) 1997-2014, International Business Machines Corporation
4 * and others. All Rights Reserved.
5 ************************************************************************/
6 #include "unicode/utypes.h"
8 #if !UCONFIG_NO_FORMATTING
11 #include "unicode/dtfmtsym.h"
12 #include "unicode/gregocal.h"
13 #include "unicode/localpointer.h"
15 #include "unicode/smpdtfmt.h"
16 #include "unicode/simpletz.h"
18 #include "unicode/udat.h"
19 #include "unicode/ustring.h"
21 #include "unicode/localpointer.h"
24 #define mkcstr(U) u_austrcpy(calloc(8, u_strlen(U) + 1), U)
26 #define TEST_CHECK_STATUS { \
27 if (U_FAILURE(status)) { \
28 if (status == U_MISSING_RESOURCE_ERROR) { \
29 dataerrln("%s:%d: Test failure. status=%s", __FILE__, __LINE__, u_errorName(status)); \
31 errln("%s:%d: Test failure. status=%s", __FILE__, __LINE__, u_errorName(status)); \
34 #define TEST_ASSERT(expr) {if ((expr)==FALSE) {errln("%s:%d: Test failure \n", __FILE__, __LINE__);};}
36 // *****************************************************************************
38 // *****************************************************************************
40 UnicodeString
CalendarTest::calToStr(const Calendar
& cal
)
43 UErrorCode status
= U_ZERO_ERROR
;
46 for(i
= 0;i
<UCAL_FIELD_COUNT
;i
++) {
47 out
+= (UnicodeString("") + fieldName((UCalendarDateFields
)i
) + "=" + cal
.get((UCalendarDateFields
)i
, status
) + UnicodeString(" "));
49 out
+= "[" + UnicodeString(cal
.getType()) + "]";
51 if(cal
.inDaylightTime(status
)) {
52 out
+= UnicodeString(" (in DST), zone=");
55 out
+= UnicodeString(", zone=");
59 out
+= cal
.getTimeZone().getDisplayName(str2
);
60 d
= cal
.getTime(status
);
61 out
+= UnicodeString(" :","") + d
;
66 void CalendarTest::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char* /*par*/ )
68 if (exec
) logln("TestSuite TestCalendar");
73 logln("TestDOW943---"); logln("");
78 name
= "TestClonesUnique908";
80 logln("TestClonesUnique908---"); logln("");
81 TestClonesUnique908();
85 name
= "TestGregorianChange768";
87 logln("TestGregorianChange768---"); logln("");
88 TestGregorianChange768();
92 name
= "TestDisambiguation765";
94 logln("TestDisambiguation765---"); logln("");
95 TestDisambiguation765();
99 name
= "TestGMTvsLocal4064654";
101 logln("TestGMTvsLocal4064654---"); logln("");
102 TestGMTvsLocal4064654();
106 name
= "TestAddSetOrder621";
108 logln("TestAddSetOrder621---"); logln("");
109 TestAddSetOrder621();
115 logln("TestAdd520---"); logln("");
120 name
= "TestFieldSet4781";
122 logln("TestFieldSet4781---"); logln("");
127 name
= "TestSerialize337";
129 logln("TestSerialize337---"); logln("");
130 // TestSerialize337();
134 name
= "TestSecondsZero121";
136 logln("TestSecondsZero121---"); logln("");
137 TestSecondsZero121();
141 name
= "TestAddSetGet0610";
143 logln("TestAddSetGet0610---"); logln("");
148 name
= "TestFields060";
150 logln("TestFields060---"); logln("");
155 name
= "TestEpochStartFields";
157 logln("TestEpochStartFields---"); logln("");
158 TestEpochStartFields();
162 name
= "TestDOWProgression";
164 logln("TestDOWProgression---"); logln("");
165 TestDOWProgression();
169 name
= "TestGenericAPI";
171 logln("TestGenericAPI---"); logln("");
176 name
= "TestAddRollExtensive";
178 logln("TestAddRollExtensive---"); logln("");
179 TestAddRollExtensive();
183 name
= "TestDOW_LOCALandYEAR_WOY";
185 logln("TestDOW_LOCALandYEAR_WOY---"); logln("");
186 TestDOW_LOCALandYEAR_WOY();
192 logln("TestWOY---"); logln("");
199 logln("TestRog---"); logln("");
206 logln("TestYWOY---"); logln("");
213 logln("TestJD---"); logln("");
220 logln("TestDebug---"); logln("");
227 logln("Test6703---"); logln("");
234 logln("Test3785---"); logln("");
241 logln("Test1624---"); logln("");
246 name
= "TestTimeStamp";
248 logln("TestTimeStamp---"); logln("");
253 name
= "TestISO8601";
255 logln("TestISO8601---"); logln("");
260 name
= "TestAmbiguousWallTimeAPIs";
262 logln("TestAmbiguousWallTimeAPIs---"); logln("");
263 TestAmbiguousWallTimeAPIs();
267 name
= "TestRepeatedWallTime";
269 logln("TestRepeatedWallTime---"); logln("");
270 TestRepeatedWallTime();
274 name
= "TestSkippedWallTime";
276 logln("TestSkippedWallTime---"); logln("");
277 TestSkippedWallTime();
281 name
= "TestCloneLocale";
283 logln("TestCloneLocale---"); logln("");
288 name
= "TestIslamicUmAlQura";
290 logln("TestIslamicUmAlQura---"); logln("");
291 TestIslamicUmAlQura();
295 name
= "TestIslamicTabularDates";
297 logln("TestIslamicTabularDates---"); logln("");
298 TestIslamicTabularDates();
302 name
= "TestHebrewMonthValidation";
304 logln("TestHebrewMonthValidation---"); logln("");
305 TestHebrewMonthValidation();
309 name
= "TestWeekData";
311 logln("TestWeekData---"); logln("");
316 name
= "TestAddAcrossZoneTransition";
318 logln("TestAddAcrossZoneTransition---"); logln("");
319 TestAddAcrossZoneTransition();
322 default: name
= ""; break;
326 // ---------------------------------------------------------------------------------
328 UnicodeString
CalendarTest::fieldName(UCalendarDateFields f
) {
330 #define FIELD_NAME_STR(x) case x: return (#x+5)
331 FIELD_NAME_STR( UCAL_ERA
);
332 FIELD_NAME_STR( UCAL_YEAR
);
333 FIELD_NAME_STR( UCAL_MONTH
);
334 FIELD_NAME_STR( UCAL_WEEK_OF_YEAR
);
335 FIELD_NAME_STR( UCAL_WEEK_OF_MONTH
);
336 FIELD_NAME_STR( UCAL_DATE
);
337 FIELD_NAME_STR( UCAL_DAY_OF_YEAR
);
338 FIELD_NAME_STR( UCAL_DAY_OF_WEEK
);
339 FIELD_NAME_STR( UCAL_DAY_OF_WEEK_IN_MONTH
);
340 FIELD_NAME_STR( UCAL_AM_PM
);
341 FIELD_NAME_STR( UCAL_HOUR
);
342 FIELD_NAME_STR( UCAL_HOUR_OF_DAY
);
343 FIELD_NAME_STR( UCAL_MINUTE
);
344 FIELD_NAME_STR( UCAL_SECOND
);
345 FIELD_NAME_STR( UCAL_MILLISECOND
);
346 FIELD_NAME_STR( UCAL_ZONE_OFFSET
);
347 FIELD_NAME_STR( UCAL_DST_OFFSET
);
348 FIELD_NAME_STR( UCAL_YEAR_WOY
);
349 FIELD_NAME_STR( UCAL_DOW_LOCAL
);
350 FIELD_NAME_STR( UCAL_EXTENDED_YEAR
);
351 FIELD_NAME_STR( UCAL_JULIAN_DAY
);
352 FIELD_NAME_STR( UCAL_MILLISECONDS_IN_DAY
);
353 #undef FIELD_NAME_STR
355 return UnicodeString("") + ((int32_t)f
);
360 * Test various API methods for API completeness.
363 CalendarTest::TestGenericAPI()
365 UErrorCode status
= U_ZERO_ERROR
;
368 UBool eq
= FALSE
,b4
= FALSE
,af
= FALSE
;
370 UDate when
= date(90, UCAL_APRIL
, 15);
372 UnicodeString
tzid("TestZone");
373 int32_t tzoffset
= 123400;
375 SimpleTimeZone
*zone
= new SimpleTimeZone(tzoffset
, tzid
);
376 Calendar
*cal
= Calendar::createInstance(zone
->clone(), status
);
377 if (failure(status
, "Calendar::createInstance", TRUE
)) return;
379 if (*zone
!= cal
->getTimeZone()) errln("FAIL: Calendar::getTimeZone failed");
381 Calendar
*cal2
= Calendar::createInstance(cal
->getTimeZone(), status
);
382 if (failure(status
, "Calendar::createInstance")) return;
383 cal
->setTime(when
, status
);
384 cal2
->setTime(when
, status
);
385 if (failure(status
, "Calendar::setTime")) return;
387 if (!(*cal
== *cal2
)) errln("FAIL: Calendar::operator== failed");
388 if ((*cal
!= *cal2
)) errln("FAIL: Calendar::operator!= failed");
389 if (!cal
->equals(*cal2
, status
) ||
390 cal
->before(*cal2
, status
) ||
391 cal
->after(*cal2
, status
) ||
392 U_FAILURE(status
)) errln("FAIL: equals/before/after failed");
394 logln(UnicodeString("cal=") +cal
->getTime(status
) + UnicodeString(calToStr(*cal
)));
395 logln(UnicodeString("cal2=") +cal2
->getTime(status
) + UnicodeString(calToStr(*cal2
)));
396 logln("cal2->setTime(when+1000)");
397 cal2
->setTime(when
+ 1000, status
);
398 logln(UnicodeString("cal2=") +cal2
->getTime(status
) + UnicodeString(calToStr(*cal2
)));
400 if (failure(status
, "Calendar::setTime")) return;
401 if (cal
->equals(*cal2
, status
) ||
402 cal2
->before(*cal
, status
) ||
403 cal
->after(*cal2
, status
) ||
404 U_FAILURE(status
)) errln("FAIL: equals/before/after failed after setTime(+1000)");
406 logln("cal->roll(UCAL_SECOND)");
407 cal
->roll(UCAL_SECOND
, (UBool
) TRUE
, status
);
408 logln(UnicodeString("cal=") +cal
->getTime(status
) + UnicodeString(calToStr(*cal
)));
409 cal
->roll(UCAL_SECOND
, (int32_t)0, status
);
410 logln(UnicodeString("cal=") +cal
->getTime(status
) + UnicodeString(calToStr(*cal
)));
411 if (failure(status
, "Calendar::roll")) return;
413 if (!(eq
=cal
->equals(*cal2
, status
)) ||
414 (b4
=cal
->before(*cal2
, status
)) ||
415 (af
=cal
->after(*cal2
, status
)) ||
417 errln("FAIL: equals[%c]/before[%c]/after[%c] failed after roll 1 second [should be T/F/F]",
421 logln(UnicodeString("cal=") +cal
->getTime(status
) + UnicodeString(calToStr(*cal
)));
422 logln(UnicodeString("cal2=") +cal2
->getTime(status
) + UnicodeString(calToStr(*cal2
)));
425 // Roll back to January
426 cal
->roll(UCAL_MONTH
, (int32_t)(1 + UCAL_DECEMBER
- cal
->get(UCAL_MONTH
, status
)), status
);
427 if (failure(status
, "Calendar::roll")) 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 rollback to January");
433 TimeZone
*z
= cal
->orphanTimeZone();
434 if (z
->getID(str
) != tzid
||
435 z
->getRawOffset() != tzoffset
)
436 errln("FAIL: orphanTimeZone failed");
441 UBool lenient
= ( i
> 0 );
442 cal
->setLenient(lenient
);
443 if (lenient
!= cal
->isLenient()) errln("FAIL: setLenient/isLenient failed");
444 // Later: Check for lenient behavior
447 for (i
=UCAL_SUNDAY
; i
<=UCAL_SATURDAY
; ++i
)
449 cal
->setFirstDayOfWeek((UCalendarDaysOfWeek
)i
);
450 if (cal
->getFirstDayOfWeek() != i
) errln("FAIL: set/getFirstDayOfWeek failed");
451 UErrorCode aStatus
= U_ZERO_ERROR
;
452 if (cal
->getFirstDayOfWeek(aStatus
) != i
|| U_FAILURE(aStatus
)) errln("FAIL: getFirstDayOfWeek(status) failed");
457 cal
->setMinimalDaysInFirstWeek((uint8_t)i
);
458 if (cal
->getMinimalDaysInFirstWeek() != i
) errln("FAIL: set/getFirstDayOfWeek failed");
461 for (i
=0; i
<UCAL_FIELD_COUNT
; ++i
)
463 if (cal
->getMinimum((UCalendarDateFields
)i
) > cal
->getGreatestMinimum((UCalendarDateFields
)i
))
464 errln(UnicodeString("FAIL: getMinimum larger than getGreatestMinimum for field ") + i
);
465 if (cal
->getLeastMaximum((UCalendarDateFields
)i
) > cal
->getMaximum((UCalendarDateFields
)i
))
466 errln(UnicodeString("FAIL: getLeastMaximum larger than getMaximum for field ") + i
);
467 if (cal
->getMinimum((UCalendarDateFields
)i
) >= cal
->getMaximum((UCalendarDateFields
)i
))
468 errln(UnicodeString("FAIL: getMinimum not less than getMaximum for field ") + i
);
471 cal
->adoptTimeZone(TimeZone::createDefault());
473 cal
->set(1984, 5, 24);
474 if (cal
->getTime(status
) != date(84, 5, 24) || U_FAILURE(status
))
475 errln("FAIL: Calendar::set(3 args) failed");
478 cal
->set(1985, 3, 2, 11, 49);
479 if (cal
->getTime(status
) != date(85, 3, 2, 11, 49) || U_FAILURE(status
))
480 errln("FAIL: Calendar::set(5 args) failed");
483 cal
->set(1995, 9, 12, 1, 39, 55);
484 if (cal
->getTime(status
) != date(95, 9, 12, 1, 39, 55) || U_FAILURE(status
))
485 errln("FAIL: Calendar::set(6 args) failed");
487 cal
->getTime(status
);
488 if (failure(status
, "Calendar::getTime")) return;
489 for (i
=0; i
<UCAL_FIELD_COUNT
; ++i
)
492 case UCAL_YEAR
: case UCAL_MONTH
: case UCAL_DATE
:
493 case UCAL_HOUR_OF_DAY
: case UCAL_MINUTE
: case UCAL_SECOND
:
494 case UCAL_EXTENDED_YEAR
:
495 if (!cal
->isSet((UCalendarDateFields
)i
)) errln("FAIL: Calendar::isSet F, should be T " + fieldName((UCalendarDateFields
)i
));
498 if (cal
->isSet((UCalendarDateFields
)i
)) errln("FAIL: Calendar::isSet = T, should be F " + fieldName((UCalendarDateFields
)i
));
500 cal
->clear((UCalendarDateFields
)i
);
501 if (cal
->isSet((UCalendarDateFields
)i
)) errln("FAIL: Calendar::clear/isSet failed " + fieldName((UCalendarDateFields
)i
));
504 if(cal
->getActualMinimum(Calendar::SECOND
, status
) != 0){
505 errln("Calendar is suppose to return 0 for getActualMinimum");
508 Calendar
*cal3
= Calendar::createInstance(status
);
509 cal3
->roll(Calendar::SECOND
, (int32_t)0, status
);
510 if (failure(status
, "Calendar::roll(EDateFields, int32_t, UErrorCode)")) return;
517 const Locale
* loc
= Calendar::getAvailableLocales(count
);
518 if (count
< 1 || loc
== 0)
520 dataerrln("FAIL: getAvailableLocales failed");
524 for (i
=0; i
<count
; ++i
)
526 cal
= Calendar::createInstance(loc
[i
], status
);
527 if (failure(status
, "Calendar::createInstance")) return;
532 cal
= Calendar::createInstance(TimeZone::createDefault(), Locale::getEnglish(), status
);
533 if (failure(status
, "Calendar::createInstance")) return;
536 cal
= Calendar::createInstance(*zone
, Locale::getEnglish(), status
);
537 if (failure(status
, "Calendar::createInstance")) return;
540 GregorianCalendar
*gc
= new GregorianCalendar(*zone
, status
);
541 if (failure(status
, "new GregorianCalendar")) return;
544 gc
= new GregorianCalendar(Locale::getEnglish(), status
);
545 if (failure(status
, "new GregorianCalendar")) return;
548 gc
= new GregorianCalendar(Locale::getEnglish(), status
);
551 gc
= new GregorianCalendar(*zone
, Locale::getEnglish(), status
);
552 if (failure(status
, "new GregorianCalendar")) return;
555 gc
= new GregorianCalendar(zone
, status
);
556 if (failure(status
, "new GregorianCalendar")) return;
559 gc
= new GregorianCalendar(1998, 10, 14, 21, 43, status
);
560 if (gc
->getTime(status
) != (d
=date(98, 10, 14, 21, 43) )|| U_FAILURE(status
))
561 errln("FAIL: new GregorianCalendar(ymdhm) failed with " + UnicodeString(u_errorName(status
)) + ", cal=" + gc
->getTime(status
) + UnicodeString(calToStr(*gc
)) + ", d=" + d
);
563 logln(UnicodeString("GOOD: cal=") +gc
->getTime(status
) + UnicodeString(calToStr(*gc
)) + ", d=" + d
);
566 gc
= new GregorianCalendar(1998, 10, 14, 21, 43, 55, status
);
567 if (gc
->getTime(status
) != (d
=date(98, 10, 14, 21, 43, 55)) || U_FAILURE(status
))
568 errln("FAIL: new GregorianCalendar(ymdhms) failed with " + UnicodeString(u_errorName(status
)));
570 GregorianCalendar
gc2(Locale::getEnglish(), status
);
571 if (failure(status
, "new GregorianCalendar")) return;
573 if (gc2
!= *gc
|| !(gc2
== *gc
)) errln("FAIL: GregorianCalendar assignment/operator==/operator!= failed");
577 /* Code coverage for Calendar class. */
578 cal
= Calendar::createInstance(status
);
579 if (failure(status
, "Calendar::createInstance")) {
582 ((Calendar
*)cal
)->roll(UCAL_HOUR
, (int32_t)100, status
);
583 ((Calendar
*)cal
)->clear(UCAL_HOUR
);
584 #if !UCONFIG_NO_SERVICE
585 URegistryKey key
= cal
->registerFactory(NULL
, status
);
586 cal
->unregister(key
, status
);
591 status
= U_ZERO_ERROR
;
592 cal
= Calendar::createInstance(Locale("he_IL@calendar=hebrew"), status
);
593 if (failure(status
, "Calendar::createInstance")) {
596 cal
->roll(Calendar::MONTH
, (int32_t)100, status
);
599 LocalPointer
<StringEnumeration
> values(
600 Calendar::getKeywordValuesForLocale("calendar", Locale("he"), FALSE
, status
));
601 if (values
.isNull() || U_FAILURE(status
)) {
602 dataerrln("FAIL: Calendar::getKeywordValuesForLocale(he): %s", u_errorName(status
));
604 UBool containsHebrew
= FALSE
;
605 const char *charValue
;
607 while ((charValue
= values
->next(&valueLength
, status
)) != NULL
) {
608 if (valueLength
== 6 && strcmp(charValue
, "hebrew") == 0) {
609 containsHebrew
= TRUE
;
612 if (!containsHebrew
) {
613 errln("Calendar::getKeywordValuesForLocale(he)->next() does not contain \"hebrew\"");
616 values
->reset(status
);
617 containsHebrew
= FALSE
;
618 UnicodeString hebrew
= UNICODE_STRING_SIMPLE("hebrew");
619 const UChar
*ucharValue
;
620 while ((ucharValue
= values
->unext(&valueLength
, status
)) != NULL
) {
621 UnicodeString
value(FALSE
, ucharValue
, valueLength
);
622 if (value
== hebrew
) {
623 containsHebrew
= TRUE
;
626 if (!containsHebrew
) {
627 errln("Calendar::getKeywordValuesForLocale(he)->unext() does not contain \"hebrew\"");
630 values
->reset(status
);
631 containsHebrew
= FALSE
;
632 const UnicodeString
*stringValue
;
633 while ((stringValue
= values
->snext(status
)) != NULL
) {
634 if (*stringValue
== hebrew
) {
635 containsHebrew
= TRUE
;
638 if (!containsHebrew
) {
639 errln("Calendar::getKeywordValuesForLocale(he)->snext() does not contain \"hebrew\"");
645 // -------------------------------------
648 * This test confirms the correct behavior of add when incrementing
649 * through subsequent days.
652 CalendarTest::TestRog()
654 UErrorCode status
= U_ZERO_ERROR
;
655 GregorianCalendar
* gc
= new GregorianCalendar(status
);
656 if (failure(status
, "new GregorianCalendar", TRUE
)) return;
657 int32_t year
= 1997, month
= UCAL_APRIL
, date
= 1;
658 gc
->set(year
, month
, date
);
659 gc
->set(UCAL_HOUR_OF_DAY
, 23);
660 gc
->set(UCAL_MINUTE
, 0);
661 gc
->set(UCAL_SECOND
, 0);
662 gc
->set(UCAL_MILLISECOND
, 0);
663 for (int32_t i
= 0; i
< 9; i
++, gc
->add(UCAL_DATE
, 1, status
)) {
664 if (U_FAILURE(status
)) { errln("Calendar::add failed"); return; }
665 if (gc
->get(UCAL_YEAR
, status
) != year
||
666 gc
->get(UCAL_MONTH
, status
) != month
||
667 gc
->get(UCAL_DATE
, status
) != (date
+ i
)) errln("FAIL: Date wrong");
668 if (U_FAILURE(status
)) { errln("Calendar::get failed"); return; }
673 // -------------------------------------
676 * Test the handling of the day of the week, checking for correctness and
677 * for correct minimum and maximum values.
680 CalendarTest::TestDOW943()
686 void CalendarTest::dowTest(UBool lenient
)
688 UErrorCode status
= U_ZERO_ERROR
;
689 GregorianCalendar
* cal
= new GregorianCalendar(status
);
690 if (failure(status
, "new GregorianCalendar", TRUE
)) return;
691 logln("cal - Aug 12, 1997\n");
692 cal
->set(1997, UCAL_AUGUST
, 12);
693 cal
->getTime(status
);
694 if (U_FAILURE(status
)) { errln("Calendar::getTime failed"); return; }
695 logln((lenient
?UnicodeString("LENIENT0: "):UnicodeString("nonlenient0: ")) + UnicodeString(calToStr(*cal
)));
696 cal
->setLenient(lenient
);
697 logln("cal - Dec 1, 1996\n");
698 cal
->set(1996, UCAL_DECEMBER
, 1);
699 logln((lenient
?UnicodeString("LENIENT: "):UnicodeString("nonlenient: ")) + UnicodeString(calToStr(*cal
)));
700 int32_t dow
= cal
->get(UCAL_DAY_OF_WEEK
, status
);
701 if (U_FAILURE(status
)) { errln("Calendar::get failed [%s]", u_errorName(status
)); return; }
702 int32_t min
= cal
->getMinimum(UCAL_DAY_OF_WEEK
);
703 int32_t max
= cal
->getMaximum(UCAL_DAY_OF_WEEK
);
705 dow
> max
) errln(UnicodeString("FAIL: Day of week ") + (int32_t)dow
+ " out of range");
706 if (dow
!= UCAL_SUNDAY
) errln("FAIL: Day of week should be SUNDAY[%d] not %d", UCAL_SUNDAY
, dow
);
707 if (min
!= UCAL_SUNDAY
||
708 max
!= UCAL_SATURDAY
) errln("FAIL: Min/max bad");
712 // -------------------------------------
715 * Confirm that cloned Calendar objects do not inadvertently share substructures.
718 CalendarTest::TestClonesUnique908()
720 UErrorCode status
= U_ZERO_ERROR
;
721 Calendar
*c
= Calendar::createInstance(status
);
722 if (failure(status
, "Calendar::createInstance", TRUE
)) return;
723 Calendar
*d
= (Calendar
*) c
->clone();
724 c
->set(UCAL_MILLISECOND
, 123);
725 d
->set(UCAL_MILLISECOND
, 456);
726 if (c
->get(UCAL_MILLISECOND
, status
) != 123 ||
727 d
->get(UCAL_MILLISECOND
, status
) != 456) {
728 errln("FAIL: Clones share fields");
730 if (U_FAILURE(status
)) { errln("Calendar::get failed"); return; }
735 // -------------------------------------
738 * Confirm that the Gregorian cutoff value works as advertised.
741 CalendarTest::TestGregorianChange768()
744 UErrorCode status
= U_ZERO_ERROR
;
746 GregorianCalendar
* c
= new GregorianCalendar(status
);
747 if (failure(status
, "new GregorianCalendar", TRUE
)) return;
748 logln(UnicodeString("With cutoff ") + dateToString(c
->getGregorianChange(), str
));
749 b
= c
->isLeapYear(1800);
750 logln(UnicodeString(" isLeapYear(1800) = ") + (b
? "true" : "false"));
751 logln(UnicodeString(" (should be FALSE)"));
752 if (b
) errln("FAIL");
753 c
->setGregorianChange(date(0, 0, 1), status
);
754 if (U_FAILURE(status
)) { errln("GregorianCalendar::setGregorianChange failed"); return; }
755 logln(UnicodeString("With cutoff ") + dateToString(c
->getGregorianChange(), str
));
756 b
= c
->isLeapYear(1800);
757 logln(UnicodeString(" isLeapYear(1800) = ") + (b
? "true" : "false"));
758 logln(UnicodeString(" (should be TRUE)"));
759 if (!b
) errln("FAIL");
763 // -------------------------------------
766 * Confirm the functioning of the field disambiguation algorithm.
769 CalendarTest::TestDisambiguation765()
771 UErrorCode status
= U_ZERO_ERROR
;
772 Calendar
*c
= Calendar::createInstance("en_US", status
);
773 if (failure(status
, "Calendar::createInstance", TRUE
)) return;
774 c
->setLenient(FALSE
);
776 c
->set(UCAL_YEAR
, 1997);
777 c
->set(UCAL_MONTH
, UCAL_JUNE
);
778 c
->set(UCAL_DATE
, 3);
779 verify765("1997 third day of June = ", c
, 1997, UCAL_JUNE
, 3);
781 c
->set(UCAL_YEAR
, 1997);
782 c
->set(UCAL_DAY_OF_WEEK
, UCAL_TUESDAY
);
783 c
->set(UCAL_MONTH
, UCAL_JUNE
);
784 c
->set(UCAL_DAY_OF_WEEK_IN_MONTH
, 1);
785 verify765("1997 first Tuesday in June = ", c
, 1997, UCAL_JUNE
, 3);
787 c
->set(UCAL_YEAR
, 1997);
788 c
->set(UCAL_DAY_OF_WEEK
, UCAL_TUESDAY
);
789 c
->set(UCAL_MONTH
, UCAL_JUNE
);
790 c
->set(UCAL_DAY_OF_WEEK_IN_MONTH
, - 1);
791 verify765("1997 last Tuesday in June = ", c
, 1997, UCAL_JUNE
, 24);
793 status
= U_ZERO_ERROR
;
795 c
->set(UCAL_YEAR
, 1997);
796 c
->set(UCAL_DAY_OF_WEEK
, UCAL_TUESDAY
);
797 c
->set(UCAL_MONTH
, UCAL_JUNE
);
798 c
->set(UCAL_DAY_OF_WEEK_IN_MONTH
, 0);
800 verify765("1997 zero-th Tuesday in June = ", status
);
803 c
->set(UCAL_YEAR
, 1997);
804 c
->set(UCAL_DAY_OF_WEEK
, UCAL_TUESDAY
);
805 c
->set(UCAL_MONTH
, UCAL_JUNE
);
806 c
->set(UCAL_WEEK_OF_MONTH
, 1);
807 verify765("1997 Tuesday in week 1 of June = ", c
, 1997, UCAL_JUNE
, 3);
809 c
->set(UCAL_YEAR
, 1997);
810 c
->set(UCAL_DAY_OF_WEEK
, UCAL_TUESDAY
);
811 c
->set(UCAL_MONTH
, UCAL_JUNE
);
812 c
->set(UCAL_WEEK_OF_MONTH
, 5);
813 verify765("1997 Tuesday in week 5 of June = ", c
, 1997, UCAL_JULY
, 1);
815 status
= U_ZERO_ERROR
;
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_WEEK_OF_MONTH
, 0);
821 c
->setMinimalDaysInFirstWeek(1);
823 verify765("1997 Tuesday in week 0 of June = ", status
);
825 /* Note: The following test used to expect YEAR 1997, WOY 1 to
826 * resolve to a date in Dec 1996; that is, to behave as if
827 * YEAR_WOY were 1997. With the addition of a new explicit
828 * YEAR_WOY field, YEAR_WOY must itself be set if that is what is
829 * desired. Using YEAR in combination with WOY is ambiguous, and
830 * results in the first WOY/DOW day of the year satisfying the
831 * given fields (there may be up to two such days). In this case,
832 * it propertly resolves to Tue Dec 30 1997, which has a WOY value
833 * of 1 (for YEAR_WOY 1998) and a DOW of Tuesday, and falls in the
834 * _calendar_ year 1997, as specified. - aliu */
836 c
->set(UCAL_YEAR_WOY
, 1997); // aliu
837 c
->set(UCAL_DAY_OF_WEEK
, UCAL_TUESDAY
);
838 c
->set(UCAL_WEEK_OF_YEAR
, 1);
839 verify765("1997 Tuesday in week 1 of yearWOY = ", c
, 1996, UCAL_DECEMBER
, 31);
840 c
->clear(); // - add test for YEAR
841 c
->setMinimalDaysInFirstWeek(1);
842 c
->set(UCAL_YEAR
, 1997);
843 c
->set(UCAL_DAY_OF_WEEK
, UCAL_TUESDAY
);
844 c
->set(UCAL_WEEK_OF_YEAR
, 1);
845 verify765("1997 Tuesday in week 1 of year = ", c
, 1997, UCAL_DECEMBER
, 30);
847 c
->set(UCAL_YEAR
, 1997);
848 c
->set(UCAL_DAY_OF_WEEK
, UCAL_TUESDAY
);
849 c
->set(UCAL_WEEK_OF_YEAR
, 10);
850 verify765("1997 Tuesday in week 10 of year = ", c
, 1997, UCAL_MARCH
, 4);
853 // {sfb} week 0 is no longer a valid week of year
855 c->set(Calendar::YEAR, 1997);
856 c->set(Calendar::DAY_OF_WEEK, Calendar::TUESDAY);
857 //c->set(Calendar::WEEK_OF_YEAR, 0);
858 c->set(Calendar::WEEK_OF_YEAR, 1);
859 verify765("1997 Tuesday in week 0 of year = ", c, 1996, Calendar::DECEMBER, 24);*/
862 //catch(IllegalArgumentException ex) {
863 // errln("FAIL: Exception seen:");
864 // ex.printStackTrace(log);
869 // -------------------------------------
872 CalendarTest::verify765(const UnicodeString
& msg
, Calendar
* c
, int32_t year
, int32_t month
, int32_t day
)
875 UErrorCode status
= U_ZERO_ERROR
;
876 int32_t y
= c
->get(UCAL_YEAR
, status
);
877 int32_t m
= c
->get(UCAL_MONTH
, status
);
878 int32_t d
= c
->get(UCAL_DATE
, status
);
882 if (U_FAILURE(status
)) { errln("FAIL: Calendar::get failed"); return; }
883 logln("PASS: " + msg
+ dateToString(c
->getTime(status
), str
));
884 if (U_FAILURE(status
)) { errln("Calendar::getTime failed"); return; }
887 errln("FAIL: " + msg
+ dateToString(c
->getTime(status
), str
) + "; expected " + (int32_t)year
+ "/" + (int32_t)(month
+ 1) + "/" + (int32_t)day
+
888 "; got " + (int32_t)y
+ "/" + (int32_t)(m
+ 1) + "/" + (int32_t)d
+ " for Locale: " + c
->getLocaleID(ULOC_ACTUAL_LOCALE
,status
));
889 if (U_FAILURE(status
)) { errln("Calendar::getTime failed"); return; }
893 // -------------------------------------
896 CalendarTest::verify765(const UnicodeString
& msg
/*, IllegalArgumentException e*/, UErrorCode status
)
898 if (status
!= U_ILLEGAL_ARGUMENT_ERROR
) errln("FAIL: No IllegalArgumentException for " + msg
);
899 else logln("PASS: " + msg
+ "IllegalArgument as expected");
902 // -------------------------------------
905 * Confirm that the offset between local time and GMT behaves as expected.
908 CalendarTest::TestGMTvsLocal4064654()
910 test4064654(1997, 1, 1, 12, 0, 0);
911 test4064654(1997, 4, 16, 18, 30, 0);
914 // -------------------------------------
917 CalendarTest::test4064654(int32_t yr
, int32_t mo
, int32_t dt
, int32_t hr
, int32_t mn
, int32_t sc
)
920 UErrorCode status
= U_ZERO_ERROR
;
922 Calendar
*gmtcal
= Calendar::createInstance(status
);
923 if (failure(status
, "Calendar::createInstance", TRUE
)) return;
924 gmtcal
->adoptTimeZone(TimeZone::createTimeZone("Africa/Casablanca"));
925 gmtcal
->set(yr
, mo
- 1, dt
, hr
, mn
, sc
);
926 gmtcal
->set(UCAL_MILLISECOND
, 0);
927 date
= gmtcal
->getTime(status
);
928 if (U_FAILURE(status
)) { errln("Calendar::getTime failed"); return; }
929 logln("date = " + dateToString(date
, str
));
930 Calendar
*cal
= Calendar::createInstance(status
);
931 if (U_FAILURE(status
)) { errln("Calendar::createInstance failed"); return; }
932 cal
->setTime(date
, status
);
933 if (U_FAILURE(status
)) { errln("Calendar::setTime failed"); return; }
934 int32_t offset
= cal
->getTimeZone().getOffset((uint8_t)cal
->get(UCAL_ERA
, status
),
935 cal
->get(UCAL_YEAR
, status
),
936 cal
->get(UCAL_MONTH
, status
),
937 cal
->get(UCAL_DATE
, status
),
938 (uint8_t)cal
->get(UCAL_DAY_OF_WEEK
, status
),
939 cal
->get(UCAL_MILLISECOND
, status
), status
);
940 if (U_FAILURE(status
)) { errln("Calendar::get failed"); return; }
941 logln("offset for " + dateToString(date
, str
) + "= " + (offset
/ 1000 / 60 / 60.0) + "hr");
942 int32_t utc
= ((cal
->get(UCAL_HOUR_OF_DAY
, status
) * 60 +
943 cal
->get(UCAL_MINUTE
, status
)) * 60 +
944 cal
->get(UCAL_SECOND
, status
)) * 1000 +
945 cal
->get(UCAL_MILLISECOND
, status
) - offset
;
946 if (U_FAILURE(status
)) { errln("Calendar::get failed"); return; }
947 int32_t expected
= ((hr
* 60 + mn
) * 60 + sc
) * 1000;
948 if (utc
!= expected
) errln(UnicodeString("FAIL: Discrepancy of ") + (utc
- expected
) +
949 " millis = " + ((utc
- expected
) / 1000 / 60 / 60.0) + " hr");
954 // -------------------------------------
957 * The operations of adding and setting should not exhibit pathological
958 * dependence on the order of operations. This test checks for this.
961 CalendarTest::TestAddSetOrder621()
963 UDate d
= date(97, 4, 14, 13, 23, 45);
964 UErrorCode status
= U_ZERO_ERROR
;
965 Calendar
*cal
= Calendar::createInstance(status
);
966 if (failure(status
, "Calendar::createInstance", TRUE
)) return;
968 cal
->setTime(d
, status
);
969 if (U_FAILURE(status
)) {
970 errln("Calendar::setTime failed");
974 cal
->add(UCAL_DATE
, - 5, status
);
975 if (U_FAILURE(status
)) {
976 errln("Calendar::add failed");
980 cal
->set(UCAL_HOUR_OF_DAY
, 0);
981 cal
->set(UCAL_MINUTE
, 0);
982 cal
->set(UCAL_SECOND
, 0);
984 dateToString(cal
->getTime(status
), s
);
985 if (U_FAILURE(status
)) {
986 errln("Calendar::getTime failed");
992 cal
= Calendar::createInstance(status
);
993 if (U_FAILURE(status
)) {
994 errln("Calendar::createInstance failed");
998 cal
->setTime(d
, status
);
999 if (U_FAILURE(status
)) {
1000 errln("Calendar::setTime failed");
1004 cal
->set(UCAL_HOUR_OF_DAY
, 0);
1005 cal
->set(UCAL_MINUTE
, 0);
1006 cal
->set(UCAL_SECOND
, 0);
1007 cal
->add(UCAL_DATE
, - 5, status
);
1008 if (U_FAILURE(status
)) {
1009 errln("Calendar::add failed");
1014 dateToString(cal
->getTime(status
), s2
);
1015 if (U_FAILURE(status
)) {
1016 errln("Calendar::getTime failed");
1021 logln("Pass: " + s
+ " == " + s2
);
1023 errln("FAIL: " + s
+ " != " + s2
);
1027 // -------------------------------------
1030 * Confirm that adding to various fields works.
1033 CalendarTest::TestAdd520()
1035 int32_t y
= 1997, m
= UCAL_FEBRUARY
, d
= 1;
1036 UErrorCode status
= U_ZERO_ERROR
;
1037 GregorianCalendar
*temp
= new GregorianCalendar(y
, m
, d
, status
);
1038 if (failure(status
, "new GregorianCalendar", TRUE
)) return;
1039 check520(temp
, y
, m
, d
);
1040 temp
->add(UCAL_YEAR
, 1, status
);
1041 if (U_FAILURE(status
)) { errln("Calendar::add failed"); return; }
1043 check520(temp
, y
, m
, d
);
1044 temp
->add(UCAL_MONTH
, 1, status
);
1045 if (U_FAILURE(status
)) { errln("Calendar::add failed"); return; }
1047 check520(temp
, y
, m
, d
);
1048 temp
->add(UCAL_DATE
, 1, status
);
1049 if (U_FAILURE(status
)) { errln("Calendar::add failed"); return; }
1051 check520(temp
, y
, m
, d
);
1052 temp
->add(UCAL_DATE
, 2, status
);
1053 if (U_FAILURE(status
)) { errln("Calendar::add failed"); return; }
1055 check520(temp
, y
, m
, d
);
1056 temp
->add(UCAL_DATE
, 28, status
);
1057 if (U_FAILURE(status
)) { errln("Calendar::add failed"); return; }
1059 check520(temp
, y
, m
, d
);
1063 // -------------------------------------
1066 * Execute adding and rolling in GregorianCalendar extensively,
1069 CalendarTest::TestAddRollExtensive()
1071 int32_t maxlimit
= 40;
1072 int32_t y
= 1997, m
= UCAL_FEBRUARY
, d
= 1, hr
= 1, min
= 1, sec
= 0, ms
= 0;
1073 UErrorCode status
= U_ZERO_ERROR
;
1074 GregorianCalendar
*temp
= new GregorianCalendar(y
, m
, d
, status
);
1075 if (failure(status
, "new GregorianCalendar", TRUE
)) return;
1077 temp
->set(UCAL_HOUR
, hr
);
1078 temp
->set(UCAL_MINUTE
, min
);
1079 temp
->set(UCAL_SECOND
, sec
);
1080 temp
->set(UCAL_MILLISECOND
, ms
);
1081 temp
->setMinimalDaysInFirstWeek(1);
1083 UCalendarDateFields e
;
1085 logln("Testing GregorianCalendar add...");
1087 while (e
< UCAL_FIELD_COUNT
) {
1089 int32_t limit
= maxlimit
;
1090 status
= U_ZERO_ERROR
;
1091 for (i
= 0; i
< limit
; i
++) {
1092 temp
->add(e
, 1, status
);
1093 if (U_FAILURE(status
)) { limit
= i
; status
= U_ZERO_ERROR
; }
1095 for (i
= 0; i
< limit
; i
++) {
1096 temp
->add(e
, -1, status
);
1097 if (U_FAILURE(status
)) { errln("GregorianCalendar::add -1 failed"); return; }
1099 check520(temp
, y
, m
, d
, hr
, min
, sec
, ms
, e
);
1101 e
= (UCalendarDateFields
) ((int32_t) e
+ 1);
1104 logln("Testing GregorianCalendar roll...");
1106 while (e
< UCAL_FIELD_COUNT
) {
1108 int32_t limit
= maxlimit
;
1109 status
= U_ZERO_ERROR
;
1110 for (i
= 0; i
< limit
; i
++) {
1111 logln(calToStr(*temp
) + UnicodeString(" " ) + fieldName(e
) + UnicodeString("++") );
1112 temp
->roll(e
, 1, status
);
1113 if (U_FAILURE(status
)) {
1114 logln("caltest.cpp:%d e=%d, i=%d - roll(+) err %s\n", __LINE__
, (int) e
, (int) i
, u_errorName(status
));
1115 logln(calToStr(*temp
));
1116 limit
= i
; status
= U_ZERO_ERROR
;
1119 for (i
= 0; i
< limit
; i
++) {
1120 logln("caltest.cpp:%d e=%d, i=%d\n", __LINE__
, (int) e
, (int) i
);
1121 logln(calToStr(*temp
) + UnicodeString(" " ) + fieldName(e
) + UnicodeString("--") );
1122 temp
->roll(e
, -1, status
);
1123 if (U_FAILURE(status
)) { errln(UnicodeString("GregorianCalendar::roll ") + CalendarTest::fieldName(e
) + " count=" + UnicodeString('@'+i
) + " by -1 failed with " + u_errorName(status
) ); return; }
1125 check520(temp
, y
, m
, d
, hr
, min
, sec
, ms
, e
);
1127 e
= (UCalendarDateFields
) ((int32_t) e
+ 1);
1133 // -------------------------------------
1135 CalendarTest::check520(Calendar
* c
,
1136 int32_t y
, int32_t m
, int32_t d
,
1137 int32_t hr
, int32_t min
, int32_t sec
,
1138 int32_t ms
, UCalendarDateFields field
)
1141 UErrorCode status
= U_ZERO_ERROR
;
1142 if (c
->get(UCAL_YEAR
, status
) != y
||
1143 c
->get(UCAL_MONTH
, status
) != m
||
1144 c
->get(UCAL_DATE
, status
) != d
||
1145 c
->get(UCAL_HOUR
, status
) != hr
||
1146 c
->get(UCAL_MINUTE
, status
) != min
||
1147 c
->get(UCAL_SECOND
, status
) != sec
||
1148 c
->get(UCAL_MILLISECOND
, status
) != ms
) {
1149 errln(UnicodeString("U_FAILURE for field ") + (int32_t)field
+
1150 ": Expected y/m/d h:m:s:ms of " +
1151 y
+ "/" + (m
+ 1) + "/" + d
+ " " +
1152 hr
+ ":" + min
+ ":" + sec
+ ":" + ms
+
1153 "; got " + c
->get(UCAL_YEAR
, status
) +
1154 "/" + (c
->get(UCAL_MONTH
, status
) + 1) +
1155 "/" + c
->get(UCAL_DATE
, status
) +
1156 " " + c
->get(UCAL_HOUR
, status
) + ":" +
1157 c
->get(UCAL_MINUTE
, status
) + ":" +
1158 c
->get(UCAL_SECOND
, status
) + ":" +
1159 c
->get(UCAL_MILLISECOND
, status
)
1162 if (U_FAILURE(status
)) { errln("Calendar::get failed"); return; }
1165 logln(UnicodeString("Confirmed: ") + y
+ "/" +
1166 (m
+ 1) + "/" + d
+ " " +
1167 hr
+ ":" + min
+ ":" + sec
+ ":" + ms
);
1170 // -------------------------------------
1172 CalendarTest::check520(Calendar
* c
,
1173 int32_t y
, int32_t m
, int32_t d
)
1176 UErrorCode status
= U_ZERO_ERROR
;
1177 if (c
->get(UCAL_YEAR
, status
) != y
||
1178 c
->get(UCAL_MONTH
, status
) != m
||
1179 c
->get(UCAL_DATE
, status
) != d
) {
1180 errln(UnicodeString("FAILURE: Expected y/m/d of ") +
1181 y
+ "/" + (m
+ 1) + "/" + d
+ " " +
1182 "; got " + c
->get(UCAL_YEAR
, status
) +
1183 "/" + (c
->get(UCAL_MONTH
, status
) + 1) +
1184 "/" + c
->get(UCAL_DATE
, status
)
1187 if (U_FAILURE(status
)) { errln("Calendar::get failed"); return; }
1190 logln(UnicodeString("Confirmed: ") + y
+ "/" +
1194 // -------------------------------------
1197 * Test that setting of fields works. In particular, make sure that all instances
1198 * of GregorianCalendar don't share a static instance of the fields array.
1201 CalendarTest::TestFieldSet4781()
1204 UErrorCode status
= U_ZERO_ERROR
;
1205 GregorianCalendar
*g
= new GregorianCalendar(status
);
1206 if (failure(status
, "new GregorianCalendar", TRUE
)) return;
1207 GregorianCalendar
*g2
= new GregorianCalendar(status
);
1208 if (U_FAILURE(status
)) { errln("Couldn't create GregorianCalendar"); return; }
1209 g2
->set(UCAL_HOUR
, 12, status
);
1210 g2
->set(UCAL_MINUTE
, 0, status
);
1211 g2
->set(UCAL_SECOND
, 0, status
);
1212 if (U_FAILURE(status
)) { errln("Calendar::set failed"); return; }
1213 if (*g
== *g2
) logln("Same");
1214 else logln("Different");
1216 //catch(IllegalArgumentException e) {
1217 //errln("Unexpected exception seen: " + e);
1223 // -------------------------------------
1225 /* We don't support serialization on C++
1227 CalendarTest::TestSerialize337()
1229 Calendar cal = Calendar::getInstance();
1232 FileOutputStream f = new FileOutputStream(FILENAME);
1233 ObjectOutput s = new ObjectOutputStream(f);
1234 s.writeObject(PREFIX);
1236 s.writeObject(POSTFIX);
1238 FileInputStream in = new FileInputStream(FILENAME);
1239 ObjectInputStream t = new ObjectInputStream(in);
1240 UnicodeString& pre = (UnicodeString&) t.readObject();
1241 Calendar c = (Calendar) t.readObject();
1242 UnicodeString& post = (UnicodeString&) t.readObject();
1244 ok = pre.equals(PREFIX) &&
1245 post.equals(POSTFIX) &&
1247 File fl = new File(FILENAME);
1250 catch(IOException e) {
1251 errln("FAIL: Exception received:");
1252 e.printStackTrace(log);
1254 catch(ClassNotFoundException e) {
1255 errln("FAIL: Exception received:");
1256 e.printStackTrace(log);
1258 if (!ok) errln("Serialization of Calendar object failed.");
1261 UnicodeString& CalendarTest::PREFIX = "abc";
1263 UnicodeString& CalendarTest::POSTFIX = "def";
1265 UnicodeString& CalendarTest::FILENAME = "tmp337.bin";
1268 // -------------------------------------
1271 * Verify that the seconds of a Calendar can be zeroed out through the
1272 * expected sequence of operations.
1275 CalendarTest::TestSecondsZero121()
1277 UErrorCode status
= U_ZERO_ERROR
;
1278 Calendar
*cal
= new GregorianCalendar(status
);
1279 if (failure(status
, "new GregorianCalendar", TRUE
)) return;
1280 cal
->setTime(Calendar::getNow(), status
);
1281 if (U_FAILURE(status
)) { errln("Calendar::setTime failed"); return; }
1282 cal
->set(UCAL_SECOND
, 0);
1283 if (U_FAILURE(status
)) { errln("Calendar::set failed"); return; }
1284 UDate d
= cal
->getTime(status
);
1285 if (U_FAILURE(status
)) { errln("Calendar::getTime failed"); return; }
1288 if (s
.indexOf("DATE_FORMAT_FAILURE") >= 0) {
1289 dataerrln("Got: \"DATE_FORMAT_FAILURE\".");
1290 } else if (s
.indexOf(":00 ") < 0) {
1291 errln("Expected to see :00 in " + s
);
1296 // -------------------------------------
1299 * Verify that a specific sequence of adding and setting works as expected;
1300 * it should not vary depending on when and whether the get method is
1304 CalendarTest::TestAddSetGet0610()
1306 UnicodeString
EXPECTED_0610("1993/0/5", "");
1307 UErrorCode status
= U_ZERO_ERROR
;
1309 Calendar
*calendar
= new GregorianCalendar(status
);
1310 if (failure(status
, "new GregorianCalendar", TRUE
)) return;
1311 calendar
->set(1993, UCAL_JANUARY
, 4);
1312 logln("1A) " + value(calendar
));
1313 calendar
->add(UCAL_DATE
, 1, status
);
1314 if (U_FAILURE(status
)) { errln("Calendar::add failed"); return; }
1315 UnicodeString v
= value(calendar
);
1317 logln("--) 1993/0/5");
1318 if (!(v
== EXPECTED_0610
)) errln("Expected " + EXPECTED_0610
+ "; saw " + v
);
1322 Calendar
*calendar
= new GregorianCalendar(1993, UCAL_JANUARY
, 4, status
);
1323 if (U_FAILURE(status
)) { errln("Couldn't create GregorianCalendar"); return; }
1324 logln("2A) " + value(calendar
));
1325 calendar
->add(UCAL_DATE
, 1, status
);
1326 if (U_FAILURE(status
)) { errln("Calendar::add failed"); return; }
1327 UnicodeString v
= value(calendar
);
1329 logln("--) 1993/0/5");
1330 if (!(v
== EXPECTED_0610
)) errln("Expected " + EXPECTED_0610
+ "; saw " + v
);
1334 Calendar
*calendar
= new GregorianCalendar(1993, UCAL_JANUARY
, 4, status
);
1335 if (U_FAILURE(status
)) { errln("Couldn't create GregorianCalendar"); return; }
1336 logln("3A) " + value(calendar
));
1337 calendar
->getTime(status
);
1338 if (U_FAILURE(status
)) { errln("Calendar::getTime failed"); return; }
1339 calendar
->add(UCAL_DATE
, 1, status
);
1340 if (U_FAILURE(status
)) { errln("Calendar::add failed"); return; }
1341 UnicodeString v
= value(calendar
);
1343 logln("--) 1993/0/5");
1344 if (!(v
== EXPECTED_0610
)) errln("Expected " + EXPECTED_0610
+ "; saw " + v
);
1349 // -------------------------------------
1352 CalendarTest::value(Calendar
* calendar
)
1354 UErrorCode status
= U_ZERO_ERROR
;
1355 return UnicodeString("") + (int32_t)calendar
->get(UCAL_YEAR
, status
) +
1356 "/" + (int32_t)calendar
->get(UCAL_MONTH
, status
) +
1357 "/" + (int32_t)calendar
->get(UCAL_DATE
, status
) +
1358 (U_FAILURE(status
) ? " FAIL: Calendar::get failed" : "");
1362 // -------------------------------------
1365 * Verify that various fields on a known date are set correctly.
1368 CalendarTest::TestFields060()
1370 UErrorCode status
= U_ZERO_ERROR
;
1371 int32_t year
= 1997;
1372 int32_t month
= UCAL_OCTOBER
;
1374 GregorianCalendar
*calendar
= 0;
1375 calendar
= new GregorianCalendar(year
, month
, dDate
, status
);
1376 if (failure(status
, "new GregorianCalendar", TRUE
)) return;
1377 for (int32_t i
= 0; i
< EXPECTED_FIELDS_length
;) {
1378 UCalendarDateFields field
= (UCalendarDateFields
)EXPECTED_FIELDS
[i
++];
1379 int32_t expected
= EXPECTED_FIELDS
[i
++];
1380 if (calendar
->get(field
, status
) != expected
) {
1381 errln(UnicodeString("Expected field ") + (int32_t)field
+ " to have value " + (int32_t)expected
+
1382 "; received " + (int32_t)calendar
->get(field
, status
) + " instead");
1383 if (U_FAILURE(status
)) { errln("Calendar::get failed"); return; }
1389 int32_t CalendarTest::EXPECTED_FIELDS
[] = {
1391 UCAL_MONTH
, UCAL_OCTOBER
,
1393 UCAL_DAY_OF_WEEK
, UCAL_WEDNESDAY
,
1394 UCAL_DAY_OF_WEEK_IN_MONTH
, 4,
1395 UCAL_DAY_OF_YEAR
, 295
1398 const int32_t CalendarTest::EXPECTED_FIELDS_length
= (int32_t)(sizeof(CalendarTest::EXPECTED_FIELDS
) /
1399 sizeof(CalendarTest::EXPECTED_FIELDS
[0]));
1401 // -------------------------------------
1404 * Verify that various fields on a known date are set correctly. In this
1405 * case, the start of the epoch (January 1 1970).
1408 CalendarTest::TestEpochStartFields()
1410 UErrorCode status
= U_ZERO_ERROR
;
1411 TimeZone
*z
= TimeZone::createDefault();
1412 Calendar
*c
= Calendar::createInstance(status
);
1413 if (failure(status
, "Calendar::createInstance", TRUE
)) return;
1414 UDate d
= - z
->getRawOffset();
1415 GregorianCalendar
*gc
= new GregorianCalendar(status
);
1416 if (U_FAILURE(status
)) { errln("Couldn't create GregorianCalendar"); return; }
1417 gc
->setTimeZone(*z
);
1418 gc
->setTime(d
, status
);
1419 if (U_FAILURE(status
)) { errln("Calendar::setTime failed"); return; }
1420 UBool idt
= gc
->inDaylightTime(status
);
1421 if (U_FAILURE(status
)) { errln("GregorianCalendar::inDaylightTime failed"); return; }
1424 logln("Warning: Skipping test because " + dateToString(d
, str
) + " is in DST.");
1427 c
->setTime(d
, status
);
1428 if (U_FAILURE(status
)) { errln("Calendar::setTime failed"); return; }
1429 for (int32_t i
= 0; i
< UCAL_ZONE_OFFSET
;++i
) {
1430 if (c
->get((UCalendarDateFields
)i
, status
) != EPOCH_FIELDS
[i
])
1431 dataerrln(UnicodeString("Expected field ") + i
+ " to have value " + EPOCH_FIELDS
[i
] +
1432 "; saw " + c
->get((UCalendarDateFields
)i
, status
) + " instead");
1433 if (U_FAILURE(status
)) { errln("Calendar::get failed"); return; }
1435 if (c
->get(UCAL_ZONE_OFFSET
, status
) != z
->getRawOffset())
1437 errln(UnicodeString("Expected field ZONE_OFFSET to have value ") + z
->getRawOffset() +
1438 "; saw " + c
->get(UCAL_ZONE_OFFSET
, status
) + " instead");
1439 if (U_FAILURE(status
)) { errln("Calendar::get failed"); return; }
1441 if (c
->get(UCAL_DST_OFFSET
, status
) != 0)
1443 errln(UnicodeString("Expected field DST_OFFSET to have value 0") +
1444 "; saw " + c
->get(UCAL_DST_OFFSET
, status
) + " instead");
1445 if (U_FAILURE(status
)) { errln("Calendar::get failed"); return; }
1453 int32_t CalendarTest::EPOCH_FIELDS
[] = {
1454 1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, - 28800000, 0
1457 // -------------------------------------
1460 * Test that the days of the week progress properly when add is called repeatedly
1461 * for increments of 24 days.
1464 CalendarTest::TestDOWProgression()
1466 UErrorCode status
= U_ZERO_ERROR
;
1467 Calendar
*cal
= new GregorianCalendar(1972, UCAL_OCTOBER
, 26, status
);
1468 if (failure(status
, "new GregorianCalendar", TRUE
)) return;
1469 marchByDelta(cal
, 24);
1473 // -------------------------------------
1476 CalendarTest::TestDOW_LOCALandYEAR_WOY()
1478 /* Note: I've commented out the loop_addroll tests for YEAR and
1479 * YEAR_WOY below because these two fields should NOT behave
1480 * identically when adding. YEAR should keep the month/dom
1481 * invariant. YEAR_WOY should keep the woy/dow invariant. I've
1482 * added a new test that checks for this in place of the old call
1483 * to loop_addroll. - aliu */
1484 UErrorCode status
= U_ZERO_ERROR
;
1486 Calendar
*cal
=Calendar::createInstance(Locale::getGermany(), status
);
1487 if (failure(status
, "Calendar::createInstance", TRUE
)) return;
1488 SimpleDateFormat
*sdf
=new SimpleDateFormat(UnicodeString("YYYY'-W'ww-ee"), Locale::getGermany(), status
);
1489 if (U_FAILURE(status
)) { dataerrln("Couldn't create SimpleDateFormat - %s", u_errorName(status
)); return; }
1491 // ICU no longer use localized date-time pattern characters by default.
1492 // So we set pattern chars using 'J' instead of 'Y'.
1493 DateFormatSymbols
*dfs
= new DateFormatSymbols(Locale::getGermany(), status
);
1494 dfs
->setLocalPatternChars(UnicodeString("GyMdkHmsSEDFwWahKzJeugAZvcLQq"));
1495 sdf
->adoptDateFormatSymbols(dfs
);
1496 sdf
->applyLocalizedPattern(UnicodeString("JJJJ'-W'ww-ee"), status
);
1497 if (U_FAILURE(status
)) { errln("Couldn't apply localized pattern"); return; }
1500 cal
->set(1997, UCAL_DECEMBER
, 25);
1501 doYEAR_WOYLoop(cal
, sdf
, times
, status
);
1502 //loop_addroll(cal, /*sdf,*/ times, UCAL_YEAR_WOY, UCAL_YEAR, status);
1503 yearAddTest(*cal
, status
); // aliu
1504 loop_addroll(cal
, /*sdf,*/ times
, UCAL_DOW_LOCAL
, UCAL_DAY_OF_WEEK
, status
);
1505 if (U_FAILURE(status
)) { errln("Error in parse/calculate test for 1997"); return; }
1508 cal
->set(1998, UCAL_DECEMBER
, 25);
1509 doYEAR_WOYLoop(cal
, sdf
, times
, status
);
1510 //loop_addroll(cal, /*sdf,*/ times, UCAL_YEAR_WOY, UCAL_YEAR, status);
1511 yearAddTest(*cal
, status
); // aliu
1512 loop_addroll(cal
, /*sdf,*/ times
, UCAL_DOW_LOCAL
, UCAL_DAY_OF_WEEK
, status
);
1513 if (U_FAILURE(status
)) { errln("Error in parse/calculate test for 1998"); return; }
1516 cal
->set(1582, UCAL_OCTOBER
, 1);
1517 doYEAR_WOYLoop(cal
, sdf
, times
, status
);
1518 //loop_addroll(cal, /*sdf,*/ times, Calendar::YEAR_WOY, Calendar::YEAR, status);
1519 yearAddTest(*cal
, status
); // aliu
1520 loop_addroll(cal
, /*sdf,*/ times
, UCAL_DOW_LOCAL
, UCAL_DAY_OF_WEEK
, status
);
1521 if (U_FAILURE(status
)) { errln("Error in parse/calculate test for 1582"); return; }
1529 * Confirm that adding a YEAR and adding a YEAR_WOY work properly for
1530 * the given Calendar at its current setting.
1532 void CalendarTest::yearAddTest(Calendar
& cal
, UErrorCode
& status
) {
1534 * When adding the YEAR, the month and day should remain constant.
1535 * When adding the YEAR_WOY, the WOY and DOW should remain constant. - aliu
1537 * Wed Jan 14 1998 / 1998-W03-03 Add(YEAR_WOY, 1) -> Wed Jan 20 1999 / 1999-W03-03
1538 * Add(YEAR, 1) -> Thu Jan 14 1999 / 1999-W02-04
1539 * Thu Jan 14 1999 / 1999-W02-04 Add(YEAR_WOY, 1) -> Thu Jan 13 2000 / 2000-W02-04
1540 * Add(YEAR, 1) -> Fri Jan 14 2000 / 2000-W02-05
1541 * Sun Oct 31 1582 / 1582-W42-07 Add(YEAR_WOY, 1) -> Sun Oct 23 1583 / 1583-W42-07
1542 * Add(YEAR, 1) -> Mon Oct 31 1583 / 1583-W44-01
1544 int32_t y
= cal
.get(UCAL_YEAR
, status
);
1545 int32_t mon
= cal
.get(UCAL_MONTH
, status
);
1546 int32_t day
= cal
.get(UCAL_DATE
, status
);
1547 int32_t ywy
= cal
.get(UCAL_YEAR_WOY
, status
);
1548 int32_t woy
= cal
.get(UCAL_WEEK_OF_YEAR
, status
);
1549 int32_t dow
= cal
.get(UCAL_DOW_LOCAL
, status
);
1550 UDate t
= cal
.getTime(status
);
1552 if(U_FAILURE(status
)){
1553 errln(UnicodeString("Failed to create Calendar for locale. Error: ") + UnicodeString(u_errorName(status
)));
1556 UnicodeString str
, str2
;
1557 SimpleDateFormat
fmt(UnicodeString("EEE MMM dd yyyy / YYYY'-W'ww-ee"), status
);
1558 fmt
.setCalendar(cal
);
1560 fmt
.format(t
, str
.remove());
1561 str
+= ".add(YEAR, 1) =>";
1562 cal
.add(UCAL_YEAR
, 1, status
);
1563 int32_t y2
= cal
.get(UCAL_YEAR
, status
);
1564 int32_t mon2
= cal
.get(UCAL_MONTH
, status
);
1565 int32_t day2
= cal
.get(UCAL_DATE
, status
);
1566 fmt
.format(cal
.getTime(status
), str
);
1567 if (y2
!= (y
+1) || mon2
!= mon
|| day2
!= day
) {
1568 str
+= (UnicodeString
)", expected year " +
1569 (y
+1) + ", month " + (mon
+1) + ", day " + day
;
1570 errln((UnicodeString
)"FAIL: " + str
);
1571 logln( UnicodeString(" -> ") + CalendarTest::calToStr(cal
) );
1576 fmt
.format(t
, str
.remove());
1577 str
+= ".add(YEAR_WOY, 1)=>";
1578 cal
.setTime(t
, status
);
1579 logln( UnicodeString(" <- ") + CalendarTest::calToStr(cal
) );
1580 cal
.add(UCAL_YEAR_WOY
, 1, status
);
1581 int32_t ywy2
= cal
.get(UCAL_YEAR_WOY
, status
);
1582 int32_t woy2
= cal
.get(UCAL_WEEK_OF_YEAR
, status
);
1583 int32_t dow2
= cal
.get(UCAL_DOW_LOCAL
, status
);
1584 fmt
.format(cal
.getTime(status
), str
);
1585 if (ywy2
!= (ywy
+1) || woy2
!= woy
|| dow2
!= dow
) {
1586 str
+= (UnicodeString
)", expected yearWOY " +
1587 (ywy
+1) + ", woy " + woy
+ ", dowLocal " + dow
;
1588 errln((UnicodeString
)"FAIL: " + str
);
1589 logln( UnicodeString(" -> ") + CalendarTest::calToStr(cal
) );
1595 // -------------------------------------
1597 void CalendarTest::loop_addroll(Calendar
*cal
, /*SimpleDateFormat *sdf,*/ int times
, UCalendarDateFields field
, UCalendarDateFields field2
, UErrorCode
& errorCode
) {
1599 SimpleDateFormat
fmt(UnicodeString("EEE MMM dd yyyy / YYYY'-W'ww-ee"), errorCode
);
1600 fmt
.setCalendar(*cal
);
1603 for(i
= 0; i
<times
; i
++) {
1604 calclone
= cal
->clone();
1605 UDate start
= cal
->getTime(errorCode
);
1606 cal
->add(field
,1,errorCode
);
1607 if (U_FAILURE(errorCode
)) { errln("Error in add"); delete calclone
; return; }
1608 calclone
->add(field2
,1,errorCode
);
1609 if (U_FAILURE(errorCode
)) { errln("Error in add"); delete calclone
; return; }
1610 if(cal
->getTime(errorCode
) != calclone
->getTime(errorCode
)) {
1611 UnicodeString
str("FAIL: Results of add differ. "), str2
;
1612 str
+= fmt
.format(start
, str2
) + " ";
1613 str
+= UnicodeString("Add(") + fieldName(field
) + ", 1) -> " +
1614 fmt
.format(cal
->getTime(errorCode
), str2
.remove()) + "; ";
1615 str
+= UnicodeString("Add(") + fieldName(field2
) + ", 1) -> " +
1616 fmt
.format(calclone
->getTime(errorCode
), str2
.remove());
1624 for(i
= 0; i
<times
; i
++) {
1625 calclone
= cal
->clone();
1626 cal
->roll(field
,(int32_t)1,errorCode
);
1627 if (U_FAILURE(errorCode
)) { errln("Error in roll"); delete calclone
; return; }
1628 calclone
->roll(field2
,(int32_t)1,errorCode
);
1629 if (U_FAILURE(errorCode
)) { errln("Error in roll"); delete calclone
; return; }
1630 if(cal
->getTime(errorCode
) != calclone
->getTime(errorCode
)) {
1632 errln("Results of roll differ!");
1639 // -------------------------------------
1642 CalendarTest::doYEAR_WOYLoop(Calendar
*cal
, SimpleDateFormat
*sdf
,
1643 int32_t times
, UErrorCode
& errorCode
) {
1646 UDate tst
, original
;
1647 Calendar
*tstres
= new GregorianCalendar(Locale::getGermany(), errorCode
);
1648 for(int i
=0; i
<times
; ++i
) {
1649 sdf
->format(Formattable(cal
->getTime(errorCode
),Formattable::kIsDate
), us
, errorCode
);
1650 //logln("expected: "+us);
1651 if (U_FAILURE(errorCode
)) { errln("Format error"); return; }
1652 tst
=sdf
->parse(us
,errorCode
);
1653 if (U_FAILURE(errorCode
)) { errln("Parse error"); return; }
1655 tstres
->setTime(tst
, errorCode
);
1656 //logln((UnicodeString)"Parsed week of year is "+tstres->get(UCAL_WEEK_OF_YEAR, errorCode));
1657 if (U_FAILURE(errorCode
)) { errln("Set time error"); return; }
1658 original
= cal
->getTime(errorCode
);
1660 sdf
->format(Formattable(tst
,Formattable::kIsDate
), us
, errorCode
);
1661 //logln("got: "+us);
1662 if (U_FAILURE(errorCode
)) { errln("Get time error"); return; }
1665 sdf
->format(Formattable(original
, Formattable::kIsDate
), us
, errorCode
);
1666 errln("FAIL: Parsed time doesn't match with regular");
1667 logln("expected "+us
+ " " + calToStr(*cal
));
1669 sdf
->format(Formattable(tst
, Formattable::kIsDate
), us
, errorCode
);
1670 logln("got "+us
+ " " + calToStr(*tstres
));
1673 tstres
->set(UCAL_YEAR_WOY
, cal
->get(UCAL_YEAR_WOY
, errorCode
));
1674 tstres
->set(UCAL_WEEK_OF_YEAR
, cal
->get(UCAL_WEEK_OF_YEAR
, errorCode
));
1675 tstres
->set(UCAL_DOW_LOCAL
, cal
->get(UCAL_DOW_LOCAL
, errorCode
));
1676 if(cal
->get(UCAL_YEAR
, errorCode
) != tstres
->get(UCAL_YEAR
, errorCode
)) {
1677 errln("FAIL: Different Year!");
1678 logln((UnicodeString
)"Expected "+cal
->get(UCAL_YEAR
, errorCode
));
1679 logln((UnicodeString
)"Got "+tstres
->get(UCAL_YEAR
, errorCode
));
1682 if(cal
->get(UCAL_DAY_OF_YEAR
, errorCode
) != tstres
->get(UCAL_DAY_OF_YEAR
, errorCode
)) {
1683 errln("FAIL: Different Day Of Year!");
1684 logln((UnicodeString
)"Expected "+cal
->get(UCAL_DAY_OF_YEAR
, errorCode
));
1685 logln((UnicodeString
)"Got "+tstres
->get(UCAL_DAY_OF_YEAR
, errorCode
));
1688 //logln(calToStr(*cal));
1689 cal
->add(UCAL_DATE
, 1, errorCode
);
1690 if (U_FAILURE(errorCode
)) { errln("Add error"); return; }
1695 // -------------------------------------
1698 CalendarTest::marchByDelta(Calendar
* cal
, int32_t delta
)
1700 UErrorCode status
= U_ZERO_ERROR
;
1701 Calendar
*cur
= (Calendar
*) cal
->clone();
1702 int32_t initialDOW
= cur
->get(UCAL_DAY_OF_WEEK
, status
);
1703 if (U_FAILURE(status
)) { errln("Calendar::get failed"); return; }
1704 int32_t DOW
, newDOW
= initialDOW
;
1708 logln(UnicodeString("DOW = ") + DOW
+ " " + dateToString(cur
->getTime(status
), str
));
1709 if (U_FAILURE(status
)) { errln("Calendar::getTime failed"); return; }
1710 cur
->add(UCAL_DAY_OF_WEEK
, delta
, status
);
1711 if (U_FAILURE(status
)) { errln("Calendar::add failed"); return; }
1712 newDOW
= cur
->get(UCAL_DAY_OF_WEEK
, status
);
1713 if (U_FAILURE(status
)) { errln("Calendar::get failed"); return; }
1714 int32_t expectedDOW
= 1 + (DOW
+ delta
- 1) % 7;
1715 if (newDOW
!= expectedDOW
) {
1716 errln(UnicodeString("Day of week should be ") + expectedDOW
+ " instead of " + newDOW
+
1717 " on " + dateToString(cur
->getTime(status
), str
));
1718 if (U_FAILURE(status
)) { errln("Calendar::getTime failed"); return; }
1722 while (newDOW
!= initialDOW
);
1726 #define CHECK(status, msg) \
1727 if (U_FAILURE(status)) { \
1728 errcheckln(status, msg); \
1732 void CalendarTest::TestWOY(void) {
1734 FDW = Mon, MDFW = 4:
1735 Sun Dec 26 1999, WOY 51
1736 Mon Dec 27 1999, WOY 52
1737 Tue Dec 28 1999, WOY 52
1738 Wed Dec 29 1999, WOY 52
1739 Thu Dec 30 1999, WOY 52
1740 Fri Dec 31 1999, WOY 52
1741 Sat Jan 01 2000, WOY 52 ***
1742 Sun Jan 02 2000, WOY 52 ***
1743 Mon Jan 03 2000, WOY 1
1744 Tue Jan 04 2000, WOY 1
1745 Wed Jan 05 2000, WOY 1
1746 Thu Jan 06 2000, WOY 1
1747 Fri Jan 07 2000, WOY 1
1748 Sat Jan 08 2000, WOY 1
1749 Sun Jan 09 2000, WOY 1
1750 Mon Jan 10 2000, WOY 2
1752 FDW = Mon, MDFW = 2:
1753 Sun Dec 26 1999, WOY 52
1754 Mon Dec 27 1999, WOY 1 ***
1755 Tue Dec 28 1999, WOY 1 ***
1756 Wed Dec 29 1999, WOY 1 ***
1757 Thu Dec 30 1999, WOY 1 ***
1758 Fri Dec 31 1999, WOY 1 ***
1759 Sat Jan 01 2000, WOY 1
1760 Sun Jan 02 2000, WOY 1
1761 Mon Jan 03 2000, WOY 2
1762 Tue Jan 04 2000, WOY 2
1763 Wed Jan 05 2000, WOY 2
1764 Thu Jan 06 2000, WOY 2
1765 Fri Jan 07 2000, WOY 2
1766 Sat Jan 08 2000, WOY 2
1767 Sun Jan 09 2000, WOY 2
1768 Mon Jan 10 2000, WOY 3
1772 UErrorCode status
= U_ZERO_ERROR
;
1775 GregorianCalendar
cal(status
);
1776 SimpleDateFormat
fmt(UnicodeString("EEE MMM dd yyyy', WOY' w"), status
);
1777 if (failure(status
, "Cannot construct calendar/format", TRUE
)) return;
1779 UCalendarDaysOfWeek fdw
= (UCalendarDaysOfWeek
) 0;
1781 //for (int8_t pass=2; pass<=2; ++pass) {
1782 for (int8_t pass
=1; pass
<=2; ++pass
) {
1786 cal
.setFirstDayOfWeek(fdw
);
1787 cal
.setMinimalDaysInFirstWeek(4);
1788 fmt
.adoptCalendar(cal
.clone());
1792 cal
.setFirstDayOfWeek(fdw
);
1793 cal
.setMinimalDaysInFirstWeek(2);
1794 fmt
.adoptCalendar(cal
.clone());
1798 //for (i=2; i<=6; ++i) {
1799 for (i
=0; i
<16; ++i
) {
1801 int32_t t_y
, t_woy
, t_dow
;
1803 cal
.set(1999, UCAL_DECEMBER
, 26 + i
);
1804 fmt
.format(t
= cal
.getTime(status
), str
.remove());
1805 CHECK(status
, "Fail: getTime failed");
1806 logln(UnicodeString("* ") + str
);
1807 int32_t dow
= cal
.get(UCAL_DAY_OF_WEEK
, status
);
1808 int32_t woy
= cal
.get(UCAL_WEEK_OF_YEAR
, status
);
1809 int32_t year
= cal
.get(UCAL_YEAR
, status
);
1810 int32_t mon
= cal
.get(UCAL_MONTH
, status
);
1811 logln(calToStr(cal
));
1812 CHECK(status
, "Fail: get failed");
1813 int32_t dowLocal
= dow
- fdw
;
1814 if (dowLocal
< 0) dowLocal
+= 7;
1816 int32_t yearWoy
= year
;
1817 if (mon
== UCAL_JANUARY
) {
1818 if (woy
>= 52) --yearWoy
;
1820 if (woy
== 1) ++yearWoy
;
1823 // Basic fields->time check y/woy/dow
1824 // Since Y/WOY is ambiguous, we do a check of the fields,
1825 // not of the specific time.
1827 cal
.set(UCAL_YEAR
, year
);
1828 cal
.set(UCAL_WEEK_OF_YEAR
, woy
);
1829 cal
.set(UCAL_DAY_OF_WEEK
, dow
);
1830 t_y
= cal
.get(UCAL_YEAR
, status
);
1831 t_woy
= cal
.get(UCAL_WEEK_OF_YEAR
, status
);
1832 t_dow
= cal
.get(UCAL_DAY_OF_WEEK
, status
);
1833 CHECK(status
, "Fail: get failed");
1834 if (t_y
!= year
|| t_woy
!= woy
|| t_dow
!= dow
) {
1835 str
= "Fail: y/woy/dow fields->time => ";
1836 fmt
.format(cal
.getTime(status
), str
);
1838 logln(calToStr(cal
));
1839 logln("[get!=set] Y%d!=%d || woy%d!=%d || dow%d!=%d\n",
1840 t_y
, year
, t_woy
, woy
, t_dow
, dow
);
1842 logln("y/woy/dow fields->time OK");
1845 // Basic fields->time check y/woy/dow_local
1846 // Since Y/WOY is ambiguous, we do a check of the fields,
1847 // not of the specific time.
1849 cal
.set(UCAL_YEAR
, year
);
1850 cal
.set(UCAL_WEEK_OF_YEAR
, woy
);
1851 cal
.set(UCAL_DOW_LOCAL
, dowLocal
);
1852 t_y
= cal
.get(UCAL_YEAR
, status
);
1853 t_woy
= cal
.get(UCAL_WEEK_OF_YEAR
, status
);
1854 t_dow
= cal
.get(UCAL_DOW_LOCAL
, status
);
1855 CHECK(status
, "Fail: get failed");
1856 if (t_y
!= year
|| t_woy
!= woy
|| t_dow
!= dowLocal
) {
1857 str
= "Fail: y/woy/dow_local fields->time => ";
1858 fmt
.format(cal
.getTime(status
), str
);
1862 // Basic fields->time check y_woy/woy/dow
1864 cal
.set(UCAL_YEAR_WOY
, yearWoy
);
1865 cal
.set(UCAL_WEEK_OF_YEAR
, woy
);
1866 cal
.set(UCAL_DAY_OF_WEEK
, dow
);
1867 t2
= cal
.getTime(status
);
1868 CHECK(status
, "Fail: getTime failed");
1870 str
= "Fail: y_woy/woy/dow fields->time => ";
1871 fmt
.format(t2
, str
);
1873 logln(calToStr(cal
));
1874 logln("%.f != %.f\n", t
, t2
);
1876 logln("y_woy/woy/dow OK");
1879 // Basic fields->time check y_woy/woy/dow_local
1881 cal
.set(UCAL_YEAR_WOY
, yearWoy
);
1882 cal
.set(UCAL_WEEK_OF_YEAR
, woy
);
1883 cal
.set(UCAL_DOW_LOCAL
, dowLocal
);
1884 t2
= cal
.getTime(status
);
1885 CHECK(status
, "Fail: getTime failed");
1887 str
= "Fail: y_woy/woy/dow_local fields->time => ";
1888 fmt
.format(t2
, str
);
1892 logln("Testing DOW_LOCAL.. dow%d\n", dow
);
1893 // Make sure DOW_LOCAL disambiguates over DOW
1894 int32_t wrongDow
= dow
- 3;
1895 if (wrongDow
< 1) wrongDow
+= 7;
1896 cal
.setTime(t
, status
);
1897 cal
.set(UCAL_DAY_OF_WEEK
, wrongDow
);
1898 cal
.set(UCAL_DOW_LOCAL
, dowLocal
);
1899 t2
= cal
.getTime(status
);
1900 CHECK(status
, "Fail: set/getTime failed");
1902 str
= "Fail: DOW_LOCAL fields->time => ";
1903 fmt
.format(t2
, str
);
1905 logln(calToStr(cal
));
1906 logln("%.f : DOW%d, DOW_LOCAL%d -> %.f\n",
1907 t
, wrongDow
, dowLocal
, t2
);
1910 // Make sure DOW disambiguates over DOW_LOCAL
1911 int32_t wrongDowLocal
= dowLocal
- 3;
1912 if (wrongDowLocal
< 1) wrongDowLocal
+= 7;
1913 cal
.setTime(t
, status
);
1914 cal
.set(UCAL_DOW_LOCAL
, wrongDowLocal
);
1915 cal
.set(UCAL_DAY_OF_WEEK
, dow
);
1916 t2
= cal
.getTime(status
);
1917 CHECK(status
, "Fail: set/getTime failed");
1919 str
= "Fail: DOW fields->time => ";
1920 fmt
.format(t2
, str
);
1924 // Make sure YEAR_WOY disambiguates over YEAR
1925 cal
.setTime(t
, status
);
1926 cal
.set(UCAL_YEAR
, year
- 2);
1927 cal
.set(UCAL_YEAR_WOY
, yearWoy
);
1928 t2
= cal
.getTime(status
);
1929 CHECK(status
, "Fail: set/getTime failed");
1931 str
= "Fail: YEAR_WOY fields->time => ";
1932 fmt
.format(t2
, str
);
1936 // Make sure YEAR disambiguates over YEAR_WOY
1937 cal
.setTime(t
, status
);
1938 cal
.set(UCAL_YEAR_WOY
, yearWoy
- 2);
1939 cal
.set(UCAL_YEAR
, year
);
1940 t2
= cal
.getTime(status
);
1941 CHECK(status
, "Fail: set/getTime failed");
1943 str
= "Fail: YEAR fields->time => ";
1944 fmt
.format(t2
, str
);
1951 FDW = Mon, MDFW = 4:
1952 Sun Dec 26 1999, WOY 51
1953 Mon Dec 27 1999, WOY 52
1954 Tue Dec 28 1999, WOY 52
1955 Wed Dec 29 1999, WOY 52
1956 Thu Dec 30 1999, WOY 52
1957 Fri Dec 31 1999, WOY 52
1958 Sat Jan 01 2000, WOY 52
1959 Sun Jan 02 2000, WOY 52
1962 // Roll the DOW_LOCAL within week 52
1963 for (i
=27; i
<=33; ++i
) {
1965 for (amount
=-7; amount
<=7; ++amount
) {
1967 cal
.set(1999, UCAL_DECEMBER
, i
);
1969 fmt
.format(cal
.getTime(status
), str
);
1970 CHECK(status
, "Fail: getTime failed");
1971 str
+= UnicodeString(", ") + amount
+ ") = ";
1973 cal
.roll(UCAL_DOW_LOCAL
, amount
, status
);
1974 CHECK(status
, "Fail: roll failed");
1976 t
= cal
.getTime(status
);
1977 int32_t newDom
= i
+ amount
;
1978 while (newDom
< 27) newDom
+= 7;
1979 while (newDom
> 33) newDom
-= 7;
1980 cal
.set(1999, UCAL_DECEMBER
, newDom
);
1981 t2
= cal
.getTime(status
);
1982 CHECK(status
, "Fail: getTime failed");
1986 str
.append(", exp ");
1987 fmt
.format(t2
, str
);
1996 void CalendarTest::TestYWOY()
1999 UErrorCode status
= U_ZERO_ERROR
;
2001 GregorianCalendar
cal(status
);
2002 if (failure(status
, "construct GregorianCalendar", TRUE
)) return;
2004 cal
.setFirstDayOfWeek(UCAL_SUNDAY
);
2005 cal
.setMinimalDaysInFirstWeek(1);
2007 logln("Setting: ywoy=2004, woy=1, dow=MONDAY");
2009 cal
.set(UCAL_YEAR_WOY
,2004);
2010 cal
.set(UCAL_WEEK_OF_YEAR
,1);
2011 cal
.set(UCAL_DAY_OF_WEEK
, UCAL_MONDAY
);
2013 logln(calToStr(cal
));
2014 if(cal
.get(UCAL_YEAR
, status
) != 2003) {
2015 errln("year not 2003");
2018 logln("+ setting DOW to THURSDAY");
2020 cal
.set(UCAL_YEAR_WOY
,2004);
2021 cal
.set(UCAL_WEEK_OF_YEAR
,1);
2022 cal
.set(UCAL_DAY_OF_WEEK
, UCAL_THURSDAY
);
2024 logln(calToStr(cal
));
2025 if(cal
.get(UCAL_YEAR
, status
) != 2004) {
2026 errln("year not 2004");
2029 logln("+ setting DOW_LOCAL to 1");
2031 cal
.set(UCAL_YEAR_WOY
,2004);
2032 cal
.set(UCAL_WEEK_OF_YEAR
,1);
2033 cal
.set(UCAL_DAY_OF_WEEK
, UCAL_THURSDAY
);
2034 cal
.set(UCAL_DOW_LOCAL
, 1);
2036 logln(calToStr(cal
));
2037 if(cal
.get(UCAL_YEAR
, status
) != 2003) {
2038 errln("year not 2003");
2041 cal
.setFirstDayOfWeek(UCAL_MONDAY
);
2042 cal
.setMinimalDaysInFirstWeek(4);
2043 UDate t
= 946713600000.;
2044 cal
.setTime(t
, status
);
2045 cal
.set(UCAL_DAY_OF_WEEK
, 4);
2046 cal
.set(UCAL_DOW_LOCAL
, 6);
2047 if(cal
.getTime(status
) != t
) {
2048 logln(calToStr(cal
));
2049 errln("FAIL: DOW_LOCAL did not take precedence");
2054 void CalendarTest::TestJD()
2057 static const int32_t kEpochStartAsJulianDay
= 2440588;
2058 UErrorCode status
= U_ZERO_ERROR
;
2059 GregorianCalendar
cal(status
);
2060 if (failure(status
, "construct GregorianCalendar", TRUE
)) return;
2061 cal
.setTimeZone(*TimeZone::getGMT());
2063 jd
= cal
.get(UCAL_JULIAN_DAY
, status
);
2064 if(jd
!= kEpochStartAsJulianDay
) {
2065 errln("Wanted JD of %d at time=0, [epoch 1970] but got %d\n", kEpochStartAsJulianDay
, jd
);
2067 logln("Wanted JD of %d at time=0, [epoch 1970], got %d\n", kEpochStartAsJulianDay
, jd
);
2070 cal
.setTime(Calendar::getNow(), status
);
2072 cal
.set(UCAL_JULIAN_DAY
, kEpochStartAsJulianDay
);
2073 UDate epochTime
= cal
.getTime(status
);
2074 if(epochTime
!= 0) {
2075 errln("Wanted time of 0 at jd=%d, got %.1lf\n", kEpochStartAsJulianDay
, epochTime
);
2077 logln("Wanted time of 0 at jd=%d, got %.1lf\n", kEpochStartAsJulianDay
, epochTime
);
2082 // make sure the ctestfw utilities are in sync with the Calendar
2083 void CalendarTest::TestDebug()
2085 for(int32_t t
=0;t
<=UDBG_ENUM_COUNT
;t
++) {
2086 int32_t count
= udbg_enumCount((UDebugEnumType
)t
);
2088 logln("enumCount(%d) returned -1", count
);
2091 for(int32_t i
=0;i
<=count
;i
++) {
2092 if(t
<=UDBG_HIGHEST_CONTIGUOUS_ENUM
&& i
<count
) {
2093 if( i
!=udbg_enumArrayValue((UDebugEnumType
)t
, i
)) {
2094 errln("FAIL: udbg_enumArrayValue(%d,%d) returned %d, expected %d", t
, i
, udbg_enumArrayValue((UDebugEnumType
)t
,i
), i
);
2097 logln("Testing count+1:");
2099 const char *name
= udbg_enumName((UDebugEnumType
)t
,i
);
2101 if(i
==count
|| t
>UDBG_HIGHEST_CONTIGUOUS_ENUM
) {
2102 logln(" null name - expected.\n");
2104 errln("FAIL: udbg_enumName(%d,%d) returned NULL", t
, i
);
2108 logln("udbg_enumArrayValue(%d,%d) = %s, returned %d", t
, i
,
2109 name
, udbg_enumArrayValue((UDebugEnumType
)t
,i
));
2110 logln("udbg_enumString = " + udbg_enumString((UDebugEnumType
)t
,i
));
2112 if(udbg_enumExpectedCount((UDebugEnumType
)t
) != count
&& t
<=UDBG_HIGHEST_CONTIGUOUS_ENUM
) {
2113 errln("FAIL: udbg_enumExpectedCount(%d): %d, != UCAL_FIELD_COUNT=%d ", t
, udbg_enumExpectedCount((UDebugEnumType
)t
), count
);
2115 logln("udbg_ucal_fieldCount: %d, UCAL_FIELD_COUNT=udbg_enumCount %d ", udbg_enumExpectedCount((UDebugEnumType
)t
), count
);
2123 // List of interesting locales
2124 const char *CalendarTest::testLocaleID(int32_t i
)
2127 case 0: return "he_IL@calendar=hebrew";
2128 case 1: return "en_US@calendar=hebrew";
2129 case 2: return "fr_FR@calendar=hebrew";
2130 case 3: return "fi_FI@calendar=hebrew";
2131 case 4: return "nl_NL@calendar=hebrew";
2132 case 5: return "hu_HU@calendar=hebrew";
2133 case 6: return "nl_BE@currency=MTL;calendar=islamic";
2134 case 7: return "th_TH_TRADITIONAL@calendar=gregorian";
2135 case 8: return "ar_JO@calendar=islamic-civil";
2136 case 9: return "fi_FI@calendar=islamic";
2137 case 10: return "fr_CH@calendar=islamic-civil";
2138 case 11: return "he_IL@calendar=islamic-civil";
2139 case 12: return "hu_HU@calendar=buddhist";
2140 case 13: return "hu_HU@calendar=islamic";
2141 case 14: return "en_US@calendar=japanese";
2142 default: return NULL
;
2146 int32_t CalendarTest::testLocaleCount()
2148 static int32_t gLocaleCount
= -1;
2149 if(gLocaleCount
< 0) {
2151 for(i
=0;testLocaleID(i
) != NULL
;i
++) {
2156 return gLocaleCount
;
2159 static UDate
doMinDateOfCalendar(Calendar
* adopt
, UBool
&isGregorian
, UErrorCode
& status
) {
2160 if(U_FAILURE(status
)) return 0.0;
2163 adopt
->set(UCAL_EXTENDED_YEAR
, adopt
->getActualMinimum(UCAL_EXTENDED_YEAR
, status
));
2164 UDate ret
= adopt
->getTime(status
);
2165 isGregorian
= dynamic_cast<GregorianCalendar
*>(adopt
) != NULL
;
2170 UDate
CalendarTest::minDateOfCalendar(const Locale
& locale
, UBool
&isGregorian
, UErrorCode
& status
) {
2171 if(U_FAILURE(status
)) return 0.0;
2172 return doMinDateOfCalendar(Calendar::createInstance(locale
, status
), isGregorian
, status
);
2175 UDate
CalendarTest::minDateOfCalendar(const Calendar
& cal
, UBool
&isGregorian
, UErrorCode
& status
) {
2176 if(U_FAILURE(status
)) return 0.0;
2177 return doMinDateOfCalendar(cal
.clone(), isGregorian
, status
);
2180 void CalendarTest::Test6703()
2182 UErrorCode status
= U_ZERO_ERROR
;
2185 Locale
loc1("en@calendar=fubar");
2186 cal
= Calendar::createInstance(loc1
, status
);
2187 if (failure(status
, "Calendar::createInstance", TRUE
)) return;
2190 status
= U_ZERO_ERROR
;
2192 cal
= Calendar::createInstance(loc2
, status
);
2193 if (failure(status
, "Calendar::createInstance")) return;
2196 status
= U_ZERO_ERROR
;
2197 Locale
loc3("en@calendar=roc");
2198 cal
= Calendar::createInstance(loc3
, status
);
2199 if (failure(status
, "Calendar::createInstance")) return;
2205 void CalendarTest::Test3785()
2207 UErrorCode status
= U_ZERO_ERROR
;
2208 UnicodeString uzone
= UNICODE_STRING_SIMPLE("Europe/Paris");
2209 UnicodeString exp1
= UNICODE_STRING_SIMPLE("Mon 30 Jumada II 1433 AH, 01:47:09");
2210 UnicodeString exp2
= UNICODE_STRING_SIMPLE("Mon 1 Rajab 1433 AH, 01:47:10");
2212 LocalUDateFormatPointer
df(udat_open(UDAT_NONE
, UDAT_NONE
, "en@calendar=islamic", uzone
.getTerminatedBuffer(),
2213 uzone
.length(), NULL
, 0, &status
));
2214 if (df
.isNull() || U_FAILURE(status
)) return;
2217 u_uastrcpy(upattern
, "EEE d MMMM y G, HH:mm:ss");
2218 udat_applyPattern(df
.getAlias(), FALSE
, upattern
, u_strlen(upattern
));
2220 UChar ubuffer
[1024];
2221 UDate ud0
= 1337557629000.0;
2223 status
= U_ZERO_ERROR
;
2224 udat_format(df
.getAlias(), ud0
, ubuffer
, 1024, NULL
, &status
);
2225 if (U_FAILURE(status
)) {
2226 errln("Error formatting date 1\n");
2229 //printf("formatted: '%s'\n", mkcstr(ubuffer));
2231 UnicodeString
act1(ubuffer
);
2232 if ( act1
!= exp1
) {
2233 errln(UnicodeString("Unexpected result from date 1 format, act1: ") + act1
);
2235 ud0
+= 1000.0; // add one second
2237 status
= U_ZERO_ERROR
;
2238 udat_format(df
.getAlias(), ud0
, ubuffer
, 1024, NULL
, &status
);
2239 if (U_FAILURE(status
)) {
2240 errln("Error formatting date 2\n");
2243 //printf("formatted: '%s'\n", mkcstr(ubuffer));
2244 UnicodeString
act2(ubuffer
);
2245 if ( act2
!= exp2
) {
2246 errln(UnicodeString("Unexpected result from date 2 format, act2: ") + act2
);
2252 void CalendarTest::Test1624() {
2253 UErrorCode status
= U_ZERO_ERROR
;
2254 Locale
loc("he_IL@calendar=hebrew");
2255 HebrewCalendar
hc(loc
,status
);
2257 for (int32_t year
= 5600; year
< 5800; year
++ ) {
2259 for (int32_t month
= HebrewCalendar::TISHRI
; month
<= HebrewCalendar::ELUL
; month
++) {
2260 // skip the adar 1 month if year is not a leap year
2261 if (HebrewCalendar::isLeapYear(year
) == FALSE
&& month
== HebrewCalendar::ADAR_1
) {
2265 hc
.set(year
,month
,day
);
2266 int32_t dayHC
= hc
.get(UCAL_DATE
,status
);
2267 int32_t monthHC
= hc
.get(UCAL_MONTH
,status
);
2268 int32_t yearHC
= hc
.get(UCAL_YEAR
,status
);
2270 if (failure(status
, "HebrewCalendar.get()", TRUE
)) continue;
2273 errln(" ==> day %d incorrect, should be: %d\n",dayHC
,day
);
2276 if (monthHC
!= month
) {
2277 errln(" ==> month %d incorrect, should be: %d\n",monthHC
,month
);
2280 if (yearHC
!= year
) {
2281 errln(" ==> day %d incorrect, should be: %d\n",yearHC
,year
);
2289 void CalendarTest::TestTimeStamp() {
2290 UErrorCode status
= U_ZERO_ERROR
;
2291 UDate start
= 0.0, time
;
2294 // Create a new Gregorian Calendar.
2295 cal
= Calendar::createInstance("en_US@calender=gregorian", status
);
2296 if (U_FAILURE(status
)) {
2297 dataerrln("Error creating Gregorian calendar.");
2301 for (int i
= 0; i
< 20000; i
++) {
2302 // Set the Gregorian Calendar to a specific date for testing.
2303 cal
->set(2009, UCAL_JULY
, 3, 0, 49, 46);
2305 time
= cal
->getTime(status
);
2306 if (U_FAILURE(status
)) {
2307 errln("Error calling getTime()");
2314 if (start
!= time
) {
2315 errln("start and time not equal.");
2324 void CalendarTest::TestISO8601() {
2325 const char* TEST_LOCALES
[] = {
2326 "en_US@calendar=iso8601",
2327 "en_US@calendar=Iso8601",
2328 "th_TH@calendar=iso8601",
2329 "ar_EG@calendar=iso8601",
2333 int32_t TEST_DATA
[][3] = {
2344 for (int i
= 0; TEST_LOCALES
[i
] != NULL
; i
++) {
2345 UErrorCode status
= U_ZERO_ERROR
;
2346 Calendar
*cal
= Calendar::createInstance(TEST_LOCALES
[i
], status
);
2347 if (U_FAILURE(status
)) {
2348 errln("Error: Failed to create a calendar for locale: %s", TEST_LOCALES
[i
]);
2351 if (uprv_strcmp(cal
->getType(), "gregorian") != 0) {
2352 errln("Error: Gregorian calendar is not used for locale: %s", TEST_LOCALES
[i
]);
2355 for (int j
= 0; TEST_DATA
[j
][0] != 0; j
++) {
2356 cal
->set(TEST_DATA
[j
][0], UCAL_JANUARY
, 1);
2357 int32_t weekNum
= cal
->get(UCAL_WEEK_OF_YEAR
, status
);
2358 int32_t weekYear
= cal
->get(UCAL_YEAR_WOY
, status
);
2359 if (U_FAILURE(status
)) {
2360 errln("Error: Failed to get week of year");
2363 if (weekNum
!= TEST_DATA
[j
][1] || weekYear
!= TEST_DATA
[j
][2]) {
2364 errln("Error: Incorrect week of year on January 1st, %d for locale %s: Returned [weekNum=%d, weekYear=%d], Expected [weekNum=%d, weekYear=%d]",
2365 TEST_DATA
[j
][0], TEST_LOCALES
[i
], weekNum
, weekYear
, TEST_DATA
[j
][1], TEST_DATA
[j
][2]);
2374 CalendarTest::TestAmbiguousWallTimeAPIs(void) {
2375 UErrorCode status
= U_ZERO_ERROR
;
2376 Calendar
* cal
= Calendar::createInstance(status
);
2377 if (U_FAILURE(status
)) {
2378 errln("Fail: Error creating a calendar instance.");
2382 if (cal
->getRepeatedWallTimeOption() != UCAL_WALLTIME_LAST
) {
2383 errln("Fail: Default repeted time option is not UCAL_WALLTIME_LAST");
2385 if (cal
->getSkippedWallTimeOption() != UCAL_WALLTIME_LAST
) {
2386 errln("Fail: Default skipped time option is not UCAL_WALLTIME_LAST");
2389 Calendar
* cal2
= cal
->clone();
2391 if (*cal
!= *cal2
) {
2392 errln("Fail: Cloned calendar != the original");
2394 if (!cal
->equals(*cal2
, status
)) {
2395 errln("Fail: The time of cloned calendar is not equal to the original");
2396 } else if (U_FAILURE(status
)) {
2397 errln("Fail: Error equals");
2399 status
= U_ZERO_ERROR
;
2401 cal2
->setRepeatedWallTimeOption(UCAL_WALLTIME_FIRST
);
2402 cal2
->setSkippedWallTimeOption(UCAL_WALLTIME_FIRST
);
2404 if (*cal
== *cal2
) {
2405 errln("Fail: Cloned and modified calendar == the original");
2407 if (!cal
->equals(*cal2
, status
)) {
2408 errln("Fail: The time of cloned calendar is not equal to the original after changing wall time options");
2409 } else if (U_FAILURE(status
)) {
2410 errln("Fail: Error equals after changing wall time options");
2412 status
= U_ZERO_ERROR
;
2414 if (cal2
->getRepeatedWallTimeOption() != UCAL_WALLTIME_FIRST
) {
2415 errln("Fail: Repeted time option is not UCAL_WALLTIME_FIRST");
2417 if (cal2
->getSkippedWallTimeOption() != UCAL_WALLTIME_FIRST
) {
2418 errln("Fail: Skipped time option is not UCAL_WALLTIME_FIRST");
2421 cal2
->setRepeatedWallTimeOption(UCAL_WALLTIME_NEXT_VALID
);
2422 if (cal2
->getRepeatedWallTimeOption() != UCAL_WALLTIME_FIRST
) {
2423 errln("Fail: Repeated wall time option was updated other than UCAL_WALLTIME_FIRST");
2432 CalFields(int32_t year
, int32_t month
, int32_t day
, int32_t hour
, int32_t min
, int32_t sec
, int32_t ms
= 0);
2433 CalFields(const Calendar
& cal
, UErrorCode
& status
);
2434 void setTo(Calendar
& cal
) const;
2435 char* toString(char* buf
, int32_t len
) const;
2436 UBool
operator==(const CalFields
& rhs
) const;
2437 UBool
operator!=(const CalFields
& rhs
) const;
2438 UBool
isEquivalentTo(const Calendar
& cal
, UErrorCode
& status
) const;
2450 CalFields::CalFields(int32_t year
, int32_t month
, int32_t day
, int32_t hour
, int32_t min
, int32_t sec
, int32_t ms
)
2451 : year(year
), month(month
), day(day
), hour(hour
), min(min
), sec(sec
), ms(ms
) {
2454 CalFields::CalFields(const Calendar
& cal
, UErrorCode
& status
) {
2455 year
= cal
.get(UCAL_YEAR
, status
);
2456 month
= cal
.get(UCAL_MONTH
, status
) + 1;
2457 day
= cal
.get(UCAL_DAY_OF_MONTH
, status
);
2458 hour
= cal
.get(UCAL_HOUR_OF_DAY
, status
);
2459 min
= cal
.get(UCAL_MINUTE
, status
);
2460 sec
= cal
.get(UCAL_SECOND
, status
);
2461 ms
= cal
.get(UCAL_MILLISECOND
, status
);
2465 CalFields::setTo(Calendar
& cal
) const {
2467 cal
.set(year
, month
- 1, day
, hour
, min
, sec
);
2468 cal
.set(UCAL_MILLISECOND
, ms
);
2472 CalFields::toString(char* buf
, int32_t len
) const {
2474 sprintf(local
, "%04d-%02d-%02d %02d:%02d:%02d.%03d", year
, month
, day
, hour
, min
, sec
, ms
);
2475 uprv_strncpy(buf
, local
, len
- 1);
2481 CalFields::operator==(const CalFields
& rhs
) const {
2482 return year
== rhs
.year
2483 && month
== rhs
.month
2492 CalFields::operator!=(const CalFields
& rhs
) const {
2493 return !(*this == rhs
);
2497 CalFields::isEquivalentTo(const Calendar
& cal
, UErrorCode
& status
) const {
2498 return year
== cal
.get(UCAL_YEAR
, status
)
2499 && month
== cal
.get(UCAL_MONTH
, status
) + 1
2500 && day
== cal
.get(UCAL_DAY_OF_MONTH
, status
)
2501 && hour
== cal
.get(UCAL_HOUR_OF_DAY
, status
)
2502 && min
== cal
.get(UCAL_MINUTE
, status
)
2503 && sec
== cal
.get(UCAL_SECOND
, status
)
2504 && ms
== cal
.get(UCAL_MILLISECOND
, status
);
2510 const CalFields expLastGMT
;
2511 const CalFields expFirstGMT
;
2512 } RepeatedWallTimeTestData
;
2514 static const RepeatedWallTimeTestData RPDATA
[] =
2516 // Time zone Input wall time WALLTIME_LAST in GMT WALLTIME_FIRST in GMT
2517 {"America/New_York", CalFields(2011,11,6,0,59,59), CalFields(2011,11,6,4,59,59), CalFields(2011,11,6,4,59,59)},
2518 {"America/New_York", CalFields(2011,11,6,1,0,0), CalFields(2011,11,6,6,0,0), CalFields(2011,11,6,5,0,0)},
2519 {"America/New_York", CalFields(2011,11,6,1,0,1), CalFields(2011,11,6,6,0,1), CalFields(2011,11,6,5,0,1)},
2520 {"America/New_York", CalFields(2011,11,6,1,30,0), CalFields(2011,11,6,6,30,0), CalFields(2011,11,6,5,30,0)},
2521 {"America/New_York", CalFields(2011,11,6,1,59,59), CalFields(2011,11,6,6,59,59), CalFields(2011,11,6,5,59,59)},
2522 {"America/New_York", CalFields(2011,11,6,2,0,0), CalFields(2011,11,6,7,0,0), CalFields(2011,11,6,7,0,0)},
2523 {"America/New_York", CalFields(2011,11,6,2,0,1), CalFields(2011,11,6,7,0,1), CalFields(2011,11,6,7,0,1)},
2525 {"Australia/Lord_Howe", CalFields(2011,4,3,1,29,59), CalFields(2011,4,2,14,29,59), CalFields(2011,4,2,14,29,59)},
2526 {"Australia/Lord_Howe", CalFields(2011,4,3,1,30,0), CalFields(2011,4,2,15,0,0), CalFields(2011,4,2,14,30,0)},
2527 {"Australia/Lord_Howe", CalFields(2011,4,3,1,45,0), CalFields(2011,4,2,15,15,0), CalFields(2011,4,2,14,45,0)},
2528 {"Australia/Lord_Howe", CalFields(2011,4,3,1,59,59), CalFields(2011,4,2,15,29,59), CalFields(2011,4,2,14,59,59)},
2529 {"Australia/Lord_Howe", CalFields(2011,4,3,2,0,0), CalFields(2011,4,2,15,30,0), CalFields(2011,4,2,15,30,0)},
2530 {"Australia/Lord_Howe", CalFields(2011,4,3,2,0,1), CalFields(2011,4,2,15,30,1), CalFields(2011,4,2,15,30,1)},
2532 {NULL
, CalFields(0,0,0,0,0,0), CalFields(0,0,0,0,0,0), CalFields(0,0,0,0,0,0)}
2535 void CalendarTest::TestRepeatedWallTime(void) {
2536 UErrorCode status
= U_ZERO_ERROR
;
2537 GregorianCalendar
calGMT((const TimeZone
&)*TimeZone::getGMT(), status
);
2538 GregorianCalendar
calDefault(status
);
2539 GregorianCalendar
calLast(status
);
2540 GregorianCalendar
calFirst(status
);
2542 if (U_FAILURE(status
)) {
2543 errln("Fail: Failed to create a calendar object.");
2547 calLast
.setRepeatedWallTimeOption(UCAL_WALLTIME_LAST
);
2548 calFirst
.setRepeatedWallTimeOption(UCAL_WALLTIME_FIRST
);
2550 for (int32_t i
= 0; RPDATA
[i
].tzid
!= NULL
; i
++) {
2552 TimeZone
*tz
= TimeZone::createTimeZone(RPDATA
[i
].tzid
);
2554 // UCAL_WALLTIME_LAST
2555 status
= U_ZERO_ERROR
;
2556 calLast
.setTimeZone(*tz
);
2557 RPDATA
[i
].in
.setTo(calLast
);
2558 calGMT
.setTime(calLast
.getTime(status
), status
);
2559 CalFields
outLastGMT(calGMT
, status
);
2560 if (U_FAILURE(status
)) {
2561 errln(UnicodeString("Fail: Failed to get/set time calLast/calGMT (UCAL_WALLTIME_LAST) - ")
2562 + RPDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + RPDATA
[i
].tzid
+ "]");
2564 if (outLastGMT
!= RPDATA
[i
].expLastGMT
) {
2565 dataerrln(UnicodeString("Fail: UCAL_WALLTIME_LAST ") + RPDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + RPDATA
[i
].tzid
+ "] is parsed as "
2566 + outLastGMT
.toString(buf
, sizeof(buf
)) + "[GMT]. Expected: " + RPDATA
[i
].expLastGMT
.toString(buf
, sizeof(buf
)) + "[GMT]");
2571 status
= U_ZERO_ERROR
;
2572 calDefault
.setTimeZone(*tz
);
2573 RPDATA
[i
].in
.setTo(calDefault
);
2574 calGMT
.setTime(calDefault
.getTime(status
), status
);
2575 CalFields
outDefGMT(calGMT
, status
);
2576 if (U_FAILURE(status
)) {
2577 errln(UnicodeString("Fail: Failed to get/set time calLast/calGMT (default) - ")
2578 + RPDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + RPDATA
[i
].tzid
+ "]");
2580 if (outDefGMT
!= RPDATA
[i
].expLastGMT
) {
2581 dataerrln(UnicodeString("Fail: (default) ") + RPDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + RPDATA
[i
].tzid
+ "] is parsed as "
2582 + outDefGMT
.toString(buf
, sizeof(buf
)) + "[GMT]. Expected: " + RPDATA
[i
].expLastGMT
.toString(buf
, sizeof(buf
)) + "[GMT]");
2586 // UCAL_WALLTIME_FIRST
2587 status
= U_ZERO_ERROR
;
2588 calFirst
.setTimeZone(*tz
);
2589 RPDATA
[i
].in
.setTo(calFirst
);
2590 calGMT
.setTime(calFirst
.getTime(status
), status
);
2591 CalFields
outFirstGMT(calGMT
, status
);
2592 if (U_FAILURE(status
)) {
2593 errln(UnicodeString("Fail: Failed to get/set time calLast/calGMT (UCAL_WALLTIME_FIRST) - ")
2594 + RPDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + RPDATA
[i
].tzid
+ "]");
2596 if (outFirstGMT
!= RPDATA
[i
].expFirstGMT
) {
2597 dataerrln(UnicodeString("Fail: UCAL_WALLTIME_FIRST ") + RPDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + RPDATA
[i
].tzid
+ "] is parsed as "
2598 + outFirstGMT
.toString(buf
, sizeof(buf
)) + "[GMT]. Expected: " + RPDATA
[i
].expFirstGMT
.toString(buf
, sizeof(buf
)) + "[GMT]");
2609 const CalFields expLastGMT
;
2610 const CalFields expFirstGMT
;
2611 const CalFields expNextAvailGMT
;
2612 } SkippedWallTimeTestData
;
2614 static SkippedWallTimeTestData SKDATA
[] =
2616 // Time zone Input wall time valid? WALLTIME_LAST in GMT WALLTIME_FIRST in GMT WALLTIME_NEXT_VALID in GMT
2617 {"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)},
2618 {"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)},
2619 {"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)},
2620 {"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)},
2621 {"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)},
2622 {"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)},
2624 {"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)},
2625 {"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)},
2626 {"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)},
2627 {"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)},
2628 {"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)},
2630 {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)}
2634 void CalendarTest::TestSkippedWallTime(void) {
2635 UErrorCode status
= U_ZERO_ERROR
;
2636 GregorianCalendar
calGMT((const TimeZone
&)*TimeZone::getGMT(), status
);
2637 GregorianCalendar
calDefault(status
);
2638 GregorianCalendar
calLast(status
);
2639 GregorianCalendar
calFirst(status
);
2640 GregorianCalendar
calNextAvail(status
);
2642 if (U_FAILURE(status
)) {
2643 errln("Fail: Failed to create a calendar object.");
2647 calLast
.setSkippedWallTimeOption(UCAL_WALLTIME_LAST
);
2648 calFirst
.setSkippedWallTimeOption(UCAL_WALLTIME_FIRST
);
2649 calNextAvail
.setSkippedWallTimeOption(UCAL_WALLTIME_NEXT_VALID
);
2651 for (int32_t i
= 0; SKDATA
[i
].tzid
!= NULL
; i
++) {
2654 TimeZone
*tz
= TimeZone::createTimeZone(SKDATA
[i
].tzid
);
2656 for (int32_t j
= 0; j
< 2; j
++) {
2657 UBool bLenient
= (j
== 0);
2659 // UCAL_WALLTIME_LAST
2660 status
= U_ZERO_ERROR
;
2661 calLast
.setLenient(bLenient
);
2662 calLast
.setTimeZone(*tz
);
2663 SKDATA
[i
].in
.setTo(calLast
);
2664 d
= calLast
.getTime(status
);
2665 if (bLenient
|| SKDATA
[i
].isValid
) {
2666 calGMT
.setTime(d
, status
);
2667 CalFields
outLastGMT(calGMT
, status
);
2668 if (U_FAILURE(status
)) {
2669 errln(UnicodeString("Fail: Failed to get/set time calLast/calGMT (UCAL_WALLTIME_LAST) - ")
2670 + SKDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + SKDATA
[i
].tzid
+ "]");
2672 if (outLastGMT
!= SKDATA
[i
].expLastGMT
) {
2673 dataerrln(UnicodeString("Fail: UCAL_WALLTIME_LAST ") + SKDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + SKDATA
[i
].tzid
+ "] is parsed as "
2674 + outLastGMT
.toString(buf
, sizeof(buf
)) + "[GMT]. Expected: " + SKDATA
[i
].expLastGMT
.toString(buf
, sizeof(buf
)) + "[GMT]");
2677 } else if (U_SUCCESS(status
)) {
2678 // strict, invalid wall time - must report an error
2679 dataerrln(UnicodeString("Fail: An error expected (UCAL_WALLTIME_LAST)") +
2680 + SKDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + SKDATA
[i
].tzid
+ "]");
2684 status
= U_ZERO_ERROR
;
2685 calDefault
.setLenient(bLenient
);
2686 calDefault
.setTimeZone(*tz
);
2687 SKDATA
[i
].in
.setTo(calDefault
);
2688 d
= calDefault
.getTime(status
);
2689 if (bLenient
|| SKDATA
[i
].isValid
) {
2690 calGMT
.setTime(d
, status
);
2691 CalFields
outDefGMT(calGMT
, status
);
2692 if (U_FAILURE(status
)) {
2693 errln(UnicodeString("Fail: Failed to get/set time calDefault/calGMT (default) - ")
2694 + SKDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + SKDATA
[i
].tzid
+ "]");
2696 if (outDefGMT
!= SKDATA
[i
].expLastGMT
) {
2697 dataerrln(UnicodeString("Fail: (default) ") + SKDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + SKDATA
[i
].tzid
+ "] is parsed as "
2698 + outDefGMT
.toString(buf
, sizeof(buf
)) + "[GMT]. Expected: " + SKDATA
[i
].expLastGMT
.toString(buf
, sizeof(buf
)) + "[GMT]");
2701 } else if (U_SUCCESS(status
)) {
2702 // strict, invalid wall time - must report an error
2703 dataerrln(UnicodeString("Fail: An error expected (default)") +
2704 + SKDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + SKDATA
[i
].tzid
+ "]");
2707 // UCAL_WALLTIME_FIRST
2708 status
= U_ZERO_ERROR
;
2709 calFirst
.setLenient(bLenient
);
2710 calFirst
.setTimeZone(*tz
);
2711 SKDATA
[i
].in
.setTo(calFirst
);
2712 d
= calFirst
.getTime(status
);
2713 if (bLenient
|| SKDATA
[i
].isValid
) {
2714 calGMT
.setTime(d
, status
);
2715 CalFields
outFirstGMT(calGMT
, status
);
2716 if (U_FAILURE(status
)) {
2717 errln(UnicodeString("Fail: Failed to get/set time calFirst/calGMT (UCAL_WALLTIME_FIRST) - ")
2718 + SKDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + SKDATA
[i
].tzid
+ "]");
2720 if (outFirstGMT
!= SKDATA
[i
].expFirstGMT
) {
2721 dataerrln(UnicodeString("Fail: UCAL_WALLTIME_FIRST ") + SKDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + SKDATA
[i
].tzid
+ "] is parsed as "
2722 + outFirstGMT
.toString(buf
, sizeof(buf
)) + "[GMT]. Expected: " + SKDATA
[i
].expFirstGMT
.toString(buf
, sizeof(buf
)) + "[GMT]");
2725 } else if (U_SUCCESS(status
)) {
2726 // strict, invalid wall time - must report an error
2727 dataerrln(UnicodeString("Fail: An error expected (UCAL_WALLTIME_FIRST)") +
2728 + SKDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + SKDATA
[i
].tzid
+ "]");
2731 // UCAL_WALLTIME_NEXT_VALID
2732 status
= U_ZERO_ERROR
;
2733 calNextAvail
.setLenient(bLenient
);
2734 calNextAvail
.setTimeZone(*tz
);
2735 SKDATA
[i
].in
.setTo(calNextAvail
);
2736 d
= calNextAvail
.getTime(status
);
2737 if (bLenient
|| SKDATA
[i
].isValid
) {
2738 calGMT
.setTime(d
, status
);
2739 CalFields
outNextAvailGMT(calGMT
, status
);
2740 if (U_FAILURE(status
)) {
2741 errln(UnicodeString("Fail: Failed to get/set time calNextAvail/calGMT (UCAL_WALLTIME_NEXT_VALID) - ")
2742 + SKDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + SKDATA
[i
].tzid
+ "]");
2744 if (outNextAvailGMT
!= SKDATA
[i
].expNextAvailGMT
) {
2745 dataerrln(UnicodeString("Fail: UCAL_WALLTIME_NEXT_VALID ") + SKDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + SKDATA
[i
].tzid
+ "] is parsed as "
2746 + outNextAvailGMT
.toString(buf
, sizeof(buf
)) + "[GMT]. Expected: " + SKDATA
[i
].expNextAvailGMT
.toString(buf
, sizeof(buf
)) + "[GMT]");
2749 } else if (U_SUCCESS(status
)) {
2750 // strict, invalid wall time - must report an error
2751 dataerrln(UnicodeString("Fail: An error expected (UCAL_WALLTIME_NEXT_VALID)") +
2752 + SKDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + SKDATA
[i
].tzid
+ "]");
2760 void CalendarTest::TestCloneLocale(void) {
2761 UErrorCode status
= U_ZERO_ERROR
;
2762 LocalPointer
<Calendar
> cal(Calendar::createInstance(TimeZone::getGMT()->clone(),
2763 Locale::createFromName("en"), status
));
2765 Locale l0
= cal
->getLocale(ULOC_VALID_LOCALE
, status
);
2767 LocalPointer
<Calendar
> cal2(cal
->clone());
2768 Locale l
= cal2
->getLocale(ULOC_VALID_LOCALE
, status
);
2770 errln("Error: cloned locale %s != original locale %s, status %s\n", l0
.getName(), l
.getName(), u_errorName(status
));
2775 void CalendarTest::setAndTestCalendar(Calendar
* cal
, int32_t initMonth
, int32_t initDay
, int32_t initYear
, UErrorCode
& status
) {
2777 cal
->setLenient(FALSE
);
2778 cal
->set(initYear
, initMonth
, initDay
);
2779 int32_t day
= cal
->get(UCAL_DAY_OF_MONTH
, status
);
2780 int32_t month
= cal
->get(UCAL_MONTH
, status
);
2781 int32_t year
= cal
->get(UCAL_YEAR
, status
);
2782 if(U_FAILURE(status
))
2785 if(initDay
!= day
|| initMonth
!= month
|| initYear
!= year
)
2787 errln(" year init values:\tmonth %i\tday %i\tyear %i", initMonth
, initDay
, initYear
);
2788 errln("values post set():\tmonth %i\tday %i\tyear %i",month
, day
, year
);
2792 void CalendarTest::setAndTestWholeYear(Calendar
* cal
, int32_t startYear
, UErrorCode
& status
) {
2793 for(int32_t startMonth
= 0; startMonth
< 12; startMonth
++) {
2794 for(int32_t startDay
= 1; startDay
< 31; startDay
++ ) {
2795 setAndTestCalendar(cal
, startMonth
, startDay
, startYear
, status
);
2796 if(U_FAILURE(status
) && startDay
== 30) {
2797 status
= U_ZERO_ERROR
;
2806 void CalendarTest::TestIslamicUmAlQura() {
2808 UErrorCode status
= U_ZERO_ERROR
;
2809 Locale
islamicLoc("ar_SA@calendar=islamic-umalqura");
2810 Calendar
* tstCal
= Calendar::createInstance(islamicLoc
, status
);
2812 IslamicCalendar
* iCal
= (IslamicCalendar
*)tstCal
;
2813 if(strcmp(iCal
->getType(), "islamic-umalqura") != 0) {
2814 errln("wrong type of calendar created - %s", iCal
->getType());
2818 int32_t firstYear
= 1318;
2819 int32_t lastYear
= 1368; // just enough to be pretty sure
2820 //int32_t lastYear = 1480; // the whole shootin' match
2823 tstCal
->setLenient(FALSE
);
2825 int32_t day
=0, month
=0, year
=0, initDay
= 27, initMonth
= IslamicCalendar::RAJAB
, initYear
= 1434;
2827 for( int32_t startYear
= firstYear
; startYear
<= lastYear
; startYear
++) {
2828 setAndTestWholeYear(tstCal
, startYear
, status
);
2829 status
= U_ZERO_ERROR
;
2832 initMonth
= IslamicCalendar::RABI_2
;
2834 int32_t loopCnt
= 25;
2836 setAndTestCalendar( tstCal
, initMonth
, initDay
, initYear
, status
);
2839 for(int x
=1; x
<=loopCnt
; x
++) {
2840 day
= tstCal
->get(UCAL_DAY_OF_MONTH
,status
);
2841 month
= tstCal
->get(UCAL_MONTH
,status
);
2842 year
= tstCal
->get(UCAL_YEAR
,status
);
2844 tstCal
->roll(UCAL_DAY_OF_MONTH
, (UBool
)TRUE
, status
);
2848 if(day
!= (initDay
+ loopCnt
- 1) || month
!= IslamicCalendar::RABI_2
|| year
!= 1434)
2849 errln("invalid values for RABI_2 date after roll of %d", loopCnt
);
2851 status
= U_ZERO_ERROR
;
2855 setAndTestCalendar( tstCal
, initMonth
, initDay
, initYear
, status
);
2856 if(U_SUCCESS(status
)) {
2857 errln("error NOT detected status %i",status
);
2858 errln(" init values:\tmonth %i\tday %i\tyear %i", initMonth
, initDay
, initYear
);
2859 int32_t day
= tstCal
->get(UCAL_DAY_OF_MONTH
, status
);
2860 int32_t month
= tstCal
->get(UCAL_MONTH
, status
);
2861 int32_t year
= tstCal
->get(UCAL_YEAR
, status
);
2862 errln("values post set():\tmonth %i\tday %i\tyear %i",month
, day
, year
);
2865 status
= U_ZERO_ERROR
;
2869 setAndTestCalendar( tstCal
, initMonth
, initDay
, initYear
, status
);
2872 SimpleDateFormat
* formatter
= new SimpleDateFormat("yyyy-MM-dd", Locale::getUS(), status
);
2873 UDate date
= formatter
->parse("1975-05-06", status
);
2874 Calendar
* is_cal
= Calendar::createInstance(islamicLoc
, status
);
2875 is_cal
->setTime(date
, status
);
2876 int32_t is_day
= is_cal
->get(UCAL_DAY_OF_MONTH
,status
);
2877 int32_t is_month
= is_cal
->get(UCAL_MONTH
,status
);
2878 int32_t is_year
= is_cal
->get(UCAL_YEAR
,status
);
2880 if(is_day
!= 24 || is_month
!= IslamicCalendar::RABI_2
|| is_year
!= 1395) // per http://www.ummulqura.org.sa/Index.aspx
2881 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
);
2883 UDate date2
= is_cal
->getTime(status
);
2886 errln("before(%f) and after(%f) dates don't match up!",date
, date2
);
2894 void CalendarTest::TestIslamicTabularDates() {
2895 UErrorCode status
= U_ZERO_ERROR
;
2896 Locale
islamicLoc("ar_SA@calendar=islamic-civil");
2897 Locale
tblaLoc("ar_SA@calendar=islamic-tbla");
2898 SimpleDateFormat
* formatter
= new SimpleDateFormat("yyyy-MM-dd", Locale::getUS(), status
);
2899 UDate date
= formatter
->parse("1975-05-06", status
);
2901 Calendar
* tstCal
= Calendar::createInstance(islamicLoc
, status
);
2902 tstCal
->setTime(date
, status
);
2903 int32_t is_day
= tstCal
->get(UCAL_DAY_OF_MONTH
,status
);
2904 int32_t is_month
= tstCal
->get(UCAL_MONTH
,status
);
2905 int32_t is_year
= tstCal
->get(UCAL_YEAR
,status
);
2909 tstCal
= Calendar::createInstance(tblaLoc
, status
);
2910 tstCal
->setTime(date
, status
);
2911 int32_t tbla_day
= tstCal
->get(UCAL_DAY_OF_MONTH
,status
);
2912 int32_t tbla_month
= tstCal
->get(UCAL_MONTH
,status
);
2913 int32_t tbla_year
= tstCal
->get(UCAL_YEAR
,status
);
2916 if(tbla_month
!= is_month
|| tbla_year
!= is_year
)
2917 errln("unexpected difference between islamic and tbla month %d : %d and/or year %d : %d",tbla_month
,is_month
,tbla_year
,is_year
);
2919 if(tbla_day
- is_day
!= 1)
2920 errln("unexpected day difference between islamic and tbla: %d : %d ",tbla_day
,is_day
);
2925 void CalendarTest::TestHebrewMonthValidation() {
2926 UErrorCode status
= U_ZERO_ERROR
;
2927 LocalPointer
<Calendar
> cal(Calendar::createInstance(Locale::createFromName("he_IL@calendar=hebrew"), status
));
2928 if (failure(status
, "Calendar::createInstance, locale:he_IL@calendar=hebrew", TRUE
)) return;
2929 Calendar
*pCal
= cal
.getAlias();
2932 pCal
->setLenient(FALSE
);
2934 // 5776 is a leap year and has month Adar I
2935 pCal
->set(5776, HebrewCalendar::ADAR_1
, 1);
2936 d
= pCal
->getTime(status
);
2937 if (U_FAILURE(status
)) {
2938 errln("Fail: 5776 Adar I 1 is a valid date.");
2940 status
= U_ZERO_ERROR
;
2942 // 5777 is NOT a lear year and does not have month Adar I
2943 pCal
->set(5777, HebrewCalendar::ADAR_1
, 1);
2944 d
= pCal
->getTime(status
);
2946 if (status
== U_ILLEGAL_ARGUMENT_ERROR
) {
2947 logln("Info: U_ILLEGAL_ARGUMENT_ERROR, because 5777 Adar I 1 is not a valid date.");
2949 errln("Fail: U_ILLEGAL_ARGUMENT_ERROR should be set for input date 5777 Adar I 1.");
2953 void CalendarTest::TestWeekData() {
2954 // Each line contains two locales using the same set of week rule data.
2955 const char* LOCALE_PAIRS
[] = {
2967 for (int32_t i
= 0; LOCALE_PAIRS
[i
] != 0; i
+= 2) {
2968 status
= U_ZERO_ERROR
;
2969 LocalPointer
<Calendar
> cal1(Calendar::createInstance(LOCALE_PAIRS
[i
], status
));
2970 LocalPointer
<Calendar
> cal2(Calendar::createInstance(LOCALE_PAIRS
[i
+ 1], status
));
2973 // First day of week
2974 UCalendarDaysOfWeek dow1
= cal1
->getFirstDayOfWeek(status
);
2975 UCalendarDaysOfWeek dow2
= cal2
->getFirstDayOfWeek(status
);
2977 TEST_ASSERT(dow1
== dow2
);
2979 // Minimum days in first week
2980 uint8_t minDays1
= cal1
->getMinimalDaysInFirstWeek();
2981 uint8_t minDays2
= cal2
->getMinimalDaysInFirstWeek();
2982 TEST_ASSERT(minDays1
== minDays2
);
2984 // Weekdays and Weekends
2985 for (int32_t d
= UCAL_SUNDAY
; d
<= UCAL_SATURDAY
; d
++) {
2986 status
= U_ZERO_ERROR
;
2987 UCalendarWeekdayType wdt1
= cal1
->getDayOfWeekType((UCalendarDaysOfWeek
)d
, status
);
2988 UCalendarWeekdayType wdt2
= cal2
->getDayOfWeekType((UCalendarDaysOfWeek
)d
, status
);
2990 TEST_ASSERT(wdt1
== wdt2
);
2997 const CalFields base
;
2999 UCalendarWallTimeOption skippedWTOpt
;
3000 const CalFields expected
;
3001 } TestAddAcrossZoneTransitionData
;
3003 static const TestAddAcrossZoneTransitionData AAZTDATA
[] =
3005 // Time zone Base wall time day(s) Skipped time options
3006 // Expected wall time
3008 // Add 1 day, from the date before DST transition
3009 {"America/Los_Angeles", CalFields(2014,3,8,1,59,59,999), 1, UCAL_WALLTIME_FIRST
,
3010 CalFields(2014,3,9,1,59,59,999)},
3012 {"America/Los_Angeles", CalFields(2014,3,8,1,59,59,999), 1, UCAL_WALLTIME_LAST
,
3013 CalFields(2014,3,9,1,59,59,999)},
3015 {"America/Los_Angeles", CalFields(2014,3,8,1,59,59,999), 1, UCAL_WALLTIME_NEXT_VALID
,
3016 CalFields(2014,3,9,1,59,59,999)},
3019 {"America/Los_Angeles", CalFields(2014,3,8,2,0,0,0), 1, UCAL_WALLTIME_FIRST
,
3020 CalFields(2014,3,9,1,0,0,0)},
3022 {"America/Los_Angeles", CalFields(2014,3,8,2,0,0,0), 1, UCAL_WALLTIME_LAST
,
3023 CalFields(2014,3,9,3,0,0,0)},
3025 {"America/Los_Angeles", CalFields(2014,3,8,2,0,0,0), 1, UCAL_WALLTIME_NEXT_VALID
,
3026 CalFields(2014,3,9,3,0,0,0)},
3029 {"America/Los_Angeles", CalFields(2014,3,8,2,30,0,0), 1, UCAL_WALLTIME_FIRST
,
3030 CalFields(2014,3,9,1,30,0,0)},
3032 {"America/Los_Angeles", CalFields(2014,3,8,2,30,0,0), 1, UCAL_WALLTIME_LAST
,
3033 CalFields(2014,3,9,3,30,0,0)},
3035 {"America/Los_Angeles", CalFields(2014,3,8,2,30,0,0), 1, UCAL_WALLTIME_NEXT_VALID
,
3036 CalFields(2014,3,9,3,0,0,0)},
3039 {"America/Los_Angeles", CalFields(2014,3,8,3,0,0,0), 1, UCAL_WALLTIME_FIRST
,
3040 CalFields(2014,3,9,3,0,0,0)},
3042 {"America/Los_Angeles", CalFields(2014,3,8,3,0,0,0), 1, UCAL_WALLTIME_LAST
,
3043 CalFields(2014,3,9,3,0,0,0)},
3045 {"America/Los_Angeles", CalFields(2014,3,8,3,0,0,0), 1, UCAL_WALLTIME_NEXT_VALID
,
3046 CalFields(2014,3,9,3,0,0,0)},
3048 // Subtract 1 day, from one day after DST transition
3049 {"America/Los_Angeles", CalFields(2014,3,10,1,59,59,999), -1, UCAL_WALLTIME_FIRST
,
3050 CalFields(2014,3,9,1,59,59,999)},
3052 {"America/Los_Angeles", CalFields(2014,3,10,1,59,59,999), -1, UCAL_WALLTIME_LAST
,
3053 CalFields(2014,3,9,1,59,59,999)},
3055 {"America/Los_Angeles", CalFields(2014,3,10,1,59,59,999), -1, UCAL_WALLTIME_NEXT_VALID
,
3056 CalFields(2014,3,9,1,59,59,999)},
3059 {"America/Los_Angeles", CalFields(2014,3,10,2,0,0,0), -1, UCAL_WALLTIME_FIRST
,
3060 CalFields(2014,3,9,1,0,0,0)},
3062 {"America/Los_Angeles", CalFields(2014,3,10,2,0,0,0), -1, UCAL_WALLTIME_LAST
,
3063 CalFields(2014,3,9,3,0,0,0)},
3065 {"America/Los_Angeles", CalFields(2014,3,10,2,0,0,0), -1, UCAL_WALLTIME_NEXT_VALID
,
3066 CalFields(2014,3,9,3,0,0,0)},
3069 {"America/Los_Angeles", CalFields(2014,3,10,2,30,0,0), -1, UCAL_WALLTIME_FIRST
,
3070 CalFields(2014,3,9,1,30,0,0)},
3072 {"America/Los_Angeles", CalFields(2014,3,10,2,30,0,0), -1, UCAL_WALLTIME_LAST
,
3073 CalFields(2014,3,9,3,30,0,0)},
3075 {"America/Los_Angeles", CalFields(2014,3,10,2,30,0,0), -1, UCAL_WALLTIME_NEXT_VALID
,
3076 CalFields(2014,3,9,3,0,0,0)},
3079 {"America/Los_Angeles", CalFields(2014,3,10,3,0,0,0), -1, UCAL_WALLTIME_FIRST
,
3080 CalFields(2014,3,9,3,0,0,0)},
3082 {"America/Los_Angeles", CalFields(2014,3,10,3,0,0,0), -1, UCAL_WALLTIME_LAST
,
3083 CalFields(2014,3,9,3,0,0,0)},
3085 {"America/Los_Angeles", CalFields(2014,3,10,3,0,0,0), -1, UCAL_WALLTIME_NEXT_VALID
,
3086 CalFields(2014,3,9,3,0,0,0)},
3089 // Test case for ticket#10544
3090 {"America/Santiago", CalFields(2013,4,27,0,0,0,0), 134, UCAL_WALLTIME_FIRST
,
3091 CalFields(2013,9,7,23,0,0,0)},
3093 {"America/Santiago", CalFields(2013,4,27,0,0,0,0), 134, UCAL_WALLTIME_LAST
,
3094 CalFields(2013,9,8,1,0,0,0)},
3096 {"America/Santiago", CalFields(2013,4,27,0,0,0,0), 134, UCAL_WALLTIME_NEXT_VALID
,
3097 CalFields(2013,9,8,1,0,0,0)},
3100 {"America/Santiago", CalFields(2013,4,27,0,30,0,0), 134, UCAL_WALLTIME_FIRST
,
3101 CalFields(2013,9,7,23,30,0,0)},
3103 {"America/Santiago", CalFields(2013,4,27,0,30,0,0), 134, UCAL_WALLTIME_LAST
,
3104 CalFields(2013,9,8,1,30,0,0)},
3106 {"America/Santiago", CalFields(2013,4,27,0,30,0,0), 134, UCAL_WALLTIME_NEXT_VALID
,
3107 CalFields(2013,9,8,1,0,0,0)},
3110 // Extreme transition - Pacific/Apia completely skips 2011-12-30
3111 {"Pacific/Apia", CalFields(2011,12,29,0,0,0,0), 1, UCAL_WALLTIME_FIRST
,
3112 CalFields(2011,12,31,0,0,0,0)},
3114 {"Pacific/Apia", CalFields(2011,12,29,0,0,0,0), 1, UCAL_WALLTIME_LAST
,
3115 CalFields(2011,12,31,0,0,0,0)},
3117 {"Pacific/Apia", CalFields(2011,12,29,0,0,0,0), 1, UCAL_WALLTIME_NEXT_VALID
,
3118 CalFields(2011,12,31,0,0,0,0)},
3121 {"Pacific/Apia", CalFields(2011,12,31,12,0,0,0), -1, UCAL_WALLTIME_FIRST
,
3122 CalFields(2011,12,29,12,0,0,0)},
3124 {"Pacific/Apia", CalFields(2011,12,31,12,0,0,0), -1, UCAL_WALLTIME_LAST
,
3125 CalFields(2011,12,29,12,0,0,0)},
3127 {"Pacific/Apia", CalFields(2011,12,31,12,0,0,0), -1, UCAL_WALLTIME_NEXT_VALID
,
3128 CalFields(2011,12,29,12,0,0,0)},
3131 // 30 minutes DST - Australia/Lord_Howe
3132 {"Australia/Lord_Howe", CalFields(2013,10,5,2,15,0,0), 1, UCAL_WALLTIME_FIRST
,
3133 CalFields(2013,10,6,1,45,0,0)},
3135 {"Australia/Lord_Howe", CalFields(2013,10,5,2,15,0,0), 1, UCAL_WALLTIME_LAST
,
3136 CalFields(2013,10,6,2,45,0,0)},
3138 {"Australia/Lord_Howe", CalFields(2013,10,5,2,15,0,0), 1, UCAL_WALLTIME_NEXT_VALID
,
3139 CalFields(2013,10,6,2,30,0,0)},
3141 {NULL
, CalFields(0,0,0,0,0,0,0), 0, UCAL_WALLTIME_LAST
, CalFields(0,0,0,0,0,0,0)}
3144 void CalendarTest::TestAddAcrossZoneTransition() {
3145 UErrorCode status
= U_ZERO_ERROR
;
3146 GregorianCalendar
cal(status
);
3149 for (int32_t i
= 0; AAZTDATA
[i
].zone
; i
++) {
3150 status
= U_ZERO_ERROR
;
3151 TimeZone
*tz
= TimeZone::createTimeZone(AAZTDATA
[i
].zone
);
3152 cal
.adoptTimeZone(tz
);
3153 cal
.setSkippedWallTimeOption(AAZTDATA
[i
].skippedWTOpt
);
3154 AAZTDATA
[i
].base
.setTo(cal
);
3155 cal
.add(UCAL_DATE
, AAZTDATA
[i
].deltaDays
, status
);
3158 if (!AAZTDATA
[i
].expected
.isEquivalentTo(cal
, status
)) {
3159 CalFields
res(cal
, status
);
3162 const char *optDisp
= AAZTDATA
[i
].skippedWTOpt
== UCAL_WALLTIME_FIRST
? "FIRST" :
3163 AAZTDATA
[i
].skippedWTOpt
== UCAL_WALLTIME_LAST
? "LAST" : "NEXT_VALID";
3164 dataerrln(UnicodeString("Error: base:") + AAZTDATA
[i
].base
.toString(buf
, sizeof(buf
)) + ", tz:" + AAZTDATA
[i
].zone
3165 + ", delta:" + AAZTDATA
[i
].deltaDays
+ " day(s), opt:" + optDisp
3166 + ", result:" + res
.toString(buf
, sizeof(buf
))
3167 + " - expected:" + AAZTDATA
[i
].expected
.toString(buf
, sizeof(buf
)));
3172 #endif /* #if !UCONFIG_NO_FORMATTING */