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
);
90 default: name
= ""; break;
94 const char* CalendarRegressionTest::FIELD_NAME
[] = {
103 "DAY_OF_WEEK_IN_MONTH",
117 CalendarRegressionTest::failure(UErrorCode status
, const char* msg
)
119 if(U_FAILURE(status
)) {
120 errcheckln(status
, UnicodeString("FAIL: ") + msg
+ " failed, error " + u_errorName(status
));
131 CalendarRegressionTest::test4100311()
133 UErrorCode status
= U_ZERO_ERROR
;
134 GregorianCalendar
*cal
= (GregorianCalendar
*)Calendar::createInstance(status
);
135 if(U_FAILURE(status
)) {
136 dataerrln("Error creating Calendar: %s", u_errorName(status
));
140 failure(status
, "Calendar::createInstance(status)");
141 cal
->set(UCAL_YEAR
, 1997);
142 cal
->set(UCAL_DAY_OF_YEAR
, 1);
143 UDate d
= cal
->getTime(status
); // Should be Jan 1
144 failure(status
, "cal->getTime");
145 logln(UnicodeString("") + d
);
154 CalendarRegressionTest::test4074758()
155 { //Set system time to between 12-1 (am or pm) and then run
156 UErrorCode status
= U_ZERO_ERROR
;
157 GregorianCalendar
*cal
= new GregorianCalendar(status
);
158 if(U_FAILURE(status
)) {
159 dataerrln("Error creating Calendar: %s", u_errorName(status
));
163 failure(status
, "new GregorianCalendar");
164 for (int32_t h
=0; h
<25; ++h
) {
165 cal
->set(97, UCAL_JANUARY
, 1, h
, 34);
166 //System.out.print(d);
167 logln(UnicodeString("HOUR=") + cal
->get(UCAL_HOUR
, status
)); //prints 0
168 failure(status
, "cal->get");
169 logln(UnicodeString("HOUR_OF_DAY=") + cal
->get(UCAL_HOUR_OF_DAY
, status
));
170 failure(status
, "cal->get");
177 CalendarRegressionTest::test4028518()
179 UErrorCode status
= U_ZERO_ERROR
;
180 GregorianCalendar
*cal1
= new GregorianCalendar(status
) ;
181 if(U_FAILURE(status
)) {
182 dataerrln("Error creating Calendar: %s", u_errorName(status
));
186 failure(status
, "new GregorianCalendar");
187 GregorianCalendar
*cal2
= (GregorianCalendar
*) cal1
->clone() ;
189 printdate(cal1
, "cal1: ") ;
190 printdate(cal2
, "cal2 - cloned(): ") ;
191 cal1
->add(UCAL_DATE
, 1, status
) ;
192 failure(status
, "cal1->add");
193 printdate(cal1
, "cal1 after adding 1 day:") ;
194 printdate(cal2
, "cal2 should be unmodified:") ;
201 CalendarRegressionTest::Test9019()
203 UErrorCode status
= U_ZERO_ERROR
;
204 LocalPointer
<GregorianCalendar
> cal1(new GregorianCalendar(status
));
205 LocalPointer
<GregorianCalendar
> cal2(new GregorianCalendar(status
));
206 cal1
->set(UCAL_HOUR
, 1);
207 cal2
->set(UCAL_HOUR
,2);
210 if(U_FAILURE(status
)) {
211 dataerrln("Error creating Calendar: %s", u_errorName(status
));
214 failure(status
, "new GregorianCalendar");
215 cal1
->set(2011,UCAL_MAY
,06);
216 cal2
->set(2012,UCAL_JANUARY
,06);
217 printdate(cal1
.getAlias(), "cal1: ") ;
218 cal1
->setLenient(FALSE
);
219 cal1
->add(UCAL_MONTH
,8,status
);
220 failure(status
, "->add(UCAL_MONTH,8)");
221 printdate(cal1
.getAlias(), "cal1 (lenient) after adding 8 months:") ;
222 printdate(cal2
.getAlias(), "cal2 (expected date):") ;
224 if(!cal1
->equals(*cal2
,status
)) {
225 errln("Error: cal1 != cal2.\n");
227 failure(status
, "equals");
231 CalendarRegressionTest::printdate(GregorianCalendar
*cal
, const char *string
)
233 UErrorCode status
= U_ZERO_ERROR
;
234 logln(UnicodeString(string
, ""));
235 log(UnicodeString("") + cal
->get(UCAL_MONTH
, status
)) ;
236 failure(status
, "cal->get");
237 int32_t date
= cal
->get(UCAL_DATE
, status
) + 1 ;
238 failure(status
, "cal->get");
239 log(UnicodeString("/") + date
) ;
240 logln(UnicodeString("/") + cal
->get(UCAL_YEAR
, status
)) ;
241 failure(status
, "cal->get");
248 CalendarRegressionTest::test4031502()
250 // This bug actually occurs on Windows NT as well, and doesn't
251 // require the host zone to be set; it can be set in Java.
252 UErrorCode status
= U_ZERO_ERROR
;
253 StringEnumeration
* ids
= TimeZone::createEnumeration();
255 dataerrln("Unable to create TimeZone Enumeration.");
259 TimeZone
* tz
=TimeZone::createTimeZone("Asia/Riyadh87");
260 failure(status
, "new TimeZone");
261 GregorianCalendar
*cl
= new GregorianCalendar(tz
, status
);
262 if (U_FAILURE(status
)) {
263 dataerrln("Fail new GregorianCalendar: %s", u_errorName(status
));
268 cl
->set(1900, 15, 5, 5, 8, 13);
269 cl
->get(UCAL_HOUR
, status
);
270 failure(status
, "cl->get(UCAL_HOUR, status)");
271 status
= U_ZERO_ERROR
;
273 for (int32_t i
=0; i
<ids
->count(status
); ++i
) {
274 TimeZone
*zone
= TimeZone::createTimeZone(*ids
->snext(status
));
275 GregorianCalendar
*cal
= new GregorianCalendar(zone
, status
);
276 failure(status
, "new GregorianCalendar");
278 cal
->set(1900, 15, 5, 5, 8, 13);
279 if (cal
->get(UCAL_HOUR
, status
) != 5 || U_FAILURE(status
)) {
281 logln(zone
->getID(temp
) + " " +
282 //zone.useDaylightTime() + " " +
283 cal
->get(UCAL_DST_OFFSET
,status
) / (60*60*1000) + " " +
284 zone
->getRawOffset() / (60*60*1000) +
285 ": HOUR = " + cal
->get(UCAL_HOUR
,status
));
291 errln("TimeZone problems with GC");
292 // delete [] ids; // TODO: bad APIs
299 void CalendarRegressionTest::test4035301()
301 UErrorCode status
= U_ZERO_ERROR
;
302 GregorianCalendar
*c
= new GregorianCalendar(98, 8, 7,status
);
303 GregorianCalendar
*d
= new GregorianCalendar(98, 8, 7,status
);
304 if (c
->after(*d
,status
) ||
305 c
->after(*c
,status
) ||
306 c
->before(*d
,status
) ||
307 c
->before(*c
,status
) ||
318 void CalendarRegressionTest::test4040996()
321 StringEnumeration
* ids
= TimeZone::createEnumeration(-8 * 60 * 60 * 1000);
323 dataerrln("Unable to create TimeZone enumeration.");
326 UErrorCode status
= U_ZERO_ERROR
;
327 count
= ids
->count(status
);
328 SimpleTimeZone
*pdt
= new SimpleTimeZone(-8 * 60 * 60 * 1000, *ids
->snext(status
));
329 pdt
->setStartRule(UCAL_APRIL
, 1, UCAL_SUNDAY
, 2 * 60 * 60 * 1000, status
);
330 pdt
->setEndRule(UCAL_OCTOBER
, -1, UCAL_SUNDAY
, 2 * 60 * 60 * 1000, status
);
331 Calendar
*calendar
= new GregorianCalendar(pdt
, status
);
332 if (U_FAILURE(status
)) {
333 dataerrln("Fail new GregorianCalendar: %s", u_errorName(status
));
336 calendar
->set(UCAL_MONTH
,3);
337 calendar
->set(UCAL_DATE
,18);
338 calendar
->set(UCAL_SECOND
, 30);
340 logln(UnicodeString("MONTH: ") + calendar
->get(UCAL_MONTH
, status
));
341 logln(UnicodeString("DAY_OF_MONTH: ") +
342 calendar
->get(UCAL_DATE
, status
));
343 logln(UnicodeString("MINUTE: ") + calendar
->get(UCAL_MINUTE
, status
));
344 logln(UnicodeString("SECOND: ") + calendar
->get(UCAL_SECOND
, status
));
346 calendar
->add(UCAL_SECOND
,6, status
);
347 //This will print out todays date for MONTH and DAY_OF_MONTH
348 //instead of the date it was set to.
349 //This happens when adding MILLISECOND or MINUTE also
350 logln(UnicodeString("MONTH: ") + calendar
->get(UCAL_MONTH
, status
));
351 logln(UnicodeString("DAY_OF_MONTH: ") +
352 calendar
->get(UCAL_DATE
, status
));
353 logln(UnicodeString("MINUTE: ") + calendar
->get(UCAL_MINUTE
, status
));
354 logln(UnicodeString("SECOND: ") + calendar
->get(UCAL_SECOND
, status
));
355 if (calendar
->get(UCAL_MONTH
, status
) != 3 ||
356 calendar
->get(UCAL_DATE
, status
) != 18 ||
357 calendar
->get(UCAL_SECOND
, status
) != 36)
358 errln(UnicodeString("Fail: Calendar::add misbehaves"));
362 // delete ids; // TODO: BAD API
368 void CalendarRegressionTest::test4051765()
370 UErrorCode status
= U_ZERO_ERROR
;
371 Calendar
*cal
= Calendar::createInstance(status
);
372 if(U_FAILURE(status
)) {
373 dataerrln("Error creating Calendar: %s", u_errorName(status
));
377 cal
->setLenient(FALSE
);
378 cal
->set(UCAL_DAY_OF_WEEK
, 0);
380 cal
->getTime(status
);
381 if( ! U_FAILURE(status
))
382 errln("Fail: DAY_OF_WEEK 0 should be disallowed");
384 catch (IllegalArgumentException e) {
391 /* User error - no bug here
392 void CalendarRegressionTest::test4059524() {
393 // Create calendar for April 10, 1997
394 GregorianCalendar calendar = new GregorianCalendar(status);
395 // print out a bunch of interesting things
396 logln("ERA: " + Calendar::get(Calendar::ERA));
397 logln("YEAR: " + Calendar::get(Calendar::YEAR));
398 logln("MONTH: " + Calendar::get(Calendar::MONTH));
399 logln("WEEK_OF_YEAR: " +
400 Calendar::get(Calendar::WEEK_OF_YEAR));
401 logln("WEEK_OF_MONTH: " +
402 Calendar::get(Calendar::WEEK_OF_MONTH));
403 logln("DATE: " + Calendar::get(Calendar::DATE));
404 logln("DAY_OF_MONTH: " +
405 Calendar::get(Calendar::DAY_OF_MONTH));
406 logln("DAY_OF_YEAR: " + Calendar::get(Calendar::DAY_OF_YEAR));
407 logln("DAY_OF_WEEK: " + Calendar::get(Calendar::DAY_OF_WEEK));
408 logln("DAY_OF_WEEK_IN_MONTH: " +
409 Calendar::get(Calendar::DAY_OF_WEEK_IN_MONTH));
410 logln("AM_PM: " + Calendar::get(Calendar::AM_PM));
411 logln("HOUR: " + Calendar::get(Calendar::HOUR));
412 logln("HOUR_OF_DAY: " + Calendar::get(Calendar::HOUR_OF_DAY));
413 logln("MINUTE: " + Calendar::get(Calendar::MINUTE));
414 logln("SECOND: " + Calendar::get(Calendar::SECOND));
415 logln("MILLISECOND: " + Calendar::get(Calendar::MILLISECOND));
416 logln("ZONE_OFFSET: "
417 + (Calendar::get(Calendar::ZONE_OFFSET)/(60*60*1000)));
419 + (Calendar::get(Calendar::DST_OFFSET)/(60*60*1000)));
420 calendar = new GregorianCalendar(1997,3,10);
422 logln("April 10, 1997");
423 logln("ERA: " + Calendar::get(Calendar::ERA));
424 logln("YEAR: " + Calendar::get(Calendar::YEAR));
425 logln("MONTH: " + Calendar::get(Calendar::MONTH));
426 logln("WEEK_OF_YEAR: " +
427 Calendar::get(Calendar::WEEK_OF_YEAR));
428 logln("WEEK_OF_MONTH: " +
429 Calendar::get(Calendar::WEEK_OF_MONTH));
430 logln("DATE: " + Calendar::get(Calendar::DATE));
431 logln("DAY_OF_MONTH: " +
432 Calendar::get(Calendar::DAY_OF_MONTH));
433 logln("DAY_OF_YEAR: " + Calendar::get(Calendar::DAY_OF_YEAR));
434 logln("DAY_OF_WEEK: " + Calendar::get(Calendar::DAY_OF_WEEK));
435 logln("DAY_OF_WEEK_IN_MONTH: " + Calendar::get(Calendar::DAY_OF_WEEK_IN_MONTH));
436 logln("AM_PM: " + Calendar::get(Calendar::AM_PM));
437 logln("HOUR: " + Calendar::get(Calendar::HOUR));
438 logln("HOUR_OF_DAY: " + Calendar::get(Calendar::HOUR_OF_DAY));
439 logln("MINUTE: " + Calendar::get(Calendar::MINUTE));
440 logln("SECOND: " + Calendar::get(Calendar::SECOND));
441 logln("MILLISECOND: " + Calendar::get(Calendar::MILLISECOND));
442 logln("ZONE_OFFSET: "
443 + (Calendar::get(Calendar::ZONE_OFFSET)/(60*60*1000))); // in hours
445 + (Calendar::get(Calendar::DST_OFFSET)/(60*60*1000))); // in hours
452 void CalendarRegressionTest::test4059654() {
453 UErrorCode status
= U_ZERO_ERROR
;
454 GregorianCalendar
*gc
= new GregorianCalendar(status
);
455 if(U_FAILURE(status
)) {
456 dataerrln("Error creating Calendar: %s", u_errorName(status
));
461 gc
->set(1997, 3, 1, 15, 16, 17); // April 1, 1997
463 gc
->set(UCAL_HOUR
, 0);
464 gc
->set(UCAL_AM_PM
, UCAL_AM
);
465 gc
->set(UCAL_MINUTE
, 0);
466 gc
->set(UCAL_SECOND
, 0);
467 gc
->set(UCAL_MILLISECOND
, 0);
469 UDate cd
= gc
->getTime(status
);
470 GregorianCalendar
*exp
= new GregorianCalendar(1997, 3, 1, 0, 0, 0, status
);
471 if (cd
!= exp
->getTime(status
))
472 errln(UnicodeString("Fail: Calendar::set broken. Got ") + cd
+ " Want " + exp
->getTime(status
));
481 void CalendarRegressionTest::test4061476()
483 UErrorCode status
= U_ZERO_ERROR
;
484 SimpleDateFormat
*fmt
= new SimpleDateFormat(UnicodeString("ddMMMyy"), Locale::getUK(),status
);
485 Calendar
*cal
= Calendar::createInstance(TimeZone::createTimeZone("GMT"),
486 Locale::getUK(),status
);
487 if(U_FAILURE(status
)) {
488 dataerrln("Error creating Calendar: %s", u_errorName(status
));
493 fmt
->adoptCalendar(cal
);
495 UDate date
= fmt
->parse("29MAY97", status
);
496 failure(status
, "fmt->parse");
497 cal
->setTime(date
, status
);
498 failure(status
, "cal->setTime");
500 //catch (Exception e) {;}
501 cal
->set(UCAL_HOUR_OF_DAY
, 13);
502 logln(UnicodeString("Hour: ")+cal
->get(UCAL_HOUR_OF_DAY
, status
));
503 cal
->add(UCAL_HOUR_OF_DAY
, 6,status
);
504 logln(UnicodeString("Hour: ")+cal
->get(UCAL_HOUR_OF_DAY
, status
));
505 if (cal
->get(UCAL_HOUR_OF_DAY
, status
) != 19)
506 errln(UnicodeString("Fail: Want 19 Got ") + cal
->get(UCAL_HOUR_OF_DAY
, status
));
514 void CalendarRegressionTest::test4070502()
516 UErrorCode status
= U_ZERO_ERROR
;
517 Calendar
*cal
= new GregorianCalendar(status
);
518 if(status
== U_USING_FALLBACK_WARNING
|| U_FAILURE(status
)) {
519 dataerrln("Error creating Calendar: %s", u_errorName(status
));
523 UDate d
= getAssociatedDate(makeDate(1998,0,30), status
);
524 cal
->setTime(d
,status
);
525 if (cal
->get(UCAL_DAY_OF_WEEK
,status
) == UCAL_SATURDAY
||
526 cal
->get(UCAL_DAY_OF_WEEK
,status
) == UCAL_SUNDAY
)
527 errln(UnicodeString("Fail: Want weekday Got ") + d
);
533 * Get the associated date starting from a specified date
534 * NOTE: the unnecessary "getTime()'s" below are a work-around for a
535 * bug in jdk 1.1.3 (and probably earlier versions also)
537 * @param date The date to start from
540 CalendarRegressionTest::getAssociatedDate(UDate d
, UErrorCode
& status
)
542 GregorianCalendar
*cal
= new GregorianCalendar(status
);
543 cal
->setTime(d
,status
);
544 //cal.add(field, amount); //<-- PROBLEM SEEN WITH field = DATE,MONTH
545 // cal.getTime(); // <--- REMOVE THIS TO SEE BUG
547 int32_t wd
= cal
->get(UCAL_DAY_OF_WEEK
, status
);
548 if (wd
== UCAL_SATURDAY
|| wd
== UCAL_SUNDAY
) {
549 cal
->add(UCAL_DATE
, 1, status
);
556 UDate dd
= cal
->getTime(status
);
564 void CalendarRegressionTest::test4071197()
570 void CalendarRegressionTest::dowTest(UBool lenient
)
572 UErrorCode status
= U_ZERO_ERROR
;
573 GregorianCalendar
*cal
= new GregorianCalendar(status
);
574 if(U_FAILURE(status
)) {
575 dataerrln("Error creating Calendar: %s", u_errorName(status
));
579 cal
->set(1997, UCAL_AUGUST
, 12); // Wednesday
580 // cal.getTime(); // Force update
581 cal
->setLenient(lenient
);
582 cal
->set(1996, UCAL_DECEMBER
, 1); // Set the date to be December 1, 1996
583 int32_t dow
= cal
->get(UCAL_DAY_OF_WEEK
, status
);
584 int32_t min
= cal
->getMinimum(UCAL_DAY_OF_WEEK
);
585 int32_t max
= cal
->getMaximum(UCAL_DAY_OF_WEEK
);
586 //logln(cal.getTime().toString());
587 if (min
!= UCAL_SUNDAY
|| max
!= UCAL_SATURDAY
)
588 errln("FAIL: Min/max bad");
589 if (dow
< min
|| dow
> max
)
590 errln("FAIL: Day of week %d out of range [%d,%d]\n", dow
, min
, max
);
591 if (dow
!= UCAL_SUNDAY
)
592 errln("FAIL: Day of week should be SUNDAY Got " + dow
);
594 if(U_FAILURE(status
)) {
595 errln("Error checking Calendar: %s", u_errorName(status
));
600 if(cal
->getActualMinimum(UCAL_DAY_OF_WEEK
, status
) != min
) {
601 errln("FAIL: actual minimum differs from minimum");
603 if(cal
->getActualMinimum(Calendar::DAY_OF_WEEK
, status
) != min
) {
604 errln("FAIL: actual minimum (Calendar::DAY_OF_WEEK, status) differs from minimum");
606 if(cal
->getActualMinimum(Calendar::DAY_OF_WEEK
) != min
) {
607 errln("FAIL: actual minimum (Calendar::DAY_OF_WEEK) differs from minimum");
609 if(((Calendar
*)cal
)->getActualMinimum(UCAL_DAY_OF_WEEK
, status
) != min
) {
610 errln("FAIL: actual minimum (UCAL_DAY_OF_WEEK, status) differs from minimum");
612 // NOTE: This function does not exist! jitterbug #3016
613 // if(((Calendar*)cal)->getActualMinimum(Calendar::DAY_OF_WEEK, status) != min) {
614 // errln("FAIL: actual minimum (Calendar::DAY_OF_WEEK, status) differs from minimum");
616 if(U_FAILURE(status
)) {
617 errln("Error getting actual minimum: %s", u_errorName(status
));
627 void CalendarRegressionTest::test4071385()
629 UErrorCode status
= U_ZERO_ERROR
;
630 Calendar
*cal
= Calendar::createInstance(status
);
631 if(U_FAILURE(status
)) {
632 dataerrln("Error creating Calendar: %s", u_errorName(status
));
636 cal
->setTime(makeDate(1998, UCAL_JUNE
, 24),status
);
637 cal
->set(UCAL_MONTH
, UCAL_NOVEMBER
); // change a field
638 //logln(cal.getTime().toString());
639 if (cal
->getTime(status
) != makeDate(1998, UCAL_NOVEMBER
, 24))
648 void CalendarRegressionTest::test4073929()
650 UErrorCode status
= U_ZERO_ERROR
;
651 GregorianCalendar
*foo1
= new GregorianCalendar(1997, 8, 27,status
);
652 if(U_FAILURE(status
)) {
653 dataerrln("Error creating Calendar: %s", u_errorName(status
));
657 logln("foo1@%.0f - %d-%d-%d %d:%d:%d.%ds\n", foo1
->getTime(status
),
658 foo1
->get(UCAL_YEAR
, status
),
659 foo1
->get(UCAL_MONTH
, status
),
660 foo1
->get(UCAL_DATE
, status
),
661 foo1
->get(UCAL_HOUR
, status
),
662 foo1
->get(UCAL_MINUTE
, status
),
663 foo1
->get(UCAL_SECOND
, status
),
664 foo1
->get(UCAL_MILLISECOND
,status
));
665 foo1
->add(UCAL_DATE
, + 1, status
);
666 logln("foo1@%.0f - %d-%d-%d %d:%d:%d.%ds after +\n", foo1
->getTime(status
),
667 foo1
->get(UCAL_YEAR
, status
),
668 foo1
->get(UCAL_MONTH
, status
),
669 foo1
->get(UCAL_DATE
, status
),
670 foo1
->get(UCAL_HOUR
, status
),
671 foo1
->get(UCAL_MINUTE
, status
),
672 foo1
->get(UCAL_SECOND
, status
),
673 foo1
->get(UCAL_MILLISECOND
,status
));
674 foo1
->add(UCAL_DATE
, - 1, status
);
675 logln("foo1@%.0f - %d-%d-%d %d:%d:%d.%ds after -\n", foo1
->getTime(status
),
676 foo1
->get(UCAL_YEAR
, status
),
677 foo1
->get(UCAL_MONTH
, status
),
678 foo1
->get(UCAL_DATE
, status
),
679 foo1
->get(UCAL_HOUR
, status
),
680 foo1
->get(UCAL_MINUTE
, status
),
681 foo1
->get(UCAL_SECOND
, status
),
682 foo1
->get(UCAL_MILLISECOND
, status
));
684 foo1
->add(UCAL_DATE
, + 1, status
);
685 int32_t testyear
= foo1
->get(UCAL_YEAR
, status
);
686 int32_t testmonth
= foo1
->get(UCAL_MONTH
, status
);
687 int32_t testday
= foo1
->get(UCAL_DATE
, status
);
688 if (testyear
!= 1997 ||
691 errln("Fail: Calendar not initialized");
699 void CalendarRegressionTest::test4083167()
701 UErrorCode status
= U_ZERO_ERROR
;
702 TimeZone
*saveZone
= TimeZone::createDefault();
704 TimeZone
*newZone
= TimeZone::createTimeZone("UTC");
705 TimeZone::setDefault(*newZone
);
706 UDate firstDate
= Calendar::getNow();
707 Calendar
*cal
= new GregorianCalendar(status
);
708 if(U_FAILURE(status
)) {
709 dataerrln("Error creating Calendar: %s", u_errorName(status
));
713 cal
->setTime(firstDate
,status
);
714 int32_t hr
= cal
->get(UCAL_HOUR_OF_DAY
, status
);
715 int32_t min
= cal
->get(UCAL_MINUTE
, status
);
716 int32_t sec
= cal
->get(UCAL_SECOND
, status
);
717 int32_t msec
= cal
->get(UCAL_MILLISECOND
, status
);
718 double firstMillisInDay
= hr
* 3600000 + min
* 60000 + sec
* 1000 + msec
;
720 //logln("Current time: " + firstDate.toString());
722 for (int32_t validity
=0; validity
<30; validity
++) {
723 UDate lastDate
= firstDate
+ validity
*1000*24*60*60.0;
724 cal
->setTime(lastDate
, status
);
725 hr
= cal
->get(UCAL_HOUR_OF_DAY
, status
);
726 min
= cal
->get(UCAL_MINUTE
, status
);
727 sec
= cal
->get(UCAL_SECOND
, status
);
728 msec
= cal
->get(UCAL_MILLISECOND
, status
);
729 double millisInDay
= hr
* 3600000.0 + min
* 60000.0 + sec
* 1000.0 + msec
;
730 if (firstMillisInDay
!= millisInDay
)
731 errln(UnicodeString("Day has shifted ") + lastDate
);
735 TimeZone::setDefault(*saveZone
);
746 void CalendarRegressionTest::test4086724()
748 UErrorCode status
= U_ZERO_ERROR
;
749 SimpleDateFormat
*date
;
750 TimeZone
*saveZone
= TimeZone::createDefault();
751 Locale saveLocale
= Locale::getDefault();
753 Locale::setDefault(Locale::getUK(),status
);
754 TimeZone
*newZone
= TimeZone::createTimeZone("GMT");
755 TimeZone::setDefault(*newZone
);
756 date
= new SimpleDateFormat(UnicodeString("dd MMM yyy (zzzz) 'is in week' ww"),status
);
757 Calendar
*cal
= Calendar::createInstance(status
);
758 if(U_FAILURE(status
)) {
759 dataerrln("Error creating Calendar: %s", u_errorName(status
));
765 cal
->set(1997,UCAL_SEPTEMBER
,30);
766 UDate now
= cal
->getTime(status
);
768 FieldPosition
pos(FieldPosition::DONT_CARE
);
769 logln(date
->format(now
, temp
, pos
));
770 cal
->set(1997,UCAL_JANUARY
,1);
771 now
=cal
->getTime(status
);
772 logln(date
->format(now
,temp
, pos
));
773 cal
->set(1997,UCAL_JANUARY
,8);
774 now
=cal
->getTime(status
);
775 logln(date
->format(now
,temp
, pos
));
776 cal
->set(1996,UCAL_DECEMBER
,31);
777 now
=cal
->getTime(status
);
778 logln(date
->format(now
,temp
, pos
));
781 Locale::setDefault(saveLocale
,status
);
782 TimeZone::setDefault(*saveZone
);
784 logln("*** THE RESULTS OF THIS TEST MUST BE VERIFIED MANUALLY ***");
795 void CalendarRegressionTest::test4092362() {
796 UErrorCode status
= U_ZERO_ERROR
;
797 GregorianCalendar
*cal1
= new GregorianCalendar(1997, 10, 11, 10, 20, 40,status
);
798 if (U_FAILURE(status
)) {
799 dataerrln("Fail new GregorianCalendar: %s", u_errorName(status
));
803 /*cal1.set( Calendar::YEAR, 1997 );
804 cal1.set( Calendar::MONTH, 10 );
805 cal1.set( Calendar::DATE, 11 );
806 cal1.set( Calendar::HOUR, 10 );
807 cal1.set( Calendar::MINUTE, 20 );
808 cal1.set( Calendar::SECOND, 40 ); */
810 logln( UnicodeString(" Cal1 = ") + cal1
->getTime(status
) );
811 logln( UnicodeString(" Cal1 time in ms = ") + cal1
->get(UCAL_MILLISECOND
,status
) );
812 for (int32_t k
= 0; k
< 100 ; k
++)
815 GregorianCalendar
*cal2
= new GregorianCalendar(1997, 10, 11, 10, 20, 40,status
);
816 /*cal2.set( Calendar::YEAR, 1997 );
817 cal2.set( Calendar::MONTH, 10 );
818 cal2.set( Calendar::DATE, 11 );
819 cal2.set( Calendar::HOUR, 10 );
820 cal2.set( Calendar::MINUTE, 20 );
821 cal2.set( Calendar::SECOND, 40 ); */
823 logln( UnicodeString(" Cal2 = ") + cal2
->getTime(status
) );
824 logln( UnicodeString(" Cal2 time in ms = ") + cal2
->get(UCAL_MILLISECOND
,status
) );
826 errln("Fail: Milliseconds randomized");
835 void CalendarRegressionTest::test4095407()
837 UErrorCode status
= U_ZERO_ERROR
;
838 GregorianCalendar
*a
= new GregorianCalendar(1997,UCAL_NOVEMBER
, 13,status
);
839 if (U_FAILURE(status
)) {
840 dataerrln("Fail new GregorianCalendar: %s", u_errorName(status
));
844 int32_t dow
= a
->get(UCAL_DAY_OF_WEEK
, status
);
845 if (dow
!= UCAL_THURSDAY
)
846 errln("Fail: Want THURSDAY Got " + dow
);
854 void CalendarRegressionTest::test4096231()
856 UErrorCode status
= U_ZERO_ERROR
;
857 TimeZone
*GMT
= TimeZone::createTimeZone("GMT");
858 TimeZone
*PST
= TimeZone::createTimeZone("PST");
859 int32_t sec
= 0, min
= 0, hr
= 0, day
= 1, month
= 10, year
= 1997;
861 Calendar
*cal1
= new GregorianCalendar(*PST
,status
);
862 if (U_FAILURE(status
)) {
863 dataerrln("Failure new GregorianCalendar: %s", u_errorName(status
));
869 cal1
->setTime(880698639000.0,status
);
870 // Issue 1: Changing the timezone doesn't change the
871 // represented time. The old API, pre 1.2.2a requires
872 // setTime to be called in order to update the time fields after the time
873 // zone has been set.
875 logln(UnicodeString("PST 1 is: ") + (h1
=cal1
->get(UCAL_HOUR_OF_DAY
, status
)));
876 cal1
->setTimeZone(*GMT
);
877 logln(UnicodeString("GMT 2 is: ") + (h2
=cal1
->get(UCAL_HOUR_OF_DAY
, status
)));
878 if ((*GMT
!= *PST
) && (h1
== h2
))
879 errln("Fail: Hour same in different zones");
881 Calendar
*cal2
= new GregorianCalendar(*GMT
,status
);
882 Calendar
*cal3
= new GregorianCalendar(*PST
,status
);
883 cal2
->set(UCAL_MILLISECOND
, 0);
884 cal3
->set(UCAL_MILLISECOND
, 0);
886 cal2
->set(cal1
->get(UCAL_YEAR
,status
),
887 cal1
->get(UCAL_MONTH
,status
),
888 cal1
->get(UCAL_DATE
,status
),
889 cal1
->get(UCAL_HOUR_OF_DAY
,status
),
890 cal1
->get(UCAL_MINUTE
,status
),
891 cal1
->get(UCAL_SECOND
,status
));
894 logln(UnicodeString("RGMT 1 is: ") + (t1
=cal2
->getTime(status
)));
895 cal3
->set(year
, month
, day
, hr
, min
, sec
);
896 logln(UnicodeString("RPST 1 is: ") + (t2
=cal3
->getTime(status
)));
897 cal3
->setTimeZone(*GMT
);
898 logln(UnicodeString("RGMT 2 is: ") + (t3
=cal3
->getTime(status
)));
899 cal3
->set(cal1
->get(UCAL_YEAR
,status
),
900 cal1
->get(UCAL_MONTH
,status
),
901 cal1
->get(UCAL_DATE
,status
),
902 cal1
->get(UCAL_HOUR_OF_DAY
,status
),
903 cal1
->get(UCAL_MINUTE
,status
),
904 cal1
->get(UCAL_SECOND
,status
));
905 // Issue 2: Calendar continues to use the timezone in its
906 // constructor for set() conversions, regardless
907 // of calls to setTimeZone()
908 logln(UnicodeString("RGMT 3 is: ") + (t4
=cal3
->getTime(status
)));
912 errln("Fail: Calendar zone behavior faulty");
924 void CalendarRegressionTest::test4096539()
926 UErrorCode status
= U_ZERO_ERROR
;
927 int32_t y
[] = {31,28,31,30,31,30,31,31,30,31,30,31};
929 for (int32_t x
=0;x
<12;x
++) {
930 GregorianCalendar
*gc
= new
931 GregorianCalendar(1997,x
,y
[x
], status
);
932 if (U_FAILURE(status
)) {
933 dataerrln("Fail new GregorianCalendar: %s", u_errorName(status
));
938 log(UnicodeString("") + (m1
=gc
->get(UCAL_MONTH
,status
)+1)+UnicodeString("/")+
939 gc
->get(UCAL_DATE
,status
)+"/"+gc
->get(UCAL_YEAR
,status
)+
942 gc
->add(UCAL_MONTH
, 1,status
);
943 logln(UnicodeString("") + (m2
=gc
->get(UCAL_MONTH
,status
)+1)+UnicodeString("/")+
944 gc
->get(UCAL_DATE
,status
)+"/"+gc
->get(UCAL_YEAR
,status
)
946 int32_t m
= (m1
% 12) + 1;
948 errln(UnicodeString("Fail: Want ") + m
+ " Got " + m2
);
957 void CalendarRegressionTest::test41003112()
959 UErrorCode status
= U_ZERO_ERROR
;
960 GregorianCalendar
*cal
= (GregorianCalendar
*)Calendar::createInstance(status
);
961 if(U_FAILURE(status
)) {
962 dataerrln("Error creating calendar: %s", u_errorName(status
));
966 cal
->set(UCAL_YEAR
, 1997);
967 cal
->set(UCAL_DAY_OF_YEAR
, 1);
968 //UDate d = cal->getTime(status); // Should be Jan 1
969 //logln(d.toString());
970 if (cal
->get(UCAL_DAY_OF_YEAR
, status
) != 1)
971 errln("Fail: DAY_OF_YEAR not set");
978 void CalendarRegressionTest::test4103271()
980 UErrorCode status
= U_ZERO_ERROR
;
981 SimpleDateFormat
sdf(status
);
982 int32_t numYears
=40, startYear
=1997, numDays
=15;
983 UnicodeString output
, testDesc
, str
, str2
;
984 GregorianCalendar
*testCal
= (GregorianCalendar
*)Calendar::createInstance(status
);
985 if(U_FAILURE(status
)) {
986 dataerrln("Error creating calendar: %s", u_errorName(status
));
991 sdf
.adoptCalendar(testCal
);
992 sdf
.applyPattern("EEE dd MMM yyyy 'WOY'ww'-'YYYY 'DOY'DDD");
994 for (int32_t firstDay
=1; firstDay
<=2; firstDay
++) {
995 for (int32_t minDays
=1; minDays
<=7; minDays
++) {
996 testCal
->setMinimalDaysInFirstWeek((uint8_t)minDays
);
997 testCal
->setFirstDayOfWeek((UCalendarDaysOfWeek
)firstDay
);
998 testDesc
= (UnicodeString("Test") + firstDay
+ minDays
);
999 logln(testDesc
+ " => 1st day of week=" +
1001 ", minimum days in first week=" +
1003 for (int32_t j
=startYear
; j
<=startYear
+numYears
; j
++) {
1004 testCal
->set(j
,11,25);
1005 for(int32_t i
=0; i
<numDays
; i
++) {
1006 testCal
->add(UCAL_DATE
,1,status
);
1007 UnicodeString calWOY
;
1008 int32_t actWOY
= testCal
->get(UCAL_WEEK_OF_YEAR
,status
);
1009 if (actWOY
< 1 || actWOY
> 53) {
1010 UDate d
= testCal
->getTime(status
);
1011 //calWOY = String.valueOf(actWOY);
1013 FieldPosition
pos(FieldPosition::DONT_CARE
);
1014 output
= testDesc
+ " - " + sdf
.format(d
,temp
,pos
) + "\t";
1015 output
= output
+ "\t" + actWOY
;
1025 3, 52, 52, 52, 52, 52, 52, 52,
1026 1, 1, 1, 1, 1, 1, 1,
1027 2, 2, 2, 2, 2, 2, 2,
1028 4, 52, 52, 52, 52, 52, 52, 52,
1029 53, 53, 53, 53, 53, 53, 53,
1030 1, 1, 1, 1, 1, 1, 1,
1032 testCal
->setFirstDayOfWeek(UCAL_SUNDAY
);
1033 for (int32_t j
=0; j
<44; j
+=22) {
1034 logln(UnicodeString("Minimal days in first week = ") + DATA
[j
] +
1035 " Week starts on Sunday");
1036 testCal
->setMinimalDaysInFirstWeek((uint8_t)DATA
[j
]);
1037 testCal
->set(1997, UCAL_DECEMBER
, 21);
1038 for (int32_t i
=0; i
<21; ++i
) {
1039 int32_t woy
= testCal
->get(UCAL_WEEK_OF_YEAR
,status
);
1041 log(UnicodeString("") + sdf
.format(testCal
->getTime(status
), str
) +
1042 UnicodeString(" ") + woy
);
1043 if (woy
!= DATA
[j
+ 1 + i
]) {
1049 // Now compute the time from the fields, and make sure we
1050 // get the same answer back. This is a round-trip test.
1051 UDate save
= testCal
->getTime(status
);
1053 testCal
->set(UCAL_YEAR_WOY
, DATA
[j
+1+i
] < 25 ? 1998 : 1997);
1054 testCal
->set(UCAL_WEEK_OF_YEAR
, DATA
[j
+1+i
]);
1055 testCal
->set(UCAL_DAY_OF_WEEK
, (i%7
) + UCAL_SUNDAY
);
1056 if (testCal
->getTime(status
) != save
) {
1058 logln(UnicodeString(" Parse failed: ") +
1059 sdf
.format(testCal
->getTime(status
), str
));
1063 testCal
->setTime(save
,status
);
1064 testCal
->add(UCAL_DATE
, 1,status
);
1067 // Test field disambiguation with a few special hard-coded cases.
1068 // This shouldn't fail if the above cases aren't failing.
1069 int32_t DISAM_int
[] = {
1071 1997, 1998, 1, UCAL_SUNDAY
,
1072 (1998), (1998), (2), (UCAL_SATURDAY
),
1073 (1998), (1998), (53), (UCAL_THURSDAY
),
1074 (1999), (1998), (53), (UCAL_FRIDAY
)
1077 UDate DISAM_date
[] = {
1078 makeDate(1997, UCAL_DECEMBER
, 28),
1079 makeDate(1998, UCAL_JANUARY
, 10),
1080 makeDate(1998, UCAL_DECEMBER
, 31),
1081 makeDate(1999, UCAL_JANUARY
, 1)
1084 testCal
->setMinimalDaysInFirstWeek(3);
1085 testCal
->setFirstDayOfWeek(UCAL_SUNDAY
);
1088 /* Enable this code to display various WOY values
1090 for (i=25; i<38; ++i) {
1091 testCal->set(1996, Calendar::DECEMBER, i);
1092 UDate got = testCal->getTime(status);
1094 logln(UnicodeString("") + sdf.format(got, str));
1096 for (i=25; i<38; ++i) {
1097 testCal->set(1997, Calendar::DECEMBER, i);
1098 UDate got = testCal->getTime(status);
1100 logln(UnicodeString("") + sdf.format(got, str));
1102 for (i=25; i<38; ++i) {
1103 testCal->set(1998, UCAL_DECEMBER, i);
1104 UDate got = testCal->getTime(status);
1106 logln(UnicodeString("") + sdf.format(got, str));
1110 for (i
=0; i
< 16; i
+= 4) {
1111 int32_t y
= DISAM_int
[i
];
1112 int32_t ywoy
= DISAM_int
[i
+1];
1113 int32_t woy
= DISAM_int
[i
+2];
1114 int32_t dow
= DISAM_int
[i
+3];
1115 UDate exp
= DISAM_date
[i
/4];
1117 testCal
->set(UCAL_YEAR
, y
);
1118 testCal
->set(UCAL_WEEK_OF_YEAR
, woy
);
1119 testCal
->set(UCAL_DAY_OF_WEEK
, dow
);
1120 UDate got
= testCal
->getTime(status
);
1123 log(UnicodeString("Y") + y
+ "-W" + woy
+
1124 "-DOW" + dow
+ " expect:" + sdf
.format(exp
, str
) +
1125 " got:" + sdf
.format(got
, str2
));
1127 log(" FAIL (%s:%d, i=%d)", __FILE__
, __LINE__
, i
);
1128 logln(CalendarTest::calToStr(*testCal
));
1129 testCal
->setTime(exp
, status
);
1130 logln(CalendarTest::calToStr(*testCal
) + UnicodeString( " <<< expected "));
1136 testCal
->set(UCAL_YEAR_WOY
, ywoy
);
1137 testCal
->set(UCAL_WEEK_OF_YEAR
, woy
);
1138 testCal
->set(UCAL_DAY_OF_WEEK
, dow
);
1139 got
= testCal
->getTime(status
);
1142 log(UnicodeString("YWOY") + ywoy
+ "-W" + woy
+
1143 "-DOW" + dow
+ " expect:" + sdf
.format(exp
, str
) +
1144 " got:" + sdf
.format(got
, str2
));
1151 // Now try adding and rolling
1152 UDate ADDROLL_date
[] = {
1153 makeDate(1998, UCAL_DECEMBER
, 25), makeDate(1999, UCAL_JANUARY
, 1),
1154 makeDate(1997, UCAL_DECEMBER
, 28), makeDate(1998, UCAL_JANUARY
, 4),
1155 makeDate(1998, UCAL_DECEMBER
, 27), makeDate(1997, UCAL_DECEMBER
, 28),
1156 makeDate(1999, UCAL_JANUARY
, 2), makeDate(1998, UCAL_JANUARY
, 3),
1159 int32_t ADDROLL_int
[]= {
1167 UBool ADDROLL_bool
[] = {
1174 testCal
->setMinimalDaysInFirstWeek(3);
1175 testCal
->setFirstDayOfWeek(UCAL_SUNDAY
);
1176 for (i
=0; i
<8; i
+= 2) {
1177 int32_t amount
= ADDROLL_int
[i
/2];
1178 UDate before
= ADDROLL_date
[i
];
1179 UDate after
= ADDROLL_date
[i
+1];
1181 testCal
->setTime(before
,status
);
1182 if (ADDROLL_bool
[i
/2])
1183 testCal
->add(UCAL_WEEK_OF_YEAR
, amount
,status
);
1185 testCal
->roll(UCAL_WEEK_OF_YEAR
, amount
,status
);
1186 UDate got
= testCal
->getTime(status
);
1189 UnicodeString opTypeStr
;
1190 if (ADDROLL_bool
[i
/2]) {
1191 opTypeStr
= UnicodeString("add(WOY,", "");
1193 opTypeStr
= UnicodeString("roll(WOY,", "");
1195 log(opTypeStr
+ amount
+ ") " + sdf
.format(before
, str
) + " => " +
1196 sdf
.format(got
, str2
));
1199 logln(UnicodeString(" exp:") + sdf
.format(after
, str
) + " FAIL");
1204 testCal
->setTime(after
,status
);
1205 if (ADDROLL_bool
[i
/2])
1206 testCal
->add(UCAL_WEEK_OF_YEAR
, -amount
,status
);
1208 testCal
->roll(UCAL_WEEK_OF_YEAR
, -amount
,status
);
1209 got
= testCal
->getTime(status
);
1212 log(opTypeStr
+ (-amount
) + ") " + sdf
.format(after
, str
) + " => " +
1213 sdf
.format(got
, str2
));
1214 if (before
!= got
) {
1216 logln(UnicodeString(" exp:") + sdf
.format(before
, str
) + " FAIL");
1222 errln("Fail: Week of year misbehaving");
1228 void CalendarRegressionTest::test4106136()
1230 UErrorCode status
= U_ZERO_ERROR
;
1231 Locale saveLocale
= Locale::getDefault();
1233 Locale locales
[] = { Locale::getChinese(), Locale::getChina() };
1234 for (int32_t i
=0; i
<2; ++i
) {
1235 Locale::setDefault(locales
[i
], status
);
1236 failure(status
, "Locale::setDefault");
1237 int32_t count1
, count2
, count3
;
1238 Calendar::getAvailableLocales(count1
);
1239 DateFormat::getAvailableLocales(count2
);
1240 NumberFormat::getAvailableLocales(count3
);
1242 count1
, count2
, count3
1244 for (int32_t j
=0; j
<3; ++j
) {
1247 dataerrln(UnicodeString("Fail: No locales for ") + locales
[i
].getName());
1252 Locale::setDefault(saveLocale
,status
);
1259 void CalendarRegressionTest::test4108764()
1261 UErrorCode status
= U_ZERO_ERROR
;
1262 Calendar
*cal
= Calendar::createInstance(status
);
1263 if(U_FAILURE(status
)) {
1264 dataerrln("Error creating calendar %s", u_errorName(status
));
1268 UDate d00
= makeDate(1997, UCAL_MARCH
, 15, 12, 00, 00);
1269 UDate d01
= makeDate(1997, UCAL_MARCH
, 15, 12, 00, 56);
1270 UDate d10
= makeDate(1997, UCAL_MARCH
, 15, 12, 34, 00);
1271 UDate d11
= makeDate(1997, UCAL_MARCH
, 15, 12, 34, 56);
1272 UDate epoch
= makeDate(1970, UCAL_JANUARY
, 1);
1274 cal
->setTime(d11
,status
);
1276 cal
->clear( UCAL_MINUTE
);
1277 logln(UnicodeString("") + cal
->getTime(status
));
1278 if (cal
->getTime(status
) != d01
)
1279 errln("Fail: clear(MINUTE) broken");
1281 cal
->set( UCAL_SECOND
, 0 );
1282 logln(UnicodeString("") + cal
->getTime(status
));
1283 if (cal
->getTime(status
) != d00
)
1284 errln("Fail: set(SECOND, 0) broken");
1286 cal
->setTime(d11
,status
);
1287 cal
->set( UCAL_SECOND
, 0 );
1288 logln(UnicodeString("") + cal
->getTime(status
));
1289 if (cal
->getTime(status
) != d10
)
1290 errln("Fail: set(SECOND, 0) broken #2");
1292 cal
->clear( UCAL_MINUTE
);
1293 logln(UnicodeString("") + cal
->getTime(status
));
1294 if (cal
->getTime(status
) != d00
)
1295 errln("Fail: clear(MINUTE) broken #2");
1298 logln(UnicodeString("") + cal
->getTime(status
));
1299 if (cal
->getTime(status
) != epoch
)
1300 errln(UnicodeString("Fail: clear() broken Want ") + epoch
);
1308 void CalendarRegressionTest::test4114578()
1310 UErrorCode status
= U_ZERO_ERROR
;
1311 double ONE_HOUR
= 60*60*1000;
1312 Calendar
*cal
= Calendar::createInstance(status
);
1313 if(U_FAILURE(status
)) {
1314 dataerrln("Error creating calendar %s", u_errorName(status
));
1318 cal
->adoptTimeZone(TimeZone::createTimeZone("PST"));
1319 UDate onset
= makeDate(1998, UCAL_APRIL
, 5, 1, 0) + ONE_HOUR
;
1320 UDate cease
= makeDate(1998, UCAL_OCTOBER
, 25, 0, 0) + 2*ONE_HOUR
;
1324 const int32_t ADD
= 1;
1325 const int32_t ROLL
= 2;
1328 // Start Action Amt Expected_change
1329 onset
- ONE_HOUR
, ADD
, 1, ONE_HOUR
,
1330 onset
, ADD
, -1, -ONE_HOUR
,
1331 onset
- ONE_HOUR
, ROLL
, 1, ONE_HOUR
,
1332 onset
, ROLL
, -1, -ONE_HOUR
,
1333 cease
- ONE_HOUR
, ADD
, 1, ONE_HOUR
,
1334 cease
, ADD
, -1, -ONE_HOUR
,
1335 cease
- ONE_HOUR
, ROLL
, 1, ONE_HOUR
,
1336 cease
, ROLL
, -1, -ONE_HOUR
,
1339 for (int32_t i
=0; i
<32; i
+=4) {
1340 UDate date
= DATA
[i
];
1341 int32_t amt
= (int32_t) DATA
[i
+2];
1342 double expectedChange
= DATA
[i
+3];
1344 log(UnicodeString("") + date
);
1345 cal
->setTime(date
,status
);
1347 switch ((int32_t) DATA
[i
+1]) {
1349 log(UnicodeString(" add (HOUR,") + (amt
<0?"":"+")+amt
+ ")= ");
1350 cal
->add(UCAL_HOUR
, amt
,status
);
1353 log(UnicodeString(" roll(HOUR,") + (amt
<0?"":"+")+amt
+ ")= ");
1354 cal
->roll(UCAL_HOUR
, amt
,status
);
1358 log(UnicodeString("") + cal
->getTime(status
));
1360 double change
= cal
->getTime(status
) - date
;
1361 if (change
!= expectedChange
) {
1368 if (fail
) errln("Fail: roll/add misbehaves around DST onset/cease");
1375 * Make sure maximum for HOUR field is 11, not 12.
1377 void CalendarRegressionTest::test4118384()
1379 UErrorCode status
= U_ZERO_ERROR
;
1380 Calendar
*cal
= Calendar::createInstance(status
);
1381 if(U_FAILURE(status
)) {
1382 dataerrln("Error creating calendar %s", u_errorName(status
));
1386 if (cal
->getMaximum(UCAL_HOUR
) != 11 ||
1387 cal
->getLeastMaximum(UCAL_HOUR
) != 11 ||
1388 cal
->getActualMaximum(UCAL_HOUR
,status
) != 11)
1389 errln("Fail: maximum of HOUR field should be 11");
1391 // test deprecated functions
1392 if (cal
->getLeastMaximum(Calendar::HOUR
) != 11 ||
1393 cal
->getMaximum(Calendar::HOUR
) != 11) {
1394 errln("Fail: [deprecated functions] maximum of HOUR field should be 11\n");
1397 if (cal
->getGreatestMinimum(Calendar::HOUR
) != 0 ||
1398 cal
->getMinimum(Calendar::HOUR
) != 0) {
1399 errln("Fail: [deprecated functions] minimum of HOUR field should be 1\n");
1403 cal
= Calendar::createInstance(Locale("th_TH@calendar=buddhist"),status
);
1404 // test deprecated functions
1405 if (cal
->getLeastMaximum(Calendar::HOUR
) != 11 ||
1406 cal
->getMaximum(Calendar::HOUR
) != 11) {
1407 errln("Fail: Buddhist:[deprecated functions] maximum of HOUR field should be 11\n");
1410 if (cal
->getGreatestMinimum(Calendar::HOUR
) != 0 ||
1411 cal
->getMinimum(Calendar::HOUR
) != 0) {
1412 errln("Fail: Buddhist:[deprecated functions] minimum of HOUR field should be 1\n");
1416 // test deprecated functions
1417 cal
= Calendar::createInstance(Locale("ja_JP@calendar=japanese"),status
);
1418 if (cal
->getLeastMaximum(Calendar::HOUR
) != 11 ||
1419 cal
->getMaximum(Calendar::HOUR
) != 11) {
1420 errln("Fail: Japanese:[deprecated functions] maximum of HOUR field should be 11\n");
1423 if (cal
->getGreatestMinimum(Calendar::HOUR
) != 0 ||
1424 cal
->getMinimum(Calendar::HOUR
) != 0) {
1425 errln("Fail: Japanese:[deprecated functions] minimum of HOUR field should be 1\n");
1433 * Check isLeapYear for BC years.
1435 void CalendarRegressionTest::test4125881()
1437 UErrorCode status
= U_ZERO_ERROR
;
1438 GregorianCalendar
*cal
= (GregorianCalendar
*) Calendar::createInstance(status
);
1439 if(U_FAILURE(status
)) {
1440 dataerrln("Error creating calendar %s", u_errorName(status
));
1444 DateFormat
*fmt
= new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"),status
);
1445 if(U_FAILURE(status
)) {
1446 dataerrln("Error creating SimpleDateFormat - %s", u_errorName(status
));
1451 for (int32_t y
=-20; y
<=10; ++y
) {
1452 cal
->set(UCAL_ERA
, y
< 1 ? GregorianCalendar::BC
: GregorianCalendar::AD
);
1453 cal
->set(UCAL_YEAR
, y
< 1 ? 1 - y
: y
);
1455 logln(UnicodeString("") + y
+ UnicodeString(" = ") + fmt
->format(cal
->getTime(status
), temp
) + " " +
1456 cal
->isLeapYear(y
));
1457 if (cal
->isLeapYear(y
) != ((y
+40)%4
== 0))
1458 errln("Leap years broken");
1467 * Prove that GregorianCalendar is proleptic (it used to cut off
1468 * at 45 BC, and not have leap years before then).
1470 void CalendarRegressionTest::test4125892() {
1471 UErrorCode status
= U_ZERO_ERROR
;
1472 GregorianCalendar
*cal
= (GregorianCalendar
*) Calendar::createInstance(status
);
1473 if(U_FAILURE(status
)) {
1474 dataerrln("Error creating calendar %s", u_errorName(status
));
1478 DateFormat
*fmt
= new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"),status
);
1479 if(U_FAILURE(status
)) {
1480 dataerrln("Error creating SimpleDateFormat - %s", u_errorName(status
));
1485 cal
->set(UCAL_ERA
, GregorianCalendar::BC
);
1486 cal
->set(UCAL_YEAR
, 81); // 81 BC is a leap year (proleptically)
1487 cal
->set(UCAL_MONTH
, UCAL_FEBRUARY
);
1488 cal
->set(UCAL_DATE
, 28);
1489 cal
->add(UCAL_DATE
, 1,status
);
1490 if(U_FAILURE(status
))
1491 errln("add(DATE,1) failed");
1492 if (cal
->get(UCAL_DATE
,status
) != 29 ||
1493 !cal
->isLeapYear(-80)) // -80 == 81 BC
1494 errln("Calendar not proleptic");
1502 * GregorianCalendar::equals() ignores cutover date
1504 void CalendarRegressionTest::test4141665()
1506 UErrorCode status
= U_ZERO_ERROR
;
1507 GregorianCalendar
*cal
= new GregorianCalendar(status
);
1508 if(U_FAILURE(status
)) {
1509 dataerrln("Error creating calendar %s", u_errorName(status
));
1513 GregorianCalendar
*cal2
= (GregorianCalendar
*)cal
->clone();
1514 UDate cut
= cal
->getGregorianChange();
1515 UDate cut2
= cut
+ 100*24*60*60*1000.0; // 100 days later
1516 if (*cal
!= *cal2
) {
1517 errln("Cloned GregorianCalendars not equal");
1519 cal2
->setGregorianChange(cut2
,status
);
1520 if ( *cal
== *cal2
) {
1521 errln("GregorianCalendar::equals() ignores cutover");
1530 * Bug states that ArrayIndexOutOfBoundsException is thrown by GregorianCalendar::roll()
1531 * when IllegalArgumentException should be.
1533 void CalendarRegressionTest::test4142933()
1535 UErrorCode status
= U_ZERO_ERROR
;
1536 GregorianCalendar
*calendar
= new GregorianCalendar(status
);
1537 if(U_FAILURE(status
)) {
1538 dataerrln("Error creating calendar %s", u_errorName(status
));
1543 calendar
->roll((UCalendarDateFields
)-1, TRUE
, status
);
1544 if(U_SUCCESS(status
))
1545 errln("Test failed, no exception thrown");
1547 //catch (IllegalArgumentException e) {
1549 // logln("Test passed");
1551 //catch (Exception e) {
1552 //errln("Test failed. Unexpected exception is thrown: " + e);
1553 //e.printStackTrace();
1561 * GregorianCalendar handling of Dates Long.MIN_VALUE and Long.MAX_VALUE is
1562 * confusing; unless the time zone has a raw offset of zero, one or the
1563 * other of these will wrap. We've modified the test given in the bug
1564 * report to therefore only check the behavior of a calendar with a zero raw
1567 void CalendarRegressionTest::test4145158()
1569 UErrorCode status
= U_ZERO_ERROR
;
1570 GregorianCalendar
*calendar
= new GregorianCalendar(status
);
1571 if(status
== U_USING_FALLBACK_WARNING
|| U_FAILURE(status
)) {
1572 dataerrln("Error creating calendar %s", u_errorName(status
));
1577 calendar
->adoptTimeZone(TimeZone::createTimeZone("GMT"));
1579 calendar
->setTime(makeDate(INT32_MIN
),status
);
1580 int32_t year1
= calendar
->get(UCAL_YEAR
,status
);
1581 int32_t era1
= calendar
->get(UCAL_ERA
,status
);
1583 calendar
->setTime(makeDate(INT32_MAX
),status
);
1584 int32_t year2
= calendar
->get(UCAL_YEAR
,status
);
1585 int32_t era2
= calendar
->get(UCAL_ERA
,status
);
1587 if (year1
== year2
&& era1
== era2
) {
1588 errln("Fail: Long.MIN_VALUE or Long.MAX_VALUE wrapping around");
1596 * Maximum value for YEAR field wrong.
1598 // {sfb} this is not directly applicable in C++, since all
1599 // possible doubles are not representable by our Calendar.
1600 // In Java, all longs are representable.
1601 // We can determine limits programmatically
1602 // Using DBL_MAX is a bit of a hack, since for large doubles
1603 // Calendar gets squirrely and doesn't behave in any sort
1604 // of linear fashion (ie years jump around, up/down, etc) for a
1605 // small change in millis.
1606 void CalendarRegressionTest::test4145983()
1608 UErrorCode status
= U_ZERO_ERROR
;
1609 GregorianCalendar
*calendar
= new GregorianCalendar(status
);
1610 if(U_FAILURE(status
)) {
1611 dataerrln("Error creating calendar %s", u_errorName(status
));
1615 calendar
->adoptTimeZone(TimeZone::createTimeZone("GMT"));
1616 UDate DATES
[] = { LATEST_SUPPORTED_MILLIS
, EARLIEST_SUPPORTED_MILLIS
};
1617 for (int32_t i
=0; i
<2; ++i
) {
1618 calendar
->setTime(DATES
[i
], status
);
1619 int32_t year
= calendar
->get(UCAL_YEAR
,status
);
1620 int32_t maxYear
= calendar
->getMaximum(UCAL_YEAR
);
1621 if (year
> maxYear
) {
1622 errln(UnicodeString("Failed for ")+DATES
[i
]+" ms: year=" +
1623 year
+ ", maxYear=" + maxYear
);
1632 * This is a bug in the validation code of GregorianCalendar:: As reported,
1633 * the bug seems worse than it really is, due to a bug in the way the bug
1634 * report test was written. In reality the bug is restricted to the DAY_OF_YEAR
1635 * field. - liu 6/29/98
1637 void CalendarRegressionTest::test4147269()
1639 UErrorCode status
= U_ZERO_ERROR
;
1640 GregorianCalendar
*calendar
= new GregorianCalendar(status
);
1641 if(status
== U_USING_FALLBACK_WARNING
|| U_FAILURE(status
)) {
1642 dataerrln("Error creating calendar %s", u_errorName(status
));
1646 calendar
->setLenient(FALSE
);
1647 UDate date
= makeDate(1996, UCAL_JANUARY
, 3); // Arbitrary date
1648 for (int32_t field
= 0; field
< UCAL_FIELD_COUNT
; field
++) {
1649 calendar
->setTime(date
,status
);
1650 // Note: In the bug report, getActualMaximum() was called instead
1651 // of getMaximum() -- this was an error. The validation code doesn't
1652 // use getActualMaximum(), since that's too costly.
1653 int32_t max
= calendar
->getMaximum((UCalendarDateFields
)field
);
1654 int32_t value
= max
+1;
1655 calendar
->set((UCalendarDateFields
)field
, value
);
1657 calendar
->getTime(status
); // Force time computation
1658 // We expect an exception to be thrown. If we fall through
1659 // to the next line, then we have a bug.
1660 if(U_SUCCESS(status
))
1661 errln(UnicodeString("Test failed with field ") + FIELD_NAME
[field
] +
1662 ", date before: " + date
+
1663 ", date after: " + calendar
->getTime(status
) +
1664 ", value: " + value
+ " (max = " + max
+")");
1665 //} catch (IllegalArgumentException e) {}
1673 * Reported bug is that a GregorianCalendar with a cutover of Date(Long.MAX_VALUE)
1674 * doesn't behave as a pure Julian calendar.
1675 * CANNOT REPRODUCE THIS BUG
1678 CalendarRegressionTest::Test4149677()
1680 UErrorCode status
= U_ZERO_ERROR
;
1682 TimeZone
*zones
[] = {
1683 TimeZone::createTimeZone("GMT"),
1684 TimeZone::createTimeZone("PST"),
1685 TimeZone::createTimeZone("EAT")
1687 if(U_FAILURE(status
)) {
1688 errln("Couldn't create zones");
1690 // could leak memory
1693 for (int32_t i
=0; i
< 3; ++i
) {
1694 GregorianCalendar
*calendar
= new GregorianCalendar(zones
[i
], status
);
1695 if(U_FAILURE(status
)) {
1696 dataerrln("Couldnt' create calendar.: %s", u_errorName(status
));
1700 // Make sure extreme values don't wrap around
1701 calendar
->setTime(EARLIEST_SUPPORTED_MILLIS
, status
);
1702 if(U_FAILURE(status
))
1703 errln("setTime failed");
1704 if (calendar
->get(UCAL_ERA
, status
) != GregorianCalendar::BC
|| U_FAILURE(status
)) {
1705 errln("Fail: Date(EARLIEST_SUPPORTED_MILLIS) has an AD year");
1707 calendar
->setTime(LATEST_SUPPORTED_MILLIS
, status
);
1708 if(U_FAILURE(status
))
1709 errln("setTime failed");
1710 if (calendar
->get(UCAL_ERA
, status
) != GregorianCalendar::AD
|| U_FAILURE(status
)) {
1711 errln("Fail: Date(LATEST_SUPPORTED_MILLIS) has a BC year");
1714 calendar
->setGregorianChange(LATEST_SUPPORTED_MILLIS
, status
);
1715 if(U_FAILURE(status
))
1716 errln("setGregorianChange failed");
1717 // to obtain a pure Julian calendar
1719 UBool is100Leap
= calendar
->isLeapYear(100);
1722 errln("test failed with zone " + zones
[i
]->getID(temp
));
1723 errln(" cutover date is Date(Long.MAX_VALUE)");
1724 errln(" isLeapYear(100) returns: " + is100Leap
);
1729 // no need for cleanup- zones were adopted
1734 * Calendar and Date HOUR broken. If HOUR is out-of-range, Calendar
1735 * and Date classes will misbehave.
1738 CalendarRegressionTest::Test4162587()
1740 UErrorCode status
= U_ZERO_ERROR
;
1741 TimeZone
*savedef
= TimeZone::createDefault();
1742 TimeZone
*tz
= TimeZone::createTimeZone("PST");
1743 //TimeZone::adoptDefault(tz);
1744 TimeZone::setDefault(*tz
);
1746 GregorianCalendar
*cal
= new GregorianCalendar(tz
, status
);
1747 if(U_FAILURE(status
)) {
1748 dataerrln("Couldn't create calendar.: %s", u_errorName(status
));
1751 UDate d0
, dPlus
, dMinus
;
1753 for(int32_t i
=0; i
<5; ++i
) {
1754 if (i
>0) logln("---");
1757 cal
->set(1998, UCAL_APRIL
, 5, i
, 0);
1758 d0
= cal
->getTime(status
);
1759 if(U_FAILURE(status
))
1760 errln("Coudln't get time (1)");
1761 //String s0 = d.toString();
1762 logln(UnicodeString("0 ") + i
+ ": " + d0
/*s0*/);
1765 cal
->set(1998, UCAL_APRIL
, 4, i
+24, 0);
1766 dPlus
= cal
->getTime(status
);
1767 if(U_FAILURE(status
))
1768 errln("Coudln't get time (2)");
1769 //String sPlus = d.toString();
1770 logln(UnicodeString("+ ") + i
+ ": " + dPlus
/*sPlus*/);
1773 cal
->set(1998, UCAL_APRIL
, 6, i
-24, 0);
1774 dMinus
= cal
->getTime(status
);
1775 if(U_FAILURE(status
))
1776 errln("Coudln't get time (3)");
1777 //String sMinus = d.toString();
1778 logln(UnicodeString("- ") + i
+ ": " + dMinus
/*sMinus*/);
1780 if (d0
!= dPlus
|| d0
!= dMinus
) {
1781 errln("Fail: All three lines must match");
1784 TimeZone::setDefault(*savedef
);
1792 * Adding 12 months behaves differently from adding 1 year
1795 CalendarRegressionTest::Test4165343()
1797 UErrorCode status
= U_ZERO_ERROR
;
1798 GregorianCalendar
*calendar
= new GregorianCalendar(1996, UCAL_FEBRUARY
, 29, status
);
1799 if(U_FAILURE(status
)) {
1800 dataerrln("Couldn't create calendar.: %s", u_errorName(status
));
1803 UDate start
= calendar
->getTime(status
);
1804 if(U_FAILURE(status
))
1805 errln("Couldn't getTime (1)");
1806 logln(UnicodeString("init date: ") + start
);
1807 calendar
->add(UCAL_MONTH
, 12, status
);
1808 if(U_FAILURE(status
))
1809 errln("Couldn't add(MONTH, 12)");
1810 UDate date1
= calendar
->getTime(status
);
1811 if(U_FAILURE(status
))
1812 errln("Couldn't getTime (2)");
1813 logln(UnicodeString("after adding 12 months: ") + date1
);
1814 calendar
->setTime(start
, status
);
1815 if(U_FAILURE(status
))
1816 errln("Couldn't setTime");
1817 calendar
->add(UCAL_YEAR
, 1, status
);
1818 if(U_FAILURE(status
))
1819 errln("Couldn't add(YEAR, 1)");
1820 UDate date2
= calendar
->getTime(status
);
1821 if(U_FAILURE(status
))
1822 errln("Couldn't getTime (3)");
1823 logln(UnicodeString("after adding one year : ") + date2
);
1824 if (date1
== date2
) {
1825 logln("Test passed");
1827 errln("Test failed");
1834 * GregorianCalendar.getActualMaximum() does not account for first day of week.
1837 CalendarRegressionTest::Test4166109()
1842 * Su Mo Tu We Th Fr Sa
1844 * 8 9 10 11 12 13 14
1845 * 15 16 17 18 19 20 21
1846 * 22 23 24 25 26 27 28
1849 UBool passed
= TRUE
;
1850 UErrorCode status
= U_ZERO_ERROR
;
1851 UCalendarDateFields field
= UCAL_WEEK_OF_MONTH
;
1853 GregorianCalendar
*calendar
= new GregorianCalendar(Locale::getUS(), status
);
1854 if(U_FAILURE(status
)) {
1855 dataerrln("Couldn't create calendar.: %s", u_errorName(status
));
1858 calendar
->set(1998, UCAL_MARCH
, 1);
1859 calendar
->setMinimalDaysInFirstWeek(1);
1860 logln(UnicodeString("Date: ") + calendar
->getTime(status
)); // 888817448000
1862 int32_t firstInMonth
= calendar
->get(UCAL_DATE
, status
);
1863 if(U_FAILURE(status
))
1864 errln("get(D_O_M) failed");
1866 for(int32_t firstInWeek
= UCAL_SUNDAY
; firstInWeek
<= UCAL_SATURDAY
; firstInWeek
++) {
1867 calendar
->setFirstDayOfWeek((UCalendarDaysOfWeek
)firstInWeek
);
1868 int32_t returned
= calendar
->getActualMaximum(field
, status
);
1869 int32_t expected
= (31 + ((firstInMonth
- firstInWeek
+ 7)% 7) + 6) / 7;
1871 logln(UnicodeString("First day of week = ") + firstInWeek
+
1872 " getActualMaximum(WEEK_OF_MONTH, status) = " + returned
+
1873 " expected = " + expected
+
1874 ((returned
== expected
) ? " ok" : " FAIL"));
1876 if (returned
!= expected
) {
1881 errln("Test failed");
1889 * Calendar.getActualMaximum(YEAR) works wrong.
1892 CalendarRegressionTest::Test4167060()
1894 UErrorCode status
= U_ZERO_ERROR
;
1895 UCalendarDateFields field
= UCAL_YEAR
;
1896 DateFormat
*format
= new SimpleDateFormat(UnicodeString("EEE MMM dd HH:mm:ss zzz yyyy G"),
1897 Locale::getUS(), status
);
1898 if(U_FAILURE(status
)) {
1899 dataerrln("Couldn't create SimpleDateFormat - %s", u_errorName(status
));
1903 GregorianCalendar
*calendars
[] = {
1904 new GregorianCalendar(100, UCAL_NOVEMBER
, 1, status
),
1905 new GregorianCalendar(-99 /*100BC*/, UCAL_JANUARY
, 1, status
),
1906 new GregorianCalendar(1996, UCAL_FEBRUARY
, 29, status
),
1908 if(U_FAILURE(status
)) {
1909 errln("Couldn't create GregorianCalendars");
1914 UnicodeString id
[] = { "Hybrid", "Gregorian", "Julian" };
1916 for (int32_t k
=0; k
<3; ++k
) {
1917 logln("--- " + id
[k
] + " ---");
1919 for (int32_t j
=0; j
< 3; ++j
) {
1920 GregorianCalendar
*calendar
= calendars
[j
];
1922 calendar
->setGregorianChange(EARLIEST_SUPPORTED_MILLIS
, status
);
1925 calendar
->setGregorianChange(LATEST_SUPPORTED_MILLIS
, status
);
1928 if(U_FAILURE(status
))
1929 errln("setGregorianChange() failed");
1930 format
->adoptCalendar((Calendar
*)calendar
->clone());
1932 UDate dateBefore
= calendar
->getTime(status
);
1933 if(U_FAILURE(status
))
1934 errln("getTime() failed");
1936 int32_t maxYear
= calendar
->getActualMaximum(field
, status
);
1938 logln(UnicodeString("maxYear: ") + maxYear
+ " for " + format
->format(calendar
->getTime(status
), temp
));
1940 logln("date before: " + format
->format(dateBefore
, temp
));
1942 int32_t years
[] = {2000, maxYear
-1, maxYear
, maxYear
+1};
1944 for (int32_t i
= 0; i
< 4; i
++) {
1945 UBool valid
= years
[i
] <= maxYear
;
1946 calendar
->set(field
, years
[i
]);
1947 UDate dateAfter
= calendar
->getTime(status
);
1948 if(U_FAILURE(status
))
1949 errln("getTime() failed");
1950 int32_t newYear
= calendar
->get(field
, status
);
1951 if(U_FAILURE(status
))
1952 errln(UnicodeString("get(") + (int32_t)field
+ ") failed");
1953 calendar
->setTime(dateBefore
, status
); // restore calendar for next use
1954 if(U_FAILURE(status
))
1955 errln("setTime() failed");
1958 logln(UnicodeString(" Year ") + years
[i
] + (valid
? " ok " : " bad") +
1959 " => " + format
->format(dateAfter
, temp
));
1960 if (valid
&& newYear
!= years
[i
]) {
1961 errln(UnicodeString(" FAIL: ") + newYear
+ " should be valid; date, month and time shouldn't change");
1963 // {sfb} this next line is a hack, but it should work since if a
1964 // double has an exponent, adding 1 should not yield the same double
1965 else if (!valid
&& /*newYear == years[i]*/ dateAfter
+ 1.0 == dateAfter
) {
1966 errln(UnicodeString(" FAIL: ") + newYear
+ " should be invalid");
1973 delete calendars
[0];
1974 delete calendars
[1];
1975 delete calendars
[2];
1979 * Week of year is wrong at the start and end of the year.
1981 void CalendarRegressionTest::Test4197699() {
1982 UErrorCode status
= U_ZERO_ERROR
;
1983 GregorianCalendar
cal(status
);
1984 cal
.setFirstDayOfWeek(UCAL_MONDAY
);
1985 cal
.setMinimalDaysInFirstWeek(4);
1986 SimpleDateFormat
fmt("E dd MMM yyyy 'DOY='D 'WOY='w",
1987 Locale::getUS(), status
);
1988 fmt
.setCalendar(cal
);
1989 if (U_FAILURE(status
)) {
1990 dataerrln("Couldn't initialize test - %s", u_errorName(status
));
1995 2000, UCAL_JANUARY
, 1, 52,
1996 2001, UCAL_DECEMBER
, 31, 1,
1998 int32_t DATA_length
= (int32_t)(sizeof(DATA
) / sizeof(DATA
[0]));
2001 DateFormat
& dfmt
= *(DateFormat
*)&fmt
;
2002 for (int32_t i
=0; i
<DATA_length
; ) {
2004 cal
.set(DATA
[i
], DATA
[i
+1], DATA
[i
+2]);
2006 int32_t expWOY
= DATA
[i
++];
2007 int32_t actWOY
= cal
.get(UCAL_WEEK_OF_YEAR
, status
);
2008 if (expWOY
== actWOY
) {
2009 logln(UnicodeString("Ok: ") + dfmt
.format(cal
.getTime(status
), str
.remove()));
2011 errln(UnicodeString("FAIL: ") + dfmt
.format(cal
.getTime(status
), str
.remove())
2012 + ", expected WOY=" + expWOY
);
2013 cal
.add(UCAL_DATE
, -8, status
);
2014 for (int j
=0; j
<14; ++j
) {
2015 cal
.add(UCAL_DATE
, 1, status
);
2016 logln(dfmt
.format(cal
.getTime(status
), str
.remove()));
2019 if (U_FAILURE(status
)) {
2020 errln("FAIL: Unexpected error from Calendar");
2026 enum Action
{ ADD
=1, ROLL
=2 };
2027 enum Sign
{ PLUS
=1, MINUS
=2 };
2029 #define ONE_HOUR (60*60*1000)
2030 #define ONE_DAY (24*ONE_HOUR)
2033 UCalendarDateFields field
;
2034 int8_t actionMask
; // ADD or ROLL or both
2035 int8_t signMask
; // PLUS or MINUS or both
2037 int32_t before
; // ms before cutover
2038 int32_t after
; // ms after cutover
2042 * Rolling and adding across the Gregorian cutover should work as expected.
2045 void CalendarRegressionTest::TestJ81() {
2046 UErrorCode status
= U_ZERO_ERROR
;
2047 UnicodeString temp
, temp2
, temp3
;
2049 GregorianCalendar
cal(TimeZone::createTimeZone("GMT"), Locale::getUS(), status
);
2050 SimpleDateFormat
fmt("HH:mm 'w'w 'd'D E d MMM yyyy", Locale::getUS(), status
);
2051 if (U_FAILURE(status
)) {
2052 dataerrln("Error: Cannot create calendar or format - %s", u_errorName(status
));
2055 fmt
.setCalendar(cal
);
2056 // Get the Gregorian cutover
2057 UDate cutover
= cal
.getGregorianChange();
2058 UDate days
= ONE_DAY
;
2059 days
= cutover
/days
;
2060 logln(UnicodeString("Cutover: {") +
2061 fmt
.format(cutover
, temp
) + "}(epoch days-" + (int)days
+ ", jd" + (2440588 + days
) +")");
2063 // Check woy and doy handling. Reference data:
2064 /* w40 d274 Mon 1 Oct 1582
2065 w40 d275 Tue 2 Oct 1582
2066 w40 d276 Wed 3 Oct 1582
2067 w40 d277 Thu 4 Oct 1582
2068 w40 d278 Fri 15 Oct 1582
2069 w40 d279 Sat 16 Oct 1582
2070 w41 d280 Sun 17 Oct 1582
2071 w41 d281 Mon 18 Oct 1582
2072 w41 d282 Tue 19 Oct 1582
2073 w41 d283 Wed 20 Oct 1582
2074 w41 d284 Thu 21 Oct 1582
2075 w41 d285 Fri 22 Oct 1582
2076 w41 d286 Sat 23 Oct 1582
2077 w42 d287 Sun 24 Oct 1582
2078 w42 d288 Mon 25 Oct 1582
2079 w42 d289 Tue 26 Oct 1582
2080 w42 d290 Wed 27 Oct 1582
2081 w42 d291 Thu 28 Oct 1582
2082 w42 d292 Fri 29 Oct 1582
2083 w42 d293 Sat 30 Oct 1582
2084 w43 d294 Sun 31 Oct 1582
2085 w43 d295 Mon 1 Nov 1582 */
2086 int32_t DOY_DATA
[] = {
2088 1, 40, 274, UCAL_MONDAY
,
2089 4, 40, 277, UCAL_THURSDAY
,
2090 15, 40, 278, UCAL_FRIDAY
,
2091 17, 41, 280, UCAL_SUNDAY
,
2092 24, 42, 287, UCAL_SUNDAY
,
2093 25, 42, 288, UCAL_MONDAY
,
2094 26, 42, 289, UCAL_TUESDAY
,
2095 27, 42, 290, UCAL_WEDNESDAY
,
2096 28, 42, 291, UCAL_THURSDAY
,
2097 29, 42, 292, UCAL_FRIDAY
,
2098 30, 42, 293, UCAL_SATURDAY
,
2099 31, 43, 294, UCAL_SUNDAY
2101 int32_t DOY_DATA_length
= (int32_t)(sizeof(DOY_DATA
) / sizeof(DOY_DATA
[0]));
2103 for (i
=0; i
<DOY_DATA_length
; i
+=4) {
2104 // Test time->fields
2105 cal
.set(1582, UCAL_OCTOBER
, DOY_DATA
[i
]);
2106 int32_t woy
= cal
.get(UCAL_WEEK_OF_YEAR
, status
);
2107 int32_t doy
= cal
.get(UCAL_DAY_OF_YEAR
, status
);
2108 int32_t dow
= cal
.get(UCAL_DAY_OF_WEEK
, status
);
2109 if (U_FAILURE(status
)) {
2110 errln("Error: get() failed");
2113 if (woy
!= DOY_DATA
[i
+1] || doy
!= DOY_DATA
[i
+2] || dow
!= DOY_DATA
[i
+3]) {
2114 errln((UnicodeString
)"Fail: expect woy=" + DOY_DATA
[i
+1] +
2115 ", doy=" + DOY_DATA
[i
+2] + ", dow=" + DOY_DATA
[i
+3] + " on " +
2116 fmt
.format(cal
.getTime(status
), temp
.remove()) +
2117 " set(1582,OCTOBER, " + DOY_DATA
[i
] + ")");
2118 logln(CalendarTest::calToStr(cal
));
2119 status
= U_ZERO_ERROR
;
2121 logln((UnicodeString
)"PASS: expect woy=" + DOY_DATA
[i
+1] +
2122 ", doy=" + DOY_DATA
[i
+2] + ", dow=" + DOY_DATA
[i
+3] + " on " +
2123 fmt
.format(cal
.getTime(status
), temp
.remove()));
2124 logln(CalendarTest::calToStr(cal
));
2125 status
= U_ZERO_ERROR
;
2127 // Test fields->time for WOY
2129 cal
.set(UCAL_YEAR
, 1582);
2130 cal
.set(UCAL_WEEK_OF_YEAR
, DOY_DATA
[i
+1]);
2131 cal
.set(UCAL_DAY_OF_WEEK
, DOY_DATA
[i
+3]);
2132 int32_t dom
= cal
.get(UCAL_DATE
, status
);
2133 if (U_FAILURE(status
)) {
2134 errln("Error: get() failed");
2137 if (dom
!= DOY_DATA
[i
]) {
2138 errln((UnicodeString
)"Fail: set woy=" + DOY_DATA
[i
+1] +
2139 " dow=" + DOY_DATA
[i
+3] + " => " +
2140 fmt
.format(cal
.getTime(status
), temp
.remove()) +
2141 ", expected 1582 Oct " + DOY_DATA
[i
]);
2142 logln(CalendarTest::calToStr(cal
));
2143 status
= U_ZERO_ERROR
;
2146 // Test fields->time for DOY
2148 cal
.set(UCAL_YEAR
, 1582);
2149 cal
.set(UCAL_DAY_OF_YEAR
, DOY_DATA
[i
+2]);
2150 dom
= cal
.get(UCAL_DATE
, status
);
2151 if (U_FAILURE(status
)) {
2152 errln("Error: get() failed");
2155 if (dom
!= DOY_DATA
[i
]) {
2156 errln((UnicodeString
)"Fail: set doy=" + DOY_DATA
[i
+2] +
2158 fmt
.format(cal
.getTime(status
), temp
.remove()) +
2159 ", expected 1582 Oct " + DOY_DATA
[i
]);
2160 status
= U_ZERO_ERROR
;
2163 status
= U_ZERO_ERROR
;
2165 #define ADD_ROLL ADD|ROLL
2166 #define PLUS_MINUS PLUS|MINUS
2169 { UCAL_WEEK_OF_YEAR
, ADD_ROLL
, PLUS_MINUS
, 1, -ONE_DAY
, +6*ONE_DAY
},
2170 { UCAL_WEEK_OF_YEAR
, ADD_ROLL
, PLUS_MINUS
, 1, -ONE_DAY
, +6*ONE_DAY
},
2171 { UCAL_WEEK_OF_MONTH
, ADD
|ROLL
, PLUS
|MINUS
, 1, -ONE_DAY
, +6*ONE_DAY
},
2172 { UCAL_DATE
, ADD
|ROLL
, PLUS
|MINUS
, 2, -ONE_DAY
, +1*ONE_DAY
},
2173 { UCAL_DATE
, ROLL
, PLUS
, -6, -ONE_DAY
, +14*ONE_DAY
},
2174 { UCAL_DATE
, ROLL
, PLUS
, -7, 0, +14*ONE_DAY
},
2175 { UCAL_DATE
, ROLL
, PLUS
, -7, +ONE_DAY
, +15*ONE_DAY
},
2176 { UCAL_DATE
, ROLL
, PLUS
, +18, -ONE_DAY
, -4*ONE_DAY
},
2177 { UCAL_DAY_OF_YEAR
, ADD
|ROLL
, PLUS
|MINUS
, 2, -ONE_DAY
, +1*ONE_DAY
},
2178 { UCAL_DAY_OF_WEEK
, ADD
|ROLL
, PLUS
|MINUS
, 2, -ONE_DAY
, +1*ONE_DAY
},
2179 { UCAL_DAY_OF_WEEK_IN_MONTH
, ADD
|ROLL
, PLUS
|MINUS
, 1, -ONE_DAY
, +6*ONE_DAY
},
2180 { UCAL_AM_PM
, ADD
, PLUS
|MINUS
, 4, -12*ONE_HOUR
, +36*ONE_HOUR
},
2181 { UCAL_HOUR
, ADD
, PLUS
|MINUS
, 48, -12*ONE_HOUR
, +36*ONE_HOUR
},
2182 { UCAL_HOUR_OF_DAY
, ADD
, PLUS
|MINUS
, 48, -12*ONE_HOUR
, +36*ONE_HOUR
},
2183 { UCAL_MINUTE
, ADD
, PLUS
|MINUS
, 48*60, -12*ONE_HOUR
, +36*ONE_HOUR
},
2184 { UCAL_SECOND
, ADD
, PLUS
|MINUS
, 48*60*60, -12*ONE_HOUR
, +36*ONE_HOUR
},
2185 { UCAL_MILLISECOND
, ADD
, PLUS
|MINUS
, 48*ONE_HOUR
, -12*ONE_HOUR
, +36*ONE_HOUR
},
2186 // NOTE: These are not supported yet. See jitterbug 180.
2187 // Uncomment these lines when add/roll supported on these fields.
2188 // { Calendar::YEAR_WOY, ADD|ROLL, 1, -ONE_DAY, +6*ONE_DAY },
2189 // { Calendar::DOW_LOCAL, ADD|ROLL, 2, -ONE_DAY, +1*ONE_DAY }
2191 int32_t DATA_length
= (int32_t)(sizeof(DATA
) / sizeof(DATA
[0]));
2193 // Now run the tests
2194 for (i
=0; i
<DATA_length
; ++i
) {
2195 for (Action action
=ADD
; action
<=ROLL
; action
=(Action
)(action
+1)) {
2196 if (!(DATA
[i
].actionMask
& action
)) {
2199 for (Sign sign
=PLUS
; sign
<=MINUS
; sign
=(Sign
)(sign
+1)) {
2200 if (!(DATA
[i
].signMask
& sign
)) {
2203 status
= U_ZERO_ERROR
;
2204 int32_t amount
= DATA
[i
].amount
* (sign
==MINUS
?-1:1);
2205 UDate date
= cutover
+
2206 (sign
==PLUS
? DATA
[i
].before
: DATA
[i
].after
);
2207 UDate expected
= cutover
+
2208 (sign
==PLUS
? DATA
[i
].after
: DATA
[i
].before
);
2209 cal
.setTime(date
, status
);
2210 if (U_FAILURE(status
)) {
2211 errln((UnicodeString
)"FAIL: setTime returned error code " + u_errorName(status
));
2214 if (action
== ADD
) {
2215 cal
.add(DATA
[i
].field
, amount
, status
);
2217 cal
.roll(DATA
[i
].field
, amount
, status
);
2219 if (U_FAILURE(status
)) {
2220 errln((UnicodeString
)"FAIL: " +
2221 (action
==ADD
?"add ":"roll ") + FIELD_NAME
[DATA
[i
].field
] +
2222 " returned error code " + u_errorName(status
));
2225 UDate result
= cal
.getTime(status
);
2226 if (U_FAILURE(status
)) {
2227 errln((UnicodeString
)"FAIL: getTime returned error code " + u_errorName(status
));
2230 if (result
== expected
) {
2231 logln((UnicodeString
)"Ok: {" +
2232 fmt
.format(date
, temp
.remove()) +
2233 "}(" + date
/ONE_DAY
+
2234 (action
==ADD
?") add ":") roll ") +
2235 amount
+ " " + FIELD_NAME
[DATA
[i
].field
] + " -> {" +
2236 fmt
.format(result
, temp2
.remove()) +
2237 "}(" + result
/ONE_DAY
+ ")");
2239 errln((UnicodeString
)"FAIL: {" +
2240 fmt
.format(date
, temp
.remove()) +
2241 "}(" + date
/ONE_DAY
+
2242 (action
==ADD
?") add ":") roll ") +
2243 amount
+ " " + FIELD_NAME
[DATA
[i
].field
] + " -> {" +
2244 fmt
.format(result
, temp2
.remove()) +
2245 "}(" + result
/ONE_DAY
+ "), expect {" +
2246 fmt
.format(expected
, temp3
.remove()) +
2247 "}(" + expected
/ONE_DAY
+ ")");
2255 * Test fieldDifference().
2257 void CalendarRegressionTest::TestJ438(void) {
2258 UErrorCode ec
= U_ZERO_ERROR
;
2260 2000, UCAL_JANUARY
, 20, 2010, UCAL_JUNE
, 15,
2261 2010, UCAL_JUNE
, 15, 2000, UCAL_JANUARY
, 20,
2262 1964, UCAL_SEPTEMBER
, 7, 1999, UCAL_JUNE
, 4,
2263 1999, UCAL_JUNE
, 4, 1964, UCAL_SEPTEMBER
, 7,
2265 int32_t DATA_length
= (int32_t)(sizeof(DATA
)/sizeof(DATA
[0]));
2266 Calendar
* pcal
= Calendar::createInstance(Locale::getUS(), ec
);
2268 dataerrln("Error creating calendar %s", u_errorName(ec
));
2272 Calendar
& cal
= *pcal
;
2274 SimpleDateFormat
fmt(UnicodeString("MMM dd yyyy",""), ec
);
2275 fmt
.setCalendar(cal
);
2276 UnicodeString s
, t
, u
;
2277 if (U_SUCCESS(ec
)) {
2278 for (i
=0; i
<DATA_length
; i
+=6) {
2279 int32_t y1
= DATA
[i
];
2280 int32_t m1
= DATA
[i
+1];
2281 int32_t d1
= DATA
[i
+2];
2282 int32_t y2
= DATA
[i
+3];
2283 int32_t m2
= DATA
[i
+4];
2284 int32_t d2
= DATA
[i
+5];
2287 cal
.set(y1
, m1
, d1
);
2288 UDate date1
= cal
.getTime(ec
);
2289 if (failure(ec
, "getTime"))
2291 cal
.set(y2
, m2
, d2
);
2292 UDate date2
= cal
.getTime(ec
);
2293 if (failure(ec
, "getTime"))
2296 cal
.setTime(date1
, ec
);
2297 if (failure(ec
, "setTime"))
2299 int32_t dy
= cal
.fieldDifference(date2
, UCAL_YEAR
, ec
);
2300 int32_t dm
= cal
.fieldDifference(date2
, UCAL_MONTH
, ec
);
2301 int32_t dd
= cal
.fieldDifference(date2
, UCAL_DATE
, ec
);
2302 if (failure(ec
, "fieldDifference"))
2306 Calendar
*cal2
= cal
.clone();
2307 UErrorCode ec2
= U_ZERO_ERROR
;
2309 cal2
->setTime(date1
, ec2
);
2311 int32_t dy2
= cal2
->fieldDifference(date2
, Calendar::YEAR
, ec2
);
2312 int32_t dm2
= cal2
->fieldDifference(date2
, Calendar::MONTH
, ec2
);
2313 int32_t dd2
= cal2
->fieldDifference(date2
, Calendar::DATE
, ec2
);
2314 if (failure(ec2
, "fieldDifference(date, Calendar::DATE, ec)"))
2319 errln("fieldDifference(UCAL_...) and fieldDifference(Calendar::...) give different results!\n");
2325 logln(UnicodeString("") +
2326 fmt
.format(date2
, s
.remove()) + " - " +
2327 fmt
.format(date1
, t
.remove()) + " = " +
2328 dy
+ "y " + dm
+ "m " + dd
+ "d");
2330 cal
.setTime(date1
, ec
);
2331 if (failure(ec
, "setTime"))
2333 cal
.add(UCAL_YEAR
, dy
, ec
);
2334 cal
.add(UCAL_MONTH
, dm
, ec
);
2335 cal
.add(UCAL_DATE
, dd
, ec
);
2336 if (failure(ec
, "add"))
2338 UDate date22
= cal
.getTime(ec
);
2339 if (failure(ec
, "getTime"))
2341 if (date2
!= date22
) {
2342 errln(UnicodeString("FAIL: ") +
2343 fmt
.format(date1
, s
.remove()) + " + " +
2344 dy
+ "y " + dm
+ "m " + dd
+ "d = " +
2345 fmt
.format(date22
, t
.remove()) + ", exp " +
2346 fmt
.format(date2
, u
.remove()));
2348 logln(UnicodeString("Ok: ") +
2349 fmt
.format(date1
, s
.remove()) + " + " +
2350 dy
+ "y " + dm
+ "m " + dd
+ "d = " +
2351 fmt
.format(date22
, t
.remove()));
2355 dataerrln("Error creating SimpleDateFormat - %s", u_errorName(ec
));
2360 void CalendarRegressionTest::TestT5555()
2362 UErrorCode ec
= U_ZERO_ERROR
;
2363 Calendar
*cal
= Calendar::createInstance(ec
);
2365 if (cal
== NULL
|| U_FAILURE(ec
)) {
2366 dataerrln("FAIL: Calendar::createInstance(): %s", u_errorName(ec
));
2371 // Set to Wednesday, February 21, 2007
2372 cal
->set(2007, UCAL_FEBRUARY
, 21);
2374 // Advance three years
2375 cal
->add(UCAL_MONTH
, 36, ec
);
2377 // Set to last Wednesday of the month
2378 cal
->set(UCAL_DAY_OF_WEEK_IN_MONTH
, -1);
2382 int32_t yy
, mm
, dd
, ee
;
2384 yy
= cal
->get(UCAL_YEAR
, ec
);
2385 mm
= cal
->get(UCAL_MONTH
, ec
);
2386 dd
= cal
->get(UCAL_DATE
, ec
);
2387 ee
= cal
->get(UCAL_DAY_OF_WEEK
, ec
);
2389 // Should be set to Wednesday, February 24, 2010
2390 if (U_FAILURE(ec
) || yy
!= 2010 || mm
!= UCAL_FEBRUARY
|| dd
!= 24 || ee
!= UCAL_WEDNESDAY
) {
2391 errln("FAIL: got date %4d/%02d/%02d, expected 210/02/24: ", yy
, mm
+ 1, dd
);
2398 int32_t startMonth
; // 0-based
2399 int32_t startDay
; // 1-based
2400 UCalendarDateFields fieldToChange
;
2403 int32_t endMonth
; // 0-based
2404 int32_t endDay
; // 1-based
2405 } CoptEthCalTestItem
;
2407 // year 1724 in coptic calendar =
2408 // year 2000 in ethiopic calendar (276 more than coptic) =
2409 // year 7500 in ethiopic-amete-alem calendar (5776 more than coptic)
2410 // (2007-2008 in gregorian calendar depending on month)
2411 static const CoptEthCalTestItem coptEthCalTestItems
[] = {
2412 { 1724, 12, 1, UCAL_MONTH
, +1, 1725, 0, 1 },
2413 { 1724, 12, 1, UCAL_MONTH
, +9, 1725, 8, 1 },
2414 { 1723, 12, 2, UCAL_MONTH
, +1, 1724, 0, 2 }, // 1723 is a leap year
2415 { 1723, 12, 2, UCAL_MONTH
, +9, 1724, 8, 2 },
2416 { 1725, 0, 1, UCAL_MONTH
, -1, 1724, 12, 1 },
2417 { 1725, 0, 1, UCAL_MONTH
, -6, 1724, 7, 1 },
2418 { 1724, 12, 1, UCAL_DATE
, +8, 1725, 0, 4 },
2419 { 1723, 12, 1, UCAL_DATE
, +8, 1724, 0, 3 }, // 1723 is a leap year
2420 { 1724, 0, 1, UCAL_DATE
, -1, 1723, 12, 6 }, // 1723 is a leap year
2421 { 0, 0, 0, (UCalendarDateFields
)0, 0, 0, 0, 0 } // terminator
2425 const char * locale
;
2429 static const CoptEthCalLocale copEthCalLocales
[] = {
2430 { "en@calendar=coptic", 0 },
2431 { "en@calendar=ethiopic", 276 },
2432 { NULL
, 0 } // terminator
2435 void CalendarRegressionTest::TestT6745()
2437 const CoptEthCalLocale
* testLocalePtr
;
2438 for ( testLocalePtr
= copEthCalLocales
; testLocalePtr
->locale
!= NULL
; ++testLocalePtr
) {
2439 UErrorCode status
= U_ZERO_ERROR
;
2440 Calendar
*cal
= Calendar::createInstance(Locale(testLocalePtr
->locale
), status
);
2441 if ( U_FAILURE(status
) ) {
2442 dataerrln((UnicodeString
)"FAIL: Calendar::createInstance, locale " + testLocalePtr
->locale
+ ", status " + u_errorName(status
));
2445 const CoptEthCalTestItem
* testItemPtr
;
2446 for (testItemPtr
= coptEthCalTestItems
; testItemPtr
->fieldDelta
!= 0; ++testItemPtr
) {
2447 status
= U_ZERO_ERROR
;
2448 cal
->set( testItemPtr
->startYear
+ testLocalePtr
->yearOffset
, testItemPtr
->startMonth
, testItemPtr
->startDay
, 9, 0 );
2449 cal
->add( testItemPtr
->fieldToChange
, testItemPtr
->fieldDelta
, status
);
2450 if ( U_FAILURE(status
) ) {
2451 errln((UnicodeString
)"FAIL: Calendar::add, locale " + testLocalePtr
->locale
+ ", field/delta " +
2452 testItemPtr
->fieldToChange
+ "/" + testItemPtr
->fieldDelta
+ ", status " + u_errorName(status
));
2455 int32_t endYear
= testItemPtr
->endYear
+ testLocalePtr
->yearOffset
;
2456 int32_t year
= cal
->get(UCAL_YEAR
, status
);
2457 int32_t month
= cal
->get(UCAL_MONTH
, status
);
2458 int32_t day
= cal
->get(UCAL_DATE
, status
);
2459 if ( U_FAILURE(status
) || year
!= endYear
|| month
!= testItemPtr
->endMonth
|| day
!= testItemPtr
->endDay
) {
2460 errln((UnicodeString
)"ERROR: Calendar::add, locale " + testLocalePtr
->locale
+ ", field/delta " +
2461 testItemPtr
->fieldToChange
+ "/" + testItemPtr
->fieldDelta
+ ", status " + u_errorName(status
) +
2462 ", expected " + endYear
+ "/" + testItemPtr
->endMonth
+ "/" + testItemPtr
->endDay
+
2463 ", got " + year
+ "/" + month
+ "/" + day
);
2471 * Test behavior of fieldDifference around leap years. Also test a large
2472 * field difference to check binary search.
2474 void CalendarRegressionTest::TestLeapFieldDifference() {
2475 UErrorCode ec
= U_ZERO_ERROR
;
2476 Calendar
* cal
= Calendar::createInstance(ec
);
2477 if (cal
== NULL
|| U_FAILURE(ec
)) {
2478 dataerrln("FAIL: Calendar::createInstance(): %s", u_errorName(ec
));
2482 cal
->set(2004, UCAL_FEBRUARY
, 29);
2483 UDate date2004
= cal
->getTime(ec
);
2484 cal
->set(2000, UCAL_FEBRUARY
, 29);
2485 UDate date2000
= cal
->getTime(ec
);
2486 if (U_FAILURE(ec
)) {
2487 errln("FAIL: getTime()");
2491 int32_t y
= cal
->fieldDifference(date2004
, UCAL_YEAR
, ec
);
2492 int32_t d
= cal
->fieldDifference(date2004
, UCAL_DAY_OF_YEAR
, ec
);
2493 if (U_FAILURE(ec
)) {
2494 errln("FAIL: fieldDifference()");
2499 logln((UnicodeString
)"Ok: 2004/Feb/29 - 2000/Feb/29 = " + y
+ " years, " + d
+ " days");
2501 errln((UnicodeString
)"FAIL: 2004/Feb/29 - 2000/Feb/29 = " + y
+ " years, " + d
+ " days");
2503 cal
->setTime(date2004
, ec
);
2504 y
= cal
->fieldDifference(date2000
, UCAL_YEAR
, ec
);
2505 d
= cal
->fieldDifference(date2000
, UCAL_DAY_OF_YEAR
, ec
);
2506 if (U_FAILURE(ec
)) {
2507 errln("FAIL: setTime() / fieldDifference()");
2512 logln((UnicodeString
)"Ok: 2000/Feb/29 - 2004/Feb/29 = " + y
+ " years, " + d
+ " days");
2514 errln((UnicodeString
)"FAIL: 2000/Feb/29 - 2004/Feb/29 = " + y
+ " years, " + d
+ " days");
2516 // Test large difference
2517 cal
->set(2001, UCAL_APRIL
, 5); // 2452005
2518 UDate ayl
= cal
->getTime(ec
);
2519 cal
->set(1964, UCAL_SEPTEMBER
, 7); // 2438646
2520 UDate asl
= cal
->getTime(ec
);
2521 if (U_FAILURE(ec
)) {
2522 errln("FAIL: getTime()");
2526 d
= cal
->fieldDifference(ayl
, UCAL_DATE
, ec
);
2527 cal
->setTime(ayl
, ec
);
2528 int32_t d2
= cal
->fieldDifference(asl
, UCAL_DATE
, ec
);
2529 if (U_FAILURE(ec
)) {
2530 errln("FAIL: setTime() / fieldDifference()");
2534 if (d
== -d2
&& d
== 13359) {
2535 logln((UnicodeString
)"Ok: large field difference symmetrical " + d
);
2537 logln((UnicodeString
)"FAIL: large field difference incorrect " + d
+ ", " + d2
+
2538 ", expect +/- 13359");
2544 * Test ms_MY "Malay (Malaysia)" locale. Bug 1543.
2546 void CalendarRegressionTest::TestMalaysianInstance() {
2547 Locale
loc("ms", "MY"); // Malay (Malaysia)
2548 UErrorCode ec
= U_ZERO_ERROR
;
2549 Calendar
* cal
= Calendar::createInstance(loc
, ec
);
2550 if (U_FAILURE(ec
)) {
2551 dataerrln("FAIL: Can't construct calendar for ms_MY: %s", u_errorName(ec
));
2557 * setFirstDayOfWeek and setMinimalDaysInFirstWeek may change the
2558 * field <=> time mapping, since they affect the interpretation of
2559 * the WEEK_OF_MONTH or WEEK_OF_YEAR fields.
2561 void CalendarRegressionTest::TestWeekShift() {
2562 UErrorCode ec
= U_ZERO_ERROR
;
2563 GregorianCalendar
cal(TimeZone::createTimeZone("America/Los_Angeles"),
2564 Locale("en", "US"), ec
);
2565 if (U_FAILURE(ec
)) {
2566 dataerrln("Fail GregorianCalendar: %s", u_errorName(ec
));
2569 cal
.setTime(UDate(997257600000.0), ec
); // Wed Aug 08 01:00:00 PDT 2001
2570 // In pass one, change the first day of week so that the weeks
2571 // shift in August 2001. In pass two, change the minimal days
2572 // in the first week so that the weeks shift in August 2001.
2574 // Su Mo Tu We Th Fr Sa
2577 // 12 13 14 15 16 17 18
2578 // 19 20 21 22 23 24 25
2579 // 26 27 28 29 30 31
2580 for (int32_t pass
=0; pass
<2; ++pass
) {
2582 cal
.setFirstDayOfWeek(UCAL_WEDNESDAY
);
2583 cal
.setMinimalDaysInFirstWeek(4);
2585 cal
.setFirstDayOfWeek(UCAL_SUNDAY
);
2586 cal
.setMinimalDaysInFirstWeek(4);
2588 cal
.add(UCAL_DATE
, 1, ec
); // Force recalc
2589 cal
.add(UCAL_DATE
, -1, ec
);
2591 UDate time1
= cal
.getTime(ec
); // Get time -- should not change
2593 // Now change a week parameter and then force a recalc.
2594 // The bug is that the recalc should not be necessary --
2595 // calendar should do so automatically.
2597 cal
.setFirstDayOfWeek(UCAL_THURSDAY
);
2599 cal
.setMinimalDaysInFirstWeek(5);
2602 int32_t woy1
= cal
.get(UCAL_WEEK_OF_YEAR
, ec
);
2603 int32_t wom1
= cal
.get(UCAL_WEEK_OF_MONTH
, ec
);
2605 cal
.add(UCAL_DATE
, 1, ec
); // Force recalc
2606 cal
.add(UCAL_DATE
, -1, ec
);
2608 int32_t woy2
= cal
.get(UCAL_WEEK_OF_YEAR
, ec
);
2609 int32_t wom2
= cal
.get(UCAL_WEEK_OF_MONTH
, ec
);
2611 UDate time2
= cal
.getTime(ec
);
2613 if (U_FAILURE(ec
)) {
2614 errln("FAIL: internal test error");
2618 if (time1
!= time2
) {
2619 errln("FAIL: shifting week should not alter time");
2623 if (woy1
== woy2
&& wom1
== wom2
) {
2624 logln((UnicodeString
)"Ok: WEEK_OF_YEAR: " + woy1
+
2625 ", WEEK_OF_MONTH: " + wom1
);
2627 errln((UnicodeString
)"FAIL: WEEK_OF_YEAR: " + woy1
+ " => " + woy2
+
2628 ", WEEK_OF_MONTH: " + wom1
+ " => " + wom2
+
2629 " after week shift");
2635 * Make sure that when adding a day, we actually wind up in a
2636 * different day. The DST adjustments we use to keep the hour
2637 * constant across DST changes can backfire and change the day.
2639 void CalendarRegressionTest::TestTimeZoneTransitionAdd() {
2640 UErrorCode ec
= U_ZERO_ERROR
;
2641 Locale
locale(Locale::getUS()); // could also be CHINA
2642 SimpleDateFormat
dateFormat("MM/dd/yyyy HH:mm z", locale
, ec
);
2644 StringEnumeration
*tz
= TimeZone::createEnumeration();
2646 dataerrln("FAIL: TimeZone::createEnumeration");
2650 UnicodeString buf1
, buf2
;
2653 while ((id
= tz
->unext(NULL
, ec
)) != NULL
&& U_SUCCESS(ec
)) {
2654 if (U_FAILURE(ec
)) {
2655 errln("FAIL: StringEnumeration::unext");
2659 TimeZone
*t
= TimeZone::createTimeZone(id
);
2661 errln("FAIL: TimeZone::createTimeZone");
2664 dateFormat
.setTimeZone(*t
);
2666 Calendar
*cal
= Calendar::createInstance(t
, locale
, ec
);
2667 if (cal
== NULL
|| U_FAILURE(ec
)) {
2668 errln("FAIL: Calendar::createTimeZone");
2674 // Scan the year 2003, overlapping the edges of the year
2675 cal
->set(UCAL_YEAR
, 2002);
2676 cal
->set(UCAL_MONTH
, UCAL_DECEMBER
);
2677 cal
->set(UCAL_DATE
, 25);
2679 for (int32_t i
=0; i
<365+10 && U_SUCCESS(ec
); ++i
) {
2680 UDate yesterday
= cal
->getTime(ec
);
2681 int32_t yesterday_day
= cal
->get(UCAL_DATE
, ec
);
2682 cal
->add(UCAL_DATE
, 1, ec
);
2683 if (yesterday_day
== cal
->get(UCAL_DATE
, ec
)) {
2684 errln(UnicodeString(id
) + " " +
2685 dateFormat
.format(yesterday
, buf1
) + " +1d= " +
2686 dateFormat
.format(cal
->getTime(ec
), buf2
));
2694 if (U_FAILURE(ec
)) {
2695 dataerrln("FAIL: %s", u_errorName(ec
));
2702 CalendarRegressionTest::makeDate(int32_t y
, int32_t m
, int32_t d
,
2703 int32_t hr
, int32_t min
, int32_t sec
)
2707 UErrorCode status
= U_ZERO_ERROR
;
2708 Calendar
*cal
= Calendar::createInstance(status
);
2711 cal
->set(UCAL_YEAR
, y
);
2713 if(m
!= 0) cal
->set(UCAL_MONTH
, m
);
2714 if(d
!= 0) cal
->set(UCAL_DATE
, d
);
2715 if(hr
!= 0) cal
->set(UCAL_HOUR
, hr
);
2716 if(min
!= 0) cal
->set(UCAL_MINUTE
, min
);
2717 if(sec
!= 0) cal
->set(UCAL_SECOND
, sec
);
2719 result
= cal
->getTime(status
);
2726 void CalendarRegressionTest::TestDeprecates(void)
2728 UErrorCode status
= U_ZERO_ERROR
;
2729 Calendar
*c1
= Calendar::createInstance("ja_JP@calendar=japanese",status
);
2730 Calendar
*c2
= Calendar::createInstance("ja_JP_TRADITIONAL",status
);
2732 if(!c1
|| !c2
|| U_FAILURE(status
)) {
2733 dataerrln("Couldn't create calendars for roll of HOUR: %s", u_errorName(status
));
2737 c2
->set(UCAL_HOUR
,2);
2738 c1
->setTime(c2
->getTime(status
),status
);
2741 c1
->roll(Calendar::HOUR
,(int32_t)3,status
);
2742 c2
->roll(UCAL_HOUR
,(int32_t)3,status
);
2744 if(U_FAILURE(status
)) {
2745 errln("Error code when trying to roll");
2746 } else if(*c1
!= *c2
) {
2747 errln("roll(EDateField, int32_t) had different effect than roll(UCalendarField, int32_t)");
2750 c1
->setTime(c2
->getTime(status
),status
);
2751 c1
->roll(Calendar::HOUR
,(UBool
)FALSE
,status
);
2752 c2
->roll(UCAL_HOUR
,(UBool
)FALSE
,status
);
2754 if(U_FAILURE(status
)) {
2755 errln("Error code when trying to roll(UBool)");
2756 } else if(*c1
!= *c2
) {
2757 errln("roll(EDateField, UBool) had different effect than roll(UCalendarField, UBool)");
2763 status
= U_ZERO_ERROR
;
2765 c1
= Calendar::createInstance("th_TH_TRADITIONAL",status
);
2766 c2
= Calendar::createInstance("th_TH@calendar=buddhist",status
);
2768 if(!c1
|| !c2
|| U_FAILURE(status
)) {
2769 errln("Couldn't create calendars for add of HOUR");
2773 c2
->set(UCAL_HOUR
,2);
2774 c1
->setTime(c2
->getTime(status
),status
);
2777 c1
->add(Calendar::HOUR
,(int32_t)1,status
);
2779 if(U_FAILURE(status
)) {
2780 errln("Error code when trying to add Calendar::HOUR - %s", u_errorName(status
));
2783 c2
->add(UCAL_HOUR
,(int32_t)1,status
);
2785 if(U_FAILURE(status
)) {
2786 errln("Error code when trying to add - UCAL_HOUR %s", u_errorName(status
));
2787 } else if(*c1
!= *c2
) {
2788 errln("add(EDateField) had different effect than add(UCalendarField)");
2794 status
= U_ZERO_ERROR
;
2796 c1
= Calendar::createInstance("es_ES",status
);
2797 c2
= Calendar::createInstance("es_ES",status
);
2799 if(!c1
|| !c2
|| U_FAILURE(status
)) {
2800 errln("Couldn't create calendars for add of YEAR");
2804 c2
->set(UCAL_YEAR
,1900);
2805 c1
->setTime(c2
->getTime(status
),status
);
2808 c1
->add(Calendar::YEAR
,(int32_t)9,status
);
2809 c2
->add(UCAL_YEAR
,(int32_t)9,status
);
2811 if(U_FAILURE(status
)) {
2812 errln("Error code when trying to add YEARs");
2813 } else if(*c1
!= *c2
) {
2814 errln("add(EDateField YEAR) had different effect than add(UCalendarField YEAR)");
2822 void CalendarRegressionTest::TestT8057(void) {
2823 // Set the calendar to the last day in a leap year
2824 UErrorCode status
= U_ZERO_ERROR
;
2825 GregorianCalendar
*cal
= (GregorianCalendar
*)Calendar::createInstance(status
);
2826 if(U_FAILURE(status
)) {
2827 errln("Error creating Calendar: %s", u_errorName(status
));
2831 cal
->setLenient(FALSE
);
2833 cal
->set(2008, UCAL_DECEMBER
, 31);
2835 // Force calculating then fields once.
2836 UDate t
= cal
->getTime(status
);
2837 if(U_FAILURE(status
)) {
2838 errln("Error while calculating the date");
2843 UDate expected
= 1262246400000.0; // 2009-12-31 00:00 PST
2845 cal
->add(UCAL_YEAR
, 1, status
);
2846 t
= cal
->getTime(status
);
2847 if (U_SUCCESS(status
)) {
2848 if (t
!= expected
) {
2849 dataerrln((UnicodeString
)"FAIL: wrong date after add: expected=" + expected
+ " returned=" + t
);
2852 errln("FAIL: error while adding one year");
2858 // Test case for ticket#8596.
2859 // Setting an year followed by getActualMaximum(Calendar.WEEK_OF_YEAR)
2860 // may result wrong maximum week.
2861 void CalendarRegressionTest::TestT8596(void) {
2862 UErrorCode status
= U_ZERO_ERROR
;
2863 GregorianCalendar
*gc
= new GregorianCalendar(*TimeZone::getGMT(), status
);
2865 if (U_FAILURE(status
)) {
2866 dataerrln("Error creating Calendar: %s", u_errorName(status
));
2871 gc
->setFirstDayOfWeek(UCAL_MONDAY
);
2872 gc
->setMinimalDaysInFirstWeek(4);
2874 // Force the calender to resolve the fields once.
2875 // The maximum week number in 2011 is 52.
2876 gc
->set(UCAL_YEAR
, 2011);
2877 gc
->get(UCAL_YEAR
, status
);
2879 // Set a date in year 2009, but not calling get to resolve
2880 // the calendar's internal field yet.
2881 gc
->set(2009, UCAL_JULY
, 1);
2883 // Then call getActuamMaximum for week of year.
2884 // #8596 was caused by conflict between year set
2885 // above and internal work calendar field resolution.
2886 int32_t maxWeeks
= gc
->getActualMaximum(UCAL_WEEK_OF_YEAR
, status
);
2888 if (U_FAILURE(status
)) {
2889 errln("Error calendar calculation: %s", u_errorName(status
));
2894 if (maxWeeks
!= 53) {
2895 errln((UnicodeString
)"FAIL: Max week in 2009 in ISO calendar is 53, but got " + maxWeeks
);
2901 #endif /* #if !UCONFIG_NO_FORMATTING */