1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /********************************************************************
5 * Copyright (c) 1997-2016, International Business Machines Corporation
6 * and others. All Rights Reserved.
7 ********************************************************************/
9 #include "unicode/utypes.h"
11 #if !UCONFIG_NO_FORMATTING
15 #include "unicode/gregocal.h"
16 #include "unicode/simpletz.h"
17 #include "unicode/smpdtfmt.h"
18 #include "unicode/strenum.h"
21 #include "unicode/localpointer.h"
25 // *****************************************************************************
26 // class CalendarRegressionTest
27 // *****************************************************************************
29 // these numbers correspond to using LONG_MIN and LONG_MAX in Java
30 // this is 2^52 - 1, the largest allowable mantissa with a 0 exponent in a 64-bit double
31 const UDate
CalendarRegressionTest::EARLIEST_SUPPORTED_MILLIS
= - 4503599627370495.0;
32 const UDate
CalendarRegressionTest::LATEST_SUPPORTED_MILLIS
= 4503599627370495.0;
34 #define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); logln((UnicodeString)""); test(); } break
37 CalendarRegressionTest::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char* /*par*/ )
39 // if (exec) logln((UnicodeString)"TestSuite NumberFormatRegressionTest");
58 CASE(17,test41003112
);
80 CASE(38,TestLeapFieldDifference
);
81 CASE(39,TestMalaysianInstance
);
84 CASE(42,TestWeekShift
);
85 CASE(43,TestTimeZoneTransitionAdd
);
86 CASE(44,TestDeprecates
);
93 default: name
= ""; break;
97 const char* CalendarRegressionTest::FIELD_NAME
[] = {
106 "DAY_OF_WEEK_IN_MONTH",
120 CalendarRegressionTest::failure(UErrorCode status
, const char* msg
)
122 if(U_FAILURE(status
)) {
123 errcheckln(status
, UnicodeString("FAIL: ") + msg
+ " failed, error " + u_errorName(status
));
134 CalendarRegressionTest::test4100311()
136 UErrorCode status
= U_ZERO_ERROR
;
137 GregorianCalendar
*cal
= (GregorianCalendar
*)Calendar::createInstance(status
);
138 if(U_FAILURE(status
)) {
139 dataerrln("Error creating Calendar: %s", u_errorName(status
));
143 failure(status
, "Calendar::createInstance(status)");
144 cal
->set(UCAL_YEAR
, 1997);
145 cal
->set(UCAL_DAY_OF_YEAR
, 1);
146 UDate d
= cal
->getTime(status
); // Should be Jan 1
147 failure(status
, "cal->getTime");
148 logln(UnicodeString("") + d
);
157 CalendarRegressionTest::test4074758()
158 { //Set system time to between 12-1 (am or pm) and then run
159 UErrorCode status
= U_ZERO_ERROR
;
160 GregorianCalendar
*cal
= new GregorianCalendar(status
);
161 if(U_FAILURE(status
)) {
162 dataerrln("Error creating Calendar: %s", u_errorName(status
));
166 failure(status
, "new GregorianCalendar");
167 for (int32_t h
=0; h
<25; ++h
) {
168 cal
->set(97, UCAL_JANUARY
, 1, h
, 34);
169 //System.out.print(d);
170 logln(UnicodeString("HOUR=") + cal
->get(UCAL_HOUR
, status
)); //prints 0
171 failure(status
, "cal->get");
172 logln(UnicodeString("HOUR_OF_DAY=") + cal
->get(UCAL_HOUR_OF_DAY
, status
));
173 failure(status
, "cal->get");
180 CalendarRegressionTest::test4028518()
182 UErrorCode status
= U_ZERO_ERROR
;
183 GregorianCalendar
*cal1
= new GregorianCalendar(status
) ;
184 if(U_FAILURE(status
)) {
185 dataerrln("Error creating Calendar: %s", u_errorName(status
));
189 failure(status
, "new GregorianCalendar");
190 GregorianCalendar
*cal2
= (GregorianCalendar
*) cal1
->clone() ;
192 printdate(cal1
, "cal1: ") ;
193 printdate(cal2
, "cal2 - cloned(): ") ;
194 cal1
->add(UCAL_DATE
, 1, status
) ;
195 failure(status
, "cal1->add");
196 printdate(cal1
, "cal1 after adding 1 day:") ;
197 printdate(cal2
, "cal2 should be unmodified:") ;
204 CalendarRegressionTest::Test9019()
206 UErrorCode status
= U_ZERO_ERROR
;
207 LocalPointer
<GregorianCalendar
> cal1(new GregorianCalendar(status
), status
);
208 LocalPointer
<GregorianCalendar
> cal2(new GregorianCalendar(status
), status
);
209 if(U_FAILURE(status
)) {
210 dataerrln("Error creating Calendar: %s", u_errorName(status
));
213 cal1
->set(UCAL_HOUR
, 1);
214 cal2
->set(UCAL_HOUR
,2);
217 failure(status
, "new GregorianCalendar");
218 cal1
->set(2011,UCAL_MAY
,06);
219 cal2
->set(2012,UCAL_JANUARY
,06);
220 printdate(cal1
.getAlias(), "cal1: ") ;
221 cal1
->setLenient(FALSE
);
222 cal1
->add(UCAL_MONTH
,8,status
);
223 failure(status
, "->add(UCAL_MONTH,8)");
224 printdate(cal1
.getAlias(), "cal1 (lenient) after adding 8 months:") ;
225 printdate(cal2
.getAlias(), "cal2 (expected date):") ;
227 if(!cal1
->equals(*cal2
,status
)) {
228 errln("Error: cal1 != cal2.\n");
230 failure(status
, "equals");
234 CalendarRegressionTest::printdate(GregorianCalendar
*cal
, const char *string
)
236 UErrorCode status
= U_ZERO_ERROR
;
237 logln(UnicodeString(string
, ""));
238 log(UnicodeString("") + cal
->get(UCAL_MONTH
, status
)) ;
239 failure(status
, "cal->get");
240 int32_t date
= cal
->get(UCAL_DATE
, status
) + 1 ;
241 failure(status
, "cal->get");
242 log(UnicodeString("/") + date
) ;
243 logln(UnicodeString("/") + cal
->get(UCAL_YEAR
, status
)) ;
244 failure(status
, "cal->get");
251 CalendarRegressionTest::test4031502()
253 // This bug actually occurs on Windows NT as well, and doesn't
254 // require the host zone to be set; it can be set in Java.
255 UErrorCode status
= U_ZERO_ERROR
;
256 StringEnumeration
* ids
= TimeZone::createEnumeration();
258 dataerrln("Unable to create TimeZone Enumeration.");
262 TimeZone
* tz
=TimeZone::createTimeZone("Asia/Riyadh87");
263 failure(status
, "new TimeZone");
264 GregorianCalendar
*cl
= new GregorianCalendar(tz
, status
);
265 if (U_FAILURE(status
)) {
266 dataerrln("Fail new GregorianCalendar: %s", u_errorName(status
));
271 cl
->set(1900, 15, 5, 5, 8, 13);
272 cl
->get(UCAL_HOUR
, status
);
273 failure(status
, "cl->get(UCAL_HOUR, status)");
274 status
= U_ZERO_ERROR
;
276 for (int32_t i
=0; i
<ids
->count(status
); ++i
) {
277 TimeZone
*zone
= TimeZone::createTimeZone(*ids
->snext(status
));
278 GregorianCalendar
*cal
= new GregorianCalendar(zone
, status
);
279 failure(status
, "new GregorianCalendar");
281 cal
->set(1900, 15, 5, 5, 8, 13);
282 if (cal
->get(UCAL_HOUR
, status
) != 5 || U_FAILURE(status
)) {
284 logln(zone
->getID(temp
) + " " +
285 //zone.useDaylightTime() + " " +
286 cal
->get(UCAL_DST_OFFSET
,status
) / (60*60*1000) + " " +
287 zone
->getRawOffset() / (60*60*1000) +
288 ": HOUR = " + cal
->get(UCAL_HOUR
,status
));
294 errln("TimeZone problems with GC");
295 // delete [] ids; // TODO: bad APIs
302 void CalendarRegressionTest::test4035301()
304 UErrorCode status
= U_ZERO_ERROR
;
305 GregorianCalendar
*c
= new GregorianCalendar(98, 8, 7,status
);
306 GregorianCalendar
*d
= new GregorianCalendar(98, 8, 7,status
);
307 if (c
->after(*d
,status
) ||
308 c
->after(*c
,status
) ||
309 c
->before(*d
,status
) ||
310 c
->before(*c
,status
) ||
321 void CalendarRegressionTest::test4040996()
324 StringEnumeration
* ids
= TimeZone::createEnumeration(-8 * 60 * 60 * 1000);
326 dataerrln("Unable to create TimeZone enumeration.");
329 UErrorCode status
= U_ZERO_ERROR
;
330 count
= ids
->count(status
);
331 (void)count
; // Suppress set but not used warning.
332 SimpleTimeZone
*pdt
= new SimpleTimeZone(-8 * 60 * 60 * 1000, *ids
->snext(status
));
333 pdt
->setStartRule(UCAL_APRIL
, 1, UCAL_SUNDAY
, 2 * 60 * 60 * 1000, status
);
334 pdt
->setEndRule(UCAL_OCTOBER
, -1, UCAL_SUNDAY
, 2 * 60 * 60 * 1000, status
);
335 Calendar
*calendar
= new GregorianCalendar(pdt
, status
);
336 if (U_FAILURE(status
)) {
337 dataerrln("Fail new GregorianCalendar: %s", u_errorName(status
));
340 calendar
->set(UCAL_MONTH
,3);
341 calendar
->set(UCAL_DATE
,18);
342 calendar
->set(UCAL_SECOND
, 30);
344 logln(UnicodeString("MONTH: ") + calendar
->get(UCAL_MONTH
, status
));
345 logln(UnicodeString("DAY_OF_MONTH: ") +
346 calendar
->get(UCAL_DATE
, status
));
347 logln(UnicodeString("MINUTE: ") + calendar
->get(UCAL_MINUTE
, status
));
348 logln(UnicodeString("SECOND: ") + calendar
->get(UCAL_SECOND
, status
));
350 calendar
->add(UCAL_SECOND
,6, status
);
351 //This will print out todays date for MONTH and DAY_OF_MONTH
352 //instead of the date it was set to.
353 //This happens when adding MILLISECOND or MINUTE also
354 logln(UnicodeString("MONTH: ") + calendar
->get(UCAL_MONTH
, status
));
355 logln(UnicodeString("DAY_OF_MONTH: ") +
356 calendar
->get(UCAL_DATE
, status
));
357 logln(UnicodeString("MINUTE: ") + calendar
->get(UCAL_MINUTE
, status
));
358 logln(UnicodeString("SECOND: ") + calendar
->get(UCAL_SECOND
, status
));
359 if (calendar
->get(UCAL_MONTH
, status
) != 3 ||
360 calendar
->get(UCAL_DATE
, status
) != 18 ||
361 calendar
->get(UCAL_SECOND
, status
) != 36)
362 errln(UnicodeString("Fail: Calendar::add misbehaves"));
366 // delete ids; // TODO: BAD API
372 void CalendarRegressionTest::test4051765()
374 UErrorCode status
= U_ZERO_ERROR
;
375 Calendar
*cal
= Calendar::createInstance(status
);
376 if(U_FAILURE(status
)) {
377 dataerrln("Error creating Calendar: %s", u_errorName(status
));
381 cal
->setLenient(FALSE
);
382 cal
->set(UCAL_DAY_OF_WEEK
, 0);
384 cal
->getTime(status
);
385 if( ! U_FAILURE(status
))
386 errln("Fail: DAY_OF_WEEK 0 should be disallowed");
388 catch (IllegalArgumentException e) {
395 /* User error - no bug here
396 void CalendarRegressionTest::test4059524() {
397 // Create calendar for April 10, 1997
398 GregorianCalendar calendar = new GregorianCalendar(status);
399 // print out a bunch of interesting things
400 logln("ERA: " + Calendar::get(Calendar::ERA));
401 logln("YEAR: " + Calendar::get(Calendar::YEAR));
402 logln("MONTH: " + Calendar::get(Calendar::MONTH));
403 logln("WEEK_OF_YEAR: " +
404 Calendar::get(Calendar::WEEK_OF_YEAR));
405 logln("WEEK_OF_MONTH: " +
406 Calendar::get(Calendar::WEEK_OF_MONTH));
407 logln("DATE: " + Calendar::get(Calendar::DATE));
408 logln("DAY_OF_MONTH: " +
409 Calendar::get(Calendar::DAY_OF_MONTH));
410 logln("DAY_OF_YEAR: " + Calendar::get(Calendar::DAY_OF_YEAR));
411 logln("DAY_OF_WEEK: " + Calendar::get(Calendar::DAY_OF_WEEK));
412 logln("DAY_OF_WEEK_IN_MONTH: " +
413 Calendar::get(Calendar::DAY_OF_WEEK_IN_MONTH));
414 logln("AM_PM: " + Calendar::get(Calendar::AM_PM));
415 logln("HOUR: " + Calendar::get(Calendar::HOUR));
416 logln("HOUR_OF_DAY: " + Calendar::get(Calendar::HOUR_OF_DAY));
417 logln("MINUTE: " + Calendar::get(Calendar::MINUTE));
418 logln("SECOND: " + Calendar::get(Calendar::SECOND));
419 logln("MILLISECOND: " + Calendar::get(Calendar::MILLISECOND));
420 logln("ZONE_OFFSET: "
421 + (Calendar::get(Calendar::ZONE_OFFSET)/(60*60*1000)));
423 + (Calendar::get(Calendar::DST_OFFSET)/(60*60*1000)));
424 calendar = new GregorianCalendar(1997,3,10);
426 logln("April 10, 1997");
427 logln("ERA: " + Calendar::get(Calendar::ERA));
428 logln("YEAR: " + Calendar::get(Calendar::YEAR));
429 logln("MONTH: " + Calendar::get(Calendar::MONTH));
430 logln("WEEK_OF_YEAR: " +
431 Calendar::get(Calendar::WEEK_OF_YEAR));
432 logln("WEEK_OF_MONTH: " +
433 Calendar::get(Calendar::WEEK_OF_MONTH));
434 logln("DATE: " + Calendar::get(Calendar::DATE));
435 logln("DAY_OF_MONTH: " +
436 Calendar::get(Calendar::DAY_OF_MONTH));
437 logln("DAY_OF_YEAR: " + Calendar::get(Calendar::DAY_OF_YEAR));
438 logln("DAY_OF_WEEK: " + Calendar::get(Calendar::DAY_OF_WEEK));
439 logln("DAY_OF_WEEK_IN_MONTH: " + Calendar::get(Calendar::DAY_OF_WEEK_IN_MONTH));
440 logln("AM_PM: " + Calendar::get(Calendar::AM_PM));
441 logln("HOUR: " + Calendar::get(Calendar::HOUR));
442 logln("HOUR_OF_DAY: " + Calendar::get(Calendar::HOUR_OF_DAY));
443 logln("MINUTE: " + Calendar::get(Calendar::MINUTE));
444 logln("SECOND: " + Calendar::get(Calendar::SECOND));
445 logln("MILLISECOND: " + Calendar::get(Calendar::MILLISECOND));
446 logln("ZONE_OFFSET: "
447 + (Calendar::get(Calendar::ZONE_OFFSET)/(60*60*1000))); // in hours
449 + (Calendar::get(Calendar::DST_OFFSET)/(60*60*1000))); // in hours
456 void CalendarRegressionTest::test4059654() {
457 UErrorCode status
= U_ZERO_ERROR
;
458 GregorianCalendar
*gc
= new GregorianCalendar(status
);
459 if(U_FAILURE(status
)) {
460 dataerrln("Error creating Calendar: %s", u_errorName(status
));
465 gc
->set(1997, 3, 1, 15, 16, 17); // April 1, 1997
467 gc
->set(UCAL_HOUR
, 0);
468 gc
->set(UCAL_AM_PM
, UCAL_AM
);
469 gc
->set(UCAL_MINUTE
, 0);
470 gc
->set(UCAL_SECOND
, 0);
471 gc
->set(UCAL_MILLISECOND
, 0);
473 UDate cd
= gc
->getTime(status
);
474 GregorianCalendar
*exp
= new GregorianCalendar(1997, 3, 1, 0, 0, 0, status
);
475 if (cd
!= exp
->getTime(status
))
476 errln(UnicodeString("Fail: Calendar::set broken. Got ") + cd
+ " Want " + exp
->getTime(status
));
485 void CalendarRegressionTest::test4061476()
487 UErrorCode status
= U_ZERO_ERROR
;
488 SimpleDateFormat
*fmt
= new SimpleDateFormat(UnicodeString("ddMMMyy"), Locale::getUK(),status
);
489 Calendar
*cal
= Calendar::createInstance(TimeZone::createTimeZone("GMT"),
490 Locale::getUK(),status
);
491 if(U_FAILURE(status
)) {
492 dataerrln("Error creating Calendar: %s", u_errorName(status
));
497 fmt
->adoptCalendar(cal
);
499 UDate date
= fmt
->parse("29MAY97", status
);
500 failure(status
, "fmt->parse");
501 cal
->setTime(date
, status
);
502 failure(status
, "cal->setTime");
504 //catch (Exception e) {;}
505 cal
->set(UCAL_HOUR_OF_DAY
, 13);
506 logln(UnicodeString("Hour: ")+cal
->get(UCAL_HOUR_OF_DAY
, status
));
507 cal
->add(UCAL_HOUR_OF_DAY
, 6,status
);
508 logln(UnicodeString("Hour: ")+cal
->get(UCAL_HOUR_OF_DAY
, status
));
509 if (cal
->get(UCAL_HOUR_OF_DAY
, status
) != 19)
510 errln(UnicodeString("Fail: Want 19 Got ") + cal
->get(UCAL_HOUR_OF_DAY
, status
));
518 void CalendarRegressionTest::test4070502()
520 UErrorCode status
= U_ZERO_ERROR
;
521 Calendar
*cal
= new GregorianCalendar(status
);
522 if(status
== U_USING_FALLBACK_WARNING
|| U_FAILURE(status
)) {
523 dataerrln("Error creating Calendar: %s", u_errorName(status
));
527 UDate d
= getAssociatedDate(makeDate(1998,0,30), status
);
528 cal
->setTime(d
,status
);
529 if (cal
->get(UCAL_DAY_OF_WEEK
,status
) == UCAL_SATURDAY
||
530 cal
->get(UCAL_DAY_OF_WEEK
,status
) == UCAL_SUNDAY
)
531 errln(UnicodeString("Fail: Want weekday Got ") + d
);
537 * Get the associated date starting from a specified date
538 * NOTE: the unnecessary "getTime()'s" below are a work-around for a
539 * bug in jdk 1.1.3 (and probably earlier versions also)
541 * @param date The date to start from
544 CalendarRegressionTest::getAssociatedDate(UDate d
, UErrorCode
& status
)
546 GregorianCalendar
*cal
= new GregorianCalendar(status
);
547 cal
->setTime(d
,status
);
548 //cal.add(field, amount); //<-- PROBLEM SEEN WITH field = DATE,MONTH
549 // cal.getTime(); // <--- REMOVE THIS TO SEE BUG
551 int32_t wd
= cal
->get(UCAL_DAY_OF_WEEK
, status
);
552 if (wd
== UCAL_SATURDAY
|| wd
== UCAL_SUNDAY
) {
553 cal
->add(UCAL_DATE
, 1, status
);
560 UDate dd
= cal
->getTime(status
);
568 void CalendarRegressionTest::test4071197()
574 void CalendarRegressionTest::dowTest(UBool lenient
)
576 UErrorCode status
= U_ZERO_ERROR
;
577 GregorianCalendar
*cal
= new GregorianCalendar(status
);
578 if(U_FAILURE(status
)) {
579 dataerrln("Error creating Calendar: %s", u_errorName(status
));
583 cal
->set(1997, UCAL_AUGUST
, 12); // Wednesday
584 // cal.getTime(); // Force update
585 cal
->setLenient(lenient
);
586 cal
->set(1996, UCAL_DECEMBER
, 1); // Set the date to be December 1, 1996
587 int32_t dow
= cal
->get(UCAL_DAY_OF_WEEK
, status
);
588 int32_t min
= cal
->getMinimum(UCAL_DAY_OF_WEEK
);
589 int32_t max
= cal
->getMaximum(UCAL_DAY_OF_WEEK
);
590 //logln(cal.getTime().toString());
591 if (min
!= UCAL_SUNDAY
|| max
!= UCAL_SATURDAY
)
592 errln("FAIL: Min/max bad");
593 if (dow
< min
|| dow
> max
)
594 errln("FAIL: Day of week %d out of range [%d,%d]\n", dow
, min
, max
);
595 if (dow
!= UCAL_SUNDAY
)
596 errln(UnicodeString("FAIL: Day of week should be SUNDAY Got ") + dow
);
598 if(U_FAILURE(status
)) {
599 errln("Error checking Calendar: %s", u_errorName(status
));
604 if(cal
->getActualMinimum(UCAL_DAY_OF_WEEK
, status
) != min
) {
605 errln("FAIL: actual minimum differs from minimum");
607 if(cal
->getActualMinimum(Calendar::DAY_OF_WEEK
, status
) != min
) {
608 errln("FAIL: actual minimum (Calendar::DAY_OF_WEEK, status) differs from minimum");
610 if(cal
->getActualMinimum(Calendar::DAY_OF_WEEK
) != min
) {
611 errln("FAIL: actual minimum (Calendar::DAY_OF_WEEK) differs from minimum");
613 if(((Calendar
*)cal
)->getActualMinimum(UCAL_DAY_OF_WEEK
, status
) != min
) {
614 errln("FAIL: actual minimum (UCAL_DAY_OF_WEEK, status) differs from minimum");
616 // NOTE: This function does not exist! jitterbug #3016
617 // if(((Calendar*)cal)->getActualMinimum(Calendar::DAY_OF_WEEK, status) != min) {
618 // errln("FAIL: actual minimum (Calendar::DAY_OF_WEEK, status) differs from minimum");
620 if(U_FAILURE(status
)) {
621 errln("Error getting actual minimum: %s", u_errorName(status
));
631 void CalendarRegressionTest::test4071385()
633 UErrorCode status
= U_ZERO_ERROR
;
634 Calendar
*cal
= Calendar::createInstance(status
);
635 if(U_FAILURE(status
)) {
636 dataerrln("Error creating Calendar: %s", u_errorName(status
));
640 cal
->setTime(makeDate(1998, UCAL_JUNE
, 24),status
);
641 cal
->set(UCAL_MONTH
, UCAL_NOVEMBER
); // change a field
642 //logln(cal.getTime().toString());
643 if (cal
->getTime(status
) != makeDate(1998, UCAL_NOVEMBER
, 24))
652 void CalendarRegressionTest::test4073929()
654 UErrorCode status
= U_ZERO_ERROR
;
655 GregorianCalendar
*foo1
= new GregorianCalendar(1997, 8, 27,status
);
656 if(U_FAILURE(status
)) {
657 dataerrln("Error creating Calendar: %s", u_errorName(status
));
661 logln("foo1@%.0f - %d-%d-%d %d:%d:%d.%ds\n", foo1
->getTime(status
),
662 foo1
->get(UCAL_YEAR
, status
),
663 foo1
->get(UCAL_MONTH
, status
),
664 foo1
->get(UCAL_DATE
, status
),
665 foo1
->get(UCAL_HOUR
, status
),
666 foo1
->get(UCAL_MINUTE
, status
),
667 foo1
->get(UCAL_SECOND
, status
),
668 foo1
->get(UCAL_MILLISECOND
,status
));
669 foo1
->add(UCAL_DATE
, + 1, status
);
670 logln("foo1@%.0f - %d-%d-%d %d:%d:%d.%ds after +\n", foo1
->getTime(status
),
671 foo1
->get(UCAL_YEAR
, status
),
672 foo1
->get(UCAL_MONTH
, status
),
673 foo1
->get(UCAL_DATE
, status
),
674 foo1
->get(UCAL_HOUR
, status
),
675 foo1
->get(UCAL_MINUTE
, status
),
676 foo1
->get(UCAL_SECOND
, status
),
677 foo1
->get(UCAL_MILLISECOND
,status
));
678 foo1
->add(UCAL_DATE
, - 1, status
);
679 logln("foo1@%.0f - %d-%d-%d %d:%d:%d.%ds after -\n", foo1
->getTime(status
),
680 foo1
->get(UCAL_YEAR
, status
),
681 foo1
->get(UCAL_MONTH
, status
),
682 foo1
->get(UCAL_DATE
, status
),
683 foo1
->get(UCAL_HOUR
, status
),
684 foo1
->get(UCAL_MINUTE
, status
),
685 foo1
->get(UCAL_SECOND
, status
),
686 foo1
->get(UCAL_MILLISECOND
, status
));
688 foo1
->add(UCAL_DATE
, + 1, status
);
689 int32_t testyear
= foo1
->get(UCAL_YEAR
, status
);
690 int32_t testmonth
= foo1
->get(UCAL_MONTH
, status
);
691 int32_t testday
= foo1
->get(UCAL_DATE
, status
);
692 if (testyear
!= 1997 ||
695 errln("Fail: Calendar not initialized");
703 void CalendarRegressionTest::test4083167()
705 UErrorCode status
= U_ZERO_ERROR
;
706 TimeZone
*saveZone
= TimeZone::createDefault();
708 TimeZone
*newZone
= TimeZone::createTimeZone("UTC");
709 TimeZone::setDefault(*newZone
);
710 UDate firstDate
= Calendar::getNow();
711 Calendar
*cal
= new GregorianCalendar(status
);
712 if(U_FAILURE(status
)) {
713 dataerrln("Error creating Calendar: %s", u_errorName(status
));
717 cal
->setTime(firstDate
,status
);
718 int32_t hr
= cal
->get(UCAL_HOUR_OF_DAY
, status
);
719 int32_t min
= cal
->get(UCAL_MINUTE
, status
);
720 int32_t sec
= cal
->get(UCAL_SECOND
, status
);
721 int32_t msec
= cal
->get(UCAL_MILLISECOND
, status
);
722 double firstMillisInDay
= hr
* 3600000 + min
* 60000 + sec
* 1000 + msec
;
724 //logln("Current time: " + firstDate.toString());
726 for (int32_t validity
=0; validity
<30; validity
++) {
727 UDate lastDate
= firstDate
+ validity
*1000*24*60*60.0;
728 cal
->setTime(lastDate
, status
);
729 hr
= cal
->get(UCAL_HOUR_OF_DAY
, status
);
730 min
= cal
->get(UCAL_MINUTE
, status
);
731 sec
= cal
->get(UCAL_SECOND
, status
);
732 msec
= cal
->get(UCAL_MILLISECOND
, status
);
733 double millisInDay
= hr
* 3600000.0 + min
* 60000.0 + sec
* 1000.0 + msec
;
734 if (firstMillisInDay
!= millisInDay
)
735 errln(UnicodeString("Day has shifted ") + lastDate
);
739 TimeZone::setDefault(*saveZone
);
750 void CalendarRegressionTest::test4086724()
752 UErrorCode status
= U_ZERO_ERROR
;
753 SimpleDateFormat
*date
;
754 TimeZone
*saveZone
= TimeZone::createDefault();
755 Locale saveLocale
= Locale::getDefault();
757 Locale::setDefault(Locale::getUK(),status
);
758 TimeZone
*newZone
= TimeZone::createTimeZone("GMT");
759 TimeZone::setDefault(*newZone
);
760 date
= new SimpleDateFormat(UnicodeString("dd MMM yyy (zzzz) 'is in week' ww"),status
);
761 Calendar
*cal
= Calendar::createInstance(status
);
762 if(U_FAILURE(status
)) {
763 dataerrln("Error creating Calendar: %s", u_errorName(status
));
769 cal
->set(1997,UCAL_SEPTEMBER
,30);
770 UDate now
= cal
->getTime(status
);
772 FieldPosition
pos(FieldPosition::DONT_CARE
);
773 logln(date
->format(now
, temp
, pos
));
774 cal
->set(1997,UCAL_JANUARY
,1);
775 now
=cal
->getTime(status
);
776 logln(date
->format(now
,temp
, pos
));
777 cal
->set(1997,UCAL_JANUARY
,8);
778 now
=cal
->getTime(status
);
779 logln(date
->format(now
,temp
, pos
));
780 cal
->set(1996,UCAL_DECEMBER
,31);
781 now
=cal
->getTime(status
);
782 logln(date
->format(now
,temp
, pos
));
785 Locale::setDefault(saveLocale
,status
);
786 TimeZone::setDefault(*saveZone
);
788 logln("*** THE RESULTS OF THIS TEST MUST BE VERIFIED MANUALLY ***");
799 void CalendarRegressionTest::test4092362() {
800 UErrorCode status
= U_ZERO_ERROR
;
801 GregorianCalendar
*cal1
= new GregorianCalendar(1997, 10, 11, 10, 20, 40,status
);
802 if (U_FAILURE(status
)) {
803 dataerrln("Fail new GregorianCalendar: %s", u_errorName(status
));
807 /*cal1.set( Calendar::YEAR, 1997 );
808 cal1.set( Calendar::MONTH, 10 );
809 cal1.set( Calendar::DATE, 11 );
810 cal1.set( Calendar::HOUR, 10 );
811 cal1.set( Calendar::MINUTE, 20 );
812 cal1.set( Calendar::SECOND, 40 ); */
814 logln( UnicodeString(" Cal1 = ") + cal1
->getTime(status
) );
815 logln( UnicodeString(" Cal1 time in ms = ") + cal1
->get(UCAL_MILLISECOND
,status
) );
816 for (int32_t k
= 0; k
< 100 ; k
++)
819 GregorianCalendar
*cal2
= new GregorianCalendar(1997, 10, 11, 10, 20, 40,status
);
820 /*cal2.set( Calendar::YEAR, 1997 );
821 cal2.set( Calendar::MONTH, 10 );
822 cal2.set( Calendar::DATE, 11 );
823 cal2.set( Calendar::HOUR, 10 );
824 cal2.set( Calendar::MINUTE, 20 );
825 cal2.set( Calendar::SECOND, 40 ); */
827 logln( UnicodeString(" Cal2 = ") + cal2
->getTime(status
) );
828 logln( UnicodeString(" Cal2 time in ms = ") + cal2
->get(UCAL_MILLISECOND
,status
) );
830 errln("Fail: Milliseconds randomized");
839 void CalendarRegressionTest::test4095407()
841 UErrorCode status
= U_ZERO_ERROR
;
842 GregorianCalendar
*a
= new GregorianCalendar(1997,UCAL_NOVEMBER
, 13,status
);
843 if (U_FAILURE(status
)) {
844 dataerrln("Fail new GregorianCalendar: %s", u_errorName(status
));
848 int32_t dow
= a
->get(UCAL_DAY_OF_WEEK
, status
);
849 if (dow
!= UCAL_THURSDAY
)
850 errln(UnicodeString("Fail: Want THURSDAY Got ") + dow
);
858 void CalendarRegressionTest::test4096231()
860 UErrorCode status
= U_ZERO_ERROR
;
861 TimeZone
*GMT
= TimeZone::createTimeZone("GMT");
862 TimeZone
*PST
= TimeZone::createTimeZone("PST");
863 int32_t sec
= 0, min
= 0, hr
= 0, day
= 1, month
= 10, year
= 1997;
865 Calendar
*cal1
= new GregorianCalendar(*PST
,status
);
866 if (U_FAILURE(status
)) {
867 dataerrln("Failure new GregorianCalendar: %s", u_errorName(status
));
873 cal1
->setTime(880698639000.0,status
);
874 // Issue 1: Changing the timezone doesn't change the
875 // represented time. The old API, pre 1.2.2a requires
876 // setTime to be called in order to update the time fields after the time
877 // zone has been set.
879 logln(UnicodeString("PST 1 is: ") + (h1
=cal1
->get(UCAL_HOUR_OF_DAY
, status
)));
880 cal1
->setTimeZone(*GMT
);
881 logln(UnicodeString("GMT 2 is: ") + (h2
=cal1
->get(UCAL_HOUR_OF_DAY
, status
)));
882 if ((*GMT
!= *PST
) && (h1
== h2
))
883 errln("Fail: Hour same in different zones");
885 Calendar
*cal2
= new GregorianCalendar(*GMT
,status
);
886 Calendar
*cal3
= new GregorianCalendar(*PST
,status
);
887 cal2
->set(UCAL_MILLISECOND
, 0);
888 cal3
->set(UCAL_MILLISECOND
, 0);
890 cal2
->set(cal1
->get(UCAL_YEAR
,status
),
891 cal1
->get(UCAL_MONTH
,status
),
892 cal1
->get(UCAL_DATE
,status
),
893 cal1
->get(UCAL_HOUR_OF_DAY
,status
),
894 cal1
->get(UCAL_MINUTE
,status
),
895 cal1
->get(UCAL_SECOND
,status
));
898 logln(UnicodeString("RGMT 1 is: ") + (t1
=cal2
->getTime(status
)));
899 cal3
->set(year
, month
, day
, hr
, min
, sec
);
900 logln(UnicodeString("RPST 1 is: ") + (t2
=cal3
->getTime(status
)));
901 cal3
->setTimeZone(*GMT
);
902 logln(UnicodeString("RGMT 2 is: ") + (t3
=cal3
->getTime(status
)));
903 cal3
->set(cal1
->get(UCAL_YEAR
,status
),
904 cal1
->get(UCAL_MONTH
,status
),
905 cal1
->get(UCAL_DATE
,status
),
906 cal1
->get(UCAL_HOUR_OF_DAY
,status
),
907 cal1
->get(UCAL_MINUTE
,status
),
908 cal1
->get(UCAL_SECOND
,status
));
909 // Issue 2: Calendar continues to use the timezone in its
910 // constructor for set() conversions, regardless
911 // of calls to setTimeZone()
912 logln(UnicodeString("RGMT 3 is: ") + (t4
=cal3
->getTime(status
)));
916 errln("Fail: Calendar zone behavior faulty");
928 void CalendarRegressionTest::test4096539()
930 UErrorCode status
= U_ZERO_ERROR
;
931 int32_t y
[] = {31,28,31,30,31,30,31,31,30,31,30,31};
933 for (int32_t x
=0;x
<12;x
++) {
934 GregorianCalendar
*gc
= new
935 GregorianCalendar(1997,x
,y
[x
], status
);
936 if (U_FAILURE(status
)) {
937 dataerrln("Fail new GregorianCalendar: %s", u_errorName(status
));
942 log(UnicodeString("") + (m1
=gc
->get(UCAL_MONTH
,status
)+1)+UnicodeString("/")+
943 gc
->get(UCAL_DATE
,status
)+"/"+gc
->get(UCAL_YEAR
,status
)+
946 gc
->add(UCAL_MONTH
, 1,status
);
947 logln(UnicodeString("") + (m2
=gc
->get(UCAL_MONTH
,status
)+1)+UnicodeString("/")+
948 gc
->get(UCAL_DATE
,status
)+"/"+gc
->get(UCAL_YEAR
,status
)
950 int32_t m
= (m1
% 12) + 1;
952 errln(UnicodeString("Fail: Want ") + m
+ " Got " + m2
);
961 void CalendarRegressionTest::test41003112()
963 UErrorCode status
= U_ZERO_ERROR
;
964 GregorianCalendar
*cal
= (GregorianCalendar
*)Calendar::createInstance(status
);
965 if(U_FAILURE(status
)) {
966 dataerrln("Error creating calendar: %s", u_errorName(status
));
970 cal
->set(UCAL_YEAR
, 1997);
971 cal
->set(UCAL_DAY_OF_YEAR
, 1);
972 //UDate d = cal->getTime(status); // Should be Jan 1
973 //logln(d.toString());
974 if (cal
->get(UCAL_DAY_OF_YEAR
, status
) != 1)
975 errln("Fail: DAY_OF_YEAR not set");
982 void CalendarRegressionTest::test4103271()
984 UErrorCode status
= U_ZERO_ERROR
;
985 SimpleDateFormat
sdf(status
);
986 int32_t numYears
=40, startYear
=1997, numDays
=15;
987 UnicodeString output
, testDesc
, str
, str2
;
988 GregorianCalendar
*testCal
= (GregorianCalendar
*)Calendar::createInstance(status
);
989 if(U_FAILURE(status
)) {
990 dataerrln("Error creating calendar: %s", u_errorName(status
));
995 sdf
.adoptCalendar(testCal
);
996 sdf
.applyPattern("EEE dd MMM yyyy 'WOY'ww'-'YYYY 'DOY'DDD");
998 for (int32_t firstDay
=1; firstDay
<=2; firstDay
++) {
999 for (int32_t minDays
=1; minDays
<=7; minDays
++) {
1000 testCal
->setMinimalDaysInFirstWeek((uint8_t)minDays
);
1001 testCal
->setFirstDayOfWeek((UCalendarDaysOfWeek
)firstDay
);
1002 testDesc
= (UnicodeString("Test") + firstDay
+ minDays
);
1003 logln(testDesc
+ " => 1st day of week=" +
1005 ", minimum days in first week=" +
1007 for (int32_t j
=startYear
; j
<=startYear
+numYears
; j
++) {
1008 testCal
->set(j
,11,25);
1009 for(int32_t i
=0; i
<numDays
; i
++) {
1010 testCal
->add(UCAL_DATE
,1,status
);
1011 UnicodeString calWOY
;
1012 int32_t actWOY
= testCal
->get(UCAL_WEEK_OF_YEAR
,status
);
1013 if (actWOY
< 1 || actWOY
> 53) {
1014 UDate d
= testCal
->getTime(status
);
1015 //calWOY = String.valueOf(actWOY);
1017 FieldPosition
pos(FieldPosition::DONT_CARE
);
1018 output
= testDesc
+ " - " + sdf
.format(d
,temp
,pos
) + "\t";
1019 output
= output
+ "\t" + actWOY
;
1029 3, 52, 52, 52, 52, 52, 52, 52,
1030 1, 1, 1, 1, 1, 1, 1,
1031 2, 2, 2, 2, 2, 2, 2,
1032 4, 52, 52, 52, 52, 52, 52, 52,
1033 53, 53, 53, 53, 53, 53, 53,
1034 1, 1, 1, 1, 1, 1, 1,
1036 testCal
->setFirstDayOfWeek(UCAL_SUNDAY
);
1037 for (int32_t j
=0; j
<44; j
+=22) {
1038 logln(UnicodeString("Minimal days in first week = ") + DATA
[j
] +
1039 " Week starts on Sunday");
1040 testCal
->setMinimalDaysInFirstWeek((uint8_t)DATA
[j
]);
1041 testCal
->set(1997, UCAL_DECEMBER
, 21);
1042 for (int32_t i
=0; i
<21; ++i
) {
1043 int32_t woy
= testCal
->get(UCAL_WEEK_OF_YEAR
,status
);
1045 log(UnicodeString("") + sdf
.format(testCal
->getTime(status
), str
) +
1046 UnicodeString(" ") + woy
);
1047 if (woy
!= DATA
[j
+ 1 + i
]) {
1053 // Now compute the time from the fields, and make sure we
1054 // get the same answer back. This is a round-trip test.
1055 UDate save
= testCal
->getTime(status
);
1057 testCal
->set(UCAL_YEAR_WOY
, DATA
[j
+1+i
] < 25 ? 1998 : 1997);
1058 testCal
->set(UCAL_WEEK_OF_YEAR
, DATA
[j
+1+i
]);
1059 testCal
->set(UCAL_DAY_OF_WEEK
, (i%7
) + UCAL_SUNDAY
);
1060 if (testCal
->getTime(status
) != save
) {
1062 logln(UnicodeString(" Parse failed: ") +
1063 sdf
.format(testCal
->getTime(status
), str
));
1067 testCal
->setTime(save
,status
);
1068 testCal
->add(UCAL_DATE
, 1,status
);
1071 // Test field disambiguation with a few special hard-coded cases.
1072 // This shouldn't fail if the above cases aren't failing.
1073 int32_t DISAM_int
[] = {
1075 1997, 1998, 1, UCAL_SUNDAY
,
1076 (1998), (1998), (2), (UCAL_SATURDAY
),
1077 (1998), (1998), (53), (UCAL_THURSDAY
),
1078 (1999), (1998), (53), (UCAL_FRIDAY
)
1081 UDate DISAM_date
[] = {
1082 makeDate(1997, UCAL_DECEMBER
, 28),
1083 makeDate(1998, UCAL_JANUARY
, 10),
1084 makeDate(1998, UCAL_DECEMBER
, 31),
1085 makeDate(1999, UCAL_JANUARY
, 1)
1088 testCal
->setMinimalDaysInFirstWeek(3);
1089 testCal
->setFirstDayOfWeek(UCAL_SUNDAY
);
1092 /* Enable this code to display various WOY values
1094 for (i=25; i<38; ++i) {
1095 testCal->set(1996, Calendar::DECEMBER, i);
1096 UDate got = testCal->getTime(status);
1098 logln(UnicodeString("") + sdf.format(got, str));
1100 for (i=25; i<38; ++i) {
1101 testCal->set(1997, Calendar::DECEMBER, i);
1102 UDate got = testCal->getTime(status);
1104 logln(UnicodeString("") + sdf.format(got, str));
1106 for (i=25; i<38; ++i) {
1107 testCal->set(1998, UCAL_DECEMBER, i);
1108 UDate got = testCal->getTime(status);
1110 logln(UnicodeString("") + sdf.format(got, str));
1114 for (i
=0; i
< 16; i
+= 4) {
1115 int32_t y
= DISAM_int
[i
];
1116 int32_t ywoy
= DISAM_int
[i
+1];
1117 int32_t woy
= DISAM_int
[i
+2];
1118 int32_t dow
= DISAM_int
[i
+3];
1119 UDate exp
= DISAM_date
[i
/4];
1121 testCal
->set(UCAL_YEAR
, y
);
1122 testCal
->set(UCAL_WEEK_OF_YEAR
, woy
);
1123 testCal
->set(UCAL_DAY_OF_WEEK
, dow
);
1124 UDate got
= testCal
->getTime(status
);
1127 log(UnicodeString("Y") + y
+ "-W" + woy
+
1128 "-DOW" + dow
+ " expect:" + sdf
.format(exp
, str
) +
1129 " got:" + sdf
.format(got
, str2
));
1131 log(" FAIL (%s:%d, i=%d)", __FILE__
, __LINE__
, i
);
1132 logln(CalendarTest::calToStr(*testCal
));
1133 testCal
->setTime(exp
, status
);
1134 logln(CalendarTest::calToStr(*testCal
) + UnicodeString( " <<< expected "));
1140 testCal
->set(UCAL_YEAR_WOY
, ywoy
);
1141 testCal
->set(UCAL_WEEK_OF_YEAR
, woy
);
1142 testCal
->set(UCAL_DAY_OF_WEEK
, dow
);
1143 got
= testCal
->getTime(status
);
1146 log(UnicodeString("YWOY") + ywoy
+ "-W" + woy
+
1147 "-DOW" + dow
+ " expect:" + sdf
.format(exp
, str
) +
1148 " got:" + sdf
.format(got
, str2
));
1155 // Now try adding and rolling
1156 UDate ADDROLL_date
[] = {
1157 makeDate(1998, UCAL_DECEMBER
, 25), makeDate(1999, UCAL_JANUARY
, 1),
1158 makeDate(1997, UCAL_DECEMBER
, 28), makeDate(1998, UCAL_JANUARY
, 4),
1159 makeDate(1998, UCAL_DECEMBER
, 27), makeDate(1997, UCAL_DECEMBER
, 28),
1160 makeDate(1999, UCAL_JANUARY
, 2), makeDate(1998, UCAL_JANUARY
, 3),
1163 int32_t ADDROLL_int
[]= {
1171 UBool ADDROLL_bool
[] = {
1178 testCal
->setMinimalDaysInFirstWeek(3);
1179 testCal
->setFirstDayOfWeek(UCAL_SUNDAY
);
1180 for (i
=0; i
<8; i
+= 2) {
1181 int32_t amount
= ADDROLL_int
[i
/2];
1182 UDate before
= ADDROLL_date
[i
];
1183 UDate after
= ADDROLL_date
[i
+1];
1185 testCal
->setTime(before
,status
);
1186 if (ADDROLL_bool
[i
/2])
1187 testCal
->add(UCAL_WEEK_OF_YEAR
, amount
,status
);
1189 testCal
->roll(UCAL_WEEK_OF_YEAR
, amount
,status
);
1190 UDate got
= testCal
->getTime(status
);
1193 UnicodeString opTypeStr
;
1194 if (ADDROLL_bool
[i
/2]) {
1195 opTypeStr
= UnicodeString("add(WOY,", "");
1197 opTypeStr
= UnicodeString("roll(WOY,", "");
1199 log(opTypeStr
+ amount
+ ") " + sdf
.format(before
, str
) + " => " +
1200 sdf
.format(got
, str2
));
1203 logln(UnicodeString(" exp:") + sdf
.format(after
, str
) + " FAIL");
1208 testCal
->setTime(after
,status
);
1209 if (ADDROLL_bool
[i
/2])
1210 testCal
->add(UCAL_WEEK_OF_YEAR
, -amount
,status
);
1212 testCal
->roll(UCAL_WEEK_OF_YEAR
, -amount
,status
);
1213 got
= testCal
->getTime(status
);
1216 log(opTypeStr
+ (-amount
) + ") " + sdf
.format(after
, str
) + " => " +
1217 sdf
.format(got
, str2
));
1218 if (before
!= got
) {
1220 logln(UnicodeString(" exp:") + sdf
.format(before
, str
) + " FAIL");
1226 errln("Fail: Week of year misbehaving");
1232 void CalendarRegressionTest::test4106136()
1234 UErrorCode status
= U_ZERO_ERROR
;
1235 Locale saveLocale
= Locale::getDefault();
1237 Locale locales
[] = { Locale::getChinese(), Locale::getChina() };
1238 for (int32_t i
=0; i
<2; ++i
) {
1239 Locale::setDefault(locales
[i
], status
);
1240 failure(status
, "Locale::setDefault");
1241 int32_t count1
, count2
, count3
;
1242 Calendar::getAvailableLocales(count1
);
1243 DateFormat::getAvailableLocales(count2
);
1244 NumberFormat::getAvailableLocales(count3
);
1246 count1
, count2
, count3
1248 for (int32_t j
=0; j
<3; ++j
) {
1251 dataerrln(UnicodeString("Fail: No locales for ") + locales
[i
].getName());
1256 Locale::setDefault(saveLocale
,status
);
1263 void CalendarRegressionTest::test4108764()
1265 UErrorCode status
= U_ZERO_ERROR
;
1266 Calendar
*cal
= Calendar::createInstance(status
);
1267 if(U_FAILURE(status
)) {
1268 dataerrln("Error creating calendar %s", u_errorName(status
));
1272 UDate d00
= makeDate(1997, UCAL_MARCH
, 15, 12, 00, 00);
1273 UDate d01
= makeDate(1997, UCAL_MARCH
, 15, 12, 00, 56);
1274 UDate d10
= makeDate(1997, UCAL_MARCH
, 15, 12, 34, 00);
1275 UDate d11
= makeDate(1997, UCAL_MARCH
, 15, 12, 34, 56);
1276 UDate epoch
= makeDate(1970, UCAL_JANUARY
, 1);
1278 cal
->setTime(d11
,status
);
1280 cal
->clear( UCAL_MINUTE
);
1281 logln(UnicodeString("") + cal
->getTime(status
));
1282 if (cal
->getTime(status
) != d01
)
1283 errln("Fail: clear(MINUTE) broken");
1285 cal
->set( UCAL_SECOND
, 0 );
1286 logln(UnicodeString("") + cal
->getTime(status
));
1287 if (cal
->getTime(status
) != d00
)
1288 errln("Fail: set(SECOND, 0) broken");
1290 cal
->setTime(d11
,status
);
1291 cal
->set( UCAL_SECOND
, 0 );
1292 logln(UnicodeString("") + cal
->getTime(status
));
1293 if (cal
->getTime(status
) != d10
)
1294 errln("Fail: set(SECOND, 0) broken #2");
1296 cal
->clear( UCAL_MINUTE
);
1297 logln(UnicodeString("") + cal
->getTime(status
));
1298 if (cal
->getTime(status
) != d00
)
1299 errln("Fail: clear(MINUTE) broken #2");
1302 logln(UnicodeString("") + cal
->getTime(status
));
1303 if (cal
->getTime(status
) != epoch
)
1304 errln(UnicodeString("Fail: clear() broken Want ") + epoch
);
1312 void CalendarRegressionTest::test4114578()
1314 UErrorCode status
= U_ZERO_ERROR
;
1315 double ONE_HOUR
= 60*60*1000;
1316 Calendar
*cal
= Calendar::createInstance(status
);
1317 if(U_FAILURE(status
)) {
1318 dataerrln("Error creating calendar %s", u_errorName(status
));
1322 cal
->adoptTimeZone(TimeZone::createTimeZone("PST"));
1323 UDate onset
= makeDate(1998, UCAL_APRIL
, 5, 1, 0) + ONE_HOUR
;
1324 UDate cease
= makeDate(1998, UCAL_OCTOBER
, 25, 0, 0) + 2*ONE_HOUR
;
1328 const int32_t ADD
= 1;
1329 const int32_t ROLL
= 2;
1332 // Start Action Amt Expected_change
1333 onset
- ONE_HOUR
, ADD
, 1, ONE_HOUR
,
1334 onset
, ADD
, -1, -ONE_HOUR
,
1335 onset
- ONE_HOUR
, ROLL
, 1, ONE_HOUR
,
1336 onset
, ROLL
, -1, -ONE_HOUR
,
1337 cease
- ONE_HOUR
, ADD
, 1, ONE_HOUR
,
1338 cease
, ADD
, -1, -ONE_HOUR
,
1339 cease
- ONE_HOUR
, ROLL
, 1, ONE_HOUR
,
1340 cease
, ROLL
, -1, -ONE_HOUR
,
1343 for (int32_t i
=0; i
<32; i
+=4) {
1344 UDate date
= DATA
[i
];
1345 int32_t amt
= (int32_t) DATA
[i
+2];
1346 double expectedChange
= DATA
[i
+3];
1348 log(UnicodeString("") + date
);
1349 cal
->setTime(date
,status
);
1351 switch ((int32_t) DATA
[i
+1]) {
1353 log(UnicodeString(" add (HOUR,") + (amt
<0?"":"+")+amt
+ ")= ");
1354 cal
->add(UCAL_HOUR
, amt
,status
);
1357 log(UnicodeString(" roll(HOUR,") + (amt
<0?"":"+")+amt
+ ")= ");
1358 cal
->roll(UCAL_HOUR
, amt
,status
);
1362 log(UnicodeString("") + cal
->getTime(status
));
1364 double change
= cal
->getTime(status
) - date
;
1365 if (change
!= expectedChange
) {
1372 if (fail
) errln("Fail: roll/add misbehaves around DST onset/cease");
1379 * Make sure maximum for HOUR field is 11, not 12.
1381 void CalendarRegressionTest::test4118384()
1383 UErrorCode status
= U_ZERO_ERROR
;
1384 Calendar
*cal
= Calendar::createInstance(status
);
1385 if(U_FAILURE(status
)) {
1386 dataerrln("Error creating calendar %s", u_errorName(status
));
1390 if (cal
->getMaximum(UCAL_HOUR
) != 11 ||
1391 cal
->getLeastMaximum(UCAL_HOUR
) != 11 ||
1392 cal
->getActualMaximum(UCAL_HOUR
,status
) != 11)
1393 errln("Fail: maximum of HOUR field should be 11");
1395 // test deprecated functions
1396 if (cal
->getLeastMaximum(Calendar::HOUR
) != 11 ||
1397 cal
->getMaximum(Calendar::HOUR
) != 11) {
1398 errln("Fail: [deprecated functions] maximum of HOUR field should be 11\n");
1401 if (cal
->getGreatestMinimum(Calendar::HOUR
) != 0 ||
1402 cal
->getMinimum(Calendar::HOUR
) != 0) {
1403 errln("Fail: [deprecated functions] minimum of HOUR field should be 1\n");
1407 cal
= Calendar::createInstance(Locale("th_TH@calendar=buddhist"),status
);
1408 // test deprecated functions
1409 if (cal
->getLeastMaximum(Calendar::HOUR
) != 11 ||
1410 cal
->getMaximum(Calendar::HOUR
) != 11) {
1411 errln("Fail: Buddhist:[deprecated functions] maximum of HOUR field should be 11\n");
1414 if (cal
->getGreatestMinimum(Calendar::HOUR
) != 0 ||
1415 cal
->getMinimum(Calendar::HOUR
) != 0) {
1416 errln("Fail: Buddhist:[deprecated functions] minimum of HOUR field should be 1\n");
1420 // test deprecated functions
1421 cal
= Calendar::createInstance(Locale("ja_JP@calendar=japanese"),status
);
1422 if (cal
->getLeastMaximum(Calendar::HOUR
) != 11 ||
1423 cal
->getMaximum(Calendar::HOUR
) != 11) {
1424 errln("Fail: Japanese:[deprecated functions] maximum of HOUR field should be 11\n");
1427 if (cal
->getGreatestMinimum(Calendar::HOUR
) != 0 ||
1428 cal
->getMinimum(Calendar::HOUR
) != 0) {
1429 errln("Fail: Japanese:[deprecated functions] minimum of HOUR field should be 1\n");
1437 * Check isLeapYear for BC years.
1439 void CalendarRegressionTest::test4125881()
1441 UErrorCode status
= U_ZERO_ERROR
;
1442 GregorianCalendar
*cal
= (GregorianCalendar
*) Calendar::createInstance(status
);
1443 if(U_FAILURE(status
)) {
1444 dataerrln("Error creating calendar %s", u_errorName(status
));
1448 DateFormat
*fmt
= new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"),status
);
1449 if(U_FAILURE(status
)) {
1450 dataerrln("Error creating SimpleDateFormat - %s", u_errorName(status
));
1455 for (int32_t y
=-20; y
<=10; ++y
) {
1456 cal
->set(UCAL_ERA
, y
< 1 ? GregorianCalendar::BC
: GregorianCalendar::AD
);
1457 cal
->set(UCAL_YEAR
, y
< 1 ? 1 - y
: y
);
1459 logln(UnicodeString("") + y
+ UnicodeString(" = ") + fmt
->format(cal
->getTime(status
), temp
) + " " +
1460 cal
->isLeapYear(y
));
1461 if (cal
->isLeapYear(y
) != ((y
+40)%4
== 0))
1462 errln("Leap years broken");
1471 * Prove that GregorianCalendar is proleptic (it used to cut off
1472 * at 45 BC, and not have leap years before then).
1474 void CalendarRegressionTest::test4125892() {
1475 UErrorCode status
= U_ZERO_ERROR
;
1476 GregorianCalendar
*cal
= (GregorianCalendar
*) Calendar::createInstance(status
);
1477 if(U_FAILURE(status
)) {
1478 dataerrln("Error creating calendar %s", u_errorName(status
));
1482 DateFormat
*fmt
= new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"),status
);
1483 if(U_FAILURE(status
)) {
1484 dataerrln("Error creating SimpleDateFormat - %s", u_errorName(status
));
1489 cal
->set(UCAL_ERA
, GregorianCalendar::BC
);
1490 cal
->set(UCAL_YEAR
, 81); // 81 BC is a leap year (proleptically)
1491 cal
->set(UCAL_MONTH
, UCAL_FEBRUARY
);
1492 cal
->set(UCAL_DATE
, 28);
1493 cal
->add(UCAL_DATE
, 1,status
);
1494 if(U_FAILURE(status
))
1495 errln("add(DATE,1) failed");
1496 if (cal
->get(UCAL_DATE
,status
) != 29 ||
1497 !cal
->isLeapYear(-80)) // -80 == 81 BC
1498 errln("Calendar not proleptic");
1506 * GregorianCalendar::equals() ignores cutover date
1508 void CalendarRegressionTest::test4141665()
1510 UErrorCode status
= U_ZERO_ERROR
;
1511 GregorianCalendar
*cal
= new GregorianCalendar(status
);
1512 if(U_FAILURE(status
)) {
1513 dataerrln("Error creating calendar %s", u_errorName(status
));
1517 GregorianCalendar
*cal2
= (GregorianCalendar
*)cal
->clone();
1518 UDate cut
= cal
->getGregorianChange();
1519 UDate cut2
= cut
+ 100*24*60*60*1000.0; // 100 days later
1520 if (*cal
!= *cal2
) {
1521 errln("Cloned GregorianCalendars not equal");
1523 cal2
->setGregorianChange(cut2
,status
);
1524 if ( *cal
== *cal2
) {
1525 errln("GregorianCalendar::equals() ignores cutover");
1534 * Bug states that ArrayIndexOutOfBoundsException is thrown by GregorianCalendar::roll()
1535 * when IllegalArgumentException should be.
1537 void CalendarRegressionTest::test4142933()
1539 UErrorCode status
= U_ZERO_ERROR
;
1540 GregorianCalendar
*calendar
= new GregorianCalendar(status
);
1541 if(U_FAILURE(status
)) {
1542 dataerrln("Error creating calendar %s", u_errorName(status
));
1547 calendar
->roll((UCalendarDateFields
)-1, TRUE
, status
);
1548 if(U_SUCCESS(status
))
1549 errln("Test failed, no exception thrown");
1551 //catch (IllegalArgumentException e) {
1553 // logln("Test passed");
1555 //catch (Exception e) {
1556 //errln("Test failed. Unexpected exception is thrown: " + e);
1557 //e.printStackTrace();
1565 * GregorianCalendar handling of Dates Long.MIN_VALUE and Long.MAX_VALUE is
1566 * confusing; unless the time zone has a raw offset of zero, one or the
1567 * other of these will wrap. We've modified the test given in the bug
1568 * report to therefore only check the behavior of a calendar with a zero raw
1571 void CalendarRegressionTest::test4145158()
1573 UErrorCode status
= U_ZERO_ERROR
;
1574 GregorianCalendar
*calendar
= new GregorianCalendar(status
);
1575 if(status
== U_USING_FALLBACK_WARNING
|| U_FAILURE(status
)) {
1576 dataerrln("Error creating calendar %s", u_errorName(status
));
1581 calendar
->adoptTimeZone(TimeZone::createTimeZone("GMT"));
1583 calendar
->setTime(makeDate(INT32_MIN
),status
);
1584 int32_t year1
= calendar
->get(UCAL_YEAR
,status
);
1585 int32_t era1
= calendar
->get(UCAL_ERA
,status
);
1587 calendar
->setTime(makeDate(INT32_MAX
),status
);
1588 int32_t year2
= calendar
->get(UCAL_YEAR
,status
);
1589 int32_t era2
= calendar
->get(UCAL_ERA
,status
);
1591 if (year1
== year2
&& era1
== era2
) {
1592 errln("Fail: Long.MIN_VALUE or Long.MAX_VALUE wrapping around");
1600 * Maximum value for YEAR field wrong.
1602 // {sfb} this is not directly applicable in C++, since all
1603 // possible doubles are not representable by our Calendar.
1604 // In Java, all longs are representable.
1605 // We can determine limits programmatically
1606 // Using DBL_MAX is a bit of a hack, since for large doubles
1607 // Calendar gets squirrely and doesn't behave in any sort
1608 // of linear fashion (ie years jump around, up/down, etc) for a
1609 // small change in millis.
1610 void CalendarRegressionTest::test4145983()
1612 UErrorCode status
= U_ZERO_ERROR
;
1613 GregorianCalendar
*calendar
= new GregorianCalendar(status
);
1614 if(U_FAILURE(status
)) {
1615 dataerrln("Error creating calendar %s", u_errorName(status
));
1619 calendar
->adoptTimeZone(TimeZone::createTimeZone("GMT"));
1620 UDate DATES
[] = { LATEST_SUPPORTED_MILLIS
, EARLIEST_SUPPORTED_MILLIS
};
1621 for (int32_t i
=0; i
<2; ++i
) {
1622 calendar
->setTime(DATES
[i
], status
);
1623 int32_t year
= calendar
->get(UCAL_YEAR
,status
);
1624 int32_t maxYear
= calendar
->getMaximum(UCAL_YEAR
);
1625 if (year
> maxYear
) {
1626 errln(UnicodeString("Failed for ")+DATES
[i
]+" ms: year=" +
1627 year
+ ", maxYear=" + maxYear
);
1636 * This is a bug in the validation code of GregorianCalendar:: As reported,
1637 * the bug seems worse than it really is, due to a bug in the way the bug
1638 * report test was written. In reality the bug is restricted to the DAY_OF_YEAR
1639 * field. - liu 6/29/98
1641 void CalendarRegressionTest::test4147269()
1643 UErrorCode status
= U_ZERO_ERROR
;
1644 GregorianCalendar
*calendar
= new GregorianCalendar(status
);
1645 if(status
== U_USING_FALLBACK_WARNING
|| U_FAILURE(status
)) {
1646 dataerrln("Error creating calendar %s", u_errorName(status
));
1650 calendar
->setLenient(FALSE
);
1651 UDate date
= makeDate(1996, UCAL_JANUARY
, 3); // Arbitrary date
1652 for (int32_t field
= 0; field
< UCAL_FIELD_COUNT
; field
++) {
1653 calendar
->setTime(date
,status
);
1654 // Note: In the bug report, getActualMaximum() was called instead
1655 // of getMaximum() -- this was an error. The validation code doesn't
1656 // use getActualMaximum(), since that's too costly.
1657 int32_t max
= calendar
->getMaximum((UCalendarDateFields
)field
);
1658 int32_t value
= max
+1;
1659 calendar
->set((UCalendarDateFields
)field
, value
);
1661 calendar
->getTime(status
); // Force time computation
1662 // We expect an exception to be thrown. If we fall through
1663 // to the next line, then we have a bug.
1664 if(U_SUCCESS(status
))
1665 errln(UnicodeString("Test failed with field ") + FIELD_NAME
[field
] +
1666 ", date before: " + date
+
1667 ", date after: " + calendar
->getTime(status
) +
1668 ", value: " + value
+ " (max = " + max
+")");
1669 //} catch (IllegalArgumentException e) {}
1677 * Reported bug is that a GregorianCalendar with a cutover of Date(Long.MAX_VALUE)
1678 * doesn't behave as a pure Julian calendar.
1679 * CANNOT REPRODUCE THIS BUG
1682 CalendarRegressionTest::Test4149677()
1684 UErrorCode status
= U_ZERO_ERROR
;
1686 TimeZone
*zones
[] = {
1687 TimeZone::createTimeZone("GMT"),
1688 TimeZone::createTimeZone("PST"),
1689 TimeZone::createTimeZone("EAT")
1691 if(U_FAILURE(status
)) {
1692 errln("Couldn't create zones");
1694 // could leak memory
1697 for (int32_t i
=0; i
< 3; ++i
) {
1698 GregorianCalendar
*calendar
= new GregorianCalendar(zones
[i
], status
);
1699 if(U_FAILURE(status
)) {
1700 dataerrln("Couldnt' create calendar.: %s", u_errorName(status
));
1704 // Make sure extreme values don't wrap around
1705 calendar
->setTime(EARLIEST_SUPPORTED_MILLIS
, status
);
1706 if(U_FAILURE(status
))
1707 errln("setTime failed");
1708 if (calendar
->get(UCAL_ERA
, status
) != GregorianCalendar::BC
|| U_FAILURE(status
)) {
1709 errln("Fail: Date(EARLIEST_SUPPORTED_MILLIS) has an AD year");
1711 calendar
->setTime(LATEST_SUPPORTED_MILLIS
, status
);
1712 if(U_FAILURE(status
))
1713 errln("setTime failed");
1714 if (calendar
->get(UCAL_ERA
, status
) != GregorianCalendar::AD
|| U_FAILURE(status
)) {
1715 errln("Fail: Date(LATEST_SUPPORTED_MILLIS) has a BC year");
1718 calendar
->setGregorianChange(LATEST_SUPPORTED_MILLIS
, status
);
1719 if(U_FAILURE(status
))
1720 errln("setGregorianChange failed");
1721 // to obtain a pure Julian calendar
1723 UBool is100Leap
= calendar
->isLeapYear(100);
1726 errln("test failed with zone " + zones
[i
]->getID(temp
));
1727 errln(" cutover date is Date(Long.MAX_VALUE)");
1728 errln(UnicodeString(" isLeapYear(100) returns: ") + is100Leap
);
1733 // no need for cleanup- zones were adopted
1738 * Calendar and Date HOUR broken. If HOUR is out-of-range, Calendar
1739 * and Date classes will misbehave.
1742 CalendarRegressionTest::Test4162587()
1744 UErrorCode status
= U_ZERO_ERROR
;
1745 TimeZone
*savedef
= TimeZone::createDefault();
1746 TimeZone
*tz
= TimeZone::createTimeZone("PST");
1747 //TimeZone::adoptDefault(tz);
1748 TimeZone::setDefault(*tz
);
1750 GregorianCalendar
*cal
= new GregorianCalendar(tz
, status
);
1751 if(U_FAILURE(status
)) {
1752 dataerrln("Couldn't create calendar.: %s", u_errorName(status
));
1755 UDate d0
, dPlus
, dMinus
;
1757 for(int32_t i
=0; i
<5; ++i
) {
1758 if (i
>0) logln("---");
1761 cal
->set(1998, UCAL_APRIL
, 5, i
, 0);
1762 d0
= cal
->getTime(status
);
1763 if(U_FAILURE(status
))
1764 errln("Coudln't get time (1)");
1765 //String s0 = d.toString();
1766 logln(UnicodeString("0 ") + i
+ ": " + d0
/*s0*/);
1769 cal
->set(1998, UCAL_APRIL
, 4, i
+24, 0);
1770 dPlus
= cal
->getTime(status
);
1771 if(U_FAILURE(status
))
1772 errln("Coudln't get time (2)");
1773 //String sPlus = d.toString();
1774 logln(UnicodeString("+ ") + i
+ ": " + dPlus
/*sPlus*/);
1777 cal
->set(1998, UCAL_APRIL
, 6, i
-24, 0);
1778 dMinus
= cal
->getTime(status
);
1779 if(U_FAILURE(status
))
1780 errln("Coudln't get time (3)");
1781 //String sMinus = d.toString();
1782 logln(UnicodeString("- ") + i
+ ": " + dMinus
/*sMinus*/);
1784 if (d0
!= dPlus
|| d0
!= dMinus
) {
1785 errln("Fail: All three lines must match");
1788 TimeZone::setDefault(*savedef
);
1796 * Adding 12 months behaves differently from adding 1 year
1799 CalendarRegressionTest::Test4165343()
1801 UErrorCode status
= U_ZERO_ERROR
;
1802 GregorianCalendar
*calendar
= new GregorianCalendar(1996, UCAL_FEBRUARY
, 29, status
);
1803 if(U_FAILURE(status
)) {
1804 dataerrln("Couldn't create calendar.: %s", u_errorName(status
));
1807 UDate start
= calendar
->getTime(status
);
1808 if(U_FAILURE(status
))
1809 errln("Couldn't getTime (1)");
1810 logln(UnicodeString("init date: ") + start
);
1811 calendar
->add(UCAL_MONTH
, 12, status
);
1812 if(U_FAILURE(status
))
1813 errln("Couldn't add(MONTH, 12)");
1814 UDate date1
= calendar
->getTime(status
);
1815 if(U_FAILURE(status
))
1816 errln("Couldn't getTime (2)");
1817 logln(UnicodeString("after adding 12 months: ") + date1
);
1818 calendar
->setTime(start
, status
);
1819 if(U_FAILURE(status
))
1820 errln("Couldn't setTime");
1821 calendar
->add(UCAL_YEAR
, 1, status
);
1822 if(U_FAILURE(status
))
1823 errln("Couldn't add(YEAR, 1)");
1824 UDate date2
= calendar
->getTime(status
);
1825 if(U_FAILURE(status
))
1826 errln("Couldn't getTime (3)");
1827 logln(UnicodeString("after adding one year : ") + date2
);
1828 if (date1
== date2
) {
1829 logln("Test passed");
1831 errln("Test failed");
1838 * GregorianCalendar.getActualMaximum() does not account for first day of week.
1841 CalendarRegressionTest::Test4166109()
1846 * Su Mo Tu We Th Fr Sa
1848 * 8 9 10 11 12 13 14
1849 * 15 16 17 18 19 20 21
1850 * 22 23 24 25 26 27 28
1853 UBool passed
= TRUE
;
1854 UErrorCode status
= U_ZERO_ERROR
;
1855 UCalendarDateFields field
= UCAL_WEEK_OF_MONTH
;
1857 GregorianCalendar
*calendar
= new GregorianCalendar(Locale::getUS(), status
);
1858 if(U_FAILURE(status
)) {
1859 dataerrln("Couldn't create calendar.: %s", u_errorName(status
));
1862 calendar
->set(1998, UCAL_MARCH
, 1);
1863 calendar
->setMinimalDaysInFirstWeek(1);
1864 logln(UnicodeString("Date: ") + calendar
->getTime(status
)); // 888817448000
1866 int32_t firstInMonth
= calendar
->get(UCAL_DATE
, status
);
1867 if(U_FAILURE(status
))
1868 errln("get(D_O_M) failed");
1870 for(int32_t firstInWeek
= UCAL_SUNDAY
; firstInWeek
<= UCAL_SATURDAY
; firstInWeek
++) {
1871 calendar
->setFirstDayOfWeek((UCalendarDaysOfWeek
)firstInWeek
);
1872 int32_t returned
= calendar
->getActualMaximum(field
, status
);
1873 int32_t expected
= (31 + ((firstInMonth
- firstInWeek
+ 7)% 7) + 6) / 7;
1875 logln(UnicodeString("First day of week = ") + firstInWeek
+
1876 " getActualMaximum(WEEK_OF_MONTH, status) = " + returned
+
1877 " expected = " + expected
+
1878 ((returned
== expected
) ? " ok" : " FAIL"));
1880 if (returned
!= expected
) {
1885 errln("Test failed");
1893 * Calendar.getActualMaximum(YEAR) works wrong.
1896 CalendarRegressionTest::Test4167060()
1898 UErrorCode status
= U_ZERO_ERROR
;
1899 UCalendarDateFields field
= UCAL_YEAR
;
1900 DateFormat
*format
= new SimpleDateFormat(UnicodeString("EEE MMM dd HH:mm:ss zzz yyyy G"),
1901 Locale::getUS(), status
);
1902 if(U_FAILURE(status
)) {
1903 dataerrln("Couldn't create SimpleDateFormat - %s", u_errorName(status
));
1907 GregorianCalendar
*calendars
[] = {
1908 new GregorianCalendar(100, UCAL_NOVEMBER
, 1, status
),
1909 new GregorianCalendar(-99 /*100BC*/, UCAL_JANUARY
, 1, status
),
1910 new GregorianCalendar(1996, UCAL_FEBRUARY
, 29, status
),
1912 if(U_FAILURE(status
)) {
1913 errln("Couldn't create GregorianCalendars");
1918 UnicodeString id
[] = { "Hybrid", "Gregorian", "Julian" };
1920 for (int32_t k
=0; k
<3; ++k
) {
1921 logln("--- " + id
[k
] + " ---");
1923 for (int32_t j
=0; j
< 3; ++j
) {
1924 GregorianCalendar
*calendar
= calendars
[j
];
1926 calendar
->setGregorianChange(EARLIEST_SUPPORTED_MILLIS
, status
);
1929 calendar
->setGregorianChange(LATEST_SUPPORTED_MILLIS
, status
);
1932 if(U_FAILURE(status
))
1933 errln("setGregorianChange() failed");
1934 format
->adoptCalendar((Calendar
*)calendar
->clone());
1936 UDate dateBefore
= calendar
->getTime(status
);
1937 if(U_FAILURE(status
))
1938 errln("getTime() failed");
1940 int32_t maxYear
= calendar
->getActualMaximum(field
, status
);
1942 logln(UnicodeString("maxYear: ") + maxYear
+ " for " + format
->format(calendar
->getTime(status
), temp
));
1944 logln("date before: " + format
->format(dateBefore
, temp
));
1946 int32_t years
[] = {2000, maxYear
-1, maxYear
, maxYear
+1};
1948 for (int32_t i
= 0; i
< 4; i
++) {
1949 UBool valid
= years
[i
] <= maxYear
;
1950 calendar
->set(field
, years
[i
]);
1951 UDate dateAfter
= calendar
->getTime(status
);
1952 if(U_FAILURE(status
))
1953 errln("getTime() failed");
1954 int32_t newYear
= calendar
->get(field
, status
);
1955 if(U_FAILURE(status
))
1956 errln(UnicodeString("get(") + (int32_t)field
+ ") failed");
1957 calendar
->setTime(dateBefore
, status
); // restore calendar for next use
1958 if(U_FAILURE(status
))
1959 errln("setTime() failed");
1962 logln(UnicodeString(" Year ") + years
[i
] + (valid
? " ok " : " bad") +
1963 " => " + format
->format(dateAfter
, temp
));
1964 if (valid
&& newYear
!= years
[i
]) {
1965 errln(UnicodeString(" FAIL: ") + newYear
+ " should be valid; date, month and time shouldn't change");
1967 // {sfb} this next line is a hack, but it should work since if a
1968 // double has an exponent, adding 1 should not yield the same double
1969 else if (!valid
&& /*newYear == years[i]*/ dateAfter
+ 1.0 == dateAfter
) {
1970 errln(UnicodeString(" FAIL: ") + newYear
+ " should be invalid");
1977 delete calendars
[0];
1978 delete calendars
[1];
1979 delete calendars
[2];
1983 * Week of year is wrong at the start and end of the year.
1985 void CalendarRegressionTest::Test4197699() {
1986 UErrorCode status
= U_ZERO_ERROR
;
1987 GregorianCalendar
cal(status
);
1988 cal
.setFirstDayOfWeek(UCAL_MONDAY
);
1989 cal
.setMinimalDaysInFirstWeek(4);
1990 SimpleDateFormat
fmt("E dd MMM yyyy 'DOY='D 'WOY='w",
1991 Locale::getUS(), status
);
1992 fmt
.setCalendar(cal
);
1993 if (U_FAILURE(status
)) {
1994 dataerrln("Couldn't initialize test - %s", u_errorName(status
));
1999 2000, UCAL_JANUARY
, 1, 52,
2000 2001, UCAL_DECEMBER
, 31, 1,
2002 int32_t DATA_length
= UPRV_LENGTHOF(DATA
);
2005 DateFormat
& dfmt
= *(DateFormat
*)&fmt
;
2006 for (int32_t i
=0; i
<DATA_length
; ) {
2008 cal
.set(DATA
[i
], DATA
[i
+1], DATA
[i
+2]);
2010 int32_t expWOY
= DATA
[i
++];
2011 int32_t actWOY
= cal
.get(UCAL_WEEK_OF_YEAR
, status
);
2012 if (expWOY
== actWOY
) {
2013 logln(UnicodeString("Ok: ") + dfmt
.format(cal
.getTime(status
), str
.remove()));
2015 errln(UnicodeString("FAIL: ") + dfmt
.format(cal
.getTime(status
), str
.remove())
2016 + ", expected WOY=" + expWOY
);
2017 cal
.add(UCAL_DATE
, -8, status
);
2018 for (int j
=0; j
<14; ++j
) {
2019 cal
.add(UCAL_DATE
, 1, status
);
2020 logln(dfmt
.format(cal
.getTime(status
), str
.remove()));
2023 if (U_FAILURE(status
)) {
2024 errln("FAIL: Unexpected error from Calendar");
2030 enum Action
{ ADD
=1, ROLL
=2 };
2031 enum Sign
{ PLUS
=1, MINUS
=2 };
2033 #define ONE_HOUR (60*60*1000)
2034 #define ONE_DAY (24*ONE_HOUR)
2037 UCalendarDateFields field
;
2038 int8_t actionMask
; // ADD or ROLL or both
2039 int8_t signMask
; // PLUS or MINUS or both
2041 int32_t before
; // ms before cutover
2042 int32_t after
; // ms after cutover
2046 * Rolling and adding across the Gregorian cutover should work as expected.
2049 void CalendarRegressionTest::TestJ81() {
2050 UErrorCode status
= U_ZERO_ERROR
;
2051 UnicodeString temp
, temp2
, temp3
;
2053 GregorianCalendar
cal(TimeZone::createTimeZone("GMT"), Locale::getUS(), status
);
2054 SimpleDateFormat
fmt("HH:mm 'w'w 'd'D E d MMM yyyy", Locale::getUS(), status
);
2055 if (U_FAILURE(status
)) {
2056 dataerrln("Error: Cannot create calendar or format - %s", u_errorName(status
));
2059 fmt
.setCalendar(cal
);
2060 // Get the Gregorian cutover
2061 UDate cutover
= cal
.getGregorianChange();
2062 UDate days
= ONE_DAY
;
2063 days
= cutover
/days
;
2064 logln(UnicodeString("Cutover: {") +
2065 fmt
.format(cutover
, temp
) + "}(epoch days-" + (int)days
+ ", jd" + (2440588 + days
) +")");
2067 // Check woy and doy handling. Reference data:
2068 /* w40 d274 Mon 1 Oct 1582
2069 w40 d275 Tue 2 Oct 1582
2070 w40 d276 Wed 3 Oct 1582
2071 w40 d277 Thu 4 Oct 1582
2072 w40 d278 Fri 15 Oct 1582
2073 w40 d279 Sat 16 Oct 1582
2074 w41 d280 Sun 17 Oct 1582
2075 w41 d281 Mon 18 Oct 1582
2076 w41 d282 Tue 19 Oct 1582
2077 w41 d283 Wed 20 Oct 1582
2078 w41 d284 Thu 21 Oct 1582
2079 w41 d285 Fri 22 Oct 1582
2080 w41 d286 Sat 23 Oct 1582
2081 w42 d287 Sun 24 Oct 1582
2082 w42 d288 Mon 25 Oct 1582
2083 w42 d289 Tue 26 Oct 1582
2084 w42 d290 Wed 27 Oct 1582
2085 w42 d291 Thu 28 Oct 1582
2086 w42 d292 Fri 29 Oct 1582
2087 w42 d293 Sat 30 Oct 1582
2088 w43 d294 Sun 31 Oct 1582
2089 w43 d295 Mon 1 Nov 1582 */
2090 int32_t DOY_DATA
[] = {
2092 1, 40, 274, UCAL_MONDAY
,
2093 4, 40, 277, UCAL_THURSDAY
,
2094 15, 40, 278, UCAL_FRIDAY
,
2095 17, 41, 280, UCAL_SUNDAY
,
2096 24, 42, 287, UCAL_SUNDAY
,
2097 25, 42, 288, UCAL_MONDAY
,
2098 26, 42, 289, UCAL_TUESDAY
,
2099 27, 42, 290, UCAL_WEDNESDAY
,
2100 28, 42, 291, UCAL_THURSDAY
,
2101 29, 42, 292, UCAL_FRIDAY
,
2102 30, 42, 293, UCAL_SATURDAY
,
2103 31, 43, 294, UCAL_SUNDAY
2105 int32_t DOY_DATA_length
= UPRV_LENGTHOF(DOY_DATA
);
2107 for (i
=0; i
<DOY_DATA_length
; i
+=4) {
2108 // Test time->fields
2109 cal
.set(1582, UCAL_OCTOBER
, DOY_DATA
[i
]);
2110 int32_t woy
= cal
.get(UCAL_WEEK_OF_YEAR
, status
);
2111 int32_t doy
= cal
.get(UCAL_DAY_OF_YEAR
, status
);
2112 int32_t dow
= cal
.get(UCAL_DAY_OF_WEEK
, status
);
2113 if (U_FAILURE(status
)) {
2114 errln("Error: get() failed");
2117 if (woy
!= DOY_DATA
[i
+1] || doy
!= DOY_DATA
[i
+2] || dow
!= DOY_DATA
[i
+3]) {
2118 errln((UnicodeString
)"Fail: expect woy=" + DOY_DATA
[i
+1] +
2119 ", doy=" + DOY_DATA
[i
+2] + ", dow=" + DOY_DATA
[i
+3] + " on " +
2120 fmt
.format(cal
.getTime(status
), temp
.remove()) +
2121 " set(1582,OCTOBER, " + DOY_DATA
[i
] + ")");
2122 logln(CalendarTest::calToStr(cal
));
2123 status
= U_ZERO_ERROR
;
2125 logln((UnicodeString
)"PASS: expect woy=" + DOY_DATA
[i
+1] +
2126 ", doy=" + DOY_DATA
[i
+2] + ", dow=" + DOY_DATA
[i
+3] + " on " +
2127 fmt
.format(cal
.getTime(status
), temp
.remove()));
2128 logln(CalendarTest::calToStr(cal
));
2129 status
= U_ZERO_ERROR
;
2131 // Test fields->time for WOY
2133 cal
.set(UCAL_YEAR
, 1582);
2134 cal
.set(UCAL_WEEK_OF_YEAR
, DOY_DATA
[i
+1]);
2135 cal
.set(UCAL_DAY_OF_WEEK
, DOY_DATA
[i
+3]);
2136 int32_t dom
= cal
.get(UCAL_DATE
, status
);
2137 if (U_FAILURE(status
)) {
2138 errln("Error: get() failed");
2141 if (dom
!= DOY_DATA
[i
]) {
2142 errln((UnicodeString
)"Fail: set woy=" + DOY_DATA
[i
+1] +
2143 " dow=" + DOY_DATA
[i
+3] + " => " +
2144 fmt
.format(cal
.getTime(status
), temp
.remove()) +
2145 ", expected 1582 Oct " + DOY_DATA
[i
]);
2146 logln(CalendarTest::calToStr(cal
));
2147 status
= U_ZERO_ERROR
;
2150 // Test fields->time for DOY
2152 cal
.set(UCAL_YEAR
, 1582);
2153 cal
.set(UCAL_DAY_OF_YEAR
, DOY_DATA
[i
+2]);
2154 dom
= cal
.get(UCAL_DATE
, status
);
2155 if (U_FAILURE(status
)) {
2156 errln("Error: get() failed");
2159 if (dom
!= DOY_DATA
[i
]) {
2160 errln((UnicodeString
)"Fail: set doy=" + DOY_DATA
[i
+2] +
2162 fmt
.format(cal
.getTime(status
), temp
.remove()) +
2163 ", expected 1582 Oct " + DOY_DATA
[i
]);
2164 status
= U_ZERO_ERROR
;
2167 status
= U_ZERO_ERROR
;
2169 #define ADD_ROLL ADD|ROLL
2170 #define PLUS_MINUS PLUS|MINUS
2173 { UCAL_WEEK_OF_YEAR
, ADD_ROLL
, PLUS_MINUS
, 1, -ONE_DAY
, +6*ONE_DAY
},
2174 { UCAL_WEEK_OF_YEAR
, ADD_ROLL
, PLUS_MINUS
, 1, -ONE_DAY
, +6*ONE_DAY
},
2175 { UCAL_WEEK_OF_MONTH
, ADD
|ROLL
, PLUS
|MINUS
, 1, -ONE_DAY
, +6*ONE_DAY
},
2176 { UCAL_DATE
, ADD
|ROLL
, PLUS
|MINUS
, 2, -ONE_DAY
, +1*ONE_DAY
},
2177 { UCAL_DATE
, ROLL
, PLUS
, -6, -ONE_DAY
, +14*ONE_DAY
},
2178 { UCAL_DATE
, ROLL
, PLUS
, -7, 0, +14*ONE_DAY
},
2179 { UCAL_DATE
, ROLL
, PLUS
, -7, +ONE_DAY
, +15*ONE_DAY
},
2180 { UCAL_DATE
, ROLL
, PLUS
, +18, -ONE_DAY
, -4*ONE_DAY
},
2181 { UCAL_DAY_OF_YEAR
, ADD
|ROLL
, PLUS
|MINUS
, 2, -ONE_DAY
, +1*ONE_DAY
},
2182 { UCAL_DAY_OF_WEEK
, ADD
|ROLL
, PLUS
|MINUS
, 2, -ONE_DAY
, +1*ONE_DAY
},
2183 { UCAL_DAY_OF_WEEK_IN_MONTH
, ADD
|ROLL
, PLUS
|MINUS
, 1, -ONE_DAY
, +6*ONE_DAY
},
2184 { UCAL_AM_PM
, ADD
, PLUS
|MINUS
, 4, -12*ONE_HOUR
, +36*ONE_HOUR
},
2185 { UCAL_HOUR
, ADD
, PLUS
|MINUS
, 48, -12*ONE_HOUR
, +36*ONE_HOUR
},
2186 { UCAL_HOUR_OF_DAY
, ADD
, PLUS
|MINUS
, 48, -12*ONE_HOUR
, +36*ONE_HOUR
},
2187 { UCAL_MINUTE
, ADD
, PLUS
|MINUS
, 48*60, -12*ONE_HOUR
, +36*ONE_HOUR
},
2188 { UCAL_SECOND
, ADD
, PLUS
|MINUS
, 48*60*60, -12*ONE_HOUR
, +36*ONE_HOUR
},
2189 { UCAL_MILLISECOND
, ADD
, PLUS
|MINUS
, 48*ONE_HOUR
, -12*ONE_HOUR
, +36*ONE_HOUR
},
2190 // NOTE: These are not supported yet. See jitterbug 180.
2191 // Uncomment these lines when add/roll supported on these fields.
2192 // { Calendar::YEAR_WOY, ADD|ROLL, 1, -ONE_DAY, +6*ONE_DAY },
2193 // { Calendar::DOW_LOCAL, ADD|ROLL, 2, -ONE_DAY, +1*ONE_DAY }
2195 int32_t DATA_length
= UPRV_LENGTHOF(DATA
);
2197 // Now run the tests
2198 for (i
=0; i
<DATA_length
; ++i
) {
2199 for (Action action
=ADD
; action
<=ROLL
; action
=(Action
)(action
+1)) {
2200 if (!(DATA
[i
].actionMask
& action
)) {
2203 for (Sign sign
=PLUS
; sign
<=MINUS
; sign
=(Sign
)(sign
+1)) {
2204 if (!(DATA
[i
].signMask
& sign
)) {
2207 status
= U_ZERO_ERROR
;
2208 int32_t amount
= DATA
[i
].amount
* (sign
==MINUS
?-1:1);
2209 UDate date
= cutover
+
2210 (sign
==PLUS
? DATA
[i
].before
: DATA
[i
].after
);
2211 UDate expected
= cutover
+
2212 (sign
==PLUS
? DATA
[i
].after
: DATA
[i
].before
);
2213 cal
.setTime(date
, status
);
2214 if (U_FAILURE(status
)) {
2215 errln((UnicodeString
)"FAIL: setTime returned error code " + u_errorName(status
));
2218 if (action
== ADD
) {
2219 cal
.add(DATA
[i
].field
, amount
, status
);
2221 cal
.roll(DATA
[i
].field
, amount
, status
);
2223 if (U_FAILURE(status
)) {
2224 errln((UnicodeString
)"FAIL: " +
2225 (action
==ADD
?"add ":"roll ") + FIELD_NAME
[DATA
[i
].field
] +
2226 " returned error code " + u_errorName(status
));
2229 UDate result
= cal
.getTime(status
);
2230 if (U_FAILURE(status
)) {
2231 errln((UnicodeString
)"FAIL: getTime returned error code " + u_errorName(status
));
2234 if (result
== expected
) {
2235 logln((UnicodeString
)"Ok: {" +
2236 fmt
.format(date
, temp
.remove()) +
2237 "}(" + date
/ONE_DAY
+
2238 (action
==ADD
?") add ":") roll ") +
2239 amount
+ " " + FIELD_NAME
[DATA
[i
].field
] + " -> {" +
2240 fmt
.format(result
, temp2
.remove()) +
2241 "}(" + result
/ONE_DAY
+ ")");
2243 errln((UnicodeString
)"FAIL: {" +
2244 fmt
.format(date
, temp
.remove()) +
2245 "}(" + date
/ONE_DAY
+
2246 (action
==ADD
?") add ":") roll ") +
2247 amount
+ " " + FIELD_NAME
[DATA
[i
].field
] + " -> {" +
2248 fmt
.format(result
, temp2
.remove()) +
2249 "}(" + result
/ONE_DAY
+ "), expect {" +
2250 fmt
.format(expected
, temp3
.remove()) +
2251 "}(" + expected
/ONE_DAY
+ ")");
2259 * Test fieldDifference().
2261 void CalendarRegressionTest::TestJ438(void) {
2262 UErrorCode ec
= U_ZERO_ERROR
;
2264 2000, UCAL_JANUARY
, 20, 2010, UCAL_JUNE
, 15,
2265 2010, UCAL_JUNE
, 15, 2000, UCAL_JANUARY
, 20,
2266 1964, UCAL_SEPTEMBER
, 7, 1999, UCAL_JUNE
, 4,
2267 1999, UCAL_JUNE
, 4, 1964, UCAL_SEPTEMBER
, 7,
2269 int32_t DATA_length
= UPRV_LENGTHOF(DATA
);
2270 Calendar
* pcal
= Calendar::createInstance(Locale::getUS(), ec
);
2272 dataerrln("Error creating calendar %s", u_errorName(ec
));
2276 Calendar
& cal
= *pcal
;
2278 SimpleDateFormat
fmt(UnicodeString("MMM dd yyyy",""), ec
);
2279 fmt
.setCalendar(cal
);
2280 UnicodeString s
, t
, u
;
2281 if (U_SUCCESS(ec
)) {
2282 for (i
=0; i
<DATA_length
; i
+=6) {
2283 int32_t y1
= DATA
[i
];
2284 int32_t m1
= DATA
[i
+1];
2285 int32_t d1
= DATA
[i
+2];
2286 int32_t y2
= DATA
[i
+3];
2287 int32_t m2
= DATA
[i
+4];
2288 int32_t d2
= DATA
[i
+5];
2291 cal
.set(y1
, m1
, d1
);
2292 UDate date1
= cal
.getTime(ec
);
2293 if (failure(ec
, "getTime"))
2295 cal
.set(y2
, m2
, d2
);
2296 UDate date2
= cal
.getTime(ec
);
2297 if (failure(ec
, "getTime"))
2300 cal
.setTime(date1
, ec
);
2301 if (failure(ec
, "setTime"))
2303 int32_t dy
= cal
.fieldDifference(date2
, UCAL_YEAR
, ec
);
2304 int32_t dm
= cal
.fieldDifference(date2
, UCAL_MONTH
, ec
);
2305 int32_t dd
= cal
.fieldDifference(date2
, UCAL_DATE
, ec
);
2306 if (failure(ec
, "fieldDifference"))
2310 Calendar
*cal2
= cal
.clone();
2311 UErrorCode ec2
= U_ZERO_ERROR
;
2313 cal2
->setTime(date1
, ec2
);
2315 int32_t dy2
= cal2
->fieldDifference(date2
, Calendar::YEAR
, ec2
);
2316 int32_t dm2
= cal2
->fieldDifference(date2
, Calendar::MONTH
, ec2
);
2317 int32_t dd2
= cal2
->fieldDifference(date2
, Calendar::DATE
, ec2
);
2318 if (failure(ec2
, "fieldDifference(date, Calendar::DATE, ec)"))
2323 errln("fieldDifference(UCAL_...) and fieldDifference(Calendar::...) give different results!\n");
2329 logln(UnicodeString("") +
2330 fmt
.format(date2
, s
.remove()) + " - " +
2331 fmt
.format(date1
, t
.remove()) + " = " +
2332 dy
+ "y " + dm
+ "m " + dd
+ "d");
2334 cal
.setTime(date1
, ec
);
2335 if (failure(ec
, "setTime"))
2337 cal
.add(UCAL_YEAR
, dy
, ec
);
2338 cal
.add(UCAL_MONTH
, dm
, ec
);
2339 cal
.add(UCAL_DATE
, dd
, ec
);
2340 if (failure(ec
, "add"))
2342 UDate date22
= cal
.getTime(ec
);
2343 if (failure(ec
, "getTime"))
2345 if (date2
!= date22
) {
2346 errln(UnicodeString("FAIL: ") +
2347 fmt
.format(date1
, s
.remove()) + " + " +
2348 dy
+ "y " + dm
+ "m " + dd
+ "d = " +
2349 fmt
.format(date22
, t
.remove()) + ", exp " +
2350 fmt
.format(date2
, u
.remove()));
2352 logln(UnicodeString("Ok: ") +
2353 fmt
.format(date1
, s
.remove()) + " + " +
2354 dy
+ "y " + dm
+ "m " + dd
+ "d = " +
2355 fmt
.format(date22
, t
.remove()));
2359 dataerrln("Error creating SimpleDateFormat - %s", u_errorName(ec
));
2364 void CalendarRegressionTest::TestT5555()
2366 UErrorCode ec
= U_ZERO_ERROR
;
2367 Calendar
*cal
= Calendar::createInstance(ec
);
2369 if (cal
== NULL
|| U_FAILURE(ec
)) {
2370 dataerrln("FAIL: Calendar::createInstance(): %s", u_errorName(ec
));
2375 // Set to Wednesday, February 21, 2007
2376 cal
->set(2007, UCAL_FEBRUARY
, 21);
2378 // Advance three years
2379 cal
->add(UCAL_MONTH
, 36, ec
);
2381 // Set to last Wednesday of the month
2382 cal
->set(UCAL_DAY_OF_WEEK_IN_MONTH
, -1);
2386 int32_t yy
, mm
, dd
, ee
;
2388 yy
= cal
->get(UCAL_YEAR
, ec
);
2389 mm
= cal
->get(UCAL_MONTH
, ec
);
2390 dd
= cal
->get(UCAL_DATE
, ec
);
2391 ee
= cal
->get(UCAL_DAY_OF_WEEK
, ec
);
2393 // Should be set to Wednesday, February 24, 2010
2394 if (U_FAILURE(ec
) || yy
!= 2010 || mm
!= UCAL_FEBRUARY
|| dd
!= 24 || ee
!= UCAL_WEDNESDAY
) {
2395 errln("FAIL: got date %4d/%02d/%02d, expected 210/02/24: ", yy
, mm
+ 1, dd
);
2402 int32_t startMonth
; // 0-based
2403 int32_t startDay
; // 1-based
2404 UCalendarDateFields fieldToChange
;
2407 int32_t endMonth
; // 0-based
2408 int32_t endDay
; // 1-based
2409 } CoptEthCalTestItem
;
2411 // year 1724 in coptic calendar =
2412 // year 2000 in ethiopic calendar (276 more than coptic) =
2413 // year 7500 in ethiopic-amete-alem calendar (5776 more than coptic)
2414 // (2007-2008 in gregorian calendar depending on month)
2415 static const CoptEthCalTestItem coptEthCalTestItems
[] = {
2416 { 1724, 12, 1, UCAL_MONTH
, +1, 1725, 0, 1 },
2417 { 1724, 12, 1, UCAL_MONTH
, +9, 1725, 8, 1 },
2418 { 1723, 12, 2, UCAL_MONTH
, +1, 1724, 0, 2 }, // 1723 is a leap year
2419 { 1723, 12, 2, UCAL_MONTH
, +9, 1724, 8, 2 },
2420 { 1725, 0, 1, UCAL_MONTH
, -1, 1724, 12, 1 },
2421 { 1725, 0, 1, UCAL_MONTH
, -6, 1724, 7, 1 },
2422 { 1724, 12, 1, UCAL_DATE
, +8, 1725, 0, 4 },
2423 { 1723, 12, 1, UCAL_DATE
, +8, 1724, 0, 3 }, // 1723 is a leap year
2424 { 1724, 0, 1, UCAL_DATE
, -1, 1723, 12, 6 }, // 1723 is a leap year
2425 { 0, 0, 0, (UCalendarDateFields
)0, 0, 0, 0, 0 } // terminator
2429 const char * locale
;
2433 static const CoptEthCalLocale copEthCalLocales
[] = {
2434 { "en@calendar=coptic", 0 },
2435 { "en@calendar=ethiopic", 276 },
2436 { NULL
, 0 } // terminator
2439 void CalendarRegressionTest::TestT6745()
2441 const CoptEthCalLocale
* testLocalePtr
;
2442 for ( testLocalePtr
= copEthCalLocales
; testLocalePtr
->locale
!= NULL
; ++testLocalePtr
) {
2443 UErrorCode status
= U_ZERO_ERROR
;
2444 Calendar
*cal
= Calendar::createInstance(Locale(testLocalePtr
->locale
), status
);
2445 if ( U_FAILURE(status
) ) {
2446 dataerrln((UnicodeString
)"FAIL: Calendar::createInstance, locale " + testLocalePtr
->locale
+ ", status " + u_errorName(status
));
2449 const CoptEthCalTestItem
* testItemPtr
;
2450 for (testItemPtr
= coptEthCalTestItems
; testItemPtr
->fieldDelta
!= 0; ++testItemPtr
) {
2451 status
= U_ZERO_ERROR
;
2452 cal
->set( testItemPtr
->startYear
+ testLocalePtr
->yearOffset
, testItemPtr
->startMonth
, testItemPtr
->startDay
, 9, 0 );
2453 cal
->add( testItemPtr
->fieldToChange
, testItemPtr
->fieldDelta
, status
);
2454 if ( U_FAILURE(status
) ) {
2455 errln((UnicodeString
)"FAIL: Calendar::add, locale " + testLocalePtr
->locale
+ ", field/delta " +
2456 testItemPtr
->fieldToChange
+ "/" + testItemPtr
->fieldDelta
+ ", status " + u_errorName(status
));
2459 int32_t endYear
= testItemPtr
->endYear
+ testLocalePtr
->yearOffset
;
2460 int32_t year
= cal
->get(UCAL_YEAR
, status
);
2461 int32_t month
= cal
->get(UCAL_MONTH
, status
);
2462 int32_t day
= cal
->get(UCAL_DATE
, status
);
2463 if ( U_FAILURE(status
) || year
!= endYear
|| month
!= testItemPtr
->endMonth
|| day
!= testItemPtr
->endDay
) {
2464 errln((UnicodeString
)"ERROR: Calendar::add, locale " + testLocalePtr
->locale
+ ", field/delta " +
2465 testItemPtr
->fieldToChange
+ "/" + testItemPtr
->fieldDelta
+ ", status " + u_errorName(status
) +
2466 ", expected " + endYear
+ "/" + testItemPtr
->endMonth
+ "/" + testItemPtr
->endDay
+
2467 ", got " + year
+ "/" + month
+ "/" + day
);
2475 * Test behavior of fieldDifference around leap years. Also test a large
2476 * field difference to check binary search.
2478 void CalendarRegressionTest::TestLeapFieldDifference() {
2479 UErrorCode ec
= U_ZERO_ERROR
;
2480 Calendar
* cal
= Calendar::createInstance(ec
);
2481 if (cal
== NULL
|| U_FAILURE(ec
)) {
2482 dataerrln("FAIL: Calendar::createInstance(): %s", u_errorName(ec
));
2486 cal
->set(2004, UCAL_FEBRUARY
, 29);
2487 UDate date2004
= cal
->getTime(ec
);
2488 cal
->set(2000, UCAL_FEBRUARY
, 29);
2489 UDate date2000
= cal
->getTime(ec
);
2490 if (U_FAILURE(ec
)) {
2491 errln("FAIL: getTime()");
2495 int32_t y
= cal
->fieldDifference(date2004
, UCAL_YEAR
, ec
);
2496 int32_t d
= cal
->fieldDifference(date2004
, UCAL_DAY_OF_YEAR
, ec
);
2497 if (U_FAILURE(ec
)) {
2498 errln("FAIL: fieldDifference()");
2503 logln((UnicodeString
)"Ok: 2004/Feb/29 - 2000/Feb/29 = " + y
+ " years, " + d
+ " days");
2505 errln((UnicodeString
)"FAIL: 2004/Feb/29 - 2000/Feb/29 = " + y
+ " years, " + d
+ " days");
2507 cal
->setTime(date2004
, ec
);
2508 y
= cal
->fieldDifference(date2000
, UCAL_YEAR
, ec
);
2509 d
= cal
->fieldDifference(date2000
, UCAL_DAY_OF_YEAR
, ec
);
2510 if (U_FAILURE(ec
)) {
2511 errln("FAIL: setTime() / fieldDifference()");
2516 logln((UnicodeString
)"Ok: 2000/Feb/29 - 2004/Feb/29 = " + y
+ " years, " + d
+ " days");
2518 errln((UnicodeString
)"FAIL: 2000/Feb/29 - 2004/Feb/29 = " + y
+ " years, " + d
+ " days");
2520 // Test large difference
2521 cal
->set(2001, UCAL_APRIL
, 5); // 2452005
2522 UDate ayl
= cal
->getTime(ec
);
2523 cal
->set(1964, UCAL_SEPTEMBER
, 7); // 2438646
2524 UDate asl
= cal
->getTime(ec
);
2525 if (U_FAILURE(ec
)) {
2526 errln("FAIL: getTime()");
2530 d
= cal
->fieldDifference(ayl
, UCAL_DATE
, ec
);
2531 cal
->setTime(ayl
, ec
);
2532 int32_t d2
= cal
->fieldDifference(asl
, UCAL_DATE
, ec
);
2533 if (U_FAILURE(ec
)) {
2534 errln("FAIL: setTime() / fieldDifference()");
2538 if (d
== -d2
&& d
== 13359) {
2539 logln((UnicodeString
)"Ok: large field difference symmetrical " + d
);
2541 logln((UnicodeString
)"FAIL: large field difference incorrect " + d
+ ", " + d2
+
2542 ", expect +/- 13359");
2548 * Test ms_MY "Malay (Malaysia)" locale. Bug 1543.
2550 void CalendarRegressionTest::TestMalaysianInstance() {
2551 Locale
loc("ms", "MY"); // Malay (Malaysia)
2552 UErrorCode ec
= U_ZERO_ERROR
;
2553 Calendar
* cal
= Calendar::createInstance(loc
, ec
);
2554 if (U_FAILURE(ec
)) {
2555 dataerrln("FAIL: Can't construct calendar for ms_MY: %s", u_errorName(ec
));
2561 * setFirstDayOfWeek and setMinimalDaysInFirstWeek may change the
2562 * field <=> time mapping, since they affect the interpretation of
2563 * the WEEK_OF_MONTH or WEEK_OF_YEAR fields.
2565 void CalendarRegressionTest::TestWeekShift() {
2566 UErrorCode ec
= U_ZERO_ERROR
;
2567 GregorianCalendar
cal(TimeZone::createTimeZone("America/Los_Angeles"),
2568 Locale("en", "US"), ec
);
2569 if (U_FAILURE(ec
)) {
2570 dataerrln("Fail GregorianCalendar: %s", u_errorName(ec
));
2573 cal
.setTime(UDate(997257600000.0), ec
); // Wed Aug 08 01:00:00 PDT 2001
2574 // In pass one, change the first day of week so that the weeks
2575 // shift in August 2001. In pass two, change the minimal days
2576 // in the first week so that the weeks shift in August 2001.
2578 // Su Mo Tu We Th Fr Sa
2581 // 12 13 14 15 16 17 18
2582 // 19 20 21 22 23 24 25
2583 // 26 27 28 29 30 31
2584 for (int32_t pass
=0; pass
<2; ++pass
) {
2586 cal
.setFirstDayOfWeek(UCAL_WEDNESDAY
);
2587 cal
.setMinimalDaysInFirstWeek(4);
2589 cal
.setFirstDayOfWeek(UCAL_SUNDAY
);
2590 cal
.setMinimalDaysInFirstWeek(4);
2592 cal
.add(UCAL_DATE
, 1, ec
); // Force recalc
2593 cal
.add(UCAL_DATE
, -1, ec
);
2595 UDate time1
= cal
.getTime(ec
); // Get time -- should not change
2597 // Now change a week parameter and then force a recalc.
2598 // The bug is that the recalc should not be necessary --
2599 // calendar should do so automatically.
2601 cal
.setFirstDayOfWeek(UCAL_THURSDAY
);
2603 cal
.setMinimalDaysInFirstWeek(5);
2606 int32_t woy1
= cal
.get(UCAL_WEEK_OF_YEAR
, ec
);
2607 int32_t wom1
= cal
.get(UCAL_WEEK_OF_MONTH
, ec
);
2609 cal
.add(UCAL_DATE
, 1, ec
); // Force recalc
2610 cal
.add(UCAL_DATE
, -1, ec
);
2612 int32_t woy2
= cal
.get(UCAL_WEEK_OF_YEAR
, ec
);
2613 int32_t wom2
= cal
.get(UCAL_WEEK_OF_MONTH
, ec
);
2615 UDate time2
= cal
.getTime(ec
);
2617 if (U_FAILURE(ec
)) {
2618 errln("FAIL: internal test error");
2622 if (time1
!= time2
) {
2623 errln("FAIL: shifting week should not alter time");
2627 if (woy1
== woy2
&& wom1
== wom2
) {
2628 logln((UnicodeString
)"Ok: WEEK_OF_YEAR: " + woy1
+
2629 ", WEEK_OF_MONTH: " + wom1
);
2631 errln((UnicodeString
)"FAIL: WEEK_OF_YEAR: " + woy1
+ " => " + woy2
+
2632 ", WEEK_OF_MONTH: " + wom1
+ " => " + wom2
+
2633 " after week shift");
2639 * Make sure that when adding a day, we actually wind up in a
2640 * different day. The DST adjustments we use to keep the hour
2641 * constant across DST changes can backfire and change the day.
2643 void CalendarRegressionTest::TestTimeZoneTransitionAdd() {
2644 UErrorCode ec
= U_ZERO_ERROR
;
2645 Locale
locale(Locale::getUS()); // could also be CHINA
2646 SimpleDateFormat
dateFormat("MM/dd/yyyy HH:mm z", locale
, ec
);
2648 StringEnumeration
*tz
= TimeZone::createEnumeration();
2650 dataerrln("FAIL: TimeZone::createEnumeration");
2654 UnicodeString buf1
, buf2
;
2657 while ((id
= tz
->unext(NULL
, ec
)) != NULL
&& U_SUCCESS(ec
)) {
2658 if (U_FAILURE(ec
)) {
2659 errln("FAIL: StringEnumeration::unext");
2663 TimeZone
*t
= TimeZone::createTimeZone(id
);
2665 errln("FAIL: TimeZone::createTimeZone");
2668 dateFormat
.setTimeZone(*t
);
2670 Calendar
*cal
= Calendar::createInstance(t
, locale
, ec
);
2671 if (cal
== NULL
|| U_FAILURE(ec
)) {
2672 errln("FAIL: Calendar::createTimeZone");
2678 // Scan the year 2003, overlapping the edges of the year
2679 cal
->set(UCAL_YEAR
, 2002);
2680 cal
->set(UCAL_MONTH
, UCAL_DECEMBER
);
2681 cal
->set(UCAL_DATE
, 25);
2683 for (int32_t i
=0; i
<365+10 && U_SUCCESS(ec
); ++i
) {
2684 UDate yesterday
= cal
->getTime(ec
);
2685 int32_t yesterday_day
= cal
->get(UCAL_DATE
, ec
);
2686 cal
->add(UCAL_DATE
, 1, ec
);
2687 if (yesterday_day
== cal
->get(UCAL_DATE
, ec
)) {
2688 errln(UnicodeString(id
) + " " +
2689 dateFormat
.format(yesterday
, buf1
) + " +1d= " +
2690 dateFormat
.format(cal
->getTime(ec
), buf2
));
2698 if (U_FAILURE(ec
)) {
2699 dataerrln("FAIL: %s", u_errorName(ec
));
2706 CalendarRegressionTest::makeDate(int32_t y
, int32_t m
, int32_t d
,
2707 int32_t hr
, int32_t min
, int32_t sec
)
2711 UErrorCode status
= U_ZERO_ERROR
;
2712 Calendar
*cal
= Calendar::createInstance(status
);
2715 cal
->set(UCAL_YEAR
, y
);
2717 if(m
!= 0) cal
->set(UCAL_MONTH
, m
);
2718 if(d
!= 0) cal
->set(UCAL_DATE
, d
);
2719 if(hr
!= 0) cal
->set(UCAL_HOUR
, hr
);
2720 if(min
!= 0) cal
->set(UCAL_MINUTE
, min
);
2721 if(sec
!= 0) cal
->set(UCAL_SECOND
, sec
);
2723 result
= cal
->getTime(status
);
2730 void CalendarRegressionTest::TestDeprecates(void)
2732 UErrorCode status
= U_ZERO_ERROR
;
2733 Calendar
*c1
= Calendar::createInstance("ja_JP@calendar=japanese",status
);
2734 Calendar
*c2
= Calendar::createInstance("ja_JP_TRADITIONAL",status
);
2736 if(!c1
|| !c2
|| U_FAILURE(status
)) {
2737 dataerrln("Couldn't create calendars for roll of HOUR: %s", u_errorName(status
));
2741 c2
->set(UCAL_HOUR
,2);
2742 c1
->setTime(c2
->getTime(status
),status
);
2745 c1
->roll(Calendar::HOUR
,(int32_t)3,status
);
2746 c2
->roll(UCAL_HOUR
,(int32_t)3,status
);
2748 if(U_FAILURE(status
)) {
2749 errln("Error code when trying to roll");
2750 } else if(*c1
!= *c2
) {
2751 errln("roll(EDateField, int32_t) had different effect than roll(UCalendarField, int32_t)");
2754 c1
->setTime(c2
->getTime(status
),status
);
2755 c1
->roll(Calendar::HOUR
,(UBool
)FALSE
,status
);
2756 c2
->roll(UCAL_HOUR
,(UBool
)FALSE
,status
);
2758 if(U_FAILURE(status
)) {
2759 errln("Error code when trying to roll(UBool)");
2760 } else if(*c1
!= *c2
) {
2761 errln("roll(EDateField, UBool) had different effect than roll(UCalendarField, UBool)");
2767 status
= U_ZERO_ERROR
;
2769 c1
= Calendar::createInstance("th_TH_TRADITIONAL",status
);
2770 c2
= Calendar::createInstance("th_TH@calendar=buddhist",status
);
2772 if(!c1
|| !c2
|| U_FAILURE(status
)) {
2773 errln("Couldn't create calendars for add of HOUR");
2777 c2
->set(UCAL_HOUR
,2);
2778 c1
->setTime(c2
->getTime(status
),status
);
2781 c1
->add(Calendar::HOUR
,(int32_t)1,status
);
2783 if(U_FAILURE(status
)) {
2784 errln("Error code when trying to add Calendar::HOUR - %s", u_errorName(status
));
2787 c2
->add(UCAL_HOUR
,(int32_t)1,status
);
2789 if(U_FAILURE(status
)) {
2790 errln("Error code when trying to add - UCAL_HOUR %s", u_errorName(status
));
2791 } else if(*c1
!= *c2
) {
2792 errln("add(EDateField) had different effect than add(UCalendarField)");
2798 status
= U_ZERO_ERROR
;
2800 c1
= Calendar::createInstance("es_ES",status
);
2801 c2
= Calendar::createInstance("es_ES",status
);
2803 if(!c1
|| !c2
|| U_FAILURE(status
)) {
2804 errln("Couldn't create calendars for add of YEAR");
2808 c2
->set(UCAL_YEAR
,1900);
2809 c1
->setTime(c2
->getTime(status
),status
);
2812 c1
->add(Calendar::YEAR
,(int32_t)9,status
);
2813 c2
->add(UCAL_YEAR
,(int32_t)9,status
);
2815 if(U_FAILURE(status
)) {
2816 errln("Error code when trying to add YEARs");
2817 } else if(*c1
!= *c2
) {
2818 errln("add(EDateField YEAR) had different effect than add(UCalendarField YEAR)");
2826 void CalendarRegressionTest::TestT8057(void) {
2827 // Set the calendar to the last day in a leap year
2828 UErrorCode status
= U_ZERO_ERROR
;
2829 GregorianCalendar
*cal
= (GregorianCalendar
*)Calendar::createInstance(status
);
2830 if(U_FAILURE(status
)) {
2831 errln("Error creating Calendar: %s", u_errorName(status
));
2835 cal
->setLenient(FALSE
);
2837 cal
->set(2008, UCAL_DECEMBER
, 31);
2839 // Force calculating then fields once.
2840 UDate t
= cal
->getTime(status
);
2841 if(U_FAILURE(status
)) {
2842 errln("Error while calculating the date");
2847 UDate expected
= 1262246400000.0; // 2009-12-31 00:00 PST
2849 cal
->add(UCAL_YEAR
, 1, status
);
2850 t
= cal
->getTime(status
);
2851 if (U_SUCCESS(status
)) {
2852 if (t
!= expected
) {
2853 dataerrln((UnicodeString
)"FAIL: wrong date after add: expected=" + expected
+ " returned=" + t
);
2856 errln("FAIL: error while adding one year");
2862 // Test case for ticket#8596.
2863 // Setting an year followed by getActualMaximum(Calendar.WEEK_OF_YEAR)
2864 // may result wrong maximum week.
2865 void CalendarRegressionTest::TestT8596(void) {
2866 UErrorCode status
= U_ZERO_ERROR
;
2867 GregorianCalendar
*gc
= new GregorianCalendar(*TimeZone::getGMT(), status
);
2869 if (U_FAILURE(status
)) {
2870 dataerrln("Error creating Calendar: %s", u_errorName(status
));
2875 gc
->setFirstDayOfWeek(UCAL_MONDAY
);
2876 gc
->setMinimalDaysInFirstWeek(4);
2878 // Force the calender to resolve the fields once.
2879 // The maximum week number in 2011 is 52.
2880 gc
->set(UCAL_YEAR
, 2011);
2881 gc
->get(UCAL_YEAR
, status
);
2883 // Set a date in year 2009, but not calling get to resolve
2884 // the calendar's internal field yet.
2885 gc
->set(2009, UCAL_JULY
, 1);
2887 // Then call getActuamMaximum for week of year.
2888 // #8596 was caused by conflict between year set
2889 // above and internal work calendar field resolution.
2890 int32_t maxWeeks
= gc
->getActualMaximum(UCAL_WEEK_OF_YEAR
, status
);
2892 if (U_FAILURE(status
)) {
2893 errln("Error calendar calculation: %s", u_errorName(status
));
2898 if (maxWeeks
!= 53) {
2899 errln((UnicodeString
)"FAIL: Max week in 2009 in ISO calendar is 53, but got " + maxWeeks
);
2905 // Test case for ticket 9452
2906 // Calendar addition fall onto the missing date - 2011-12-30 in Samoa
2907 void CalendarRegressionTest::TestT9452(void) {
2908 UErrorCode status
= U_ZERO_ERROR
;
2909 GregorianCalendar
cal(TimeZone::createTimeZone("Pacific/Apia"), status
);
2910 failure(status
, "initializing GregorianCalendar");
2912 SimpleDateFormat
sdf(UnicodeString("y-MM-dd'T'HH:mm:ssZZZZZ"), status
);
2913 failure(status
, "initializing SimpleDateFormat");
2914 sdf
.setCalendar(cal
);
2918 // Set date to 2011-12-29 00:00
2920 cal
.set(2011, UCAL_DECEMBER
, 29, 0, 0, 0);
2922 UDate d
= cal
.getTime(status
);
2923 if (!failure(status
, "getTime for initial date")) {
2924 sdf
.format(d
, dstr
);
2925 logln(UnicodeString("Initial date: ") + dstr
);
2928 cal
.add(UCAL_DATE
, 1, status
);
2929 failure(status
, "add 1 day");
2930 d
= cal
.getTime(status
);
2931 failure(status
, "getTime after +1 day");
2933 sdf
.format(d
, dstr
);
2934 logln(UnicodeString("+1 day: ") + dstr
);
2935 assertEquals("Add 1 day", UnicodeString("2011-12-31T00:00:00+14:00"), dstr
);
2938 cal
.add(UCAL_DATE
, -1, status
);
2939 failure(status
, "subtract 1 day");
2940 d
= cal
.getTime(status
);
2941 failure(status
, "getTime after -1 day");
2943 sdf
.format(d
, dstr
);
2944 logln(UnicodeString("-1 day: ") + dstr
);
2945 assertEquals("Subtract 1 day", UnicodeString("2011-12-29T00:00:00-10:00"), dstr
);
2949 #endif /* #if !UCONFIG_NO_FORMATTING */