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
13 #include "unicode/gregocal.h"
14 #include "unicode/simpletz.h"
15 #include "unicode/smpdtfmt.h"
16 #include "unicode/strenum.h"
19 #include "unicode/localpointer.h"
23 // *****************************************************************************
24 // class CalendarRegressionTest
25 // *****************************************************************************
27 // these numbers correspond to using LONG_MIN and LONG_MAX in Java
28 // this is 2^52 - 1, the largest allowable mantissa with a 0 exponent in a 64-bit double
29 const UDate
CalendarRegressionTest::EARLIEST_SUPPORTED_MILLIS
= - 4503599627370495.0;
30 const UDate
CalendarRegressionTest::LATEST_SUPPORTED_MILLIS
= 4503599627370495.0;
32 #define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); logln((UnicodeString)""); test(); } break
35 CalendarRegressionTest::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char* /*par*/ )
37 // if (exec) logln((UnicodeString)"TestSuite NumberFormatRegressionTest");
56 CASE(17,test41003112
);
78 CASE(38,TestLeapFieldDifference
);
79 CASE(39,TestMalaysianInstance
);
82 CASE(42,TestWeekShift
);
83 CASE(43,TestTimeZoneTransitionAdd
);
84 CASE(44,TestDeprecates
);
91 default: name
= ""; break;
95 const char* CalendarRegressionTest::FIELD_NAME
[] = {
104 "DAY_OF_WEEK_IN_MONTH",
118 CalendarRegressionTest::failure(UErrorCode status
, const char* msg
)
120 if(U_FAILURE(status
)) {
121 errcheckln(status
, UnicodeString("FAIL: ") + msg
+ " failed, error " + u_errorName(status
));
132 CalendarRegressionTest::test4100311()
134 UErrorCode status
= U_ZERO_ERROR
;
135 GregorianCalendar
*cal
= (GregorianCalendar
*)Calendar::createInstance(status
);
136 if(U_FAILURE(status
)) {
137 dataerrln("Error creating Calendar: %s", u_errorName(status
));
141 failure(status
, "Calendar::createInstance(status)");
142 cal
->set(UCAL_YEAR
, 1997);
143 cal
->set(UCAL_DAY_OF_YEAR
, 1);
144 UDate d
= cal
->getTime(status
); // Should be Jan 1
145 failure(status
, "cal->getTime");
146 logln(UnicodeString("") + d
);
155 CalendarRegressionTest::test4074758()
156 { //Set system time to between 12-1 (am or pm) and then run
157 UErrorCode status
= U_ZERO_ERROR
;
158 GregorianCalendar
*cal
= new GregorianCalendar(status
);
159 if(U_FAILURE(status
)) {
160 dataerrln("Error creating Calendar: %s", u_errorName(status
));
164 failure(status
, "new GregorianCalendar");
165 for (int32_t h
=0; h
<25; ++h
) {
166 cal
->set(97, UCAL_JANUARY
, 1, h
, 34);
167 //System.out.print(d);
168 logln(UnicodeString("HOUR=") + cal
->get(UCAL_HOUR
, status
)); //prints 0
169 failure(status
, "cal->get");
170 logln(UnicodeString("HOUR_OF_DAY=") + cal
->get(UCAL_HOUR_OF_DAY
, status
));
171 failure(status
, "cal->get");
178 CalendarRegressionTest::test4028518()
180 UErrorCode status
= U_ZERO_ERROR
;
181 GregorianCalendar
*cal1
= new GregorianCalendar(status
) ;
182 if(U_FAILURE(status
)) {
183 dataerrln("Error creating Calendar: %s", u_errorName(status
));
187 failure(status
, "new GregorianCalendar");
188 GregorianCalendar
*cal2
= (GregorianCalendar
*) cal1
->clone() ;
190 printdate(cal1
, "cal1: ") ;
191 printdate(cal2
, "cal2 - cloned(): ") ;
192 cal1
->add(UCAL_DATE
, 1, status
) ;
193 failure(status
, "cal1->add");
194 printdate(cal1
, "cal1 after adding 1 day:") ;
195 printdate(cal2
, "cal2 should be unmodified:") ;
202 CalendarRegressionTest::Test9019()
204 UErrorCode status
= U_ZERO_ERROR
;
205 LocalPointer
<GregorianCalendar
> cal1(new GregorianCalendar(status
));
206 LocalPointer
<GregorianCalendar
> cal2(new GregorianCalendar(status
));
207 cal1
->set(UCAL_HOUR
, 1);
208 cal2
->set(UCAL_HOUR
,2);
211 if(U_FAILURE(status
)) {
212 dataerrln("Error creating Calendar: %s", u_errorName(status
));
215 failure(status
, "new GregorianCalendar");
216 cal1
->set(2011,UCAL_MAY
,06);
217 cal2
->set(2012,UCAL_JANUARY
,06);
218 printdate(cal1
.getAlias(), "cal1: ") ;
219 cal1
->setLenient(FALSE
);
220 cal1
->add(UCAL_MONTH
,8,status
);
221 failure(status
, "->add(UCAL_MONTH,8)");
222 printdate(cal1
.getAlias(), "cal1 (lenient) after adding 8 months:") ;
223 printdate(cal2
.getAlias(), "cal2 (expected date):") ;
225 if(!cal1
->equals(*cal2
,status
)) {
226 errln("Error: cal1 != cal2.\n");
228 failure(status
, "equals");
232 CalendarRegressionTest::printdate(GregorianCalendar
*cal
, const char *string
)
234 UErrorCode status
= U_ZERO_ERROR
;
235 logln(UnicodeString(string
, ""));
236 log(UnicodeString("") + cal
->get(UCAL_MONTH
, status
)) ;
237 failure(status
, "cal->get");
238 int32_t date
= cal
->get(UCAL_DATE
, status
) + 1 ;
239 failure(status
, "cal->get");
240 log(UnicodeString("/") + date
) ;
241 logln(UnicodeString("/") + cal
->get(UCAL_YEAR
, status
)) ;
242 failure(status
, "cal->get");
249 CalendarRegressionTest::test4031502()
251 // This bug actually occurs on Windows NT as well, and doesn't
252 // require the host zone to be set; it can be set in Java.
253 UErrorCode status
= U_ZERO_ERROR
;
254 StringEnumeration
* ids
= TimeZone::createEnumeration();
256 dataerrln("Unable to create TimeZone Enumeration.");
260 TimeZone
* tz
=TimeZone::createTimeZone("Asia/Riyadh87");
261 failure(status
, "new TimeZone");
262 GregorianCalendar
*cl
= new GregorianCalendar(tz
, status
);
263 if (U_FAILURE(status
)) {
264 dataerrln("Fail new GregorianCalendar: %s", u_errorName(status
));
269 cl
->set(1900, 15, 5, 5, 8, 13);
270 cl
->get(UCAL_HOUR
, status
);
271 failure(status
, "cl->get(UCAL_HOUR, status)");
272 status
= U_ZERO_ERROR
;
274 for (int32_t i
=0; i
<ids
->count(status
); ++i
) {
275 TimeZone
*zone
= TimeZone::createTimeZone(*ids
->snext(status
));
276 GregorianCalendar
*cal
= new GregorianCalendar(zone
, status
);
277 failure(status
, "new GregorianCalendar");
279 cal
->set(1900, 15, 5, 5, 8, 13);
280 if (cal
->get(UCAL_HOUR
, status
) != 5 || U_FAILURE(status
)) {
282 logln(zone
->getID(temp
) + " " +
283 //zone.useDaylightTime() + " " +
284 cal
->get(UCAL_DST_OFFSET
,status
) / (60*60*1000) + " " +
285 zone
->getRawOffset() / (60*60*1000) +
286 ": HOUR = " + cal
->get(UCAL_HOUR
,status
));
292 errln("TimeZone problems with GC");
293 // delete [] ids; // TODO: bad APIs
300 void CalendarRegressionTest::test4035301()
302 UErrorCode status
= U_ZERO_ERROR
;
303 GregorianCalendar
*c
= new GregorianCalendar(98, 8, 7,status
);
304 GregorianCalendar
*d
= new GregorianCalendar(98, 8, 7,status
);
305 if (c
->after(*d
,status
) ||
306 c
->after(*c
,status
) ||
307 c
->before(*d
,status
) ||
308 c
->before(*c
,status
) ||
319 void CalendarRegressionTest::test4040996()
322 StringEnumeration
* ids
= TimeZone::createEnumeration(-8 * 60 * 60 * 1000);
324 dataerrln("Unable to create TimeZone enumeration.");
327 UErrorCode status
= U_ZERO_ERROR
;
328 count
= ids
->count(status
);
329 SimpleTimeZone
*pdt
= new SimpleTimeZone(-8 * 60 * 60 * 1000, *ids
->snext(status
));
330 pdt
->setStartRule(UCAL_APRIL
, 1, UCAL_SUNDAY
, 2 * 60 * 60 * 1000, status
);
331 pdt
->setEndRule(UCAL_OCTOBER
, -1, UCAL_SUNDAY
, 2 * 60 * 60 * 1000, status
);
332 Calendar
*calendar
= new GregorianCalendar(pdt
, status
);
333 if (U_FAILURE(status
)) {
334 dataerrln("Fail new GregorianCalendar: %s", u_errorName(status
));
337 calendar
->set(UCAL_MONTH
,3);
338 calendar
->set(UCAL_DATE
,18);
339 calendar
->set(UCAL_SECOND
, 30);
341 logln(UnicodeString("MONTH: ") + calendar
->get(UCAL_MONTH
, status
));
342 logln(UnicodeString("DAY_OF_MONTH: ") +
343 calendar
->get(UCAL_DATE
, status
));
344 logln(UnicodeString("MINUTE: ") + calendar
->get(UCAL_MINUTE
, status
));
345 logln(UnicodeString("SECOND: ") + calendar
->get(UCAL_SECOND
, status
));
347 calendar
->add(UCAL_SECOND
,6, status
);
348 //This will print out todays date for MONTH and DAY_OF_MONTH
349 //instead of the date it was set to.
350 //This happens when adding MILLISECOND or MINUTE also
351 logln(UnicodeString("MONTH: ") + calendar
->get(UCAL_MONTH
, status
));
352 logln(UnicodeString("DAY_OF_MONTH: ") +
353 calendar
->get(UCAL_DATE
, status
));
354 logln(UnicodeString("MINUTE: ") + calendar
->get(UCAL_MINUTE
, status
));
355 logln(UnicodeString("SECOND: ") + calendar
->get(UCAL_SECOND
, status
));
356 if (calendar
->get(UCAL_MONTH
, status
) != 3 ||
357 calendar
->get(UCAL_DATE
, status
) != 18 ||
358 calendar
->get(UCAL_SECOND
, status
) != 36)
359 errln(UnicodeString("Fail: Calendar::add misbehaves"));
363 // delete ids; // TODO: BAD API
369 void CalendarRegressionTest::test4051765()
371 UErrorCode status
= U_ZERO_ERROR
;
372 Calendar
*cal
= Calendar::createInstance(status
);
373 if(U_FAILURE(status
)) {
374 dataerrln("Error creating Calendar: %s", u_errorName(status
));
378 cal
->setLenient(FALSE
);
379 cal
->set(UCAL_DAY_OF_WEEK
, 0);
381 cal
->getTime(status
);
382 if( ! U_FAILURE(status
))
383 errln("Fail: DAY_OF_WEEK 0 should be disallowed");
385 catch (IllegalArgumentException e) {
392 /* User error - no bug here
393 void CalendarRegressionTest::test4059524() {
394 // Create calendar for April 10, 1997
395 GregorianCalendar calendar = new GregorianCalendar(status);
396 // print out a bunch of interesting things
397 logln("ERA: " + Calendar::get(Calendar::ERA));
398 logln("YEAR: " + Calendar::get(Calendar::YEAR));
399 logln("MONTH: " + Calendar::get(Calendar::MONTH));
400 logln("WEEK_OF_YEAR: " +
401 Calendar::get(Calendar::WEEK_OF_YEAR));
402 logln("WEEK_OF_MONTH: " +
403 Calendar::get(Calendar::WEEK_OF_MONTH));
404 logln("DATE: " + Calendar::get(Calendar::DATE));
405 logln("DAY_OF_MONTH: " +
406 Calendar::get(Calendar::DAY_OF_MONTH));
407 logln("DAY_OF_YEAR: " + Calendar::get(Calendar::DAY_OF_YEAR));
408 logln("DAY_OF_WEEK: " + Calendar::get(Calendar::DAY_OF_WEEK));
409 logln("DAY_OF_WEEK_IN_MONTH: " +
410 Calendar::get(Calendar::DAY_OF_WEEK_IN_MONTH));
411 logln("AM_PM: " + Calendar::get(Calendar::AM_PM));
412 logln("HOUR: " + Calendar::get(Calendar::HOUR));
413 logln("HOUR_OF_DAY: " + Calendar::get(Calendar::HOUR_OF_DAY));
414 logln("MINUTE: " + Calendar::get(Calendar::MINUTE));
415 logln("SECOND: " + Calendar::get(Calendar::SECOND));
416 logln("MILLISECOND: " + Calendar::get(Calendar::MILLISECOND));
417 logln("ZONE_OFFSET: "
418 + (Calendar::get(Calendar::ZONE_OFFSET)/(60*60*1000)));
420 + (Calendar::get(Calendar::DST_OFFSET)/(60*60*1000)));
421 calendar = new GregorianCalendar(1997,3,10);
423 logln("April 10, 1997");
424 logln("ERA: " + Calendar::get(Calendar::ERA));
425 logln("YEAR: " + Calendar::get(Calendar::YEAR));
426 logln("MONTH: " + Calendar::get(Calendar::MONTH));
427 logln("WEEK_OF_YEAR: " +
428 Calendar::get(Calendar::WEEK_OF_YEAR));
429 logln("WEEK_OF_MONTH: " +
430 Calendar::get(Calendar::WEEK_OF_MONTH));
431 logln("DATE: " + Calendar::get(Calendar::DATE));
432 logln("DAY_OF_MONTH: " +
433 Calendar::get(Calendar::DAY_OF_MONTH));
434 logln("DAY_OF_YEAR: " + Calendar::get(Calendar::DAY_OF_YEAR));
435 logln("DAY_OF_WEEK: " + Calendar::get(Calendar::DAY_OF_WEEK));
436 logln("DAY_OF_WEEK_IN_MONTH: " + Calendar::get(Calendar::DAY_OF_WEEK_IN_MONTH));
437 logln("AM_PM: " + Calendar::get(Calendar::AM_PM));
438 logln("HOUR: " + Calendar::get(Calendar::HOUR));
439 logln("HOUR_OF_DAY: " + Calendar::get(Calendar::HOUR_OF_DAY));
440 logln("MINUTE: " + Calendar::get(Calendar::MINUTE));
441 logln("SECOND: " + Calendar::get(Calendar::SECOND));
442 logln("MILLISECOND: " + Calendar::get(Calendar::MILLISECOND));
443 logln("ZONE_OFFSET: "
444 + (Calendar::get(Calendar::ZONE_OFFSET)/(60*60*1000))); // in hours
446 + (Calendar::get(Calendar::DST_OFFSET)/(60*60*1000))); // in hours
453 void CalendarRegressionTest::test4059654() {
454 UErrorCode status
= U_ZERO_ERROR
;
455 GregorianCalendar
*gc
= new GregorianCalendar(status
);
456 if(U_FAILURE(status
)) {
457 dataerrln("Error creating Calendar: %s", u_errorName(status
));
462 gc
->set(1997, 3, 1, 15, 16, 17); // April 1, 1997
464 gc
->set(UCAL_HOUR
, 0);
465 gc
->set(UCAL_AM_PM
, UCAL_AM
);
466 gc
->set(UCAL_MINUTE
, 0);
467 gc
->set(UCAL_SECOND
, 0);
468 gc
->set(UCAL_MILLISECOND
, 0);
470 UDate cd
= gc
->getTime(status
);
471 GregorianCalendar
*exp
= new GregorianCalendar(1997, 3, 1, 0, 0, 0, status
);
472 if (cd
!= exp
->getTime(status
))
473 errln(UnicodeString("Fail: Calendar::set broken. Got ") + cd
+ " Want " + exp
->getTime(status
));
482 void CalendarRegressionTest::test4061476()
484 UErrorCode status
= U_ZERO_ERROR
;
485 SimpleDateFormat
*fmt
= new SimpleDateFormat(UnicodeString("ddMMMyy"), Locale::getUK(),status
);
486 Calendar
*cal
= Calendar::createInstance(TimeZone::createTimeZone("GMT"),
487 Locale::getUK(),status
);
488 if(U_FAILURE(status
)) {
489 dataerrln("Error creating Calendar: %s", u_errorName(status
));
494 fmt
->adoptCalendar(cal
);
496 UDate date
= fmt
->parse("29MAY97", status
);
497 failure(status
, "fmt->parse");
498 cal
->setTime(date
, status
);
499 failure(status
, "cal->setTime");
501 //catch (Exception e) {;}
502 cal
->set(UCAL_HOUR_OF_DAY
, 13);
503 logln(UnicodeString("Hour: ")+cal
->get(UCAL_HOUR_OF_DAY
, status
));
504 cal
->add(UCAL_HOUR_OF_DAY
, 6,status
);
505 logln(UnicodeString("Hour: ")+cal
->get(UCAL_HOUR_OF_DAY
, status
));
506 if (cal
->get(UCAL_HOUR_OF_DAY
, status
) != 19)
507 errln(UnicodeString("Fail: Want 19 Got ") + cal
->get(UCAL_HOUR_OF_DAY
, status
));
515 void CalendarRegressionTest::test4070502()
517 UErrorCode status
= U_ZERO_ERROR
;
518 Calendar
*cal
= new GregorianCalendar(status
);
519 if(status
== U_USING_FALLBACK_WARNING
|| U_FAILURE(status
)) {
520 dataerrln("Error creating Calendar: %s", u_errorName(status
));
524 UDate d
= getAssociatedDate(makeDate(1998,0,30), status
);
525 cal
->setTime(d
,status
);
526 if (cal
->get(UCAL_DAY_OF_WEEK
,status
) == UCAL_SATURDAY
||
527 cal
->get(UCAL_DAY_OF_WEEK
,status
) == UCAL_SUNDAY
)
528 errln(UnicodeString("Fail: Want weekday Got ") + d
);
534 * Get the associated date starting from a specified date
535 * NOTE: the unnecessary "getTime()'s" below are a work-around for a
536 * bug in jdk 1.1.3 (and probably earlier versions also)
538 * @param date The date to start from
541 CalendarRegressionTest::getAssociatedDate(UDate d
, UErrorCode
& status
)
543 GregorianCalendar
*cal
= new GregorianCalendar(status
);
544 cal
->setTime(d
,status
);
545 //cal.add(field, amount); //<-- PROBLEM SEEN WITH field = DATE,MONTH
546 // cal.getTime(); // <--- REMOVE THIS TO SEE BUG
548 int32_t wd
= cal
->get(UCAL_DAY_OF_WEEK
, status
);
549 if (wd
== UCAL_SATURDAY
|| wd
== UCAL_SUNDAY
) {
550 cal
->add(UCAL_DATE
, 1, status
);
557 UDate dd
= cal
->getTime(status
);
565 void CalendarRegressionTest::test4071197()
571 void CalendarRegressionTest::dowTest(UBool lenient
)
573 UErrorCode status
= U_ZERO_ERROR
;
574 GregorianCalendar
*cal
= new GregorianCalendar(status
);
575 if(U_FAILURE(status
)) {
576 dataerrln("Error creating Calendar: %s", u_errorName(status
));
580 cal
->set(1997, UCAL_AUGUST
, 12); // Wednesday
581 // cal.getTime(); // Force update
582 cal
->setLenient(lenient
);
583 cal
->set(1996, UCAL_DECEMBER
, 1); // Set the date to be December 1, 1996
584 int32_t dow
= cal
->get(UCAL_DAY_OF_WEEK
, status
);
585 int32_t min
= cal
->getMinimum(UCAL_DAY_OF_WEEK
);
586 int32_t max
= cal
->getMaximum(UCAL_DAY_OF_WEEK
);
587 //logln(cal.getTime().toString());
588 if (min
!= UCAL_SUNDAY
|| max
!= UCAL_SATURDAY
)
589 errln("FAIL: Min/max bad");
590 if (dow
< min
|| dow
> max
)
591 errln("FAIL: Day of week %d out of range [%d,%d]\n", dow
, min
, max
);
592 if (dow
!= UCAL_SUNDAY
)
593 errln(UnicodeString("FAIL: Day of week should be SUNDAY Got ") + dow
);
595 if(U_FAILURE(status
)) {
596 errln("Error checking Calendar: %s", u_errorName(status
));
601 if(cal
->getActualMinimum(UCAL_DAY_OF_WEEK
, status
) != min
) {
602 errln("FAIL: actual minimum differs from minimum");
604 if(cal
->getActualMinimum(Calendar::DAY_OF_WEEK
, status
) != min
) {
605 errln("FAIL: actual minimum (Calendar::DAY_OF_WEEK, status) differs from minimum");
607 if(cal
->getActualMinimum(Calendar::DAY_OF_WEEK
) != min
) {
608 errln("FAIL: actual minimum (Calendar::DAY_OF_WEEK) differs from minimum");
610 if(((Calendar
*)cal
)->getActualMinimum(UCAL_DAY_OF_WEEK
, status
) != min
) {
611 errln("FAIL: actual minimum (UCAL_DAY_OF_WEEK, status) differs from minimum");
613 // NOTE: This function does not exist! jitterbug #3016
614 // if(((Calendar*)cal)->getActualMinimum(Calendar::DAY_OF_WEEK, status) != min) {
615 // errln("FAIL: actual minimum (Calendar::DAY_OF_WEEK, status) differs from minimum");
617 if(U_FAILURE(status
)) {
618 errln("Error getting actual minimum: %s", u_errorName(status
));
628 void CalendarRegressionTest::test4071385()
630 UErrorCode status
= U_ZERO_ERROR
;
631 Calendar
*cal
= Calendar::createInstance(status
);
632 if(U_FAILURE(status
)) {
633 dataerrln("Error creating Calendar: %s", u_errorName(status
));
637 cal
->setTime(makeDate(1998, UCAL_JUNE
, 24),status
);
638 cal
->set(UCAL_MONTH
, UCAL_NOVEMBER
); // change a field
639 //logln(cal.getTime().toString());
640 if (cal
->getTime(status
) != makeDate(1998, UCAL_NOVEMBER
, 24))
649 void CalendarRegressionTest::test4073929()
651 UErrorCode status
= U_ZERO_ERROR
;
652 GregorianCalendar
*foo1
= new GregorianCalendar(1997, 8, 27,status
);
653 if(U_FAILURE(status
)) {
654 dataerrln("Error creating Calendar: %s", u_errorName(status
));
658 logln("foo1@%.0f - %d-%d-%d %d:%d:%d.%ds\n", foo1
->getTime(status
),
659 foo1
->get(UCAL_YEAR
, status
),
660 foo1
->get(UCAL_MONTH
, status
),
661 foo1
->get(UCAL_DATE
, status
),
662 foo1
->get(UCAL_HOUR
, status
),
663 foo1
->get(UCAL_MINUTE
, status
),
664 foo1
->get(UCAL_SECOND
, status
),
665 foo1
->get(UCAL_MILLISECOND
,status
));
666 foo1
->add(UCAL_DATE
, + 1, status
);
667 logln("foo1@%.0f - %d-%d-%d %d:%d:%d.%ds after +\n", foo1
->getTime(status
),
668 foo1
->get(UCAL_YEAR
, status
),
669 foo1
->get(UCAL_MONTH
, status
),
670 foo1
->get(UCAL_DATE
, status
),
671 foo1
->get(UCAL_HOUR
, status
),
672 foo1
->get(UCAL_MINUTE
, status
),
673 foo1
->get(UCAL_SECOND
, status
),
674 foo1
->get(UCAL_MILLISECOND
,status
));
675 foo1
->add(UCAL_DATE
, - 1, status
);
676 logln("foo1@%.0f - %d-%d-%d %d:%d:%d.%ds after -\n", foo1
->getTime(status
),
677 foo1
->get(UCAL_YEAR
, status
),
678 foo1
->get(UCAL_MONTH
, status
),
679 foo1
->get(UCAL_DATE
, status
),
680 foo1
->get(UCAL_HOUR
, status
),
681 foo1
->get(UCAL_MINUTE
, status
),
682 foo1
->get(UCAL_SECOND
, status
),
683 foo1
->get(UCAL_MILLISECOND
, status
));
685 foo1
->add(UCAL_DATE
, + 1, status
);
686 int32_t testyear
= foo1
->get(UCAL_YEAR
, status
);
687 int32_t testmonth
= foo1
->get(UCAL_MONTH
, status
);
688 int32_t testday
= foo1
->get(UCAL_DATE
, status
);
689 if (testyear
!= 1997 ||
692 errln("Fail: Calendar not initialized");
700 void CalendarRegressionTest::test4083167()
702 UErrorCode status
= U_ZERO_ERROR
;
703 TimeZone
*saveZone
= TimeZone::createDefault();
705 TimeZone
*newZone
= TimeZone::createTimeZone("UTC");
706 TimeZone::setDefault(*newZone
);
707 UDate firstDate
= Calendar::getNow();
708 Calendar
*cal
= new GregorianCalendar(status
);
709 if(U_FAILURE(status
)) {
710 dataerrln("Error creating Calendar: %s", u_errorName(status
));
714 cal
->setTime(firstDate
,status
);
715 int32_t hr
= cal
->get(UCAL_HOUR_OF_DAY
, status
);
716 int32_t min
= cal
->get(UCAL_MINUTE
, status
);
717 int32_t sec
= cal
->get(UCAL_SECOND
, status
);
718 int32_t msec
= cal
->get(UCAL_MILLISECOND
, status
);
719 double firstMillisInDay
= hr
* 3600000 + min
* 60000 + sec
* 1000 + msec
;
721 //logln("Current time: " + firstDate.toString());
723 for (int32_t validity
=0; validity
<30; validity
++) {
724 UDate lastDate
= firstDate
+ validity
*1000*24*60*60.0;
725 cal
->setTime(lastDate
, status
);
726 hr
= cal
->get(UCAL_HOUR_OF_DAY
, status
);
727 min
= cal
->get(UCAL_MINUTE
, status
);
728 sec
= cal
->get(UCAL_SECOND
, status
);
729 msec
= cal
->get(UCAL_MILLISECOND
, status
);
730 double millisInDay
= hr
* 3600000.0 + min
* 60000.0 + sec
* 1000.0 + msec
;
731 if (firstMillisInDay
!= millisInDay
)
732 errln(UnicodeString("Day has shifted ") + lastDate
);
736 TimeZone::setDefault(*saveZone
);
747 void CalendarRegressionTest::test4086724()
749 UErrorCode status
= U_ZERO_ERROR
;
750 SimpleDateFormat
*date
;
751 TimeZone
*saveZone
= TimeZone::createDefault();
752 Locale saveLocale
= Locale::getDefault();
754 Locale::setDefault(Locale::getUK(),status
);
755 TimeZone
*newZone
= TimeZone::createTimeZone("GMT");
756 TimeZone::setDefault(*newZone
);
757 date
= new SimpleDateFormat(UnicodeString("dd MMM yyy (zzzz) 'is in week' ww"),status
);
758 Calendar
*cal
= Calendar::createInstance(status
);
759 if(U_FAILURE(status
)) {
760 dataerrln("Error creating Calendar: %s", u_errorName(status
));
766 cal
->set(1997,UCAL_SEPTEMBER
,30);
767 UDate now
= cal
->getTime(status
);
769 FieldPosition
pos(FieldPosition::DONT_CARE
);
770 logln(date
->format(now
, temp
, pos
));
771 cal
->set(1997,UCAL_JANUARY
,1);
772 now
=cal
->getTime(status
);
773 logln(date
->format(now
,temp
, pos
));
774 cal
->set(1997,UCAL_JANUARY
,8);
775 now
=cal
->getTime(status
);
776 logln(date
->format(now
,temp
, pos
));
777 cal
->set(1996,UCAL_DECEMBER
,31);
778 now
=cal
->getTime(status
);
779 logln(date
->format(now
,temp
, pos
));
782 Locale::setDefault(saveLocale
,status
);
783 TimeZone::setDefault(*saveZone
);
785 logln("*** THE RESULTS OF THIS TEST MUST BE VERIFIED MANUALLY ***");
796 void CalendarRegressionTest::test4092362() {
797 UErrorCode status
= U_ZERO_ERROR
;
798 GregorianCalendar
*cal1
= new GregorianCalendar(1997, 10, 11, 10, 20, 40,status
);
799 if (U_FAILURE(status
)) {
800 dataerrln("Fail new GregorianCalendar: %s", u_errorName(status
));
804 /*cal1.set( Calendar::YEAR, 1997 );
805 cal1.set( Calendar::MONTH, 10 );
806 cal1.set( Calendar::DATE, 11 );
807 cal1.set( Calendar::HOUR, 10 );
808 cal1.set( Calendar::MINUTE, 20 );
809 cal1.set( Calendar::SECOND, 40 ); */
811 logln( UnicodeString(" Cal1 = ") + cal1
->getTime(status
) );
812 logln( UnicodeString(" Cal1 time in ms = ") + cal1
->get(UCAL_MILLISECOND
,status
) );
813 for (int32_t k
= 0; k
< 100 ; k
++)
816 GregorianCalendar
*cal2
= new GregorianCalendar(1997, 10, 11, 10, 20, 40,status
);
817 /*cal2.set( Calendar::YEAR, 1997 );
818 cal2.set( Calendar::MONTH, 10 );
819 cal2.set( Calendar::DATE, 11 );
820 cal2.set( Calendar::HOUR, 10 );
821 cal2.set( Calendar::MINUTE, 20 );
822 cal2.set( Calendar::SECOND, 40 ); */
824 logln( UnicodeString(" Cal2 = ") + cal2
->getTime(status
) );
825 logln( UnicodeString(" Cal2 time in ms = ") + cal2
->get(UCAL_MILLISECOND
,status
) );
827 errln("Fail: Milliseconds randomized");
836 void CalendarRegressionTest::test4095407()
838 UErrorCode status
= U_ZERO_ERROR
;
839 GregorianCalendar
*a
= new GregorianCalendar(1997,UCAL_NOVEMBER
, 13,status
);
840 if (U_FAILURE(status
)) {
841 dataerrln("Fail new GregorianCalendar: %s", u_errorName(status
));
845 int32_t dow
= a
->get(UCAL_DAY_OF_WEEK
, status
);
846 if (dow
!= UCAL_THURSDAY
)
847 errln(UnicodeString("Fail: Want THURSDAY Got ") + dow
);
855 void CalendarRegressionTest::test4096231()
857 UErrorCode status
= U_ZERO_ERROR
;
858 TimeZone
*GMT
= TimeZone::createTimeZone("GMT");
859 TimeZone
*PST
= TimeZone::createTimeZone("PST");
860 int32_t sec
= 0, min
= 0, hr
= 0, day
= 1, month
= 10, year
= 1997;
862 Calendar
*cal1
= new GregorianCalendar(*PST
,status
);
863 if (U_FAILURE(status
)) {
864 dataerrln("Failure new GregorianCalendar: %s", u_errorName(status
));
870 cal1
->setTime(880698639000.0,status
);
871 // Issue 1: Changing the timezone doesn't change the
872 // represented time. The old API, pre 1.2.2a requires
873 // setTime to be called in order to update the time fields after the time
874 // zone has been set.
876 logln(UnicodeString("PST 1 is: ") + (h1
=cal1
->get(UCAL_HOUR_OF_DAY
, status
)));
877 cal1
->setTimeZone(*GMT
);
878 logln(UnicodeString("GMT 2 is: ") + (h2
=cal1
->get(UCAL_HOUR_OF_DAY
, status
)));
879 if ((*GMT
!= *PST
) && (h1
== h2
))
880 errln("Fail: Hour same in different zones");
882 Calendar
*cal2
= new GregorianCalendar(*GMT
,status
);
883 Calendar
*cal3
= new GregorianCalendar(*PST
,status
);
884 cal2
->set(UCAL_MILLISECOND
, 0);
885 cal3
->set(UCAL_MILLISECOND
, 0);
887 cal2
->set(cal1
->get(UCAL_YEAR
,status
),
888 cal1
->get(UCAL_MONTH
,status
),
889 cal1
->get(UCAL_DATE
,status
),
890 cal1
->get(UCAL_HOUR_OF_DAY
,status
),
891 cal1
->get(UCAL_MINUTE
,status
),
892 cal1
->get(UCAL_SECOND
,status
));
895 logln(UnicodeString("RGMT 1 is: ") + (t1
=cal2
->getTime(status
)));
896 cal3
->set(year
, month
, day
, hr
, min
, sec
);
897 logln(UnicodeString("RPST 1 is: ") + (t2
=cal3
->getTime(status
)));
898 cal3
->setTimeZone(*GMT
);
899 logln(UnicodeString("RGMT 2 is: ") + (t3
=cal3
->getTime(status
)));
900 cal3
->set(cal1
->get(UCAL_YEAR
,status
),
901 cal1
->get(UCAL_MONTH
,status
),
902 cal1
->get(UCAL_DATE
,status
),
903 cal1
->get(UCAL_HOUR_OF_DAY
,status
),
904 cal1
->get(UCAL_MINUTE
,status
),
905 cal1
->get(UCAL_SECOND
,status
));
906 // Issue 2: Calendar continues to use the timezone in its
907 // constructor for set() conversions, regardless
908 // of calls to setTimeZone()
909 logln(UnicodeString("RGMT 3 is: ") + (t4
=cal3
->getTime(status
)));
913 errln("Fail: Calendar zone behavior faulty");
925 void CalendarRegressionTest::test4096539()
927 UErrorCode status
= U_ZERO_ERROR
;
928 int32_t y
[] = {31,28,31,30,31,30,31,31,30,31,30,31};
930 for (int32_t x
=0;x
<12;x
++) {
931 GregorianCalendar
*gc
= new
932 GregorianCalendar(1997,x
,y
[x
], status
);
933 if (U_FAILURE(status
)) {
934 dataerrln("Fail new GregorianCalendar: %s", u_errorName(status
));
939 log(UnicodeString("") + (m1
=gc
->get(UCAL_MONTH
,status
)+1)+UnicodeString("/")+
940 gc
->get(UCAL_DATE
,status
)+"/"+gc
->get(UCAL_YEAR
,status
)+
943 gc
->add(UCAL_MONTH
, 1,status
);
944 logln(UnicodeString("") + (m2
=gc
->get(UCAL_MONTH
,status
)+1)+UnicodeString("/")+
945 gc
->get(UCAL_DATE
,status
)+"/"+gc
->get(UCAL_YEAR
,status
)
947 int32_t m
= (m1
% 12) + 1;
949 errln(UnicodeString("Fail: Want ") + m
+ " Got " + m2
);
958 void CalendarRegressionTest::test41003112()
960 UErrorCode status
= U_ZERO_ERROR
;
961 GregorianCalendar
*cal
= (GregorianCalendar
*)Calendar::createInstance(status
);
962 if(U_FAILURE(status
)) {
963 dataerrln("Error creating calendar: %s", u_errorName(status
));
967 cal
->set(UCAL_YEAR
, 1997);
968 cal
->set(UCAL_DAY_OF_YEAR
, 1);
969 //UDate d = cal->getTime(status); // Should be Jan 1
970 //logln(d.toString());
971 if (cal
->get(UCAL_DAY_OF_YEAR
, status
) != 1)
972 errln("Fail: DAY_OF_YEAR not set");
979 void CalendarRegressionTest::test4103271()
981 UErrorCode status
= U_ZERO_ERROR
;
982 SimpleDateFormat
sdf(status
);
983 int32_t numYears
=40, startYear
=1997, numDays
=15;
984 UnicodeString output
, testDesc
, str
, str2
;
985 GregorianCalendar
*testCal
= (GregorianCalendar
*)Calendar::createInstance(status
);
986 if(U_FAILURE(status
)) {
987 dataerrln("Error creating calendar: %s", u_errorName(status
));
992 sdf
.adoptCalendar(testCal
);
993 sdf
.applyPattern("EEE dd MMM yyyy 'WOY'ww'-'YYYY 'DOY'DDD");
995 for (int32_t firstDay
=1; firstDay
<=2; firstDay
++) {
996 for (int32_t minDays
=1; minDays
<=7; minDays
++) {
997 testCal
->setMinimalDaysInFirstWeek((uint8_t)minDays
);
998 testCal
->setFirstDayOfWeek((UCalendarDaysOfWeek
)firstDay
);
999 testDesc
= (UnicodeString("Test") + firstDay
+ minDays
);
1000 logln(testDesc
+ " => 1st day of week=" +
1002 ", minimum days in first week=" +
1004 for (int32_t j
=startYear
; j
<=startYear
+numYears
; j
++) {
1005 testCal
->set(j
,11,25);
1006 for(int32_t i
=0; i
<numDays
; i
++) {
1007 testCal
->add(UCAL_DATE
,1,status
);
1008 UnicodeString calWOY
;
1009 int32_t actWOY
= testCal
->get(UCAL_WEEK_OF_YEAR
,status
);
1010 if (actWOY
< 1 || actWOY
> 53) {
1011 UDate d
= testCal
->getTime(status
);
1012 //calWOY = String.valueOf(actWOY);
1014 FieldPosition
pos(FieldPosition::DONT_CARE
);
1015 output
= testDesc
+ " - " + sdf
.format(d
,temp
,pos
) + "\t";
1016 output
= output
+ "\t" + actWOY
;
1026 3, 52, 52, 52, 52, 52, 52, 52,
1027 1, 1, 1, 1, 1, 1, 1,
1028 2, 2, 2, 2, 2, 2, 2,
1029 4, 52, 52, 52, 52, 52, 52, 52,
1030 53, 53, 53, 53, 53, 53, 53,
1031 1, 1, 1, 1, 1, 1, 1,
1033 testCal
->setFirstDayOfWeek(UCAL_SUNDAY
);
1034 for (int32_t j
=0; j
<44; j
+=22) {
1035 logln(UnicodeString("Minimal days in first week = ") + DATA
[j
] +
1036 " Week starts on Sunday");
1037 testCal
->setMinimalDaysInFirstWeek((uint8_t)DATA
[j
]);
1038 testCal
->set(1997, UCAL_DECEMBER
, 21);
1039 for (int32_t i
=0; i
<21; ++i
) {
1040 int32_t woy
= testCal
->get(UCAL_WEEK_OF_YEAR
,status
);
1042 log(UnicodeString("") + sdf
.format(testCal
->getTime(status
), str
) +
1043 UnicodeString(" ") + woy
);
1044 if (woy
!= DATA
[j
+ 1 + i
]) {
1050 // Now compute the time from the fields, and make sure we
1051 // get the same answer back. This is a round-trip test.
1052 UDate save
= testCal
->getTime(status
);
1054 testCal
->set(UCAL_YEAR_WOY
, DATA
[j
+1+i
] < 25 ? 1998 : 1997);
1055 testCal
->set(UCAL_WEEK_OF_YEAR
, DATA
[j
+1+i
]);
1056 testCal
->set(UCAL_DAY_OF_WEEK
, (i%7
) + UCAL_SUNDAY
);
1057 if (testCal
->getTime(status
) != save
) {
1059 logln(UnicodeString(" Parse failed: ") +
1060 sdf
.format(testCal
->getTime(status
), str
));
1064 testCal
->setTime(save
,status
);
1065 testCal
->add(UCAL_DATE
, 1,status
);
1068 // Test field disambiguation with a few special hard-coded cases.
1069 // This shouldn't fail if the above cases aren't failing.
1070 int32_t DISAM_int
[] = {
1072 1997, 1998, 1, UCAL_SUNDAY
,
1073 (1998), (1998), (2), (UCAL_SATURDAY
),
1074 (1998), (1998), (53), (UCAL_THURSDAY
),
1075 (1999), (1998), (53), (UCAL_FRIDAY
)
1078 UDate DISAM_date
[] = {
1079 makeDate(1997, UCAL_DECEMBER
, 28),
1080 makeDate(1998, UCAL_JANUARY
, 10),
1081 makeDate(1998, UCAL_DECEMBER
, 31),
1082 makeDate(1999, UCAL_JANUARY
, 1)
1085 testCal
->setMinimalDaysInFirstWeek(3);
1086 testCal
->setFirstDayOfWeek(UCAL_SUNDAY
);
1089 /* Enable this code to display various WOY values
1091 for (i=25; i<38; ++i) {
1092 testCal->set(1996, Calendar::DECEMBER, i);
1093 UDate got = testCal->getTime(status);
1095 logln(UnicodeString("") + sdf.format(got, str));
1097 for (i=25; i<38; ++i) {
1098 testCal->set(1997, Calendar::DECEMBER, i);
1099 UDate got = testCal->getTime(status);
1101 logln(UnicodeString("") + sdf.format(got, str));
1103 for (i=25; i<38; ++i) {
1104 testCal->set(1998, UCAL_DECEMBER, i);
1105 UDate got = testCal->getTime(status);
1107 logln(UnicodeString("") + sdf.format(got, str));
1111 for (i
=0; i
< 16; i
+= 4) {
1112 int32_t y
= DISAM_int
[i
];
1113 int32_t ywoy
= DISAM_int
[i
+1];
1114 int32_t woy
= DISAM_int
[i
+2];
1115 int32_t dow
= DISAM_int
[i
+3];
1116 UDate exp
= DISAM_date
[i
/4];
1118 testCal
->set(UCAL_YEAR
, y
);
1119 testCal
->set(UCAL_WEEK_OF_YEAR
, woy
);
1120 testCal
->set(UCAL_DAY_OF_WEEK
, dow
);
1121 UDate got
= testCal
->getTime(status
);
1124 log(UnicodeString("Y") + y
+ "-W" + woy
+
1125 "-DOW" + dow
+ " expect:" + sdf
.format(exp
, str
) +
1126 " got:" + sdf
.format(got
, str2
));
1128 log(" FAIL (%s:%d, i=%d)", __FILE__
, __LINE__
, i
);
1129 logln(CalendarTest::calToStr(*testCal
));
1130 testCal
->setTime(exp
, status
);
1131 logln(CalendarTest::calToStr(*testCal
) + UnicodeString( " <<< expected "));
1137 testCal
->set(UCAL_YEAR_WOY
, ywoy
);
1138 testCal
->set(UCAL_WEEK_OF_YEAR
, woy
);
1139 testCal
->set(UCAL_DAY_OF_WEEK
, dow
);
1140 got
= testCal
->getTime(status
);
1143 log(UnicodeString("YWOY") + ywoy
+ "-W" + woy
+
1144 "-DOW" + dow
+ " expect:" + sdf
.format(exp
, str
) +
1145 " got:" + sdf
.format(got
, str2
));
1152 // Now try adding and rolling
1153 UDate ADDROLL_date
[] = {
1154 makeDate(1998, UCAL_DECEMBER
, 25), makeDate(1999, UCAL_JANUARY
, 1),
1155 makeDate(1997, UCAL_DECEMBER
, 28), makeDate(1998, UCAL_JANUARY
, 4),
1156 makeDate(1998, UCAL_DECEMBER
, 27), makeDate(1997, UCAL_DECEMBER
, 28),
1157 makeDate(1999, UCAL_JANUARY
, 2), makeDate(1998, UCAL_JANUARY
, 3),
1160 int32_t ADDROLL_int
[]= {
1168 UBool ADDROLL_bool
[] = {
1175 testCal
->setMinimalDaysInFirstWeek(3);
1176 testCal
->setFirstDayOfWeek(UCAL_SUNDAY
);
1177 for (i
=0; i
<8; i
+= 2) {
1178 int32_t amount
= ADDROLL_int
[i
/2];
1179 UDate before
= ADDROLL_date
[i
];
1180 UDate after
= ADDROLL_date
[i
+1];
1182 testCal
->setTime(before
,status
);
1183 if (ADDROLL_bool
[i
/2])
1184 testCal
->add(UCAL_WEEK_OF_YEAR
, amount
,status
);
1186 testCal
->roll(UCAL_WEEK_OF_YEAR
, amount
,status
);
1187 UDate got
= testCal
->getTime(status
);
1190 UnicodeString opTypeStr
;
1191 if (ADDROLL_bool
[i
/2]) {
1192 opTypeStr
= UnicodeString("add(WOY,", "");
1194 opTypeStr
= UnicodeString("roll(WOY,", "");
1196 log(opTypeStr
+ amount
+ ") " + sdf
.format(before
, str
) + " => " +
1197 sdf
.format(got
, str2
));
1200 logln(UnicodeString(" exp:") + sdf
.format(after
, str
) + " FAIL");
1205 testCal
->setTime(after
,status
);
1206 if (ADDROLL_bool
[i
/2])
1207 testCal
->add(UCAL_WEEK_OF_YEAR
, -amount
,status
);
1209 testCal
->roll(UCAL_WEEK_OF_YEAR
, -amount
,status
);
1210 got
= testCal
->getTime(status
);
1213 log(opTypeStr
+ (-amount
) + ") " + sdf
.format(after
, str
) + " => " +
1214 sdf
.format(got
, str2
));
1215 if (before
!= got
) {
1217 logln(UnicodeString(" exp:") + sdf
.format(before
, str
) + " FAIL");
1223 errln("Fail: Week of year misbehaving");
1229 void CalendarRegressionTest::test4106136()
1231 UErrorCode status
= U_ZERO_ERROR
;
1232 Locale saveLocale
= Locale::getDefault();
1234 Locale locales
[] = { Locale::getChinese(), Locale::getChina() };
1235 for (int32_t i
=0; i
<2; ++i
) {
1236 Locale::setDefault(locales
[i
], status
);
1237 failure(status
, "Locale::setDefault");
1238 int32_t count1
, count2
, count3
;
1239 Calendar::getAvailableLocales(count1
);
1240 DateFormat::getAvailableLocales(count2
);
1241 NumberFormat::getAvailableLocales(count3
);
1243 count1
, count2
, count3
1245 for (int32_t j
=0; j
<3; ++j
) {
1248 dataerrln(UnicodeString("Fail: No locales for ") + locales
[i
].getName());
1253 Locale::setDefault(saveLocale
,status
);
1260 void CalendarRegressionTest::test4108764()
1262 UErrorCode status
= U_ZERO_ERROR
;
1263 Calendar
*cal
= Calendar::createInstance(status
);
1264 if(U_FAILURE(status
)) {
1265 dataerrln("Error creating calendar %s", u_errorName(status
));
1269 UDate d00
= makeDate(1997, UCAL_MARCH
, 15, 12, 00, 00);
1270 UDate d01
= makeDate(1997, UCAL_MARCH
, 15, 12, 00, 56);
1271 UDate d10
= makeDate(1997, UCAL_MARCH
, 15, 12, 34, 00);
1272 UDate d11
= makeDate(1997, UCAL_MARCH
, 15, 12, 34, 56);
1273 UDate epoch
= makeDate(1970, UCAL_JANUARY
, 1);
1275 cal
->setTime(d11
,status
);
1277 cal
->clear( UCAL_MINUTE
);
1278 logln(UnicodeString("") + cal
->getTime(status
));
1279 if (cal
->getTime(status
) != d01
)
1280 errln("Fail: clear(MINUTE) broken");
1282 cal
->set( UCAL_SECOND
, 0 );
1283 logln(UnicodeString("") + cal
->getTime(status
));
1284 if (cal
->getTime(status
) != d00
)
1285 errln("Fail: set(SECOND, 0) broken");
1287 cal
->setTime(d11
,status
);
1288 cal
->set( UCAL_SECOND
, 0 );
1289 logln(UnicodeString("") + cal
->getTime(status
));
1290 if (cal
->getTime(status
) != d10
)
1291 errln("Fail: set(SECOND, 0) broken #2");
1293 cal
->clear( UCAL_MINUTE
);
1294 logln(UnicodeString("") + cal
->getTime(status
));
1295 if (cal
->getTime(status
) != d00
)
1296 errln("Fail: clear(MINUTE) broken #2");
1299 logln(UnicodeString("") + cal
->getTime(status
));
1300 if (cal
->getTime(status
) != epoch
)
1301 errln(UnicodeString("Fail: clear() broken Want ") + epoch
);
1309 void CalendarRegressionTest::test4114578()
1311 UErrorCode status
= U_ZERO_ERROR
;
1312 double ONE_HOUR
= 60*60*1000;
1313 Calendar
*cal
= Calendar::createInstance(status
);
1314 if(U_FAILURE(status
)) {
1315 dataerrln("Error creating calendar %s", u_errorName(status
));
1319 cal
->adoptTimeZone(TimeZone::createTimeZone("PST"));
1320 UDate onset
= makeDate(1998, UCAL_APRIL
, 5, 1, 0) + ONE_HOUR
;
1321 UDate cease
= makeDate(1998, UCAL_OCTOBER
, 25, 0, 0) + 2*ONE_HOUR
;
1325 const int32_t ADD
= 1;
1326 const int32_t ROLL
= 2;
1329 // Start Action Amt Expected_change
1330 onset
- ONE_HOUR
, ADD
, 1, ONE_HOUR
,
1331 onset
, ADD
, -1, -ONE_HOUR
,
1332 onset
- ONE_HOUR
, ROLL
, 1, ONE_HOUR
,
1333 onset
, ROLL
, -1, -ONE_HOUR
,
1334 cease
- ONE_HOUR
, ADD
, 1, ONE_HOUR
,
1335 cease
, ADD
, -1, -ONE_HOUR
,
1336 cease
- ONE_HOUR
, ROLL
, 1, ONE_HOUR
,
1337 cease
, ROLL
, -1, -ONE_HOUR
,
1340 for (int32_t i
=0; i
<32; i
+=4) {
1341 UDate date
= DATA
[i
];
1342 int32_t amt
= (int32_t) DATA
[i
+2];
1343 double expectedChange
= DATA
[i
+3];
1345 log(UnicodeString("") + date
);
1346 cal
->setTime(date
,status
);
1348 switch ((int32_t) DATA
[i
+1]) {
1350 log(UnicodeString(" add (HOUR,") + (amt
<0?"":"+")+amt
+ ")= ");
1351 cal
->add(UCAL_HOUR
, amt
,status
);
1354 log(UnicodeString(" roll(HOUR,") + (amt
<0?"":"+")+amt
+ ")= ");
1355 cal
->roll(UCAL_HOUR
, amt
,status
);
1359 log(UnicodeString("") + cal
->getTime(status
));
1361 double change
= cal
->getTime(status
) - date
;
1362 if (change
!= expectedChange
) {
1369 if (fail
) errln("Fail: roll/add misbehaves around DST onset/cease");
1376 * Make sure maximum for HOUR field is 11, not 12.
1378 void CalendarRegressionTest::test4118384()
1380 UErrorCode status
= U_ZERO_ERROR
;
1381 Calendar
*cal
= Calendar::createInstance(status
);
1382 if(U_FAILURE(status
)) {
1383 dataerrln("Error creating calendar %s", u_errorName(status
));
1387 if (cal
->getMaximum(UCAL_HOUR
) != 11 ||
1388 cal
->getLeastMaximum(UCAL_HOUR
) != 11 ||
1389 cal
->getActualMaximum(UCAL_HOUR
,status
) != 11)
1390 errln("Fail: maximum of HOUR field should be 11");
1392 // test deprecated functions
1393 if (cal
->getLeastMaximum(Calendar::HOUR
) != 11 ||
1394 cal
->getMaximum(Calendar::HOUR
) != 11) {
1395 errln("Fail: [deprecated functions] maximum of HOUR field should be 11\n");
1398 if (cal
->getGreatestMinimum(Calendar::HOUR
) != 0 ||
1399 cal
->getMinimum(Calendar::HOUR
) != 0) {
1400 errln("Fail: [deprecated functions] minimum of HOUR field should be 1\n");
1404 cal
= Calendar::createInstance(Locale("th_TH@calendar=buddhist"),status
);
1405 // test deprecated functions
1406 if (cal
->getLeastMaximum(Calendar::HOUR
) != 11 ||
1407 cal
->getMaximum(Calendar::HOUR
) != 11) {
1408 errln("Fail: Buddhist:[deprecated functions] maximum of HOUR field should be 11\n");
1411 if (cal
->getGreatestMinimum(Calendar::HOUR
) != 0 ||
1412 cal
->getMinimum(Calendar::HOUR
) != 0) {
1413 errln("Fail: Buddhist:[deprecated functions] minimum of HOUR field should be 1\n");
1417 // test deprecated functions
1418 cal
= Calendar::createInstance(Locale("ja_JP@calendar=japanese"),status
);
1419 if (cal
->getLeastMaximum(Calendar::HOUR
) != 11 ||
1420 cal
->getMaximum(Calendar::HOUR
) != 11) {
1421 errln("Fail: Japanese:[deprecated functions] maximum of HOUR field should be 11\n");
1424 if (cal
->getGreatestMinimum(Calendar::HOUR
) != 0 ||
1425 cal
->getMinimum(Calendar::HOUR
) != 0) {
1426 errln("Fail: Japanese:[deprecated functions] minimum of HOUR field should be 1\n");
1434 * Check isLeapYear for BC years.
1436 void CalendarRegressionTest::test4125881()
1438 UErrorCode status
= U_ZERO_ERROR
;
1439 GregorianCalendar
*cal
= (GregorianCalendar
*) Calendar::createInstance(status
);
1440 if(U_FAILURE(status
)) {
1441 dataerrln("Error creating calendar %s", u_errorName(status
));
1445 DateFormat
*fmt
= new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"),status
);
1446 if(U_FAILURE(status
)) {
1447 dataerrln("Error creating SimpleDateFormat - %s", u_errorName(status
));
1452 for (int32_t y
=-20; y
<=10; ++y
) {
1453 cal
->set(UCAL_ERA
, y
< 1 ? GregorianCalendar::BC
: GregorianCalendar::AD
);
1454 cal
->set(UCAL_YEAR
, y
< 1 ? 1 - y
: y
);
1456 logln(UnicodeString("") + y
+ UnicodeString(" = ") + fmt
->format(cal
->getTime(status
), temp
) + " " +
1457 cal
->isLeapYear(y
));
1458 if (cal
->isLeapYear(y
) != ((y
+40)%4
== 0))
1459 errln("Leap years broken");
1468 * Prove that GregorianCalendar is proleptic (it used to cut off
1469 * at 45 BC, and not have leap years before then).
1471 void CalendarRegressionTest::test4125892() {
1472 UErrorCode status
= U_ZERO_ERROR
;
1473 GregorianCalendar
*cal
= (GregorianCalendar
*) Calendar::createInstance(status
);
1474 if(U_FAILURE(status
)) {
1475 dataerrln("Error creating calendar %s", u_errorName(status
));
1479 DateFormat
*fmt
= new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"),status
);
1480 if(U_FAILURE(status
)) {
1481 dataerrln("Error creating SimpleDateFormat - %s", u_errorName(status
));
1486 cal
->set(UCAL_ERA
, GregorianCalendar::BC
);
1487 cal
->set(UCAL_YEAR
, 81); // 81 BC is a leap year (proleptically)
1488 cal
->set(UCAL_MONTH
, UCAL_FEBRUARY
);
1489 cal
->set(UCAL_DATE
, 28);
1490 cal
->add(UCAL_DATE
, 1,status
);
1491 if(U_FAILURE(status
))
1492 errln("add(DATE,1) failed");
1493 if (cal
->get(UCAL_DATE
,status
) != 29 ||
1494 !cal
->isLeapYear(-80)) // -80 == 81 BC
1495 errln("Calendar not proleptic");
1503 * GregorianCalendar::equals() ignores cutover date
1505 void CalendarRegressionTest::test4141665()
1507 UErrorCode status
= U_ZERO_ERROR
;
1508 GregorianCalendar
*cal
= new GregorianCalendar(status
);
1509 if(U_FAILURE(status
)) {
1510 dataerrln("Error creating calendar %s", u_errorName(status
));
1514 GregorianCalendar
*cal2
= (GregorianCalendar
*)cal
->clone();
1515 UDate cut
= cal
->getGregorianChange();
1516 UDate cut2
= cut
+ 100*24*60*60*1000.0; // 100 days later
1517 if (*cal
!= *cal2
) {
1518 errln("Cloned GregorianCalendars not equal");
1520 cal2
->setGregorianChange(cut2
,status
);
1521 if ( *cal
== *cal2
) {
1522 errln("GregorianCalendar::equals() ignores cutover");
1531 * Bug states that ArrayIndexOutOfBoundsException is thrown by GregorianCalendar::roll()
1532 * when IllegalArgumentException should be.
1534 void CalendarRegressionTest::test4142933()
1536 UErrorCode status
= U_ZERO_ERROR
;
1537 GregorianCalendar
*calendar
= new GregorianCalendar(status
);
1538 if(U_FAILURE(status
)) {
1539 dataerrln("Error creating calendar %s", u_errorName(status
));
1544 calendar
->roll((UCalendarDateFields
)-1, TRUE
, status
);
1545 if(U_SUCCESS(status
))
1546 errln("Test failed, no exception thrown");
1548 //catch (IllegalArgumentException e) {
1550 // logln("Test passed");
1552 //catch (Exception e) {
1553 //errln("Test failed. Unexpected exception is thrown: " + e);
1554 //e.printStackTrace();
1562 * GregorianCalendar handling of Dates Long.MIN_VALUE and Long.MAX_VALUE is
1563 * confusing; unless the time zone has a raw offset of zero, one or the
1564 * other of these will wrap. We've modified the test given in the bug
1565 * report to therefore only check the behavior of a calendar with a zero raw
1568 void CalendarRegressionTest::test4145158()
1570 UErrorCode status
= U_ZERO_ERROR
;
1571 GregorianCalendar
*calendar
= new GregorianCalendar(status
);
1572 if(status
== U_USING_FALLBACK_WARNING
|| U_FAILURE(status
)) {
1573 dataerrln("Error creating calendar %s", u_errorName(status
));
1578 calendar
->adoptTimeZone(TimeZone::createTimeZone("GMT"));
1580 calendar
->setTime(makeDate(INT32_MIN
),status
);
1581 int32_t year1
= calendar
->get(UCAL_YEAR
,status
);
1582 int32_t era1
= calendar
->get(UCAL_ERA
,status
);
1584 calendar
->setTime(makeDate(INT32_MAX
),status
);
1585 int32_t year2
= calendar
->get(UCAL_YEAR
,status
);
1586 int32_t era2
= calendar
->get(UCAL_ERA
,status
);
1588 if (year1
== year2
&& era1
== era2
) {
1589 errln("Fail: Long.MIN_VALUE or Long.MAX_VALUE wrapping around");
1597 * Maximum value for YEAR field wrong.
1599 // {sfb} this is not directly applicable in C++, since all
1600 // possible doubles are not representable by our Calendar.
1601 // In Java, all longs are representable.
1602 // We can determine limits programmatically
1603 // Using DBL_MAX is a bit of a hack, since for large doubles
1604 // Calendar gets squirrely and doesn't behave in any sort
1605 // of linear fashion (ie years jump around, up/down, etc) for a
1606 // small change in millis.
1607 void CalendarRegressionTest::test4145983()
1609 UErrorCode status
= U_ZERO_ERROR
;
1610 GregorianCalendar
*calendar
= new GregorianCalendar(status
);
1611 if(U_FAILURE(status
)) {
1612 dataerrln("Error creating calendar %s", u_errorName(status
));
1616 calendar
->adoptTimeZone(TimeZone::createTimeZone("GMT"));
1617 UDate DATES
[] = { LATEST_SUPPORTED_MILLIS
, EARLIEST_SUPPORTED_MILLIS
};
1618 for (int32_t i
=0; i
<2; ++i
) {
1619 calendar
->setTime(DATES
[i
], status
);
1620 int32_t year
= calendar
->get(UCAL_YEAR
,status
);
1621 int32_t maxYear
= calendar
->getMaximum(UCAL_YEAR
);
1622 if (year
> maxYear
) {
1623 errln(UnicodeString("Failed for ")+DATES
[i
]+" ms: year=" +
1624 year
+ ", maxYear=" + maxYear
);
1633 * This is a bug in the validation code of GregorianCalendar:: As reported,
1634 * the bug seems worse than it really is, due to a bug in the way the bug
1635 * report test was written. In reality the bug is restricted to the DAY_OF_YEAR
1636 * field. - liu 6/29/98
1638 void CalendarRegressionTest::test4147269()
1640 UErrorCode status
= U_ZERO_ERROR
;
1641 GregorianCalendar
*calendar
= new GregorianCalendar(status
);
1642 if(status
== U_USING_FALLBACK_WARNING
|| U_FAILURE(status
)) {
1643 dataerrln("Error creating calendar %s", u_errorName(status
));
1647 calendar
->setLenient(FALSE
);
1648 UDate date
= makeDate(1996, UCAL_JANUARY
, 3); // Arbitrary date
1649 for (int32_t field
= 0; field
< UCAL_FIELD_COUNT
; field
++) {
1650 calendar
->setTime(date
,status
);
1651 // Note: In the bug report, getActualMaximum() was called instead
1652 // of getMaximum() -- this was an error. The validation code doesn't
1653 // use getActualMaximum(), since that's too costly.
1654 int32_t max
= calendar
->getMaximum((UCalendarDateFields
)field
);
1655 int32_t value
= max
+1;
1656 calendar
->set((UCalendarDateFields
)field
, value
);
1658 calendar
->getTime(status
); // Force time computation
1659 // We expect an exception to be thrown. If we fall through
1660 // to the next line, then we have a bug.
1661 if(U_SUCCESS(status
))
1662 errln(UnicodeString("Test failed with field ") + FIELD_NAME
[field
] +
1663 ", date before: " + date
+
1664 ", date after: " + calendar
->getTime(status
) +
1665 ", value: " + value
+ " (max = " + max
+")");
1666 //} catch (IllegalArgumentException e) {}
1674 * Reported bug is that a GregorianCalendar with a cutover of Date(Long.MAX_VALUE)
1675 * doesn't behave as a pure Julian calendar.
1676 * CANNOT REPRODUCE THIS BUG
1679 CalendarRegressionTest::Test4149677()
1681 UErrorCode status
= U_ZERO_ERROR
;
1683 TimeZone
*zones
[] = {
1684 TimeZone::createTimeZone("GMT"),
1685 TimeZone::createTimeZone("PST"),
1686 TimeZone::createTimeZone("EAT")
1688 if(U_FAILURE(status
)) {
1689 errln("Couldn't create zones");
1691 // could leak memory
1694 for (int32_t i
=0; i
< 3; ++i
) {
1695 GregorianCalendar
*calendar
= new GregorianCalendar(zones
[i
], status
);
1696 if(U_FAILURE(status
)) {
1697 dataerrln("Couldnt' create calendar.: %s", u_errorName(status
));
1701 // Make sure extreme values don't wrap around
1702 calendar
->setTime(EARLIEST_SUPPORTED_MILLIS
, status
);
1703 if(U_FAILURE(status
))
1704 errln("setTime failed");
1705 if (calendar
->get(UCAL_ERA
, status
) != GregorianCalendar::BC
|| U_FAILURE(status
)) {
1706 errln("Fail: Date(EARLIEST_SUPPORTED_MILLIS) has an AD year");
1708 calendar
->setTime(LATEST_SUPPORTED_MILLIS
, status
);
1709 if(U_FAILURE(status
))
1710 errln("setTime failed");
1711 if (calendar
->get(UCAL_ERA
, status
) != GregorianCalendar::AD
|| U_FAILURE(status
)) {
1712 errln("Fail: Date(LATEST_SUPPORTED_MILLIS) has a BC year");
1715 calendar
->setGregorianChange(LATEST_SUPPORTED_MILLIS
, status
);
1716 if(U_FAILURE(status
))
1717 errln("setGregorianChange failed");
1718 // to obtain a pure Julian calendar
1720 UBool is100Leap
= calendar
->isLeapYear(100);
1723 errln("test failed with zone " + zones
[i
]->getID(temp
));
1724 errln(" cutover date is Date(Long.MAX_VALUE)");
1725 errln(UnicodeString(" isLeapYear(100) returns: ") + is100Leap
);
1730 // no need for cleanup- zones were adopted
1735 * Calendar and Date HOUR broken. If HOUR is out-of-range, Calendar
1736 * and Date classes will misbehave.
1739 CalendarRegressionTest::Test4162587()
1741 UErrorCode status
= U_ZERO_ERROR
;
1742 TimeZone
*savedef
= TimeZone::createDefault();
1743 TimeZone
*tz
= TimeZone::createTimeZone("PST");
1744 //TimeZone::adoptDefault(tz);
1745 TimeZone::setDefault(*tz
);
1747 GregorianCalendar
*cal
= new GregorianCalendar(tz
, status
);
1748 if(U_FAILURE(status
)) {
1749 dataerrln("Couldn't create calendar.: %s", u_errorName(status
));
1752 UDate d0
, dPlus
, dMinus
;
1754 for(int32_t i
=0; i
<5; ++i
) {
1755 if (i
>0) logln("---");
1758 cal
->set(1998, UCAL_APRIL
, 5, i
, 0);
1759 d0
= cal
->getTime(status
);
1760 if(U_FAILURE(status
))
1761 errln("Coudln't get time (1)");
1762 //String s0 = d.toString();
1763 logln(UnicodeString("0 ") + i
+ ": " + d0
/*s0*/);
1766 cal
->set(1998, UCAL_APRIL
, 4, i
+24, 0);
1767 dPlus
= cal
->getTime(status
);
1768 if(U_FAILURE(status
))
1769 errln("Coudln't get time (2)");
1770 //String sPlus = d.toString();
1771 logln(UnicodeString("+ ") + i
+ ": " + dPlus
/*sPlus*/);
1774 cal
->set(1998, UCAL_APRIL
, 6, i
-24, 0);
1775 dMinus
= cal
->getTime(status
);
1776 if(U_FAILURE(status
))
1777 errln("Coudln't get time (3)");
1778 //String sMinus = d.toString();
1779 logln(UnicodeString("- ") + i
+ ": " + dMinus
/*sMinus*/);
1781 if (d0
!= dPlus
|| d0
!= dMinus
) {
1782 errln("Fail: All three lines must match");
1785 TimeZone::setDefault(*savedef
);
1793 * Adding 12 months behaves differently from adding 1 year
1796 CalendarRegressionTest::Test4165343()
1798 UErrorCode status
= U_ZERO_ERROR
;
1799 GregorianCalendar
*calendar
= new GregorianCalendar(1996, UCAL_FEBRUARY
, 29, status
);
1800 if(U_FAILURE(status
)) {
1801 dataerrln("Couldn't create calendar.: %s", u_errorName(status
));
1804 UDate start
= calendar
->getTime(status
);
1805 if(U_FAILURE(status
))
1806 errln("Couldn't getTime (1)");
1807 logln(UnicodeString("init date: ") + start
);
1808 calendar
->add(UCAL_MONTH
, 12, status
);
1809 if(U_FAILURE(status
))
1810 errln("Couldn't add(MONTH, 12)");
1811 UDate date1
= calendar
->getTime(status
);
1812 if(U_FAILURE(status
))
1813 errln("Couldn't getTime (2)");
1814 logln(UnicodeString("after adding 12 months: ") + date1
);
1815 calendar
->setTime(start
, status
);
1816 if(U_FAILURE(status
))
1817 errln("Couldn't setTime");
1818 calendar
->add(UCAL_YEAR
, 1, status
);
1819 if(U_FAILURE(status
))
1820 errln("Couldn't add(YEAR, 1)");
1821 UDate date2
= calendar
->getTime(status
);
1822 if(U_FAILURE(status
))
1823 errln("Couldn't getTime (3)");
1824 logln(UnicodeString("after adding one year : ") + date2
);
1825 if (date1
== date2
) {
1826 logln("Test passed");
1828 errln("Test failed");
1835 * GregorianCalendar.getActualMaximum() does not account for first day of week.
1838 CalendarRegressionTest::Test4166109()
1843 * Su Mo Tu We Th Fr Sa
1845 * 8 9 10 11 12 13 14
1846 * 15 16 17 18 19 20 21
1847 * 22 23 24 25 26 27 28
1850 UBool passed
= TRUE
;
1851 UErrorCode status
= U_ZERO_ERROR
;
1852 UCalendarDateFields field
= UCAL_WEEK_OF_MONTH
;
1854 GregorianCalendar
*calendar
= new GregorianCalendar(Locale::getUS(), status
);
1855 if(U_FAILURE(status
)) {
1856 dataerrln("Couldn't create calendar.: %s", u_errorName(status
));
1859 calendar
->set(1998, UCAL_MARCH
, 1);
1860 calendar
->setMinimalDaysInFirstWeek(1);
1861 logln(UnicodeString("Date: ") + calendar
->getTime(status
)); // 888817448000
1863 int32_t firstInMonth
= calendar
->get(UCAL_DATE
, status
);
1864 if(U_FAILURE(status
))
1865 errln("get(D_O_M) failed");
1867 for(int32_t firstInWeek
= UCAL_SUNDAY
; firstInWeek
<= UCAL_SATURDAY
; firstInWeek
++) {
1868 calendar
->setFirstDayOfWeek((UCalendarDaysOfWeek
)firstInWeek
);
1869 int32_t returned
= calendar
->getActualMaximum(field
, status
);
1870 int32_t expected
= (31 + ((firstInMonth
- firstInWeek
+ 7)% 7) + 6) / 7;
1872 logln(UnicodeString("First day of week = ") + firstInWeek
+
1873 " getActualMaximum(WEEK_OF_MONTH, status) = " + returned
+
1874 " expected = " + expected
+
1875 ((returned
== expected
) ? " ok" : " FAIL"));
1877 if (returned
!= expected
) {
1882 errln("Test failed");
1890 * Calendar.getActualMaximum(YEAR) works wrong.
1893 CalendarRegressionTest::Test4167060()
1895 UErrorCode status
= U_ZERO_ERROR
;
1896 UCalendarDateFields field
= UCAL_YEAR
;
1897 DateFormat
*format
= new SimpleDateFormat(UnicodeString("EEE MMM dd HH:mm:ss zzz yyyy G"),
1898 Locale::getUS(), status
);
1899 if(U_FAILURE(status
)) {
1900 dataerrln("Couldn't create SimpleDateFormat - %s", u_errorName(status
));
1904 GregorianCalendar
*calendars
[] = {
1905 new GregorianCalendar(100, UCAL_NOVEMBER
, 1, status
),
1906 new GregorianCalendar(-99 /*100BC*/, UCAL_JANUARY
, 1, status
),
1907 new GregorianCalendar(1996, UCAL_FEBRUARY
, 29, status
),
1909 if(U_FAILURE(status
)) {
1910 errln("Couldn't create GregorianCalendars");
1915 UnicodeString id
[] = { "Hybrid", "Gregorian", "Julian" };
1917 for (int32_t k
=0; k
<3; ++k
) {
1918 logln("--- " + id
[k
] + " ---");
1920 for (int32_t j
=0; j
< 3; ++j
) {
1921 GregorianCalendar
*calendar
= calendars
[j
];
1923 calendar
->setGregorianChange(EARLIEST_SUPPORTED_MILLIS
, status
);
1926 calendar
->setGregorianChange(LATEST_SUPPORTED_MILLIS
, status
);
1929 if(U_FAILURE(status
))
1930 errln("setGregorianChange() failed");
1931 format
->adoptCalendar((Calendar
*)calendar
->clone());
1933 UDate dateBefore
= calendar
->getTime(status
);
1934 if(U_FAILURE(status
))
1935 errln("getTime() failed");
1937 int32_t maxYear
= calendar
->getActualMaximum(field
, status
);
1939 logln(UnicodeString("maxYear: ") + maxYear
+ " for " + format
->format(calendar
->getTime(status
), temp
));
1941 logln("date before: " + format
->format(dateBefore
, temp
));
1943 int32_t years
[] = {2000, maxYear
-1, maxYear
, maxYear
+1};
1945 for (int32_t i
= 0; i
< 4; i
++) {
1946 UBool valid
= years
[i
] <= maxYear
;
1947 calendar
->set(field
, years
[i
]);
1948 UDate dateAfter
= calendar
->getTime(status
);
1949 if(U_FAILURE(status
))
1950 errln("getTime() failed");
1951 int32_t newYear
= calendar
->get(field
, status
);
1952 if(U_FAILURE(status
))
1953 errln(UnicodeString("get(") + (int32_t)field
+ ") failed");
1954 calendar
->setTime(dateBefore
, status
); // restore calendar for next use
1955 if(U_FAILURE(status
))
1956 errln("setTime() failed");
1959 logln(UnicodeString(" Year ") + years
[i
] + (valid
? " ok " : " bad") +
1960 " => " + format
->format(dateAfter
, temp
));
1961 if (valid
&& newYear
!= years
[i
]) {
1962 errln(UnicodeString(" FAIL: ") + newYear
+ " should be valid; date, month and time shouldn't change");
1964 // {sfb} this next line is a hack, but it should work since if a
1965 // double has an exponent, adding 1 should not yield the same double
1966 else if (!valid
&& /*newYear == years[i]*/ dateAfter
+ 1.0 == dateAfter
) {
1967 errln(UnicodeString(" FAIL: ") + newYear
+ " should be invalid");
1974 delete calendars
[0];
1975 delete calendars
[1];
1976 delete calendars
[2];
1980 * Week of year is wrong at the start and end of the year.
1982 void CalendarRegressionTest::Test4197699() {
1983 UErrorCode status
= U_ZERO_ERROR
;
1984 GregorianCalendar
cal(status
);
1985 cal
.setFirstDayOfWeek(UCAL_MONDAY
);
1986 cal
.setMinimalDaysInFirstWeek(4);
1987 SimpleDateFormat
fmt("E dd MMM yyyy 'DOY='D 'WOY='w",
1988 Locale::getUS(), status
);
1989 fmt
.setCalendar(cal
);
1990 if (U_FAILURE(status
)) {
1991 dataerrln("Couldn't initialize test - %s", u_errorName(status
));
1996 2000, UCAL_JANUARY
, 1, 52,
1997 2001, UCAL_DECEMBER
, 31, 1,
1999 int32_t DATA_length
= (int32_t)(sizeof(DATA
) / sizeof(DATA
[0]));
2002 DateFormat
& dfmt
= *(DateFormat
*)&fmt
;
2003 for (int32_t i
=0; i
<DATA_length
; ) {
2005 cal
.set(DATA
[i
], DATA
[i
+1], DATA
[i
+2]);
2007 int32_t expWOY
= DATA
[i
++];
2008 int32_t actWOY
= cal
.get(UCAL_WEEK_OF_YEAR
, status
);
2009 if (expWOY
== actWOY
) {
2010 logln(UnicodeString("Ok: ") + dfmt
.format(cal
.getTime(status
), str
.remove()));
2012 errln(UnicodeString("FAIL: ") + dfmt
.format(cal
.getTime(status
), str
.remove())
2013 + ", expected WOY=" + expWOY
);
2014 cal
.add(UCAL_DATE
, -8, status
);
2015 for (int j
=0; j
<14; ++j
) {
2016 cal
.add(UCAL_DATE
, 1, status
);
2017 logln(dfmt
.format(cal
.getTime(status
), str
.remove()));
2020 if (U_FAILURE(status
)) {
2021 errln("FAIL: Unexpected error from Calendar");
2027 enum Action
{ ADD
=1, ROLL
=2 };
2028 enum Sign
{ PLUS
=1, MINUS
=2 };
2030 #define ONE_HOUR (60*60*1000)
2031 #define ONE_DAY (24*ONE_HOUR)
2034 UCalendarDateFields field
;
2035 int8_t actionMask
; // ADD or ROLL or both
2036 int8_t signMask
; // PLUS or MINUS or both
2038 int32_t before
; // ms before cutover
2039 int32_t after
; // ms after cutover
2043 * Rolling and adding across the Gregorian cutover should work as expected.
2046 void CalendarRegressionTest::TestJ81() {
2047 UErrorCode status
= U_ZERO_ERROR
;
2048 UnicodeString temp
, temp2
, temp3
;
2050 GregorianCalendar
cal(TimeZone::createTimeZone("GMT"), Locale::getUS(), status
);
2051 SimpleDateFormat
fmt("HH:mm 'w'w 'd'D E d MMM yyyy", Locale::getUS(), status
);
2052 if (U_FAILURE(status
)) {
2053 dataerrln("Error: Cannot create calendar or format - %s", u_errorName(status
));
2056 fmt
.setCalendar(cal
);
2057 // Get the Gregorian cutover
2058 UDate cutover
= cal
.getGregorianChange();
2059 UDate days
= ONE_DAY
;
2060 days
= cutover
/days
;
2061 logln(UnicodeString("Cutover: {") +
2062 fmt
.format(cutover
, temp
) + "}(epoch days-" + (int)days
+ ", jd" + (2440588 + days
) +")");
2064 // Check woy and doy handling. Reference data:
2065 /* w40 d274 Mon 1 Oct 1582
2066 w40 d275 Tue 2 Oct 1582
2067 w40 d276 Wed 3 Oct 1582
2068 w40 d277 Thu 4 Oct 1582
2069 w40 d278 Fri 15 Oct 1582
2070 w40 d279 Sat 16 Oct 1582
2071 w41 d280 Sun 17 Oct 1582
2072 w41 d281 Mon 18 Oct 1582
2073 w41 d282 Tue 19 Oct 1582
2074 w41 d283 Wed 20 Oct 1582
2075 w41 d284 Thu 21 Oct 1582
2076 w41 d285 Fri 22 Oct 1582
2077 w41 d286 Sat 23 Oct 1582
2078 w42 d287 Sun 24 Oct 1582
2079 w42 d288 Mon 25 Oct 1582
2080 w42 d289 Tue 26 Oct 1582
2081 w42 d290 Wed 27 Oct 1582
2082 w42 d291 Thu 28 Oct 1582
2083 w42 d292 Fri 29 Oct 1582
2084 w42 d293 Sat 30 Oct 1582
2085 w43 d294 Sun 31 Oct 1582
2086 w43 d295 Mon 1 Nov 1582 */
2087 int32_t DOY_DATA
[] = {
2089 1, 40, 274, UCAL_MONDAY
,
2090 4, 40, 277, UCAL_THURSDAY
,
2091 15, 40, 278, UCAL_FRIDAY
,
2092 17, 41, 280, UCAL_SUNDAY
,
2093 24, 42, 287, UCAL_SUNDAY
,
2094 25, 42, 288, UCAL_MONDAY
,
2095 26, 42, 289, UCAL_TUESDAY
,
2096 27, 42, 290, UCAL_WEDNESDAY
,
2097 28, 42, 291, UCAL_THURSDAY
,
2098 29, 42, 292, UCAL_FRIDAY
,
2099 30, 42, 293, UCAL_SATURDAY
,
2100 31, 43, 294, UCAL_SUNDAY
2102 int32_t DOY_DATA_length
= (int32_t)(sizeof(DOY_DATA
) / sizeof(DOY_DATA
[0]));
2104 for (i
=0; i
<DOY_DATA_length
; i
+=4) {
2105 // Test time->fields
2106 cal
.set(1582, UCAL_OCTOBER
, DOY_DATA
[i
]);
2107 int32_t woy
= cal
.get(UCAL_WEEK_OF_YEAR
, status
);
2108 int32_t doy
= cal
.get(UCAL_DAY_OF_YEAR
, status
);
2109 int32_t dow
= cal
.get(UCAL_DAY_OF_WEEK
, status
);
2110 if (U_FAILURE(status
)) {
2111 errln("Error: get() failed");
2114 if (woy
!= DOY_DATA
[i
+1] || doy
!= DOY_DATA
[i
+2] || dow
!= DOY_DATA
[i
+3]) {
2115 errln((UnicodeString
)"Fail: expect woy=" + DOY_DATA
[i
+1] +
2116 ", doy=" + DOY_DATA
[i
+2] + ", dow=" + DOY_DATA
[i
+3] + " on " +
2117 fmt
.format(cal
.getTime(status
), temp
.remove()) +
2118 " set(1582,OCTOBER, " + DOY_DATA
[i
] + ")");
2119 logln(CalendarTest::calToStr(cal
));
2120 status
= U_ZERO_ERROR
;
2122 logln((UnicodeString
)"PASS: expect woy=" + DOY_DATA
[i
+1] +
2123 ", doy=" + DOY_DATA
[i
+2] + ", dow=" + DOY_DATA
[i
+3] + " on " +
2124 fmt
.format(cal
.getTime(status
), temp
.remove()));
2125 logln(CalendarTest::calToStr(cal
));
2126 status
= U_ZERO_ERROR
;
2128 // Test fields->time for WOY
2130 cal
.set(UCAL_YEAR
, 1582);
2131 cal
.set(UCAL_WEEK_OF_YEAR
, DOY_DATA
[i
+1]);
2132 cal
.set(UCAL_DAY_OF_WEEK
, DOY_DATA
[i
+3]);
2133 int32_t dom
= cal
.get(UCAL_DATE
, status
);
2134 if (U_FAILURE(status
)) {
2135 errln("Error: get() failed");
2138 if (dom
!= DOY_DATA
[i
]) {
2139 errln((UnicodeString
)"Fail: set woy=" + DOY_DATA
[i
+1] +
2140 " dow=" + DOY_DATA
[i
+3] + " => " +
2141 fmt
.format(cal
.getTime(status
), temp
.remove()) +
2142 ", expected 1582 Oct " + DOY_DATA
[i
]);
2143 logln(CalendarTest::calToStr(cal
));
2144 status
= U_ZERO_ERROR
;
2147 // Test fields->time for DOY
2149 cal
.set(UCAL_YEAR
, 1582);
2150 cal
.set(UCAL_DAY_OF_YEAR
, DOY_DATA
[i
+2]);
2151 dom
= cal
.get(UCAL_DATE
, status
);
2152 if (U_FAILURE(status
)) {
2153 errln("Error: get() failed");
2156 if (dom
!= DOY_DATA
[i
]) {
2157 errln((UnicodeString
)"Fail: set doy=" + DOY_DATA
[i
+2] +
2159 fmt
.format(cal
.getTime(status
), temp
.remove()) +
2160 ", expected 1582 Oct " + DOY_DATA
[i
]);
2161 status
= U_ZERO_ERROR
;
2164 status
= U_ZERO_ERROR
;
2166 #define ADD_ROLL ADD|ROLL
2167 #define PLUS_MINUS PLUS|MINUS
2170 { UCAL_WEEK_OF_YEAR
, ADD_ROLL
, PLUS_MINUS
, 1, -ONE_DAY
, +6*ONE_DAY
},
2171 { UCAL_WEEK_OF_YEAR
, ADD_ROLL
, PLUS_MINUS
, 1, -ONE_DAY
, +6*ONE_DAY
},
2172 { UCAL_WEEK_OF_MONTH
, ADD
|ROLL
, PLUS
|MINUS
, 1, -ONE_DAY
, +6*ONE_DAY
},
2173 { UCAL_DATE
, ADD
|ROLL
, PLUS
|MINUS
, 2, -ONE_DAY
, +1*ONE_DAY
},
2174 { UCAL_DATE
, ROLL
, PLUS
, -6, -ONE_DAY
, +14*ONE_DAY
},
2175 { UCAL_DATE
, ROLL
, PLUS
, -7, 0, +14*ONE_DAY
},
2176 { UCAL_DATE
, ROLL
, PLUS
, -7, +ONE_DAY
, +15*ONE_DAY
},
2177 { UCAL_DATE
, ROLL
, PLUS
, +18, -ONE_DAY
, -4*ONE_DAY
},
2178 { UCAL_DAY_OF_YEAR
, ADD
|ROLL
, PLUS
|MINUS
, 2, -ONE_DAY
, +1*ONE_DAY
},
2179 { UCAL_DAY_OF_WEEK
, ADD
|ROLL
, PLUS
|MINUS
, 2, -ONE_DAY
, +1*ONE_DAY
},
2180 { UCAL_DAY_OF_WEEK_IN_MONTH
, ADD
|ROLL
, PLUS
|MINUS
, 1, -ONE_DAY
, +6*ONE_DAY
},
2181 { UCAL_AM_PM
, ADD
, PLUS
|MINUS
, 4, -12*ONE_HOUR
, +36*ONE_HOUR
},
2182 { UCAL_HOUR
, ADD
, PLUS
|MINUS
, 48, -12*ONE_HOUR
, +36*ONE_HOUR
},
2183 { UCAL_HOUR_OF_DAY
, ADD
, PLUS
|MINUS
, 48, -12*ONE_HOUR
, +36*ONE_HOUR
},
2184 { UCAL_MINUTE
, ADD
, PLUS
|MINUS
, 48*60, -12*ONE_HOUR
, +36*ONE_HOUR
},
2185 { UCAL_SECOND
, ADD
, PLUS
|MINUS
, 48*60*60, -12*ONE_HOUR
, +36*ONE_HOUR
},
2186 { UCAL_MILLISECOND
, ADD
, PLUS
|MINUS
, 48*ONE_HOUR
, -12*ONE_HOUR
, +36*ONE_HOUR
},
2187 // NOTE: These are not supported yet. See jitterbug 180.
2188 // Uncomment these lines when add/roll supported on these fields.
2189 // { Calendar::YEAR_WOY, ADD|ROLL, 1, -ONE_DAY, +6*ONE_DAY },
2190 // { Calendar::DOW_LOCAL, ADD|ROLL, 2, -ONE_DAY, +1*ONE_DAY }
2192 int32_t DATA_length
= (int32_t)(sizeof(DATA
) / sizeof(DATA
[0]));
2194 // Now run the tests
2195 for (i
=0; i
<DATA_length
; ++i
) {
2196 for (Action action
=ADD
; action
<=ROLL
; action
=(Action
)(action
+1)) {
2197 if (!(DATA
[i
].actionMask
& action
)) {
2200 for (Sign sign
=PLUS
; sign
<=MINUS
; sign
=(Sign
)(sign
+1)) {
2201 if (!(DATA
[i
].signMask
& sign
)) {
2204 status
= U_ZERO_ERROR
;
2205 int32_t amount
= DATA
[i
].amount
* (sign
==MINUS
?-1:1);
2206 UDate date
= cutover
+
2207 (sign
==PLUS
? DATA
[i
].before
: DATA
[i
].after
);
2208 UDate expected
= cutover
+
2209 (sign
==PLUS
? DATA
[i
].after
: DATA
[i
].before
);
2210 cal
.setTime(date
, status
);
2211 if (U_FAILURE(status
)) {
2212 errln((UnicodeString
)"FAIL: setTime returned error code " + u_errorName(status
));
2215 if (action
== ADD
) {
2216 cal
.add(DATA
[i
].field
, amount
, status
);
2218 cal
.roll(DATA
[i
].field
, amount
, status
);
2220 if (U_FAILURE(status
)) {
2221 errln((UnicodeString
)"FAIL: " +
2222 (action
==ADD
?"add ":"roll ") + FIELD_NAME
[DATA
[i
].field
] +
2223 " returned error code " + u_errorName(status
));
2226 UDate result
= cal
.getTime(status
);
2227 if (U_FAILURE(status
)) {
2228 errln((UnicodeString
)"FAIL: getTime returned error code " + u_errorName(status
));
2231 if (result
== expected
) {
2232 logln((UnicodeString
)"Ok: {" +
2233 fmt
.format(date
, temp
.remove()) +
2234 "}(" + date
/ONE_DAY
+
2235 (action
==ADD
?") add ":") roll ") +
2236 amount
+ " " + FIELD_NAME
[DATA
[i
].field
] + " -> {" +
2237 fmt
.format(result
, temp2
.remove()) +
2238 "}(" + result
/ONE_DAY
+ ")");
2240 errln((UnicodeString
)"FAIL: {" +
2241 fmt
.format(date
, temp
.remove()) +
2242 "}(" + date
/ONE_DAY
+
2243 (action
==ADD
?") add ":") roll ") +
2244 amount
+ " " + FIELD_NAME
[DATA
[i
].field
] + " -> {" +
2245 fmt
.format(result
, temp2
.remove()) +
2246 "}(" + result
/ONE_DAY
+ "), expect {" +
2247 fmt
.format(expected
, temp3
.remove()) +
2248 "}(" + expected
/ONE_DAY
+ ")");
2256 * Test fieldDifference().
2258 void CalendarRegressionTest::TestJ438(void) {
2259 UErrorCode ec
= U_ZERO_ERROR
;
2261 2000, UCAL_JANUARY
, 20, 2010, UCAL_JUNE
, 15,
2262 2010, UCAL_JUNE
, 15, 2000, UCAL_JANUARY
, 20,
2263 1964, UCAL_SEPTEMBER
, 7, 1999, UCAL_JUNE
, 4,
2264 1999, UCAL_JUNE
, 4, 1964, UCAL_SEPTEMBER
, 7,
2266 int32_t DATA_length
= (int32_t)(sizeof(DATA
)/sizeof(DATA
[0]));
2267 Calendar
* pcal
= Calendar::createInstance(Locale::getUS(), ec
);
2269 dataerrln("Error creating calendar %s", u_errorName(ec
));
2273 Calendar
& cal
= *pcal
;
2275 SimpleDateFormat
fmt(UnicodeString("MMM dd yyyy",""), ec
);
2276 fmt
.setCalendar(cal
);
2277 UnicodeString s
, t
, u
;
2278 if (U_SUCCESS(ec
)) {
2279 for (i
=0; i
<DATA_length
; i
+=6) {
2280 int32_t y1
= DATA
[i
];
2281 int32_t m1
= DATA
[i
+1];
2282 int32_t d1
= DATA
[i
+2];
2283 int32_t y2
= DATA
[i
+3];
2284 int32_t m2
= DATA
[i
+4];
2285 int32_t d2
= DATA
[i
+5];
2288 cal
.set(y1
, m1
, d1
);
2289 UDate date1
= cal
.getTime(ec
);
2290 if (failure(ec
, "getTime"))
2292 cal
.set(y2
, m2
, d2
);
2293 UDate date2
= cal
.getTime(ec
);
2294 if (failure(ec
, "getTime"))
2297 cal
.setTime(date1
, ec
);
2298 if (failure(ec
, "setTime"))
2300 int32_t dy
= cal
.fieldDifference(date2
, UCAL_YEAR
, ec
);
2301 int32_t dm
= cal
.fieldDifference(date2
, UCAL_MONTH
, ec
);
2302 int32_t dd
= cal
.fieldDifference(date2
, UCAL_DATE
, ec
);
2303 if (failure(ec
, "fieldDifference"))
2307 Calendar
*cal2
= cal
.clone();
2308 UErrorCode ec2
= U_ZERO_ERROR
;
2310 cal2
->setTime(date1
, ec2
);
2312 int32_t dy2
= cal2
->fieldDifference(date2
, Calendar::YEAR
, ec2
);
2313 int32_t dm2
= cal2
->fieldDifference(date2
, Calendar::MONTH
, ec2
);
2314 int32_t dd2
= cal2
->fieldDifference(date2
, Calendar::DATE
, ec2
);
2315 if (failure(ec2
, "fieldDifference(date, Calendar::DATE, ec)"))
2320 errln("fieldDifference(UCAL_...) and fieldDifference(Calendar::...) give different results!\n");
2326 logln(UnicodeString("") +
2327 fmt
.format(date2
, s
.remove()) + " - " +
2328 fmt
.format(date1
, t
.remove()) + " = " +
2329 dy
+ "y " + dm
+ "m " + dd
+ "d");
2331 cal
.setTime(date1
, ec
);
2332 if (failure(ec
, "setTime"))
2334 cal
.add(UCAL_YEAR
, dy
, ec
);
2335 cal
.add(UCAL_MONTH
, dm
, ec
);
2336 cal
.add(UCAL_DATE
, dd
, ec
);
2337 if (failure(ec
, "add"))
2339 UDate date22
= cal
.getTime(ec
);
2340 if (failure(ec
, "getTime"))
2342 if (date2
!= date22
) {
2343 errln(UnicodeString("FAIL: ") +
2344 fmt
.format(date1
, s
.remove()) + " + " +
2345 dy
+ "y " + dm
+ "m " + dd
+ "d = " +
2346 fmt
.format(date22
, t
.remove()) + ", exp " +
2347 fmt
.format(date2
, u
.remove()));
2349 logln(UnicodeString("Ok: ") +
2350 fmt
.format(date1
, s
.remove()) + " + " +
2351 dy
+ "y " + dm
+ "m " + dd
+ "d = " +
2352 fmt
.format(date22
, t
.remove()));
2356 dataerrln("Error creating SimpleDateFormat - %s", u_errorName(ec
));
2361 void CalendarRegressionTest::TestT5555()
2363 UErrorCode ec
= U_ZERO_ERROR
;
2364 Calendar
*cal
= Calendar::createInstance(ec
);
2366 if (cal
== NULL
|| U_FAILURE(ec
)) {
2367 dataerrln("FAIL: Calendar::createInstance(): %s", u_errorName(ec
));
2372 // Set to Wednesday, February 21, 2007
2373 cal
->set(2007, UCAL_FEBRUARY
, 21);
2375 // Advance three years
2376 cal
->add(UCAL_MONTH
, 36, ec
);
2378 // Set to last Wednesday of the month
2379 cal
->set(UCAL_DAY_OF_WEEK_IN_MONTH
, -1);
2383 int32_t yy
, mm
, dd
, ee
;
2385 yy
= cal
->get(UCAL_YEAR
, ec
);
2386 mm
= cal
->get(UCAL_MONTH
, ec
);
2387 dd
= cal
->get(UCAL_DATE
, ec
);
2388 ee
= cal
->get(UCAL_DAY_OF_WEEK
, ec
);
2390 // Should be set to Wednesday, February 24, 2010
2391 if (U_FAILURE(ec
) || yy
!= 2010 || mm
!= UCAL_FEBRUARY
|| dd
!= 24 || ee
!= UCAL_WEDNESDAY
) {
2392 errln("FAIL: got date %4d/%02d/%02d, expected 210/02/24: ", yy
, mm
+ 1, dd
);
2399 int32_t startMonth
; // 0-based
2400 int32_t startDay
; // 1-based
2401 UCalendarDateFields fieldToChange
;
2404 int32_t endMonth
; // 0-based
2405 int32_t endDay
; // 1-based
2406 } CoptEthCalTestItem
;
2408 // year 1724 in coptic calendar =
2409 // year 2000 in ethiopic calendar (276 more than coptic) =
2410 // year 7500 in ethiopic-amete-alem calendar (5776 more than coptic)
2411 // (2007-2008 in gregorian calendar depending on month)
2412 static const CoptEthCalTestItem coptEthCalTestItems
[] = {
2413 { 1724, 12, 1, UCAL_MONTH
, +1, 1725, 0, 1 },
2414 { 1724, 12, 1, UCAL_MONTH
, +9, 1725, 8, 1 },
2415 { 1723, 12, 2, UCAL_MONTH
, +1, 1724, 0, 2 }, // 1723 is a leap year
2416 { 1723, 12, 2, UCAL_MONTH
, +9, 1724, 8, 2 },
2417 { 1725, 0, 1, UCAL_MONTH
, -1, 1724, 12, 1 },
2418 { 1725, 0, 1, UCAL_MONTH
, -6, 1724, 7, 1 },
2419 { 1724, 12, 1, UCAL_DATE
, +8, 1725, 0, 4 },
2420 { 1723, 12, 1, UCAL_DATE
, +8, 1724, 0, 3 }, // 1723 is a leap year
2421 { 1724, 0, 1, UCAL_DATE
, -1, 1723, 12, 6 }, // 1723 is a leap year
2422 { 0, 0, 0, (UCalendarDateFields
)0, 0, 0, 0, 0 } // terminator
2426 const char * locale
;
2430 static const CoptEthCalLocale copEthCalLocales
[] = {
2431 { "en@calendar=coptic", 0 },
2432 { "en@calendar=ethiopic", 276 },
2433 { NULL
, 0 } // terminator
2436 void CalendarRegressionTest::TestT6745()
2438 const CoptEthCalLocale
* testLocalePtr
;
2439 for ( testLocalePtr
= copEthCalLocales
; testLocalePtr
->locale
!= NULL
; ++testLocalePtr
) {
2440 UErrorCode status
= U_ZERO_ERROR
;
2441 Calendar
*cal
= Calendar::createInstance(Locale(testLocalePtr
->locale
), status
);
2442 if ( U_FAILURE(status
) ) {
2443 dataerrln((UnicodeString
)"FAIL: Calendar::createInstance, locale " + testLocalePtr
->locale
+ ", status " + u_errorName(status
));
2446 const CoptEthCalTestItem
* testItemPtr
;
2447 for (testItemPtr
= coptEthCalTestItems
; testItemPtr
->fieldDelta
!= 0; ++testItemPtr
) {
2448 status
= U_ZERO_ERROR
;
2449 cal
->set( testItemPtr
->startYear
+ testLocalePtr
->yearOffset
, testItemPtr
->startMonth
, testItemPtr
->startDay
, 9, 0 );
2450 cal
->add( testItemPtr
->fieldToChange
, testItemPtr
->fieldDelta
, status
);
2451 if ( U_FAILURE(status
) ) {
2452 errln((UnicodeString
)"FAIL: Calendar::add, locale " + testLocalePtr
->locale
+ ", field/delta " +
2453 testItemPtr
->fieldToChange
+ "/" + testItemPtr
->fieldDelta
+ ", status " + u_errorName(status
));
2456 int32_t endYear
= testItemPtr
->endYear
+ testLocalePtr
->yearOffset
;
2457 int32_t year
= cal
->get(UCAL_YEAR
, status
);
2458 int32_t month
= cal
->get(UCAL_MONTH
, status
);
2459 int32_t day
= cal
->get(UCAL_DATE
, status
);
2460 if ( U_FAILURE(status
) || year
!= endYear
|| month
!= testItemPtr
->endMonth
|| day
!= testItemPtr
->endDay
) {
2461 errln((UnicodeString
)"ERROR: Calendar::add, locale " + testLocalePtr
->locale
+ ", field/delta " +
2462 testItemPtr
->fieldToChange
+ "/" + testItemPtr
->fieldDelta
+ ", status " + u_errorName(status
) +
2463 ", expected " + endYear
+ "/" + testItemPtr
->endMonth
+ "/" + testItemPtr
->endDay
+
2464 ", got " + year
+ "/" + month
+ "/" + day
);
2472 * Test behavior of fieldDifference around leap years. Also test a large
2473 * field difference to check binary search.
2475 void CalendarRegressionTest::TestLeapFieldDifference() {
2476 UErrorCode ec
= U_ZERO_ERROR
;
2477 Calendar
* cal
= Calendar::createInstance(ec
);
2478 if (cal
== NULL
|| U_FAILURE(ec
)) {
2479 dataerrln("FAIL: Calendar::createInstance(): %s", u_errorName(ec
));
2483 cal
->set(2004, UCAL_FEBRUARY
, 29);
2484 UDate date2004
= cal
->getTime(ec
);
2485 cal
->set(2000, UCAL_FEBRUARY
, 29);
2486 UDate date2000
= cal
->getTime(ec
);
2487 if (U_FAILURE(ec
)) {
2488 errln("FAIL: getTime()");
2492 int32_t y
= cal
->fieldDifference(date2004
, UCAL_YEAR
, ec
);
2493 int32_t d
= cal
->fieldDifference(date2004
, UCAL_DAY_OF_YEAR
, ec
);
2494 if (U_FAILURE(ec
)) {
2495 errln("FAIL: fieldDifference()");
2500 logln((UnicodeString
)"Ok: 2004/Feb/29 - 2000/Feb/29 = " + y
+ " years, " + d
+ " days");
2502 errln((UnicodeString
)"FAIL: 2004/Feb/29 - 2000/Feb/29 = " + y
+ " years, " + d
+ " days");
2504 cal
->setTime(date2004
, ec
);
2505 y
= cal
->fieldDifference(date2000
, UCAL_YEAR
, ec
);
2506 d
= cal
->fieldDifference(date2000
, UCAL_DAY_OF_YEAR
, ec
);
2507 if (U_FAILURE(ec
)) {
2508 errln("FAIL: setTime() / fieldDifference()");
2513 logln((UnicodeString
)"Ok: 2000/Feb/29 - 2004/Feb/29 = " + y
+ " years, " + d
+ " days");
2515 errln((UnicodeString
)"FAIL: 2000/Feb/29 - 2004/Feb/29 = " + y
+ " years, " + d
+ " days");
2517 // Test large difference
2518 cal
->set(2001, UCAL_APRIL
, 5); // 2452005
2519 UDate ayl
= cal
->getTime(ec
);
2520 cal
->set(1964, UCAL_SEPTEMBER
, 7); // 2438646
2521 UDate asl
= cal
->getTime(ec
);
2522 if (U_FAILURE(ec
)) {
2523 errln("FAIL: getTime()");
2527 d
= cal
->fieldDifference(ayl
, UCAL_DATE
, ec
);
2528 cal
->setTime(ayl
, ec
);
2529 int32_t d2
= cal
->fieldDifference(asl
, UCAL_DATE
, ec
);
2530 if (U_FAILURE(ec
)) {
2531 errln("FAIL: setTime() / fieldDifference()");
2535 if (d
== -d2
&& d
== 13359) {
2536 logln((UnicodeString
)"Ok: large field difference symmetrical " + d
);
2538 logln((UnicodeString
)"FAIL: large field difference incorrect " + d
+ ", " + d2
+
2539 ", expect +/- 13359");
2545 * Test ms_MY "Malay (Malaysia)" locale. Bug 1543.
2547 void CalendarRegressionTest::TestMalaysianInstance() {
2548 Locale
loc("ms", "MY"); // Malay (Malaysia)
2549 UErrorCode ec
= U_ZERO_ERROR
;
2550 Calendar
* cal
= Calendar::createInstance(loc
, ec
);
2551 if (U_FAILURE(ec
)) {
2552 dataerrln("FAIL: Can't construct calendar for ms_MY: %s", u_errorName(ec
));
2558 * setFirstDayOfWeek and setMinimalDaysInFirstWeek may change the
2559 * field <=> time mapping, since they affect the interpretation of
2560 * the WEEK_OF_MONTH or WEEK_OF_YEAR fields.
2562 void CalendarRegressionTest::TestWeekShift() {
2563 UErrorCode ec
= U_ZERO_ERROR
;
2564 GregorianCalendar
cal(TimeZone::createTimeZone("America/Los_Angeles"),
2565 Locale("en", "US"), ec
);
2566 if (U_FAILURE(ec
)) {
2567 dataerrln("Fail GregorianCalendar: %s", u_errorName(ec
));
2570 cal
.setTime(UDate(997257600000.0), ec
); // Wed Aug 08 01:00:00 PDT 2001
2571 // In pass one, change the first day of week so that the weeks
2572 // shift in August 2001. In pass two, change the minimal days
2573 // in the first week so that the weeks shift in August 2001.
2575 // Su Mo Tu We Th Fr Sa
2578 // 12 13 14 15 16 17 18
2579 // 19 20 21 22 23 24 25
2580 // 26 27 28 29 30 31
2581 for (int32_t pass
=0; pass
<2; ++pass
) {
2583 cal
.setFirstDayOfWeek(UCAL_WEDNESDAY
);
2584 cal
.setMinimalDaysInFirstWeek(4);
2586 cal
.setFirstDayOfWeek(UCAL_SUNDAY
);
2587 cal
.setMinimalDaysInFirstWeek(4);
2589 cal
.add(UCAL_DATE
, 1, ec
); // Force recalc
2590 cal
.add(UCAL_DATE
, -1, ec
);
2592 UDate time1
= cal
.getTime(ec
); // Get time -- should not change
2594 // Now change a week parameter and then force a recalc.
2595 // The bug is that the recalc should not be necessary --
2596 // calendar should do so automatically.
2598 cal
.setFirstDayOfWeek(UCAL_THURSDAY
);
2600 cal
.setMinimalDaysInFirstWeek(5);
2603 int32_t woy1
= cal
.get(UCAL_WEEK_OF_YEAR
, ec
);
2604 int32_t wom1
= cal
.get(UCAL_WEEK_OF_MONTH
, ec
);
2606 cal
.add(UCAL_DATE
, 1, ec
); // Force recalc
2607 cal
.add(UCAL_DATE
, -1, ec
);
2609 int32_t woy2
= cal
.get(UCAL_WEEK_OF_YEAR
, ec
);
2610 int32_t wom2
= cal
.get(UCAL_WEEK_OF_MONTH
, ec
);
2612 UDate time2
= cal
.getTime(ec
);
2614 if (U_FAILURE(ec
)) {
2615 errln("FAIL: internal test error");
2619 if (time1
!= time2
) {
2620 errln("FAIL: shifting week should not alter time");
2624 if (woy1
== woy2
&& wom1
== wom2
) {
2625 logln((UnicodeString
)"Ok: WEEK_OF_YEAR: " + woy1
+
2626 ", WEEK_OF_MONTH: " + wom1
);
2628 errln((UnicodeString
)"FAIL: WEEK_OF_YEAR: " + woy1
+ " => " + woy2
+
2629 ", WEEK_OF_MONTH: " + wom1
+ " => " + wom2
+
2630 " after week shift");
2636 * Make sure that when adding a day, we actually wind up in a
2637 * different day. The DST adjustments we use to keep the hour
2638 * constant across DST changes can backfire and change the day.
2640 void CalendarRegressionTest::TestTimeZoneTransitionAdd() {
2641 UErrorCode ec
= U_ZERO_ERROR
;
2642 Locale
locale(Locale::getUS()); // could also be CHINA
2643 SimpleDateFormat
dateFormat("MM/dd/yyyy HH:mm z", locale
, ec
);
2645 StringEnumeration
*tz
= TimeZone::createEnumeration();
2647 dataerrln("FAIL: TimeZone::createEnumeration");
2651 UnicodeString buf1
, buf2
;
2654 while ((id
= tz
->unext(NULL
, ec
)) != NULL
&& U_SUCCESS(ec
)) {
2655 if (U_FAILURE(ec
)) {
2656 errln("FAIL: StringEnumeration::unext");
2660 TimeZone
*t
= TimeZone::createTimeZone(id
);
2662 errln("FAIL: TimeZone::createTimeZone");
2665 dateFormat
.setTimeZone(*t
);
2667 Calendar
*cal
= Calendar::createInstance(t
, locale
, ec
);
2668 if (cal
== NULL
|| U_FAILURE(ec
)) {
2669 errln("FAIL: Calendar::createTimeZone");
2675 // Scan the year 2003, overlapping the edges of the year
2676 cal
->set(UCAL_YEAR
, 2002);
2677 cal
->set(UCAL_MONTH
, UCAL_DECEMBER
);
2678 cal
->set(UCAL_DATE
, 25);
2680 for (int32_t i
=0; i
<365+10 && U_SUCCESS(ec
); ++i
) {
2681 UDate yesterday
= cal
->getTime(ec
);
2682 int32_t yesterday_day
= cal
->get(UCAL_DATE
, ec
);
2683 cal
->add(UCAL_DATE
, 1, ec
);
2684 if (yesterday_day
== cal
->get(UCAL_DATE
, ec
)) {
2685 errln(UnicodeString(id
) + " " +
2686 dateFormat
.format(yesterday
, buf1
) + " +1d= " +
2687 dateFormat
.format(cal
->getTime(ec
), buf2
));
2695 if (U_FAILURE(ec
)) {
2696 dataerrln("FAIL: %s", u_errorName(ec
));
2703 CalendarRegressionTest::makeDate(int32_t y
, int32_t m
, int32_t d
,
2704 int32_t hr
, int32_t min
, int32_t sec
)
2708 UErrorCode status
= U_ZERO_ERROR
;
2709 Calendar
*cal
= Calendar::createInstance(status
);
2712 cal
->set(UCAL_YEAR
, y
);
2714 if(m
!= 0) cal
->set(UCAL_MONTH
, m
);
2715 if(d
!= 0) cal
->set(UCAL_DATE
, d
);
2716 if(hr
!= 0) cal
->set(UCAL_HOUR
, hr
);
2717 if(min
!= 0) cal
->set(UCAL_MINUTE
, min
);
2718 if(sec
!= 0) cal
->set(UCAL_SECOND
, sec
);
2720 result
= cal
->getTime(status
);
2727 void CalendarRegressionTest::TestDeprecates(void)
2729 UErrorCode status
= U_ZERO_ERROR
;
2730 Calendar
*c1
= Calendar::createInstance("ja_JP@calendar=japanese",status
);
2731 Calendar
*c2
= Calendar::createInstance("ja_JP_TRADITIONAL",status
);
2733 if(!c1
|| !c2
|| U_FAILURE(status
)) {
2734 dataerrln("Couldn't create calendars for roll of HOUR: %s", u_errorName(status
));
2738 c2
->set(UCAL_HOUR
,2);
2739 c1
->setTime(c2
->getTime(status
),status
);
2742 c1
->roll(Calendar::HOUR
,(int32_t)3,status
);
2743 c2
->roll(UCAL_HOUR
,(int32_t)3,status
);
2745 if(U_FAILURE(status
)) {
2746 errln("Error code when trying to roll");
2747 } else if(*c1
!= *c2
) {
2748 errln("roll(EDateField, int32_t) had different effect than roll(UCalendarField, int32_t)");
2751 c1
->setTime(c2
->getTime(status
),status
);
2752 c1
->roll(Calendar::HOUR
,(UBool
)FALSE
,status
);
2753 c2
->roll(UCAL_HOUR
,(UBool
)FALSE
,status
);
2755 if(U_FAILURE(status
)) {
2756 errln("Error code when trying to roll(UBool)");
2757 } else if(*c1
!= *c2
) {
2758 errln("roll(EDateField, UBool) had different effect than roll(UCalendarField, UBool)");
2764 status
= U_ZERO_ERROR
;
2766 c1
= Calendar::createInstance("th_TH_TRADITIONAL",status
);
2767 c2
= Calendar::createInstance("th_TH@calendar=buddhist",status
);
2769 if(!c1
|| !c2
|| U_FAILURE(status
)) {
2770 errln("Couldn't create calendars for add of HOUR");
2774 c2
->set(UCAL_HOUR
,2);
2775 c1
->setTime(c2
->getTime(status
),status
);
2778 c1
->add(Calendar::HOUR
,(int32_t)1,status
);
2780 if(U_FAILURE(status
)) {
2781 errln("Error code when trying to add Calendar::HOUR - %s", u_errorName(status
));
2784 c2
->add(UCAL_HOUR
,(int32_t)1,status
);
2786 if(U_FAILURE(status
)) {
2787 errln("Error code when trying to add - UCAL_HOUR %s", u_errorName(status
));
2788 } else if(*c1
!= *c2
) {
2789 errln("add(EDateField) had different effect than add(UCalendarField)");
2795 status
= U_ZERO_ERROR
;
2797 c1
= Calendar::createInstance("es_ES",status
);
2798 c2
= Calendar::createInstance("es_ES",status
);
2800 if(!c1
|| !c2
|| U_FAILURE(status
)) {
2801 errln("Couldn't create calendars for add of YEAR");
2805 c2
->set(UCAL_YEAR
,1900);
2806 c1
->setTime(c2
->getTime(status
),status
);
2809 c1
->add(Calendar::YEAR
,(int32_t)9,status
);
2810 c2
->add(UCAL_YEAR
,(int32_t)9,status
);
2812 if(U_FAILURE(status
)) {
2813 errln("Error code when trying to add YEARs");
2814 } else if(*c1
!= *c2
) {
2815 errln("add(EDateField YEAR) had different effect than add(UCalendarField YEAR)");
2823 void CalendarRegressionTest::TestT8057(void) {
2824 // Set the calendar to the last day in a leap year
2825 UErrorCode status
= U_ZERO_ERROR
;
2826 GregorianCalendar
*cal
= (GregorianCalendar
*)Calendar::createInstance(status
);
2827 if(U_FAILURE(status
)) {
2828 errln("Error creating Calendar: %s", u_errorName(status
));
2832 cal
->setLenient(FALSE
);
2834 cal
->set(2008, UCAL_DECEMBER
, 31);
2836 // Force calculating then fields once.
2837 UDate t
= cal
->getTime(status
);
2838 if(U_FAILURE(status
)) {
2839 errln("Error while calculating the date");
2844 UDate expected
= 1262246400000.0; // 2009-12-31 00:00 PST
2846 cal
->add(UCAL_YEAR
, 1, status
);
2847 t
= cal
->getTime(status
);
2848 if (U_SUCCESS(status
)) {
2849 if (t
!= expected
) {
2850 dataerrln((UnicodeString
)"FAIL: wrong date after add: expected=" + expected
+ " returned=" + t
);
2853 errln("FAIL: error while adding one year");
2859 // Test case for ticket#8596.
2860 // Setting an year followed by getActualMaximum(Calendar.WEEK_OF_YEAR)
2861 // may result wrong maximum week.
2862 void CalendarRegressionTest::TestT8596(void) {
2863 UErrorCode status
= U_ZERO_ERROR
;
2864 GregorianCalendar
*gc
= new GregorianCalendar(*TimeZone::getGMT(), status
);
2866 if (U_FAILURE(status
)) {
2867 dataerrln("Error creating Calendar: %s", u_errorName(status
));
2872 gc
->setFirstDayOfWeek(UCAL_MONDAY
);
2873 gc
->setMinimalDaysInFirstWeek(4);
2875 // Force the calender to resolve the fields once.
2876 // The maximum week number in 2011 is 52.
2877 gc
->set(UCAL_YEAR
, 2011);
2878 gc
->get(UCAL_YEAR
, status
);
2880 // Set a date in year 2009, but not calling get to resolve
2881 // the calendar's internal field yet.
2882 gc
->set(2009, UCAL_JULY
, 1);
2884 // Then call getActuamMaximum for week of year.
2885 // #8596 was caused by conflict between year set
2886 // above and internal work calendar field resolution.
2887 int32_t maxWeeks
= gc
->getActualMaximum(UCAL_WEEK_OF_YEAR
, status
);
2889 if (U_FAILURE(status
)) {
2890 errln("Error calendar calculation: %s", u_errorName(status
));
2895 if (maxWeeks
!= 53) {
2896 errln((UnicodeString
)"FAIL: Max week in 2009 in ISO calendar is 53, but got " + maxWeeks
);
2902 // Test case for ticket 9452
2903 // Calendar addition fall onto the missing date - 2011-12-30 in Samoa
2904 void CalendarRegressionTest::TestT9452(void) {
2905 UErrorCode status
= U_ZERO_ERROR
;
2906 GregorianCalendar
cal(TimeZone::createTimeZone("Pacific/Apia"), status
);
2907 failure(status
, "initializing GregorianCalendar");
2909 SimpleDateFormat
sdf(UnicodeString("y-MM-dd'T'HH:mm:ssZZZZZ"), status
);
2910 failure(status
, "initializing SimpleDateFormat");
2911 sdf
.setCalendar(cal
);
2915 // Set date to 2011-12-29 00:00
2917 cal
.set(2011, UCAL_DECEMBER
, 29, 0, 0, 0);
2919 UDate d
= cal
.getTime(status
);
2920 if (!failure(status
, "getTime for initial date")) {
2921 sdf
.format(d
, dstr
);
2922 logln(UnicodeString("Initial date: ") + dstr
);
2925 cal
.add(UCAL_DATE
, 1, status
);
2926 failure(status
, "add 1 day");
2927 d
= cal
.getTime(status
);
2928 failure(status
, "getTime after +1 day");
2930 sdf
.format(d
, dstr
);
2931 logln(UnicodeString("+1 day: ") + dstr
);
2932 assertEquals("Add 1 day", UnicodeString("2011-12-31T00:00:00+14:00"), dstr
);
2935 cal
.add(UCAL_DATE
, -1, status
);
2936 failure(status
, "subtract 1 day");
2937 d
= cal
.getTime(status
);
2938 failure(status
, "getTime after -1 day");
2940 sdf
.format(d
, dstr
);
2941 logln(UnicodeString("-1 day: ") + dstr
);
2942 assertEquals("Subtract 1 day", UnicodeString("2011-12-29T00:00:00-10:00"), dstr
);
2946 #endif /* #if !UCONFIG_NO_FORMATTING */