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/calendar.h"
16 #include "unicode/gregocal.h"
17 #include "unicode/simpletz.h"
18 #include "unicode/smpdtfmt.h"
19 #include "unicode/strenum.h"
20 #include "unicode/localpointer.h"
23 #include "unicode/localpointer.h"
27 // *****************************************************************************
28 // class CalendarRegressionTest
29 // *****************************************************************************
31 // these numbers correspond to using LONG_MIN and LONG_MAX in Java
32 // this is 2^52 - 1, the largest allowable mantissa with a 0 exponent in a 64-bit double
33 const UDate
CalendarRegressionTest::EARLIEST_SUPPORTED_MILLIS
= - 4503599627370495.0;
34 const UDate
CalendarRegressionTest::LATEST_SUPPORTED_MILLIS
= 4503599627370495.0;
36 #define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); logln((UnicodeString)""); test(); } break
39 CalendarRegressionTest::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char* /*par*/ )
41 // if (exec) logln((UnicodeString)"TestSuite NumberFormatRegressionTest");
60 CASE(17,test41003112
);
82 CASE(38,TestLeapFieldDifference
);
83 CASE(39,TestMalaysianInstance
);
86 CASE(42,TestWeekShift
);
87 CASE(43,TestTimeZoneTransitionAdd
);
88 CASE(44,TestDeprecates
);
96 CASE(52,TestPersianCalOverflow
);
97 CASE(53,TestIslamicCalOverflow
);
98 CASE(54,TestWeekOfYear13548
);
99 default: name
= ""; break;
103 const char* CalendarRegressionTest::FIELD_NAME
[] = {
112 "DAY_OF_WEEK_IN_MONTH",
126 CalendarRegressionTest::failure(UErrorCode status
, const char* msg
)
128 if(U_FAILURE(status
)) {
129 errcheckln(status
, UnicodeString("FAIL: ") + msg
+ " failed, error " + u_errorName(status
));
140 CalendarRegressionTest::test4100311()
142 UErrorCode status
= U_ZERO_ERROR
;
143 GregorianCalendar
*cal
= (GregorianCalendar
*)Calendar::createInstance(status
);
144 if(U_FAILURE(status
)) {
145 dataerrln("Error creating Calendar: %s", u_errorName(status
));
149 failure(status
, "Calendar::createInstance(status)");
150 cal
->set(UCAL_YEAR
, 1997);
151 cal
->set(UCAL_DAY_OF_YEAR
, 1);
152 UDate d
= cal
->getTime(status
); // Should be Jan 1
153 failure(status
, "cal->getTime");
154 logln(UnicodeString("") + d
);
163 CalendarRegressionTest::test4074758()
164 { //Set system time to between 12-1 (am or pm) and then run
165 UErrorCode status
= U_ZERO_ERROR
;
166 GregorianCalendar
*cal
= new GregorianCalendar(status
);
167 if(U_FAILURE(status
)) {
168 dataerrln("Error creating Calendar: %s", u_errorName(status
));
172 failure(status
, "new GregorianCalendar");
173 for (int32_t h
=0; h
<25; ++h
) {
174 cal
->set(97, UCAL_JANUARY
, 1, h
, 34);
175 //System.out.print(d);
176 logln(UnicodeString("HOUR=") + cal
->get(UCAL_HOUR
, status
)); //prints 0
177 failure(status
, "cal->get");
178 logln(UnicodeString("HOUR_OF_DAY=") + cal
->get(UCAL_HOUR_OF_DAY
, status
));
179 failure(status
, "cal->get");
186 CalendarRegressionTest::test4028518()
188 UErrorCode status
= U_ZERO_ERROR
;
189 GregorianCalendar
*cal1
= new GregorianCalendar(status
) ;
190 if(U_FAILURE(status
)) {
191 dataerrln("Error creating Calendar: %s", u_errorName(status
));
195 failure(status
, "new GregorianCalendar");
196 GregorianCalendar
*cal2
= (GregorianCalendar
*) cal1
->clone() ;
198 printdate(cal1
, "cal1: ") ;
199 printdate(cal2
, "cal2 - cloned(): ") ;
200 cal1
->add(UCAL_DATE
, 1, status
) ;
201 failure(status
, "cal1->add");
202 printdate(cal1
, "cal1 after adding 1 day:") ;
203 printdate(cal2
, "cal2 should be unmodified:") ;
210 CalendarRegressionTest::Test9019()
212 UErrorCode status
= U_ZERO_ERROR
;
213 LocalPointer
<GregorianCalendar
> cal1(new GregorianCalendar(status
), status
);
214 LocalPointer
<GregorianCalendar
> cal2(new GregorianCalendar(status
), status
);
215 if(U_FAILURE(status
)) {
216 dataerrln("Error creating Calendar: %s", u_errorName(status
));
219 cal1
->set(UCAL_HOUR
, 1);
220 cal2
->set(UCAL_HOUR
,2);
223 failure(status
, "new GregorianCalendar");
224 cal1
->set(2011,UCAL_MAY
,06);
225 cal2
->set(2012,UCAL_JANUARY
,06);
226 printdate(cal1
.getAlias(), "cal1: ") ;
227 cal1
->setLenient(FALSE
);
228 cal1
->add(UCAL_MONTH
,8,status
);
229 failure(status
, "->add(UCAL_MONTH,8)");
230 printdate(cal1
.getAlias(), "cal1 (lenient) after adding 8 months:") ;
231 printdate(cal2
.getAlias(), "cal2 (expected date):") ;
233 if(!cal1
->equals(*cal2
,status
)) {
234 errln("Error: cal1 != cal2.\n");
236 failure(status
, "equals");
240 CalendarRegressionTest::printdate(GregorianCalendar
*cal
, const char *string
)
242 UErrorCode status
= U_ZERO_ERROR
;
243 logln(UnicodeString(string
, ""));
244 log(UnicodeString("") + cal
->get(UCAL_MONTH
, status
)) ;
245 failure(status
, "cal->get");
246 int32_t date
= cal
->get(UCAL_DATE
, status
) + 1 ;
247 failure(status
, "cal->get");
248 log(UnicodeString("/") + date
) ;
249 logln(UnicodeString("/") + cal
->get(UCAL_YEAR
, status
)) ;
250 failure(status
, "cal->get");
257 CalendarRegressionTest::test4031502()
259 // This bug actually occurs on Windows NT as well, and doesn't
260 // require the host zone to be set; it can be set in Java.
261 UErrorCode status
= U_ZERO_ERROR
;
262 StringEnumeration
* ids
= TimeZone::createEnumeration();
264 dataerrln("Unable to create TimeZone Enumeration.");
268 TimeZone
* tz
=TimeZone::createTimeZone("Asia/Riyadh87");
269 failure(status
, "new TimeZone");
270 GregorianCalendar
*cl
= new GregorianCalendar(tz
, status
);
271 if (U_FAILURE(status
)) {
272 dataerrln("Fail new GregorianCalendar: %s", u_errorName(status
));
277 cl
->set(1900, 15, 5, 5, 8, 13);
278 cl
->get(UCAL_HOUR
, status
);
279 failure(status
, "cl->get(UCAL_HOUR, status)");
280 status
= U_ZERO_ERROR
;
282 for (int32_t i
=0; i
<ids
->count(status
); ++i
) {
283 TimeZone
*zone
= TimeZone::createTimeZone(*ids
->snext(status
));
284 GregorianCalendar
*cal
= new GregorianCalendar(zone
, status
);
285 failure(status
, "new GregorianCalendar");
287 cal
->set(1900, 15, 5, 5, 8, 13);
288 if (cal
->get(UCAL_HOUR
, status
) != 5 || U_FAILURE(status
)) {
290 logln(zone
->getID(temp
) + " " +
291 //zone.useDaylightTime() + " " +
292 cal
->get(UCAL_DST_OFFSET
,status
) / (60*60*1000) + " " +
293 zone
->getRawOffset() / (60*60*1000) +
294 ": HOUR = " + cal
->get(UCAL_HOUR
,status
));
300 errln("TimeZone problems with GC");
301 // delete [] ids; // TODO: bad APIs
308 void CalendarRegressionTest::test4035301()
310 UErrorCode status
= U_ZERO_ERROR
;
311 GregorianCalendar
*c
= new GregorianCalendar(98, 8, 7,status
);
312 GregorianCalendar
*d
= new GregorianCalendar(98, 8, 7,status
);
313 if (c
->after(*d
,status
) ||
314 c
->after(*c
,status
) ||
315 c
->before(*d
,status
) ||
316 c
->before(*c
,status
) ||
327 void CalendarRegressionTest::test4040996()
330 StringEnumeration
* ids
= TimeZone::createEnumeration(-8 * 60 * 60 * 1000);
332 dataerrln("Unable to create TimeZone enumeration.");
335 UErrorCode status
= U_ZERO_ERROR
;
336 count
= ids
->count(status
);
337 (void)count
; // Suppress set but not used warning.
338 SimpleTimeZone
*pdt
= new SimpleTimeZone(-8 * 60 * 60 * 1000, *ids
->snext(status
));
339 pdt
->setStartRule(UCAL_APRIL
, 1, UCAL_SUNDAY
, 2 * 60 * 60 * 1000, status
);
340 pdt
->setEndRule(UCAL_OCTOBER
, -1, UCAL_SUNDAY
, 2 * 60 * 60 * 1000, status
);
341 Calendar
*calendar
= new GregorianCalendar(pdt
, status
);
342 if (U_FAILURE(status
)) {
343 dataerrln("Fail new GregorianCalendar: %s", u_errorName(status
));
346 calendar
->set(UCAL_MONTH
,3);
347 calendar
->set(UCAL_DATE
,18);
348 calendar
->set(UCAL_SECOND
, 30);
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
));
356 calendar
->add(UCAL_SECOND
,6, status
);
357 //This will print out todays date for MONTH and DAY_OF_MONTH
358 //instead of the date it was set to.
359 //This happens when adding MILLISECOND or MINUTE also
360 logln(UnicodeString("MONTH: ") + calendar
->get(UCAL_MONTH
, status
));
361 logln(UnicodeString("DAY_OF_MONTH: ") +
362 calendar
->get(UCAL_DATE
, status
));
363 logln(UnicodeString("MINUTE: ") + calendar
->get(UCAL_MINUTE
, status
));
364 logln(UnicodeString("SECOND: ") + calendar
->get(UCAL_SECOND
, status
));
365 if (calendar
->get(UCAL_MONTH
, status
) != 3 ||
366 calendar
->get(UCAL_DATE
, status
) != 18 ||
367 calendar
->get(UCAL_SECOND
, status
) != 36)
368 errln(UnicodeString("Fail: Calendar::add misbehaves"));
372 // delete ids; // TODO: BAD API
378 void CalendarRegressionTest::test4051765()
380 UErrorCode status
= U_ZERO_ERROR
;
381 Calendar
*cal
= Calendar::createInstance(status
);
382 if(U_FAILURE(status
)) {
383 dataerrln("Error creating Calendar: %s", u_errorName(status
));
387 cal
->setLenient(FALSE
);
388 cal
->set(UCAL_DAY_OF_WEEK
, 0);
390 cal
->getTime(status
);
391 if( ! U_FAILURE(status
))
392 errln("Fail: DAY_OF_WEEK 0 should be disallowed");
394 catch (IllegalArgumentException e) {
401 /* User error - no bug here
402 void CalendarRegressionTest::test4059524() {
403 // Create calendar for April 10, 1997
404 GregorianCalendar calendar = new GregorianCalendar(status);
405 // print out a bunch of interesting things
406 logln("ERA: " + Calendar::get(Calendar::ERA));
407 logln("YEAR: " + Calendar::get(Calendar::YEAR));
408 logln("MONTH: " + Calendar::get(Calendar::MONTH));
409 logln("WEEK_OF_YEAR: " +
410 Calendar::get(Calendar::WEEK_OF_YEAR));
411 logln("WEEK_OF_MONTH: " +
412 Calendar::get(Calendar::WEEK_OF_MONTH));
413 logln("DATE: " + Calendar::get(Calendar::DATE));
414 logln("DAY_OF_MONTH: " +
415 Calendar::get(Calendar::DAY_OF_MONTH));
416 logln("DAY_OF_YEAR: " + Calendar::get(Calendar::DAY_OF_YEAR));
417 logln("DAY_OF_WEEK: " + Calendar::get(Calendar::DAY_OF_WEEK));
418 logln("DAY_OF_WEEK_IN_MONTH: " +
419 Calendar::get(Calendar::DAY_OF_WEEK_IN_MONTH));
420 logln("AM_PM: " + Calendar::get(Calendar::AM_PM));
421 logln("HOUR: " + Calendar::get(Calendar::HOUR));
422 logln("HOUR_OF_DAY: " + Calendar::get(Calendar::HOUR_OF_DAY));
423 logln("MINUTE: " + Calendar::get(Calendar::MINUTE));
424 logln("SECOND: " + Calendar::get(Calendar::SECOND));
425 logln("MILLISECOND: " + Calendar::get(Calendar::MILLISECOND));
426 logln("ZONE_OFFSET: "
427 + (Calendar::get(Calendar::ZONE_OFFSET)/(60*60*1000)));
429 + (Calendar::get(Calendar::DST_OFFSET)/(60*60*1000)));
430 calendar = new GregorianCalendar(1997,3,10);
432 logln("April 10, 1997");
433 logln("ERA: " + Calendar::get(Calendar::ERA));
434 logln("YEAR: " + Calendar::get(Calendar::YEAR));
435 logln("MONTH: " + Calendar::get(Calendar::MONTH));
436 logln("WEEK_OF_YEAR: " +
437 Calendar::get(Calendar::WEEK_OF_YEAR));
438 logln("WEEK_OF_MONTH: " +
439 Calendar::get(Calendar::WEEK_OF_MONTH));
440 logln("DATE: " + Calendar::get(Calendar::DATE));
441 logln("DAY_OF_MONTH: " +
442 Calendar::get(Calendar::DAY_OF_MONTH));
443 logln("DAY_OF_YEAR: " + Calendar::get(Calendar::DAY_OF_YEAR));
444 logln("DAY_OF_WEEK: " + Calendar::get(Calendar::DAY_OF_WEEK));
445 logln("DAY_OF_WEEK_IN_MONTH: " + Calendar::get(Calendar::DAY_OF_WEEK_IN_MONTH));
446 logln("AM_PM: " + Calendar::get(Calendar::AM_PM));
447 logln("HOUR: " + Calendar::get(Calendar::HOUR));
448 logln("HOUR_OF_DAY: " + Calendar::get(Calendar::HOUR_OF_DAY));
449 logln("MINUTE: " + Calendar::get(Calendar::MINUTE));
450 logln("SECOND: " + Calendar::get(Calendar::SECOND));
451 logln("MILLISECOND: " + Calendar::get(Calendar::MILLISECOND));
452 logln("ZONE_OFFSET: "
453 + (Calendar::get(Calendar::ZONE_OFFSET)/(60*60*1000))); // in hours
455 + (Calendar::get(Calendar::DST_OFFSET)/(60*60*1000))); // in hours
462 void CalendarRegressionTest::test4059654() {
463 UErrorCode status
= U_ZERO_ERROR
;
464 GregorianCalendar
*gc
= new GregorianCalendar(status
);
465 if(U_FAILURE(status
)) {
466 dataerrln("Error creating Calendar: %s", u_errorName(status
));
471 gc
->set(1997, 3, 1, 15, 16, 17); // April 1, 1997
473 gc
->set(UCAL_HOUR
, 0);
474 gc
->set(UCAL_AM_PM
, UCAL_AM
);
475 gc
->set(UCAL_MINUTE
, 0);
476 gc
->set(UCAL_SECOND
, 0);
477 gc
->set(UCAL_MILLISECOND
, 0);
479 UDate cd
= gc
->getTime(status
);
480 GregorianCalendar
*exp
= new GregorianCalendar(1997, 3, 1, 0, 0, 0, status
);
481 if (cd
!= exp
->getTime(status
))
482 errln(UnicodeString("Fail: Calendar::set broken. Got ") + cd
+ " Want " + exp
->getTime(status
));
491 void CalendarRegressionTest::test4061476()
493 UErrorCode status
= U_ZERO_ERROR
;
494 SimpleDateFormat
*fmt
= new SimpleDateFormat(UnicodeString("ddMMMyy"), Locale::getUK(),status
);
495 Calendar
*cal
= Calendar::createInstance(TimeZone::createTimeZone("GMT"),
496 Locale::getUK(),status
);
497 if(U_FAILURE(status
)) {
498 dataerrln("Error creating Calendar: %s", u_errorName(status
));
503 fmt
->adoptCalendar(cal
);
505 UDate date
= fmt
->parse("29MAY97", status
);
506 failure(status
, "fmt->parse");
507 cal
->setTime(date
, status
);
508 failure(status
, "cal->setTime");
510 //catch (Exception e) {;}
511 cal
->set(UCAL_HOUR_OF_DAY
, 13);
512 logln(UnicodeString("Hour: ")+cal
->get(UCAL_HOUR_OF_DAY
, status
));
513 cal
->add(UCAL_HOUR_OF_DAY
, 6,status
);
514 logln(UnicodeString("Hour: ")+cal
->get(UCAL_HOUR_OF_DAY
, status
));
515 if (cal
->get(UCAL_HOUR_OF_DAY
, status
) != 19)
516 errln(UnicodeString("Fail: Want 19 Got ") + cal
->get(UCAL_HOUR_OF_DAY
, status
));
524 void CalendarRegressionTest::test4070502()
526 UErrorCode status
= U_ZERO_ERROR
;
527 Calendar
*cal
= new GregorianCalendar(status
);
528 if(status
== U_USING_FALLBACK_WARNING
|| U_FAILURE(status
)) {
529 dataerrln("Error creating Calendar: %s", u_errorName(status
));
533 UDate d
= getAssociatedDate(makeDate(1998,0,30), status
);
534 cal
->setTime(d
,status
);
535 if (cal
->get(UCAL_DAY_OF_WEEK
,status
) == UCAL_SATURDAY
||
536 cal
->get(UCAL_DAY_OF_WEEK
,status
) == UCAL_SUNDAY
)
537 errln(UnicodeString("Fail: Want weekday Got ") + d
);
543 * Get the associated date starting from a specified date
544 * NOTE: the unnecessary "getTime()'s" below are a work-around for a
545 * bug in jdk 1.1.3 (and probably earlier versions also)
547 * @param date The date to start from
550 CalendarRegressionTest::getAssociatedDate(UDate d
, UErrorCode
& status
)
552 GregorianCalendar
*cal
= new GregorianCalendar(status
);
553 cal
->setTime(d
,status
);
554 //cal.add(field, amount); //<-- PROBLEM SEEN WITH field = DATE,MONTH
555 // cal.getTime(); // <--- REMOVE THIS TO SEE BUG
557 int32_t wd
= cal
->get(UCAL_DAY_OF_WEEK
, status
);
558 if (wd
== UCAL_SATURDAY
|| wd
== UCAL_SUNDAY
) {
559 cal
->add(UCAL_DATE
, 1, status
);
566 UDate dd
= cal
->getTime(status
);
574 void CalendarRegressionTest::test4071197()
580 void CalendarRegressionTest::dowTest(UBool lenient
)
582 UErrorCode status
= U_ZERO_ERROR
;
583 GregorianCalendar
*cal
= new GregorianCalendar(status
);
584 if(U_FAILURE(status
)) {
585 dataerrln("Error creating Calendar: %s", u_errorName(status
));
589 cal
->set(1997, UCAL_AUGUST
, 12); // Wednesday
590 // cal.getTime(); // Force update
591 cal
->setLenient(lenient
);
592 cal
->set(1996, UCAL_DECEMBER
, 1); // Set the date to be December 1, 1996
593 int32_t dow
= cal
->get(UCAL_DAY_OF_WEEK
, status
);
594 int32_t min
= cal
->getMinimum(UCAL_DAY_OF_WEEK
);
595 int32_t max
= cal
->getMaximum(UCAL_DAY_OF_WEEK
);
596 //logln(cal.getTime().toString());
597 if (min
!= UCAL_SUNDAY
|| max
!= UCAL_SATURDAY
)
598 errln("FAIL: Min/max bad");
599 if (dow
< min
|| dow
> max
)
600 errln("FAIL: Day of week %d out of range [%d,%d]\n", dow
, min
, max
);
601 if (dow
!= UCAL_SUNDAY
)
602 errln(UnicodeString("FAIL: Day of week should be SUNDAY Got ") + dow
);
604 if(U_FAILURE(status
)) {
605 errln("Error checking Calendar: %s", u_errorName(status
));
610 if(cal
->getActualMinimum(UCAL_DAY_OF_WEEK
, status
) != min
) {
611 errln("FAIL: actual minimum differs from minimum");
613 if(cal
->getActualMinimum(Calendar::DAY_OF_WEEK
, status
) != min
) {
614 errln("FAIL: actual minimum (Calendar::DAY_OF_WEEK, status) differs from minimum");
616 if(cal
->getActualMinimum(Calendar::DAY_OF_WEEK
) != min
) {
617 errln("FAIL: actual minimum (Calendar::DAY_OF_WEEK) differs from minimum");
619 if(((Calendar
*)cal
)->getActualMinimum(UCAL_DAY_OF_WEEK
, status
) != min
) {
620 errln("FAIL: actual minimum (UCAL_DAY_OF_WEEK, status) differs from minimum");
622 // NOTE: This function does not exist! jitterbug #3016
623 // if(((Calendar*)cal)->getActualMinimum(Calendar::DAY_OF_WEEK, status) != min) {
624 // errln("FAIL: actual minimum (Calendar::DAY_OF_WEEK, status) differs from minimum");
626 if(U_FAILURE(status
)) {
627 errln("Error getting actual minimum: %s", u_errorName(status
));
637 void CalendarRegressionTest::test4071385()
639 UErrorCode status
= U_ZERO_ERROR
;
640 Calendar
*cal
= Calendar::createInstance(status
);
641 if(U_FAILURE(status
)) {
642 dataerrln("Error creating Calendar: %s", u_errorName(status
));
646 cal
->setTime(makeDate(1998, UCAL_JUNE
, 24),status
);
647 cal
->set(UCAL_MONTH
, UCAL_NOVEMBER
); // change a field
648 //logln(cal.getTime().toString());
649 if (cal
->getTime(status
) != makeDate(1998, UCAL_NOVEMBER
, 24))
658 void CalendarRegressionTest::test4073929()
660 UErrorCode status
= U_ZERO_ERROR
;
661 GregorianCalendar
*foo1
= new GregorianCalendar(1997, 8, 27,status
);
662 if(U_FAILURE(status
)) {
663 dataerrln("Error creating Calendar: %s", u_errorName(status
));
667 logln("foo1@%.0f - %d-%d-%d %d:%d:%d.%ds\n", foo1
->getTime(status
),
668 foo1
->get(UCAL_YEAR
, status
),
669 foo1
->get(UCAL_MONTH
, status
),
670 foo1
->get(UCAL_DATE
, status
),
671 foo1
->get(UCAL_HOUR
, status
),
672 foo1
->get(UCAL_MINUTE
, status
),
673 foo1
->get(UCAL_SECOND
, status
),
674 foo1
->get(UCAL_MILLISECOND
,status
));
675 foo1
->add(UCAL_DATE
, + 1, status
);
676 logln("foo1@%.0f - %d-%d-%d %d:%d:%d.%ds after +\n", foo1
->getTime(status
),
677 foo1
->get(UCAL_YEAR
, status
),
678 foo1
->get(UCAL_MONTH
, status
),
679 foo1
->get(UCAL_DATE
, status
),
680 foo1
->get(UCAL_HOUR
, status
),
681 foo1
->get(UCAL_MINUTE
, status
),
682 foo1
->get(UCAL_SECOND
, status
),
683 foo1
->get(UCAL_MILLISECOND
,status
));
684 foo1
->add(UCAL_DATE
, - 1, status
);
685 logln("foo1@%.0f - %d-%d-%d %d:%d:%d.%ds after -\n", foo1
->getTime(status
),
686 foo1
->get(UCAL_YEAR
, status
),
687 foo1
->get(UCAL_MONTH
, status
),
688 foo1
->get(UCAL_DATE
, status
),
689 foo1
->get(UCAL_HOUR
, status
),
690 foo1
->get(UCAL_MINUTE
, status
),
691 foo1
->get(UCAL_SECOND
, status
),
692 foo1
->get(UCAL_MILLISECOND
, status
));
694 foo1
->add(UCAL_DATE
, + 1, status
);
695 int32_t testyear
= foo1
->get(UCAL_YEAR
, status
);
696 int32_t testmonth
= foo1
->get(UCAL_MONTH
, status
);
697 int32_t testday
= foo1
->get(UCAL_DATE
, status
);
698 if (testyear
!= 1997 ||
701 errln("Fail: Calendar not initialized");
709 void CalendarRegressionTest::test4083167()
711 UErrorCode status
= U_ZERO_ERROR
;
712 TimeZone
*saveZone
= TimeZone::createDefault();
714 TimeZone
*newZone
= TimeZone::createTimeZone("UTC");
715 TimeZone::setDefault(*newZone
);
716 UDate firstDate
= Calendar::getNow();
717 Calendar
*cal
= new GregorianCalendar(status
);
718 if(U_FAILURE(status
)) {
719 dataerrln("Error creating Calendar: %s", u_errorName(status
));
723 cal
->setTime(firstDate
,status
);
724 int32_t hr
= cal
->get(UCAL_HOUR_OF_DAY
, status
);
725 int32_t min
= cal
->get(UCAL_MINUTE
, status
);
726 int32_t sec
= cal
->get(UCAL_SECOND
, status
);
727 int32_t msec
= cal
->get(UCAL_MILLISECOND
, status
);
728 double firstMillisInDay
= hr
* 3600000 + min
* 60000 + sec
* 1000 + msec
;
730 //logln("Current time: " + firstDate.toString());
732 for (int32_t validity
=0; validity
<30; validity
++) {
733 UDate lastDate
= firstDate
+ validity
*1000*24*60*60.0;
734 cal
->setTime(lastDate
, status
);
735 hr
= cal
->get(UCAL_HOUR_OF_DAY
, status
);
736 min
= cal
->get(UCAL_MINUTE
, status
);
737 sec
= cal
->get(UCAL_SECOND
, status
);
738 msec
= cal
->get(UCAL_MILLISECOND
, status
);
739 double millisInDay
= hr
* 3600000.0 + min
* 60000.0 + sec
* 1000.0 + msec
;
740 if (firstMillisInDay
!= millisInDay
)
741 errln(UnicodeString("Day has shifted ") + lastDate
);
745 TimeZone::setDefault(*saveZone
);
756 void CalendarRegressionTest::test4086724()
758 UErrorCode status
= U_ZERO_ERROR
;
759 SimpleDateFormat
*date
;
760 TimeZone
*saveZone
= TimeZone::createDefault();
761 Locale saveLocale
= Locale::getDefault();
763 Locale::setDefault(Locale::getUK(),status
);
764 TimeZone
*newZone
= TimeZone::createTimeZone("GMT");
765 TimeZone::setDefault(*newZone
);
766 date
= new SimpleDateFormat(UnicodeString("dd MMM yyy (zzzz) 'is in week' ww"),status
);
767 Calendar
*cal
= Calendar::createInstance(status
);
768 if(U_FAILURE(status
)) {
769 dataerrln("Error creating Calendar: %s", u_errorName(status
));
775 cal
->set(1997,UCAL_SEPTEMBER
,30);
776 UDate now
= cal
->getTime(status
);
778 FieldPosition
pos(FieldPosition::DONT_CARE
);
779 logln(date
->format(now
, temp
, pos
));
780 cal
->set(1997,UCAL_JANUARY
,1);
781 now
=cal
->getTime(status
);
782 logln(date
->format(now
,temp
, pos
));
783 cal
->set(1997,UCAL_JANUARY
,8);
784 now
=cal
->getTime(status
);
785 logln(date
->format(now
,temp
, pos
));
786 cal
->set(1996,UCAL_DECEMBER
,31);
787 now
=cal
->getTime(status
);
788 logln(date
->format(now
,temp
, pos
));
791 Locale::setDefault(saveLocale
,status
);
792 TimeZone::setDefault(*saveZone
);
794 logln("*** THE RESULTS OF THIS TEST MUST BE VERIFIED MANUALLY ***");
805 void CalendarRegressionTest::test4092362() {
806 UErrorCode status
= U_ZERO_ERROR
;
807 GregorianCalendar
*cal1
= new GregorianCalendar(1997, 10, 11, 10, 20, 40,status
);
808 if (U_FAILURE(status
)) {
809 dataerrln("Fail new GregorianCalendar: %s", u_errorName(status
));
813 /*cal1.set( Calendar::YEAR, 1997 );
814 cal1.set( Calendar::MONTH, 10 );
815 cal1.set( Calendar::DATE, 11 );
816 cal1.set( Calendar::HOUR, 10 );
817 cal1.set( Calendar::MINUTE, 20 );
818 cal1.set( Calendar::SECOND, 40 ); */
820 logln( UnicodeString(" Cal1 = ") + cal1
->getTime(status
) );
821 logln( UnicodeString(" Cal1 time in ms = ") + cal1
->get(UCAL_MILLISECOND
,status
) );
822 for (int32_t k
= 0; k
< 100 ; k
++)
825 GregorianCalendar
*cal2
= new GregorianCalendar(1997, 10, 11, 10, 20, 40,status
);
826 /*cal2.set( Calendar::YEAR, 1997 );
827 cal2.set( Calendar::MONTH, 10 );
828 cal2.set( Calendar::DATE, 11 );
829 cal2.set( Calendar::HOUR, 10 );
830 cal2.set( Calendar::MINUTE, 20 );
831 cal2.set( Calendar::SECOND, 40 ); */
833 logln( UnicodeString(" Cal2 = ") + cal2
->getTime(status
) );
834 logln( UnicodeString(" Cal2 time in ms = ") + cal2
->get(UCAL_MILLISECOND
,status
) );
836 errln("Fail: Milliseconds randomized");
845 void CalendarRegressionTest::test4095407()
847 UErrorCode status
= U_ZERO_ERROR
;
848 GregorianCalendar
*a
= new GregorianCalendar(1997,UCAL_NOVEMBER
, 13,status
);
849 if (U_FAILURE(status
)) {
850 dataerrln("Fail new GregorianCalendar: %s", u_errorName(status
));
854 int32_t dow
= a
->get(UCAL_DAY_OF_WEEK
, status
);
855 if (dow
!= UCAL_THURSDAY
)
856 errln(UnicodeString("Fail: Want THURSDAY Got ") + dow
);
864 void CalendarRegressionTest::test4096231()
866 UErrorCode status
= U_ZERO_ERROR
;
867 TimeZone
*GMT
= TimeZone::createTimeZone("GMT");
868 TimeZone
*PST
= TimeZone::createTimeZone("PST");
869 int32_t sec
= 0, min
= 0, hr
= 0, day
= 1, month
= 10, year
= 1997;
871 Calendar
*cal1
= new GregorianCalendar(*PST
,status
);
872 if (U_FAILURE(status
)) {
873 dataerrln("Failure new GregorianCalendar: %s", u_errorName(status
));
879 cal1
->setTime(880698639000.0,status
);
880 // Issue 1: Changing the timezone doesn't change the
881 // represented time. The old API, pre 1.2.2a requires
882 // setTime to be called in order to update the time fields after the time
883 // zone has been set.
885 logln(UnicodeString("PST 1 is: ") + (h1
=cal1
->get(UCAL_HOUR_OF_DAY
, status
)));
886 cal1
->setTimeZone(*GMT
);
887 logln(UnicodeString("GMT 2 is: ") + (h2
=cal1
->get(UCAL_HOUR_OF_DAY
, status
)));
888 if ((*GMT
!= *PST
) && (h1
== h2
))
889 errln("Fail: Hour same in different zones");
891 Calendar
*cal2
= new GregorianCalendar(*GMT
,status
);
892 Calendar
*cal3
= new GregorianCalendar(*PST
,status
);
893 cal2
->set(UCAL_MILLISECOND
, 0);
894 cal3
->set(UCAL_MILLISECOND
, 0);
896 cal2
->set(cal1
->get(UCAL_YEAR
,status
),
897 cal1
->get(UCAL_MONTH
,status
),
898 cal1
->get(UCAL_DATE
,status
),
899 cal1
->get(UCAL_HOUR_OF_DAY
,status
),
900 cal1
->get(UCAL_MINUTE
,status
),
901 cal1
->get(UCAL_SECOND
,status
));
904 logln(UnicodeString("RGMT 1 is: ") + (t1
=cal2
->getTime(status
)));
905 cal3
->set(year
, month
, day
, hr
, min
, sec
);
906 logln(UnicodeString("RPST 1 is: ") + (t2
=cal3
->getTime(status
)));
907 cal3
->setTimeZone(*GMT
);
908 logln(UnicodeString("RGMT 2 is: ") + (t3
=cal3
->getTime(status
)));
909 cal3
->set(cal1
->get(UCAL_YEAR
,status
),
910 cal1
->get(UCAL_MONTH
,status
),
911 cal1
->get(UCAL_DATE
,status
),
912 cal1
->get(UCAL_HOUR_OF_DAY
,status
),
913 cal1
->get(UCAL_MINUTE
,status
),
914 cal1
->get(UCAL_SECOND
,status
));
915 // Issue 2: Calendar continues to use the timezone in its
916 // constructor for set() conversions, regardless
917 // of calls to setTimeZone()
918 logln(UnicodeString("RGMT 3 is: ") + (t4
=cal3
->getTime(status
)));
922 errln("Fail: Calendar zone behavior faulty");
934 void CalendarRegressionTest::test4096539()
936 UErrorCode status
= U_ZERO_ERROR
;
937 int32_t y
[] = {31,28,31,30,31,30,31,31,30,31,30,31};
939 for (int32_t x
=0;x
<12;x
++) {
940 GregorianCalendar
*gc
= new
941 GregorianCalendar(1997,x
,y
[x
], status
);
942 if (U_FAILURE(status
)) {
943 dataerrln("Fail new GregorianCalendar: %s", u_errorName(status
));
948 log(UnicodeString("") + (m1
=gc
->get(UCAL_MONTH
,status
)+1)+UnicodeString("/")+
949 gc
->get(UCAL_DATE
,status
)+"/"+gc
->get(UCAL_YEAR
,status
)+
952 gc
->add(UCAL_MONTH
, 1,status
);
953 logln(UnicodeString("") + (m2
=gc
->get(UCAL_MONTH
,status
)+1)+UnicodeString("/")+
954 gc
->get(UCAL_DATE
,status
)+"/"+gc
->get(UCAL_YEAR
,status
)
956 int32_t m
= (m1
% 12) + 1;
958 errln(UnicodeString("Fail: Want ") + m
+ " Got " + m2
);
967 void CalendarRegressionTest::test41003112()
969 UErrorCode status
= U_ZERO_ERROR
;
970 GregorianCalendar
*cal
= (GregorianCalendar
*)Calendar::createInstance(status
);
971 if(U_FAILURE(status
)) {
972 dataerrln("Error creating calendar: %s", u_errorName(status
));
976 cal
->set(UCAL_YEAR
, 1997);
977 cal
->set(UCAL_DAY_OF_YEAR
, 1);
978 //UDate d = cal->getTime(status); // Should be Jan 1
979 //logln(d.toString());
980 if (cal
->get(UCAL_DAY_OF_YEAR
, status
) != 1)
981 errln("Fail: DAY_OF_YEAR not set");
988 void CalendarRegressionTest::test4103271()
990 UErrorCode status
= U_ZERO_ERROR
;
991 SimpleDateFormat
sdf(status
);
992 int32_t numYears
=40, startYear
=1997, numDays
=15;
993 UnicodeString output
, testDesc
, str
, str2
;
994 GregorianCalendar
*testCal
= (GregorianCalendar
*)Calendar::createInstance(status
);
995 if(U_FAILURE(status
)) {
996 dataerrln("Error creating calendar: %s", u_errorName(status
));
1001 sdf
.adoptCalendar(testCal
);
1002 sdf
.applyPattern("EEE dd MMM yyyy 'WOY'ww'-'YYYY 'DOY'DDD");
1004 for (int32_t firstDay
=1; firstDay
<=2; firstDay
++) {
1005 for (int32_t minDays
=1; minDays
<=7; minDays
++) {
1006 testCal
->setMinimalDaysInFirstWeek((uint8_t)minDays
);
1007 testCal
->setFirstDayOfWeek((UCalendarDaysOfWeek
)firstDay
);
1008 testDesc
= (UnicodeString("Test") + firstDay
+ minDays
);
1009 logln(testDesc
+ " => 1st day of week=" +
1011 ", minimum days in first week=" +
1013 for (int32_t j
=startYear
; j
<=startYear
+numYears
; j
++) {
1014 testCal
->set(j
,11,25);
1015 for(int32_t i
=0; i
<numDays
; i
++) {
1016 testCal
->add(UCAL_DATE
,1,status
);
1017 UnicodeString calWOY
;
1018 int32_t actWOY
= testCal
->get(UCAL_WEEK_OF_YEAR
,status
);
1019 if (actWOY
< 1 || actWOY
> 53) {
1020 UDate d
= testCal
->getTime(status
);
1021 //calWOY = String.valueOf(actWOY);
1023 FieldPosition
pos(FieldPosition::DONT_CARE
);
1024 output
= testDesc
+ " - " + sdf
.format(d
,temp
,pos
) + "\t";
1025 output
= output
+ "\t" + actWOY
;
1035 3, 52, 52, 52, 52, 52, 52, 52,
1036 1, 1, 1, 1, 1, 1, 1,
1037 2, 2, 2, 2, 2, 2, 2,
1038 4, 52, 52, 52, 52, 52, 52, 52,
1039 53, 53, 53, 53, 53, 53, 53,
1040 1, 1, 1, 1, 1, 1, 1,
1042 testCal
->setFirstDayOfWeek(UCAL_SUNDAY
);
1043 for (int32_t j
=0; j
<44; j
+=22) {
1044 logln(UnicodeString("Minimal days in first week = ") + DATA
[j
] +
1045 " Week starts on Sunday");
1046 testCal
->setMinimalDaysInFirstWeek((uint8_t)DATA
[j
]);
1047 testCal
->set(1997, UCAL_DECEMBER
, 21);
1048 for (int32_t i
=0; i
<21; ++i
) {
1049 int32_t woy
= testCal
->get(UCAL_WEEK_OF_YEAR
,status
);
1051 log(UnicodeString("") + sdf
.format(testCal
->getTime(status
), str
) +
1052 UnicodeString(" ") + woy
);
1053 if (woy
!= DATA
[j
+ 1 + i
]) {
1059 // Now compute the time from the fields, and make sure we
1060 // get the same answer back. This is a round-trip test.
1061 UDate save
= testCal
->getTime(status
);
1063 testCal
->set(UCAL_YEAR_WOY
, DATA
[j
+1+i
] < 25 ? 1998 : 1997);
1064 testCal
->set(UCAL_WEEK_OF_YEAR
, DATA
[j
+1+i
]);
1065 testCal
->set(UCAL_DAY_OF_WEEK
, (i%7
) + UCAL_SUNDAY
);
1066 if (testCal
->getTime(status
) != save
) {
1068 logln(UnicodeString(" Parse failed: ") +
1069 sdf
.format(testCal
->getTime(status
), str
));
1073 testCal
->setTime(save
,status
);
1074 testCal
->add(UCAL_DATE
, 1,status
);
1077 // Test field disambiguation with a few special hard-coded cases.
1078 // This shouldn't fail if the above cases aren't failing.
1079 int32_t DISAM_int
[] = {
1081 1997, 1998, 1, UCAL_SUNDAY
,
1082 (1998), (1998), (2), (UCAL_SATURDAY
),
1083 (1998), (1998), (53), (UCAL_THURSDAY
),
1084 (1999), (1998), (53), (UCAL_FRIDAY
)
1087 UDate DISAM_date
[] = {
1088 makeDate(1997, UCAL_DECEMBER
, 28),
1089 makeDate(1998, UCAL_JANUARY
, 10),
1090 makeDate(1998, UCAL_DECEMBER
, 31),
1091 makeDate(1999, UCAL_JANUARY
, 1)
1094 testCal
->setMinimalDaysInFirstWeek(3);
1095 testCal
->setFirstDayOfWeek(UCAL_SUNDAY
);
1098 /* Enable this code to display various WOY values
1100 for (i=25; i<38; ++i) {
1101 testCal->set(1996, 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(1997, Calendar::DECEMBER, i);
1108 UDate got = testCal->getTime(status);
1110 logln(UnicodeString("") + sdf.format(got, str));
1112 for (i=25; i<38; ++i) {
1113 testCal->set(1998, UCAL_DECEMBER, i);
1114 UDate got = testCal->getTime(status);
1116 logln(UnicodeString("") + sdf.format(got, str));
1120 for (i
=0; i
< 16; i
+= 4) {
1121 int32_t y
= DISAM_int
[i
];
1122 int32_t ywoy
= DISAM_int
[i
+1];
1123 int32_t woy
= DISAM_int
[i
+2];
1124 int32_t dow
= DISAM_int
[i
+3];
1125 UDate exp
= DISAM_date
[i
/4];
1127 testCal
->set(UCAL_YEAR
, y
);
1128 testCal
->set(UCAL_WEEK_OF_YEAR
, woy
);
1129 testCal
->set(UCAL_DAY_OF_WEEK
, dow
);
1130 UDate got
= testCal
->getTime(status
);
1133 log(UnicodeString("Y") + y
+ "-W" + woy
+
1134 "-DOW" + dow
+ " expect:" + sdf
.format(exp
, str
) +
1135 " got:" + sdf
.format(got
, str2
));
1137 log(" FAIL (%s:%d, i=%d)", __FILE__
, __LINE__
, i
);
1138 logln(CalendarTest::calToStr(*testCal
));
1139 testCal
->setTime(exp
, status
);
1140 logln(CalendarTest::calToStr(*testCal
) + UnicodeString( " <<< expected "));
1146 testCal
->set(UCAL_YEAR_WOY
, ywoy
);
1147 testCal
->set(UCAL_WEEK_OF_YEAR
, woy
);
1148 testCal
->set(UCAL_DAY_OF_WEEK
, dow
);
1149 got
= testCal
->getTime(status
);
1152 log(UnicodeString("YWOY") + ywoy
+ "-W" + woy
+
1153 "-DOW" + dow
+ " expect:" + sdf
.format(exp
, str
) +
1154 " got:" + sdf
.format(got
, str2
));
1161 // Now try adding and rolling
1162 UDate ADDROLL_date
[] = {
1163 makeDate(1998, UCAL_DECEMBER
, 25), makeDate(1999, UCAL_JANUARY
, 1),
1164 makeDate(1997, UCAL_DECEMBER
, 28), makeDate(1998, UCAL_JANUARY
, 4),
1165 makeDate(1998, UCAL_DECEMBER
, 27), makeDate(1997, UCAL_DECEMBER
, 28),
1166 makeDate(1999, UCAL_JANUARY
, 2), makeDate(1998, UCAL_JANUARY
, 3),
1169 int32_t ADDROLL_int
[]= {
1177 UBool ADDROLL_bool
[] = {
1184 testCal
->setMinimalDaysInFirstWeek(3);
1185 testCal
->setFirstDayOfWeek(UCAL_SUNDAY
);
1186 for (i
=0; i
<8; i
+= 2) {
1187 int32_t amount
= ADDROLL_int
[i
/2];
1188 UDate before
= ADDROLL_date
[i
];
1189 UDate after
= ADDROLL_date
[i
+1];
1191 testCal
->setTime(before
,status
);
1192 if (ADDROLL_bool
[i
/2])
1193 testCal
->add(UCAL_WEEK_OF_YEAR
, amount
,status
);
1195 testCal
->roll(UCAL_WEEK_OF_YEAR
, amount
,status
);
1196 UDate got
= testCal
->getTime(status
);
1199 UnicodeString opTypeStr
;
1200 if (ADDROLL_bool
[i
/2]) {
1201 opTypeStr
= UnicodeString("add(WOY,", "");
1203 opTypeStr
= UnicodeString("roll(WOY,", "");
1205 log(opTypeStr
+ amount
+ ") " + sdf
.format(before
, str
) + " => " +
1206 sdf
.format(got
, str2
));
1209 logln(UnicodeString(" exp:") + sdf
.format(after
, str
) + " FAIL");
1214 testCal
->setTime(after
,status
);
1215 if (ADDROLL_bool
[i
/2])
1216 testCal
->add(UCAL_WEEK_OF_YEAR
, -amount
,status
);
1218 testCal
->roll(UCAL_WEEK_OF_YEAR
, -amount
,status
);
1219 got
= testCal
->getTime(status
);
1222 log(opTypeStr
+ (-amount
) + ") " + sdf
.format(after
, str
) + " => " +
1223 sdf
.format(got
, str2
));
1224 if (before
!= got
) {
1226 logln(UnicodeString(" exp:") + sdf
.format(before
, str
) + " FAIL");
1232 errln("Fail: Week of year misbehaving");
1238 void CalendarRegressionTest::test4106136()
1240 UErrorCode status
= U_ZERO_ERROR
;
1241 Locale saveLocale
= Locale::getDefault();
1243 Locale locales
[] = { Locale::getChinese(), Locale::getChina() };
1244 for (int32_t i
=0; i
<2; ++i
) {
1245 Locale::setDefault(locales
[i
], status
);
1246 failure(status
, "Locale::setDefault");
1247 int32_t count1
, count2
, count3
;
1248 Calendar::getAvailableLocales(count1
);
1249 DateFormat::getAvailableLocales(count2
);
1250 NumberFormat::getAvailableLocales(count3
);
1252 count1
, count2
, count3
1254 for (int32_t j
=0; j
<3; ++j
) {
1257 dataerrln(UnicodeString("Fail: No locales for ") + locales
[i
].getName());
1262 Locale::setDefault(saveLocale
,status
);
1269 void CalendarRegressionTest::test4108764()
1271 UErrorCode status
= U_ZERO_ERROR
;
1272 Calendar
*cal
= Calendar::createInstance(status
);
1273 if(U_FAILURE(status
)) {
1274 dataerrln("Error creating calendar %s", u_errorName(status
));
1278 UDate d00
= makeDate(1997, UCAL_MARCH
, 15, 12, 00, 00);
1279 UDate d01
= makeDate(1997, UCAL_MARCH
, 15, 12, 00, 56);
1280 UDate d10
= makeDate(1997, UCAL_MARCH
, 15, 12, 34, 00);
1281 UDate d11
= makeDate(1997, UCAL_MARCH
, 15, 12, 34, 56);
1282 UDate epoch
= makeDate(1970, UCAL_JANUARY
, 1);
1284 cal
->setTime(d11
,status
);
1286 cal
->clear( UCAL_MINUTE
);
1287 logln(UnicodeString("") + cal
->getTime(status
));
1288 if (cal
->getTime(status
) != d01
)
1289 errln("Fail: clear(MINUTE) broken");
1291 cal
->set( UCAL_SECOND
, 0 );
1292 logln(UnicodeString("") + cal
->getTime(status
));
1293 if (cal
->getTime(status
) != d00
)
1294 errln("Fail: set(SECOND, 0) broken");
1296 cal
->setTime(d11
,status
);
1297 cal
->set( UCAL_SECOND
, 0 );
1298 logln(UnicodeString("") + cal
->getTime(status
));
1299 if (cal
->getTime(status
) != d10
)
1300 errln("Fail: set(SECOND, 0) broken #2");
1302 cal
->clear( UCAL_MINUTE
);
1303 logln(UnicodeString("") + cal
->getTime(status
));
1304 if (cal
->getTime(status
) != d00
)
1305 errln("Fail: clear(MINUTE) broken #2");
1308 logln(UnicodeString("") + cal
->getTime(status
));
1309 if (cal
->getTime(status
) != epoch
)
1310 errln(UnicodeString("Fail: clear() broken Want ") + epoch
);
1318 void CalendarRegressionTest::test4114578()
1320 UErrorCode status
= U_ZERO_ERROR
;
1321 double ONE_HOUR
= 60*60*1000;
1322 Calendar
*cal
= Calendar::createInstance(status
);
1323 if(U_FAILURE(status
)) {
1324 dataerrln("Error creating calendar %s", u_errorName(status
));
1328 cal
->adoptTimeZone(TimeZone::createTimeZone("PST"));
1329 UDate onset
= makeDate(1998, UCAL_APRIL
, 5, 1, 0) + ONE_HOUR
;
1330 UDate cease
= makeDate(1998, UCAL_OCTOBER
, 25, 0, 0) + 2*ONE_HOUR
;
1334 const int32_t ADD
= 1;
1335 const int32_t ROLL
= 2;
1338 // Start Action Amt Expected_change
1339 onset
- ONE_HOUR
, ADD
, 1, ONE_HOUR
,
1340 onset
, ADD
, -1, -ONE_HOUR
,
1341 onset
- ONE_HOUR
, ROLL
, 1, ONE_HOUR
,
1342 onset
, ROLL
, -1, -ONE_HOUR
,
1343 cease
- ONE_HOUR
, ADD
, 1, ONE_HOUR
,
1344 cease
, ADD
, -1, -ONE_HOUR
,
1345 cease
- ONE_HOUR
, ROLL
, 1, ONE_HOUR
,
1346 cease
, ROLL
, -1, -ONE_HOUR
,
1349 for (int32_t i
=0; i
<32; i
+=4) {
1350 UDate date
= DATA
[i
];
1351 int32_t amt
= (int32_t) DATA
[i
+2];
1352 double expectedChange
= DATA
[i
+3];
1354 log(UnicodeString("") + date
);
1355 cal
->setTime(date
,status
);
1357 switch ((int32_t) DATA
[i
+1]) {
1359 log(UnicodeString(" add (HOUR,") + (amt
<0?"":"+")+amt
+ ")= ");
1360 cal
->add(UCAL_HOUR
, amt
,status
);
1363 log(UnicodeString(" roll(HOUR,") + (amt
<0?"":"+")+amt
+ ")= ");
1364 cal
->roll(UCAL_HOUR
, amt
,status
);
1368 log(UnicodeString("") + cal
->getTime(status
));
1370 double change
= cal
->getTime(status
) - date
;
1371 if (change
!= expectedChange
) {
1378 if (fail
) errln("Fail: roll/add misbehaves around DST onset/cease");
1385 * Make sure maximum for HOUR field is 11, not 12.
1387 void CalendarRegressionTest::test4118384()
1389 UErrorCode status
= U_ZERO_ERROR
;
1390 Calendar
*cal
= Calendar::createInstance(status
);
1391 if(U_FAILURE(status
)) {
1392 dataerrln("Error creating calendar %s", u_errorName(status
));
1396 if (cal
->getMaximum(UCAL_HOUR
) != 11 ||
1397 cal
->getLeastMaximum(UCAL_HOUR
) != 11 ||
1398 cal
->getActualMaximum(UCAL_HOUR
,status
) != 11)
1399 errln("Fail: maximum of HOUR field should be 11");
1401 // test deprecated functions
1402 if (cal
->getLeastMaximum(Calendar::HOUR
) != 11 ||
1403 cal
->getMaximum(Calendar::HOUR
) != 11) {
1404 errln("Fail: [deprecated functions] maximum of HOUR field should be 11\n");
1407 if (cal
->getGreatestMinimum(Calendar::HOUR
) != 0 ||
1408 cal
->getMinimum(Calendar::HOUR
) != 0) {
1409 errln("Fail: [deprecated functions] minimum of HOUR field should be 1\n");
1413 cal
= Calendar::createInstance(Locale("th_TH@calendar=buddhist"),status
);
1414 if(U_FAILURE(status
)) {
1415 dataerrln("Error creating calendar %s", u_errorName(status
));
1419 // test deprecated functions
1420 if (cal
->getLeastMaximum(Calendar::HOUR
) != 11 ||
1421 cal
->getMaximum(Calendar::HOUR
) != 11) {
1422 errln("Fail: Buddhist:[deprecated functions] maximum of HOUR field should be 11\n");
1425 if (cal
->getGreatestMinimum(Calendar::HOUR
) != 0 ||
1426 cal
->getMinimum(Calendar::HOUR
) != 0) {
1427 errln("Fail: Buddhist:[deprecated functions] minimum of HOUR field should be 1\n");
1431 // test deprecated functions
1432 cal
= Calendar::createInstance(Locale("ja_JP@calendar=japanese"),status
);
1433 if(U_FAILURE(status
)) {
1434 dataerrln("Error creating calendar %s", u_errorName(status
));
1438 if (cal
->getLeastMaximum(Calendar::HOUR
) != 11 ||
1439 cal
->getMaximum(Calendar::HOUR
) != 11) {
1440 errln("Fail: Japanese:[deprecated functions] maximum of HOUR field should be 11\n");
1443 if (cal
->getGreatestMinimum(Calendar::HOUR
) != 0 ||
1444 cal
->getMinimum(Calendar::HOUR
) != 0) {
1445 errln("Fail: Japanese:[deprecated functions] minimum of HOUR field should be 1\n");
1453 * Check isLeapYear for BC years.
1455 void CalendarRegressionTest::test4125881()
1457 UErrorCode status
= U_ZERO_ERROR
;
1458 GregorianCalendar
*cal
= (GregorianCalendar
*) Calendar::createInstance(status
);
1459 if(U_FAILURE(status
)) {
1460 dataerrln("Error creating calendar %s", u_errorName(status
));
1464 DateFormat
*fmt
= new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"),status
);
1465 if(U_FAILURE(status
)) {
1466 dataerrln("Error creating SimpleDateFormat - %s", u_errorName(status
));
1471 for (int32_t y
=-20; y
<=10; ++y
) {
1472 cal
->set(UCAL_ERA
, y
< 1 ? GregorianCalendar::BC
: GregorianCalendar::AD
);
1473 cal
->set(UCAL_YEAR
, y
< 1 ? 1 - y
: y
);
1475 logln(UnicodeString("") + y
+ UnicodeString(" = ") + fmt
->format(cal
->getTime(status
), temp
) + " " +
1476 cal
->isLeapYear(y
));
1477 if (cal
->isLeapYear(y
) != ((y
+40)%4
== 0))
1478 errln("Leap years broken");
1487 * Prove that GregorianCalendar is proleptic (it used to cut off
1488 * at 45 BC, and not have leap years before then).
1490 void CalendarRegressionTest::test4125892() {
1491 UErrorCode status
= U_ZERO_ERROR
;
1492 GregorianCalendar
*cal
= (GregorianCalendar
*) Calendar::createInstance(status
);
1493 if(U_FAILURE(status
)) {
1494 dataerrln("Error creating calendar %s", u_errorName(status
));
1498 DateFormat
*fmt
= new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"),status
);
1499 if(U_FAILURE(status
)) {
1500 dataerrln("Error creating SimpleDateFormat - %s", u_errorName(status
));
1505 cal
->set(UCAL_ERA
, GregorianCalendar::BC
);
1506 cal
->set(UCAL_YEAR
, 81); // 81 BC is a leap year (proleptically)
1507 cal
->set(UCAL_MONTH
, UCAL_FEBRUARY
);
1508 cal
->set(UCAL_DATE
, 28);
1509 cal
->add(UCAL_DATE
, 1,status
);
1510 if(U_FAILURE(status
))
1511 errln("add(DATE,1) failed");
1512 if (cal
->get(UCAL_DATE
,status
) != 29 ||
1513 !cal
->isLeapYear(-80)) // -80 == 81 BC
1514 errln("Calendar not proleptic");
1522 * GregorianCalendar::equals() ignores cutover date
1524 void CalendarRegressionTest::test4141665()
1526 UErrorCode status
= U_ZERO_ERROR
;
1527 GregorianCalendar
*cal
= new GregorianCalendar(status
);
1528 if(U_FAILURE(status
)) {
1529 dataerrln("Error creating calendar %s", u_errorName(status
));
1533 GregorianCalendar
*cal2
= (GregorianCalendar
*)cal
->clone();
1534 UDate cut
= cal
->getGregorianChange();
1535 UDate cut2
= cut
+ 100*24*60*60*1000.0; // 100 days later
1536 if (*cal
!= *cal2
) {
1537 errln("Cloned GregorianCalendars not equal");
1539 cal2
->setGregorianChange(cut2
,status
);
1540 if ( *cal
== *cal2
) {
1541 errln("GregorianCalendar::equals() ignores cutover");
1550 * Bug states that ArrayIndexOutOfBoundsException is thrown by GregorianCalendar::roll()
1551 * when IllegalArgumentException should be.
1553 void CalendarRegressionTest::test4142933()
1555 UErrorCode status
= U_ZERO_ERROR
;
1556 GregorianCalendar
*calendar
= new GregorianCalendar(status
);
1557 if(U_FAILURE(status
)) {
1558 dataerrln("Error creating calendar %s", u_errorName(status
));
1563 calendar
->roll((UCalendarDateFields
)-1, TRUE
, status
);
1564 if(U_SUCCESS(status
))
1565 errln("Test failed, no exception thrown");
1567 //catch (IllegalArgumentException e) {
1569 // logln("Test passed");
1571 //catch (Exception e) {
1572 //errln("Test failed. Unexpected exception is thrown: " + e);
1573 //e.printStackTrace();
1581 * GregorianCalendar handling of Dates Long.MIN_VALUE and Long.MAX_VALUE is
1582 * confusing; unless the time zone has a raw offset of zero, one or the
1583 * other of these will wrap. We've modified the test given in the bug
1584 * report to therefore only check the behavior of a calendar with a zero raw
1587 void CalendarRegressionTest::test4145158()
1589 UErrorCode status
= U_ZERO_ERROR
;
1590 GregorianCalendar
*calendar
= new GregorianCalendar(status
);
1591 if(status
== U_USING_FALLBACK_WARNING
|| U_FAILURE(status
)) {
1592 dataerrln("Error creating calendar %s", u_errorName(status
));
1597 calendar
->adoptTimeZone(TimeZone::createTimeZone("GMT"));
1599 calendar
->setTime(makeDate(INT32_MIN
),status
);
1600 int32_t year1
= calendar
->get(UCAL_YEAR
,status
);
1601 int32_t era1
= calendar
->get(UCAL_ERA
,status
);
1603 calendar
->setTime(makeDate(INT32_MAX
),status
);
1604 int32_t year2
= calendar
->get(UCAL_YEAR
,status
);
1605 int32_t era2
= calendar
->get(UCAL_ERA
,status
);
1607 if (year1
== year2
&& era1
== era2
) {
1608 errln("Fail: Long.MIN_VALUE or Long.MAX_VALUE wrapping around");
1616 * Maximum value for YEAR field wrong.
1618 // {sfb} this is not directly applicable in C++, since all
1619 // possible doubles are not representable by our Calendar.
1620 // In Java, all longs are representable.
1621 // We can determine limits programmatically
1622 // Using DBL_MAX is a bit of a hack, since for large doubles
1623 // Calendar gets squirrely and doesn't behave in any sort
1624 // of linear fashion (ie years jump around, up/down, etc) for a
1625 // small change in millis.
1626 void CalendarRegressionTest::test4145983()
1628 UErrorCode status
= U_ZERO_ERROR
;
1629 GregorianCalendar
*calendar
= new GregorianCalendar(status
);
1630 if(U_FAILURE(status
)) {
1631 dataerrln("Error creating calendar %s", u_errorName(status
));
1635 calendar
->adoptTimeZone(TimeZone::createTimeZone("GMT"));
1636 UDate DATES
[] = { LATEST_SUPPORTED_MILLIS
, EARLIEST_SUPPORTED_MILLIS
};
1637 for (int32_t i
=0; i
<2; ++i
) {
1638 calendar
->setTime(DATES
[i
], status
);
1639 int32_t year
= calendar
->get(UCAL_YEAR
,status
);
1640 int32_t maxYear
= calendar
->getMaximum(UCAL_YEAR
);
1641 if (year
> maxYear
) {
1642 errln(UnicodeString("Failed for ")+DATES
[i
]+" ms: year=" +
1643 year
+ ", maxYear=" + maxYear
);
1652 * This is a bug in the validation code of GregorianCalendar:: As reported,
1653 * the bug seems worse than it really is, due to a bug in the way the bug
1654 * report test was written. In reality the bug is restricted to the DAY_OF_YEAR
1655 * field. - liu 6/29/98
1657 void CalendarRegressionTest::test4147269()
1659 UErrorCode status
= U_ZERO_ERROR
;
1660 GregorianCalendar
*calendar
= new GregorianCalendar(status
);
1661 if(status
== U_USING_FALLBACK_WARNING
|| U_FAILURE(status
)) {
1662 dataerrln("Error creating calendar %s", u_errorName(status
));
1666 calendar
->setLenient(FALSE
);
1667 UDate date
= makeDate(1996, UCAL_JANUARY
, 3); // Arbitrary date
1668 for (int32_t field
= 0; field
< UCAL_FIELD_COUNT
; field
++) {
1669 calendar
->setTime(date
,status
);
1670 // Note: In the bug report, getActualMaximum() was called instead
1671 // of getMaximum() -- this was an error. The validation code doesn't
1672 // use getActualMaximum(), since that's too costly.
1673 int32_t max
= calendar
->getMaximum((UCalendarDateFields
)field
);
1674 int32_t value
= max
+1;
1675 calendar
->set((UCalendarDateFields
)field
, value
);
1677 calendar
->getTime(status
); // Force time computation
1678 // We expect an exception to be thrown. If we fall through
1679 // to the next line, then we have a bug.
1680 if(U_SUCCESS(status
))
1681 errln(UnicodeString("Test failed with field ") + FIELD_NAME
[field
] +
1682 ", date before: " + date
+
1683 ", date after: " + calendar
->getTime(status
) +
1684 ", value: " + value
+ " (max = " + max
+")");
1685 //} catch (IllegalArgumentException e) {}
1693 * Reported bug is that a GregorianCalendar with a cutover of Date(Long.MAX_VALUE)
1694 * doesn't behave as a pure Julian calendar.
1695 * CANNOT REPRODUCE THIS BUG
1698 CalendarRegressionTest::Test4149677()
1700 UErrorCode status
= U_ZERO_ERROR
;
1702 TimeZone
*zones
[] = {
1703 TimeZone::createTimeZone("GMT"),
1704 TimeZone::createTimeZone("PST"),
1705 TimeZone::createTimeZone("EAT")
1707 if(U_FAILURE(status
)) {
1708 errln("Couldn't create zones");
1710 // could leak memory
1713 for (int32_t i
=0; i
< 3; ++i
) {
1714 GregorianCalendar
*calendar
= new GregorianCalendar(zones
[i
], status
);
1715 if(U_FAILURE(status
)) {
1716 dataerrln("Couldnt' create calendar.: %s", u_errorName(status
));
1720 // Make sure extreme values don't wrap around
1721 calendar
->setTime(EARLIEST_SUPPORTED_MILLIS
, status
);
1722 if(U_FAILURE(status
))
1723 errln("setTime failed");
1724 if (calendar
->get(UCAL_ERA
, status
) != GregorianCalendar::BC
|| U_FAILURE(status
)) {
1725 errln("Fail: Date(EARLIEST_SUPPORTED_MILLIS) has an AD year");
1727 calendar
->setTime(LATEST_SUPPORTED_MILLIS
, status
);
1728 if(U_FAILURE(status
))
1729 errln("setTime failed");
1730 if (calendar
->get(UCAL_ERA
, status
) != GregorianCalendar::AD
|| U_FAILURE(status
)) {
1731 errln("Fail: Date(LATEST_SUPPORTED_MILLIS) has a BC year");
1734 calendar
->setGregorianChange(LATEST_SUPPORTED_MILLIS
, status
);
1735 if(U_FAILURE(status
))
1736 errln("setGregorianChange failed");
1737 // to obtain a pure Julian calendar
1739 UBool is100Leap
= calendar
->isLeapYear(100);
1742 errln("test failed with zone " + zones
[i
]->getID(temp
));
1743 errln(" cutover date is Date(Long.MAX_VALUE)");
1744 errln(UnicodeString(" isLeapYear(100) returns: ") + is100Leap
);
1749 // no need for cleanup- zones were adopted
1754 * Calendar and Date HOUR broken. If HOUR is out-of-range, Calendar
1755 * and Date classes will misbehave.
1758 CalendarRegressionTest::Test4162587()
1760 UErrorCode status
= U_ZERO_ERROR
;
1761 TimeZone
*savedef
= TimeZone::createDefault();
1762 TimeZone
*tz
= TimeZone::createTimeZone("PST");
1763 //TimeZone::adoptDefault(tz);
1764 TimeZone::setDefault(*tz
);
1766 GregorianCalendar
*cal
= new GregorianCalendar(tz
, status
);
1767 if(U_FAILURE(status
)) {
1768 dataerrln("Couldn't create calendar.: %s", u_errorName(status
));
1771 UDate d0
, dPlus
, dMinus
;
1773 for(int32_t i
=0; i
<5; ++i
) {
1774 if (i
>0) logln("---");
1777 cal
->set(1998, UCAL_APRIL
, 5, i
, 0);
1778 d0
= cal
->getTime(status
);
1779 if(U_FAILURE(status
))
1780 errln("Coudln't get time (1)");
1781 //String s0 = d.toString();
1782 logln(UnicodeString("0 ") + i
+ ": " + d0
/*s0*/);
1785 cal
->set(1998, UCAL_APRIL
, 4, i
+24, 0);
1786 dPlus
= cal
->getTime(status
);
1787 if(U_FAILURE(status
))
1788 errln("Coudln't get time (2)");
1789 //String sPlus = d.toString();
1790 logln(UnicodeString("+ ") + i
+ ": " + dPlus
/*sPlus*/);
1793 cal
->set(1998, UCAL_APRIL
, 6, i
-24, 0);
1794 dMinus
= cal
->getTime(status
);
1795 if(U_FAILURE(status
))
1796 errln("Coudln't get time (3)");
1797 //String sMinus = d.toString();
1798 logln(UnicodeString("- ") + i
+ ": " + dMinus
/*sMinus*/);
1800 if (d0
!= dPlus
|| d0
!= dMinus
) {
1801 errln("Fail: All three lines must match");
1804 TimeZone::setDefault(*savedef
);
1812 * Adding 12 months behaves differently from adding 1 year
1815 CalendarRegressionTest::Test4165343()
1817 UErrorCode status
= U_ZERO_ERROR
;
1818 GregorianCalendar
*calendar
= new GregorianCalendar(1996, UCAL_FEBRUARY
, 29, status
);
1819 if(U_FAILURE(status
)) {
1820 dataerrln("Couldn't create calendar.: %s", u_errorName(status
));
1823 UDate start
= calendar
->getTime(status
);
1824 if(U_FAILURE(status
))
1825 errln("Couldn't getTime (1)");
1826 logln(UnicodeString("init date: ") + start
);
1827 calendar
->add(UCAL_MONTH
, 12, status
);
1828 if(U_FAILURE(status
))
1829 errln("Couldn't add(MONTH, 12)");
1830 UDate date1
= calendar
->getTime(status
);
1831 if(U_FAILURE(status
))
1832 errln("Couldn't getTime (2)");
1833 logln(UnicodeString("after adding 12 months: ") + date1
);
1834 calendar
->setTime(start
, status
);
1835 if(U_FAILURE(status
))
1836 errln("Couldn't setTime");
1837 calendar
->add(UCAL_YEAR
, 1, status
);
1838 if(U_FAILURE(status
))
1839 errln("Couldn't add(YEAR, 1)");
1840 UDate date2
= calendar
->getTime(status
);
1841 if(U_FAILURE(status
))
1842 errln("Couldn't getTime (3)");
1843 logln(UnicodeString("after adding one year : ") + date2
);
1844 if (date1
== date2
) {
1845 logln("Test passed");
1847 errln("Test failed");
1854 * GregorianCalendar.getActualMaximum() does not account for first day of week.
1857 CalendarRegressionTest::Test4166109()
1862 * Su Mo Tu We Th Fr Sa
1864 * 8 9 10 11 12 13 14
1865 * 15 16 17 18 19 20 21
1866 * 22 23 24 25 26 27 28
1869 UBool passed
= TRUE
;
1870 UErrorCode status
= U_ZERO_ERROR
;
1871 UCalendarDateFields field
= UCAL_WEEK_OF_MONTH
;
1873 GregorianCalendar
*calendar
= new GregorianCalendar(Locale::getUS(), status
);
1874 if(U_FAILURE(status
)) {
1875 dataerrln("Couldn't create calendar.: %s", u_errorName(status
));
1878 calendar
->set(1998, UCAL_MARCH
, 1);
1879 calendar
->setMinimalDaysInFirstWeek(1);
1880 logln(UnicodeString("Date: ") + calendar
->getTime(status
)); // 888817448000
1882 int32_t firstInMonth
= calendar
->get(UCAL_DATE
, status
);
1883 if(U_FAILURE(status
))
1884 errln("get(D_O_M) failed");
1886 for(int32_t firstInWeek
= UCAL_SUNDAY
; firstInWeek
<= UCAL_SATURDAY
; firstInWeek
++) {
1887 calendar
->setFirstDayOfWeek((UCalendarDaysOfWeek
)firstInWeek
);
1888 int32_t returned
= calendar
->getActualMaximum(field
, status
);
1889 int32_t expected
= (31 + ((firstInMonth
- firstInWeek
+ 7)% 7) + 6) / 7;
1891 logln(UnicodeString("First day of week = ") + firstInWeek
+
1892 " getActualMaximum(WEEK_OF_MONTH, status) = " + returned
+
1893 " expected = " + expected
+
1894 ((returned
== expected
) ? " ok" : " FAIL"));
1896 if (returned
!= expected
) {
1901 errln("Test failed");
1909 * Calendar.getActualMaximum(YEAR) works wrong.
1912 CalendarRegressionTest::Test4167060()
1914 UErrorCode status
= U_ZERO_ERROR
;
1915 UCalendarDateFields field
= UCAL_YEAR
;
1916 DateFormat
*format
= new SimpleDateFormat(UnicodeString("EEE MMM dd HH:mm:ss zzz yyyy G"),
1917 Locale::getUS(), status
);
1918 if(U_FAILURE(status
)) {
1919 dataerrln("Couldn't create SimpleDateFormat - %s", u_errorName(status
));
1923 GregorianCalendar
*calendars
[] = {
1924 new GregorianCalendar(100, UCAL_NOVEMBER
, 1, status
),
1925 new GregorianCalendar(-99 /*100BC*/, UCAL_JANUARY
, 1, status
),
1926 new GregorianCalendar(1996, UCAL_FEBRUARY
, 29, status
),
1928 if(U_FAILURE(status
)) {
1929 errln("Couldn't create GregorianCalendars");
1934 UnicodeString id
[] = { "Hybrid", "Gregorian", "Julian" };
1936 for (int32_t k
=0; k
<3; ++k
) {
1937 logln("--- " + id
[k
] + " ---");
1939 for (int32_t j
=0; j
< 3; ++j
) {
1940 GregorianCalendar
*calendar
= calendars
[j
];
1942 calendar
->setGregorianChange(EARLIEST_SUPPORTED_MILLIS
, status
);
1945 calendar
->setGregorianChange(LATEST_SUPPORTED_MILLIS
, status
);
1948 if(U_FAILURE(status
))
1949 errln("setGregorianChange() failed");
1950 format
->adoptCalendar((Calendar
*)calendar
->clone());
1952 UDate dateBefore
= calendar
->getTime(status
);
1953 if(U_FAILURE(status
))
1954 errln("getTime() failed");
1956 int32_t maxYear
= calendar
->getActualMaximum(field
, status
);
1958 logln(UnicodeString("maxYear: ") + maxYear
+ " for " + format
->format(calendar
->getTime(status
), temp
));
1960 logln("date before: " + format
->format(dateBefore
, temp
));
1962 int32_t years
[] = {2000, maxYear
-1, maxYear
, maxYear
+1};
1964 for (int32_t i
= 0; i
< 4; i
++) {
1965 UBool valid
= years
[i
] <= maxYear
;
1966 calendar
->set(field
, years
[i
]);
1967 UDate dateAfter
= calendar
->getTime(status
);
1968 if(U_FAILURE(status
))
1969 errln("getTime() failed");
1970 int32_t newYear
= calendar
->get(field
, status
);
1971 if(U_FAILURE(status
))
1972 errln(UnicodeString("get(") + (int32_t)field
+ ") failed");
1973 calendar
->setTime(dateBefore
, status
); // restore calendar for next use
1974 if(U_FAILURE(status
))
1975 errln("setTime() failed");
1978 logln(UnicodeString(" Year ") + years
[i
] + (valid
? " ok " : " bad") +
1979 " => " + format
->format(dateAfter
, temp
));
1980 if (valid
&& newYear
!= years
[i
]) {
1981 errln(UnicodeString(" FAIL: ") + newYear
+ " should be valid; date, month and time shouldn't change");
1983 // {sfb} this next line is a hack, but it should work since if a
1984 // double has an exponent, adding 1 should not yield the same double
1985 else if (!valid
&& /*newYear == years[i]*/ dateAfter
+ 1.0 == dateAfter
) {
1986 errln(UnicodeString(" FAIL: ") + newYear
+ " should be invalid");
1993 delete calendars
[0];
1994 delete calendars
[1];
1995 delete calendars
[2];
1999 * Week of year is wrong at the start and end of the year.
2001 void CalendarRegressionTest::Test4197699() {
2002 UErrorCode status
= U_ZERO_ERROR
;
2003 GregorianCalendar
cal(status
);
2004 cal
.setFirstDayOfWeek(UCAL_MONDAY
);
2005 cal
.setMinimalDaysInFirstWeek(4);
2006 SimpleDateFormat
fmt("E dd MMM yyyy 'DOY='D 'WOY='w",
2007 Locale::getUS(), status
);
2008 fmt
.setCalendar(cal
);
2009 if (U_FAILURE(status
)) {
2010 dataerrln("Couldn't initialize test - %s", u_errorName(status
));
2015 2000, UCAL_JANUARY
, 1, 52,
2016 2001, UCAL_DECEMBER
, 31, 1,
2018 int32_t DATA_length
= UPRV_LENGTHOF(DATA
);
2021 DateFormat
& dfmt
= *(DateFormat
*)&fmt
;
2022 for (int32_t i
=0; i
<DATA_length
; ) {
2024 cal
.set(DATA
[i
], DATA
[i
+1], DATA
[i
+2]);
2026 int32_t expWOY
= DATA
[i
++];
2027 int32_t actWOY
= cal
.get(UCAL_WEEK_OF_YEAR
, status
);
2028 if (expWOY
== actWOY
) {
2029 logln(UnicodeString("Ok: ") + dfmt
.format(cal
.getTime(status
), str
.remove()));
2031 errln(UnicodeString("FAIL: ") + dfmt
.format(cal
.getTime(status
), str
.remove())
2032 + ", expected WOY=" + expWOY
);
2033 cal
.add(UCAL_DATE
, -8, status
);
2034 for (int j
=0; j
<14; ++j
) {
2035 cal
.add(UCAL_DATE
, 1, status
);
2036 logln(dfmt
.format(cal
.getTime(status
), str
.remove()));
2039 if (U_FAILURE(status
)) {
2040 errln("FAIL: Unexpected error from Calendar");
2046 enum Action
{ ADD
=1, ROLL
=2 };
2047 enum Sign
{ PLUS
=1, MINUS
=2 };
2049 #define ONE_HOUR (60*60*1000)
2050 #define ONE_DAY (24*ONE_HOUR)
2053 UCalendarDateFields field
;
2054 int8_t actionMask
; // ADD or ROLL or both
2055 int8_t signMask
; // PLUS or MINUS or both
2057 int32_t before
; // ms before cutover
2058 int32_t after
; // ms after cutover
2062 * Rolling and adding across the Gregorian cutover should work as expected.
2065 void CalendarRegressionTest::TestJ81() {
2066 UErrorCode status
= U_ZERO_ERROR
;
2067 UnicodeString temp
, temp2
, temp3
;
2069 GregorianCalendar
cal(TimeZone::createTimeZone("GMT"), Locale::getUS(), status
);
2070 SimpleDateFormat
fmt("HH:mm 'w'w 'd'D E d MMM yyyy", Locale::getUS(), status
);
2071 if (U_FAILURE(status
)) {
2072 dataerrln("Error: Cannot create calendar or format - %s", u_errorName(status
));
2075 fmt
.setCalendar(cal
);
2076 // Get the Gregorian cutover
2077 UDate cutover
= cal
.getGregorianChange();
2078 UDate days
= ONE_DAY
;
2079 days
= cutover
/days
;
2080 logln(UnicodeString("Cutover: {") +
2081 fmt
.format(cutover
, temp
) + "}(epoch days-" + (int)days
+ ", jd" + (2440588 + days
) +")");
2083 // Check woy and doy handling. Reference data:
2084 /* w40 d274 Mon 1 Oct 1582
2085 w40 d275 Tue 2 Oct 1582
2086 w40 d276 Wed 3 Oct 1582
2087 w40 d277 Thu 4 Oct 1582
2088 w40 d278 Fri 15 Oct 1582
2089 w40 d279 Sat 16 Oct 1582
2090 w41 d280 Sun 17 Oct 1582
2091 w41 d281 Mon 18 Oct 1582
2092 w41 d282 Tue 19 Oct 1582
2093 w41 d283 Wed 20 Oct 1582
2094 w41 d284 Thu 21 Oct 1582
2095 w41 d285 Fri 22 Oct 1582
2096 w41 d286 Sat 23 Oct 1582
2097 w42 d287 Sun 24 Oct 1582
2098 w42 d288 Mon 25 Oct 1582
2099 w42 d289 Tue 26 Oct 1582
2100 w42 d290 Wed 27 Oct 1582
2101 w42 d291 Thu 28 Oct 1582
2102 w42 d292 Fri 29 Oct 1582
2103 w42 d293 Sat 30 Oct 1582
2104 w43 d294 Sun 31 Oct 1582
2105 w43 d295 Mon 1 Nov 1582 */
2106 int32_t DOY_DATA
[] = {
2108 1, 40, 274, UCAL_MONDAY
,
2109 4, 40, 277, UCAL_THURSDAY
,
2110 15, 40, 278, UCAL_FRIDAY
,
2111 17, 41, 280, UCAL_SUNDAY
,
2112 24, 42, 287, UCAL_SUNDAY
,
2113 25, 42, 288, UCAL_MONDAY
,
2114 26, 42, 289, UCAL_TUESDAY
,
2115 27, 42, 290, UCAL_WEDNESDAY
,
2116 28, 42, 291, UCAL_THURSDAY
,
2117 29, 42, 292, UCAL_FRIDAY
,
2118 30, 42, 293, UCAL_SATURDAY
,
2119 31, 43, 294, UCAL_SUNDAY
2121 int32_t DOY_DATA_length
= UPRV_LENGTHOF(DOY_DATA
);
2123 for (i
=0; i
<DOY_DATA_length
; i
+=4) {
2124 // Test time->fields
2125 cal
.set(1582, UCAL_OCTOBER
, DOY_DATA
[i
]);
2126 int32_t woy
= cal
.get(UCAL_WEEK_OF_YEAR
, status
);
2127 int32_t doy
= cal
.get(UCAL_DAY_OF_YEAR
, status
);
2128 int32_t dow
= cal
.get(UCAL_DAY_OF_WEEK
, status
);
2129 if (U_FAILURE(status
)) {
2130 errln("Error: get() failed");
2133 if (woy
!= DOY_DATA
[i
+1] || doy
!= DOY_DATA
[i
+2] || dow
!= DOY_DATA
[i
+3]) {
2134 errln((UnicodeString
)"Fail: expect woy=" + DOY_DATA
[i
+1] +
2135 ", doy=" + DOY_DATA
[i
+2] + ", dow=" + DOY_DATA
[i
+3] + " on " +
2136 fmt
.format(cal
.getTime(status
), temp
.remove()) +
2137 " set(1582,OCTOBER, " + DOY_DATA
[i
] + ")");
2138 logln(CalendarTest::calToStr(cal
));
2139 status
= U_ZERO_ERROR
;
2141 logln((UnicodeString
)"PASS: expect woy=" + DOY_DATA
[i
+1] +
2142 ", doy=" + DOY_DATA
[i
+2] + ", dow=" + DOY_DATA
[i
+3] + " on " +
2143 fmt
.format(cal
.getTime(status
), temp
.remove()));
2144 logln(CalendarTest::calToStr(cal
));
2145 status
= U_ZERO_ERROR
;
2147 // Test fields->time for WOY
2149 cal
.set(UCAL_YEAR
, 1582);
2150 cal
.set(UCAL_WEEK_OF_YEAR
, DOY_DATA
[i
+1]);
2151 cal
.set(UCAL_DAY_OF_WEEK
, DOY_DATA
[i
+3]);
2152 int32_t dom
= cal
.get(UCAL_DATE
, status
);
2153 if (U_FAILURE(status
)) {
2154 errln("Error: get() failed");
2157 if (dom
!= DOY_DATA
[i
]) {
2158 errln((UnicodeString
)"Fail: set woy=" + DOY_DATA
[i
+1] +
2159 " dow=" + DOY_DATA
[i
+3] + " => " +
2160 fmt
.format(cal
.getTime(status
), temp
.remove()) +
2161 ", expected 1582 Oct " + DOY_DATA
[i
]);
2162 logln(CalendarTest::calToStr(cal
));
2163 status
= U_ZERO_ERROR
;
2166 // Test fields->time for DOY
2168 cal
.set(UCAL_YEAR
, 1582);
2169 cal
.set(UCAL_DAY_OF_YEAR
, DOY_DATA
[i
+2]);
2170 dom
= cal
.get(UCAL_DATE
, status
);
2171 if (U_FAILURE(status
)) {
2172 errln("Error: get() failed");
2175 if (dom
!= DOY_DATA
[i
]) {
2176 errln((UnicodeString
)"Fail: set doy=" + DOY_DATA
[i
+2] +
2178 fmt
.format(cal
.getTime(status
), temp
.remove()) +
2179 ", expected 1582 Oct " + DOY_DATA
[i
]);
2180 status
= U_ZERO_ERROR
;
2183 status
= U_ZERO_ERROR
;
2185 #define ADD_ROLL ADD|ROLL
2186 #define PLUS_MINUS PLUS|MINUS
2189 { UCAL_WEEK_OF_YEAR
, ADD_ROLL
, PLUS_MINUS
, 1, -ONE_DAY
, +6*ONE_DAY
},
2190 { UCAL_WEEK_OF_YEAR
, ADD_ROLL
, PLUS_MINUS
, 1, -ONE_DAY
, +6*ONE_DAY
},
2191 { UCAL_WEEK_OF_MONTH
, ADD
|ROLL
, PLUS
|MINUS
, 1, -ONE_DAY
, +6*ONE_DAY
},
2192 { UCAL_DATE
, ADD
|ROLL
, PLUS
|MINUS
, 2, -ONE_DAY
, +1*ONE_DAY
},
2193 { UCAL_DATE
, ROLL
, PLUS
, -6, -ONE_DAY
, +14*ONE_DAY
},
2194 { UCAL_DATE
, ROLL
, PLUS
, -7, 0, +14*ONE_DAY
},
2195 { UCAL_DATE
, ROLL
, PLUS
, -7, +ONE_DAY
, +15*ONE_DAY
},
2196 { UCAL_DATE
, ROLL
, PLUS
, +18, -ONE_DAY
, -4*ONE_DAY
},
2197 { UCAL_DAY_OF_YEAR
, ADD
|ROLL
, PLUS
|MINUS
, 2, -ONE_DAY
, +1*ONE_DAY
},
2198 { UCAL_DAY_OF_WEEK
, ADD
|ROLL
, PLUS
|MINUS
, 2, -ONE_DAY
, +1*ONE_DAY
},
2199 { UCAL_DAY_OF_WEEK_IN_MONTH
, ADD
|ROLL
, PLUS
|MINUS
, 1, -ONE_DAY
, +6*ONE_DAY
},
2200 { UCAL_AM_PM
, ADD
, PLUS
|MINUS
, 4, -12*ONE_HOUR
, +36*ONE_HOUR
},
2201 { UCAL_HOUR
, ADD
, PLUS
|MINUS
, 48, -12*ONE_HOUR
, +36*ONE_HOUR
},
2202 { UCAL_HOUR_OF_DAY
, ADD
, PLUS
|MINUS
, 48, -12*ONE_HOUR
, +36*ONE_HOUR
},
2203 { UCAL_MINUTE
, ADD
, PLUS
|MINUS
, 48*60, -12*ONE_HOUR
, +36*ONE_HOUR
},
2204 { UCAL_SECOND
, ADD
, PLUS
|MINUS
, 48*60*60, -12*ONE_HOUR
, +36*ONE_HOUR
},
2205 { UCAL_MILLISECOND
, ADD
, PLUS
|MINUS
, 48*ONE_HOUR
, -12*ONE_HOUR
, +36*ONE_HOUR
},
2206 // NOTE: These are not supported yet. See jitterbug 180.
2207 // Uncomment these lines when add/roll supported on these fields.
2208 // { Calendar::YEAR_WOY, ADD|ROLL, 1, -ONE_DAY, +6*ONE_DAY },
2209 // { Calendar::DOW_LOCAL, ADD|ROLL, 2, -ONE_DAY, +1*ONE_DAY }
2211 int32_t DATA_length
= UPRV_LENGTHOF(DATA
);
2213 // Now run the tests
2214 for (i
=0; i
<DATA_length
; ++i
) {
2215 for (Action action
=ADD
; action
<=ROLL
; action
=(Action
)(action
+1)) {
2216 if (!(DATA
[i
].actionMask
& action
)) {
2219 for (Sign sign
=PLUS
; sign
<=MINUS
; sign
=(Sign
)(sign
+1)) {
2220 if (!(DATA
[i
].signMask
& sign
)) {
2223 status
= U_ZERO_ERROR
;
2224 int32_t amount
= DATA
[i
].amount
* (sign
==MINUS
?-1:1);
2225 UDate date
= cutover
+
2226 (sign
==PLUS
? DATA
[i
].before
: DATA
[i
].after
);
2227 UDate expected
= cutover
+
2228 (sign
==PLUS
? DATA
[i
].after
: DATA
[i
].before
);
2229 cal
.setTime(date
, status
);
2230 if (U_FAILURE(status
)) {
2231 errln((UnicodeString
)"FAIL: setTime returned error code " + u_errorName(status
));
2234 if (action
== ADD
) {
2235 cal
.add(DATA
[i
].field
, amount
, status
);
2237 cal
.roll(DATA
[i
].field
, amount
, status
);
2239 if (U_FAILURE(status
)) {
2240 errln((UnicodeString
)"FAIL: " +
2241 (action
==ADD
?"add ":"roll ") + FIELD_NAME
[DATA
[i
].field
] +
2242 " returned error code " + u_errorName(status
));
2245 UDate result
= cal
.getTime(status
);
2246 if (U_FAILURE(status
)) {
2247 errln((UnicodeString
)"FAIL: getTime returned error code " + u_errorName(status
));
2250 if (result
== expected
) {
2251 logln((UnicodeString
)"Ok: {" +
2252 fmt
.format(date
, temp
.remove()) +
2253 "}(" + date
/ONE_DAY
+
2254 (action
==ADD
?") add ":") roll ") +
2255 amount
+ " " + FIELD_NAME
[DATA
[i
].field
] + " -> {" +
2256 fmt
.format(result
, temp2
.remove()) +
2257 "}(" + result
/ONE_DAY
+ ")");
2259 errln((UnicodeString
)"FAIL: {" +
2260 fmt
.format(date
, temp
.remove()) +
2261 "}(" + date
/ONE_DAY
+
2262 (action
==ADD
?") add ":") roll ") +
2263 amount
+ " " + FIELD_NAME
[DATA
[i
].field
] + " -> {" +
2264 fmt
.format(result
, temp2
.remove()) +
2265 "}(" + result
/ONE_DAY
+ "), expect {" +
2266 fmt
.format(expected
, temp3
.remove()) +
2267 "}(" + expected
/ONE_DAY
+ ")");
2275 * Test fieldDifference().
2277 void CalendarRegressionTest::TestJ438(void) {
2278 UErrorCode ec
= U_ZERO_ERROR
;
2280 2000, UCAL_JANUARY
, 20, 2010, UCAL_JUNE
, 15,
2281 2010, UCAL_JUNE
, 15, 2000, UCAL_JANUARY
, 20,
2282 1964, UCAL_SEPTEMBER
, 7, 1999, UCAL_JUNE
, 4,
2283 1999, UCAL_JUNE
, 4, 1964, UCAL_SEPTEMBER
, 7,
2285 int32_t DATA_length
= UPRV_LENGTHOF(DATA
);
2286 Calendar
* pcal
= Calendar::createInstance(Locale::getUS(), ec
);
2288 dataerrln("Error creating calendar %s", u_errorName(ec
));
2292 Calendar
& cal
= *pcal
;
2294 SimpleDateFormat
fmt(UnicodeString("MMM dd yyyy",""), ec
);
2295 fmt
.setCalendar(cal
);
2296 UnicodeString s
, t
, u
;
2297 if (U_SUCCESS(ec
)) {
2298 for (i
=0; i
<DATA_length
; i
+=6) {
2299 int32_t y1
= DATA
[i
];
2300 int32_t m1
= DATA
[i
+1];
2301 int32_t d1
= DATA
[i
+2];
2302 int32_t y2
= DATA
[i
+3];
2303 int32_t m2
= DATA
[i
+4];
2304 int32_t d2
= DATA
[i
+5];
2307 cal
.set(y1
, m1
, d1
);
2308 UDate date1
= cal
.getTime(ec
);
2309 if (failure(ec
, "getTime"))
2311 cal
.set(y2
, m2
, d2
);
2312 UDate date2
= cal
.getTime(ec
);
2313 if (failure(ec
, "getTime"))
2316 cal
.setTime(date1
, ec
);
2317 if (failure(ec
, "setTime"))
2319 int32_t dy
= cal
.fieldDifference(date2
, UCAL_YEAR
, ec
);
2320 int32_t dm
= cal
.fieldDifference(date2
, UCAL_MONTH
, ec
);
2321 int32_t dd
= cal
.fieldDifference(date2
, UCAL_DATE
, ec
);
2322 if (failure(ec
, "fieldDifference"))
2326 Calendar
*cal2
= cal
.clone();
2327 UErrorCode ec2
= U_ZERO_ERROR
;
2329 cal2
->setTime(date1
, ec2
);
2331 int32_t dy2
= cal2
->fieldDifference(date2
, Calendar::YEAR
, ec2
);
2332 int32_t dm2
= cal2
->fieldDifference(date2
, Calendar::MONTH
, ec2
);
2333 int32_t dd2
= cal2
->fieldDifference(date2
, Calendar::DATE
, ec2
);
2334 if (failure(ec2
, "fieldDifference(date, Calendar::DATE, ec)"))
2339 errln("fieldDifference(UCAL_...) and fieldDifference(Calendar::...) give different results!\n");
2345 logln(UnicodeString("") +
2346 fmt
.format(date2
, s
.remove()) + " - " +
2347 fmt
.format(date1
, t
.remove()) + " = " +
2348 dy
+ "y " + dm
+ "m " + dd
+ "d");
2350 cal
.setTime(date1
, ec
);
2351 if (failure(ec
, "setTime"))
2353 cal
.add(UCAL_YEAR
, dy
, ec
);
2354 cal
.add(UCAL_MONTH
, dm
, ec
);
2355 cal
.add(UCAL_DATE
, dd
, ec
);
2356 if (failure(ec
, "add"))
2358 UDate date22
= cal
.getTime(ec
);
2359 if (failure(ec
, "getTime"))
2361 if (date2
!= date22
) {
2362 errln(UnicodeString("FAIL: ") +
2363 fmt
.format(date1
, s
.remove()) + " + " +
2364 dy
+ "y " + dm
+ "m " + dd
+ "d = " +
2365 fmt
.format(date22
, t
.remove()) + ", exp " +
2366 fmt
.format(date2
, u
.remove()));
2368 logln(UnicodeString("Ok: ") +
2369 fmt
.format(date1
, s
.remove()) + " + " +
2370 dy
+ "y " + dm
+ "m " + dd
+ "d = " +
2371 fmt
.format(date22
, t
.remove()));
2375 dataerrln("Error creating SimpleDateFormat - %s", u_errorName(ec
));
2380 void CalendarRegressionTest::TestT5555()
2382 UErrorCode ec
= U_ZERO_ERROR
;
2383 Calendar
*cal
= Calendar::createInstance(ec
);
2385 if (cal
== NULL
|| U_FAILURE(ec
)) {
2386 dataerrln("FAIL: Calendar::createInstance(): %s", u_errorName(ec
));
2391 // Set to Wednesday, February 21, 2007
2392 cal
->set(2007, UCAL_FEBRUARY
, 21);
2394 // Advance three years
2395 cal
->add(UCAL_MONTH
, 36, ec
);
2397 // Set to last Wednesday of the month
2398 cal
->set(UCAL_DAY_OF_WEEK_IN_MONTH
, -1);
2402 int32_t yy
, mm
, dd
, ee
;
2404 yy
= cal
->get(UCAL_YEAR
, ec
);
2405 mm
= cal
->get(UCAL_MONTH
, ec
);
2406 dd
= cal
->get(UCAL_DATE
, ec
);
2407 ee
= cal
->get(UCAL_DAY_OF_WEEK
, ec
);
2409 // Should be set to Wednesday, February 24, 2010
2410 if (U_FAILURE(ec
) || yy
!= 2010 || mm
!= UCAL_FEBRUARY
|| dd
!= 24 || ee
!= UCAL_WEDNESDAY
) {
2411 errln("FAIL: got date %4d/%02d/%02d, expected 210/02/24: ", yy
, mm
+ 1, dd
);
2418 int32_t startMonth
; // 0-based
2419 int32_t startDay
; // 1-based
2420 UCalendarDateFields fieldToChange
;
2423 int32_t endMonth
; // 0-based
2424 int32_t endDay
; // 1-based
2425 } CoptEthCalTestItem
;
2427 // year 1724 in coptic calendar =
2428 // year 2000 in ethiopic calendar (276 more than coptic) =
2429 // year 7500 in ethiopic-amete-alem calendar (5776 more than coptic)
2430 // (2007-2008 in gregorian calendar depending on month)
2431 static const CoptEthCalTestItem coptEthCalTestItems
[] = {
2432 { 1724, 12, 1, UCAL_MONTH
, +1, 1725, 0, 1 },
2433 { 1724, 12, 1, UCAL_MONTH
, +9, 1725, 8, 1 },
2434 { 1723, 12, 2, UCAL_MONTH
, +1, 1724, 0, 2 }, // 1723 is a leap year
2435 { 1723, 12, 2, UCAL_MONTH
, +9, 1724, 8, 2 },
2436 { 1725, 0, 1, UCAL_MONTH
, -1, 1724, 12, 1 },
2437 { 1725, 0, 1, UCAL_MONTH
, -6, 1724, 7, 1 },
2438 { 1724, 12, 1, UCAL_DATE
, +8, 1725, 0, 4 },
2439 { 1723, 12, 1, UCAL_DATE
, +8, 1724, 0, 3 }, // 1723 is a leap year
2440 { 1724, 0, 1, UCAL_DATE
, -1, 1723, 12, 6 }, // 1723 is a leap year
2441 { 0, 0, 0, (UCalendarDateFields
)0, 0, 0, 0, 0 } // terminator
2445 const char * locale
;
2449 static const CoptEthCalLocale copEthCalLocales
[] = {
2450 { "en@calendar=coptic", 0 },
2451 { "en@calendar=ethiopic", 276 },
2452 { NULL
, 0 } // terminator
2455 void CalendarRegressionTest::TestT6745()
2457 const CoptEthCalLocale
* testLocalePtr
;
2458 for ( testLocalePtr
= copEthCalLocales
; testLocalePtr
->locale
!= NULL
; ++testLocalePtr
) {
2459 UErrorCode status
= U_ZERO_ERROR
;
2460 Calendar
*cal
= Calendar::createInstance(Locale(testLocalePtr
->locale
), status
);
2461 if ( U_FAILURE(status
) ) {
2462 dataerrln((UnicodeString
)"FAIL: Calendar::createInstance, locale " + testLocalePtr
->locale
+ ", status " + u_errorName(status
));
2465 const CoptEthCalTestItem
* testItemPtr
;
2466 for (testItemPtr
= coptEthCalTestItems
; testItemPtr
->fieldDelta
!= 0; ++testItemPtr
) {
2467 status
= U_ZERO_ERROR
;
2468 cal
->set( testItemPtr
->startYear
+ testLocalePtr
->yearOffset
, testItemPtr
->startMonth
, testItemPtr
->startDay
, 9, 0 );
2469 cal
->add( testItemPtr
->fieldToChange
, testItemPtr
->fieldDelta
, status
);
2470 if ( U_FAILURE(status
) ) {
2471 errln((UnicodeString
)"FAIL: Calendar::add, locale " + testLocalePtr
->locale
+ ", field/delta " +
2472 testItemPtr
->fieldToChange
+ "/" + testItemPtr
->fieldDelta
+ ", status " + u_errorName(status
));
2475 int32_t endYear
= testItemPtr
->endYear
+ testLocalePtr
->yearOffset
;
2476 int32_t year
= cal
->get(UCAL_YEAR
, status
);
2477 int32_t month
= cal
->get(UCAL_MONTH
, status
);
2478 int32_t day
= cal
->get(UCAL_DATE
, status
);
2479 if ( U_FAILURE(status
) || year
!= endYear
|| month
!= testItemPtr
->endMonth
|| day
!= testItemPtr
->endDay
) {
2480 errln((UnicodeString
)"ERROR: Calendar::add, locale " + testLocalePtr
->locale
+ ", field/delta " +
2481 testItemPtr
->fieldToChange
+ "/" + testItemPtr
->fieldDelta
+ ", status " + u_errorName(status
) +
2482 ", expected " + endYear
+ "/" + testItemPtr
->endMonth
+ "/" + testItemPtr
->endDay
+
2483 ", got " + year
+ "/" + month
+ "/" + day
);
2491 * Test behavior of fieldDifference around leap years. Also test a large
2492 * field difference to check binary search.
2494 void CalendarRegressionTest::TestLeapFieldDifference() {
2495 UErrorCode ec
= U_ZERO_ERROR
;
2496 Calendar
* cal
= Calendar::createInstance(ec
);
2497 if (cal
== NULL
|| U_FAILURE(ec
)) {
2498 dataerrln("FAIL: Calendar::createInstance(): %s", u_errorName(ec
));
2502 cal
->set(2004, UCAL_FEBRUARY
, 29);
2503 UDate date2004
= cal
->getTime(ec
);
2504 cal
->set(2000, UCAL_FEBRUARY
, 29);
2505 UDate date2000
= cal
->getTime(ec
);
2506 if (U_FAILURE(ec
)) {
2507 errln("FAIL: getTime()");
2511 int32_t y
= cal
->fieldDifference(date2004
, UCAL_YEAR
, ec
);
2512 int32_t d
= cal
->fieldDifference(date2004
, UCAL_DAY_OF_YEAR
, ec
);
2513 if (U_FAILURE(ec
)) {
2514 errln("FAIL: fieldDifference()");
2519 logln((UnicodeString
)"Ok: 2004/Feb/29 - 2000/Feb/29 = " + y
+ " years, " + d
+ " days");
2521 errln((UnicodeString
)"FAIL: 2004/Feb/29 - 2000/Feb/29 = " + y
+ " years, " + d
+ " days");
2523 cal
->setTime(date2004
, ec
);
2524 y
= cal
->fieldDifference(date2000
, UCAL_YEAR
, ec
);
2525 d
= cal
->fieldDifference(date2000
, UCAL_DAY_OF_YEAR
, ec
);
2526 if (U_FAILURE(ec
)) {
2527 errln("FAIL: setTime() / fieldDifference()");
2532 logln((UnicodeString
)"Ok: 2000/Feb/29 - 2004/Feb/29 = " + y
+ " years, " + d
+ " days");
2534 errln((UnicodeString
)"FAIL: 2000/Feb/29 - 2004/Feb/29 = " + y
+ " years, " + d
+ " days");
2536 // Test large difference
2537 cal
->set(2001, UCAL_APRIL
, 5); // 2452005
2538 UDate ayl
= cal
->getTime(ec
);
2539 cal
->set(1964, UCAL_SEPTEMBER
, 7); // 2438646
2540 UDate asl
= cal
->getTime(ec
);
2541 if (U_FAILURE(ec
)) {
2542 errln("FAIL: getTime()");
2546 d
= cal
->fieldDifference(ayl
, UCAL_DATE
, ec
);
2547 cal
->setTime(ayl
, ec
);
2548 int32_t d2
= cal
->fieldDifference(asl
, UCAL_DATE
, ec
);
2549 if (U_FAILURE(ec
)) {
2550 errln("FAIL: setTime() / fieldDifference()");
2554 if (d
== -d2
&& d
== 13359) {
2555 logln((UnicodeString
)"Ok: large field difference symmetrical " + d
);
2557 logln((UnicodeString
)"FAIL: large field difference incorrect " + d
+ ", " + d2
+
2558 ", expect +/- 13359");
2564 * Test ms_MY "Malay (Malaysia)" locale. Bug 1543.
2566 void CalendarRegressionTest::TestMalaysianInstance() {
2567 Locale
loc("ms", "MY"); // Malay (Malaysia)
2568 UErrorCode ec
= U_ZERO_ERROR
;
2569 Calendar
* cal
= Calendar::createInstance(loc
, ec
);
2570 if (U_FAILURE(ec
)) {
2571 dataerrln("FAIL: Can't construct calendar for ms_MY: %s", u_errorName(ec
));
2577 * setFirstDayOfWeek and setMinimalDaysInFirstWeek may change the
2578 * field <=> time mapping, since they affect the interpretation of
2579 * the WEEK_OF_MONTH or WEEK_OF_YEAR fields.
2581 void CalendarRegressionTest::TestWeekShift() {
2582 UErrorCode ec
= U_ZERO_ERROR
;
2583 GregorianCalendar
cal(TimeZone::createTimeZone("America/Los_Angeles"),
2584 Locale("en", "US"), ec
);
2585 if (U_FAILURE(ec
)) {
2586 dataerrln("Fail GregorianCalendar: %s", u_errorName(ec
));
2589 cal
.setTime(UDate(997257600000.0), ec
); // Wed Aug 08 01:00:00 PDT 2001
2590 // In pass one, change the first day of week so that the weeks
2591 // shift in August 2001. In pass two, change the minimal days
2592 // in the first week so that the weeks shift in August 2001.
2594 // Su Mo Tu We Th Fr Sa
2597 // 12 13 14 15 16 17 18
2598 // 19 20 21 22 23 24 25
2599 // 26 27 28 29 30 31
2600 for (int32_t pass
=0; pass
<2; ++pass
) {
2602 cal
.setFirstDayOfWeek(UCAL_WEDNESDAY
);
2603 cal
.setMinimalDaysInFirstWeek(4);
2605 cal
.setFirstDayOfWeek(UCAL_SUNDAY
);
2606 cal
.setMinimalDaysInFirstWeek(4);
2608 cal
.add(UCAL_DATE
, 1, ec
); // Force recalc
2609 cal
.add(UCAL_DATE
, -1, ec
);
2611 UDate time1
= cal
.getTime(ec
); // Get time -- should not change
2613 // Now change a week parameter and then force a recalc.
2614 // The bug is that the recalc should not be necessary --
2615 // calendar should do so automatically.
2617 cal
.setFirstDayOfWeek(UCAL_THURSDAY
);
2619 cal
.setMinimalDaysInFirstWeek(5);
2622 int32_t woy1
= cal
.get(UCAL_WEEK_OF_YEAR
, ec
);
2623 int32_t wom1
= cal
.get(UCAL_WEEK_OF_MONTH
, ec
);
2625 cal
.add(UCAL_DATE
, 1, ec
); // Force recalc
2626 cal
.add(UCAL_DATE
, -1, ec
);
2628 int32_t woy2
= cal
.get(UCAL_WEEK_OF_YEAR
, ec
);
2629 int32_t wom2
= cal
.get(UCAL_WEEK_OF_MONTH
, ec
);
2631 UDate time2
= cal
.getTime(ec
);
2633 if (U_FAILURE(ec
)) {
2634 errln("FAIL: internal test error");
2638 if (time1
!= time2
) {
2639 errln("FAIL: shifting week should not alter time");
2643 if (woy1
== woy2
&& wom1
== wom2
) {
2644 logln((UnicodeString
)"Ok: WEEK_OF_YEAR: " + woy1
+
2645 ", WEEK_OF_MONTH: " + wom1
);
2647 errln((UnicodeString
)"FAIL: WEEK_OF_YEAR: " + woy1
+ " => " + woy2
+
2648 ", WEEK_OF_MONTH: " + wom1
+ " => " + wom2
+
2649 " after week shift");
2655 * Make sure that when adding a day, we actually wind up in a
2656 * different day. The DST adjustments we use to keep the hour
2657 * constant across DST changes can backfire and change the day.
2659 void CalendarRegressionTest::TestTimeZoneTransitionAdd() {
2660 UErrorCode ec
= U_ZERO_ERROR
;
2661 Locale
locale(Locale::getUS()); // could also be CHINA
2662 SimpleDateFormat
dateFormat("MM/dd/yyyy HH:mm z", locale
, ec
);
2664 StringEnumeration
*tz
= TimeZone::createEnumeration();
2666 dataerrln("FAIL: TimeZone::createEnumeration");
2670 UnicodeString buf1
, buf2
;
2673 while ((id
= tz
->unext(NULL
, ec
)) != NULL
&& U_SUCCESS(ec
)) {
2674 if (U_FAILURE(ec
)) {
2675 errln("FAIL: StringEnumeration::unext");
2679 TimeZone
*t
= TimeZone::createTimeZone(id
);
2681 errln("FAIL: TimeZone::createTimeZone");
2684 dateFormat
.setTimeZone(*t
);
2686 Calendar
*cal
= Calendar::createInstance(t
, locale
, ec
);
2687 if (cal
== NULL
|| U_FAILURE(ec
)) {
2688 errln("FAIL: Calendar::createTimeZone");
2694 // Scan the year 2003, overlapping the edges of the year
2695 cal
->set(UCAL_YEAR
, 2002);
2696 cal
->set(UCAL_MONTH
, UCAL_DECEMBER
);
2697 cal
->set(UCAL_DATE
, 25);
2699 for (int32_t i
=0; i
<365+10 && U_SUCCESS(ec
); ++i
) {
2700 UDate yesterday
= cal
->getTime(ec
);
2701 int32_t yesterday_day
= cal
->get(UCAL_DATE
, ec
);
2702 cal
->add(UCAL_DATE
, 1, ec
);
2703 if (yesterday_day
== cal
->get(UCAL_DATE
, ec
)) {
2704 errln(UnicodeString(id
) + " " +
2705 dateFormat
.format(yesterday
, buf1
) + " +1d= " +
2706 dateFormat
.format(cal
->getTime(ec
), buf2
));
2714 if (U_FAILURE(ec
)) {
2715 dataerrln("FAIL: %s", u_errorName(ec
));
2722 CalendarRegressionTest::makeDate(int32_t y
, int32_t m
, int32_t d
,
2723 int32_t hr
, int32_t min
, int32_t sec
)
2727 UErrorCode status
= U_ZERO_ERROR
;
2728 Calendar
*cal
= Calendar::createInstance(status
);
2731 cal
->set(UCAL_YEAR
, y
);
2733 if(m
!= 0) cal
->set(UCAL_MONTH
, m
);
2734 if(d
!= 0) cal
->set(UCAL_DATE
, d
);
2735 if(hr
!= 0) cal
->set(UCAL_HOUR
, hr
);
2736 if(min
!= 0) cal
->set(UCAL_MINUTE
, min
);
2737 if(sec
!= 0) cal
->set(UCAL_SECOND
, sec
);
2739 result
= cal
->getTime(status
);
2746 void CalendarRegressionTest::TestDeprecates(void)
2748 UErrorCode status
= U_ZERO_ERROR
;
2749 Calendar
*c1
= Calendar::createInstance("ja_JP@calendar=japanese",status
);
2750 Calendar
*c2
= Calendar::createInstance("ja_JP@calendar=japanese",status
);
2752 if(!c1
|| !c2
|| U_FAILURE(status
)) {
2753 dataerrln("Couldn't create calendars for roll of HOUR: %s", u_errorName(status
));
2757 c2
->set(UCAL_HOUR
,2);
2758 c1
->setTime(c2
->getTime(status
),status
);
2761 c1
->roll(Calendar::HOUR
,(int32_t)3,status
);
2762 c2
->roll(UCAL_HOUR
,(int32_t)3,status
);
2764 if(U_FAILURE(status
)) {
2765 errln("Error code when trying to roll");
2766 } else if(*c1
!= *c2
) {
2767 errln("roll(EDateField, int32_t) had different effect than roll(UCalendarField, int32_t)");
2770 c1
->setTime(c2
->getTime(status
),status
);
2771 c1
->roll(Calendar::HOUR
,(UBool
)FALSE
,status
);
2772 c2
->roll(UCAL_HOUR
,(UBool
)FALSE
,status
);
2774 if(U_FAILURE(status
)) {
2775 errln("Error code when trying to roll(UBool)");
2776 } else if(*c1
!= *c2
) {
2777 errln("roll(EDateField, UBool) had different effect than roll(UCalendarField, UBool)");
2783 status
= U_ZERO_ERROR
;
2785 c1
= Calendar::createInstance("th_TH@calendar=buddhist",status
);
2786 c2
= Calendar::createInstance("th_TH@calendar=buddhist",status
);
2788 if(!c1
|| !c2
|| U_FAILURE(status
)) {
2789 errln("Couldn't create calendars for add of HOUR");
2793 c2
->set(UCAL_HOUR
,2);
2794 c1
->setTime(c2
->getTime(status
),status
);
2797 c1
->add(Calendar::HOUR
,(int32_t)1,status
);
2799 if(U_FAILURE(status
)) {
2800 errln("Error code when trying to add Calendar::HOUR - %s", u_errorName(status
));
2803 c2
->add(UCAL_HOUR
,(int32_t)1,status
);
2805 if(U_FAILURE(status
)) {
2806 errln("Error code when trying to add - UCAL_HOUR %s", u_errorName(status
));
2807 } else if(*c1
!= *c2
) {
2808 errln("add(EDateField) had different effect than add(UCalendarField)");
2814 status
= U_ZERO_ERROR
;
2816 c1
= Calendar::createInstance("es_ES",status
);
2817 c2
= Calendar::createInstance("es_ES",status
);
2819 if(!c1
|| !c2
|| U_FAILURE(status
)) {
2820 errln("Couldn't create calendars for add of YEAR");
2824 c2
->set(UCAL_YEAR
,1900);
2825 c1
->setTime(c2
->getTime(status
),status
);
2828 c1
->add(Calendar::YEAR
,(int32_t)9,status
);
2829 c2
->add(UCAL_YEAR
,(int32_t)9,status
);
2831 if(U_FAILURE(status
)) {
2832 errln("Error code when trying to add YEARs");
2833 } else if(*c1
!= *c2
) {
2834 errln("add(EDateField YEAR) had different effect than add(UCalendarField YEAR)");
2842 void CalendarRegressionTest::TestT8057(void) {
2843 // Set the calendar to the last day in a leap year
2844 UErrorCode status
= U_ZERO_ERROR
;
2845 GregorianCalendar
*cal
= (GregorianCalendar
*)Calendar::createInstance(status
);
2846 if(U_FAILURE(status
)) {
2847 errln("Error creating Calendar: %s", u_errorName(status
));
2851 cal
->setLenient(FALSE
);
2853 cal
->set(2008, UCAL_DECEMBER
, 31);
2855 // Force calculating then fields once.
2856 UDate t
= cal
->getTime(status
);
2857 if(U_FAILURE(status
)) {
2858 errln("Error while calculating the date");
2863 UDate expected
= 1262246400000.0; // 2009-12-31 00:00 PST
2865 cal
->add(UCAL_YEAR
, 1, status
);
2866 t
= cal
->getTime(status
);
2867 if (U_SUCCESS(status
)) {
2868 if (t
!= expected
) {
2869 dataerrln((UnicodeString
)"FAIL: wrong date after add: expected=" + expected
+ " returned=" + t
);
2872 errln("FAIL: error while adding one year");
2878 // Test case for ticket#8596.
2879 // Setting an year followed by getActualMaximum(Calendar.WEEK_OF_YEAR)
2880 // may result wrong maximum week.
2881 void CalendarRegressionTest::TestT8596(void) {
2882 UErrorCode status
= U_ZERO_ERROR
;
2883 GregorianCalendar
*gc
= new GregorianCalendar(*TimeZone::getGMT(), status
);
2885 if (U_FAILURE(status
)) {
2886 dataerrln("Error creating Calendar: %s", u_errorName(status
));
2891 gc
->setFirstDayOfWeek(UCAL_MONDAY
);
2892 gc
->setMinimalDaysInFirstWeek(4);
2894 // Force the calender to resolve the fields once.
2895 // The maximum week number in 2011 is 52.
2896 gc
->set(UCAL_YEAR
, 2011);
2897 gc
->get(UCAL_YEAR
, status
);
2899 // Set a date in year 2009, but not calling get to resolve
2900 // the calendar's internal field yet.
2901 gc
->set(2009, UCAL_JULY
, 1);
2903 // Then call getActuamMaximum for week of year.
2904 // #8596 was caused by conflict between year set
2905 // above and internal work calendar field resolution.
2906 int32_t maxWeeks
= gc
->getActualMaximum(UCAL_WEEK_OF_YEAR
, status
);
2908 if (U_FAILURE(status
)) {
2909 errln("Error calendar calculation: %s", u_errorName(status
));
2914 if (maxWeeks
!= 53) {
2915 errln((UnicodeString
)"FAIL: Max week in 2009 in ISO calendar is 53, but got " + maxWeeks
);
2921 // Test case for ticket 9452
2922 // Calendar addition fall onto the missing date - 2011-12-30 in Samoa
2923 void CalendarRegressionTest::TestT9452(void) {
2924 UErrorCode status
= U_ZERO_ERROR
;
2925 GregorianCalendar
cal(TimeZone::createTimeZone("Pacific/Apia"), status
);
2926 failure(status
, "initializing GregorianCalendar");
2928 SimpleDateFormat
sdf(UnicodeString("y-MM-dd'T'HH:mm:ssZZZZZ"), status
);
2929 failure(status
, "initializing SimpleDateFormat");
2930 sdf
.setCalendar(cal
);
2934 // Set date to 2011-12-29 00:00
2936 cal
.set(2011, UCAL_DECEMBER
, 29, 0, 0, 0);
2938 UDate d
= cal
.getTime(status
);
2939 if (!failure(status
, "getTime for initial date")) {
2940 sdf
.format(d
, dstr
);
2941 logln(UnicodeString("Initial date: ") + dstr
);
2944 cal
.add(UCAL_DATE
, 1, status
);
2945 failure(status
, "add 1 day");
2946 d
= cal
.getTime(status
);
2947 failure(status
, "getTime after +1 day");
2949 sdf
.format(d
, dstr
);
2950 logln(UnicodeString("+1 day: ") + dstr
);
2951 assertEquals("Add 1 day", UnicodeString("2011-12-31T00:00:00+14:00"), dstr
);
2954 cal
.add(UCAL_DATE
, -1, status
);
2955 failure(status
, "subtract 1 day");
2956 d
= cal
.getTime(status
);
2957 failure(status
, "getTime after -1 day");
2959 sdf
.format(d
, dstr
);
2960 logln(UnicodeString("-1 day: ") + dstr
);
2961 assertEquals("Subtract 1 day", UnicodeString("2011-12-29T00:00:00-10:00"), dstr
);
2968 void CalendarRegressionTest::TestT11632(void) {
2969 UErrorCode status
= U_ZERO_ERROR
;
2970 GregorianCalendar
cal(TimeZone::createTimeZone("Pacific/Apia"), status
);
2971 if(U_FAILURE(status
)) {
2972 dataerrln("Error creating Calendar: %s", u_errorName(status
));
2975 failure(status
, "Calendar::createInstance(status)");
2977 failure(status
, "clear calendar");
2978 cal
.set(UCAL_HOUR
, 597);
2979 failure(status
, "set hour value in calendar");
2980 SimpleDateFormat
sdf(UnicodeString("y-MM-dd'T'HH:mm:ss"), status
);
2981 failure(status
, "initializing SimpleDateFormat");
2982 sdf
.setCalendar(cal
);
2984 UDate d
= cal
.getTime(status
);
2985 if (!failure(status
, "getTime for date")) {
2986 sdf
.format(d
, dstr
);
2988 dstr
.toUTF8String(utf8
);
2989 assertEquals("correct datetime displayed for hour value", UnicodeString("1970-01-25T21:00:00"), dstr
);
2991 failure(status
, "clear calendar");
2992 cal
.set(UCAL_HOUR
, 300);
2993 failure(status
, "set hour value in calendar");
2994 sdf
.setCalendar(cal
);
2995 d
= cal
.getTime(status
);
2996 if (!failure(status
, "getTime for initial date")) {
2998 sdf
.format(d
, dstr
);
2999 dstr
.toUTF8String(utf8
);
3000 assertEquals("correct datetime displayed for hour value", UnicodeString("1970-01-13T12:00:00"), dstr
);
3008 void CalendarRegressionTest::TestPersianCalOverflow(void) {
3009 const char* localeID
= "bs_Cyrl@calendar=persian";
3010 UErrorCode status
= U_ZERO_ERROR
;
3011 Calendar
* cal
= Calendar::createInstance(Locale(localeID
), status
);
3012 if(U_FAILURE(status
)) {
3013 dataerrln("FAIL: Calendar::createInstance for localeID %s: %s", localeID
, u_errorName(status
));
3015 int32_t maxMonth
= cal
->getMaximum(UCAL_MONTH
);
3016 int32_t maxDayOfMonth
= cal
->getMaximum(UCAL_DATE
);
3017 int32_t jd
, month
, dayOfMonth
;
3018 for (jd
= 67023580; jd
<= 67023584; jd
++) { // year 178171, int32_t overflow if jd >= 67023582
3019 status
= U_ZERO_ERROR
;
3021 cal
->set(UCAL_JULIAN_DAY
, jd
);
3022 month
= cal
->get(UCAL_MONTH
, status
);
3023 dayOfMonth
= cal
->get(UCAL_DATE
, status
);
3024 if ( U_FAILURE(status
) ) {
3025 errln("FAIL: Calendar->get MONTH/DATE for localeID %s, julianDay %d, status %s", localeID
, jd
, u_errorName(status
));
3026 } else if (month
> maxMonth
|| dayOfMonth
> maxDayOfMonth
) {
3027 errln("FAIL: localeID %s, julianDay %d; maxMonth %d, got month %d; maxDayOfMonth %d, got dayOfMonth %d",
3028 localeID
, jd
, maxMonth
, month
, maxDayOfMonth
, dayOfMonth
);
3036 * @bug tickets 12661, 13538
3038 void CalendarRegressionTest::TestIslamicCalOverflow(void) {
3039 const char* localeID
= "ar@calendar=islamic-civil";
3040 UErrorCode status
= U_ZERO_ERROR
;
3041 Calendar
* cal
= Calendar::createInstance(Locale(localeID
), status
);
3042 if(U_FAILURE(status
)) {
3043 dataerrln("FAIL: Calendar::createInstance for localeID %s: %s", localeID
, u_errorName(status
));
3045 int32_t maxMonth
= cal
->getMaximum(UCAL_MONTH
);
3046 int32_t maxDayOfMonth
= cal
->getMaximum(UCAL_DATE
);
3047 int32_t jd
, year
, month
, dayOfMonth
;
3048 for (jd
= 73530872; jd
<= 73530876; jd
++) { // year 202002, int32_t overflow if jd >= 73530874
3049 status
= U_ZERO_ERROR
;
3051 cal
->set(UCAL_JULIAN_DAY
, jd
);
3052 year
= cal
->get(UCAL_YEAR
, status
);
3053 month
= cal
->get(UCAL_MONTH
, status
);
3054 dayOfMonth
= cal
->get(UCAL_DATE
, status
);
3055 if ( U_FAILURE(status
) ) {
3056 errln("FAIL: Calendar->get YEAR/MONTH/DATE for localeID %s, julianDay %d, status %s", localeID
, jd
, u_errorName(status
));
3057 } else if (month
> maxMonth
|| dayOfMonth
> maxDayOfMonth
) {
3058 errln("FAIL: localeID %s, julianDay %d; got year %d; maxMonth %d, got month %d; maxDayOfMonth %d, got dayOfMonth %d",
3059 localeID
, jd
, year
, maxMonth
, month
, maxDayOfMonth
, dayOfMonth
);
3066 void CalendarRegressionTest::TestWeekOfYear13548(void) {
3067 int32_t year
= 2000;
3068 UErrorCode status
= U_ZERO_ERROR
;
3069 LocalPointer
<Calendar
> cal(Calendar::createInstance(status
));
3070 failure(status
, "Calendar::createInstance(status)");
3072 cal
->set(UCAL_YEAR
, year
);
3073 cal
->set(UCAL_WEEK_OF_YEAR
, 4);
3075 int32_t resultYear
= cal
->get(UCAL_YEAR
, status
);
3076 failure(status
, "get(UCAL_YEAR, status)");
3077 if (year
!= resultYear
) {
3078 errln((UnicodeString
)"Fail: Expected year=" + year
+ ", actual=" + resultYear
);
3082 #endif /* #if !UCONFIG_NO_FORMATTING */