1 /************************************************************************
3 * Copyright (c) 1997-2012, 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("");
282 default: name
= ""; break;
286 // ---------------------------------------------------------------------------------
288 UnicodeString
CalendarTest::fieldName(UCalendarDateFields f
) {
290 #define FIELD_NAME_STR(x) case x: return (#x+5)
291 FIELD_NAME_STR( UCAL_ERA
);
292 FIELD_NAME_STR( UCAL_YEAR
);
293 FIELD_NAME_STR( UCAL_MONTH
);
294 FIELD_NAME_STR( UCAL_WEEK_OF_YEAR
);
295 FIELD_NAME_STR( UCAL_WEEK_OF_MONTH
);
296 FIELD_NAME_STR( UCAL_DATE
);
297 FIELD_NAME_STR( UCAL_DAY_OF_YEAR
);
298 FIELD_NAME_STR( UCAL_DAY_OF_WEEK
);
299 FIELD_NAME_STR( UCAL_DAY_OF_WEEK_IN_MONTH
);
300 FIELD_NAME_STR( UCAL_AM_PM
);
301 FIELD_NAME_STR( UCAL_HOUR
);
302 FIELD_NAME_STR( UCAL_HOUR_OF_DAY
);
303 FIELD_NAME_STR( UCAL_MINUTE
);
304 FIELD_NAME_STR( UCAL_SECOND
);
305 FIELD_NAME_STR( UCAL_MILLISECOND
);
306 FIELD_NAME_STR( UCAL_ZONE_OFFSET
);
307 FIELD_NAME_STR( UCAL_DST_OFFSET
);
308 FIELD_NAME_STR( UCAL_YEAR_WOY
);
309 FIELD_NAME_STR( UCAL_DOW_LOCAL
);
310 FIELD_NAME_STR( UCAL_EXTENDED_YEAR
);
311 FIELD_NAME_STR( UCAL_JULIAN_DAY
);
312 FIELD_NAME_STR( UCAL_MILLISECONDS_IN_DAY
);
313 #undef FIELD_NAME_STR
315 return UnicodeString("") + ((int32_t)f
);
320 * Test various API methods for API completeness.
323 CalendarTest::TestGenericAPI()
325 UErrorCode status
= U_ZERO_ERROR
;
328 UBool eq
= FALSE
,b4
= FALSE
,af
= FALSE
;
330 UDate when
= date(90, UCAL_APRIL
, 15);
332 UnicodeString
tzid("TestZone");
333 int32_t tzoffset
= 123400;
335 SimpleTimeZone
*zone
= new SimpleTimeZone(tzoffset
, tzid
);
336 Calendar
*cal
= Calendar::createInstance(zone
->clone(), status
);
337 if (failure(status
, "Calendar::createInstance", TRUE
)) return;
339 if (*zone
!= cal
->getTimeZone()) errln("FAIL: Calendar::getTimeZone failed");
341 Calendar
*cal2
= Calendar::createInstance(cal
->getTimeZone(), status
);
342 if (failure(status
, "Calendar::createInstance")) return;
343 cal
->setTime(when
, status
);
344 cal2
->setTime(when
, status
);
345 if (failure(status
, "Calendar::setTime")) return;
347 if (!(*cal
== *cal2
)) errln("FAIL: Calendar::operator== failed");
348 if ((*cal
!= *cal2
)) errln("FAIL: Calendar::operator!= failed");
349 if (!cal
->equals(*cal2
, status
) ||
350 cal
->before(*cal2
, status
) ||
351 cal
->after(*cal2
, status
) ||
352 U_FAILURE(status
)) errln("FAIL: equals/before/after failed");
354 logln(UnicodeString("cal=") +cal
->getTime(status
) + UnicodeString(calToStr(*cal
)));
355 logln(UnicodeString("cal2=") +cal2
->getTime(status
) + UnicodeString(calToStr(*cal2
)));
356 logln("cal2->setTime(when+1000)");
357 cal2
->setTime(when
+ 1000, status
);
358 logln(UnicodeString("cal2=") +cal2
->getTime(status
) + UnicodeString(calToStr(*cal2
)));
360 if (failure(status
, "Calendar::setTime")) return;
361 if (cal
->equals(*cal2
, status
) ||
362 cal2
->before(*cal
, status
) ||
363 cal
->after(*cal2
, status
) ||
364 U_FAILURE(status
)) errln("FAIL: equals/before/after failed after setTime(+1000)");
366 logln("cal->roll(UCAL_SECOND)");
367 cal
->roll(UCAL_SECOND
, (UBool
) TRUE
, status
);
368 logln(UnicodeString("cal=") +cal
->getTime(status
) + UnicodeString(calToStr(*cal
)));
369 cal
->roll(UCAL_SECOND
, (int32_t)0, status
);
370 logln(UnicodeString("cal=") +cal
->getTime(status
) + UnicodeString(calToStr(*cal
)));
371 if (failure(status
, "Calendar::roll")) return;
373 if (!(eq
=cal
->equals(*cal2
, status
)) ||
374 (b4
=cal
->before(*cal2
, status
)) ||
375 (af
=cal
->after(*cal2
, status
)) ||
377 errln("FAIL: equals[%c]/before[%c]/after[%c] failed after roll 1 second [should be T/F/F]",
381 logln(UnicodeString("cal=") +cal
->getTime(status
) + UnicodeString(calToStr(*cal
)));
382 logln(UnicodeString("cal2=") +cal2
->getTime(status
) + UnicodeString(calToStr(*cal2
)));
385 // Roll back to January
386 cal
->roll(UCAL_MONTH
, (int32_t)(1 + UCAL_DECEMBER
- cal
->get(UCAL_MONTH
, status
)), status
);
387 if (failure(status
, "Calendar::roll")) return;
388 if (cal
->equals(*cal2
, status
) ||
389 cal2
->before(*cal
, status
) ||
390 cal
->after(*cal2
, status
) ||
391 U_FAILURE(status
)) errln("FAIL: equals/before/after failed after rollback to January");
393 TimeZone
*z
= cal
->orphanTimeZone();
394 if (z
->getID(str
) != tzid
||
395 z
->getRawOffset() != tzoffset
)
396 errln("FAIL: orphanTimeZone failed");
401 UBool lenient
= ( i
> 0 );
402 cal
->setLenient(lenient
);
403 if (lenient
!= cal
->isLenient()) errln("FAIL: setLenient/isLenient failed");
404 // Later: Check for lenient behavior
407 for (i
=UCAL_SUNDAY
; i
<=UCAL_SATURDAY
; ++i
)
409 cal
->setFirstDayOfWeek((UCalendarDaysOfWeek
)i
);
410 if (cal
->getFirstDayOfWeek() != i
) errln("FAIL: set/getFirstDayOfWeek failed");
411 UErrorCode aStatus
= U_ZERO_ERROR
;
412 if (cal
->getFirstDayOfWeek(aStatus
) != i
|| U_FAILURE(aStatus
)) errln("FAIL: getFirstDayOfWeek(status) failed");
417 cal
->setMinimalDaysInFirstWeek((uint8_t)i
);
418 if (cal
->getMinimalDaysInFirstWeek() != i
) errln("FAIL: set/getFirstDayOfWeek failed");
421 for (i
=0; i
<UCAL_FIELD_COUNT
; ++i
)
423 if (cal
->getMinimum((UCalendarDateFields
)i
) > cal
->getGreatestMinimum((UCalendarDateFields
)i
))
424 errln(UnicodeString("FAIL: getMinimum larger than getGreatestMinimum for field ") + i
);
425 if (cal
->getLeastMaximum((UCalendarDateFields
)i
) > cal
->getMaximum((UCalendarDateFields
)i
))
426 errln(UnicodeString("FAIL: getLeastMaximum larger than getMaximum for field ") + i
);
427 if (cal
->getMinimum((UCalendarDateFields
)i
) >= cal
->getMaximum((UCalendarDateFields
)i
))
428 errln(UnicodeString("FAIL: getMinimum not less than getMaximum for field ") + i
);
431 cal
->adoptTimeZone(TimeZone::createDefault());
433 cal
->set(1984, 5, 24);
434 if (cal
->getTime(status
) != date(84, 5, 24) || U_FAILURE(status
))
435 errln("FAIL: Calendar::set(3 args) failed");
438 cal
->set(1985, 3, 2, 11, 49);
439 if (cal
->getTime(status
) != date(85, 3, 2, 11, 49) || U_FAILURE(status
))
440 errln("FAIL: Calendar::set(5 args) failed");
443 cal
->set(1995, 9, 12, 1, 39, 55);
444 if (cal
->getTime(status
) != date(95, 9, 12, 1, 39, 55) || U_FAILURE(status
))
445 errln("FAIL: Calendar::set(6 args) failed");
447 cal
->getTime(status
);
448 if (failure(status
, "Calendar::getTime")) return;
449 for (i
=0; i
<UCAL_FIELD_COUNT
; ++i
)
452 case UCAL_YEAR
: case UCAL_MONTH
: case UCAL_DATE
:
453 case UCAL_HOUR_OF_DAY
: case UCAL_MINUTE
: case UCAL_SECOND
:
454 case UCAL_EXTENDED_YEAR
:
455 if (!cal
->isSet((UCalendarDateFields
)i
)) errln("FAIL: Calendar::isSet F, should be T " + fieldName((UCalendarDateFields
)i
));
458 if (cal
->isSet((UCalendarDateFields
)i
)) errln("FAIL: Calendar::isSet = T, should be F " + fieldName((UCalendarDateFields
)i
));
460 cal
->clear((UCalendarDateFields
)i
);
461 if (cal
->isSet((UCalendarDateFields
)i
)) errln("FAIL: Calendar::clear/isSet failed " + fieldName((UCalendarDateFields
)i
));
464 if(cal
->getActualMinimum(Calendar::SECOND
, status
) != 0){
465 errln("Calendar is suppose to return 0 for getActualMinimum");
468 Calendar
*cal3
= Calendar::createInstance(status
);
469 cal3
->roll(Calendar::SECOND
, (int32_t)0, status
);
470 if (failure(status
, "Calendar::roll(EDateFields, int32_t, UErrorCode)")) return;
477 const Locale
* loc
= Calendar::getAvailableLocales(count
);
478 if (count
< 1 || loc
== 0)
480 dataerrln("FAIL: getAvailableLocales failed");
484 for (i
=0; i
<count
; ++i
)
486 cal
= Calendar::createInstance(loc
[i
], status
);
487 if (failure(status
, "Calendar::createInstance")) return;
492 cal
= Calendar::createInstance(TimeZone::createDefault(), Locale::getEnglish(), status
);
493 if (failure(status
, "Calendar::createInstance")) return;
496 cal
= Calendar::createInstance(*zone
, Locale::getEnglish(), status
);
497 if (failure(status
, "Calendar::createInstance")) return;
500 GregorianCalendar
*gc
= new GregorianCalendar(*zone
, status
);
501 if (failure(status
, "new GregorianCalendar")) return;
504 gc
= new GregorianCalendar(Locale::getEnglish(), status
);
505 if (failure(status
, "new GregorianCalendar")) return;
508 gc
= new GregorianCalendar(Locale::getEnglish(), status
);
511 gc
= new GregorianCalendar(*zone
, Locale::getEnglish(), status
);
512 if (failure(status
, "new GregorianCalendar")) return;
515 gc
= new GregorianCalendar(zone
, status
);
516 if (failure(status
, "new GregorianCalendar")) return;
519 gc
= new GregorianCalendar(1998, 10, 14, 21, 43, status
);
520 if (gc
->getTime(status
) != (d
=date(98, 10, 14, 21, 43) )|| U_FAILURE(status
))
521 errln("FAIL: new GregorianCalendar(ymdhm) failed with " + UnicodeString(u_errorName(status
)) + ", cal=" + gc
->getTime(status
) + UnicodeString(calToStr(*gc
)) + ", d=" + d
);
523 logln(UnicodeString("GOOD: cal=") +gc
->getTime(status
) + UnicodeString(calToStr(*gc
)) + ", d=" + d
);
526 gc
= new GregorianCalendar(1998, 10, 14, 21, 43, 55, status
);
527 if (gc
->getTime(status
) != (d
=date(98, 10, 14, 21, 43, 55)) || U_FAILURE(status
))
528 errln("FAIL: new GregorianCalendar(ymdhms) failed with " + UnicodeString(u_errorName(status
)));
530 GregorianCalendar
gc2(Locale::getEnglish(), status
);
531 if (failure(status
, "new GregorianCalendar")) return;
533 if (gc2
!= *gc
|| !(gc2
== *gc
)) errln("FAIL: GregorianCalendar assignment/operator==/operator!= failed");
537 /* Code coverage for Calendar class. */
538 cal
= Calendar::createInstance(status
);
539 if (failure(status
, "Calendar::createInstance")) {
542 ((Calendar
*)cal
)->roll(UCAL_HOUR
, (int32_t)100, status
);
543 ((Calendar
*)cal
)->clear(UCAL_HOUR
);
544 #if !UCONFIG_NO_SERVICE
545 URegistryKey key
= cal
->registerFactory(NULL
, status
);
546 cal
->unregister(key
, status
);
551 status
= U_ZERO_ERROR
;
552 cal
= Calendar::createInstance(Locale("he_IL@calendar=hebrew"), status
);
553 if (failure(status
, "Calendar::createInstance")) {
556 cal
->roll(Calendar::MONTH
, (int32_t)100, status
);
559 LocalPointer
<StringEnumeration
> values(
560 Calendar::getKeywordValuesForLocale("calendar", Locale("he"), FALSE
, status
));
561 if (values
.isNull() || U_FAILURE(status
)) {
562 dataerrln("FAIL: Calendar::getKeywordValuesForLocale(he): %s", u_errorName(status
));
564 UBool containsHebrew
= FALSE
;
565 const char *charValue
;
567 while ((charValue
= values
->next(&valueLength
, status
)) != NULL
) {
568 if (valueLength
== 6 && strcmp(charValue
, "hebrew") == 0) {
569 containsHebrew
= TRUE
;
572 if (!containsHebrew
) {
573 errln("Calendar::getKeywordValuesForLocale(he)->next() does not contain \"hebrew\"");
576 values
->reset(status
);
577 containsHebrew
= FALSE
;
578 UnicodeString hebrew
= UNICODE_STRING_SIMPLE("hebrew");
579 const UChar
*ucharValue
;
580 while ((ucharValue
= values
->unext(&valueLength
, status
)) != NULL
) {
581 UnicodeString
value(FALSE
, ucharValue
, valueLength
);
582 if (value
== hebrew
) {
583 containsHebrew
= TRUE
;
586 if (!containsHebrew
) {
587 errln("Calendar::getKeywordValuesForLocale(he)->unext() does not contain \"hebrew\"");
590 values
->reset(status
);
591 containsHebrew
= FALSE
;
592 const UnicodeString
*stringValue
;
593 while ((stringValue
= values
->snext(status
)) != NULL
) {
594 if (*stringValue
== hebrew
) {
595 containsHebrew
= TRUE
;
598 if (!containsHebrew
) {
599 errln("Calendar::getKeywordValuesForLocale(he)->snext() does not contain \"hebrew\"");
605 // -------------------------------------
608 * This test confirms the correct behavior of add when incrementing
609 * through subsequent days.
612 CalendarTest::TestRog()
614 UErrorCode status
= U_ZERO_ERROR
;
615 GregorianCalendar
* gc
= new GregorianCalendar(status
);
616 if (failure(status
, "new GregorianCalendar", TRUE
)) return;
617 int32_t year
= 1997, month
= UCAL_APRIL
, date
= 1;
618 gc
->set(year
, month
, date
);
619 gc
->set(UCAL_HOUR_OF_DAY
, 23);
620 gc
->set(UCAL_MINUTE
, 0);
621 gc
->set(UCAL_SECOND
, 0);
622 gc
->set(UCAL_MILLISECOND
, 0);
623 for (int32_t i
= 0; i
< 9; i
++, gc
->add(UCAL_DATE
, 1, status
)) {
624 if (U_FAILURE(status
)) { errln("Calendar::add failed"); return; }
625 if (gc
->get(UCAL_YEAR
, status
) != year
||
626 gc
->get(UCAL_MONTH
, status
) != month
||
627 gc
->get(UCAL_DATE
, status
) != (date
+ i
)) errln("FAIL: Date wrong");
628 if (U_FAILURE(status
)) { errln("Calendar::get failed"); return; }
633 // -------------------------------------
636 * Test the handling of the day of the week, checking for correctness and
637 * for correct minimum and maximum values.
640 CalendarTest::TestDOW943()
646 void CalendarTest::dowTest(UBool lenient
)
648 UErrorCode status
= U_ZERO_ERROR
;
649 GregorianCalendar
* cal
= new GregorianCalendar(status
);
650 if (failure(status
, "new GregorianCalendar", TRUE
)) return;
651 logln("cal - Aug 12, 1997\n");
652 cal
->set(1997, UCAL_AUGUST
, 12);
653 cal
->getTime(status
);
654 if (U_FAILURE(status
)) { errln("Calendar::getTime failed"); return; }
655 logln((lenient
?UnicodeString("LENIENT0: "):UnicodeString("nonlenient0: ")) + UnicodeString(calToStr(*cal
)));
656 cal
->setLenient(lenient
);
657 logln("cal - Dec 1, 1996\n");
658 cal
->set(1996, UCAL_DECEMBER
, 1);
659 logln((lenient
?UnicodeString("LENIENT: "):UnicodeString("nonlenient: ")) + UnicodeString(calToStr(*cal
)));
660 int32_t dow
= cal
->get(UCAL_DAY_OF_WEEK
, status
);
661 if (U_FAILURE(status
)) { errln("Calendar::get failed [%s]", u_errorName(status
)); return; }
662 int32_t min
= cal
->getMinimum(UCAL_DAY_OF_WEEK
);
663 int32_t max
= cal
->getMaximum(UCAL_DAY_OF_WEEK
);
665 dow
> max
) errln(UnicodeString("FAIL: Day of week ") + (int32_t)dow
+ " out of range");
666 if (dow
!= UCAL_SUNDAY
) errln("FAIL: Day of week should be SUNDAY[%d] not %d", UCAL_SUNDAY
, dow
);
667 if (min
!= UCAL_SUNDAY
||
668 max
!= UCAL_SATURDAY
) errln("FAIL: Min/max bad");
672 // -------------------------------------
675 * Confirm that cloned Calendar objects do not inadvertently share substructures.
678 CalendarTest::TestClonesUnique908()
680 UErrorCode status
= U_ZERO_ERROR
;
681 Calendar
*c
= Calendar::createInstance(status
);
682 if (failure(status
, "Calendar::createInstance", TRUE
)) return;
683 Calendar
*d
= (Calendar
*) c
->clone();
684 c
->set(UCAL_MILLISECOND
, 123);
685 d
->set(UCAL_MILLISECOND
, 456);
686 if (c
->get(UCAL_MILLISECOND
, status
) != 123 ||
687 d
->get(UCAL_MILLISECOND
, status
) != 456) {
688 errln("FAIL: Clones share fields");
690 if (U_FAILURE(status
)) { errln("Calendar::get failed"); return; }
695 // -------------------------------------
698 * Confirm that the Gregorian cutoff value works as advertised.
701 CalendarTest::TestGregorianChange768()
704 UErrorCode status
= U_ZERO_ERROR
;
706 GregorianCalendar
* c
= new GregorianCalendar(status
);
707 if (failure(status
, "new GregorianCalendar", TRUE
)) return;
708 logln(UnicodeString("With cutoff ") + dateToString(c
->getGregorianChange(), str
));
709 b
= c
->isLeapYear(1800);
710 logln(UnicodeString(" isLeapYear(1800) = ") + (b
? "true" : "false"));
711 logln(UnicodeString(" (should be FALSE)"));
712 if (b
) errln("FAIL");
713 c
->setGregorianChange(date(0, 0, 1), status
);
714 if (U_FAILURE(status
)) { errln("GregorianCalendar::setGregorianChange failed"); 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 TRUE)"));
719 if (!b
) errln("FAIL");
723 // -------------------------------------
726 * Confirm the functioning of the field disambiguation algorithm.
729 CalendarTest::TestDisambiguation765()
731 UErrorCode status
= U_ZERO_ERROR
;
732 Calendar
*c
= Calendar::createInstance("en_US", status
);
733 if (failure(status
, "Calendar::createInstance", TRUE
)) return;
734 c
->setLenient(FALSE
);
736 c
->set(UCAL_YEAR
, 1997);
737 c
->set(UCAL_MONTH
, UCAL_JUNE
);
738 c
->set(UCAL_DATE
, 3);
739 verify765("1997 third day of June = ", c
, 1997, UCAL_JUNE
, 3);
741 c
->set(UCAL_YEAR
, 1997);
742 c
->set(UCAL_DAY_OF_WEEK
, UCAL_TUESDAY
);
743 c
->set(UCAL_MONTH
, UCAL_JUNE
);
744 c
->set(UCAL_DAY_OF_WEEK_IN_MONTH
, 1);
745 verify765("1997 first Tuesday in June = ", c
, 1997, UCAL_JUNE
, 3);
747 c
->set(UCAL_YEAR
, 1997);
748 c
->set(UCAL_DAY_OF_WEEK
, UCAL_TUESDAY
);
749 c
->set(UCAL_MONTH
, UCAL_JUNE
);
750 c
->set(UCAL_DAY_OF_WEEK_IN_MONTH
, - 1);
751 verify765("1997 last Tuesday in June = ", c
, 1997, UCAL_JUNE
, 24);
753 status
= U_ZERO_ERROR
;
755 c
->set(UCAL_YEAR
, 1997);
756 c
->set(UCAL_DAY_OF_WEEK
, UCAL_TUESDAY
);
757 c
->set(UCAL_MONTH
, UCAL_JUNE
);
758 c
->set(UCAL_DAY_OF_WEEK_IN_MONTH
, 0);
760 verify765("1997 zero-th Tuesday in June = ", status
);
763 c
->set(UCAL_YEAR
, 1997);
764 c
->set(UCAL_DAY_OF_WEEK
, UCAL_TUESDAY
);
765 c
->set(UCAL_MONTH
, UCAL_JUNE
);
766 c
->set(UCAL_WEEK_OF_MONTH
, 1);
767 verify765("1997 Tuesday in week 1 of June = ", c
, 1997, UCAL_JUNE
, 3);
769 c
->set(UCAL_YEAR
, 1997);
770 c
->set(UCAL_DAY_OF_WEEK
, UCAL_TUESDAY
);
771 c
->set(UCAL_MONTH
, UCAL_JUNE
);
772 c
->set(UCAL_WEEK_OF_MONTH
, 5);
773 verify765("1997 Tuesday in week 5 of June = ", c
, 1997, UCAL_JULY
, 1);
775 status
= U_ZERO_ERROR
;
777 c
->set(UCAL_YEAR
, 1997);
778 c
->set(UCAL_DAY_OF_WEEK
, UCAL_TUESDAY
);
779 c
->set(UCAL_MONTH
, UCAL_JUNE
);
780 c
->set(UCAL_WEEK_OF_MONTH
, 0);
781 c
->setMinimalDaysInFirstWeek(1);
783 verify765("1997 Tuesday in week 0 of June = ", status
);
785 /* Note: The following test used to expect YEAR 1997, WOY 1 to
786 * resolve to a date in Dec 1996; that is, to behave as if
787 * YEAR_WOY were 1997. With the addition of a new explicit
788 * YEAR_WOY field, YEAR_WOY must itself be set if that is what is
789 * desired. Using YEAR in combination with WOY is ambiguous, and
790 * results in the first WOY/DOW day of the year satisfying the
791 * given fields (there may be up to two such days). In this case,
792 * it propertly resolves to Tue Dec 30 1997, which has a WOY value
793 * of 1 (for YEAR_WOY 1998) and a DOW of Tuesday, and falls in the
794 * _calendar_ year 1997, as specified. - aliu */
796 c
->set(UCAL_YEAR_WOY
, 1997); // aliu
797 c
->set(UCAL_DAY_OF_WEEK
, UCAL_TUESDAY
);
798 c
->set(UCAL_WEEK_OF_YEAR
, 1);
799 verify765("1997 Tuesday in week 1 of yearWOY = ", c
, 1996, UCAL_DECEMBER
, 31);
800 c
->clear(); // - add test for YEAR
801 c
->setMinimalDaysInFirstWeek(1);
802 c
->set(UCAL_YEAR
, 1997);
803 c
->set(UCAL_DAY_OF_WEEK
, UCAL_TUESDAY
);
804 c
->set(UCAL_WEEK_OF_YEAR
, 1);
805 verify765("1997 Tuesday in week 1 of year = ", c
, 1997, UCAL_DECEMBER
, 30);
807 c
->set(UCAL_YEAR
, 1997);
808 c
->set(UCAL_DAY_OF_WEEK
, UCAL_TUESDAY
);
809 c
->set(UCAL_WEEK_OF_YEAR
, 10);
810 verify765("1997 Tuesday in week 10 of year = ", c
, 1997, UCAL_MARCH
, 4);
813 // {sfb} week 0 is no longer a valid week of year
815 c->set(Calendar::YEAR, 1997);
816 c->set(Calendar::DAY_OF_WEEK, Calendar::TUESDAY);
817 //c->set(Calendar::WEEK_OF_YEAR, 0);
818 c->set(Calendar::WEEK_OF_YEAR, 1);
819 verify765("1997 Tuesday in week 0 of year = ", c, 1996, Calendar::DECEMBER, 24);*/
822 //catch(IllegalArgumentException ex) {
823 // errln("FAIL: Exception seen:");
824 // ex.printStackTrace(log);
829 // -------------------------------------
832 CalendarTest::verify765(const UnicodeString
& msg
, Calendar
* c
, int32_t year
, int32_t month
, int32_t day
)
835 UErrorCode status
= U_ZERO_ERROR
;
836 int32_t y
= c
->get(UCAL_YEAR
, status
);
837 int32_t m
= c
->get(UCAL_MONTH
, status
);
838 int32_t d
= c
->get(UCAL_DATE
, status
);
842 if (U_FAILURE(status
)) { errln("FAIL: Calendar::get failed"); return; }
843 logln("PASS: " + msg
+ dateToString(c
->getTime(status
), str
));
844 if (U_FAILURE(status
)) { errln("Calendar::getTime failed"); return; }
847 errln("FAIL: " + msg
+ dateToString(c
->getTime(status
), str
) + "; expected " + (int32_t)year
+ "/" + (int32_t)(month
+ 1) + "/" + (int32_t)day
+
848 "; got " + (int32_t)y
+ "/" + (int32_t)(m
+ 1) + "/" + (int32_t)d
+ " for Locale: " + c
->getLocaleID(ULOC_ACTUAL_LOCALE
,status
));
849 if (U_FAILURE(status
)) { errln("Calendar::getTime failed"); return; }
853 // -------------------------------------
856 CalendarTest::verify765(const UnicodeString
& msg
/*, IllegalArgumentException e*/, UErrorCode status
)
858 if (status
!= U_ILLEGAL_ARGUMENT_ERROR
) errln("FAIL: No IllegalArgumentException for " + msg
);
859 else logln("PASS: " + msg
+ "IllegalArgument as expected");
862 // -------------------------------------
865 * Confirm that the offset between local time and GMT behaves as expected.
868 CalendarTest::TestGMTvsLocal4064654()
870 test4064654(1997, 1, 1, 12, 0, 0);
871 test4064654(1997, 4, 16, 18, 30, 0);
874 // -------------------------------------
877 CalendarTest::test4064654(int32_t yr
, int32_t mo
, int32_t dt
, int32_t hr
, int32_t mn
, int32_t sc
)
880 UErrorCode status
= U_ZERO_ERROR
;
882 Calendar
*gmtcal
= Calendar::createInstance(status
);
883 if (failure(status
, "Calendar::createInstance", TRUE
)) return;
884 gmtcal
->adoptTimeZone(TimeZone::createTimeZone("Africa/Casablanca"));
885 gmtcal
->set(yr
, mo
- 1, dt
, hr
, mn
, sc
);
886 gmtcal
->set(UCAL_MILLISECOND
, 0);
887 date
= gmtcal
->getTime(status
);
888 if (U_FAILURE(status
)) { errln("Calendar::getTime failed"); return; }
889 logln("date = " + dateToString(date
, str
));
890 Calendar
*cal
= Calendar::createInstance(status
);
891 if (U_FAILURE(status
)) { errln("Calendar::createInstance failed"); return; }
892 cal
->setTime(date
, status
);
893 if (U_FAILURE(status
)) { errln("Calendar::setTime failed"); return; }
894 int32_t offset
= cal
->getTimeZone().getOffset((uint8_t)cal
->get(UCAL_ERA
, status
),
895 cal
->get(UCAL_YEAR
, status
),
896 cal
->get(UCAL_MONTH
, status
),
897 cal
->get(UCAL_DATE
, status
),
898 (uint8_t)cal
->get(UCAL_DAY_OF_WEEK
, status
),
899 cal
->get(UCAL_MILLISECOND
, status
), status
);
900 if (U_FAILURE(status
)) { errln("Calendar::get failed"); return; }
901 logln("offset for " + dateToString(date
, str
) + "= " + (offset
/ 1000 / 60 / 60.0) + "hr");
902 int32_t utc
= ((cal
->get(UCAL_HOUR_OF_DAY
, status
) * 60 +
903 cal
->get(UCAL_MINUTE
, status
)) * 60 +
904 cal
->get(UCAL_SECOND
, status
)) * 1000 +
905 cal
->get(UCAL_MILLISECOND
, status
) - offset
;
906 if (U_FAILURE(status
)) { errln("Calendar::get failed"); return; }
907 int32_t expected
= ((hr
* 60 + mn
) * 60 + sc
) * 1000;
908 if (utc
!= expected
) errln(UnicodeString("FAIL: Discrepancy of ") + (utc
- expected
) +
909 " millis = " + ((utc
- expected
) / 1000 / 60 / 60.0) + " hr");
914 // -------------------------------------
917 * The operations of adding and setting should not exhibit pathological
918 * dependence on the order of operations. This test checks for this.
921 CalendarTest::TestAddSetOrder621()
923 UDate d
= date(97, 4, 14, 13, 23, 45);
924 UErrorCode status
= U_ZERO_ERROR
;
925 Calendar
*cal
= Calendar::createInstance(status
);
926 if (failure(status
, "Calendar::createInstance", TRUE
)) return;
928 cal
->setTime(d
, status
);
929 if (U_FAILURE(status
)) {
930 errln("Calendar::setTime failed");
934 cal
->add(UCAL_DATE
, - 5, status
);
935 if (U_FAILURE(status
)) {
936 errln("Calendar::add failed");
940 cal
->set(UCAL_HOUR_OF_DAY
, 0);
941 cal
->set(UCAL_MINUTE
, 0);
942 cal
->set(UCAL_SECOND
, 0);
944 dateToString(cal
->getTime(status
), s
);
945 if (U_FAILURE(status
)) {
946 errln("Calendar::getTime failed");
952 cal
= Calendar::createInstance(status
);
953 if (U_FAILURE(status
)) {
954 errln("Calendar::createInstance failed");
958 cal
->setTime(d
, status
);
959 if (U_FAILURE(status
)) {
960 errln("Calendar::setTime failed");
964 cal
->set(UCAL_HOUR_OF_DAY
, 0);
965 cal
->set(UCAL_MINUTE
, 0);
966 cal
->set(UCAL_SECOND
, 0);
967 cal
->add(UCAL_DATE
, - 5, status
);
968 if (U_FAILURE(status
)) {
969 errln("Calendar::add failed");
974 dateToString(cal
->getTime(status
), s2
);
975 if (U_FAILURE(status
)) {
976 errln("Calendar::getTime failed");
981 logln("Pass: " + s
+ " == " + s2
);
983 errln("FAIL: " + s
+ " != " + s2
);
987 // -------------------------------------
990 * Confirm that adding to various fields works.
993 CalendarTest::TestAdd520()
995 int32_t y
= 1997, m
= UCAL_FEBRUARY
, d
= 1;
996 UErrorCode status
= U_ZERO_ERROR
;
997 GregorianCalendar
*temp
= new GregorianCalendar(y
, m
, d
, status
);
998 if (failure(status
, "new GregorianCalendar", TRUE
)) return;
999 check520(temp
, y
, m
, d
);
1000 temp
->add(UCAL_YEAR
, 1, status
);
1001 if (U_FAILURE(status
)) { errln("Calendar::add failed"); return; }
1003 check520(temp
, y
, m
, d
);
1004 temp
->add(UCAL_MONTH
, 1, status
);
1005 if (U_FAILURE(status
)) { errln("Calendar::add failed"); return; }
1007 check520(temp
, y
, m
, d
);
1008 temp
->add(UCAL_DATE
, 1, status
);
1009 if (U_FAILURE(status
)) { errln("Calendar::add failed"); return; }
1011 check520(temp
, y
, m
, d
);
1012 temp
->add(UCAL_DATE
, 2, status
);
1013 if (U_FAILURE(status
)) { errln("Calendar::add failed"); return; }
1015 check520(temp
, y
, m
, d
);
1016 temp
->add(UCAL_DATE
, 28, status
);
1017 if (U_FAILURE(status
)) { errln("Calendar::add failed"); return; }
1019 check520(temp
, y
, m
, d
);
1023 // -------------------------------------
1026 * Execute adding and rolling in GregorianCalendar extensively,
1029 CalendarTest::TestAddRollExtensive()
1031 int32_t maxlimit
= 40;
1032 int32_t y
= 1997, m
= UCAL_FEBRUARY
, d
= 1, hr
= 1, min
= 1, sec
= 0, ms
= 0;
1033 UErrorCode status
= U_ZERO_ERROR
;
1034 GregorianCalendar
*temp
= new GregorianCalendar(y
, m
, d
, status
);
1035 if (failure(status
, "new GregorianCalendar", TRUE
)) return;
1037 temp
->set(UCAL_HOUR
, hr
);
1038 temp
->set(UCAL_MINUTE
, min
);
1039 temp
->set(UCAL_SECOND
, sec
);
1040 temp
->set(UCAL_MILLISECOND
, ms
);
1041 temp
->setMinimalDaysInFirstWeek(1);
1043 UCalendarDateFields e
;
1045 logln("Testing GregorianCalendar add...");
1047 while (e
< UCAL_FIELD_COUNT
) {
1049 int32_t limit
= maxlimit
;
1050 status
= U_ZERO_ERROR
;
1051 for (i
= 0; i
< limit
; i
++) {
1052 temp
->add(e
, 1, status
);
1053 if (U_FAILURE(status
)) { limit
= i
; status
= U_ZERO_ERROR
; }
1055 for (i
= 0; i
< limit
; i
++) {
1056 temp
->add(e
, -1, status
);
1057 if (U_FAILURE(status
)) { errln("GregorianCalendar::add -1 failed"); return; }
1059 check520(temp
, y
, m
, d
, hr
, min
, sec
, ms
, e
);
1061 e
= (UCalendarDateFields
) ((int32_t) e
+ 1);
1064 logln("Testing GregorianCalendar roll...");
1066 while (e
< UCAL_FIELD_COUNT
) {
1068 int32_t limit
= maxlimit
;
1069 status
= U_ZERO_ERROR
;
1070 for (i
= 0; i
< limit
; i
++) {
1071 logln(calToStr(*temp
) + UnicodeString(" " ) + fieldName(e
) + UnicodeString("++") );
1072 temp
->roll(e
, 1, status
);
1073 if (U_FAILURE(status
)) {
1074 logln("caltest.cpp:%d e=%d, i=%d - roll(+) err %s\n", __LINE__
, (int) e
, (int) i
, u_errorName(status
));
1075 logln(calToStr(*temp
));
1076 limit
= i
; status
= U_ZERO_ERROR
;
1079 for (i
= 0; i
< limit
; i
++) {
1080 logln("caltest.cpp:%d e=%d, i=%d\n", __LINE__
, (int) e
, (int) i
);
1081 logln(calToStr(*temp
) + UnicodeString(" " ) + fieldName(e
) + UnicodeString("--") );
1082 temp
->roll(e
, -1, status
);
1083 if (U_FAILURE(status
)) { errln(UnicodeString("GregorianCalendar::roll ") + CalendarTest::fieldName(e
) + " count=" + UnicodeString('@'+i
) + " by -1 failed with " + u_errorName(status
) ); return; }
1085 check520(temp
, y
, m
, d
, hr
, min
, sec
, ms
, e
);
1087 e
= (UCalendarDateFields
) ((int32_t) e
+ 1);
1093 // -------------------------------------
1095 CalendarTest::check520(Calendar
* c
,
1096 int32_t y
, int32_t m
, int32_t d
,
1097 int32_t hr
, int32_t min
, int32_t sec
,
1098 int32_t ms
, UCalendarDateFields field
)
1101 UErrorCode status
= U_ZERO_ERROR
;
1102 if (c
->get(UCAL_YEAR
, status
) != y
||
1103 c
->get(UCAL_MONTH
, status
) != m
||
1104 c
->get(UCAL_DATE
, status
) != d
||
1105 c
->get(UCAL_HOUR
, status
) != hr
||
1106 c
->get(UCAL_MINUTE
, status
) != min
||
1107 c
->get(UCAL_SECOND
, status
) != sec
||
1108 c
->get(UCAL_MILLISECOND
, status
) != ms
) {
1109 errln(UnicodeString("U_FAILURE for field ") + (int32_t)field
+
1110 ": Expected y/m/d h:m:s:ms of " +
1111 y
+ "/" + (m
+ 1) + "/" + d
+ " " +
1112 hr
+ ":" + min
+ ":" + sec
+ ":" + ms
+
1113 "; got " + c
->get(UCAL_YEAR
, status
) +
1114 "/" + (c
->get(UCAL_MONTH
, status
) + 1) +
1115 "/" + c
->get(UCAL_DATE
, status
) +
1116 " " + c
->get(UCAL_HOUR
, status
) + ":" +
1117 c
->get(UCAL_MINUTE
, status
) + ":" +
1118 c
->get(UCAL_SECOND
, status
) + ":" +
1119 c
->get(UCAL_MILLISECOND
, status
)
1122 if (U_FAILURE(status
)) { errln("Calendar::get failed"); return; }
1125 logln(UnicodeString("Confirmed: ") + y
+ "/" +
1126 (m
+ 1) + "/" + d
+ " " +
1127 hr
+ ":" + min
+ ":" + sec
+ ":" + ms
);
1130 // -------------------------------------
1132 CalendarTest::check520(Calendar
* c
,
1133 int32_t y
, int32_t m
, int32_t d
)
1136 UErrorCode status
= U_ZERO_ERROR
;
1137 if (c
->get(UCAL_YEAR
, status
) != y
||
1138 c
->get(UCAL_MONTH
, status
) != m
||
1139 c
->get(UCAL_DATE
, status
) != d
) {
1140 errln(UnicodeString("FAILURE: Expected y/m/d of ") +
1141 y
+ "/" + (m
+ 1) + "/" + d
+ " " +
1142 "; got " + c
->get(UCAL_YEAR
, status
) +
1143 "/" + (c
->get(UCAL_MONTH
, status
) + 1) +
1144 "/" + c
->get(UCAL_DATE
, status
)
1147 if (U_FAILURE(status
)) { errln("Calendar::get failed"); return; }
1150 logln(UnicodeString("Confirmed: ") + y
+ "/" +
1154 // -------------------------------------
1157 * Test that setting of fields works. In particular, make sure that all instances
1158 * of GregorianCalendar don't share a static instance of the fields array.
1161 CalendarTest::TestFieldSet4781()
1164 UErrorCode status
= U_ZERO_ERROR
;
1165 GregorianCalendar
*g
= new GregorianCalendar(status
);
1166 if (failure(status
, "new GregorianCalendar", TRUE
)) return;
1167 GregorianCalendar
*g2
= new GregorianCalendar(status
);
1168 if (U_FAILURE(status
)) { errln("Couldn't create GregorianCalendar"); return; }
1169 g2
->set(UCAL_HOUR
, 12, status
);
1170 g2
->set(UCAL_MINUTE
, 0, status
);
1171 g2
->set(UCAL_SECOND
, 0, status
);
1172 if (U_FAILURE(status
)) { errln("Calendar::set failed"); return; }
1173 if (*g
== *g2
) logln("Same");
1174 else logln("Different");
1176 //catch(IllegalArgumentException e) {
1177 //errln("Unexpected exception seen: " + e);
1183 // -------------------------------------
1185 /* We don't support serialization on C++
1187 CalendarTest::TestSerialize337()
1189 Calendar cal = Calendar::getInstance();
1192 FileOutputStream f = new FileOutputStream(FILENAME);
1193 ObjectOutput s = new ObjectOutputStream(f);
1194 s.writeObject(PREFIX);
1196 s.writeObject(POSTFIX);
1198 FileInputStream in = new FileInputStream(FILENAME);
1199 ObjectInputStream t = new ObjectInputStream(in);
1200 UnicodeString& pre = (UnicodeString&) t.readObject();
1201 Calendar c = (Calendar) t.readObject();
1202 UnicodeString& post = (UnicodeString&) t.readObject();
1204 ok = pre.equals(PREFIX) &&
1205 post.equals(POSTFIX) &&
1207 File fl = new File(FILENAME);
1210 catch(IOException e) {
1211 errln("FAIL: Exception received:");
1212 e.printStackTrace(log);
1214 catch(ClassNotFoundException e) {
1215 errln("FAIL: Exception received:");
1216 e.printStackTrace(log);
1218 if (!ok) errln("Serialization of Calendar object failed.");
1221 UnicodeString& CalendarTest::PREFIX = "abc";
1223 UnicodeString& CalendarTest::POSTFIX = "def";
1225 UnicodeString& CalendarTest::FILENAME = "tmp337.bin";
1228 // -------------------------------------
1231 * Verify that the seconds of a Calendar can be zeroed out through the
1232 * expected sequence of operations.
1235 CalendarTest::TestSecondsZero121()
1237 UErrorCode status
= U_ZERO_ERROR
;
1238 Calendar
*cal
= new GregorianCalendar(status
);
1239 if (failure(status
, "new GregorianCalendar", TRUE
)) return;
1240 cal
->setTime(Calendar::getNow(), status
);
1241 if (U_FAILURE(status
)) { errln("Calendar::setTime failed"); return; }
1242 cal
->set(UCAL_SECOND
, 0);
1243 if (U_FAILURE(status
)) { errln("Calendar::set failed"); return; }
1244 UDate d
= cal
->getTime(status
);
1245 if (U_FAILURE(status
)) { errln("Calendar::getTime failed"); return; }
1248 if (s
.indexOf("DATE_FORMAT_FAILURE") >= 0) {
1249 dataerrln("Got: \"DATE_FORMAT_FAILURE\".");
1250 } else if (s
.indexOf(":00 ") < 0) {
1251 errln("Expected to see :00 in " + s
);
1256 // -------------------------------------
1259 * Verify that a specific sequence of adding and setting works as expected;
1260 * it should not vary depending on when and whether the get method is
1264 CalendarTest::TestAddSetGet0610()
1266 UnicodeString
EXPECTED_0610("1993/0/5", "");
1267 UErrorCode status
= U_ZERO_ERROR
;
1269 Calendar
*calendar
= new GregorianCalendar(status
);
1270 if (failure(status
, "new GregorianCalendar", TRUE
)) return;
1271 calendar
->set(1993, UCAL_JANUARY
, 4);
1272 logln("1A) " + value(calendar
));
1273 calendar
->add(UCAL_DATE
, 1, status
);
1274 if (U_FAILURE(status
)) { errln("Calendar::add failed"); return; }
1275 UnicodeString v
= value(calendar
);
1277 logln("--) 1993/0/5");
1278 if (!(v
== EXPECTED_0610
)) errln("Expected " + EXPECTED_0610
+ "; saw " + v
);
1282 Calendar
*calendar
= new GregorianCalendar(1993, UCAL_JANUARY
, 4, status
);
1283 if (U_FAILURE(status
)) { errln("Couldn't create GregorianCalendar"); return; }
1284 logln("2A) " + value(calendar
));
1285 calendar
->add(UCAL_DATE
, 1, status
);
1286 if (U_FAILURE(status
)) { errln("Calendar::add failed"); return; }
1287 UnicodeString v
= value(calendar
);
1289 logln("--) 1993/0/5");
1290 if (!(v
== EXPECTED_0610
)) errln("Expected " + EXPECTED_0610
+ "; saw " + v
);
1294 Calendar
*calendar
= new GregorianCalendar(1993, UCAL_JANUARY
, 4, status
);
1295 if (U_FAILURE(status
)) { errln("Couldn't create GregorianCalendar"); return; }
1296 logln("3A) " + value(calendar
));
1297 calendar
->getTime(status
);
1298 if (U_FAILURE(status
)) { errln("Calendar::getTime failed"); return; }
1299 calendar
->add(UCAL_DATE
, 1, status
);
1300 if (U_FAILURE(status
)) { errln("Calendar::add failed"); return; }
1301 UnicodeString v
= value(calendar
);
1303 logln("--) 1993/0/5");
1304 if (!(v
== EXPECTED_0610
)) errln("Expected " + EXPECTED_0610
+ "; saw " + v
);
1309 // -------------------------------------
1312 CalendarTest::value(Calendar
* calendar
)
1314 UErrorCode status
= U_ZERO_ERROR
;
1315 return UnicodeString("") + (int32_t)calendar
->get(UCAL_YEAR
, status
) +
1316 "/" + (int32_t)calendar
->get(UCAL_MONTH
, status
) +
1317 "/" + (int32_t)calendar
->get(UCAL_DATE
, status
) +
1318 (U_FAILURE(status
) ? " FAIL: Calendar::get failed" : "");
1322 // -------------------------------------
1325 * Verify that various fields on a known date are set correctly.
1328 CalendarTest::TestFields060()
1330 UErrorCode status
= U_ZERO_ERROR
;
1331 int32_t year
= 1997;
1332 int32_t month
= UCAL_OCTOBER
;
1334 GregorianCalendar
*calendar
= 0;
1335 calendar
= new GregorianCalendar(year
, month
, dDate
, status
);
1336 if (failure(status
, "new GregorianCalendar", TRUE
)) return;
1337 for (int32_t i
= 0; i
< EXPECTED_FIELDS_length
;) {
1338 UCalendarDateFields field
= (UCalendarDateFields
)EXPECTED_FIELDS
[i
++];
1339 int32_t expected
= EXPECTED_FIELDS
[i
++];
1340 if (calendar
->get(field
, status
) != expected
) {
1341 errln(UnicodeString("Expected field ") + (int32_t)field
+ " to have value " + (int32_t)expected
+
1342 "; received " + (int32_t)calendar
->get(field
, status
) + " instead");
1343 if (U_FAILURE(status
)) { errln("Calendar::get failed"); return; }
1349 int32_t CalendarTest::EXPECTED_FIELDS
[] = {
1351 UCAL_MONTH
, UCAL_OCTOBER
,
1353 UCAL_DAY_OF_WEEK
, UCAL_WEDNESDAY
,
1354 UCAL_DAY_OF_WEEK_IN_MONTH
, 4,
1355 UCAL_DAY_OF_YEAR
, 295
1358 const int32_t CalendarTest::EXPECTED_FIELDS_length
= (int32_t)(sizeof(CalendarTest::EXPECTED_FIELDS
) /
1359 sizeof(CalendarTest::EXPECTED_FIELDS
[0]));
1361 // -------------------------------------
1364 * Verify that various fields on a known date are set correctly. In this
1365 * case, the start of the epoch (January 1 1970).
1368 CalendarTest::TestEpochStartFields()
1370 UErrorCode status
= U_ZERO_ERROR
;
1371 TimeZone
*z
= TimeZone::createDefault();
1372 Calendar
*c
= Calendar::createInstance(status
);
1373 if (failure(status
, "Calendar::createInstance", TRUE
)) return;
1374 UDate d
= - z
->getRawOffset();
1375 GregorianCalendar
*gc
= new GregorianCalendar(status
);
1376 if (U_FAILURE(status
)) { errln("Couldn't create GregorianCalendar"); return; }
1377 gc
->setTimeZone(*z
);
1378 gc
->setTime(d
, status
);
1379 if (U_FAILURE(status
)) { errln("Calendar::setTime failed"); return; }
1380 UBool idt
= gc
->inDaylightTime(status
);
1381 if (U_FAILURE(status
)) { errln("GregorianCalendar::inDaylightTime failed"); return; }
1384 logln("Warning: Skipping test because " + dateToString(d
, str
) + " is in DST.");
1387 c
->setTime(d
, status
);
1388 if (U_FAILURE(status
)) { errln("Calendar::setTime failed"); return; }
1389 for (int32_t i
= 0; i
< UCAL_ZONE_OFFSET
;++i
) {
1390 if (c
->get((UCalendarDateFields
)i
, status
) != EPOCH_FIELDS
[i
])
1391 dataerrln(UnicodeString("Expected field ") + i
+ " to have value " + EPOCH_FIELDS
[i
] +
1392 "; saw " + c
->get((UCalendarDateFields
)i
, status
) + " instead");
1393 if (U_FAILURE(status
)) { errln("Calendar::get failed"); return; }
1395 if (c
->get(UCAL_ZONE_OFFSET
, status
) != z
->getRawOffset())
1397 errln(UnicodeString("Expected field ZONE_OFFSET to have value ") + z
->getRawOffset() +
1398 "; saw " + c
->get(UCAL_ZONE_OFFSET
, status
) + " instead");
1399 if (U_FAILURE(status
)) { errln("Calendar::get failed"); return; }
1401 if (c
->get(UCAL_DST_OFFSET
, status
) != 0)
1403 errln(UnicodeString("Expected field DST_OFFSET to have value 0") +
1404 "; saw " + c
->get(UCAL_DST_OFFSET
, status
) + " instead");
1405 if (U_FAILURE(status
)) { errln("Calendar::get failed"); return; }
1413 int32_t CalendarTest::EPOCH_FIELDS
[] = {
1414 1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, - 28800000, 0
1417 // -------------------------------------
1420 * Test that the days of the week progress properly when add is called repeatedly
1421 * for increments of 24 days.
1424 CalendarTest::TestDOWProgression()
1426 UErrorCode status
= U_ZERO_ERROR
;
1427 Calendar
*cal
= new GregorianCalendar(1972, UCAL_OCTOBER
, 26, status
);
1428 if (failure(status
, "new GregorianCalendar", TRUE
)) return;
1429 marchByDelta(cal
, 24);
1433 // -------------------------------------
1436 CalendarTest::TestDOW_LOCALandYEAR_WOY()
1438 /* Note: I've commented out the loop_addroll tests for YEAR and
1439 * YEAR_WOY below because these two fields should NOT behave
1440 * identically when adding. YEAR should keep the month/dom
1441 * invariant. YEAR_WOY should keep the woy/dow invariant. I've
1442 * added a new test that checks for this in place of the old call
1443 * to loop_addroll. - aliu */
1444 UErrorCode status
= U_ZERO_ERROR
;
1446 Calendar
*cal
=Calendar::createInstance(Locale::getGermany(), status
);
1447 if (failure(status
, "Calendar::createInstance", TRUE
)) return;
1448 SimpleDateFormat
*sdf
=new SimpleDateFormat(UnicodeString("YYYY'-W'ww-ee"), Locale::getGermany(), status
);
1449 if (U_FAILURE(status
)) { dataerrln("Couldn't create SimpleDateFormat - %s", u_errorName(status
)); return; }
1451 // ICU no longer use localized date-time pattern characters by default.
1452 // So we set pattern chars using 'J' instead of 'Y'.
1453 DateFormatSymbols
*dfs
= new DateFormatSymbols(Locale::getGermany(), status
);
1454 dfs
->setLocalPatternChars(UnicodeString("GyMdkHmsSEDFwWahKzJeugAZvcLQq"));
1455 sdf
->adoptDateFormatSymbols(dfs
);
1456 sdf
->applyLocalizedPattern(UnicodeString("JJJJ'-W'ww-ee"), status
);
1457 if (U_FAILURE(status
)) { errln("Couldn't apply localized pattern"); return; }
1460 cal
->set(1997, UCAL_DECEMBER
, 25);
1461 doYEAR_WOYLoop(cal
, sdf
, times
, status
);
1462 //loop_addroll(cal, /*sdf,*/ times, UCAL_YEAR_WOY, UCAL_YEAR, status);
1463 yearAddTest(*cal
, status
); // aliu
1464 loop_addroll(cal
, /*sdf,*/ times
, UCAL_DOW_LOCAL
, UCAL_DAY_OF_WEEK
, status
);
1465 if (U_FAILURE(status
)) { errln("Error in parse/calculate test for 1997"); return; }
1468 cal
->set(1998, UCAL_DECEMBER
, 25);
1469 doYEAR_WOYLoop(cal
, sdf
, times
, status
);
1470 //loop_addroll(cal, /*sdf,*/ times, UCAL_YEAR_WOY, UCAL_YEAR, status);
1471 yearAddTest(*cal
, status
); // aliu
1472 loop_addroll(cal
, /*sdf,*/ times
, UCAL_DOW_LOCAL
, UCAL_DAY_OF_WEEK
, status
);
1473 if (U_FAILURE(status
)) { errln("Error in parse/calculate test for 1998"); return; }
1476 cal
->set(1582, UCAL_OCTOBER
, 1);
1477 doYEAR_WOYLoop(cal
, sdf
, times
, status
);
1478 //loop_addroll(cal, /*sdf,*/ times, Calendar::YEAR_WOY, Calendar::YEAR, status);
1479 yearAddTest(*cal
, status
); // aliu
1480 loop_addroll(cal
, /*sdf,*/ times
, UCAL_DOW_LOCAL
, UCAL_DAY_OF_WEEK
, status
);
1481 if (U_FAILURE(status
)) { errln("Error in parse/calculate test for 1582"); return; }
1489 * Confirm that adding a YEAR and adding a YEAR_WOY work properly for
1490 * the given Calendar at its current setting.
1492 void CalendarTest::yearAddTest(Calendar
& cal
, UErrorCode
& status
) {
1494 * When adding the YEAR, the month and day should remain constant.
1495 * When adding the YEAR_WOY, the WOY and DOW should remain constant. - aliu
1497 * Wed Jan 14 1998 / 1998-W03-03 Add(YEAR_WOY, 1) -> Wed Jan 20 1999 / 1999-W03-03
1498 * Add(YEAR, 1) -> Thu Jan 14 1999 / 1999-W02-04
1499 * Thu Jan 14 1999 / 1999-W02-04 Add(YEAR_WOY, 1) -> Thu Jan 13 2000 / 2000-W02-04
1500 * Add(YEAR, 1) -> Fri Jan 14 2000 / 2000-W02-05
1501 * Sun Oct 31 1582 / 1582-W42-07 Add(YEAR_WOY, 1) -> Sun Oct 23 1583 / 1583-W42-07
1502 * Add(YEAR, 1) -> Mon Oct 31 1583 / 1583-W44-01
1504 int32_t y
= cal
.get(UCAL_YEAR
, status
);
1505 int32_t mon
= cal
.get(UCAL_MONTH
, status
);
1506 int32_t day
= cal
.get(UCAL_DATE
, status
);
1507 int32_t ywy
= cal
.get(UCAL_YEAR_WOY
, status
);
1508 int32_t woy
= cal
.get(UCAL_WEEK_OF_YEAR
, status
);
1509 int32_t dow
= cal
.get(UCAL_DOW_LOCAL
, status
);
1510 UDate t
= cal
.getTime(status
);
1512 if(U_FAILURE(status
)){
1513 errln(UnicodeString("Failed to create Calendar for locale. Error: ") + UnicodeString(u_errorName(status
)));
1516 UnicodeString str
, str2
;
1517 SimpleDateFormat
fmt(UnicodeString("EEE MMM dd yyyy / YYYY'-W'ww-ee"), status
);
1518 fmt
.setCalendar(cal
);
1520 fmt
.format(t
, str
.remove());
1521 str
+= ".add(YEAR, 1) =>";
1522 cal
.add(UCAL_YEAR
, 1, status
);
1523 int32_t y2
= cal
.get(UCAL_YEAR
, status
);
1524 int32_t mon2
= cal
.get(UCAL_MONTH
, status
);
1525 int32_t day2
= cal
.get(UCAL_DATE
, status
);
1526 fmt
.format(cal
.getTime(status
), str
);
1527 if (y2
!= (y
+1) || mon2
!= mon
|| day2
!= day
) {
1528 str
+= (UnicodeString
)", expected year " +
1529 (y
+1) + ", month " + (mon
+1) + ", day " + day
;
1530 errln((UnicodeString
)"FAIL: " + str
);
1531 logln( UnicodeString(" -> ") + CalendarTest::calToStr(cal
) );
1536 fmt
.format(t
, str
.remove());
1537 str
+= ".add(YEAR_WOY, 1)=>";
1538 cal
.setTime(t
, status
);
1539 logln( UnicodeString(" <- ") + CalendarTest::calToStr(cal
) );
1540 cal
.add(UCAL_YEAR_WOY
, 1, status
);
1541 int32_t ywy2
= cal
.get(UCAL_YEAR_WOY
, status
);
1542 int32_t woy2
= cal
.get(UCAL_WEEK_OF_YEAR
, status
);
1543 int32_t dow2
= cal
.get(UCAL_DOW_LOCAL
, status
);
1544 fmt
.format(cal
.getTime(status
), str
);
1545 if (ywy2
!= (ywy
+1) || woy2
!= woy
|| dow2
!= dow
) {
1546 str
+= (UnicodeString
)", expected yearWOY " +
1547 (ywy
+1) + ", woy " + woy
+ ", dowLocal " + dow
;
1548 errln((UnicodeString
)"FAIL: " + str
);
1549 logln( UnicodeString(" -> ") + CalendarTest::calToStr(cal
) );
1555 // -------------------------------------
1557 void CalendarTest::loop_addroll(Calendar
*cal
, /*SimpleDateFormat *sdf,*/ int times
, UCalendarDateFields field
, UCalendarDateFields field2
, UErrorCode
& errorCode
) {
1559 SimpleDateFormat
fmt(UnicodeString("EEE MMM dd yyyy / YYYY'-W'ww-ee"), errorCode
);
1560 fmt
.setCalendar(*cal
);
1563 for(i
= 0; i
<times
; i
++) {
1564 calclone
= cal
->clone();
1565 UDate start
= cal
->getTime(errorCode
);
1566 cal
->add(field
,1,errorCode
);
1567 if (U_FAILURE(errorCode
)) { errln("Error in add"); delete calclone
; return; }
1568 calclone
->add(field2
,1,errorCode
);
1569 if (U_FAILURE(errorCode
)) { errln("Error in add"); delete calclone
; return; }
1570 if(cal
->getTime(errorCode
) != calclone
->getTime(errorCode
)) {
1571 UnicodeString
str("FAIL: Results of add differ. "), str2
;
1572 str
+= fmt
.format(start
, str2
) + " ";
1573 str
+= UnicodeString("Add(") + fieldName(field
) + ", 1) -> " +
1574 fmt
.format(cal
->getTime(errorCode
), str2
.remove()) + "; ";
1575 str
+= UnicodeString("Add(") + fieldName(field2
) + ", 1) -> " +
1576 fmt
.format(calclone
->getTime(errorCode
), str2
.remove());
1584 for(i
= 0; i
<times
; i
++) {
1585 calclone
= cal
->clone();
1586 cal
->roll(field
,(int32_t)1,errorCode
);
1587 if (U_FAILURE(errorCode
)) { errln("Error in roll"); delete calclone
; return; }
1588 calclone
->roll(field2
,(int32_t)1,errorCode
);
1589 if (U_FAILURE(errorCode
)) { errln("Error in roll"); delete calclone
; return; }
1590 if(cal
->getTime(errorCode
) != calclone
->getTime(errorCode
)) {
1592 errln("Results of roll differ!");
1599 // -------------------------------------
1602 CalendarTest::doYEAR_WOYLoop(Calendar
*cal
, SimpleDateFormat
*sdf
,
1603 int32_t times
, UErrorCode
& errorCode
) {
1606 UDate tst
, original
;
1607 Calendar
*tstres
= new GregorianCalendar(Locale::getGermany(), errorCode
);
1608 for(int i
=0; i
<times
; ++i
) {
1609 sdf
->format(Formattable(cal
->getTime(errorCode
),Formattable::kIsDate
), us
, errorCode
);
1610 //logln("expected: "+us);
1611 if (U_FAILURE(errorCode
)) { errln("Format error"); return; }
1612 tst
=sdf
->parse(us
,errorCode
);
1613 if (U_FAILURE(errorCode
)) { errln("Parse error"); return; }
1615 tstres
->setTime(tst
, errorCode
);
1616 //logln((UnicodeString)"Parsed week of year is "+tstres->get(UCAL_WEEK_OF_YEAR, errorCode));
1617 if (U_FAILURE(errorCode
)) { errln("Set time error"); return; }
1618 original
= cal
->getTime(errorCode
);
1620 sdf
->format(Formattable(tst
,Formattable::kIsDate
), us
, errorCode
);
1621 //logln("got: "+us);
1622 if (U_FAILURE(errorCode
)) { errln("Get time error"); return; }
1625 sdf
->format(Formattable(original
, Formattable::kIsDate
), us
, errorCode
);
1626 errln("FAIL: Parsed time doesn't match with regular");
1627 logln("expected "+us
+ " " + calToStr(*cal
));
1629 sdf
->format(Formattable(tst
, Formattable::kIsDate
), us
, errorCode
);
1630 logln("got "+us
+ " " + calToStr(*tstres
));
1633 tstres
->set(UCAL_YEAR_WOY
, cal
->get(UCAL_YEAR_WOY
, errorCode
));
1634 tstres
->set(UCAL_WEEK_OF_YEAR
, cal
->get(UCAL_WEEK_OF_YEAR
, errorCode
));
1635 tstres
->set(UCAL_DOW_LOCAL
, cal
->get(UCAL_DOW_LOCAL
, errorCode
));
1636 if(cal
->get(UCAL_YEAR
, errorCode
) != tstres
->get(UCAL_YEAR
, errorCode
)) {
1637 errln("FAIL: Different Year!");
1638 logln((UnicodeString
)"Expected "+cal
->get(UCAL_YEAR
, errorCode
));
1639 logln((UnicodeString
)"Got "+tstres
->get(UCAL_YEAR
, errorCode
));
1642 if(cal
->get(UCAL_DAY_OF_YEAR
, errorCode
) != tstres
->get(UCAL_DAY_OF_YEAR
, errorCode
)) {
1643 errln("FAIL: Different Day Of Year!");
1644 logln((UnicodeString
)"Expected "+cal
->get(UCAL_DAY_OF_YEAR
, errorCode
));
1645 logln((UnicodeString
)"Got "+tstres
->get(UCAL_DAY_OF_YEAR
, errorCode
));
1648 //logln(calToStr(*cal));
1649 cal
->add(UCAL_DATE
, 1, errorCode
);
1650 if (U_FAILURE(errorCode
)) { errln("Add error"); return; }
1655 // -------------------------------------
1658 CalendarTest::marchByDelta(Calendar
* cal
, int32_t delta
)
1660 UErrorCode status
= U_ZERO_ERROR
;
1661 Calendar
*cur
= (Calendar
*) cal
->clone();
1662 int32_t initialDOW
= cur
->get(UCAL_DAY_OF_WEEK
, status
);
1663 if (U_FAILURE(status
)) { errln("Calendar::get failed"); return; }
1664 int32_t DOW
, newDOW
= initialDOW
;
1668 logln(UnicodeString("DOW = ") + DOW
+ " " + dateToString(cur
->getTime(status
), str
));
1669 if (U_FAILURE(status
)) { errln("Calendar::getTime failed"); return; }
1670 cur
->add(UCAL_DAY_OF_WEEK
, delta
, status
);
1671 if (U_FAILURE(status
)) { errln("Calendar::add failed"); return; }
1672 newDOW
= cur
->get(UCAL_DAY_OF_WEEK
, status
);
1673 if (U_FAILURE(status
)) { errln("Calendar::get failed"); return; }
1674 int32_t expectedDOW
= 1 + (DOW
+ delta
- 1) % 7;
1675 if (newDOW
!= expectedDOW
) {
1676 errln(UnicodeString("Day of week should be ") + expectedDOW
+ " instead of " + newDOW
+
1677 " on " + dateToString(cur
->getTime(status
), str
));
1678 if (U_FAILURE(status
)) { errln("Calendar::getTime failed"); return; }
1682 while (newDOW
!= initialDOW
);
1686 #define CHECK(status, msg) \
1687 if (U_FAILURE(status)) { \
1688 errcheckln(status, msg); \
1692 void CalendarTest::TestWOY(void) {
1694 FDW = Mon, MDFW = 4:
1695 Sun Dec 26 1999, WOY 51
1696 Mon Dec 27 1999, WOY 52
1697 Tue Dec 28 1999, WOY 52
1698 Wed Dec 29 1999, WOY 52
1699 Thu Dec 30 1999, WOY 52
1700 Fri Dec 31 1999, WOY 52
1701 Sat Jan 01 2000, WOY 52 ***
1702 Sun Jan 02 2000, WOY 52 ***
1703 Mon Jan 03 2000, WOY 1
1704 Tue Jan 04 2000, WOY 1
1705 Wed Jan 05 2000, WOY 1
1706 Thu Jan 06 2000, WOY 1
1707 Fri Jan 07 2000, WOY 1
1708 Sat Jan 08 2000, WOY 1
1709 Sun Jan 09 2000, WOY 1
1710 Mon Jan 10 2000, WOY 2
1712 FDW = Mon, MDFW = 2:
1713 Sun Dec 26 1999, WOY 52
1714 Mon Dec 27 1999, WOY 1 ***
1715 Tue Dec 28 1999, WOY 1 ***
1716 Wed Dec 29 1999, WOY 1 ***
1717 Thu Dec 30 1999, WOY 1 ***
1718 Fri Dec 31 1999, WOY 1 ***
1719 Sat Jan 01 2000, WOY 1
1720 Sun Jan 02 2000, WOY 1
1721 Mon Jan 03 2000, WOY 2
1722 Tue Jan 04 2000, WOY 2
1723 Wed Jan 05 2000, WOY 2
1724 Thu Jan 06 2000, WOY 2
1725 Fri Jan 07 2000, WOY 2
1726 Sat Jan 08 2000, WOY 2
1727 Sun Jan 09 2000, WOY 2
1728 Mon Jan 10 2000, WOY 3
1732 UErrorCode status
= U_ZERO_ERROR
;
1735 GregorianCalendar
cal(status
);
1736 SimpleDateFormat
fmt(UnicodeString("EEE MMM dd yyyy', WOY' w"), status
);
1737 if (failure(status
, "Cannot construct calendar/format", TRUE
)) return;
1739 UCalendarDaysOfWeek fdw
= (UCalendarDaysOfWeek
) 0;
1741 //for (int8_t pass=2; pass<=2; ++pass) {
1742 for (int8_t pass
=1; pass
<=2; ++pass
) {
1746 cal
.setFirstDayOfWeek(fdw
);
1747 cal
.setMinimalDaysInFirstWeek(4);
1748 fmt
.adoptCalendar(cal
.clone());
1752 cal
.setFirstDayOfWeek(fdw
);
1753 cal
.setMinimalDaysInFirstWeek(2);
1754 fmt
.adoptCalendar(cal
.clone());
1758 //for (i=2; i<=6; ++i) {
1759 for (i
=0; i
<16; ++i
) {
1761 int32_t t_y
, t_woy
, t_dow
;
1763 cal
.set(1999, UCAL_DECEMBER
, 26 + i
);
1764 fmt
.format(t
= cal
.getTime(status
), str
.remove());
1765 CHECK(status
, "Fail: getTime failed");
1766 logln(UnicodeString("* ") + str
);
1767 int32_t dow
= cal
.get(UCAL_DAY_OF_WEEK
, status
);
1768 int32_t woy
= cal
.get(UCAL_WEEK_OF_YEAR
, status
);
1769 int32_t year
= cal
.get(UCAL_YEAR
, status
);
1770 int32_t mon
= cal
.get(UCAL_MONTH
, status
);
1771 logln(calToStr(cal
));
1772 CHECK(status
, "Fail: get failed");
1773 int32_t dowLocal
= dow
- fdw
;
1774 if (dowLocal
< 0) dowLocal
+= 7;
1776 int32_t yearWoy
= year
;
1777 if (mon
== UCAL_JANUARY
) {
1778 if (woy
>= 52) --yearWoy
;
1780 if (woy
== 1) ++yearWoy
;
1783 // Basic fields->time check y/woy/dow
1784 // Since Y/WOY is ambiguous, we do a check of the fields,
1785 // not of the specific time.
1787 cal
.set(UCAL_YEAR
, year
);
1788 cal
.set(UCAL_WEEK_OF_YEAR
, woy
);
1789 cal
.set(UCAL_DAY_OF_WEEK
, dow
);
1790 t_y
= cal
.get(UCAL_YEAR
, status
);
1791 t_woy
= cal
.get(UCAL_WEEK_OF_YEAR
, status
);
1792 t_dow
= cal
.get(UCAL_DAY_OF_WEEK
, status
);
1793 CHECK(status
, "Fail: get failed");
1794 if (t_y
!= year
|| t_woy
!= woy
|| t_dow
!= dow
) {
1795 str
= "Fail: y/woy/dow fields->time => ";
1796 fmt
.format(cal
.getTime(status
), str
);
1798 logln(calToStr(cal
));
1799 logln("[get!=set] Y%d!=%d || woy%d!=%d || dow%d!=%d\n",
1800 t_y
, year
, t_woy
, woy
, t_dow
, dow
);
1802 logln("y/woy/dow fields->time OK");
1805 // Basic fields->time check y/woy/dow_local
1806 // Since Y/WOY is ambiguous, we do a check of the fields,
1807 // not of the specific time.
1809 cal
.set(UCAL_YEAR
, year
);
1810 cal
.set(UCAL_WEEK_OF_YEAR
, woy
);
1811 cal
.set(UCAL_DOW_LOCAL
, dowLocal
);
1812 t_y
= cal
.get(UCAL_YEAR
, status
);
1813 t_woy
= cal
.get(UCAL_WEEK_OF_YEAR
, status
);
1814 t_dow
= cal
.get(UCAL_DOW_LOCAL
, status
);
1815 CHECK(status
, "Fail: get failed");
1816 if (t_y
!= year
|| t_woy
!= woy
|| t_dow
!= dowLocal
) {
1817 str
= "Fail: y/woy/dow_local fields->time => ";
1818 fmt
.format(cal
.getTime(status
), str
);
1822 // Basic fields->time check y_woy/woy/dow
1824 cal
.set(UCAL_YEAR_WOY
, yearWoy
);
1825 cal
.set(UCAL_WEEK_OF_YEAR
, woy
);
1826 cal
.set(UCAL_DAY_OF_WEEK
, dow
);
1827 t2
= cal
.getTime(status
);
1828 CHECK(status
, "Fail: getTime failed");
1830 str
= "Fail: y_woy/woy/dow fields->time => ";
1831 fmt
.format(t2
, str
);
1833 logln(calToStr(cal
));
1834 logln("%.f != %.f\n", t
, t2
);
1836 logln("y_woy/woy/dow OK");
1839 // Basic fields->time check y_woy/woy/dow_local
1841 cal
.set(UCAL_YEAR_WOY
, yearWoy
);
1842 cal
.set(UCAL_WEEK_OF_YEAR
, woy
);
1843 cal
.set(UCAL_DOW_LOCAL
, dowLocal
);
1844 t2
= cal
.getTime(status
);
1845 CHECK(status
, "Fail: getTime failed");
1847 str
= "Fail: y_woy/woy/dow_local fields->time => ";
1848 fmt
.format(t2
, str
);
1852 logln("Testing DOW_LOCAL.. dow%d\n", dow
);
1853 // Make sure DOW_LOCAL disambiguates over DOW
1854 int32_t wrongDow
= dow
- 3;
1855 if (wrongDow
< 1) wrongDow
+= 7;
1856 cal
.setTime(t
, status
);
1857 cal
.set(UCAL_DAY_OF_WEEK
, wrongDow
);
1858 cal
.set(UCAL_DOW_LOCAL
, dowLocal
);
1859 t2
= cal
.getTime(status
);
1860 CHECK(status
, "Fail: set/getTime failed");
1862 str
= "Fail: DOW_LOCAL fields->time => ";
1863 fmt
.format(t2
, str
);
1865 logln(calToStr(cal
));
1866 logln("%.f : DOW%d, DOW_LOCAL%d -> %.f\n",
1867 t
, wrongDow
, dowLocal
, t2
);
1870 // Make sure DOW disambiguates over DOW_LOCAL
1871 int32_t wrongDowLocal
= dowLocal
- 3;
1872 if (wrongDowLocal
< 1) wrongDowLocal
+= 7;
1873 cal
.setTime(t
, status
);
1874 cal
.set(UCAL_DOW_LOCAL
, wrongDowLocal
);
1875 cal
.set(UCAL_DAY_OF_WEEK
, dow
);
1876 t2
= cal
.getTime(status
);
1877 CHECK(status
, "Fail: set/getTime failed");
1879 str
= "Fail: DOW fields->time => ";
1880 fmt
.format(t2
, str
);
1884 // Make sure YEAR_WOY disambiguates over YEAR
1885 cal
.setTime(t
, status
);
1886 cal
.set(UCAL_YEAR
, year
- 2);
1887 cal
.set(UCAL_YEAR_WOY
, yearWoy
);
1888 t2
= cal
.getTime(status
);
1889 CHECK(status
, "Fail: set/getTime failed");
1891 str
= "Fail: YEAR_WOY fields->time => ";
1892 fmt
.format(t2
, str
);
1896 // Make sure YEAR disambiguates over YEAR_WOY
1897 cal
.setTime(t
, status
);
1898 cal
.set(UCAL_YEAR_WOY
, yearWoy
- 2);
1899 cal
.set(UCAL_YEAR
, year
);
1900 t2
= cal
.getTime(status
);
1901 CHECK(status
, "Fail: set/getTime failed");
1903 str
= "Fail: YEAR fields->time => ";
1904 fmt
.format(t2
, str
);
1911 FDW = Mon, MDFW = 4:
1912 Sun Dec 26 1999, WOY 51
1913 Mon Dec 27 1999, WOY 52
1914 Tue Dec 28 1999, WOY 52
1915 Wed Dec 29 1999, WOY 52
1916 Thu Dec 30 1999, WOY 52
1917 Fri Dec 31 1999, WOY 52
1918 Sat Jan 01 2000, WOY 52
1919 Sun Jan 02 2000, WOY 52
1922 // Roll the DOW_LOCAL within week 52
1923 for (i
=27; i
<=33; ++i
) {
1925 for (amount
=-7; amount
<=7; ++amount
) {
1927 cal
.set(1999, UCAL_DECEMBER
, i
);
1929 fmt
.format(cal
.getTime(status
), str
);
1930 CHECK(status
, "Fail: getTime failed");
1931 str
+= UnicodeString(", ") + amount
+ ") = ";
1933 cal
.roll(UCAL_DOW_LOCAL
, amount
, status
);
1934 CHECK(status
, "Fail: roll failed");
1936 t
= cal
.getTime(status
);
1937 int32_t newDom
= i
+ amount
;
1938 while (newDom
< 27) newDom
+= 7;
1939 while (newDom
> 33) newDom
-= 7;
1940 cal
.set(1999, UCAL_DECEMBER
, newDom
);
1941 t2
= cal
.getTime(status
);
1942 CHECK(status
, "Fail: getTime failed");
1946 str
.append(", exp ");
1947 fmt
.format(t2
, str
);
1956 void CalendarTest::TestYWOY()
1959 UErrorCode status
= U_ZERO_ERROR
;
1961 GregorianCalendar
cal(status
);
1962 if (failure(status
, "construct GregorianCalendar", TRUE
)) return;
1964 cal
.setFirstDayOfWeek(UCAL_SUNDAY
);
1965 cal
.setMinimalDaysInFirstWeek(1);
1967 logln("Setting: ywoy=2004, woy=1, dow=MONDAY");
1969 cal
.set(UCAL_YEAR_WOY
,2004);
1970 cal
.set(UCAL_WEEK_OF_YEAR
,1);
1971 cal
.set(UCAL_DAY_OF_WEEK
, UCAL_MONDAY
);
1973 logln(calToStr(cal
));
1974 if(cal
.get(UCAL_YEAR
, status
) != 2003) {
1975 errln("year not 2003");
1978 logln("+ setting DOW to THURSDAY");
1980 cal
.set(UCAL_YEAR_WOY
,2004);
1981 cal
.set(UCAL_WEEK_OF_YEAR
,1);
1982 cal
.set(UCAL_DAY_OF_WEEK
, UCAL_THURSDAY
);
1984 logln(calToStr(cal
));
1985 if(cal
.get(UCAL_YEAR
, status
) != 2004) {
1986 errln("year not 2004");
1989 logln("+ setting DOW_LOCAL to 1");
1991 cal
.set(UCAL_YEAR_WOY
,2004);
1992 cal
.set(UCAL_WEEK_OF_YEAR
,1);
1993 cal
.set(UCAL_DAY_OF_WEEK
, UCAL_THURSDAY
);
1994 cal
.set(UCAL_DOW_LOCAL
, 1);
1996 logln(calToStr(cal
));
1997 if(cal
.get(UCAL_YEAR
, status
) != 2003) {
1998 errln("year not 2003");
2001 cal
.setFirstDayOfWeek(UCAL_MONDAY
);
2002 cal
.setMinimalDaysInFirstWeek(4);
2003 UDate t
= 946713600000.;
2004 cal
.setTime(t
, status
);
2005 cal
.set(UCAL_DAY_OF_WEEK
, 4);
2006 cal
.set(UCAL_DOW_LOCAL
, 6);
2007 if(cal
.getTime(status
) != t
) {
2008 logln(calToStr(cal
));
2009 errln("FAIL: DOW_LOCAL did not take precedence");
2014 void CalendarTest::TestJD()
2017 static const int32_t kEpochStartAsJulianDay
= 2440588;
2018 UErrorCode status
= U_ZERO_ERROR
;
2019 GregorianCalendar
cal(status
);
2020 if (failure(status
, "construct GregorianCalendar", TRUE
)) return;
2021 cal
.setTimeZone(*TimeZone::getGMT());
2023 jd
= cal
.get(UCAL_JULIAN_DAY
, status
);
2024 if(jd
!= kEpochStartAsJulianDay
) {
2025 errln("Wanted JD of %d at time=0, [epoch 1970] but got %d\n", kEpochStartAsJulianDay
, jd
);
2027 logln("Wanted JD of %d at time=0, [epoch 1970], got %d\n", kEpochStartAsJulianDay
, jd
);
2030 cal
.setTime(Calendar::getNow(), status
);
2032 cal
.set(UCAL_JULIAN_DAY
, kEpochStartAsJulianDay
);
2033 UDate epochTime
= cal
.getTime(status
);
2034 if(epochTime
!= 0) {
2035 errln("Wanted time of 0 at jd=%d, got %.1lf\n", kEpochStartAsJulianDay
, epochTime
);
2037 logln("Wanted time of 0 at jd=%d, got %.1lf\n", kEpochStartAsJulianDay
, epochTime
);
2042 // make sure the ctestfw utilities are in sync with the Calendar
2043 void CalendarTest::TestDebug()
2045 for(int32_t t
=0;t
<=UDBG_ENUM_COUNT
;t
++) {
2046 int32_t count
= udbg_enumCount((UDebugEnumType
)t
);
2048 logln("enumCount(%d) returned -1", count
);
2051 for(int32_t i
=0;i
<=count
;i
++) {
2052 if(t
<=UDBG_HIGHEST_CONTIGUOUS_ENUM
&& i
<count
) {
2053 if( i
!=udbg_enumArrayValue((UDebugEnumType
)t
, i
)) {
2054 errln("FAIL: udbg_enumArrayValue(%d,%d) returned %d, expected %d", t
, i
, udbg_enumArrayValue((UDebugEnumType
)t
,i
), i
);
2057 logln("Testing count+1:");
2059 const char *name
= udbg_enumName((UDebugEnumType
)t
,i
);
2061 if(i
==count
|| t
>UDBG_HIGHEST_CONTIGUOUS_ENUM
) {
2062 logln(" null name - expected.\n");
2064 errln("FAIL: udbg_enumName(%d,%d) returned NULL", t
, i
);
2068 logln("udbg_enumArrayValue(%d,%d) = %s, returned %d", t
, i
,
2069 name
, udbg_enumArrayValue((UDebugEnumType
)t
,i
));
2070 logln("udbg_enumString = " + udbg_enumString((UDebugEnumType
)t
,i
));
2072 if(udbg_enumExpectedCount((UDebugEnumType
)t
) != count
&& t
<=UDBG_HIGHEST_CONTIGUOUS_ENUM
) {
2073 errln("FAIL: udbg_enumExpectedCount(%d): %d, != UCAL_FIELD_COUNT=%d ", t
, udbg_enumExpectedCount((UDebugEnumType
)t
), count
);
2075 logln("udbg_ucal_fieldCount: %d, UCAL_FIELD_COUNT=udbg_enumCount %d ", udbg_enumExpectedCount((UDebugEnumType
)t
), count
);
2083 // List of interesting locales
2084 const char *CalendarTest::testLocaleID(int32_t i
)
2087 case 0: return "he_IL@calendar=hebrew";
2088 case 1: return "en_US@calendar=hebrew";
2089 case 2: return "fr_FR@calendar=hebrew";
2090 case 3: return "fi_FI@calendar=hebrew";
2091 case 4: return "nl_NL@calendar=hebrew";
2092 case 5: return "hu_HU@calendar=hebrew";
2093 case 6: return "nl_BE@currency=MTL;calendar=islamic";
2094 case 7: return "th_TH_TRADITIONAL@calendar=gregorian";
2095 case 8: return "ar_JO@calendar=islamic-civil";
2096 case 9: return "fi_FI@calendar=islamic";
2097 case 10: return "fr_CH@calendar=islamic-civil";
2098 case 11: return "he_IL@calendar=islamic-civil";
2099 case 12: return "hu_HU@calendar=buddhist";
2100 case 13: return "hu_HU@calendar=islamic";
2101 case 14: return "en_US@calendar=japanese";
2102 default: return NULL
;
2106 int32_t CalendarTest::testLocaleCount()
2108 static int32_t gLocaleCount
= -1;
2109 if(gLocaleCount
< 0) {
2111 for(i
=0;testLocaleID(i
) != NULL
;i
++) {
2116 return gLocaleCount
;
2119 static UDate
doMinDateOfCalendar(Calendar
* adopt
, UBool
&isGregorian
, UErrorCode
& status
) {
2120 if(U_FAILURE(status
)) return 0.0;
2123 adopt
->set(UCAL_EXTENDED_YEAR
, adopt
->getActualMinimum(UCAL_EXTENDED_YEAR
, status
));
2124 UDate ret
= adopt
->getTime(status
);
2125 isGregorian
= dynamic_cast<GregorianCalendar
*>(adopt
) != NULL
;
2130 UDate
CalendarTest::minDateOfCalendar(const Locale
& locale
, UBool
&isGregorian
, UErrorCode
& status
) {
2131 if(U_FAILURE(status
)) return 0.0;
2132 return doMinDateOfCalendar(Calendar::createInstance(locale
, status
), isGregorian
, status
);
2135 UDate
CalendarTest::minDateOfCalendar(const Calendar
& cal
, UBool
&isGregorian
, UErrorCode
& status
) {
2136 if(U_FAILURE(status
)) return 0.0;
2137 return doMinDateOfCalendar(cal
.clone(), isGregorian
, status
);
2140 void CalendarTest::Test6703()
2142 UErrorCode status
= U_ZERO_ERROR
;
2145 Locale
loc1("en@calendar=fubar");
2146 cal
= Calendar::createInstance(loc1
, status
);
2147 if (failure(status
, "Calendar::createInstance", TRUE
)) return;
2150 status
= U_ZERO_ERROR
;
2152 cal
= Calendar::createInstance(loc2
, status
);
2153 if (failure(status
, "Calendar::createInstance")) return;
2156 status
= U_ZERO_ERROR
;
2157 Locale
loc3("en@calendar=roc");
2158 cal
= Calendar::createInstance(loc3
, status
);
2159 if (failure(status
, "Calendar::createInstance")) return;
2165 void CalendarTest::Test3785()
2167 UErrorCode status
= U_ZERO_ERROR
;
2168 UnicodeString uzone
= UNICODE_STRING_SIMPLE("Europe/Paris");
2169 UnicodeString exp1
= UNICODE_STRING_SIMPLE("Mon 30 Jumada II 1433 AH, 01:47:03");
2170 UnicodeString exp2
= UNICODE_STRING_SIMPLE("Mon 1 Rajab 1433 AH, 01:47:04");
2172 LocalUDateFormatPointer
df(udat_open(UDAT_NONE
, UDAT_NONE
, "en@calendar=islamic", uzone
.getTerminatedBuffer(),
2173 uzone
.length(), NULL
, 0, &status
));
2174 if (df
.isNull() || U_FAILURE(status
)) return;
2177 u_uastrcpy(upattern
, "EEE d MMMM y G, HH:mm:ss");
2178 udat_applyPattern(df
.getAlias(), FALSE
, upattern
, u_strlen(upattern
));
2180 UChar ubuffer
[1024];
2181 UDate ud0
= 1337557623000.0;
2183 status
= U_ZERO_ERROR
;
2184 udat_format(df
.getAlias(), ud0
, ubuffer
, 1024, NULL
, &status
);
2185 if (U_FAILURE(status
)) {
2186 errln("Error formatting date 1\n");
2189 //printf("formatted: '%s'\n", mkcstr(ubuffer));
2191 UnicodeString
act1(ubuffer
);
2192 if ( act1
!= exp1
) {
2193 errln("Unexpected result from date 1 format\n");
2195 ud0
+= 1000.0; // add one second
2197 status
= U_ZERO_ERROR
;
2198 udat_format(df
.getAlias(), ud0
, ubuffer
, 1024, NULL
, &status
);
2199 if (U_FAILURE(status
)) {
2200 errln("Error formatting date 2\n");
2203 //printf("formatted: '%s'\n", mkcstr(ubuffer));
2204 UnicodeString
act2(ubuffer
);
2205 if ( act2
!= exp2
) {
2206 errln("Unexpected result from date 2 format\n");
2212 void CalendarTest::Test1624() {
2213 UErrorCode status
= U_ZERO_ERROR
;
2214 Locale
loc("he_IL@calendar=hebrew");
2215 HebrewCalendar
hc(loc
,status
);
2217 for (int32_t year
= 5600; year
< 5800; year
++ ) {
2219 for (int32_t month
= HebrewCalendar::TISHRI
; month
<= HebrewCalendar::ELUL
; month
++) {
2220 // skip the adar 1 month if year is not a leap year
2221 if (HebrewCalendar::isLeapYear(year
) == FALSE
&& month
== HebrewCalendar::ADAR_1
) {
2225 hc
.set(year
,month
,day
);
2226 int32_t dayHC
= hc
.get(UCAL_DATE
,status
);
2227 int32_t monthHC
= hc
.get(UCAL_MONTH
,status
);
2228 int32_t yearHC
= hc
.get(UCAL_YEAR
,status
);
2230 if (failure(status
, "HebrewCalendar.get()", TRUE
)) continue;
2233 errln(" ==> day %d incorrect, should be: %d\n",dayHC
,day
);
2236 if (monthHC
!= month
) {
2237 errln(" ==> month %d incorrect, should be: %d\n",monthHC
,month
);
2240 if (yearHC
!= year
) {
2241 errln(" ==> day %d incorrect, should be: %d\n",yearHC
,year
);
2249 void CalendarTest::TestTimeStamp() {
2250 UErrorCode status
= U_ZERO_ERROR
;
2251 UDate start
= 0.0, time
;
2254 // Create a new Gregorian Calendar.
2255 cal
= Calendar::createInstance("en_US@calender=gregorian", status
);
2256 if (U_FAILURE(status
)) {
2257 dataerrln("Error creating Gregorian calendar.");
2261 for (int i
= 0; i
< 20000; i
++) {
2262 // Set the Gregorian Calendar to a specific date for testing.
2263 cal
->set(2009, UCAL_JULY
, 3, 0, 49, 46);
2265 time
= cal
->getTime(status
);
2266 if (U_FAILURE(status
)) {
2267 errln("Error calling getTime()");
2274 if (start
!= time
) {
2275 errln("start and time not equal.");
2284 void CalendarTest::TestISO8601() {
2285 const char* TEST_LOCALES
[] = {
2286 "en_US@calendar=iso8601",
2287 "en_US@calendar=Iso8601",
2288 "th_TH@calendar=iso8601",
2289 "ar_EG@calendar=iso8601",
2293 int32_t TEST_DATA
[][3] = {
2304 for (int i
= 0; TEST_LOCALES
[i
] != NULL
; i
++) {
2305 UErrorCode status
= U_ZERO_ERROR
;
2306 Calendar
*cal
= Calendar::createInstance(TEST_LOCALES
[i
], status
);
2307 if (U_FAILURE(status
)) {
2308 errln("Error: Failed to create a calendar for locale: %s", TEST_LOCALES
[i
]);
2311 if (uprv_strcmp(cal
->getType(), "gregorian") != 0) {
2312 errln("Error: Gregorian calendar is not used for locale: %s", TEST_LOCALES
[i
]);
2315 for (int j
= 0; TEST_DATA
[j
][0] != 0; j
++) {
2316 cal
->set(TEST_DATA
[j
][0], UCAL_JANUARY
, 1);
2317 int32_t weekNum
= cal
->get(UCAL_WEEK_OF_YEAR
, status
);
2318 int32_t weekYear
= cal
->get(UCAL_YEAR_WOY
, status
);
2319 if (U_FAILURE(status
)) {
2320 errln("Error: Failed to get week of year");
2323 if (weekNum
!= TEST_DATA
[j
][1] || weekYear
!= TEST_DATA
[j
][2]) {
2324 errln("Error: Incorrect week of year on January 1st, %d for locale %s: Returned [weekNum=%d, weekYear=%d], Expected [weekNum=%d, weekYear=%d]",
2325 TEST_DATA
[j
][0], TEST_LOCALES
[i
], weekNum
, weekYear
, TEST_DATA
[j
][1], TEST_DATA
[j
][2]);
2334 CalendarTest::TestAmbiguousWallTimeAPIs(void) {
2335 UErrorCode status
= U_ZERO_ERROR
;
2336 Calendar
* cal
= Calendar::createInstance(status
);
2337 if (U_FAILURE(status
)) {
2338 errln("Fail: Error creating a calendar instance.");
2342 if (cal
->getRepeatedWallTimeOption() != UCAL_WALLTIME_LAST
) {
2343 errln("Fail: Default repeted time option is not UCAL_WALLTIME_LAST");
2345 if (cal
->getSkippedWallTimeOption() != UCAL_WALLTIME_LAST
) {
2346 errln("Fail: Default skipped time option is not UCAL_WALLTIME_LAST");
2349 Calendar
* cal2
= cal
->clone();
2351 if (*cal
!= *cal2
) {
2352 errln("Fail: Cloned calendar != the original");
2354 if (!cal
->equals(*cal2
, status
)) {
2355 errln("Fail: The time of cloned calendar is not equal to the original");
2356 } else if (U_FAILURE(status
)) {
2357 errln("Fail: Error equals");
2359 status
= U_ZERO_ERROR
;
2361 cal2
->setRepeatedWallTimeOption(UCAL_WALLTIME_FIRST
);
2362 cal2
->setSkippedWallTimeOption(UCAL_WALLTIME_FIRST
);
2364 if (*cal
== *cal2
) {
2365 errln("Fail: Cloned and modified calendar == the original");
2367 if (!cal
->equals(*cal2
, status
)) {
2368 errln("Fail: The time of cloned calendar is not equal to the original after changing wall time options");
2369 } else if (U_FAILURE(status
)) {
2370 errln("Fail: Error equals after changing wall time options");
2372 status
= U_ZERO_ERROR
;
2374 if (cal2
->getRepeatedWallTimeOption() != UCAL_WALLTIME_FIRST
) {
2375 errln("Fail: Repeted time option is not UCAL_WALLTIME_FIRST");
2377 if (cal2
->getSkippedWallTimeOption() != UCAL_WALLTIME_FIRST
) {
2378 errln("Fail: Skipped time option is not UCAL_WALLTIME_FIRST");
2381 cal2
->setRepeatedWallTimeOption(UCAL_WALLTIME_NEXT_VALID
);
2382 if (cal2
->getRepeatedWallTimeOption() != UCAL_WALLTIME_FIRST
) {
2383 errln("Fail: Repeated wall time option was updated other than UCAL_WALLTIME_FIRST");
2392 CalFields(int32_t year
, int32_t month
, int32_t day
, int32_t hour
, int32_t min
, int32_t sec
);
2393 CalFields(const Calendar
& cal
, UErrorCode
& status
);
2394 void setTo(Calendar
& cal
) const;
2395 char* toString(char* buf
, int32_t len
) const;
2396 UBool
operator==(const CalFields
& rhs
) const;
2397 UBool
operator!=(const CalFields
& rhs
) const;
2408 CalFields::CalFields(int32_t year
, int32_t month
, int32_t day
, int32_t hour
, int32_t min
, int32_t sec
)
2409 : year(year
), month(month
), day(day
), hour(hour
), min(min
), sec(sec
) {
2412 CalFields::CalFields(const Calendar
& cal
, UErrorCode
& status
) {
2413 year
= cal
.get(UCAL_YEAR
, status
);
2414 month
= cal
.get(UCAL_MONTH
, status
) + 1;
2415 day
= cal
.get(UCAL_DAY_OF_MONTH
, status
);
2416 hour
= cal
.get(UCAL_HOUR_OF_DAY
, status
);
2417 min
= cal
.get(UCAL_MINUTE
, status
);
2418 sec
= cal
.get(UCAL_SECOND
, status
);
2422 CalFields::setTo(Calendar
& cal
) const {
2424 cal
.set(year
, month
- 1, day
, hour
, min
, sec
);
2428 CalFields::toString(char* buf
, int32_t len
) const {
2430 sprintf(local
, "%04d-%02d-%02d %02d:%02d:%02d", year
, month
, day
, hour
, min
, sec
);
2431 uprv_strncpy(buf
, local
, len
- 1);
2437 CalFields::operator==(const CalFields
& rhs
) const {
2438 return year
== rhs
.year
2439 && month
== rhs
.month
2447 CalFields::operator!=(const CalFields
& rhs
) const {
2448 return !(*this == rhs
);
2454 const CalFields expLastGMT
;
2455 const CalFields expFirstGMT
;
2456 } RepeatedWallTimeTestData
;
2458 static const RepeatedWallTimeTestData RPDATA
[] =
2460 // Time zone Input wall time WALLTIME_LAST in GMT WALLTIME_FIRST in GMT
2461 {"America/New_York", CalFields(2011,11,6,0,59,59), CalFields(2011,11,6,4,59,59), CalFields(2011,11,6,4,59,59)},
2462 {"America/New_York", CalFields(2011,11,6,1,0,0), CalFields(2011,11,6,6,0,0), CalFields(2011,11,6,5,0,0)},
2463 {"America/New_York", CalFields(2011,11,6,1,0,1), CalFields(2011,11,6,6,0,1), CalFields(2011,11,6,5,0,1)},
2464 {"America/New_York", CalFields(2011,11,6,1,30,0), CalFields(2011,11,6,6,30,0), CalFields(2011,11,6,5,30,0)},
2465 {"America/New_York", CalFields(2011,11,6,1,59,59), CalFields(2011,11,6,6,59,59), CalFields(2011,11,6,5,59,59)},
2466 {"America/New_York", CalFields(2011,11,6,2,0,0), CalFields(2011,11,6,7,0,0), CalFields(2011,11,6,7,0,0)},
2467 {"America/New_York", CalFields(2011,11,6,2,0,1), CalFields(2011,11,6,7,0,1), CalFields(2011,11,6,7,0,1)},
2469 {"Australia/Lord_Howe", CalFields(2011,4,3,1,29,59), CalFields(2011,4,2,14,29,59), CalFields(2011,4,2,14,29,59)},
2470 {"Australia/Lord_Howe", CalFields(2011,4,3,1,30,0), CalFields(2011,4,2,15,0,0), CalFields(2011,4,2,14,30,0)},
2471 {"Australia/Lord_Howe", CalFields(2011,4,3,1,45,0), CalFields(2011,4,2,15,15,0), CalFields(2011,4,2,14,45,0)},
2472 {"Australia/Lord_Howe", CalFields(2011,4,3,1,59,59), CalFields(2011,4,2,15,29,59), CalFields(2011,4,2,14,59,59)},
2473 {"Australia/Lord_Howe", CalFields(2011,4,3,2,0,0), CalFields(2011,4,2,15,30,0), CalFields(2011,4,2,15,30,0)},
2474 {"Australia/Lord_Howe", CalFields(2011,4,3,2,0,1), CalFields(2011,4,2,15,30,1), CalFields(2011,4,2,15,30,1)},
2476 {NULL
, CalFields(0,0,0,0,0,0), CalFields(0,0,0,0,0,0), CalFields(0,0,0,0,0,0)}
2479 void CalendarTest::TestRepeatedWallTime(void) {
2480 UErrorCode status
= U_ZERO_ERROR
;
2481 GregorianCalendar
calGMT((const TimeZone
&)*TimeZone::getGMT(), status
);
2482 GregorianCalendar
calDefault(status
);
2483 GregorianCalendar
calLast(status
);
2484 GregorianCalendar
calFirst(status
);
2486 if (U_FAILURE(status
)) {
2487 errln("Fail: Failed to create a calendar object.");
2491 calLast
.setRepeatedWallTimeOption(UCAL_WALLTIME_LAST
);
2492 calFirst
.setRepeatedWallTimeOption(UCAL_WALLTIME_FIRST
);
2494 for (int32_t i
= 0; RPDATA
[i
].tzid
!= NULL
; i
++) {
2496 TimeZone
*tz
= TimeZone::createTimeZone(RPDATA
[i
].tzid
);
2498 // UCAL_WALLTIME_LAST
2499 status
= U_ZERO_ERROR
;
2500 calLast
.setTimeZone(*tz
);
2501 RPDATA
[i
].in
.setTo(calLast
);
2502 calGMT
.setTime(calLast
.getTime(status
), status
);
2503 CalFields
outLastGMT(calGMT
, status
);
2504 if (U_FAILURE(status
)) {
2505 errln(UnicodeString("Fail: Failed to get/set time calLast/calGMT (UCAL_WALLTIME_LAST) - ")
2506 + RPDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + RPDATA
[i
].tzid
+ "]");
2508 if (outLastGMT
!= RPDATA
[i
].expLastGMT
) {
2509 dataerrln(UnicodeString("Fail: UCAL_WALLTIME_LAST ") + RPDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + RPDATA
[i
].tzid
+ "] is parsed as "
2510 + outLastGMT
.toString(buf
, sizeof(buf
)) + "[GMT]. Expected: " + RPDATA
[i
].expLastGMT
.toString(buf
, sizeof(buf
)) + "[GMT]");
2515 status
= U_ZERO_ERROR
;
2516 calDefault
.setTimeZone(*tz
);
2517 RPDATA
[i
].in
.setTo(calDefault
);
2518 calGMT
.setTime(calDefault
.getTime(status
), status
);
2519 CalFields
outDefGMT(calGMT
, status
);
2520 if (U_FAILURE(status
)) {
2521 errln(UnicodeString("Fail: Failed to get/set time calLast/calGMT (default) - ")
2522 + RPDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + RPDATA
[i
].tzid
+ "]");
2524 if (outDefGMT
!= RPDATA
[i
].expLastGMT
) {
2525 dataerrln(UnicodeString("Fail: (default) ") + RPDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + RPDATA
[i
].tzid
+ "] is parsed as "
2526 + outDefGMT
.toString(buf
, sizeof(buf
)) + "[GMT]. Expected: " + RPDATA
[i
].expLastGMT
.toString(buf
, sizeof(buf
)) + "[GMT]");
2530 // UCAL_WALLTIME_FIRST
2531 status
= U_ZERO_ERROR
;
2532 calFirst
.setTimeZone(*tz
);
2533 RPDATA
[i
].in
.setTo(calFirst
);
2534 calGMT
.setTime(calFirst
.getTime(status
), status
);
2535 CalFields
outFirstGMT(calGMT
, status
);
2536 if (U_FAILURE(status
)) {
2537 errln(UnicodeString("Fail: Failed to get/set time calLast/calGMT (UCAL_WALLTIME_FIRST) - ")
2538 + RPDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + RPDATA
[i
].tzid
+ "]");
2540 if (outFirstGMT
!= RPDATA
[i
].expFirstGMT
) {
2541 dataerrln(UnicodeString("Fail: UCAL_WALLTIME_FIRST ") + RPDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + RPDATA
[i
].tzid
+ "] is parsed as "
2542 + outFirstGMT
.toString(buf
, sizeof(buf
)) + "[GMT]. Expected: " + RPDATA
[i
].expFirstGMT
.toString(buf
, sizeof(buf
)) + "[GMT]");
2553 const CalFields expLastGMT
;
2554 const CalFields expFirstGMT
;
2555 const CalFields expNextAvailGMT
;
2556 } SkippedWallTimeTestData
;
2558 static SkippedWallTimeTestData SKDATA
[] =
2560 // Time zone Input wall time valid? WALLTIME_LAST in GMT WALLTIME_FIRST in GMT WALLTIME_NEXT_VALID in GMT
2561 {"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)},
2562 {"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)},
2563 {"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)},
2564 {"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)},
2565 {"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)},
2566 {"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)},
2568 {"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)},
2569 {"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)},
2570 {"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)},
2571 {"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)},
2572 {"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)},
2574 {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)}
2578 void CalendarTest::TestSkippedWallTime(void) {
2579 UErrorCode status
= U_ZERO_ERROR
;
2580 GregorianCalendar
calGMT((const TimeZone
&)*TimeZone::getGMT(), status
);
2581 GregorianCalendar
calDefault(status
);
2582 GregorianCalendar
calLast(status
);
2583 GregorianCalendar
calFirst(status
);
2584 GregorianCalendar
calNextAvail(status
);
2586 if (U_FAILURE(status
)) {
2587 errln("Fail: Failed to create a calendar object.");
2591 calLast
.setSkippedWallTimeOption(UCAL_WALLTIME_LAST
);
2592 calFirst
.setSkippedWallTimeOption(UCAL_WALLTIME_FIRST
);
2593 calNextAvail
.setSkippedWallTimeOption(UCAL_WALLTIME_NEXT_VALID
);
2595 for (int32_t i
= 0; SKDATA
[i
].tzid
!= NULL
; i
++) {
2598 TimeZone
*tz
= TimeZone::createTimeZone(SKDATA
[i
].tzid
);
2600 for (int32_t j
= 0; j
< 2; j
++) {
2601 UBool bLenient
= (j
== 0);
2603 // UCAL_WALLTIME_LAST
2604 status
= U_ZERO_ERROR
;
2605 calLast
.setLenient(bLenient
);
2606 calLast
.setTimeZone(*tz
);
2607 SKDATA
[i
].in
.setTo(calLast
);
2608 d
= calLast
.getTime(status
);
2609 if (bLenient
|| SKDATA
[i
].isValid
) {
2610 calGMT
.setTime(d
, status
);
2611 CalFields
outLastGMT(calGMT
, status
);
2612 if (U_FAILURE(status
)) {
2613 errln(UnicodeString("Fail: Failed to get/set time calLast/calGMT (UCAL_WALLTIME_LAST) - ")
2614 + SKDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + SKDATA
[i
].tzid
+ "]");
2616 if (outLastGMT
!= SKDATA
[i
].expLastGMT
) {
2617 dataerrln(UnicodeString("Fail: UCAL_WALLTIME_LAST ") + SKDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + SKDATA
[i
].tzid
+ "] is parsed as "
2618 + outLastGMT
.toString(buf
, sizeof(buf
)) + "[GMT]. Expected: " + SKDATA
[i
].expLastGMT
.toString(buf
, sizeof(buf
)) + "[GMT]");
2621 } else if (U_SUCCESS(status
)) {
2622 // strict, invalid wall time - must report an error
2623 dataerrln(UnicodeString("Fail: An error expected (UCAL_WALLTIME_LAST)") +
2624 + SKDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + SKDATA
[i
].tzid
+ "]");
2628 status
= U_ZERO_ERROR
;
2629 calDefault
.setLenient(bLenient
);
2630 calDefault
.setTimeZone(*tz
);
2631 SKDATA
[i
].in
.setTo(calDefault
);
2632 d
= calDefault
.getTime(status
);
2633 if (bLenient
|| SKDATA
[i
].isValid
) {
2634 calGMT
.setTime(d
, status
);
2635 CalFields
outDefGMT(calGMT
, status
);
2636 if (U_FAILURE(status
)) {
2637 errln(UnicodeString("Fail: Failed to get/set time calDefault/calGMT (default) - ")
2638 + SKDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + SKDATA
[i
].tzid
+ "]");
2640 if (outDefGMT
!= SKDATA
[i
].expLastGMT
) {
2641 dataerrln(UnicodeString("Fail: (default) ") + SKDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + SKDATA
[i
].tzid
+ "] is parsed as "
2642 + outDefGMT
.toString(buf
, sizeof(buf
)) + "[GMT]. Expected: " + SKDATA
[i
].expLastGMT
.toString(buf
, sizeof(buf
)) + "[GMT]");
2645 } else if (U_SUCCESS(status
)) {
2646 // strict, invalid wall time - must report an error
2647 dataerrln(UnicodeString("Fail: An error expected (default)") +
2648 + SKDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + SKDATA
[i
].tzid
+ "]");
2651 // UCAL_WALLTIME_FIRST
2652 status
= U_ZERO_ERROR
;
2653 calFirst
.setLenient(bLenient
);
2654 calFirst
.setTimeZone(*tz
);
2655 SKDATA
[i
].in
.setTo(calFirst
);
2656 d
= calFirst
.getTime(status
);
2657 if (bLenient
|| SKDATA
[i
].isValid
) {
2658 calGMT
.setTime(d
, status
);
2659 CalFields
outFirstGMT(calGMT
, status
);
2660 if (U_FAILURE(status
)) {
2661 errln(UnicodeString("Fail: Failed to get/set time calFirst/calGMT (UCAL_WALLTIME_FIRST) - ")
2662 + SKDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + SKDATA
[i
].tzid
+ "]");
2664 if (outFirstGMT
!= SKDATA
[i
].expFirstGMT
) {
2665 dataerrln(UnicodeString("Fail: UCAL_WALLTIME_FIRST ") + SKDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + SKDATA
[i
].tzid
+ "] is parsed as "
2666 + outFirstGMT
.toString(buf
, sizeof(buf
)) + "[GMT]. Expected: " + SKDATA
[i
].expFirstGMT
.toString(buf
, sizeof(buf
)) + "[GMT]");
2669 } else if (U_SUCCESS(status
)) {
2670 // strict, invalid wall time - must report an error
2671 dataerrln(UnicodeString("Fail: An error expected (UCAL_WALLTIME_FIRST)") +
2672 + SKDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + SKDATA
[i
].tzid
+ "]");
2675 // UCAL_WALLTIME_NEXT_VALID
2676 status
= U_ZERO_ERROR
;
2677 calNextAvail
.setLenient(bLenient
);
2678 calNextAvail
.setTimeZone(*tz
);
2679 SKDATA
[i
].in
.setTo(calNextAvail
);
2680 d
= calNextAvail
.getTime(status
);
2681 if (bLenient
|| SKDATA
[i
].isValid
) {
2682 calGMT
.setTime(d
, status
);
2683 CalFields
outNextAvailGMT(calGMT
, status
);
2684 if (U_FAILURE(status
)) {
2685 errln(UnicodeString("Fail: Failed to get/set time calNextAvail/calGMT (UCAL_WALLTIME_NEXT_VALID) - ")
2686 + SKDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + SKDATA
[i
].tzid
+ "]");
2688 if (outNextAvailGMT
!= SKDATA
[i
].expNextAvailGMT
) {
2689 dataerrln(UnicodeString("Fail: UCAL_WALLTIME_NEXT_VALID ") + SKDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + SKDATA
[i
].tzid
+ "] is parsed as "
2690 + outNextAvailGMT
.toString(buf
, sizeof(buf
)) + "[GMT]. Expected: " + SKDATA
[i
].expNextAvailGMT
.toString(buf
, sizeof(buf
)) + "[GMT]");
2693 } else if (U_SUCCESS(status
)) {
2694 // strict, invalid wall time - must report an error
2695 dataerrln(UnicodeString("Fail: An error expected (UCAL_WALLTIME_NEXT_VALID)") +
2696 + SKDATA
[i
].in
.toString(buf
, sizeof(buf
)) + "[" + SKDATA
[i
].tzid
+ "]");
2704 void CalendarTest::TestCloneLocale(void) {
2705 UErrorCode status
= U_ZERO_ERROR
;
2706 LocalPointer
<Calendar
> cal(Calendar::createInstance(TimeZone::getGMT()->clone(),
2707 Locale::createFromName("en"), status
));
2709 Locale l0
= cal
->getLocale(ULOC_VALID_LOCALE
, status
);
2711 LocalPointer
<Calendar
> cal2(cal
->clone());
2712 Locale l
= cal2
->getLocale(ULOC_VALID_LOCALE
, status
);
2714 errln("Error: cloned locale %s != original locale %s, status %s\n", l0
.getName(), l
.getName(), u_errorName(status
));
2719 #endif /* #if !UCONFIG_NO_FORMATTING */