1 /************************************************************************
3 * Copyright (c) 1997-2014, International Business Machines Corporation
4 * and others. All Rights Reserved.
5 ************************************************************************/
7 #include "unicode/utypes.h"
9 #if !UCONFIG_NO_FORMATTING
12 #include "unicode/dtfmtsym.h"
13 #include "unicode/gregocal.h"
14 #include "unicode/localpointer.h"
16 #include "unicode/smpdtfmt.h"
17 #include "unicode/simpletz.h"
19 #include "unicode/udat.h"
20 #include "unicode/ustring.h"
22 #include "unicode/localpointer.h"
24 #define mkcstr(U) u_austrcpy(calloc(8, u_strlen(U) + 1), U)
26 #define TEST_CHECK_STATUS {if (U_FAILURE(status)) {errln("%s:%d: Test failure. status=%s", \
27 __FILE__, __LINE__, u_errorName(status)); return;}}
29 #define TEST_ASSERT(expr) {if ((expr)==FALSE) {errln("%s:%d: Test failure \n", __FILE__, __LINE__);};}
31 // *****************************************************************************
33 // *****************************************************************************
35 UnicodeString
CalendarTest::calToStr(const Calendar
& cal
)
38 UErrorCode status
= U_ZERO_ERROR
;
41 for(i
= 0;i
<UCAL_FIELD_COUNT
;i
++) {
42 out
+= (UnicodeString("") + fieldName((UCalendarDateFields
)i
) + "=" + cal
.get((UCalendarDateFields
)i
, status
) + UnicodeString(" "));
44 out
+= "[" + UnicodeString(cal
.getType()) + "]";
46 if(cal
.inDaylightTime(status
)) {
47 out
+= UnicodeString(" (in DST), zone=");
50 out
+= UnicodeString(", zone=");
54 out
+= cal
.getTimeZone().getDisplayName(str2
);
55 d
= cal
.getTime(status
);
56 out
+= UnicodeString(" :","") + d
;
61 void CalendarTest::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char* /*par*/ )
63 if (exec
) logln("TestSuite TestCalendar");
68 logln("TestDOW943---"); logln("");
73 name
= "TestClonesUnique908";
75 logln("TestClonesUnique908---"); logln("");
76 TestClonesUnique908();
80 name
= "TestGregorianChange768";
82 logln("TestGregorianChange768---"); logln("");
83 TestGregorianChange768();
87 name
= "TestDisambiguation765";
89 logln("TestDisambiguation765---"); logln("");
90 TestDisambiguation765();
94 name
= "TestGMTvsLocal4064654";
96 logln("TestGMTvsLocal4064654---"); logln("");
97 TestGMTvsLocal4064654();
101 name
= "TestAddSetOrder621";
103 logln("TestAddSetOrder621---"); logln("");
104 TestAddSetOrder621();
110 logln("TestAdd520---"); logln("");
115 name
= "TestFieldSet4781";
117 logln("TestFieldSet4781---"); logln("");
122 name
= "TestSerialize337";
124 logln("TestSerialize337---"); logln("");
125 // TestSerialize337();
129 name
= "TestSecondsZero121";
131 logln("TestSecondsZero121---"); logln("");
132 TestSecondsZero121();
136 name
= "TestAddSetGet0610";
138 logln("TestAddSetGet0610---"); logln("");
143 name
= "TestFields060";
145 logln("TestFields060---"); logln("");
150 name
= "TestEpochStartFields";
152 logln("TestEpochStartFields---"); logln("");
153 TestEpochStartFields();
157 name
= "TestDOWProgression";
159 logln("TestDOWProgression---"); logln("");
160 TestDOWProgression();
164 name
= "TestGenericAPI";
166 logln("TestGenericAPI---"); logln("");
171 name
= "TestAddRollExtensive";
173 logln("TestAddRollExtensive---"); logln("");
174 TestAddRollExtensive();
178 name
= "TestDOW_LOCALandYEAR_WOY";
180 logln("TestDOW_LOCALandYEAR_WOY---"); logln("");
181 TestDOW_LOCALandYEAR_WOY();
187 logln("TestWOY---"); logln("");
194 logln("TestRog---"); logln("");
201 logln("TestYWOY---"); logln("");
208 logln("TestJD---"); logln("");
215 logln("TestDebug---"); logln("");
222 logln("Test6703---"); logln("");
229 logln("Test3785---"); logln("");
236 logln("Test1624---"); logln("");
241 name
= "TestTimeStamp";
243 logln("TestTimeStamp---"); logln("");
248 name
= "TestISO8601";
250 logln("TestISO8601---"); logln("");
255 name
= "TestAmbiguousWallTimeAPIs";
257 logln("TestAmbiguousWallTimeAPIs---"); logln("");
258 TestAmbiguousWallTimeAPIs();
262 name
= "TestRepeatedWallTime";
264 logln("TestRepeatedWallTime---"); logln("");
265 TestRepeatedWallTime();
269 name
= "TestSkippedWallTime";
271 logln("TestSkippedWallTime---"); logln("");
272 TestSkippedWallTime();
276 name
= "TestCloneLocale";
278 logln("TestCloneLocale---"); logln("");
283 name
= "TestAddAcrossZoneTransition";
285 logln("TestAddAcrossZoneTransition---"); logln("");
286 TestAddAcrossZoneTransition();
289 default: name
= ""; break;
293 // ---------------------------------------------------------------------------------
295 UnicodeString
CalendarTest::fieldName(UCalendarDateFields f
) {
297 #define FIELD_NAME_STR(x) case x: return (#x+5)
298 FIELD_NAME_STR( UCAL_ERA
);
299 FIELD_NAME_STR( UCAL_YEAR
);
300 FIELD_NAME_STR( UCAL_MONTH
);
301 FIELD_NAME_STR( UCAL_WEEK_OF_YEAR
);
302 FIELD_NAME_STR( UCAL_WEEK_OF_MONTH
);
303 FIELD_NAME_STR( UCAL_DATE
);
304 FIELD_NAME_STR( UCAL_DAY_OF_YEAR
);
305 FIELD_NAME_STR( UCAL_DAY_OF_WEEK
);
306 FIELD_NAME_STR( UCAL_DAY_OF_WEEK_IN_MONTH
);
307 FIELD_NAME_STR( UCAL_AM_PM
);
308 FIELD_NAME_STR( UCAL_HOUR
);
309 FIELD_NAME_STR( UCAL_HOUR_OF_DAY
);
310 FIELD_NAME_STR( UCAL_MINUTE
);
311 FIELD_NAME_STR( UCAL_SECOND
);
312 FIELD_NAME_STR( UCAL_MILLISECOND
);
313 FIELD_NAME_STR( UCAL_ZONE_OFFSET
);
314 FIELD_NAME_STR( UCAL_DST_OFFSET
);
315 FIELD_NAME_STR( UCAL_YEAR_WOY
);
316 FIELD_NAME_STR( UCAL_DOW_LOCAL
);
317 FIELD_NAME_STR( UCAL_EXTENDED_YEAR
);
318 FIELD_NAME_STR( UCAL_JULIAN_DAY
);
319 FIELD_NAME_STR( UCAL_MILLISECONDS_IN_DAY
);
320 #undef FIELD_NAME_STR
322 return UnicodeString("") + ((int32_t)f
);
327 * Test various API methods for API completeness.
330 CalendarTest::TestGenericAPI()
332 UErrorCode status
= U_ZERO_ERROR
;
335 UBool eq
= FALSE
,b4
= FALSE
,af
= FALSE
;
337 UDate when
= date(90, UCAL_APRIL
, 15);
339 UnicodeString
tzid("TestZone");
340 int32_t tzoffset
= 123400;
342 SimpleTimeZone
*zone
= new SimpleTimeZone(tzoffset
, tzid
);
343 Calendar
*cal
= Calendar::createInstance(zone
->clone(), status
);
344 if (failure(status
, "Calendar::createInstance", TRUE
)) return;
346 if (*zone
!= cal
->getTimeZone()) errln("FAIL: Calendar::getTimeZone failed");
348 Calendar
*cal2
= Calendar::createInstance(cal
->getTimeZone(), status
);
349 if (failure(status
, "Calendar::createInstance")) return;
350 cal
->setTime(when
, status
);
351 cal2
->setTime(when
, status
);
352 if (failure(status
, "Calendar::setTime")) return;
354 if (!(*cal
== *cal2
)) errln("FAIL: Calendar::operator== failed");
355 if ((*cal
!= *cal2
)) errln("FAIL: Calendar::operator!= failed");
356 if (!cal
->equals(*cal2
, status
) ||
357 cal
->before(*cal2
, status
) ||
358 cal
->after(*cal2
, status
) ||
359 U_FAILURE(status
)) errln("FAIL: equals/before/after failed");
361 logln(UnicodeString("cal=") +cal
->getTime(status
) + UnicodeString(calToStr(*cal
)));
362 logln(UnicodeString("cal2=") +cal2
->getTime(status
) + UnicodeString(calToStr(*cal2
)));
363 logln("cal2->setTime(when+1000)");
364 cal2
->setTime(when
+ 1000, status
);
365 logln(UnicodeString("cal2=") +cal2
->getTime(status
) + UnicodeString(calToStr(*cal2
)));
367 if (failure(status
, "Calendar::setTime")) return;
368 if (cal
->equals(*cal2
, status
) ||
369 cal2
->before(*cal
, status
) ||
370 cal
->after(*cal2
, status
) ||
371 U_FAILURE(status
)) errln("FAIL: equals/before/after failed after setTime(+1000)");
373 logln("cal->roll(UCAL_SECOND)");
374 cal
->roll(UCAL_SECOND
, (UBool
) TRUE
, status
);
375 logln(UnicodeString("cal=") +cal
->getTime(status
) + UnicodeString(calToStr(*cal
)));
376 cal
->roll(UCAL_SECOND
, (int32_t)0, status
);
377 logln(UnicodeString("cal=") +cal
->getTime(status
) + UnicodeString(calToStr(*cal
)));
378 if (failure(status
, "Calendar::roll")) return;
380 if (!(eq
=cal
->equals(*cal2
, status
)) ||
381 (b4
=cal
->before(*cal2
, status
)) ||
382 (af
=cal
->after(*cal2
, status
)) ||
384 errln("FAIL: equals[%c]/before[%c]/after[%c] failed after roll 1 second [should be T/F/F]",
388 logln(UnicodeString("cal=") +cal
->getTime(status
) + UnicodeString(calToStr(*cal
)));
389 logln(UnicodeString("cal2=") +cal2
->getTime(status
) + UnicodeString(calToStr(*cal2
)));
392 // Roll back to January
393 cal
->roll(UCAL_MONTH
, (int32_t)(1 + UCAL_DECEMBER
- cal
->get(UCAL_MONTH
, status
)), status
);
394 if (failure(status
, "Calendar::roll")) return;
395 if (cal
->equals(*cal2
, status
) ||
396 cal2
->before(*cal
, status
) ||
397 cal
->after(*cal2
, status
) ||
398 U_FAILURE(status
)) errln("FAIL: equals/before/after failed after rollback to January");
400 TimeZone
*z
= cal
->orphanTimeZone();
401 if (z
->getID(str
) != tzid
||
402 z
->getRawOffset() != tzoffset
)
403 errln("FAIL: orphanTimeZone failed");
408 UBool lenient
= ( i
> 0 );
409 cal
->setLenient(lenient
);
410 if (lenient
!= cal
->isLenient()) errln("FAIL: setLenient/isLenient failed");
411 // Later: Check for lenient behavior
414 for (i
=UCAL_SUNDAY
; i
<=UCAL_SATURDAY
; ++i
)
416 cal
->setFirstDayOfWeek((UCalendarDaysOfWeek
)i
);
417 if (cal
->getFirstDayOfWeek() != i
) errln("FAIL: set/getFirstDayOfWeek failed");
418 UErrorCode aStatus
= U_ZERO_ERROR
;
419 if (cal
->getFirstDayOfWeek(aStatus
) != i
|| U_FAILURE(aStatus
)) errln("FAIL: getFirstDayOfWeek(status) failed");
424 cal
->setMinimalDaysInFirstWeek((uint8_t)i
);
425 if (cal
->getMinimalDaysInFirstWeek() != i
) errln("FAIL: set/getFirstDayOfWeek failed");
428 for (i
=0; i
<UCAL_FIELD_COUNT
; ++i
)
430 if (cal
->getMinimum((UCalendarDateFields
)i
) > cal
->getGreatestMinimum((UCalendarDateFields
)i
))
431 errln(UnicodeString("FAIL: getMinimum larger than getGreatestMinimum for field ") + i
);
432 if (cal
->getLeastMaximum((UCalendarDateFields
)i
) > cal
->getMaximum((UCalendarDateFields
)i
))
433 errln(UnicodeString("FAIL: getLeastMaximum larger than getMaximum for field ") + i
);
434 if (cal
->getMinimum((UCalendarDateFields
)i
) >= cal
->getMaximum((UCalendarDateFields
)i
))
435 errln(UnicodeString("FAIL: getMinimum not less than getMaximum for field ") + i
);
438 cal
->adoptTimeZone(TimeZone::createDefault());
440 cal
->set(1984, 5, 24);
441 if (cal
->getTime(status
) != date(84, 5, 24) || U_FAILURE(status
))
442 errln("FAIL: Calendar::set(3 args) failed");
445 cal
->set(1985, 3, 2, 11, 49);
446 if (cal
->getTime(status
) != date(85, 3, 2, 11, 49) || U_FAILURE(status
))
447 errln("FAIL: Calendar::set(5 args) failed");
450 cal
->set(1995, 9, 12, 1, 39, 55);
451 if (cal
->getTime(status
) != date(95, 9, 12, 1, 39, 55) || U_FAILURE(status
))
452 errln("FAIL: Calendar::set(6 args) failed");
454 cal
->getTime(status
);
455 if (failure(status
, "Calendar::getTime")) return;
456 for (i
=0; i
<UCAL_FIELD_COUNT
; ++i
)
459 case UCAL_YEAR
: case UCAL_MONTH
: case UCAL_DATE
:
460 case UCAL_HOUR_OF_DAY
: case UCAL_MINUTE
: case UCAL_SECOND
:
461 case UCAL_EXTENDED_YEAR
:
462 if (!cal
->isSet((UCalendarDateFields
)i
)) errln("FAIL: Calendar::isSet F, should be T " + fieldName((UCalendarDateFields
)i
));
465 if (cal
->isSet((UCalendarDateFields
)i
)) errln("FAIL: Calendar::isSet = T, should be F " + fieldName((UCalendarDateFields
)i
));
467 cal
->clear((UCalendarDateFields
)i
);
468 if (cal
->isSet((UCalendarDateFields
)i
)) errln("FAIL: Calendar::clear/isSet failed " + fieldName((UCalendarDateFields
)i
));
471 if(cal
->getActualMinimum(Calendar::SECOND
, status
) != 0){
472 errln("Calendar is suppose to return 0 for getActualMinimum");
475 Calendar
*cal3
= Calendar::createInstance(status
);
476 cal3
->roll(Calendar::SECOND
, (int32_t)0, status
);
477 if (failure(status
, "Calendar::roll(EDateFields, int32_t, UErrorCode)")) return;
484 const Locale
* loc
= Calendar::getAvailableLocales(count
);
485 if (count
< 1 || loc
== 0)
487 dataerrln("FAIL: getAvailableLocales failed");
491 for (i
=0; i
<count
; ++i
)
493 cal
= Calendar::createInstance(loc
[i
], status
);
494 if (failure(status
, "Calendar::createInstance")) return;
499 cal
= Calendar::createInstance(TimeZone::createDefault(), Locale::getEnglish(), status
);
500 if (failure(status
, "Calendar::createInstance")) return;
503 cal
= Calendar::createInstance(*zone
, Locale::getEnglish(), status
);
504 if (failure(status
, "Calendar::createInstance")) return;
507 GregorianCalendar
*gc
= new GregorianCalendar(*zone
, status
);
508 if (failure(status
, "new GregorianCalendar")) return;
511 gc
= new GregorianCalendar(Locale::getEnglish(), status
);
512 if (failure(status
, "new GregorianCalendar")) return;
515 gc
= new GregorianCalendar(Locale::getEnglish(), status
);
518 gc
= new GregorianCalendar(*zone
, Locale::getEnglish(), status
);
519 if (failure(status
, "new GregorianCalendar")) return;
522 gc
= new GregorianCalendar(zone
, status
);
523 if (failure(status
, "new GregorianCalendar")) return;
526 gc
= new GregorianCalendar(1998, 10, 14, 21, 43, status
);
527 if (gc
->getTime(status
) != (d
=date(98, 10, 14, 21, 43) )|| U_FAILURE(status
))
528 errln("FAIL: new GregorianCalendar(ymdhm) failed with " + UnicodeString(u_errorName(status
)) + ", cal=" + gc
->getTime(status
) + UnicodeString(calToStr(*gc
)) + ", d=" + d
);
530 logln(UnicodeString("GOOD: cal=") +gc
->getTime(status
) + UnicodeString(calToStr(*gc
)) + ", d=" + d
);
533 gc
= new GregorianCalendar(1998, 10, 14, 21, 43, 55, status
);
534 if (gc
->getTime(status
) != (d
=date(98, 10, 14, 21, 43, 55)) || U_FAILURE(status
))
535 errln("FAIL: new GregorianCalendar(ymdhms) failed with " + UnicodeString(u_errorName(status
)));
537 GregorianCalendar
gc2(Locale::getEnglish(), status
);
538 if (failure(status
, "new GregorianCalendar")) return;
540 if (gc2
!= *gc
|| !(gc2
== *gc
)) errln("FAIL: GregorianCalendar assignment/operator==/operator!= failed");
544 /* Code coverage for Calendar class. */
545 cal
= Calendar::createInstance(status
);
546 if (failure(status
, "Calendar::createInstance")) {
549 ((Calendar
*)cal
)->roll(UCAL_HOUR
, (int32_t)100, status
);
550 ((Calendar
*)cal
)->clear(UCAL_HOUR
);
551 #if !UCONFIG_NO_SERVICE
552 URegistryKey key
= cal
->registerFactory(NULL
, status
);
553 cal
->unregister(key
, status
);
558 status
= U_ZERO_ERROR
;
559 cal
= Calendar::createInstance(Locale("he_IL@calendar=hebrew"), status
);
560 if (failure(status
, "Calendar::createInstance")) {
563 cal
->roll(Calendar::MONTH
, (int32_t)100, status
);
566 LocalPointer
<StringEnumeration
> values(
567 Calendar::getKeywordValuesForLocale("calendar", Locale("he"), FALSE
, status
));
568 if (values
.isNull() || U_FAILURE(status
)) {
569 dataerrln("FAIL: Calendar::getKeywordValuesForLocale(he): %s", u_errorName(status
));
571 UBool containsHebrew
= FALSE
;
572 const char *charValue
;
574 while ((charValue
= values
->next(&valueLength
, status
)) != NULL
) {
575 if (valueLength
== 6 && strcmp(charValue
, "hebrew") == 0) {
576 containsHebrew
= TRUE
;
579 if (!containsHebrew
) {
580 errln("Calendar::getKeywordValuesForLocale(he)->next() does not contain \"hebrew\"");
583 values
->reset(status
);
584 containsHebrew
= FALSE
;
585 UnicodeString hebrew
= UNICODE_STRING_SIMPLE("hebrew");
586 const UChar
*ucharValue
;
587 while ((ucharValue
= values
->unext(&valueLength
, status
)) != NULL
) {
588 UnicodeString
value(FALSE
, ucharValue
, valueLength
);
589 if (value
== hebrew
) {
590 containsHebrew
= TRUE
;
593 if (!containsHebrew
) {
594 errln("Calendar::getKeywordValuesForLocale(he)->unext() does not contain \"hebrew\"");
597 values
->reset(status
);
598 containsHebrew
= FALSE
;
599 const UnicodeString
*stringValue
;
600 while ((stringValue
= values
->snext(status
)) != NULL
) {
601 if (*stringValue
== hebrew
) {
602 containsHebrew
= TRUE
;
605 if (!containsHebrew
) {
606 errln("Calendar::getKeywordValuesForLocale(he)->snext() does not contain \"hebrew\"");
612 // -------------------------------------
615 * This test confirms the correct behavior of add when incrementing
616 * through subsequent days.
619 CalendarTest::TestRog()
621 UErrorCode status
= U_ZERO_ERROR
;
622 GregorianCalendar
* gc
= new GregorianCalendar(status
);
623 if (failure(status
, "new GregorianCalendar", TRUE
)) return;
624 int32_t year
= 1997, month
= UCAL_APRIL
, date
= 1;
625 gc
->set(year
, month
, date
);
626 gc
->set(UCAL_HOUR_OF_DAY
, 23);
627 gc
->set(UCAL_MINUTE
, 0);
628 gc
->set(UCAL_SECOND
, 0);
629 gc
->set(UCAL_MILLISECOND
, 0);
630 for (int32_t i
= 0; i
< 9; i
++, gc
->add(UCAL_DATE
, 1, status
)) {
631 if (U_FAILURE(status
)) { errln("Calendar::add failed"); return; }
632 if (gc
->get(UCAL_YEAR
, status
) != year
||
633 gc
->get(UCAL_MONTH
, status
) != month
||
634 gc
->get(UCAL_DATE
, status
) != (date
+ i
)) errln("FAIL: Date wrong");
635 if (U_FAILURE(status
)) { errln("Calendar::get failed"); return; }
640 // -------------------------------------
643 * Test the handling of the day of the week, checking for correctness and
644 * for correct minimum and maximum values.
647 CalendarTest::TestDOW943()
653 void CalendarTest::dowTest(UBool lenient
)
655 UErrorCode status
= U_ZERO_ERROR
;
656 GregorianCalendar
* cal
= new GregorianCalendar(status
);
657 if (failure(status
, "new GregorianCalendar", TRUE
)) return;
658 logln("cal - Aug 12, 1997\n");
659 cal
->set(1997, UCAL_AUGUST
, 12);
660 cal
->getTime(status
);
661 if (U_FAILURE(status
)) { errln("Calendar::getTime failed"); return; }
662 logln((lenient
?UnicodeString("LENIENT0: "):UnicodeString("nonlenient0: ")) + UnicodeString(calToStr(*cal
)));
663 cal
->setLenient(lenient
);
664 logln("cal - Dec 1, 1996\n");
665 cal
->set(1996, UCAL_DECEMBER
, 1);
666 logln((lenient
?UnicodeString("LENIENT: "):UnicodeString("nonlenient: ")) + UnicodeString(calToStr(*cal
)));
667 int32_t dow
= cal
->get(UCAL_DAY_OF_WEEK
, status
);
668 if (U_FAILURE(status
)) { errln("Calendar::get failed [%s]", u_errorName(status
)); return; }
669 int32_t min
= cal
->getMinimum(UCAL_DAY_OF_WEEK
);
670 int32_t max
= cal
->getMaximum(UCAL_DAY_OF_WEEK
);
672 dow
> max
) errln(UnicodeString("FAIL: Day of week ") + (int32_t)dow
+ " out of range");
673 if (dow
!= UCAL_SUNDAY
) errln("FAIL: Day of week should be SUNDAY[%d] not %d", UCAL_SUNDAY
, dow
);
674 if (min
!= UCAL_SUNDAY
||
675 max
!= UCAL_SATURDAY
) errln("FAIL: Min/max bad");
679 // -------------------------------------
682 * Confirm that cloned Calendar objects do not inadvertently share substructures.
685 CalendarTest::TestClonesUnique908()
687 UErrorCode status
= U_ZERO_ERROR
;
688 Calendar
*c
= Calendar::createInstance(status
);
689 if (failure(status
, "Calendar::createInstance", TRUE
)) return;
690 Calendar
*d
= (Calendar
*) c
->clone();
691 c
->set(UCAL_MILLISECOND
, 123);
692 d
->set(UCAL_MILLISECOND
, 456);
693 if (c
->get(UCAL_MILLISECOND
, status
) != 123 ||
694 d
->get(UCAL_MILLISECOND
, status
) != 456) {
695 errln("FAIL: Clones share fields");
697 if (U_FAILURE(status
)) { errln("Calendar::get failed"); return; }
702 // -------------------------------------
705 * Confirm that the Gregorian cutoff value works as advertised.
708 CalendarTest::TestGregorianChange768()
711 UErrorCode status
= U_ZERO_ERROR
;
713 GregorianCalendar
* c
= new GregorianCalendar(status
);
714 if (failure(status
, "new GregorianCalendar", TRUE
)) return;
715 logln(UnicodeString("With cutoff ") + dateToString(c
->getGregorianChange(), str
));
716 b
= c
->isLeapYear(1800);
717 logln(UnicodeString(" isLeapYear(1800) = ") + (b
? "true" : "false"));
718 logln(UnicodeString(" (should be FALSE)"));
719 if (b
) errln("FAIL");
720 c
->setGregorianChange(date(0, 0, 1), status
);
721 if (U_FAILURE(status
)) { errln("GregorianCalendar::setGregorianChange failed"); return; }
722 logln(UnicodeString("With cutoff ") + dateToString(c
->getGregorianChange(), str
));
723 b
= c
->isLeapYear(1800);
724 logln(UnicodeString(" isLeapYear(1800) = ") + (b
? "true" : "false"));
725 logln(UnicodeString(" (should be TRUE)"));
726 if (!b
) errln("FAIL");
730 // -------------------------------------
733 * Confirm the functioning of the field disambiguation algorithm.
736 CalendarTest::TestDisambiguation765()
738 UErrorCode status
= U_ZERO_ERROR
;
739 Calendar
*c
= Calendar::createInstance("en_US", status
);
740 if (failure(status
, "Calendar::createInstance", TRUE
)) return;
741 c
->setLenient(FALSE
);
743 c
->set(UCAL_YEAR
, 1997);
744 c
->set(UCAL_MONTH
, UCAL_JUNE
);
745 c
->set(UCAL_DATE
, 3);
746 verify765("1997 third day of June = ", c
, 1997, UCAL_JUNE
, 3);
748 c
->set(UCAL_YEAR
, 1997);
749 c
->set(UCAL_DAY_OF_WEEK
, UCAL_TUESDAY
);
750 c
->set(UCAL_MONTH
, UCAL_JUNE
);
751 c
->set(UCAL_DAY_OF_WEEK_IN_MONTH
, 1);
752 verify765("1997 first Tuesday in June = ", c
, 1997, UCAL_JUNE
, 3);
754 c
->set(UCAL_YEAR
, 1997);
755 c
->set(UCAL_DAY_OF_WEEK
, UCAL_TUESDAY
);
756 c
->set(UCAL_MONTH
, UCAL_JUNE
);
757 c
->set(UCAL_DAY_OF_WEEK_IN_MONTH
, - 1);
758 verify765("1997 last Tuesday in June = ", c
, 1997, UCAL_JUNE
, 24);
760 status
= U_ZERO_ERROR
;
762 c
->set(UCAL_YEAR
, 1997);
763 c
->set(UCAL_DAY_OF_WEEK
, UCAL_TUESDAY
);
764 c
->set(UCAL_MONTH
, UCAL_JUNE
);
765 c
->set(UCAL_DAY_OF_WEEK_IN_MONTH
, 0);
767 verify765("1997 zero-th Tuesday in June = ", status
);
770 c
->set(UCAL_YEAR
, 1997);
771 c
->set(UCAL_DAY_OF_WEEK
, UCAL_TUESDAY
);
772 c
->set(UCAL_MONTH
, UCAL_JUNE
);
773 c
->set(UCAL_WEEK_OF_MONTH
, 1);
774 verify765("1997 Tuesday in week 1 of June = ", c
, 1997, UCAL_JUNE
, 3);
776 c
->set(UCAL_YEAR
, 1997);
777 c
->set(UCAL_DAY_OF_WEEK
, UCAL_TUESDAY
);
778 c
->set(UCAL_MONTH
, UCAL_JUNE
);
779 c
->set(UCAL_WEEK_OF_MONTH
, 5);
780 verify765("1997 Tuesday in week 5 of June = ", c
, 1997, UCAL_JULY
, 1);
782 status
= U_ZERO_ERROR
;
784 c
->set(UCAL_YEAR
, 1997);
785 c
->set(UCAL_DAY_OF_WEEK
, UCAL_TUESDAY
);
786 c
->set(UCAL_MONTH
, UCAL_JUNE
);
787 c
->set(UCAL_WEEK_OF_MONTH
, 0);
788 c
->setMinimalDaysInFirstWeek(1);
790 verify765("1997 Tuesday in week 0 of June = ", status
);
792 /* Note: The following test used to expect YEAR 1997, WOY 1 to
793 * resolve to a date in Dec 1996; that is, to behave as if
794 * YEAR_WOY were 1997. With the addition of a new explicit
795 * YEAR_WOY field, YEAR_WOY must itself be set if that is what is
796 * desired. Using YEAR in combination with WOY is ambiguous, and
797 * results in the first WOY/DOW day of the year satisfying the
798 * given fields (there may be up to two such days). In this case,
799 * it propertly resolves to Tue Dec 30 1997, which has a WOY value
800 * of 1 (for YEAR_WOY 1998) and a DOW of Tuesday, and falls in the
801 * _calendar_ year 1997, as specified. - aliu */
803 c
->set(UCAL_YEAR_WOY
, 1997); // aliu
804 c
->set(UCAL_DAY_OF_WEEK
, UCAL_TUESDAY
);
805 c
->set(UCAL_WEEK_OF_YEAR
, 1);
806 verify765("1997 Tuesday in week 1 of yearWOY = ", c
, 1996, UCAL_DECEMBER
, 31);
807 c
->clear(); // - add test for YEAR
808 c
->setMinimalDaysInFirstWeek(1);
809 c
->set(UCAL_YEAR
, 1997);
810 c
->set(UCAL_DAY_OF_WEEK
, UCAL_TUESDAY
);
811 c
->set(UCAL_WEEK_OF_YEAR
, 1);
812 verify765("1997 Tuesday in week 1 of year = ", c
, 1997, UCAL_DECEMBER
, 30);
814 c
->set(UCAL_YEAR
, 1997);
815 c
->set(UCAL_DAY_OF_WEEK
, UCAL_TUESDAY
);
816 c
->set(UCAL_WEEK_OF_YEAR
, 10);
817 verify765("1997 Tuesday in week 10 of year = ", c
, 1997, UCAL_MARCH
, 4);
820 // {sfb} week 0 is no longer a valid week of year
822 c->set(Calendar::YEAR, 1997);
823 c->set(Calendar::DAY_OF_WEEK, Calendar::TUESDAY);
824 //c->set(Calendar::WEEK_OF_YEAR, 0);
825 c->set(Calendar::WEEK_OF_YEAR, 1);
826 verify765("1997 Tuesday in week 0 of year = ", c, 1996, Calendar::DECEMBER, 24);*/
829 //catch(IllegalArgumentException ex) {
830 // errln("FAIL: Exception seen:");
831 // ex.printStackTrace(log);
836 // -------------------------------------
839 CalendarTest::verify765(const UnicodeString
& msg
, Calendar
* c
, int32_t year
, int32_t month
, int32_t day
)
842 UErrorCode status
= U_ZERO_ERROR
;
843 int32_t y
= c
->get(UCAL_YEAR
, status
);
844 int32_t m
= c
->get(UCAL_MONTH
, status
);
845 int32_t d
= c
->get(UCAL_DATE
, status
);
849 if (U_FAILURE(status
)) { errln("FAIL: Calendar::get failed"); return; }
850 logln("PASS: " + msg
+ dateToString(c
->getTime(status
), str
));
851 if (U_FAILURE(status
)) { errln("Calendar::getTime failed"); return; }
854 errln("FAIL: " + msg
+ dateToString(c
->getTime(status
), str
) + "; expected " + (int32_t)year
+ "/" + (int32_t)(month
+ 1) + "/" + (int32_t)day
+
855 "; got " + (int32_t)y
+ "/" + (int32_t)(m
+ 1) + "/" + (int32_t)d
+ " for Locale: " + c
->getLocaleID(ULOC_ACTUAL_LOCALE
,status
));
856 if (U_FAILURE(status
)) { errln("Calendar::getTime failed"); return; }
860 // -------------------------------------
863 CalendarTest::verify765(const UnicodeString
& msg
/*, IllegalArgumentException e*/, UErrorCode status
)
865 if (status
!= U_ILLEGAL_ARGUMENT_ERROR
) errln("FAIL: No IllegalArgumentException for " + msg
);
866 else logln("PASS: " + msg
+ "IllegalArgument as expected");
869 // -------------------------------------
872 * Confirm that the offset between local time and GMT behaves as expected.
875 CalendarTest::TestGMTvsLocal4064654()
877 test4064654(1997, 1, 1, 12, 0, 0);
878 test4064654(1997, 4, 16, 18, 30, 0);
881 // -------------------------------------
884 CalendarTest::test4064654(int32_t yr
, int32_t mo
, int32_t dt
, int32_t hr
, int32_t mn
, int32_t sc
)
887 UErrorCode status
= U_ZERO_ERROR
;
889 Calendar
*gmtcal
= Calendar::createInstance(status
);
890 if (failure(status
, "Calendar::createInstance", TRUE
)) return;
891 gmtcal
->adoptTimeZone(TimeZone::createTimeZone("Africa/Casablanca"));
892 gmtcal
->set(yr
, mo
- 1, dt
, hr
, mn
, sc
);
893 gmtcal
->set(UCAL_MILLISECOND
, 0);
894 date
= gmtcal
->getTime(status
);
895 if (U_FAILURE(status
)) { errln("Calendar::getTime failed"); return; }
896 logln("date = " + dateToString(date
, str
));
897 Calendar
*cal
= Calendar::createInstance(status
);
898 if (U_FAILURE(status
)) { errln("Calendar::createInstance failed"); return; }
899 cal
->setTime(date
, status
);
900 if (U_FAILURE(status
)) { errln("Calendar::setTime failed"); return; }
901 int32_t offset
= cal
->getTimeZone().getOffset((uint8_t)cal
->get(UCAL_ERA
, status
),
902 cal
->get(UCAL_YEAR
, status
),
903 cal
->get(UCAL_MONTH
, status
),
904 cal
->get(UCAL_DATE
, status
),
905 (uint8_t)cal
->get(UCAL_DAY_OF_WEEK
, status
),
906 cal
->get(UCAL_MILLISECOND
, status
), status
);
907 if (U_FAILURE(status
)) { errln("Calendar::get failed"); return; }
908 logln("offset for " + dateToString(date
, str
) + "= " + (offset
/ 1000 / 60 / 60.0) + "hr");
909 int32_t utc
= ((cal
->get(UCAL_HOUR_OF_DAY
, status
) * 60 +
910 cal
->get(UCAL_MINUTE
, status
)) * 60 +
911 cal
->get(UCAL_SECOND
, status
)) * 1000 +
912 cal
->get(UCAL_MILLISECOND
, status
) - offset
;
913 if (U_FAILURE(status
)) { errln("Calendar::get failed"); return; }
914 int32_t expected
= ((hr
* 60 + mn
) * 60 + sc
) * 1000;
915 if (utc
!= expected
) errln(UnicodeString("FAIL: Discrepancy of ") + (utc
- expected
) +
916 " millis = " + ((utc
- expected
) / 1000 / 60 / 60.0) + " hr");
921 // -------------------------------------
924 * The operations of adding and setting should not exhibit pathological
925 * dependence on the order of operations. This test checks for this.
928 CalendarTest::TestAddSetOrder621()
930 UDate d
= date(97, 4, 14, 13, 23, 45);
931 UErrorCode status
= U_ZERO_ERROR
;
932 Calendar
*cal
= Calendar::createInstance(status
);
933 if (failure(status
, "Calendar::createInstance", TRUE
)) return;
935 cal
->setTime(d
, status
);
936 if (U_FAILURE(status
)) {
937 errln("Calendar::setTime failed");
941 cal
->add(UCAL_DATE
, - 5, status
);
942 if (U_FAILURE(status
)) {
943 errln("Calendar::add failed");
947 cal
->set(UCAL_HOUR_OF_DAY
, 0);
948 cal
->set(UCAL_MINUTE
, 0);
949 cal
->set(UCAL_SECOND
, 0);
951 dateToString(cal
->getTime(status
), s
);
952 if (U_FAILURE(status
)) {
953 errln("Calendar::getTime failed");
959 cal
= Calendar::createInstance(status
);
960 if (U_FAILURE(status
)) {
961 errln("Calendar::createInstance failed");
965 cal
->setTime(d
, status
);
966 if (U_FAILURE(status
)) {
967 errln("Calendar::setTime failed");
971 cal
->set(UCAL_HOUR_OF_DAY
, 0);
972 cal
->set(UCAL_MINUTE
, 0);
973 cal
->set(UCAL_SECOND
, 0);
974 cal
->add(UCAL_DATE
, - 5, status
);
975 if (U_FAILURE(status
)) {
976 errln("Calendar::add failed");
981 dateToString(cal
->getTime(status
), s2
);
982 if (U_FAILURE(status
)) {
983 errln("Calendar::getTime failed");
988 logln("Pass: " + s
+ " == " + s2
);
990 errln("FAIL: " + s
+ " != " + s2
);
994 // -------------------------------------
997 * Confirm that adding to various fields works.
1000 CalendarTest::TestAdd520()
1002 int32_t y
= 1997, m
= UCAL_FEBRUARY
, d
= 1;
1003 UErrorCode status
= U_ZERO_ERROR
;
1004 GregorianCalendar
*temp
= new GregorianCalendar(y
, m
, d
, status
);
1005 if (failure(status
, "new GregorianCalendar", TRUE
)) return;
1006 check520(temp
, y
, m
, d
);
1007 temp
->add(UCAL_YEAR
, 1, status
);
1008 if (U_FAILURE(status
)) { errln("Calendar::add failed"); return; }
1010 check520(temp
, y
, m
, d
);
1011 temp
->add(UCAL_MONTH
, 1, status
);
1012 if (U_FAILURE(status
)) { errln("Calendar::add failed"); return; }
1014 check520(temp
, y
, m
, d
);
1015 temp
->add(UCAL_DATE
, 1, status
);
1016 if (U_FAILURE(status
)) { errln("Calendar::add failed"); return; }
1018 check520(temp
, y
, m
, d
);
1019 temp
->add(UCAL_DATE
, 2, status
);
1020 if (U_FAILURE(status
)) { errln("Calendar::add failed"); return; }
1022 check520(temp
, y
, m
, d
);
1023 temp
->add(UCAL_DATE
, 28, status
);
1024 if (U_FAILURE(status
)) { errln("Calendar::add failed"); return; }
1026 check520(temp
, y
, m
, d
);
1030 // -------------------------------------
1033 * Execute adding and rolling in GregorianCalendar extensively,
1036 CalendarTest::TestAddRollExtensive()
1038 int32_t maxlimit
= 40;
1039 int32_t y
= 1997, m
= UCAL_FEBRUARY
, d
= 1, hr
= 1, min
= 1, sec
= 0, ms
= 0;
1040 UErrorCode status
= U_ZERO_ERROR
;
1041 GregorianCalendar
*temp
= new GregorianCalendar(y
, m
, d
, status
);
1042 if (failure(status
, "new GregorianCalendar", TRUE
)) return;
1044 temp
->set(UCAL_HOUR
, hr
);
1045 temp
->set(UCAL_MINUTE
, min
);
1046 temp
->set(UCAL_SECOND
, sec
);
1047 temp
->set(UCAL_MILLISECOND
, ms
);
1048 temp
->setMinimalDaysInFirstWeek(1);
1050 UCalendarDateFields e
;
1052 logln("Testing GregorianCalendar add...");
1054 while (e
< UCAL_FIELD_COUNT
) {
1056 int32_t limit
= maxlimit
;
1057 status
= U_ZERO_ERROR
;
1058 for (i
= 0; i
< limit
; i
++) {
1059 temp
->add(e
, 1, status
);
1060 if (U_FAILURE(status
)) { limit
= i
; status
= U_ZERO_ERROR
; }
1062 for (i
= 0; i
< limit
; i
++) {
1063 temp
->add(e
, -1, status
);
1064 if (U_FAILURE(status
)) { errln("GregorianCalendar::add -1 failed"); return; }
1066 check520(temp
, y
, m
, d
, hr
, min
, sec
, ms
, e
);
1068 e
= (UCalendarDateFields
) ((int32_t) e
+ 1);
1071 logln("Testing GregorianCalendar roll...");
1073 while (e
< UCAL_FIELD_COUNT
) {
1075 int32_t limit
= maxlimit
;
1076 status
= U_ZERO_ERROR
;
1077 for (i
= 0; i
< limit
; i
++) {
1078 logln(calToStr(*temp
) + UnicodeString(" " ) + fieldName(e
) + UnicodeString("++") );
1079 temp
->roll(e
, 1, status
);
1080 if (U_FAILURE(status
)) {
1081 logln("caltest.cpp:%d e=%d, i=%d - roll(+) err %s\n", __LINE__
, (int) e
, (int) i
, u_errorName(status
));
1082 logln(calToStr(*temp
));
1083 limit
= i
; status
= U_ZERO_ERROR
;
1086 for (i
= 0; i
< limit
; i
++) {
1087 logln("caltest.cpp:%d e=%d, i=%d\n", __LINE__
, (int) e
, (int) i
);
1088 logln(calToStr(*temp
) + UnicodeString(" " ) + fieldName(e
) + UnicodeString("--") );
1089 temp
->roll(e
, -1, status
);
1090 if (U_FAILURE(status
)) { errln(UnicodeString("GregorianCalendar::roll ") + CalendarTest::fieldName(e
) + " count=" + UnicodeString('@'+i
) + " by -1 failed with " + u_errorName(status
) ); return; }
1092 check520(temp
, y
, m
, d
, hr
, min
, sec
, ms
, e
);
1094 e
= (UCalendarDateFields
) ((int32_t) e
+ 1);
1100 // -------------------------------------
1102 CalendarTest::check520(Calendar
* c
,
1103 int32_t y
, int32_t m
, int32_t d
,
1104 int32_t hr
, int32_t min
, int32_t sec
,
1105 int32_t ms
, UCalendarDateFields field
)
1108 UErrorCode status
= U_ZERO_ERROR
;
1109 if (c
->get(UCAL_YEAR
, status
) != y
||
1110 c
->get(UCAL_MONTH
, status
) != m
||
1111 c
->get(UCAL_DATE
, status
) != d
||
1112 c
->get(UCAL_HOUR
, status
) != hr
||
1113 c
->get(UCAL_MINUTE
, status
) != min
||
1114 c
->get(UCAL_SECOND
, status
) != sec
||
1115 c
->get(UCAL_MILLISECOND
, status
) != ms
) {
1116 errln(UnicodeString("U_FAILURE for field ") + (int32_t)field
+
1117 ": Expected y/m/d h:m:s:ms of " +
1118 y
+ "/" + (m
+ 1) + "/" + d
+ " " +
1119 hr
+ ":" + min
+ ":" + sec
+ ":" + ms
+
1120 "; got " + c
->get(UCAL_YEAR
, status
) +
1121 "/" + (c
->get(UCAL_MONTH
, status
) + 1) +
1122 "/" + c
->get(UCAL_DATE
, status
) +
1123 " " + c
->get(UCAL_HOUR
, status
) + ":" +
1124 c
->get(UCAL_MINUTE
, status
) + ":" +
1125 c
->get(UCAL_SECOND
, status
) + ":" +
1126 c
->get(UCAL_MILLISECOND
, status
)
1129 if (U_FAILURE(status
)) { errln("Calendar::get failed"); return; }
1132 logln(UnicodeString("Confirmed: ") + y
+ "/" +
1133 (m
+ 1) + "/" + d
+ " " +
1134 hr
+ ":" + min
+ ":" + sec
+ ":" + ms
);
1137 // -------------------------------------
1139 CalendarTest::check520(Calendar
* c
,
1140 int32_t y
, int32_t m
, int32_t d
)
1143 UErrorCode status
= U_ZERO_ERROR
;
1144 if (c
->get(UCAL_YEAR
, status
) != y
||
1145 c
->get(UCAL_MONTH
, status
) != m
||
1146 c
->get(UCAL_DATE
, status
) != d
) {
1147 errln(UnicodeString("FAILURE: Expected y/m/d of ") +
1148 y
+ "/" + (m
+ 1) + "/" + d
+ " " +
1149 "; got " + c
->get(UCAL_YEAR
, status
) +
1150 "/" + (c
->get(UCAL_MONTH
, status
) + 1) +
1151 "/" + c
->get(UCAL_DATE
, status
)
1154 if (U_FAILURE(status
)) { errln("Calendar::get failed"); return; }
1157 logln(UnicodeString("Confirmed: ") + y
+ "/" +
1161 // -------------------------------------
1164 * Test that setting of fields works. In particular, make sure that all instances
1165 * of GregorianCalendar don't share a static instance of the fields array.
1168 CalendarTest::TestFieldSet4781()
1171 UErrorCode status
= U_ZERO_ERROR
;
1172 GregorianCalendar
*g
= new GregorianCalendar(status
);
1173 if (failure(status
, "new GregorianCalendar", TRUE
)) return;
1174 GregorianCalendar
*g2
= new GregorianCalendar(status
);
1175 if (U_FAILURE(status
)) { errln("Couldn't create GregorianCalendar"); return; }
1176 g2
->set(UCAL_HOUR
, 12, status
);
1177 g2
->set(UCAL_MINUTE
, 0, status
);
1178 g2
->set(UCAL_SECOND
, 0, status
);
1179 if (U_FAILURE(status
)) { errln("Calendar::set failed"); return; }
1180 if (*g
== *g2
) logln("Same");
1181 else logln("Different");
1183 //catch(IllegalArgumentException e) {
1184 //errln("Unexpected exception seen: " + e);
1190 // -------------------------------------
1192 /* We don't support serialization on C++
1194 CalendarTest::TestSerialize337()
1196 Calendar cal = Calendar::getInstance();
1199 FileOutputStream f = new FileOutputStream(FILENAME);
1200 ObjectOutput s = new ObjectOutputStream(f);
1201 s.writeObject(PREFIX);
1203 s.writeObject(POSTFIX);
1205 FileInputStream in = new FileInputStream(FILENAME);
1206 ObjectInputStream t = new ObjectInputStream(in);
1207 UnicodeString& pre = (UnicodeString&) t.readObject();
1208 Calendar c = (Calendar) t.readObject();
1209 UnicodeString& post = (UnicodeString&) t.readObject();
1211 ok = pre.equals(PREFIX) &&
1212 post.equals(POSTFIX) &&
1214 File fl = new File(FILENAME);
1217 catch(IOException e) {
1218 errln("FAIL: Exception received:");
1219 e.printStackTrace(log);
1221 catch(ClassNotFoundException e) {
1222 errln("FAIL: Exception received:");
1223 e.printStackTrace(log);
1225 if (!ok) errln("Serialization of Calendar object failed.");
1228 UnicodeString& CalendarTest::PREFIX = "abc";
1230 UnicodeString& CalendarTest::POSTFIX = "def";
1232 UnicodeString& CalendarTest::FILENAME = "tmp337.bin";
1235 // -------------------------------------
1238 * Verify that the seconds of a Calendar can be zeroed out through the
1239 * expected sequence of operations.
1242 CalendarTest::TestSecondsZero121()
1244 UErrorCode status
= U_ZERO_ERROR
;
1245 Calendar
*cal
= new GregorianCalendar(status
);
1246 if (failure(status
, "new GregorianCalendar", TRUE
)) return;
1247 cal
->setTime(Calendar::getNow(), status
);
1248 if (U_FAILURE(status
)) { errln("Calendar::setTime failed"); return; }
1249 cal
->set(UCAL_SECOND
, 0);
1250 if (U_FAILURE(status
)) { errln("Calendar::set failed"); return; }
1251 UDate d
= cal
->getTime(status
);
1252 if (U_FAILURE(status
)) { errln("Calendar::getTime failed"); return; }
1255 if (s
.indexOf("DATE_FORMAT_FAILURE") >= 0) {
1256 dataerrln("Got: \"DATE_FORMAT_FAILURE\".");
1257 } else if (s
.indexOf(":00 ") < 0) {
1258 errln("Expected to see :00 in " + s
);
1263 // -------------------------------------
1266 * Verify that a specific sequence of adding and setting works as expected;
1267 * it should not vary depending on when and whether the get method is
1271 CalendarTest::TestAddSetGet0610()
1273 UnicodeString
EXPECTED_0610("1993/0/5", "");
1274 UErrorCode status
= U_ZERO_ERROR
;
1276 Calendar
*calendar
= new GregorianCalendar(status
);
1277 if (failure(status
, "new GregorianCalendar", TRUE
)) return;
1278 calendar
->set(1993, UCAL_JANUARY
, 4);
1279 logln("1A) " + value(calendar
));
1280 calendar
->add(UCAL_DATE
, 1, status
);
1281 if (U_FAILURE(status
)) { errln("Calendar::add failed"); return; }
1282 UnicodeString v
= value(calendar
);
1284 logln("--) 1993/0/5");
1285 if (!(v
== EXPECTED_0610
)) errln("Expected " + EXPECTED_0610
+ "; saw " + v
);
1289 Calendar
*calendar
= new GregorianCalendar(1993, UCAL_JANUARY
, 4, status
);
1290 if (U_FAILURE(status
)) { errln("Couldn't create GregorianCalendar"); return; }
1291 logln("2A) " + value(calendar
));
1292 calendar
->add(UCAL_DATE
, 1, status
);
1293 if (U_FAILURE(status
)) { errln("Calendar::add failed"); return; }
1294 UnicodeString v
= value(calendar
);
1296 logln("--) 1993/0/5");
1297 if (!(v
== EXPECTED_0610
)) errln("Expected " + EXPECTED_0610
+ "; saw " + v
);
1301 Calendar
*calendar
= new GregorianCalendar(1993, UCAL_JANUARY
, 4, status
);
1302 if (U_FAILURE(status
)) { errln("Couldn't create GregorianCalendar"); return; }
1303 logln("3A) " + value(calendar
));
1304 calendar
->getTime(status
);
1305 if (U_FAILURE(status
)) { errln("Calendar::getTime failed"); return; }
1306 calendar
->add(UCAL_DATE
, 1, status
);
1307 if (U_FAILURE(status
)) { errln("Calendar::add failed"); return; }
1308 UnicodeString v
= value(calendar
);
1310 logln("--) 1993/0/5");
1311 if (!(v
== EXPECTED_0610
)) errln("Expected " + EXPECTED_0610
+ "; saw " + v
);
1316 // -------------------------------------
1319 CalendarTest::value(Calendar
* calendar
)
1321 UErrorCode status
= U_ZERO_ERROR
;
1322 return UnicodeString("") + (int32_t)calendar
->get(UCAL_YEAR
, status
) +
1323 "/" + (int32_t)calendar
->get(UCAL_MONTH
, status
) +
1324 "/" + (int32_t)calendar
->get(UCAL_DATE
, status
) +
1325 (U_FAILURE(status
) ? " FAIL: Calendar::get failed" : "");
1329 // -------------------------------------
1332 * Verify that various fields on a known date are set correctly.
1335 CalendarTest::TestFields060()
1337 UErrorCode status
= U_ZERO_ERROR
;
1338 int32_t year
= 1997;
1339 int32_t month
= UCAL_OCTOBER
;
1341 GregorianCalendar
*calendar
= 0;
1342 calendar
= new GregorianCalendar(year
, month
, dDate
, status
);
1343 if (failure(status
, "new GregorianCalendar", TRUE
)) return;
1344 for (int32_t i
= 0; i
< EXPECTED_FIELDS_length
;) {
1345 UCalendarDateFields field
= (UCalendarDateFields
)EXPECTED_FIELDS
[i
++];
1346 int32_t expected
= EXPECTED_FIELDS
[i
++];
1347 if (calendar
->get(field
, status
) != expected
) {
1348 errln(UnicodeString("Expected field ") + (int32_t)field
+ " to have value " + (int32_t)expected
+
1349 "; received " + (int32_t)calendar
->get(field
, status
) + " instead");
1350 if (U_FAILURE(status
)) { errln("Calendar::get failed"); return; }
1356 int32_t CalendarTest::EXPECTED_FIELDS
[] = {
1358 UCAL_MONTH
, UCAL_OCTOBER
,
1360 UCAL_DAY_OF_WEEK
, UCAL_WEDNESDAY
,
1361 UCAL_DAY_OF_WEEK_IN_MONTH
, 4,
1362 UCAL_DAY_OF_YEAR
, 295
1365 const int32_t CalendarTest::EXPECTED_FIELDS_length
= (int32_t)(sizeof(CalendarTest::EXPECTED_FIELDS
) /
1366 sizeof(CalendarTest::EXPECTED_FIELDS
[0]));
1368 // -------------------------------------
1371 * Verify that various fields on a known date are set correctly. In this
1372 * case, the start of the epoch (January 1 1970).
1375 CalendarTest::TestEpochStartFields()
1377 UErrorCode status
= U_ZERO_ERROR
;
1378 TimeZone
*z
= TimeZone::createDefault();
1379 Calendar
*c
= Calendar::createInstance(status
);
1380 if (failure(status
, "Calendar::createInstance", TRUE
)) return;
1381 UDate d
= - z
->getRawOffset();
1382 GregorianCalendar
*gc
= new GregorianCalendar(status
);
1383 if (U_FAILURE(status
)) { errln("Couldn't create GregorianCalendar"); return; }
1384 gc
->setTimeZone(*z
);
1385 gc
->setTime(d
, status
);
1386 if (U_FAILURE(status
)) { errln("Calendar::setTime failed"); return; }
1387 UBool idt
= gc
->inDaylightTime(status
);
1388 if (U_FAILURE(status
)) { errln("GregorianCalendar::inDaylightTime failed"); return; }
1391 logln("Warning: Skipping test because " + dateToString(d
, str
) + " is in DST.");
1394 c
->setTime(d
, status
);
1395 if (U_FAILURE(status
)) { errln("Calendar::setTime failed"); return; }
1396 for (int32_t i
= 0; i
< UCAL_ZONE_OFFSET
;++i
) {
1397 if (c
->get((UCalendarDateFields
)i
, status
) != EPOCH_FIELDS
[i
])
1398 dataerrln(UnicodeString("Expected field ") + i
+ " to have value " + EPOCH_FIELDS
[i
] +
1399 "; saw " + c
->get((UCalendarDateFields
)i
, status
) + " instead");
1400 if (U_FAILURE(status
)) { errln("Calendar::get failed"); return; }
1402 if (c
->get(UCAL_ZONE_OFFSET
, status
) != z
->getRawOffset())
1404 errln(UnicodeString("Expected field ZONE_OFFSET to have value ") + z
->getRawOffset() +
1405 "; saw " + c
->get(UCAL_ZONE_OFFSET
, status
) + " instead");
1406 if (U_FAILURE(status
)) { errln("Calendar::get failed"); return; }
1408 if (c
->get(UCAL_DST_OFFSET
, status
) != 0)
1410 errln(UnicodeString("Expected field DST_OFFSET to have value 0") +
1411 "; saw " + c
->get(UCAL_DST_OFFSET
, status
) + " instead");
1412 if (U_FAILURE(status
)) { errln("Calendar::get failed"); return; }
1420 int32_t CalendarTest::EPOCH_FIELDS
[] = {
1421 1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, - 28800000, 0
1424 // -------------------------------------
1427 * Test that the days of the week progress properly when add is called repeatedly
1428 * for increments of 24 days.
1431 CalendarTest::TestDOWProgression()
1433 UErrorCode status
= U_ZERO_ERROR
;
1434 Calendar
*cal
= new GregorianCalendar(1972, UCAL_OCTOBER
, 26, status
);
1435 if (failure(status
, "new GregorianCalendar", TRUE
)) return;
1436 marchByDelta(cal
, 24);
1440 // -------------------------------------
1443 CalendarTest::TestDOW_LOCALandYEAR_WOY()
1445 /* Note: I've commented out the loop_addroll tests for YEAR and
1446 * YEAR_WOY below because these two fields should NOT behave
1447 * identically when adding. YEAR should keep the month/dom
1448 * invariant. YEAR_WOY should keep the woy/dow invariant. I've
1449 * added a new test that checks for this in place of the old call
1450 * to loop_addroll. - aliu */
1451 UErrorCode status
= U_ZERO_ERROR
;
1453 Calendar
*cal
=Calendar::createInstance(Locale::getGermany(), status
);
1454 if (failure(status
, "Calendar::createInstance", TRUE
)) return;
1455 SimpleDateFormat
*sdf
=new SimpleDateFormat(UnicodeString("YYYY'-W'ww-ee"), Locale::getGermany(), status
);
1456 if (U_FAILURE(status
)) { dataerrln("Couldn't create SimpleDateFormat - %s", u_errorName(status
)); return; }
1458 // ICU no longer use localized date-time pattern characters by default.
1459 // So we set pattern chars using 'J' instead of 'Y'.
1460 DateFormatSymbols
*dfs
= new DateFormatSymbols(Locale::getGermany(), status
);
1461 dfs
->setLocalPatternChars(UnicodeString("GyMdkHmsSEDFwWahKzJeugAZvcLQq"));
1462 sdf
->adoptDateFormatSymbols(dfs
);
1463 sdf
->applyLocalizedPattern(UnicodeString("JJJJ'-W'ww-ee"), status
);
1464 if (U_FAILURE(status
)) { errln("Couldn't apply localized pattern"); return; }
1467 cal
->set(1997, UCAL_DECEMBER
, 25);
1468 doYEAR_WOYLoop(cal
, sdf
, times
, status
);
1469 //loop_addroll(cal, /*sdf,*/ times, UCAL_YEAR_WOY, UCAL_YEAR, status);
1470 yearAddTest(*cal
, status
); // aliu
1471 loop_addroll(cal
, /*sdf,*/ times
, UCAL_DOW_LOCAL
, UCAL_DAY_OF_WEEK
, status
);
1472 if (U_FAILURE(status
)) { errln("Error in parse/calculate test for 1997"); return; }
1475 cal
->set(1998, UCAL_DECEMBER
, 25);
1476 doYEAR_WOYLoop(cal
, sdf
, times
, status
);
1477 //loop_addroll(cal, /*sdf,*/ times, UCAL_YEAR_WOY, UCAL_YEAR, status);
1478 yearAddTest(*cal
, status
); // aliu
1479 loop_addroll(cal
, /*sdf,*/ times
, UCAL_DOW_LOCAL
, UCAL_DAY_OF_WEEK
, status
);
1480 if (U_FAILURE(status
)) { errln("Error in parse/calculate test for 1998"); return; }
1483 cal
->set(1582, UCAL_OCTOBER
, 1);
1484 doYEAR_WOYLoop(cal
, sdf
, times
, status
);
1485 //loop_addroll(cal, /*sdf,*/ times, Calendar::YEAR_WOY, Calendar::YEAR, status);
1486 yearAddTest(*cal
, status
); // aliu
1487 loop_addroll(cal
, /*sdf,*/ times
, UCAL_DOW_LOCAL
, UCAL_DAY_OF_WEEK
, status
);
1488 if (U_FAILURE(status
)) { errln("Error in parse/calculate test for 1582"); return; }
1496 * Confirm that adding a YEAR and adding a YEAR_WOY work properly for
1497 * the given Calendar at its current setting.
1499 void CalendarTest::yearAddTest(Calendar
& cal
, UErrorCode
& status
) {
1501 * When adding the YEAR, the month and day should remain constant.
1502 * When adding the YEAR_WOY, the WOY and DOW should remain constant. - aliu
1504 * Wed Jan 14 1998 / 1998-W03-03 Add(YEAR_WOY, 1) -> Wed Jan 20 1999 / 1999-W03-03
1505 * Add(YEAR, 1) -> Thu Jan 14 1999 / 1999-W02-04
1506 * Thu Jan 14 1999 / 1999-W02-04 Add(YEAR_WOY, 1) -> Thu Jan 13 2000 / 2000-W02-04
1507 * Add(YEAR, 1) -> Fri Jan 14 2000 / 2000-W02-05
1508 * Sun Oct 31 1582 / 1582-W42-07 Add(YEAR_WOY, 1) -> Sun Oct 23 1583 / 1583-W42-07
1509 * Add(YEAR, 1) -> Mon Oct 31 1583 / 1583-W44-01
1511 int32_t y
= cal
.get(UCAL_YEAR
, status
);
1512 int32_t mon
= cal
.get(UCAL_MONTH
, status
);
1513 int32_t day
= cal
.get(UCAL_DATE
, status
);
1514 int32_t ywy
= cal
.get(UCAL_YEAR_WOY
, status
);
1515 int32_t woy
= cal
.get(UCAL_WEEK_OF_YEAR
, status
);
1516 int32_t dow
= cal
.get(UCAL_DOW_LOCAL
, status
);
1517 UDate t
= cal
.getTime(status
);
1519 if(U_FAILURE(status
)){
1520 errln(UnicodeString("Failed to create Calendar for locale. Error: ") + UnicodeString(u_errorName(status
)));
1523 UnicodeString str
, str2
;
1524 SimpleDateFormat
fmt(UnicodeString("EEE MMM dd yyyy / YYYY'-W'ww-ee"), status
);
1525 fmt
.setCalendar(cal
);
1527 fmt
.format(t
, str
.remove());
1528 str
+= ".add(YEAR, 1) =>";
1529 cal
.add(UCAL_YEAR
, 1, status
);
1530 int32_t y2
= cal
.get(UCAL_YEAR
, status
);
1531 int32_t mon2
= cal
.get(UCAL_MONTH
, status
);
1532 int32_t day2
= cal
.get(UCAL_DATE
, status
);
1533 fmt
.format(cal
.getTime(status
), str
);
1534 if (y2
!= (y
+1) || mon2
!= mon
|| day2
!= day
) {
1535 str
+= (UnicodeString
)", expected year " +
1536 (y
+1) + ", month " + (mon
+1) + ", day " + day
;
1537 errln((UnicodeString
)"FAIL: " + str
);
1538 logln( UnicodeString(" -> ") + CalendarTest::calToStr(cal
) );
1543 fmt
.format(t
, str
.remove());
1544 str
+= ".add(YEAR_WOY, 1)=>";
1545 cal
.setTime(t
, status
);
1546 logln( UnicodeString(" <- ") + CalendarTest::calToStr(cal
) );
1547 cal
.add(UCAL_YEAR_WOY
, 1, status
);
1548 int32_t ywy2
= cal
.get(UCAL_YEAR_WOY
, status
);
1549 int32_t woy2
= cal
.get(UCAL_WEEK_OF_YEAR
, status
);
1550 int32_t dow2
= cal
.get(UCAL_DOW_LOCAL
, status
);
1551 fmt
.format(cal
.getTime(status
), str
);
1552 if (ywy2
!= (ywy
+1) || woy2
!= woy
|| dow2
!= dow
) {
1553 str
+= (UnicodeString
)", expected yearWOY " +
1554 (ywy
+1) + ", woy " + woy
+ ", dowLocal " + dow
;
1555 errln((UnicodeString
)"FAIL: " + str
);
1556 logln( UnicodeString(" -> ") + CalendarTest::calToStr(cal
) );
1562 // -------------------------------------
1564 void CalendarTest::loop_addroll(Calendar
*cal
, /*SimpleDateFormat *sdf,*/ int times
, UCalendarDateFields field
, UCalendarDateFields field2
, UErrorCode
& errorCode
) {
1566 SimpleDateFormat
fmt(UnicodeString("EEE MMM dd yyyy / YYYY'-W'ww-ee"), errorCode
);
1567 fmt
.setCalendar(*cal
);
1570 for(i
= 0; i
<times
; i
++) {
1571 calclone
= cal
->clone();
1572 UDate start
= cal
->getTime(errorCode
);
1573 cal
->add(field
,1,errorCode
);
1574 if (U_FAILURE(errorCode
)) { errln("Error in add"); delete calclone
; return; }
1575 calclone
->add(field2
,1,errorCode
);
1576 if (U_FAILURE(errorCode
)) { errln("Error in add"); delete calclone
; return; }
1577 if(cal
->getTime(errorCode
) != calclone
->getTime(errorCode
)) {
1578 UnicodeString
str("FAIL: Results of add differ. "), str2
;
1579 str
+= fmt
.format(start
, str2
) + " ";
1580 str
+= UnicodeString("Add(") + fieldName(field
) + ", 1) -> " +
1581 fmt
.format(cal
->getTime(errorCode
), str2
.remove()) + "; ";
1582 str
+= UnicodeString("Add(") + fieldName(field2
) + ", 1) -> " +
1583 fmt
.format(calclone
->getTime(errorCode
), str2
.remove());
1591 for(i
= 0; i
<times
; i
++) {
1592 calclone
= cal
->clone();
1593 cal
->roll(field
,(int32_t)1,errorCode
);
1594 if (U_FAILURE(errorCode
)) { errln("Error in roll"); delete calclone
; return; }
1595 calclone
->roll(field2
,(int32_t)1,errorCode
);
1596 if (U_FAILURE(errorCode
)) { errln("Error in roll"); delete calclone
; return; }
1597 if(cal
->getTime(errorCode
) != calclone
->getTime(errorCode
)) {
1599 errln("Results of roll differ!");
1606 // -------------------------------------
1609 CalendarTest::doYEAR_WOYLoop(Calendar
*cal
, SimpleDateFormat
*sdf
,
1610 int32_t times
, UErrorCode
& errorCode
) {
1613 UDate tst
, original
;
1614 Calendar
*tstres
= new GregorianCalendar(Locale::getGermany(), errorCode
);
1615 for(int i
=0; i
<times
; ++i
) {
1616 sdf
->format(Formattable(cal
->getTime(errorCode
),Formattable::kIsDate
), us
, errorCode
);
1617 //logln("expected: "+us);
1618 if (U_FAILURE(errorCode
)) { errln("Format error"); return; }
1619 tst
=sdf
->parse(us
,errorCode
);
1620 if (U_FAILURE(errorCode
)) { errln("Parse error"); return; }
1622 tstres
->setTime(tst
, errorCode
);
1623 //logln((UnicodeString)"Parsed week of year is "+tstres->get(UCAL_WEEK_OF_YEAR, errorCode));
1624 if (U_FAILURE(errorCode
)) { errln("Set time error"); return; }
1625 original
= cal
->getTime(errorCode
);
1627 sdf
->format(Formattable(tst
,Formattable::kIsDate
), us
, errorCode
);
1628 //logln("got: "+us);
1629 if (U_FAILURE(errorCode
)) { errln("Get time error"); return; }
1632 sdf
->format(Formattable(original
, Formattable::kIsDate
), us
, errorCode
);
1633 errln("FAIL: Parsed time doesn't match with regular");
1634 logln("expected "+us
+ " " + calToStr(*cal
));
1636 sdf
->format(Formattable(tst
, Formattable::kIsDate
), us
, errorCode
);
1637 logln("got "+us
+ " " + calToStr(*tstres
));
1640 tstres
->set(UCAL_YEAR_WOY
, cal
->get(UCAL_YEAR_WOY
, errorCode
));
1641 tstres
->set(UCAL_WEEK_OF_YEAR
, cal
->get(UCAL_WEEK_OF_YEAR
, errorCode
));
1642 tstres
->set(UCAL_DOW_LOCAL
, cal
->get(UCAL_DOW_LOCAL
, errorCode
));
1643 if(cal
->get(UCAL_YEAR
, errorCode
) != tstres
->get(UCAL_YEAR
, errorCode
)) {
1644 errln("FAIL: Different Year!");
1645 logln((UnicodeString
)"Expected "+cal
->get(UCAL_YEAR
, errorCode
));
1646 logln((UnicodeString
)"Got "+tstres
->get(UCAL_YEAR
, errorCode
));
1649 if(cal
->get(UCAL_DAY_OF_YEAR
, errorCode
) != tstres
->get(UCAL_DAY_OF_YEAR
, errorCode
)) {
1650 errln("FAIL: Different Day Of Year!");
1651 logln((UnicodeString
)"Expected "+cal
->get(UCAL_DAY_OF_YEAR
, errorCode
));
1652 logln((UnicodeString
)"Got "+tstres
->get(UCAL_DAY_OF_YEAR
, errorCode
));
1655 //logln(calToStr(*cal));
1656 cal
->add(UCAL_DATE
, 1, errorCode
);
1657 if (U_FAILURE(errorCode
)) { errln("Add error"); return; }
1662 // -------------------------------------
1665 CalendarTest::marchByDelta(Calendar
* cal
, int32_t delta
)
1667 UErrorCode status
= U_ZERO_ERROR
;
1668 Calendar
*cur
= (Calendar
*) cal
->clone();
1669 int32_t initialDOW
= cur
->get(UCAL_DAY_OF_WEEK
, status
);
1670 if (U_FAILURE(status
)) { errln("Calendar::get failed"); return; }
1671 int32_t DOW
, newDOW
= initialDOW
;
1675 logln(UnicodeString("DOW = ") + DOW
+ " " + dateToString(cur
->getTime(status
), str
));
1676 if (U_FAILURE(status
)) { errln("Calendar::getTime failed"); return; }
1677 cur
->add(UCAL_DAY_OF_WEEK
, delta
, status
);
1678 if (U_FAILURE(status
)) { errln("Calendar::add failed"); return; }
1679 newDOW
= cur
->get(UCAL_DAY_OF_WEEK
, status
);
1680 if (U_FAILURE(status
)) { errln("Calendar::get failed"); return; }
1681 int32_t expectedDOW
= 1 + (DOW
+ delta
- 1) % 7;
1682 if (newDOW
!= expectedDOW
) {
1683 errln(UnicodeString("Day of week should be ") + expectedDOW
+ " instead of " + newDOW
+
1684 " on " + dateToString(cur
->getTime(status
), str
));
1685 if (U_FAILURE(status
)) { errln("Calendar::getTime failed"); return; }
1689 while (newDOW
!= initialDOW
);
1693 #define CHECK(status, msg) \
1694 if (U_FAILURE(status)) { \
1695 errcheckln(status, msg); \
1699 void CalendarTest::TestWOY(void) {
1701 FDW = Mon, MDFW = 4:
1702 Sun Dec 26 1999, WOY 51
1703 Mon Dec 27 1999, WOY 52
1704 Tue Dec 28 1999, WOY 52
1705 Wed Dec 29 1999, WOY 52
1706 Thu Dec 30 1999, WOY 52
1707 Fri Dec 31 1999, WOY 52
1708 Sat Jan 01 2000, WOY 52 ***
1709 Sun Jan 02 2000, WOY 52 ***
1710 Mon Jan 03 2000, WOY 1
1711 Tue Jan 04 2000, WOY 1
1712 Wed Jan 05 2000, WOY 1
1713 Thu Jan 06 2000, WOY 1
1714 Fri Jan 07 2000, WOY 1
1715 Sat Jan 08 2000, WOY 1
1716 Sun Jan 09 2000, WOY 1
1717 Mon Jan 10 2000, WOY 2
1719 FDW = Mon, MDFW = 2:
1720 Sun Dec 26 1999, WOY 52
1721 Mon Dec 27 1999, WOY 1 ***
1722 Tue Dec 28 1999, WOY 1 ***
1723 Wed Dec 29 1999, WOY 1 ***
1724 Thu Dec 30 1999, WOY 1 ***
1725 Fri Dec 31 1999, WOY 1 ***
1726 Sat Jan 01 2000, WOY 1
1727 Sun Jan 02 2000, WOY 1
1728 Mon Jan 03 2000, WOY 2
1729 Tue Jan 04 2000, WOY 2
1730 Wed Jan 05 2000, WOY 2
1731 Thu Jan 06 2000, WOY 2
1732 Fri Jan 07 2000, WOY 2
1733 Sat Jan 08 2000, WOY 2
1734 Sun Jan 09 2000, WOY 2
1735 Mon Jan 10 2000, WOY 3
1739 UErrorCode status
= U_ZERO_ERROR
;
1742 GregorianCalendar
cal(status
);
1743 SimpleDateFormat
fmt(UnicodeString("EEE MMM dd yyyy', WOY' w"), status
);
1744 if (failure(status
, "Cannot construct calendar/format", TRUE
)) return;
1746 UCalendarDaysOfWeek fdw
= (UCalendarDaysOfWeek
) 0;
1748 //for (int8_t pass=2; pass<=2; ++pass) {
1749 for (int8_t pass
=1; pass
<=2; ++pass
) {
1753 cal
.setFirstDayOfWeek(fdw
);
1754 cal
.setMinimalDaysInFirstWeek(4);
1755 fmt
.adoptCalendar(cal
.clone());
1759 cal
.setFirstDayOfWeek(fdw
);
1760 cal
.setMinimalDaysInFirstWeek(2);
1761 fmt
.adoptCalendar(cal
.clone());
1765 //for (i=2; i<=6; ++i) {
1766 for (i
=0; i
<16; ++i
) {
1768 int32_t t_y
, t_woy
, t_dow
;
1770 cal
.set(1999, UCAL_DECEMBER
, 26 + i
);
1771 fmt
.format(t
= cal
.getTime(status
), str
.remove());
1772 CHECK(status
, "Fail: getTime failed");
1773 logln(UnicodeString("* ") + str
);
1774 int32_t dow
= cal
.get(UCAL_DAY_OF_WEEK
, status
);
1775 int32_t woy
= cal
.get(UCAL_WEEK_OF_YEAR
, status
);
1776 int32_t year
= cal
.get(UCAL_YEAR
, status
);
1777 int32_t mon
= cal
.get(UCAL_MONTH
, status
);
1778 logln(calToStr(cal
));
1779 CHECK(status
, "Fail: get failed");
1780 int32_t dowLocal
= dow
- fdw
;
1781 if (dowLocal
< 0) dowLocal
+= 7;
1783 int32_t yearWoy
= year
;
1784 if (mon
== UCAL_JANUARY
) {
1785 if (woy
>= 52) --yearWoy
;
1787 if (woy
== 1) ++yearWoy
;
1790 // Basic fields->time check y/woy/dow
1791 // Since Y/WOY is ambiguous, we do a check of the fields,
1792 // not of the specific time.
1794 cal
.set(UCAL_YEAR
, year
);
1795 cal
.set(UCAL_WEEK_OF_YEAR
, woy
);
1796 cal
.set(UCAL_DAY_OF_WEEK
, dow
);
1797 t_y
= cal
.get(UCAL_YEAR
, status
);
1798 t_woy
= cal
.get(UCAL_WEEK_OF_YEAR
, status
);
1799 t_dow
= cal
.get(UCAL_DAY_OF_WEEK
, status
);
1800 CHECK(status
, "Fail: get failed");
1801 if (t_y
!= year
|| t_woy
!= woy
|| t_dow
!= dow
) {
1802 str
= "Fail: y/woy/dow fields->time => ";
1803 fmt
.format(cal
.getTime(status
), str
);
1805 logln(calToStr(cal
));
1806 logln("[get!=set] Y%d!=%d || woy%d!=%d || dow%d!=%d\n",
1807 t_y
, year
, t_woy
, woy
, t_dow
, dow
);
1809 logln("y/woy/dow fields->time OK");
1812 // Basic fields->time check y/woy/dow_local
1813 // Since Y/WOY is ambiguous, we do a check of the fields,
1814 // not of the specific time.
1816 cal
.set(UCAL_YEAR
, year
);
1817 cal
.set(UCAL_WEEK_OF_YEAR
, woy
);
1818 cal
.set(UCAL_DOW_LOCAL
, dowLocal
);
1819 t_y
= cal
.get(UCAL_YEAR
, status
);
1820 t_woy
= cal
.get(UCAL_WEEK_OF_YEAR
, status
);
1821 t_dow
= cal
.get(UCAL_DOW_LOCAL
, status
);
1822 CHECK(status
, "Fail: get failed");
1823 if (t_y
!= year
|| t_woy
!= woy
|| t_dow
!= dowLocal
) {
1824 str
= "Fail: y/woy/dow_local fields->time => ";
1825 fmt
.format(cal
.getTime(status
), str
);
1829 // Basic fields->time check y_woy/woy/dow
1831 cal
.set(UCAL_YEAR_WOY
, yearWoy
);
1832 cal
.set(UCAL_WEEK_OF_YEAR
, woy
);
1833 cal
.set(UCAL_DAY_OF_WEEK
, dow
);
1834 t2
= cal
.getTime(status
);
1835 CHECK(status
, "Fail: getTime failed");
1837 str
= "Fail: y_woy/woy/dow fields->time => ";
1838 fmt
.format(t2
, str
);
1840 logln(calToStr(cal
));
1841 logln("%.f != %.f\n", t
, t2
);
1843 logln("y_woy/woy/dow OK");
1846 // Basic fields->time check y_woy/woy/dow_local
1848 cal
.set(UCAL_YEAR_WOY
, yearWoy
);
1849 cal
.set(UCAL_WEEK_OF_YEAR
, woy
);
1850 cal
.set(UCAL_DOW_LOCAL
, dowLocal
);
1851 t2
= cal
.getTime(status
);
1852 CHECK(status
, "Fail: getTime failed");
1854 str
= "Fail: y_woy/woy/dow_local fields->time => ";
1855 fmt
.format(t2
, str
);
1859 logln("Testing DOW_LOCAL.. dow%d\n", dow
);
1860 // Make sure DOW_LOCAL disambiguates over DOW
1861 int32_t wrongDow
= dow
- 3;
1862 if (wrongDow
< 1) wrongDow
+= 7;
1863 cal
.setTime(t
, status
);
1864 cal
.set(UCAL_DAY_OF_WEEK
, wrongDow
);
1865 cal
.set(UCAL_DOW_LOCAL
, dowLocal
);
1866 t2
= cal
.getTime(status
);
1867 CHECK(status
, "Fail: set/getTime failed");
1869 str
= "Fail: DOW_LOCAL fields->time => ";
1870 fmt
.format(t2
, str
);
1872 logln(calToStr(cal
));
1873 logln("%.f : DOW%d, DOW_LOCAL%d -> %.f\n",
1874 t
, wrongDow
, dowLocal
, t2
);
1877 // Make sure DOW disambiguates over DOW_LOCAL
1878 int32_t wrongDowLocal
= dowLocal
- 3;
1879 if (wrongDowLocal
< 1) wrongDowLocal
+= 7;
1880 cal
.setTime(t
, status
);
1881 cal
.set(UCAL_DOW_LOCAL
, wrongDowLocal
);
1882 cal
.set(UCAL_DAY_OF_WEEK
, dow
);
1883 t2
= cal
.getTime(status
);
1884 CHECK(status
, "Fail: set/getTime failed");
1886 str
= "Fail: DOW fields->time => ";
1887 fmt
.format(t2
, str
);
1891 // Make sure YEAR_WOY disambiguates over YEAR
1892 cal
.setTime(t
, status
);
1893 cal
.set(UCAL_YEAR
, year
- 2);
1894 cal
.set(UCAL_YEAR_WOY
, yearWoy
);
1895 t2
= cal
.getTime(status
);
1896 CHECK(status
, "Fail: set/getTime failed");
1898 str
= "Fail: YEAR_WOY fields->time => ";
1899 fmt
.format(t2
, str
);
1903 // Make sure YEAR disambiguates over YEAR_WOY
1904 cal
.setTime(t
, status
);
1905 cal
.set(UCAL_YEAR_WOY
, yearWoy
- 2);
1906 cal
.set(UCAL_YEAR
, year
);
1907 t2
= cal
.getTime(status
);
1908 CHECK(status
, "Fail: set/getTime failed");
1910 str
= "Fail: YEAR fields->time => ";
1911 fmt
.format(t2
, str
);
1918 FDW = Mon, MDFW = 4:
1919 Sun Dec 26 1999, WOY 51
1920 Mon Dec 27 1999, WOY 52
1921 Tue Dec 28 1999, WOY 52
1922 Wed Dec 29 1999, WOY 52
1923 Thu Dec 30 1999, WOY 52
1924 Fri Dec 31 1999, WOY 52
1925 Sat Jan 01 2000, WOY 52
1926 Sun Jan 02 2000, WOY 52
1929 // Roll the DOW_LOCAL within week 52
1930 for (i
=27; i
<=33; ++i
) {
1932 for (amount
=-7; amount
<=7; ++amount
) {
1934 cal
.set(1999, UCAL_DECEMBER
, i
);
1936 fmt
.format(cal
.getTime(status
), str
);
1937 CHECK(status
, "Fail: getTime failed");
1938 str
+= UnicodeString(", ") + amount
+ ") = ";
1940 cal
.roll(UCAL_DOW_LOCAL
, amount
, status
);
1941 CHECK(status
, "Fail: roll failed");
1943 t
= cal
.getTime(status
);
1944 int32_t newDom
= i
+ amount
;
1945 while (newDom
< 27) newDom
+= 7;
1946 while (newDom
> 33) newDom
-= 7;
1947 cal
.set(1999, UCAL_DECEMBER
, newDom
);
1948 t2
= cal
.getTime(status
);
1949 CHECK(status
, "Fail: getTime failed");
1953 str
.append(", exp ");
1954 fmt
.format(t2
, str
);
1963 void CalendarTest::TestYWOY()
1966 UErrorCode status
= U_ZERO_ERROR
;
1968 GregorianCalendar
cal(status
);
1969 if (failure(status
, "construct GregorianCalendar", TRUE
)) return;
1971 cal
.setFirstDayOfWeek(UCAL_SUNDAY
);
1972 cal
.setMinimalDaysInFirstWeek(1);
1974 logln("Setting: ywoy=2004, woy=1, dow=MONDAY");
1976 cal
.set(UCAL_YEAR_WOY
,2004);
1977 cal
.set(UCAL_WEEK_OF_YEAR
,1);
1978 cal
.set(UCAL_DAY_OF_WEEK
, UCAL_MONDAY
);
1980 logln(calToStr(cal
));
1981 if(cal
.get(UCAL_YEAR
, status
) != 2003) {
1982 errln("year not 2003");
1985 logln("+ setting DOW to THURSDAY");
1987 cal
.set(UCAL_YEAR_WOY
,2004);
1988 cal
.set(UCAL_WEEK_OF_YEAR
,1);
1989 cal
.set(UCAL_DAY_OF_WEEK
, UCAL_THURSDAY
);
1991 logln(calToStr(cal
));
1992 if(cal
.get(UCAL_YEAR
, status
) != 2004) {
1993 errln("year not 2004");
1996 logln("+ setting DOW_LOCAL to 1");
1998 cal
.set(UCAL_YEAR_WOY
,2004);
1999 cal
.set(UCAL_WEEK_OF_YEAR
,1);
2000 cal
.set(UCAL_DAY_OF_WEEK
, UCAL_THURSDAY
);
2001 cal
.set(UCAL_DOW_LOCAL
, 1);
2003 logln(calToStr(cal
));
2004 if(cal
.get(UCAL_YEAR
, status
) != 2003) {
2005 errln("year not 2003");
2008 cal
.setFirstDayOfWeek(UCAL_MONDAY
);
2009 cal
.setMinimalDaysInFirstWeek(4);
2010 UDate t
= 946713600000.;
2011 cal
.setTime(t
, status
);
2012 cal
.set(UCAL_DAY_OF_WEEK
, 4);
2013 cal
.set(UCAL_DOW_LOCAL
, 6);
2014 if(cal
.getTime(status
) != t
) {
2015 logln(calToStr(cal
));
2016 errln("FAIL: DOW_LOCAL did not take precedence");
2021 void CalendarTest::TestJD()
2024 static const int32_t kEpochStartAsJulianDay
= 2440588;
2025 UErrorCode status
= U_ZERO_ERROR
;
2026 GregorianCalendar
cal(status
);
2027 if (failure(status
, "construct GregorianCalendar", TRUE
)) return;
2028 cal
.setTimeZone(*TimeZone::getGMT());
2030 jd
= cal
.get(UCAL_JULIAN_DAY
, status
);
2031 if(jd
!= kEpochStartAsJulianDay
) {
2032 errln("Wanted JD of %d at time=0, [epoch 1970] but got %d\n", kEpochStartAsJulianDay
, jd
);
2034 logln("Wanted JD of %d at time=0, [epoch 1970], got %d\n", kEpochStartAsJulianDay
, jd
);
2037 cal
.setTime(Calendar::getNow(), status
);
2039 cal
.set(UCAL_JULIAN_DAY
, kEpochStartAsJulianDay
);
2040 UDate epochTime
= cal
.getTime(status
);
2041 if(epochTime
!= 0) {
2042 errln("Wanted time of 0 at jd=%d, got %.1lf\n", kEpochStartAsJulianDay
, epochTime
);
2044 logln("Wanted time of 0 at jd=%d, got %.1lf\n", kEpochStartAsJulianDay
, epochTime
);
2049 // make sure the ctestfw utilities are in sync with the Calendar
2050 void CalendarTest::TestDebug()
2052 for(int32_t t
=0;t
<=UDBG_ENUM_COUNT
;t
++) {
2053 int32_t count
= udbg_enumCount((UDebugEnumType
)t
);
2055 logln("enumCount(%d) returned -1", count
);
2058 for(int32_t i
=0;i
<=count
;i
++) {
2059 if(t
<=UDBG_HIGHEST_CONTIGUOUS_ENUM
&& i
<count
) {
2060 if( i
!=udbg_enumArrayValue((UDebugEnumType
)t
, i
)) {
2061 errln("FAIL: udbg_enumArrayValue(%d,%d) returned %d, expected %d", t
, i
, udbg_enumArrayValue((UDebugEnumType
)t
,i
), i
);
2064 logln("Testing count+1:");
2066 const char *name
= udbg_enumName((UDebugEnumType
)t
,i
);
2068 if(i
==count
|| t
>UDBG_HIGHEST_CONTIGUOUS_ENUM
) {
2069 logln(" null name - expected.\n");
2071 errln("FAIL: udbg_enumName(%d,%d) returned NULL", t
, i
);
2075 logln("udbg_enumArrayValue(%d,%d) = %s, returned %d", t
, i
,
2076 name
, udbg_enumArrayValue((UDebugEnumType
)t
,i
));
2077 logln("udbg_enumString = " + udbg_enumString((UDebugEnumType
)t
,i
));
2079 if(udbg_enumExpectedCount((UDebugEnumType
)t
) != count
&& t
<=UDBG_HIGHEST_CONTIGUOUS_ENUM
) {
2080 errln("FAIL: udbg_enumExpectedCount(%d): %d, != UCAL_FIELD_COUNT=%d ", t
, udbg_enumExpectedCount((UDebugEnumType
)t
), count
);
2082 logln("udbg_ucal_fieldCount: %d, UCAL_FIELD_COUNT=udbg_enumCount %d ", udbg_enumExpectedCount((UDebugEnumType
)t
), count
);
2090 // List of interesting locales
2091 const char *CalendarTest::testLocaleID(int32_t i
)
2094 case 0: return "he_IL@calendar=hebrew";
2095 case 1: return "en_US@calendar=hebrew";
2096 case 2: return "fr_FR@calendar=hebrew";
2097 case 3: return "fi_FI@calendar=hebrew";
2098 case 4: return "nl_NL@calendar=hebrew";
2099 case 5: return "hu_HU@calendar=hebrew";
2100 case 6: return "nl_BE@currency=MTL;calendar=islamic";
2101 case 7: return "th_TH_TRADITIONAL@calendar=gregorian";
2102 case 8: return "ar_JO@calendar=islamic-civil";
2103 case 9: return "fi_FI@calendar=islamic";
2104 case 10: return "fr_CH@calendar=islamic-civil";
2105 case 11: return "he_IL@calendar=islamic-civil";
2106 case 12: return "hu_HU@calendar=buddhist";
2107 case 13: return "hu_HU@calendar=islamic";
2108 case 14: return "en_US@calendar=japanese";
2109 default: return NULL
;
2113 int32_t CalendarTest::testLocaleCount()
2115 static int32_t gLocaleCount
= -1;
2116 if(gLocaleCount
< 0) {
2118 for(i
=0;testLocaleID(i
) != NULL
;i
++) {
2123 return gLocaleCount
;
2126 static UDate
doMinDateOfCalendar(Calendar
* adopt
, UBool
&isGregorian
, UErrorCode
& status
) {
2127 if(U_FAILURE(status
)) return 0.0;
2130 adopt
->set(UCAL_EXTENDED_YEAR
, adopt
->getActualMinimum(UCAL_EXTENDED_YEAR
, status
));
2131 UDate ret
= adopt
->getTime(status
);
2132 isGregorian
= dynamic_cast<GregorianCalendar
*>(adopt
) != NULL
;
2137 UDate
CalendarTest::minDateOfCalendar(const Locale
& locale
, UBool
&isGregorian
, UErrorCode
& status
) {
2138 if(U_FAILURE(status
)) return 0.0;
2139 return doMinDateOfCalendar(Calendar::createInstance(locale
, status
), isGregorian
, status
);
2142 UDate
CalendarTest::minDateOfCalendar(const Calendar
& cal
, UBool
&isGregorian
, UErrorCode
& status
) {
2143 if(U_FAILURE(status
)) return 0.0;
2144 return doMinDateOfCalendar(cal
.clone(), isGregorian
, status
);
2147 void CalendarTest::Test6703()
2149 UErrorCode status
= U_ZERO_ERROR
;
2152 Locale
loc1("en@calendar=fubar");
2153 cal
= Calendar::createInstance(loc1
, status
);
2154 if (failure(status
, "Calendar::createInstance", TRUE
)) return;
2157 status
= U_ZERO_ERROR
;
2159 cal
= Calendar::createInstance(loc2
, status
);
2160 if (failure(status
, "Calendar::createInstance")) return;
2163 status
= U_ZERO_ERROR
;
2164 Locale
loc3("en@calendar=roc");
2165 cal
= Calendar::createInstance(loc3
, status
);
2166 if (failure(status
, "Calendar::createInstance")) return;
2172 void CalendarTest::Test3785()
2174 UErrorCode status
= U_ZERO_ERROR
;
2175 UnicodeString uzone
= UNICODE_STRING_SIMPLE("Europe/Paris");
2176 UnicodeString exp1
= UNICODE_STRING_SIMPLE("Mon 30 Jumada II 1433 AH, 01:47:03");
2177 UnicodeString exp2
= UNICODE_STRING_SIMPLE("Mon 1 Rajab 1433 AH, 01:47:04");
2179 LocalUDateFormatPointer
df(udat_open(UDAT_NONE
, UDAT_NONE
, "en@calendar=islamic", uzone
.getTerminatedBuffer(),
2180 uzone
.length(), NULL
, 0, &status
));
2181 if (df
.isNull() || U_FAILURE(status
)) return;
2184 u_uastrcpy(upattern
, "EEE d MMMM y G, HH:mm:ss");
2185 udat_applyPattern(df
.getAlias(), FALSE
, upattern
, u_strlen(upattern
));
2187 UChar ubuffer
[1024];
2188 UDate ud0
= 1337557623000.0;
2190 status
= U_ZERO_ERROR
;
2191 udat_format(df
.getAlias(), ud0
, ubuffer
, 1024, NULL
, &status
);
2192 if (U_FAILURE(status
)) {
2193 errln("Error formatting date 1\n");
2196 //printf("formatted: '%s'\n", mkcstr(ubuffer));
2198 UnicodeString
act1(ubuffer
);
2199 if ( act1
!= exp1
) {
2200 errln("Unexpected result from date 1 format\n");
2202 ud0
+= 1000.0; // add one second
2204 status
= U_ZERO_ERROR
;
2205 udat_format(df
.getAlias(), ud0
, ubuffer
, 1024, NULL
, &status
);
2206 if (U_FAILURE(status
)) {
2207 errln("Error formatting date 2\n");
2210 //printf("formatted: '%s'\n", mkcstr(ubuffer));
2211 UnicodeString
act2(ubuffer
);
2212 if ( act2
!= exp2
) {
2213 errln("Unexpected result from date 2 format\n");
2219 void CalendarTest::Test1624() {
2220 UErrorCode status
= U_ZERO_ERROR
;
2221 Locale
loc("he_IL@calendar=hebrew");
2222 HebrewCalendar
hc(loc
,status
);
2224 for (int32_t year
= 5600; year
< 5800; year
++ ) {
2226 for (int32_t month
= HebrewCalendar::TISHRI
; month
<= HebrewCalendar::ELUL
; month
++) {
2227 // skip the adar 1 month if year is not a leap year
2228 if (HebrewCalendar::isLeapYear(year
) == FALSE
&& month
== HebrewCalendar::ADAR_1
) {
2232 hc
.set(year
,month
,day
);
2233 int32_t dayHC
= hc
.get(UCAL_DATE
,status
);
2234 int32_t monthHC
= hc
.get(UCAL_MONTH
,status
);
2235 int32_t yearHC
= hc
.get(UCAL_YEAR
,status
);
2237 if (failure(status
, "HebrewCalendar.get()", TRUE
)) continue;
2240 errln(" ==> day %d incorrect, should be: %d\n",dayHC
,day
);
2243 if (monthHC
!= month
) {
2244 errln(" ==> month %d incorrect, should be: %d\n",monthHC
,month
);
2247 if (yearHC
!= year
) {
2248 errln(" ==> day %d incorrect, should be: %d\n",yearHC
,year
);
2256 void CalendarTest::TestTimeStamp() {
2257 UErrorCode status
= U_ZERO_ERROR
;
2258 UDate start
= 0.0, time
;
2261 // Create a new Gregorian Calendar.
2262 cal
= Calendar::createInstance("en_US@calender=gregorian", status
);
2263 if (U_FAILURE(status
)) {
2264 dataerrln("Error creating Gregorian calendar.");
2268 for (int i
= 0; i
< 20000; i
++) {
2269 // Set the Gregorian Calendar to a specific date for testing.
2270 cal
->set(2009, UCAL_JULY
, 3, 0, 49, 46);
2272 time
= cal
->getTime(status
);
2273 if (U_FAILURE(status
)) {
2274 errln("Error calling getTime()");
2281 if (start
!= time
) {
2282 errln("start and time not equal.");
2291 void CalendarTest::TestISO8601() {
2292 const char* TEST_LOCALES
[] = {
2293 "en_US@calendar=iso8601",
2294 "en_US@calendar=Iso8601",
2295 "th_TH@calendar=iso8601",
2296 "ar_EG@calendar=iso8601",
2300 int32_t TEST_DATA
[][3] = {
2311 for (int i
= 0; TEST_LOCALES
[i
] != NULL
; i
++) {
2312 UErrorCode status
= U_ZERO_ERROR
;
2313 Calendar
*cal
= Calendar::createInstance(TEST_LOCALES
[i
], status
);
2314 if (U_FAILURE(status
)) {
2315 errln("Error: Failed to create a calendar for locale: %s", TEST_LOCALES
[i
]);
2318 if (uprv_strcmp(cal
->getType(), "gregorian") != 0) {
2319 errln("Error: Gregorian calendar is not used for locale: %s", TEST_LOCALES
[i
]);
2322 for (int j
= 0; TEST_DATA
[j
][0] != 0; j
++) {
2323 cal
->set(TEST_DATA
[j
][0], UCAL_JANUARY
, 1);
2324 int32_t weekNum
= cal
->get(UCAL_WEEK_OF_YEAR
, status
);
2325 int32_t weekYear
= cal
->get(UCAL_YEAR_WOY
, status
);
2326 if (U_FAILURE(status
)) {
2327 errln("Error: Failed to get week of year");
2330 if (weekNum
!= TEST_DATA
[j
][1] || weekYear
!= TEST_DATA
[j
][2]) {
2331 errln("Error: Incorrect week of year on January 1st, %d for locale %s: Returned [weekNum=%d, weekYear=%d], Expected [weekNum=%d, weekYear=%d]",
2332 TEST_DATA
[j
][0], TEST_LOCALES
[i
], weekNum
, weekYear
, TEST_DATA
[j
][1], TEST_DATA
[j
][2]);
2341 CalendarTest::TestAmbiguousWallTimeAPIs(void) {
2342 UErrorCode status
= U_ZERO_ERROR
;
2343 Calendar
* cal
= Calendar::createInstance(status
);
2344 if (U_FAILURE(status
)) {
2345 errln("Fail: Error creating a calendar instance.");
2349 if (cal
->getRepeatedWallTimeOption() != UCAL_WALLTIME_LAST
) {
2350 errln("Fail: Default repeted time option is not UCAL_WALLTIME_LAST");
2352 if (cal
->getSkippedWallTimeOption() != UCAL_WALLTIME_LAST
) {
2353 errln("Fail: Default skipped time option is not UCAL_WALLTIME_LAST");
2356 Calendar
* cal2
= cal
->clone();
2358 if (*cal
!= *cal2
) {
2359 errln("Fail: Cloned calendar != the original");
2361 if (!cal
->equals(*cal2
, status
)) {
2362 errln("Fail: The time of cloned calendar is not equal to the original");
2363 } else if (U_FAILURE(status
)) {
2364 errln("Fail: Error equals");
2366 status
= U_ZERO_ERROR
;
2368 cal2
->setRepeatedWallTimeOption(UCAL_WALLTIME_FIRST
);
2369 cal2
->setSkippedWallTimeOption(UCAL_WALLTIME_FIRST
);
2371 if (*cal
== *cal2
) {
2372 errln("Fail: Cloned and modified calendar == the original");
2374 if (!cal
->equals(*cal2
, status
)) {
2375 errln("Fail: The time of cloned calendar is not equal to the original after changing wall time options");
2376 } else if (U_FAILURE(status
)) {
2377 errln("Fail: Error equals after changing wall time options");
2379 status
= U_ZERO_ERROR
;
2381 if (cal2
->getRepeatedWallTimeOption() != UCAL_WALLTIME_FIRST
) {
2382 errln("Fail: Repeted time option is not UCAL_WALLTIME_FIRST");
2384 if (cal2
->getSkippedWallTimeOption() != UCAL_WALLTIME_FIRST
) {
2385 errln("Fail: Skipped time option is not UCAL_WALLTIME_FIRST");
2388 cal2
->setRepeatedWallTimeOption(UCAL_WALLTIME_NEXT_VALID
);
2389 if (cal2
->getRepeatedWallTimeOption() != UCAL_WALLTIME_FIRST
) {
2390 errln("Fail: Repeated wall time option was updated other than UCAL_WALLTIME_FIRST");
2399 CalFields(int32_t year
, int32_t month
, int32_t day
, int32_t hour
, int32_t min
, int32_t sec
, int32_t ms
= 0);
2400 CalFields(const Calendar
& cal
, UErrorCode
& status
);
2401 void setTo(Calendar
& cal
) const;
2402 char* toString(char* buf
, int32_t len
) const;
2403 UBool
operator==(const CalFields
& rhs
) const;
2404 UBool
operator!=(const CalFields
& rhs
) const;
2405 UBool
isEquivalentTo(const Calendar
& cal
, UErrorCode
& status
) const;
2417 CalFields::CalFields(int32_t year
, int32_t month
, int32_t day
, int32_t hour
, int32_t min
, int32_t sec
, int32_t ms
)
2418 : year(year
), month(month
), day(day
), hour(hour
), min(min
), sec(sec
), ms(ms
) {
2421 CalFields::CalFields(const Calendar
& cal
, UErrorCode
& status
) {
2422 year
= cal
.get(UCAL_YEAR
, status
);
2423 month
= cal
.get(UCAL_MONTH
, status
) + 1;
2424 day
= cal
.get(UCAL_DAY_OF_MONTH
, status
);
2425 hour
= cal
.get(UCAL_HOUR_OF_DAY
, status
);
2426 min
= cal
.get(UCAL_MINUTE
, status
);
2427 sec
= cal
.get(UCAL_SECOND
, status
);
2428 ms
= cal
.get(UCAL_MILLISECOND
, status
);
2432 CalFields::setTo(Calendar
& cal
) const {
2434 cal
.set(year
, month
- 1, day
, hour
, min
, sec
);
2435 cal
.set(UCAL_MILLISECOND
, ms
);
2439 CalFields::toString(char* buf
, int32_t len
) const {
2441 sprintf(local
, "%04d-%02d-%02d %02d:%02d:%02d.%03d", year
, month
, day
, hour
, min
, sec
, ms
);
2442 uprv_strncpy(buf
, local
, len
- 1);
2448 CalFields::operator==(const CalFields
& rhs
) const {
2449 return year
== rhs
.year
2450 && month
== rhs
.month
2459 CalFields::operator!=(const CalFields
& rhs
) const {
2460 return !(*this == rhs
);
2464 CalFields::isEquivalentTo(const Calendar
& cal
, UErrorCode
& status
) const {
2465 return year
== cal
.get(UCAL_YEAR
, status
)
2466 && month
== cal
.get(UCAL_MONTH
, status
) + 1
2467 && day
== cal
.get(UCAL_DAY_OF_MONTH
, status
)
2468 && hour
== cal
.get(UCAL_HOUR_OF_DAY
, status
)
2469 && min
== cal
.get(UCAL_MINUTE
, status
)
2470 && sec
== cal
.get(UCAL_SECOND
, status
)
2471 && ms
== cal
.get(UCAL_MILLISECOND
, status
);
2477 const CalFields expLastGMT
;
2478 const CalFields expFirstGMT
;
2479 } RepeatedWallTimeTestData
;
2481 static const RepeatedWallTimeTestData RPDATA
[] =
2483 // Time zone Input wall time WALLTIME_LAST in GMT WALLTIME_FIRST in GMT
2484 {"America/New_York", CalFields(2011,11,6,0,59,59), CalFields(2011,11,6,4,59,59), CalFields(2011,11,6,4,59,59)},
2485 {"America/New_York", CalFields(2011,11,6,1,0,0), CalFields(2011,11,6,6,0,0), CalFields(2011,11,6,5,0,0)},
2486 {"America/New_York", CalFields(2011,11,6,1,0,1), CalFields(2011,11,6,6,0,1), CalFields(2011,11,6,5,0,1)},
2487 {"America/New_York", CalFields(2011,11,6,1,30,0), CalFields(2011,11,6,6,30,0), CalFields(2011,11,6,5,30,0)},
2488 {"America/New_York", CalFields(2011,11,6,1,59,59), CalFields(2011,11,6,6,59,59), CalFields(2011,11,6,5,59,59)},
2489 {"America/New_York", CalFields(2011,11,6,2,0,0), CalFields(2011,11,6,7,0,0), CalFields(2011,11,6,7,0,0)},
2490 {"America/New_York", CalFields(2011,11,6,2,0,1), CalFields(2011,11,6,7,0,1), CalFields(2011,11,6,7,0,1)},
2492 {"Australia/Lord_Howe", CalFields(2011,4,3,1,29,59), CalFields(2011,4,2,14,29,59), CalFields(2011,4,2,14,29,59)},
2493 {"Australia/Lord_Howe", CalFields(2011,4,3,1,30,0), CalFields(2011,4,2,15,0,0), CalFields(2011,4,2,14,30,0)},
2494 {"Australia/Lord_Howe", CalFields(2011,4,3,1,45,0), CalFields(2011,4,2,15,15,0), CalFields(2011,4,2,14,45,0)},
2495 {"Australia/Lord_Howe", CalFields(2011,4,3,1,59,59), CalFields(2011,4,2,15,29,59), CalFields(2011,4,2,14,59,59)},
2496 {"Australia/Lord_Howe", CalFields(2011,4,3,2,0,0), CalFields(2011,4,2,15,30,0), CalFields(2011,4,2,15,30,0)},
2497 {"Australia/Lord_Howe", CalFields(2011,4,3,2,0,1), CalFields(2011,4,2,15,30,1), CalFields(2011,4,2,15,30,1)},
2499 {NULL
, CalFields(0,0,0,0,0,0), CalFields(0,0,0,0,0,0), CalFields(0,0,0,0,0,0)}
2502 void CalendarTest::TestRepeatedWallTime(void) {
2503 UErrorCode status
= U_ZERO_ERROR
;
2504 GregorianCalendar
calGMT((const TimeZone
&)*TimeZone::getGMT(), status
);
2505 GregorianCalendar
calDefault(status
);
2506 GregorianCalendar
calLast(status
);
2507 GregorianCalendar
calFirst(status
);
2509 if (U_FAILURE(status
)) {
2510 errln("Fail: Failed to create a calendar object.");
2514 calLast
.setRepeatedWallTimeOption(UCAL_WALLTIME_LAST
);
2515 calFirst
.setRepeatedWallTimeOption(UCAL_WALLTIME_FIRST
);
2517 for (int32_t i
= 0; RPDATA
[i
].tzid
!= NULL
; i
++) {
2519 TimeZone
*tz
= TimeZone::createTimeZone(RPDATA
[i
].tzid
);
2521 // UCAL_WALLTIME_LAST
2522 status
= U_ZERO_ERROR
;
2523 calLast
.setTimeZone(*tz
);
2524 RPDATA
[i
].in
.setTo(calLast
);
2525 calGMT
.setTime(calLast
.getTime(status
), status
);
2526 CalFields
outLastGMT(calGMT
, status
);
2527 if (U_FAILURE(status
)) {
2528 errln(UnicodeString("Fail: Failed to get/set time calLast/calGMT (UCAL_WALLTIME_LAST) - ")
2529 + RPDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + RPDATA
[i
].tzid
+ "]");
2531 if (outLastGMT
!= RPDATA
[i
].expLastGMT
) {
2532 dataerrln(UnicodeString("Fail: UCAL_WALLTIME_LAST ") + RPDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + RPDATA
[i
].tzid
+ "] is parsed as "
2533 + outLastGMT
.toString(buf
, sizeof(buf
)) + "[GMT]. Expected: " + RPDATA
[i
].expLastGMT
.toString(buf
, sizeof(buf
)) + "[GMT]");
2538 status
= U_ZERO_ERROR
;
2539 calDefault
.setTimeZone(*tz
);
2540 RPDATA
[i
].in
.setTo(calDefault
);
2541 calGMT
.setTime(calDefault
.getTime(status
), status
);
2542 CalFields
outDefGMT(calGMT
, status
);
2543 if (U_FAILURE(status
)) {
2544 errln(UnicodeString("Fail: Failed to get/set time calLast/calGMT (default) - ")
2545 + RPDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + RPDATA
[i
].tzid
+ "]");
2547 if (outDefGMT
!= RPDATA
[i
].expLastGMT
) {
2548 dataerrln(UnicodeString("Fail: (default) ") + RPDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + RPDATA
[i
].tzid
+ "] is parsed as "
2549 + outDefGMT
.toString(buf
, sizeof(buf
)) + "[GMT]. Expected: " + RPDATA
[i
].expLastGMT
.toString(buf
, sizeof(buf
)) + "[GMT]");
2553 // UCAL_WALLTIME_FIRST
2554 status
= U_ZERO_ERROR
;
2555 calFirst
.setTimeZone(*tz
);
2556 RPDATA
[i
].in
.setTo(calFirst
);
2557 calGMT
.setTime(calFirst
.getTime(status
), status
);
2558 CalFields
outFirstGMT(calGMT
, status
);
2559 if (U_FAILURE(status
)) {
2560 errln(UnicodeString("Fail: Failed to get/set time calLast/calGMT (UCAL_WALLTIME_FIRST) - ")
2561 + RPDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + RPDATA
[i
].tzid
+ "]");
2563 if (outFirstGMT
!= RPDATA
[i
].expFirstGMT
) {
2564 dataerrln(UnicodeString("Fail: UCAL_WALLTIME_FIRST ") + RPDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + RPDATA
[i
].tzid
+ "] is parsed as "
2565 + outFirstGMT
.toString(buf
, sizeof(buf
)) + "[GMT]. Expected: " + RPDATA
[i
].expFirstGMT
.toString(buf
, sizeof(buf
)) + "[GMT]");
2576 const CalFields expLastGMT
;
2577 const CalFields expFirstGMT
;
2578 const CalFields expNextAvailGMT
;
2579 } SkippedWallTimeTestData
;
2581 static SkippedWallTimeTestData SKDATA
[] =
2583 // Time zone Input wall time valid? WALLTIME_LAST in GMT WALLTIME_FIRST in GMT WALLTIME_NEXT_VALID in GMT
2584 {"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)},
2585 {"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)},
2586 {"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)},
2587 {"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)},
2588 {"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)},
2589 {"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)},
2591 {"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)},
2592 {"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)},
2593 {"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)},
2594 {"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)},
2595 {"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)},
2597 {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)}
2601 void CalendarTest::TestSkippedWallTime(void) {
2602 UErrorCode status
= U_ZERO_ERROR
;
2603 GregorianCalendar
calGMT((const TimeZone
&)*TimeZone::getGMT(), status
);
2604 GregorianCalendar
calDefault(status
);
2605 GregorianCalendar
calLast(status
);
2606 GregorianCalendar
calFirst(status
);
2607 GregorianCalendar
calNextAvail(status
);
2609 if (U_FAILURE(status
)) {
2610 errln("Fail: Failed to create a calendar object.");
2614 calLast
.setSkippedWallTimeOption(UCAL_WALLTIME_LAST
);
2615 calFirst
.setSkippedWallTimeOption(UCAL_WALLTIME_FIRST
);
2616 calNextAvail
.setSkippedWallTimeOption(UCAL_WALLTIME_NEXT_VALID
);
2618 for (int32_t i
= 0; SKDATA
[i
].tzid
!= NULL
; i
++) {
2621 TimeZone
*tz
= TimeZone::createTimeZone(SKDATA
[i
].tzid
);
2623 for (int32_t j
= 0; j
< 2; j
++) {
2624 UBool bLenient
= (j
== 0);
2626 // UCAL_WALLTIME_LAST
2627 status
= U_ZERO_ERROR
;
2628 calLast
.setLenient(bLenient
);
2629 calLast
.setTimeZone(*tz
);
2630 SKDATA
[i
].in
.setTo(calLast
);
2631 d
= calLast
.getTime(status
);
2632 if (bLenient
|| SKDATA
[i
].isValid
) {
2633 calGMT
.setTime(d
, status
);
2634 CalFields
outLastGMT(calGMT
, status
);
2635 if (U_FAILURE(status
)) {
2636 errln(UnicodeString("Fail: Failed to get/set time calLast/calGMT (UCAL_WALLTIME_LAST) - ")
2637 + SKDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + SKDATA
[i
].tzid
+ "]");
2639 if (outLastGMT
!= SKDATA
[i
].expLastGMT
) {
2640 dataerrln(UnicodeString("Fail: UCAL_WALLTIME_LAST ") + SKDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + SKDATA
[i
].tzid
+ "] is parsed as "
2641 + outLastGMT
.toString(buf
, sizeof(buf
)) + "[GMT]. Expected: " + SKDATA
[i
].expLastGMT
.toString(buf
, sizeof(buf
)) + "[GMT]");
2644 } else if (U_SUCCESS(status
)) {
2645 // strict, invalid wall time - must report an error
2646 dataerrln(UnicodeString("Fail: An error expected (UCAL_WALLTIME_LAST)") +
2647 + SKDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + SKDATA
[i
].tzid
+ "]");
2651 status
= U_ZERO_ERROR
;
2652 calDefault
.setLenient(bLenient
);
2653 calDefault
.setTimeZone(*tz
);
2654 SKDATA
[i
].in
.setTo(calDefault
);
2655 d
= calDefault
.getTime(status
);
2656 if (bLenient
|| SKDATA
[i
].isValid
) {
2657 calGMT
.setTime(d
, status
);
2658 CalFields
outDefGMT(calGMT
, status
);
2659 if (U_FAILURE(status
)) {
2660 errln(UnicodeString("Fail: Failed to get/set time calDefault/calGMT (default) - ")
2661 + SKDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + SKDATA
[i
].tzid
+ "]");
2663 if (outDefGMT
!= SKDATA
[i
].expLastGMT
) {
2664 dataerrln(UnicodeString("Fail: (default) ") + SKDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + SKDATA
[i
].tzid
+ "] is parsed as "
2665 + outDefGMT
.toString(buf
, sizeof(buf
)) + "[GMT]. Expected: " + SKDATA
[i
].expLastGMT
.toString(buf
, sizeof(buf
)) + "[GMT]");
2668 } else if (U_SUCCESS(status
)) {
2669 // strict, invalid wall time - must report an error
2670 dataerrln(UnicodeString("Fail: An error expected (default)") +
2671 + SKDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + SKDATA
[i
].tzid
+ "]");
2674 // UCAL_WALLTIME_FIRST
2675 status
= U_ZERO_ERROR
;
2676 calFirst
.setLenient(bLenient
);
2677 calFirst
.setTimeZone(*tz
);
2678 SKDATA
[i
].in
.setTo(calFirst
);
2679 d
= calFirst
.getTime(status
);
2680 if (bLenient
|| SKDATA
[i
].isValid
) {
2681 calGMT
.setTime(d
, status
);
2682 CalFields
outFirstGMT(calGMT
, status
);
2683 if (U_FAILURE(status
)) {
2684 errln(UnicodeString("Fail: Failed to get/set time calFirst/calGMT (UCAL_WALLTIME_FIRST) - ")
2685 + SKDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + SKDATA
[i
].tzid
+ "]");
2687 if (outFirstGMT
!= SKDATA
[i
].expFirstGMT
) {
2688 dataerrln(UnicodeString("Fail: UCAL_WALLTIME_FIRST ") + SKDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + SKDATA
[i
].tzid
+ "] is parsed as "
2689 + outFirstGMT
.toString(buf
, sizeof(buf
)) + "[GMT]. Expected: " + SKDATA
[i
].expFirstGMT
.toString(buf
, sizeof(buf
)) + "[GMT]");
2692 } else if (U_SUCCESS(status
)) {
2693 // strict, invalid wall time - must report an error
2694 dataerrln(UnicodeString("Fail: An error expected (UCAL_WALLTIME_FIRST)") +
2695 + SKDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + SKDATA
[i
].tzid
+ "]");
2698 // UCAL_WALLTIME_NEXT_VALID
2699 status
= U_ZERO_ERROR
;
2700 calNextAvail
.setLenient(bLenient
);
2701 calNextAvail
.setTimeZone(*tz
);
2702 SKDATA
[i
].in
.setTo(calNextAvail
);
2703 d
= calNextAvail
.getTime(status
);
2704 if (bLenient
|| SKDATA
[i
].isValid
) {
2705 calGMT
.setTime(d
, status
);
2706 CalFields
outNextAvailGMT(calGMT
, status
);
2707 if (U_FAILURE(status
)) {
2708 errln(UnicodeString("Fail: Failed to get/set time calNextAvail/calGMT (UCAL_WALLTIME_NEXT_VALID) - ")
2709 + SKDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + SKDATA
[i
].tzid
+ "]");
2711 if (outNextAvailGMT
!= SKDATA
[i
].expNextAvailGMT
) {
2712 dataerrln(UnicodeString("Fail: UCAL_WALLTIME_NEXT_VALID ") + SKDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + SKDATA
[i
].tzid
+ "] is parsed as "
2713 + outNextAvailGMT
.toString(buf
, sizeof(buf
)) + "[GMT]. Expected: " + SKDATA
[i
].expNextAvailGMT
.toString(buf
, sizeof(buf
)) + "[GMT]");
2716 } else if (U_SUCCESS(status
)) {
2717 // strict, invalid wall time - must report an error
2718 dataerrln(UnicodeString("Fail: An error expected (UCAL_WALLTIME_NEXT_VALID)") +
2719 + SKDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + SKDATA
[i
].tzid
+ "]");
2727 void CalendarTest::TestCloneLocale(void) {
2728 UErrorCode status
= U_ZERO_ERROR
;
2729 LocalPointer
<Calendar
> cal(Calendar::createInstance(TimeZone::getGMT()->clone(),
2730 Locale::createFromName("en"), status
));
2732 Locale l0
= cal
->getLocale(ULOC_VALID_LOCALE
, status
);
2734 LocalPointer
<Calendar
> cal2(cal
->clone());
2735 Locale l
= cal2
->getLocale(ULOC_VALID_LOCALE
, status
);
2737 errln("Error: cloned locale %s != original locale %s, status %s\n", l0
.getName(), l
.getName(), u_errorName(status
));
2744 const CalFields base
;
2746 UCalendarWallTimeOption skippedWTOpt
;
2747 const CalFields expected
;
2748 } TestAddAcrossZoneTransitionData
;
2750 static const TestAddAcrossZoneTransitionData AAZTDATA
[] =
2752 // Time zone Base wall time day(s) Skipped time options
2753 // Expected wall time
2755 // Add 1 day, from the date before DST transition
2756 {"America/Los_Angeles", CalFields(2014,3,8,1,59,59,999), 1, UCAL_WALLTIME_FIRST
,
2757 CalFields(2014,3,9,1,59,59,999)},
2759 {"America/Los_Angeles", CalFields(2014,3,8,1,59,59,999), 1, UCAL_WALLTIME_LAST
,
2760 CalFields(2014,3,9,1,59,59,999)},
2762 {"America/Los_Angeles", CalFields(2014,3,8,1,59,59,999), 1, UCAL_WALLTIME_NEXT_VALID
,
2763 CalFields(2014,3,9,1,59,59,999)},
2766 {"America/Los_Angeles", CalFields(2014,3,8,2,0,0,0), 1, UCAL_WALLTIME_FIRST
,
2767 CalFields(2014,3,9,1,0,0,0)},
2769 {"America/Los_Angeles", CalFields(2014,3,8,2,0,0,0), 1, UCAL_WALLTIME_LAST
,
2770 CalFields(2014,3,9,3,0,0,0)},
2772 {"America/Los_Angeles", CalFields(2014,3,8,2,0,0,0), 1, UCAL_WALLTIME_NEXT_VALID
,
2773 CalFields(2014,3,9,3,0,0,0)},
2776 {"America/Los_Angeles", CalFields(2014,3,8,2,30,0,0), 1, UCAL_WALLTIME_FIRST
,
2777 CalFields(2014,3,9,1,30,0,0)},
2779 {"America/Los_Angeles", CalFields(2014,3,8,2,30,0,0), 1, UCAL_WALLTIME_LAST
,
2780 CalFields(2014,3,9,3,30,0,0)},
2782 {"America/Los_Angeles", CalFields(2014,3,8,2,30,0,0), 1, UCAL_WALLTIME_NEXT_VALID
,
2783 CalFields(2014,3,9,3,0,0,0)},
2786 {"America/Los_Angeles", CalFields(2014,3,8,3,0,0,0), 1, UCAL_WALLTIME_FIRST
,
2787 CalFields(2014,3,9,3,0,0,0)},
2789 {"America/Los_Angeles", CalFields(2014,3,8,3,0,0,0), 1, UCAL_WALLTIME_LAST
,
2790 CalFields(2014,3,9,3,0,0,0)},
2792 {"America/Los_Angeles", CalFields(2014,3,8,3,0,0,0), 1, UCAL_WALLTIME_NEXT_VALID
,
2793 CalFields(2014,3,9,3,0,0,0)},
2795 // Subtract 1 day, from one day after DST transition
2796 {"America/Los_Angeles", CalFields(2014,3,10,1,59,59,999), -1, UCAL_WALLTIME_FIRST
,
2797 CalFields(2014,3,9,1,59,59,999)},
2799 {"America/Los_Angeles", CalFields(2014,3,10,1,59,59,999), -1, UCAL_WALLTIME_LAST
,
2800 CalFields(2014,3,9,1,59,59,999)},
2802 {"America/Los_Angeles", CalFields(2014,3,10,1,59,59,999), -1, UCAL_WALLTIME_NEXT_VALID
,
2803 CalFields(2014,3,9,1,59,59,999)},
2806 {"America/Los_Angeles", CalFields(2014,3,10,2,0,0,0), -1, UCAL_WALLTIME_FIRST
,
2807 CalFields(2014,3,9,1,0,0,0)},
2809 {"America/Los_Angeles", CalFields(2014,3,10,2,0,0,0), -1, UCAL_WALLTIME_LAST
,
2810 CalFields(2014,3,9,3,0,0,0)},
2812 {"America/Los_Angeles", CalFields(2014,3,10,2,0,0,0), -1, UCAL_WALLTIME_NEXT_VALID
,
2813 CalFields(2014,3,9,3,0,0,0)},
2816 {"America/Los_Angeles", CalFields(2014,3,10,2,30,0,0), -1, UCAL_WALLTIME_FIRST
,
2817 CalFields(2014,3,9,1,30,0,0)},
2819 {"America/Los_Angeles", CalFields(2014,3,10,2,30,0,0), -1, UCAL_WALLTIME_LAST
,
2820 CalFields(2014,3,9,3,30,0,0)},
2822 {"America/Los_Angeles", CalFields(2014,3,10,2,30,0,0), -1, UCAL_WALLTIME_NEXT_VALID
,
2823 CalFields(2014,3,9,3,0,0,0)},
2826 {"America/Los_Angeles", CalFields(2014,3,10,3,0,0,0), -1, UCAL_WALLTIME_FIRST
,
2827 CalFields(2014,3,9,3,0,0,0)},
2829 {"America/Los_Angeles", CalFields(2014,3,10,3,0,0,0), -1, UCAL_WALLTIME_LAST
,
2830 CalFields(2014,3,9,3,0,0,0)},
2832 {"America/Los_Angeles", CalFields(2014,3,10,3,0,0,0), -1, UCAL_WALLTIME_NEXT_VALID
,
2833 CalFields(2014,3,9,3,0,0,0)},
2836 // Test case for ticket#10544
2837 {"America/Santiago", CalFields(2013,4,27,0,0,0,0), 134, UCAL_WALLTIME_FIRST
,
2838 CalFields(2013,9,7,23,0,0,0)},
2840 {"America/Santiago", CalFields(2013,4,27,0,0,0,0), 134, UCAL_WALLTIME_LAST
,
2841 CalFields(2013,9,8,1,0,0,0)},
2843 {"America/Santiago", CalFields(2013,4,27,0,0,0,0), 134, UCAL_WALLTIME_NEXT_VALID
,
2844 CalFields(2013,9,8,1,0,0,0)},
2847 {"America/Santiago", CalFields(2013,4,27,0,30,0,0), 134, UCAL_WALLTIME_FIRST
,
2848 CalFields(2013,9,7,23,30,0,0)},
2850 {"America/Santiago", CalFields(2013,4,27,0,30,0,0), 134, UCAL_WALLTIME_LAST
,
2851 CalFields(2013,9,8,1,30,0,0)},
2853 {"America/Santiago", CalFields(2013,4,27,0,30,0,0), 134, UCAL_WALLTIME_NEXT_VALID
,
2854 CalFields(2013,9,8,1,0,0,0)},
2857 // Extreme transition - Pacific/Apia completely skips 2011-12-30
2858 {"Pacific/Apia", CalFields(2011,12,29,0,0,0,0), 1, UCAL_WALLTIME_FIRST
,
2859 CalFields(2011,12,31,0,0,0,0)},
2861 {"Pacific/Apia", CalFields(2011,12,29,0,0,0,0), 1, UCAL_WALLTIME_LAST
,
2862 CalFields(2011,12,31,0,0,0,0)},
2864 {"Pacific/Apia", CalFields(2011,12,29,0,0,0,0), 1, UCAL_WALLTIME_NEXT_VALID
,
2865 CalFields(2011,12,31,0,0,0,0)},
2868 {"Pacific/Apia", CalFields(2011,12,31,12,0,0,0), -1, UCAL_WALLTIME_FIRST
,
2869 CalFields(2011,12,29,12,0,0,0)},
2871 {"Pacific/Apia", CalFields(2011,12,31,12,0,0,0), -1, UCAL_WALLTIME_LAST
,
2872 CalFields(2011,12,29,12,0,0,0)},
2874 {"Pacific/Apia", CalFields(2011,12,31,12,0,0,0), -1, UCAL_WALLTIME_NEXT_VALID
,
2875 CalFields(2011,12,29,12,0,0,0)},
2878 // 30 minutes DST - Australia/Lord_Howe
2879 {"Australia/Lord_Howe", CalFields(2013,10,5,2,15,0,0), 1, UCAL_WALLTIME_FIRST
,
2880 CalFields(2013,10,6,1,45,0,0)},
2882 {"Australia/Lord_Howe", CalFields(2013,10,5,2,15,0,0), 1, UCAL_WALLTIME_LAST
,
2883 CalFields(2013,10,6,2,45,0,0)},
2885 {"Australia/Lord_Howe", CalFields(2013,10,5,2,15,0,0), 1, UCAL_WALLTIME_NEXT_VALID
,
2886 CalFields(2013,10,6,2,30,0,0)},
2888 {NULL
, CalFields(0,0,0,0,0,0,0), 0, UCAL_WALLTIME_LAST
, CalFields(0,0,0,0,0,0,0)}
2891 void CalendarTest::TestAddAcrossZoneTransition() {
2892 UErrorCode status
= U_ZERO_ERROR
;
2893 GregorianCalendar
cal(status
);
2896 for (int32_t i
= 0; AAZTDATA
[i
].zone
; i
++) {
2897 status
= U_ZERO_ERROR
;
2898 TimeZone
*tz
= TimeZone::createTimeZone(AAZTDATA
[i
].zone
);
2899 cal
.adoptTimeZone(tz
);
2900 cal
.setSkippedWallTimeOption(AAZTDATA
[i
].skippedWTOpt
);
2901 AAZTDATA
[i
].base
.setTo(cal
);
2902 cal
.add(UCAL_DATE
, AAZTDATA
[i
].deltaDays
, status
);
2905 if (!AAZTDATA
[i
].expected
.isEquivalentTo(cal
, status
)) {
2906 CalFields
res(cal
, status
);
2909 const char *optDisp
= AAZTDATA
[i
].skippedWTOpt
== UCAL_WALLTIME_FIRST
? "FIRST" :
2910 AAZTDATA
[i
].skippedWTOpt
== UCAL_WALLTIME_LAST
? "LAST" : "NEXT_VALID";
2911 errln(UnicodeString("Error: base:") + AAZTDATA
[i
].base
.toString(buf
, sizeof(buf
)) + ", tz:" + AAZTDATA
[i
].zone
2912 + ", delta:" + AAZTDATA
[i
].deltaDays
+ " day(s), opt:" + optDisp
2913 + ", result:" + res
.toString(buf
, sizeof(buf
))
2914 + " - expected:" + AAZTDATA
[i
].expected
.toString(buf
, sizeof(buf
)));
2919 #endif /* #if !UCONFIG_NO_FORMATTING */