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 // test deprecated functions
1415 if (cal
->getLeastMaximum(Calendar::HOUR
) != 11 ||
1416 cal
->getMaximum(Calendar::HOUR
) != 11) {
1417 errln("Fail: Buddhist:[deprecated functions] maximum of HOUR field should be 11\n");
1420 if (cal
->getGreatestMinimum(Calendar::HOUR
) != 0 ||
1421 cal
->getMinimum(Calendar::HOUR
) != 0) {
1422 errln("Fail: Buddhist:[deprecated functions] minimum of HOUR field should be 1\n");
1426 // test deprecated functions
1427 cal
= Calendar::createInstance(Locale("ja_JP@calendar=japanese"),status
);
1428 if (cal
->getLeastMaximum(Calendar::HOUR
) != 11 ||
1429 cal
->getMaximum(Calendar::HOUR
) != 11) {
1430 errln("Fail: Japanese:[deprecated functions] maximum of HOUR field should be 11\n");
1433 if (cal
->getGreatestMinimum(Calendar::HOUR
) != 0 ||
1434 cal
->getMinimum(Calendar::HOUR
) != 0) {
1435 errln("Fail: Japanese:[deprecated functions] minimum of HOUR field should be 1\n");
1443 * Check isLeapYear for BC years.
1445 void CalendarRegressionTest::test4125881()
1447 UErrorCode status
= U_ZERO_ERROR
;
1448 GregorianCalendar
*cal
= (GregorianCalendar
*) Calendar::createInstance(status
);
1449 if(U_FAILURE(status
)) {
1450 dataerrln("Error creating calendar %s", u_errorName(status
));
1454 DateFormat
*fmt
= new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"),status
);
1455 if(U_FAILURE(status
)) {
1456 dataerrln("Error creating SimpleDateFormat - %s", u_errorName(status
));
1461 for (int32_t y
=-20; y
<=10; ++y
) {
1462 cal
->set(UCAL_ERA
, y
< 1 ? GregorianCalendar::BC
: GregorianCalendar::AD
);
1463 cal
->set(UCAL_YEAR
, y
< 1 ? 1 - y
: y
);
1465 logln(UnicodeString("") + y
+ UnicodeString(" = ") + fmt
->format(cal
->getTime(status
), temp
) + " " +
1466 cal
->isLeapYear(y
));
1467 if (cal
->isLeapYear(y
) != ((y
+40)%4
== 0))
1468 errln("Leap years broken");
1477 * Prove that GregorianCalendar is proleptic (it used to cut off
1478 * at 45 BC, and not have leap years before then).
1480 void CalendarRegressionTest::test4125892() {
1481 UErrorCode status
= U_ZERO_ERROR
;
1482 GregorianCalendar
*cal
= (GregorianCalendar
*) Calendar::createInstance(status
);
1483 if(U_FAILURE(status
)) {
1484 dataerrln("Error creating calendar %s", u_errorName(status
));
1488 DateFormat
*fmt
= new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"),status
);
1489 if(U_FAILURE(status
)) {
1490 dataerrln("Error creating SimpleDateFormat - %s", u_errorName(status
));
1495 cal
->set(UCAL_ERA
, GregorianCalendar::BC
);
1496 cal
->set(UCAL_YEAR
, 81); // 81 BC is a leap year (proleptically)
1497 cal
->set(UCAL_MONTH
, UCAL_FEBRUARY
);
1498 cal
->set(UCAL_DATE
, 28);
1499 cal
->add(UCAL_DATE
, 1,status
);
1500 if(U_FAILURE(status
))
1501 errln("add(DATE,1) failed");
1502 if (cal
->get(UCAL_DATE
,status
) != 29 ||
1503 !cal
->isLeapYear(-80)) // -80 == 81 BC
1504 errln("Calendar not proleptic");
1512 * GregorianCalendar::equals() ignores cutover date
1514 void CalendarRegressionTest::test4141665()
1516 UErrorCode status
= U_ZERO_ERROR
;
1517 GregorianCalendar
*cal
= new GregorianCalendar(status
);
1518 if(U_FAILURE(status
)) {
1519 dataerrln("Error creating calendar %s", u_errorName(status
));
1523 GregorianCalendar
*cal2
= (GregorianCalendar
*)cal
->clone();
1524 UDate cut
= cal
->getGregorianChange();
1525 UDate cut2
= cut
+ 100*24*60*60*1000.0; // 100 days later
1526 if (*cal
!= *cal2
) {
1527 errln("Cloned GregorianCalendars not equal");
1529 cal2
->setGregorianChange(cut2
,status
);
1530 if ( *cal
== *cal2
) {
1531 errln("GregorianCalendar::equals() ignores cutover");
1540 * Bug states that ArrayIndexOutOfBoundsException is thrown by GregorianCalendar::roll()
1541 * when IllegalArgumentException should be.
1543 void CalendarRegressionTest::test4142933()
1545 UErrorCode status
= U_ZERO_ERROR
;
1546 GregorianCalendar
*calendar
= new GregorianCalendar(status
);
1547 if(U_FAILURE(status
)) {
1548 dataerrln("Error creating calendar %s", u_errorName(status
));
1553 calendar
->roll((UCalendarDateFields
)-1, TRUE
, status
);
1554 if(U_SUCCESS(status
))
1555 errln("Test failed, no exception thrown");
1557 //catch (IllegalArgumentException e) {
1559 // logln("Test passed");
1561 //catch (Exception e) {
1562 //errln("Test failed. Unexpected exception is thrown: " + e);
1563 //e.printStackTrace();
1571 * GregorianCalendar handling of Dates Long.MIN_VALUE and Long.MAX_VALUE is
1572 * confusing; unless the time zone has a raw offset of zero, one or the
1573 * other of these will wrap. We've modified the test given in the bug
1574 * report to therefore only check the behavior of a calendar with a zero raw
1577 void CalendarRegressionTest::test4145158()
1579 UErrorCode status
= U_ZERO_ERROR
;
1580 GregorianCalendar
*calendar
= new GregorianCalendar(status
);
1581 if(status
== U_USING_FALLBACK_WARNING
|| U_FAILURE(status
)) {
1582 dataerrln("Error creating calendar %s", u_errorName(status
));
1587 calendar
->adoptTimeZone(TimeZone::createTimeZone("GMT"));
1589 calendar
->setTime(makeDate(INT32_MIN
),status
);
1590 int32_t year1
= calendar
->get(UCAL_YEAR
,status
);
1591 int32_t era1
= calendar
->get(UCAL_ERA
,status
);
1593 calendar
->setTime(makeDate(INT32_MAX
),status
);
1594 int32_t year2
= calendar
->get(UCAL_YEAR
,status
);
1595 int32_t era2
= calendar
->get(UCAL_ERA
,status
);
1597 if (year1
== year2
&& era1
== era2
) {
1598 errln("Fail: Long.MIN_VALUE or Long.MAX_VALUE wrapping around");
1606 * Maximum value for YEAR field wrong.
1608 // {sfb} this is not directly applicable in C++, since all
1609 // possible doubles are not representable by our Calendar.
1610 // In Java, all longs are representable.
1611 // We can determine limits programmatically
1612 // Using DBL_MAX is a bit of a hack, since for large doubles
1613 // Calendar gets squirrely and doesn't behave in any sort
1614 // of linear fashion (ie years jump around, up/down, etc) for a
1615 // small change in millis.
1616 void CalendarRegressionTest::test4145983()
1618 UErrorCode status
= U_ZERO_ERROR
;
1619 GregorianCalendar
*calendar
= new GregorianCalendar(status
);
1620 if(U_FAILURE(status
)) {
1621 dataerrln("Error creating calendar %s", u_errorName(status
));
1625 calendar
->adoptTimeZone(TimeZone::createTimeZone("GMT"));
1626 UDate DATES
[] = { LATEST_SUPPORTED_MILLIS
, EARLIEST_SUPPORTED_MILLIS
};
1627 for (int32_t i
=0; i
<2; ++i
) {
1628 calendar
->setTime(DATES
[i
], status
);
1629 int32_t year
= calendar
->get(UCAL_YEAR
,status
);
1630 int32_t maxYear
= calendar
->getMaximum(UCAL_YEAR
);
1631 if (year
> maxYear
) {
1632 errln(UnicodeString("Failed for ")+DATES
[i
]+" ms: year=" +
1633 year
+ ", maxYear=" + maxYear
);
1642 * This is a bug in the validation code of GregorianCalendar:: As reported,
1643 * the bug seems worse than it really is, due to a bug in the way the bug
1644 * report test was written. In reality the bug is restricted to the DAY_OF_YEAR
1645 * field. - liu 6/29/98
1647 void CalendarRegressionTest::test4147269()
1649 UErrorCode status
= U_ZERO_ERROR
;
1650 GregorianCalendar
*calendar
= new GregorianCalendar(status
);
1651 if(status
== U_USING_FALLBACK_WARNING
|| U_FAILURE(status
)) {
1652 dataerrln("Error creating calendar %s", u_errorName(status
));
1656 calendar
->setLenient(FALSE
);
1657 UDate date
= makeDate(1996, UCAL_JANUARY
, 3); // Arbitrary date
1658 for (int32_t field
= 0; field
< UCAL_FIELD_COUNT
; field
++) {
1659 calendar
->setTime(date
,status
);
1660 // Note: In the bug report, getActualMaximum() was called instead
1661 // of getMaximum() -- this was an error. The validation code doesn't
1662 // use getActualMaximum(), since that's too costly.
1663 int32_t max
= calendar
->getMaximum((UCalendarDateFields
)field
);
1664 int32_t value
= max
+1;
1665 calendar
->set((UCalendarDateFields
)field
, value
);
1667 calendar
->getTime(status
); // Force time computation
1668 // We expect an exception to be thrown. If we fall through
1669 // to the next line, then we have a bug.
1670 if(U_SUCCESS(status
))
1671 errln(UnicodeString("Test failed with field ") + FIELD_NAME
[field
] +
1672 ", date before: " + date
+
1673 ", date after: " + calendar
->getTime(status
) +
1674 ", value: " + value
+ " (max = " + max
+")");
1675 //} catch (IllegalArgumentException e) {}
1683 * Reported bug is that a GregorianCalendar with a cutover of Date(Long.MAX_VALUE)
1684 * doesn't behave as a pure Julian calendar.
1685 * CANNOT REPRODUCE THIS BUG
1688 CalendarRegressionTest::Test4149677()
1690 UErrorCode status
= U_ZERO_ERROR
;
1692 TimeZone
*zones
[] = {
1693 TimeZone::createTimeZone("GMT"),
1694 TimeZone::createTimeZone("PST"),
1695 TimeZone::createTimeZone("EAT")
1697 if(U_FAILURE(status
)) {
1698 errln("Couldn't create zones");
1700 // could leak memory
1703 for (int32_t i
=0; i
< 3; ++i
) {
1704 GregorianCalendar
*calendar
= new GregorianCalendar(zones
[i
], status
);
1705 if(U_FAILURE(status
)) {
1706 dataerrln("Couldnt' create calendar.: %s", u_errorName(status
));
1710 // Make sure extreme values don't wrap around
1711 calendar
->setTime(EARLIEST_SUPPORTED_MILLIS
, status
);
1712 if(U_FAILURE(status
))
1713 errln("setTime failed");
1714 if (calendar
->get(UCAL_ERA
, status
) != GregorianCalendar::BC
|| U_FAILURE(status
)) {
1715 errln("Fail: Date(EARLIEST_SUPPORTED_MILLIS) has an AD year");
1717 calendar
->setTime(LATEST_SUPPORTED_MILLIS
, status
);
1718 if(U_FAILURE(status
))
1719 errln("setTime failed");
1720 if (calendar
->get(UCAL_ERA
, status
) != GregorianCalendar::AD
|| U_FAILURE(status
)) {
1721 errln("Fail: Date(LATEST_SUPPORTED_MILLIS) has a BC year");
1724 calendar
->setGregorianChange(LATEST_SUPPORTED_MILLIS
, status
);
1725 if(U_FAILURE(status
))
1726 errln("setGregorianChange failed");
1727 // to obtain a pure Julian calendar
1729 UBool is100Leap
= calendar
->isLeapYear(100);
1732 errln("test failed with zone " + zones
[i
]->getID(temp
));
1733 errln(" cutover date is Date(Long.MAX_VALUE)");
1734 errln(UnicodeString(" isLeapYear(100) returns: ") + is100Leap
);
1739 // no need for cleanup- zones were adopted
1744 * Calendar and Date HOUR broken. If HOUR is out-of-range, Calendar
1745 * and Date classes will misbehave.
1748 CalendarRegressionTest::Test4162587()
1750 UErrorCode status
= U_ZERO_ERROR
;
1751 TimeZone
*savedef
= TimeZone::createDefault();
1752 TimeZone
*tz
= TimeZone::createTimeZone("PST");
1753 //TimeZone::adoptDefault(tz);
1754 TimeZone::setDefault(*tz
);
1756 GregorianCalendar
*cal
= new GregorianCalendar(tz
, status
);
1757 if(U_FAILURE(status
)) {
1758 dataerrln("Couldn't create calendar.: %s", u_errorName(status
));
1761 UDate d0
, dPlus
, dMinus
;
1763 for(int32_t i
=0; i
<5; ++i
) {
1764 if (i
>0) logln("---");
1767 cal
->set(1998, UCAL_APRIL
, 5, i
, 0);
1768 d0
= cal
->getTime(status
);
1769 if(U_FAILURE(status
))
1770 errln("Coudln't get time (1)");
1771 //String s0 = d.toString();
1772 logln(UnicodeString("0 ") + i
+ ": " + d0
/*s0*/);
1775 cal
->set(1998, UCAL_APRIL
, 4, i
+24, 0);
1776 dPlus
= cal
->getTime(status
);
1777 if(U_FAILURE(status
))
1778 errln("Coudln't get time (2)");
1779 //String sPlus = d.toString();
1780 logln(UnicodeString("+ ") + i
+ ": " + dPlus
/*sPlus*/);
1783 cal
->set(1998, UCAL_APRIL
, 6, i
-24, 0);
1784 dMinus
= cal
->getTime(status
);
1785 if(U_FAILURE(status
))
1786 errln("Coudln't get time (3)");
1787 //String sMinus = d.toString();
1788 logln(UnicodeString("- ") + i
+ ": " + dMinus
/*sMinus*/);
1790 if (d0
!= dPlus
|| d0
!= dMinus
) {
1791 errln("Fail: All three lines must match");
1794 TimeZone::setDefault(*savedef
);
1802 * Adding 12 months behaves differently from adding 1 year
1805 CalendarRegressionTest::Test4165343()
1807 UErrorCode status
= U_ZERO_ERROR
;
1808 GregorianCalendar
*calendar
= new GregorianCalendar(1996, UCAL_FEBRUARY
, 29, status
);
1809 if(U_FAILURE(status
)) {
1810 dataerrln("Couldn't create calendar.: %s", u_errorName(status
));
1813 UDate start
= calendar
->getTime(status
);
1814 if(U_FAILURE(status
))
1815 errln("Couldn't getTime (1)");
1816 logln(UnicodeString("init date: ") + start
);
1817 calendar
->add(UCAL_MONTH
, 12, status
);
1818 if(U_FAILURE(status
))
1819 errln("Couldn't add(MONTH, 12)");
1820 UDate date1
= calendar
->getTime(status
);
1821 if(U_FAILURE(status
))
1822 errln("Couldn't getTime (2)");
1823 logln(UnicodeString("after adding 12 months: ") + date1
);
1824 calendar
->setTime(start
, status
);
1825 if(U_FAILURE(status
))
1826 errln("Couldn't setTime");
1827 calendar
->add(UCAL_YEAR
, 1, status
);
1828 if(U_FAILURE(status
))
1829 errln("Couldn't add(YEAR, 1)");
1830 UDate date2
= calendar
->getTime(status
);
1831 if(U_FAILURE(status
))
1832 errln("Couldn't getTime (3)");
1833 logln(UnicodeString("after adding one year : ") + date2
);
1834 if (date1
== date2
) {
1835 logln("Test passed");
1837 errln("Test failed");
1844 * GregorianCalendar.getActualMaximum() does not account for first day of week.
1847 CalendarRegressionTest::Test4166109()
1852 * Su Mo Tu We Th Fr Sa
1854 * 8 9 10 11 12 13 14
1855 * 15 16 17 18 19 20 21
1856 * 22 23 24 25 26 27 28
1859 UBool passed
= TRUE
;
1860 UErrorCode status
= U_ZERO_ERROR
;
1861 UCalendarDateFields field
= UCAL_WEEK_OF_MONTH
;
1863 GregorianCalendar
*calendar
= new GregorianCalendar(Locale::getUS(), status
);
1864 if(U_FAILURE(status
)) {
1865 dataerrln("Couldn't create calendar.: %s", u_errorName(status
));
1868 calendar
->set(1998, UCAL_MARCH
, 1);
1869 calendar
->setMinimalDaysInFirstWeek(1);
1870 logln(UnicodeString("Date: ") + calendar
->getTime(status
)); // 888817448000
1872 int32_t firstInMonth
= calendar
->get(UCAL_DATE
, status
);
1873 if(U_FAILURE(status
))
1874 errln("get(D_O_M) failed");
1876 for(int32_t firstInWeek
= UCAL_SUNDAY
; firstInWeek
<= UCAL_SATURDAY
; firstInWeek
++) {
1877 calendar
->setFirstDayOfWeek((UCalendarDaysOfWeek
)firstInWeek
);
1878 int32_t returned
= calendar
->getActualMaximum(field
, status
);
1879 int32_t expected
= (31 + ((firstInMonth
- firstInWeek
+ 7)% 7) + 6) / 7;
1881 logln(UnicodeString("First day of week = ") + firstInWeek
+
1882 " getActualMaximum(WEEK_OF_MONTH, status) = " + returned
+
1883 " expected = " + expected
+
1884 ((returned
== expected
) ? " ok" : " FAIL"));
1886 if (returned
!= expected
) {
1891 errln("Test failed");
1899 * Calendar.getActualMaximum(YEAR) works wrong.
1902 CalendarRegressionTest::Test4167060()
1904 UErrorCode status
= U_ZERO_ERROR
;
1905 UCalendarDateFields field
= UCAL_YEAR
;
1906 DateFormat
*format
= new SimpleDateFormat(UnicodeString("EEE MMM dd HH:mm:ss zzz yyyy G"),
1907 Locale::getUS(), status
);
1908 if(U_FAILURE(status
)) {
1909 dataerrln("Couldn't create SimpleDateFormat - %s", u_errorName(status
));
1913 GregorianCalendar
*calendars
[] = {
1914 new GregorianCalendar(100, UCAL_NOVEMBER
, 1, status
),
1915 new GregorianCalendar(-99 /*100BC*/, UCAL_JANUARY
, 1, status
),
1916 new GregorianCalendar(1996, UCAL_FEBRUARY
, 29, status
),
1918 if(U_FAILURE(status
)) {
1919 errln("Couldn't create GregorianCalendars");
1924 UnicodeString id
[] = { "Hybrid", "Gregorian", "Julian" };
1926 for (int32_t k
=0; k
<3; ++k
) {
1927 logln("--- " + id
[k
] + " ---");
1929 for (int32_t j
=0; j
< 3; ++j
) {
1930 GregorianCalendar
*calendar
= calendars
[j
];
1932 calendar
->setGregorianChange(EARLIEST_SUPPORTED_MILLIS
, status
);
1935 calendar
->setGregorianChange(LATEST_SUPPORTED_MILLIS
, status
);
1938 if(U_FAILURE(status
))
1939 errln("setGregorianChange() failed");
1940 format
->adoptCalendar((Calendar
*)calendar
->clone());
1942 UDate dateBefore
= calendar
->getTime(status
);
1943 if(U_FAILURE(status
))
1944 errln("getTime() failed");
1946 int32_t maxYear
= calendar
->getActualMaximum(field
, status
);
1948 logln(UnicodeString("maxYear: ") + maxYear
+ " for " + format
->format(calendar
->getTime(status
), temp
));
1950 logln("date before: " + format
->format(dateBefore
, temp
));
1952 int32_t years
[] = {2000, maxYear
-1, maxYear
, maxYear
+1};
1954 for (int32_t i
= 0; i
< 4; i
++) {
1955 UBool valid
= years
[i
] <= maxYear
;
1956 calendar
->set(field
, years
[i
]);
1957 UDate dateAfter
= calendar
->getTime(status
);
1958 if(U_FAILURE(status
))
1959 errln("getTime() failed");
1960 int32_t newYear
= calendar
->get(field
, status
);
1961 if(U_FAILURE(status
))
1962 errln(UnicodeString("get(") + (int32_t)field
+ ") failed");
1963 calendar
->setTime(dateBefore
, status
); // restore calendar for next use
1964 if(U_FAILURE(status
))
1965 errln("setTime() failed");
1968 logln(UnicodeString(" Year ") + years
[i
] + (valid
? " ok " : " bad") +
1969 " => " + format
->format(dateAfter
, temp
));
1970 if (valid
&& newYear
!= years
[i
]) {
1971 errln(UnicodeString(" FAIL: ") + newYear
+ " should be valid; date, month and time shouldn't change");
1973 // {sfb} this next line is a hack, but it should work since if a
1974 // double has an exponent, adding 1 should not yield the same double
1975 else if (!valid
&& /*newYear == years[i]*/ dateAfter
+ 1.0 == dateAfter
) {
1976 errln(UnicodeString(" FAIL: ") + newYear
+ " should be invalid");
1983 delete calendars
[0];
1984 delete calendars
[1];
1985 delete calendars
[2];
1989 * Week of year is wrong at the start and end of the year.
1991 void CalendarRegressionTest::Test4197699() {
1992 UErrorCode status
= U_ZERO_ERROR
;
1993 GregorianCalendar
cal(status
);
1994 cal
.setFirstDayOfWeek(UCAL_MONDAY
);
1995 cal
.setMinimalDaysInFirstWeek(4);
1996 SimpleDateFormat
fmt("E dd MMM yyyy 'DOY='D 'WOY='w",
1997 Locale::getUS(), status
);
1998 fmt
.setCalendar(cal
);
1999 if (U_FAILURE(status
)) {
2000 dataerrln("Couldn't initialize test - %s", u_errorName(status
));
2005 2000, UCAL_JANUARY
, 1, 52,
2006 2001, UCAL_DECEMBER
, 31, 1,
2008 int32_t DATA_length
= UPRV_LENGTHOF(DATA
);
2011 DateFormat
& dfmt
= *(DateFormat
*)&fmt
;
2012 for (int32_t i
=0; i
<DATA_length
; ) {
2014 cal
.set(DATA
[i
], DATA
[i
+1], DATA
[i
+2]);
2016 int32_t expWOY
= DATA
[i
++];
2017 int32_t actWOY
= cal
.get(UCAL_WEEK_OF_YEAR
, status
);
2018 if (expWOY
== actWOY
) {
2019 logln(UnicodeString("Ok: ") + dfmt
.format(cal
.getTime(status
), str
.remove()));
2021 errln(UnicodeString("FAIL: ") + dfmt
.format(cal
.getTime(status
), str
.remove())
2022 + ", expected WOY=" + expWOY
);
2023 cal
.add(UCAL_DATE
, -8, status
);
2024 for (int j
=0; j
<14; ++j
) {
2025 cal
.add(UCAL_DATE
, 1, status
);
2026 logln(dfmt
.format(cal
.getTime(status
), str
.remove()));
2029 if (U_FAILURE(status
)) {
2030 errln("FAIL: Unexpected error from Calendar");
2036 enum Action
{ ADD
=1, ROLL
=2 };
2037 enum Sign
{ PLUS
=1, MINUS
=2 };
2039 #define ONE_HOUR (60*60*1000)
2040 #define ONE_DAY (24*ONE_HOUR)
2043 UCalendarDateFields field
;
2044 int8_t actionMask
; // ADD or ROLL or both
2045 int8_t signMask
; // PLUS or MINUS or both
2047 int32_t before
; // ms before cutover
2048 int32_t after
; // ms after cutover
2052 * Rolling and adding across the Gregorian cutover should work as expected.
2055 void CalendarRegressionTest::TestJ81() {
2056 UErrorCode status
= U_ZERO_ERROR
;
2057 UnicodeString temp
, temp2
, temp3
;
2059 GregorianCalendar
cal(TimeZone::createTimeZone("GMT"), Locale::getUS(), status
);
2060 SimpleDateFormat
fmt("HH:mm 'w'w 'd'D E d MMM yyyy", Locale::getUS(), status
);
2061 if (U_FAILURE(status
)) {
2062 dataerrln("Error: Cannot create calendar or format - %s", u_errorName(status
));
2065 fmt
.setCalendar(cal
);
2066 // Get the Gregorian cutover
2067 UDate cutover
= cal
.getGregorianChange();
2068 UDate days
= ONE_DAY
;
2069 days
= cutover
/days
;
2070 logln(UnicodeString("Cutover: {") +
2071 fmt
.format(cutover
, temp
) + "}(epoch days-" + (int)days
+ ", jd" + (2440588 + days
) +")");
2073 // Check woy and doy handling. Reference data:
2074 /* w40 d274 Mon 1 Oct 1582
2075 w40 d275 Tue 2 Oct 1582
2076 w40 d276 Wed 3 Oct 1582
2077 w40 d277 Thu 4 Oct 1582
2078 w40 d278 Fri 15 Oct 1582
2079 w40 d279 Sat 16 Oct 1582
2080 w41 d280 Sun 17 Oct 1582
2081 w41 d281 Mon 18 Oct 1582
2082 w41 d282 Tue 19 Oct 1582
2083 w41 d283 Wed 20 Oct 1582
2084 w41 d284 Thu 21 Oct 1582
2085 w41 d285 Fri 22 Oct 1582
2086 w41 d286 Sat 23 Oct 1582
2087 w42 d287 Sun 24 Oct 1582
2088 w42 d288 Mon 25 Oct 1582
2089 w42 d289 Tue 26 Oct 1582
2090 w42 d290 Wed 27 Oct 1582
2091 w42 d291 Thu 28 Oct 1582
2092 w42 d292 Fri 29 Oct 1582
2093 w42 d293 Sat 30 Oct 1582
2094 w43 d294 Sun 31 Oct 1582
2095 w43 d295 Mon 1 Nov 1582 */
2096 int32_t DOY_DATA
[] = {
2098 1, 40, 274, UCAL_MONDAY
,
2099 4, 40, 277, UCAL_THURSDAY
,
2100 15, 40, 278, UCAL_FRIDAY
,
2101 17, 41, 280, UCAL_SUNDAY
,
2102 24, 42, 287, UCAL_SUNDAY
,
2103 25, 42, 288, UCAL_MONDAY
,
2104 26, 42, 289, UCAL_TUESDAY
,
2105 27, 42, 290, UCAL_WEDNESDAY
,
2106 28, 42, 291, UCAL_THURSDAY
,
2107 29, 42, 292, UCAL_FRIDAY
,
2108 30, 42, 293, UCAL_SATURDAY
,
2109 31, 43, 294, UCAL_SUNDAY
2111 int32_t DOY_DATA_length
= UPRV_LENGTHOF(DOY_DATA
);
2113 for (i
=0; i
<DOY_DATA_length
; i
+=4) {
2114 // Test time->fields
2115 cal
.set(1582, UCAL_OCTOBER
, DOY_DATA
[i
]);
2116 int32_t woy
= cal
.get(UCAL_WEEK_OF_YEAR
, status
);
2117 int32_t doy
= cal
.get(UCAL_DAY_OF_YEAR
, status
);
2118 int32_t dow
= cal
.get(UCAL_DAY_OF_WEEK
, status
);
2119 if (U_FAILURE(status
)) {
2120 errln("Error: get() failed");
2123 if (woy
!= DOY_DATA
[i
+1] || doy
!= DOY_DATA
[i
+2] || dow
!= DOY_DATA
[i
+3]) {
2124 errln((UnicodeString
)"Fail: expect woy=" + DOY_DATA
[i
+1] +
2125 ", doy=" + DOY_DATA
[i
+2] + ", dow=" + DOY_DATA
[i
+3] + " on " +
2126 fmt
.format(cal
.getTime(status
), temp
.remove()) +
2127 " set(1582,OCTOBER, " + DOY_DATA
[i
] + ")");
2128 logln(CalendarTest::calToStr(cal
));
2129 status
= U_ZERO_ERROR
;
2131 logln((UnicodeString
)"PASS: expect woy=" + DOY_DATA
[i
+1] +
2132 ", doy=" + DOY_DATA
[i
+2] + ", dow=" + DOY_DATA
[i
+3] + " on " +
2133 fmt
.format(cal
.getTime(status
), temp
.remove()));
2134 logln(CalendarTest::calToStr(cal
));
2135 status
= U_ZERO_ERROR
;
2137 // Test fields->time for WOY
2139 cal
.set(UCAL_YEAR
, 1582);
2140 cal
.set(UCAL_WEEK_OF_YEAR
, DOY_DATA
[i
+1]);
2141 cal
.set(UCAL_DAY_OF_WEEK
, DOY_DATA
[i
+3]);
2142 int32_t dom
= cal
.get(UCAL_DATE
, status
);
2143 if (U_FAILURE(status
)) {
2144 errln("Error: get() failed");
2147 if (dom
!= DOY_DATA
[i
]) {
2148 errln((UnicodeString
)"Fail: set woy=" + DOY_DATA
[i
+1] +
2149 " dow=" + DOY_DATA
[i
+3] + " => " +
2150 fmt
.format(cal
.getTime(status
), temp
.remove()) +
2151 ", expected 1582 Oct " + DOY_DATA
[i
]);
2152 logln(CalendarTest::calToStr(cal
));
2153 status
= U_ZERO_ERROR
;
2156 // Test fields->time for DOY
2158 cal
.set(UCAL_YEAR
, 1582);
2159 cal
.set(UCAL_DAY_OF_YEAR
, DOY_DATA
[i
+2]);
2160 dom
= cal
.get(UCAL_DATE
, status
);
2161 if (U_FAILURE(status
)) {
2162 errln("Error: get() failed");
2165 if (dom
!= DOY_DATA
[i
]) {
2166 errln((UnicodeString
)"Fail: set doy=" + DOY_DATA
[i
+2] +
2168 fmt
.format(cal
.getTime(status
), temp
.remove()) +
2169 ", expected 1582 Oct " + DOY_DATA
[i
]);
2170 status
= U_ZERO_ERROR
;
2173 status
= U_ZERO_ERROR
;
2175 #define ADD_ROLL ADD|ROLL
2176 #define PLUS_MINUS PLUS|MINUS
2179 { UCAL_WEEK_OF_YEAR
, ADD_ROLL
, PLUS_MINUS
, 1, -ONE_DAY
, +6*ONE_DAY
},
2180 { UCAL_WEEK_OF_YEAR
, ADD_ROLL
, PLUS_MINUS
, 1, -ONE_DAY
, +6*ONE_DAY
},
2181 { UCAL_WEEK_OF_MONTH
, ADD
|ROLL
, PLUS
|MINUS
, 1, -ONE_DAY
, +6*ONE_DAY
},
2182 { UCAL_DATE
, ADD
|ROLL
, PLUS
|MINUS
, 2, -ONE_DAY
, +1*ONE_DAY
},
2183 { UCAL_DATE
, ROLL
, PLUS
, -6, -ONE_DAY
, +14*ONE_DAY
},
2184 { UCAL_DATE
, ROLL
, PLUS
, -7, 0, +14*ONE_DAY
},
2185 { UCAL_DATE
, ROLL
, PLUS
, -7, +ONE_DAY
, +15*ONE_DAY
},
2186 { UCAL_DATE
, ROLL
, PLUS
, +18, -ONE_DAY
, -4*ONE_DAY
},
2187 { UCAL_DAY_OF_YEAR
, ADD
|ROLL
, PLUS
|MINUS
, 2, -ONE_DAY
, +1*ONE_DAY
},
2188 { UCAL_DAY_OF_WEEK
, ADD
|ROLL
, PLUS
|MINUS
, 2, -ONE_DAY
, +1*ONE_DAY
},
2189 { UCAL_DAY_OF_WEEK_IN_MONTH
, ADD
|ROLL
, PLUS
|MINUS
, 1, -ONE_DAY
, +6*ONE_DAY
},
2190 { UCAL_AM_PM
, ADD
, PLUS
|MINUS
, 4, -12*ONE_HOUR
, +36*ONE_HOUR
},
2191 { UCAL_HOUR
, ADD
, PLUS
|MINUS
, 48, -12*ONE_HOUR
, +36*ONE_HOUR
},
2192 { UCAL_HOUR_OF_DAY
, ADD
, PLUS
|MINUS
, 48, -12*ONE_HOUR
, +36*ONE_HOUR
},
2193 { UCAL_MINUTE
, ADD
, PLUS
|MINUS
, 48*60, -12*ONE_HOUR
, +36*ONE_HOUR
},
2194 { UCAL_SECOND
, ADD
, PLUS
|MINUS
, 48*60*60, -12*ONE_HOUR
, +36*ONE_HOUR
},
2195 { UCAL_MILLISECOND
, ADD
, PLUS
|MINUS
, 48*ONE_HOUR
, -12*ONE_HOUR
, +36*ONE_HOUR
},
2196 // NOTE: These are not supported yet. See jitterbug 180.
2197 // Uncomment these lines when add/roll supported on these fields.
2198 // { Calendar::YEAR_WOY, ADD|ROLL, 1, -ONE_DAY, +6*ONE_DAY },
2199 // { Calendar::DOW_LOCAL, ADD|ROLL, 2, -ONE_DAY, +1*ONE_DAY }
2201 int32_t DATA_length
= UPRV_LENGTHOF(DATA
);
2203 // Now run the tests
2204 for (i
=0; i
<DATA_length
; ++i
) {
2205 for (Action action
=ADD
; action
<=ROLL
; action
=(Action
)(action
+1)) {
2206 if (!(DATA
[i
].actionMask
& action
)) {
2209 for (Sign sign
=PLUS
; sign
<=MINUS
; sign
=(Sign
)(sign
+1)) {
2210 if (!(DATA
[i
].signMask
& sign
)) {
2213 status
= U_ZERO_ERROR
;
2214 int32_t amount
= DATA
[i
].amount
* (sign
==MINUS
?-1:1);
2215 UDate date
= cutover
+
2216 (sign
==PLUS
? DATA
[i
].before
: DATA
[i
].after
);
2217 UDate expected
= cutover
+
2218 (sign
==PLUS
? DATA
[i
].after
: DATA
[i
].before
);
2219 cal
.setTime(date
, status
);
2220 if (U_FAILURE(status
)) {
2221 errln((UnicodeString
)"FAIL: setTime returned error code " + u_errorName(status
));
2224 if (action
== ADD
) {
2225 cal
.add(DATA
[i
].field
, amount
, status
);
2227 cal
.roll(DATA
[i
].field
, amount
, status
);
2229 if (U_FAILURE(status
)) {
2230 errln((UnicodeString
)"FAIL: " +
2231 (action
==ADD
?"add ":"roll ") + FIELD_NAME
[DATA
[i
].field
] +
2232 " returned error code " + u_errorName(status
));
2235 UDate result
= cal
.getTime(status
);
2236 if (U_FAILURE(status
)) {
2237 errln((UnicodeString
)"FAIL: getTime returned error code " + u_errorName(status
));
2240 if (result
== expected
) {
2241 logln((UnicodeString
)"Ok: {" +
2242 fmt
.format(date
, temp
.remove()) +
2243 "}(" + date
/ONE_DAY
+
2244 (action
==ADD
?") add ":") roll ") +
2245 amount
+ " " + FIELD_NAME
[DATA
[i
].field
] + " -> {" +
2246 fmt
.format(result
, temp2
.remove()) +
2247 "}(" + result
/ONE_DAY
+ ")");
2249 errln((UnicodeString
)"FAIL: {" +
2250 fmt
.format(date
, temp
.remove()) +
2251 "}(" + date
/ONE_DAY
+
2252 (action
==ADD
?") add ":") roll ") +
2253 amount
+ " " + FIELD_NAME
[DATA
[i
].field
] + " -> {" +
2254 fmt
.format(result
, temp2
.remove()) +
2255 "}(" + result
/ONE_DAY
+ "), expect {" +
2256 fmt
.format(expected
, temp3
.remove()) +
2257 "}(" + expected
/ONE_DAY
+ ")");
2265 * Test fieldDifference().
2267 void CalendarRegressionTest::TestJ438(void) {
2268 UErrorCode ec
= U_ZERO_ERROR
;
2270 2000, UCAL_JANUARY
, 20, 2010, UCAL_JUNE
, 15,
2271 2010, UCAL_JUNE
, 15, 2000, UCAL_JANUARY
, 20,
2272 1964, UCAL_SEPTEMBER
, 7, 1999, UCAL_JUNE
, 4,
2273 1999, UCAL_JUNE
, 4, 1964, UCAL_SEPTEMBER
, 7,
2275 int32_t DATA_length
= UPRV_LENGTHOF(DATA
);
2276 Calendar
* pcal
= Calendar::createInstance(Locale::getUS(), ec
);
2278 dataerrln("Error creating calendar %s", u_errorName(ec
));
2282 Calendar
& cal
= *pcal
;
2284 SimpleDateFormat
fmt(UnicodeString("MMM dd yyyy",""), ec
);
2285 fmt
.setCalendar(cal
);
2286 UnicodeString s
, t
, u
;
2287 if (U_SUCCESS(ec
)) {
2288 for (i
=0; i
<DATA_length
; i
+=6) {
2289 int32_t y1
= DATA
[i
];
2290 int32_t m1
= DATA
[i
+1];
2291 int32_t d1
= DATA
[i
+2];
2292 int32_t y2
= DATA
[i
+3];
2293 int32_t m2
= DATA
[i
+4];
2294 int32_t d2
= DATA
[i
+5];
2297 cal
.set(y1
, m1
, d1
);
2298 UDate date1
= cal
.getTime(ec
);
2299 if (failure(ec
, "getTime"))
2301 cal
.set(y2
, m2
, d2
);
2302 UDate date2
= cal
.getTime(ec
);
2303 if (failure(ec
, "getTime"))
2306 cal
.setTime(date1
, ec
);
2307 if (failure(ec
, "setTime"))
2309 int32_t dy
= cal
.fieldDifference(date2
, UCAL_YEAR
, ec
);
2310 int32_t dm
= cal
.fieldDifference(date2
, UCAL_MONTH
, ec
);
2311 int32_t dd
= cal
.fieldDifference(date2
, UCAL_DATE
, ec
);
2312 if (failure(ec
, "fieldDifference"))
2316 Calendar
*cal2
= cal
.clone();
2317 UErrorCode ec2
= U_ZERO_ERROR
;
2319 cal2
->setTime(date1
, ec2
);
2321 int32_t dy2
= cal2
->fieldDifference(date2
, Calendar::YEAR
, ec2
);
2322 int32_t dm2
= cal2
->fieldDifference(date2
, Calendar::MONTH
, ec2
);
2323 int32_t dd2
= cal2
->fieldDifference(date2
, Calendar::DATE
, ec2
);
2324 if (failure(ec2
, "fieldDifference(date, Calendar::DATE, ec)"))
2329 errln("fieldDifference(UCAL_...) and fieldDifference(Calendar::...) give different results!\n");
2335 logln(UnicodeString("") +
2336 fmt
.format(date2
, s
.remove()) + " - " +
2337 fmt
.format(date1
, t
.remove()) + " = " +
2338 dy
+ "y " + dm
+ "m " + dd
+ "d");
2340 cal
.setTime(date1
, ec
);
2341 if (failure(ec
, "setTime"))
2343 cal
.add(UCAL_YEAR
, dy
, ec
);
2344 cal
.add(UCAL_MONTH
, dm
, ec
);
2345 cal
.add(UCAL_DATE
, dd
, ec
);
2346 if (failure(ec
, "add"))
2348 UDate date22
= cal
.getTime(ec
);
2349 if (failure(ec
, "getTime"))
2351 if (date2
!= date22
) {
2352 errln(UnicodeString("FAIL: ") +
2353 fmt
.format(date1
, s
.remove()) + " + " +
2354 dy
+ "y " + dm
+ "m " + dd
+ "d = " +
2355 fmt
.format(date22
, t
.remove()) + ", exp " +
2356 fmt
.format(date2
, u
.remove()));
2358 logln(UnicodeString("Ok: ") +
2359 fmt
.format(date1
, s
.remove()) + " + " +
2360 dy
+ "y " + dm
+ "m " + dd
+ "d = " +
2361 fmt
.format(date22
, t
.remove()));
2365 dataerrln("Error creating SimpleDateFormat - %s", u_errorName(ec
));
2370 void CalendarRegressionTest::TestT5555()
2372 UErrorCode ec
= U_ZERO_ERROR
;
2373 Calendar
*cal
= Calendar::createInstance(ec
);
2375 if (cal
== NULL
|| U_FAILURE(ec
)) {
2376 dataerrln("FAIL: Calendar::createInstance(): %s", u_errorName(ec
));
2381 // Set to Wednesday, February 21, 2007
2382 cal
->set(2007, UCAL_FEBRUARY
, 21);
2384 // Advance three years
2385 cal
->add(UCAL_MONTH
, 36, ec
);
2387 // Set to last Wednesday of the month
2388 cal
->set(UCAL_DAY_OF_WEEK_IN_MONTH
, -1);
2392 int32_t yy
, mm
, dd
, ee
;
2394 yy
= cal
->get(UCAL_YEAR
, ec
);
2395 mm
= cal
->get(UCAL_MONTH
, ec
);
2396 dd
= cal
->get(UCAL_DATE
, ec
);
2397 ee
= cal
->get(UCAL_DAY_OF_WEEK
, ec
);
2399 // Should be set to Wednesday, February 24, 2010
2400 if (U_FAILURE(ec
) || yy
!= 2010 || mm
!= UCAL_FEBRUARY
|| dd
!= 24 || ee
!= UCAL_WEDNESDAY
) {
2401 errln("FAIL: got date %4d/%02d/%02d, expected 210/02/24: ", yy
, mm
+ 1, dd
);
2408 int32_t startMonth
; // 0-based
2409 int32_t startDay
; // 1-based
2410 UCalendarDateFields fieldToChange
;
2413 int32_t endMonth
; // 0-based
2414 int32_t endDay
; // 1-based
2415 } CoptEthCalTestItem
;
2417 // year 1724 in coptic calendar =
2418 // year 2000 in ethiopic calendar (276 more than coptic) =
2419 // year 7500 in ethiopic-amete-alem calendar (5776 more than coptic)
2420 // (2007-2008 in gregorian calendar depending on month)
2421 static const CoptEthCalTestItem coptEthCalTestItems
[] = {
2422 { 1724, 12, 1, UCAL_MONTH
, +1, 1725, 0, 1 },
2423 { 1724, 12, 1, UCAL_MONTH
, +9, 1725, 8, 1 },
2424 { 1723, 12, 2, UCAL_MONTH
, +1, 1724, 0, 2 }, // 1723 is a leap year
2425 { 1723, 12, 2, UCAL_MONTH
, +9, 1724, 8, 2 },
2426 { 1725, 0, 1, UCAL_MONTH
, -1, 1724, 12, 1 },
2427 { 1725, 0, 1, UCAL_MONTH
, -6, 1724, 7, 1 },
2428 { 1724, 12, 1, UCAL_DATE
, +8, 1725, 0, 4 },
2429 { 1723, 12, 1, UCAL_DATE
, +8, 1724, 0, 3 }, // 1723 is a leap year
2430 { 1724, 0, 1, UCAL_DATE
, -1, 1723, 12, 6 }, // 1723 is a leap year
2431 { 0, 0, 0, (UCalendarDateFields
)0, 0, 0, 0, 0 } // terminator
2435 const char * locale
;
2439 static const CoptEthCalLocale copEthCalLocales
[] = {
2440 { "en@calendar=coptic", 0 },
2441 { "en@calendar=ethiopic", 276 },
2442 { NULL
, 0 } // terminator
2445 void CalendarRegressionTest::TestT6745()
2447 const CoptEthCalLocale
* testLocalePtr
;
2448 for ( testLocalePtr
= copEthCalLocales
; testLocalePtr
->locale
!= NULL
; ++testLocalePtr
) {
2449 UErrorCode status
= U_ZERO_ERROR
;
2450 Calendar
*cal
= Calendar::createInstance(Locale(testLocalePtr
->locale
), status
);
2451 if ( U_FAILURE(status
) ) {
2452 dataerrln((UnicodeString
)"FAIL: Calendar::createInstance, locale " + testLocalePtr
->locale
+ ", status " + u_errorName(status
));
2455 const CoptEthCalTestItem
* testItemPtr
;
2456 for (testItemPtr
= coptEthCalTestItems
; testItemPtr
->fieldDelta
!= 0; ++testItemPtr
) {
2457 status
= U_ZERO_ERROR
;
2458 cal
->set( testItemPtr
->startYear
+ testLocalePtr
->yearOffset
, testItemPtr
->startMonth
, testItemPtr
->startDay
, 9, 0 );
2459 cal
->add( testItemPtr
->fieldToChange
, testItemPtr
->fieldDelta
, status
);
2460 if ( U_FAILURE(status
) ) {
2461 errln((UnicodeString
)"FAIL: Calendar::add, locale " + testLocalePtr
->locale
+ ", field/delta " +
2462 testItemPtr
->fieldToChange
+ "/" + testItemPtr
->fieldDelta
+ ", status " + u_errorName(status
));
2465 int32_t endYear
= testItemPtr
->endYear
+ testLocalePtr
->yearOffset
;
2466 int32_t year
= cal
->get(UCAL_YEAR
, status
);
2467 int32_t month
= cal
->get(UCAL_MONTH
, status
);
2468 int32_t day
= cal
->get(UCAL_DATE
, status
);
2469 if ( U_FAILURE(status
) || year
!= endYear
|| month
!= testItemPtr
->endMonth
|| day
!= testItemPtr
->endDay
) {
2470 errln((UnicodeString
)"ERROR: Calendar::add, locale " + testLocalePtr
->locale
+ ", field/delta " +
2471 testItemPtr
->fieldToChange
+ "/" + testItemPtr
->fieldDelta
+ ", status " + u_errorName(status
) +
2472 ", expected " + endYear
+ "/" + testItemPtr
->endMonth
+ "/" + testItemPtr
->endDay
+
2473 ", got " + year
+ "/" + month
+ "/" + day
);
2481 * Test behavior of fieldDifference around leap years. Also test a large
2482 * field difference to check binary search.
2484 void CalendarRegressionTest::TestLeapFieldDifference() {
2485 UErrorCode ec
= U_ZERO_ERROR
;
2486 Calendar
* cal
= Calendar::createInstance(ec
);
2487 if (cal
== NULL
|| U_FAILURE(ec
)) {
2488 dataerrln("FAIL: Calendar::createInstance(): %s", u_errorName(ec
));
2492 cal
->set(2004, UCAL_FEBRUARY
, 29);
2493 UDate date2004
= cal
->getTime(ec
);
2494 cal
->set(2000, UCAL_FEBRUARY
, 29);
2495 UDate date2000
= cal
->getTime(ec
);
2496 if (U_FAILURE(ec
)) {
2497 errln("FAIL: getTime()");
2501 int32_t y
= cal
->fieldDifference(date2004
, UCAL_YEAR
, ec
);
2502 int32_t d
= cal
->fieldDifference(date2004
, UCAL_DAY_OF_YEAR
, ec
);
2503 if (U_FAILURE(ec
)) {
2504 errln("FAIL: fieldDifference()");
2509 logln((UnicodeString
)"Ok: 2004/Feb/29 - 2000/Feb/29 = " + y
+ " years, " + d
+ " days");
2511 errln((UnicodeString
)"FAIL: 2004/Feb/29 - 2000/Feb/29 = " + y
+ " years, " + d
+ " days");
2513 cal
->setTime(date2004
, ec
);
2514 y
= cal
->fieldDifference(date2000
, UCAL_YEAR
, ec
);
2515 d
= cal
->fieldDifference(date2000
, UCAL_DAY_OF_YEAR
, ec
);
2516 if (U_FAILURE(ec
)) {
2517 errln("FAIL: setTime() / fieldDifference()");
2522 logln((UnicodeString
)"Ok: 2000/Feb/29 - 2004/Feb/29 = " + y
+ " years, " + d
+ " days");
2524 errln((UnicodeString
)"FAIL: 2000/Feb/29 - 2004/Feb/29 = " + y
+ " years, " + d
+ " days");
2526 // Test large difference
2527 cal
->set(2001, UCAL_APRIL
, 5); // 2452005
2528 UDate ayl
= cal
->getTime(ec
);
2529 cal
->set(1964, UCAL_SEPTEMBER
, 7); // 2438646
2530 UDate asl
= cal
->getTime(ec
);
2531 if (U_FAILURE(ec
)) {
2532 errln("FAIL: getTime()");
2536 d
= cal
->fieldDifference(ayl
, UCAL_DATE
, ec
);
2537 cal
->setTime(ayl
, ec
);
2538 int32_t d2
= cal
->fieldDifference(asl
, UCAL_DATE
, ec
);
2539 if (U_FAILURE(ec
)) {
2540 errln("FAIL: setTime() / fieldDifference()");
2544 if (d
== -d2
&& d
== 13359) {
2545 logln((UnicodeString
)"Ok: large field difference symmetrical " + d
);
2547 logln((UnicodeString
)"FAIL: large field difference incorrect " + d
+ ", " + d2
+
2548 ", expect +/- 13359");
2554 * Test ms_MY "Malay (Malaysia)" locale. Bug 1543.
2556 void CalendarRegressionTest::TestMalaysianInstance() {
2557 Locale
loc("ms", "MY"); // Malay (Malaysia)
2558 UErrorCode ec
= U_ZERO_ERROR
;
2559 Calendar
* cal
= Calendar::createInstance(loc
, ec
);
2560 if (U_FAILURE(ec
)) {
2561 dataerrln("FAIL: Can't construct calendar for ms_MY: %s", u_errorName(ec
));
2567 * setFirstDayOfWeek and setMinimalDaysInFirstWeek may change the
2568 * field <=> time mapping, since they affect the interpretation of
2569 * the WEEK_OF_MONTH or WEEK_OF_YEAR fields.
2571 void CalendarRegressionTest::TestWeekShift() {
2572 UErrorCode ec
= U_ZERO_ERROR
;
2573 GregorianCalendar
cal(TimeZone::createTimeZone("America/Los_Angeles"),
2574 Locale("en", "US"), ec
);
2575 if (U_FAILURE(ec
)) {
2576 dataerrln("Fail GregorianCalendar: %s", u_errorName(ec
));
2579 cal
.setTime(UDate(997257600000.0), ec
); // Wed Aug 08 01:00:00 PDT 2001
2580 // In pass one, change the first day of week so that the weeks
2581 // shift in August 2001. In pass two, change the minimal days
2582 // in the first week so that the weeks shift in August 2001.
2584 // Su Mo Tu We Th Fr Sa
2587 // 12 13 14 15 16 17 18
2588 // 19 20 21 22 23 24 25
2589 // 26 27 28 29 30 31
2590 for (int32_t pass
=0; pass
<2; ++pass
) {
2592 cal
.setFirstDayOfWeek(UCAL_WEDNESDAY
);
2593 cal
.setMinimalDaysInFirstWeek(4);
2595 cal
.setFirstDayOfWeek(UCAL_SUNDAY
);
2596 cal
.setMinimalDaysInFirstWeek(4);
2598 cal
.add(UCAL_DATE
, 1, ec
); // Force recalc
2599 cal
.add(UCAL_DATE
, -1, ec
);
2601 UDate time1
= cal
.getTime(ec
); // Get time -- should not change
2603 // Now change a week parameter and then force a recalc.
2604 // The bug is that the recalc should not be necessary --
2605 // calendar should do so automatically.
2607 cal
.setFirstDayOfWeek(UCAL_THURSDAY
);
2609 cal
.setMinimalDaysInFirstWeek(5);
2612 int32_t woy1
= cal
.get(UCAL_WEEK_OF_YEAR
, ec
);
2613 int32_t wom1
= cal
.get(UCAL_WEEK_OF_MONTH
, ec
);
2615 cal
.add(UCAL_DATE
, 1, ec
); // Force recalc
2616 cal
.add(UCAL_DATE
, -1, ec
);
2618 int32_t woy2
= cal
.get(UCAL_WEEK_OF_YEAR
, ec
);
2619 int32_t wom2
= cal
.get(UCAL_WEEK_OF_MONTH
, ec
);
2621 UDate time2
= cal
.getTime(ec
);
2623 if (U_FAILURE(ec
)) {
2624 errln("FAIL: internal test error");
2628 if (time1
!= time2
) {
2629 errln("FAIL: shifting week should not alter time");
2633 if (woy1
== woy2
&& wom1
== wom2
) {
2634 logln((UnicodeString
)"Ok: WEEK_OF_YEAR: " + woy1
+
2635 ", WEEK_OF_MONTH: " + wom1
);
2637 errln((UnicodeString
)"FAIL: WEEK_OF_YEAR: " + woy1
+ " => " + woy2
+
2638 ", WEEK_OF_MONTH: " + wom1
+ " => " + wom2
+
2639 " after week shift");
2645 * Make sure that when adding a day, we actually wind up in a
2646 * different day. The DST adjustments we use to keep the hour
2647 * constant across DST changes can backfire and change the day.
2649 void CalendarRegressionTest::TestTimeZoneTransitionAdd() {
2650 UErrorCode ec
= U_ZERO_ERROR
;
2651 Locale
locale(Locale::getUS()); // could also be CHINA
2652 SimpleDateFormat
dateFormat("MM/dd/yyyy HH:mm z", locale
, ec
);
2654 StringEnumeration
*tz
= TimeZone::createEnumeration();
2656 dataerrln("FAIL: TimeZone::createEnumeration");
2660 UnicodeString buf1
, buf2
;
2663 while ((id
= tz
->unext(NULL
, ec
)) != NULL
&& U_SUCCESS(ec
)) {
2664 if (U_FAILURE(ec
)) {
2665 errln("FAIL: StringEnumeration::unext");
2669 TimeZone
*t
= TimeZone::createTimeZone(id
);
2671 errln("FAIL: TimeZone::createTimeZone");
2674 dateFormat
.setTimeZone(*t
);
2676 Calendar
*cal
= Calendar::createInstance(t
, locale
, ec
);
2677 if (cal
== NULL
|| U_FAILURE(ec
)) {
2678 errln("FAIL: Calendar::createTimeZone");
2684 // Scan the year 2003, overlapping the edges of the year
2685 cal
->set(UCAL_YEAR
, 2002);
2686 cal
->set(UCAL_MONTH
, UCAL_DECEMBER
);
2687 cal
->set(UCAL_DATE
, 25);
2689 for (int32_t i
=0; i
<365+10 && U_SUCCESS(ec
); ++i
) {
2690 UDate yesterday
= cal
->getTime(ec
);
2691 int32_t yesterday_day
= cal
->get(UCAL_DATE
, ec
);
2692 cal
->add(UCAL_DATE
, 1, ec
);
2693 if (yesterday_day
== cal
->get(UCAL_DATE
, ec
)) {
2694 errln(UnicodeString(id
) + " " +
2695 dateFormat
.format(yesterday
, buf1
) + " +1d= " +
2696 dateFormat
.format(cal
->getTime(ec
), buf2
));
2704 if (U_FAILURE(ec
)) {
2705 dataerrln("FAIL: %s", u_errorName(ec
));
2712 CalendarRegressionTest::makeDate(int32_t y
, int32_t m
, int32_t d
,
2713 int32_t hr
, int32_t min
, int32_t sec
)
2717 UErrorCode status
= U_ZERO_ERROR
;
2718 Calendar
*cal
= Calendar::createInstance(status
);
2721 cal
->set(UCAL_YEAR
, y
);
2723 if(m
!= 0) cal
->set(UCAL_MONTH
, m
);
2724 if(d
!= 0) cal
->set(UCAL_DATE
, d
);
2725 if(hr
!= 0) cal
->set(UCAL_HOUR
, hr
);
2726 if(min
!= 0) cal
->set(UCAL_MINUTE
, min
);
2727 if(sec
!= 0) cal
->set(UCAL_SECOND
, sec
);
2729 result
= cal
->getTime(status
);
2736 void CalendarRegressionTest::TestDeprecates(void)
2738 UErrorCode status
= U_ZERO_ERROR
;
2739 Calendar
*c1
= Calendar::createInstance("ja_JP@calendar=japanese",status
);
2740 Calendar
*c2
= Calendar::createInstance("ja_JP_TRADITIONAL",status
);
2742 if(!c1
|| !c2
|| U_FAILURE(status
)) {
2743 dataerrln("Couldn't create calendars for roll of HOUR: %s", u_errorName(status
));
2747 c2
->set(UCAL_HOUR
,2);
2748 c1
->setTime(c2
->getTime(status
),status
);
2751 c1
->roll(Calendar::HOUR
,(int32_t)3,status
);
2752 c2
->roll(UCAL_HOUR
,(int32_t)3,status
);
2754 if(U_FAILURE(status
)) {
2755 errln("Error code when trying to roll");
2756 } else if(*c1
!= *c2
) {
2757 errln("roll(EDateField, int32_t) had different effect than roll(UCalendarField, int32_t)");
2760 c1
->setTime(c2
->getTime(status
),status
);
2761 c1
->roll(Calendar::HOUR
,(UBool
)FALSE
,status
);
2762 c2
->roll(UCAL_HOUR
,(UBool
)FALSE
,status
);
2764 if(U_FAILURE(status
)) {
2765 errln("Error code when trying to roll(UBool)");
2766 } else if(*c1
!= *c2
) {
2767 errln("roll(EDateField, UBool) had different effect than roll(UCalendarField, UBool)");
2773 status
= U_ZERO_ERROR
;
2775 c1
= Calendar::createInstance("th_TH_TRADITIONAL",status
);
2776 c2
= Calendar::createInstance("th_TH@calendar=buddhist",status
);
2778 if(!c1
|| !c2
|| U_FAILURE(status
)) {
2779 errln("Couldn't create calendars for add of HOUR");
2783 c2
->set(UCAL_HOUR
,2);
2784 c1
->setTime(c2
->getTime(status
),status
);
2787 c1
->add(Calendar::HOUR
,(int32_t)1,status
);
2789 if(U_FAILURE(status
)) {
2790 errln("Error code when trying to add Calendar::HOUR - %s", u_errorName(status
));
2793 c2
->add(UCAL_HOUR
,(int32_t)1,status
);
2795 if(U_FAILURE(status
)) {
2796 errln("Error code when trying to add - UCAL_HOUR %s", u_errorName(status
));
2797 } else if(*c1
!= *c2
) {
2798 errln("add(EDateField) had different effect than add(UCalendarField)");
2804 status
= U_ZERO_ERROR
;
2806 c1
= Calendar::createInstance("es_ES",status
);
2807 c2
= Calendar::createInstance("es_ES",status
);
2809 if(!c1
|| !c2
|| U_FAILURE(status
)) {
2810 errln("Couldn't create calendars for add of YEAR");
2814 c2
->set(UCAL_YEAR
,1900);
2815 c1
->setTime(c2
->getTime(status
),status
);
2818 c1
->add(Calendar::YEAR
,(int32_t)9,status
);
2819 c2
->add(UCAL_YEAR
,(int32_t)9,status
);
2821 if(U_FAILURE(status
)) {
2822 errln("Error code when trying to add YEARs");
2823 } else if(*c1
!= *c2
) {
2824 errln("add(EDateField YEAR) had different effect than add(UCalendarField YEAR)");
2832 void CalendarRegressionTest::TestT8057(void) {
2833 // Set the calendar to the last day in a leap year
2834 UErrorCode status
= U_ZERO_ERROR
;
2835 GregorianCalendar
*cal
= (GregorianCalendar
*)Calendar::createInstance(status
);
2836 if(U_FAILURE(status
)) {
2837 errln("Error creating Calendar: %s", u_errorName(status
));
2841 cal
->setLenient(FALSE
);
2843 cal
->set(2008, UCAL_DECEMBER
, 31);
2845 // Force calculating then fields once.
2846 UDate t
= cal
->getTime(status
);
2847 if(U_FAILURE(status
)) {
2848 errln("Error while calculating the date");
2853 UDate expected
= 1262246400000.0; // 2009-12-31 00:00 PST
2855 cal
->add(UCAL_YEAR
, 1, status
);
2856 t
= cal
->getTime(status
);
2857 if (U_SUCCESS(status
)) {
2858 if (t
!= expected
) {
2859 dataerrln((UnicodeString
)"FAIL: wrong date after add: expected=" + expected
+ " returned=" + t
);
2862 errln("FAIL: error while adding one year");
2868 // Test case for ticket#8596.
2869 // Setting an year followed by getActualMaximum(Calendar.WEEK_OF_YEAR)
2870 // may result wrong maximum week.
2871 void CalendarRegressionTest::TestT8596(void) {
2872 UErrorCode status
= U_ZERO_ERROR
;
2873 GregorianCalendar
*gc
= new GregorianCalendar(*TimeZone::getGMT(), status
);
2875 if (U_FAILURE(status
)) {
2876 dataerrln("Error creating Calendar: %s", u_errorName(status
));
2881 gc
->setFirstDayOfWeek(UCAL_MONDAY
);
2882 gc
->setMinimalDaysInFirstWeek(4);
2884 // Force the calender to resolve the fields once.
2885 // The maximum week number in 2011 is 52.
2886 gc
->set(UCAL_YEAR
, 2011);
2887 gc
->get(UCAL_YEAR
, status
);
2889 // Set a date in year 2009, but not calling get to resolve
2890 // the calendar's internal field yet.
2891 gc
->set(2009, UCAL_JULY
, 1);
2893 // Then call getActuamMaximum for week of year.
2894 // #8596 was caused by conflict between year set
2895 // above and internal work calendar field resolution.
2896 int32_t maxWeeks
= gc
->getActualMaximum(UCAL_WEEK_OF_YEAR
, status
);
2898 if (U_FAILURE(status
)) {
2899 errln("Error calendar calculation: %s", u_errorName(status
));
2904 if (maxWeeks
!= 53) {
2905 errln((UnicodeString
)"FAIL: Max week in 2009 in ISO calendar is 53, but got " + maxWeeks
);
2911 // Test case for ticket 9452
2912 // Calendar addition fall onto the missing date - 2011-12-30 in Samoa
2913 void CalendarRegressionTest::TestT9452(void) {
2914 UErrorCode status
= U_ZERO_ERROR
;
2915 GregorianCalendar
cal(TimeZone::createTimeZone("Pacific/Apia"), status
);
2916 failure(status
, "initializing GregorianCalendar");
2918 SimpleDateFormat
sdf(UnicodeString("y-MM-dd'T'HH:mm:ssZZZZZ"), status
);
2919 failure(status
, "initializing SimpleDateFormat");
2920 sdf
.setCalendar(cal
);
2924 // Set date to 2011-12-29 00:00
2926 cal
.set(2011, UCAL_DECEMBER
, 29, 0, 0, 0);
2928 UDate d
= cal
.getTime(status
);
2929 if (!failure(status
, "getTime for initial date")) {
2930 sdf
.format(d
, dstr
);
2931 logln(UnicodeString("Initial date: ") + dstr
);
2934 cal
.add(UCAL_DATE
, 1, status
);
2935 failure(status
, "add 1 day");
2936 d
= cal
.getTime(status
);
2937 failure(status
, "getTime after +1 day");
2939 sdf
.format(d
, dstr
);
2940 logln(UnicodeString("+1 day: ") + dstr
);
2941 assertEquals("Add 1 day", UnicodeString("2011-12-31T00:00:00+14:00"), dstr
);
2944 cal
.add(UCAL_DATE
, -1, status
);
2945 failure(status
, "subtract 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("Subtract 1 day", UnicodeString("2011-12-29T00:00:00-10:00"), dstr
);
2958 void CalendarRegressionTest::TestT11632(void) {
2959 UErrorCode status
= U_ZERO_ERROR
;
2960 GregorianCalendar
cal(TimeZone::createTimeZone("Pacific/Apia"), status
);
2961 if(U_FAILURE(status
)) {
2962 dataerrln("Error creating Calendar: %s", u_errorName(status
));
2965 failure(status
, "Calendar::createInstance(status)");
2967 failure(status
, "clear calendar");
2968 cal
.set(UCAL_HOUR
, 597);
2969 failure(status
, "set hour value in calendar");
2970 SimpleDateFormat
sdf(UnicodeString("y-MM-dd'T'HH:mm:ss"), status
);
2971 failure(status
, "initializing SimpleDateFormat");
2972 sdf
.setCalendar(cal
);
2974 UDate d
= cal
.getTime(status
);
2975 if (!failure(status
, "getTime for date")) {
2976 sdf
.format(d
, dstr
);
2978 dstr
.toUTF8String(utf8
);
2979 assertEquals("correct datetime displayed for hour value", UnicodeString("1970-01-25T21:00:00"), dstr
);
2981 failure(status
, "clear calendar");
2982 cal
.set(UCAL_HOUR
, 300);
2983 failure(status
, "set hour value in calendar");
2984 sdf
.setCalendar(cal
);
2985 d
= cal
.getTime(status
);
2986 if (!failure(status
, "getTime for initial date")) {
2988 sdf
.format(d
, dstr
);
2989 dstr
.toUTF8String(utf8
);
2990 assertEquals("correct datetime displayed for hour value", UnicodeString("1970-01-13T12:00:00"), dstr
);
2998 void CalendarRegressionTest::TestPersianCalOverflow(void) {
2999 const char* localeID
= "bs_Cyrl@calendar=persian";
3000 UErrorCode status
= U_ZERO_ERROR
;
3001 Calendar
* cal
= Calendar::createInstance(Locale(localeID
), status
);
3002 if(U_FAILURE(status
)) {
3003 dataerrln("FAIL: Calendar::createInstance for localeID %s: %s", localeID
, u_errorName(status
));
3005 int32_t maxMonth
= cal
->getMaximum(UCAL_MONTH
);
3006 int32_t maxDayOfMonth
= cal
->getMaximum(UCAL_DATE
);
3007 int32_t jd
, month
, dayOfMonth
;
3008 for (jd
= 67023580; jd
<= 67023584; jd
++) { // year 178171, int32_t overflow if jd >= 67023582
3009 status
= U_ZERO_ERROR
;
3011 cal
->set(UCAL_JULIAN_DAY
, jd
);
3012 month
= cal
->get(UCAL_MONTH
, status
);
3013 dayOfMonth
= cal
->get(UCAL_DATE
, status
);
3014 if ( U_FAILURE(status
) ) {
3015 errln("FAIL: Calendar->get MONTH/DATE for localeID %s, julianDay %d, status %s", localeID
, jd
, u_errorName(status
));
3016 } else if (month
> maxMonth
|| dayOfMonth
> maxDayOfMonth
) {
3017 errln("FAIL: localeID %s, julianDay %d; maxMonth %d, got month %d; maxDayOfMonth %d, got dayOfMonth %d",
3018 localeID
, jd
, maxMonth
, month
, maxDayOfMonth
, dayOfMonth
);
3026 * @bug tickets 12661, 13538
3028 void CalendarRegressionTest::TestIslamicCalOverflow(void) {
3029 const char* localeID
= "ar@calendar=islamic-civil";
3030 UErrorCode status
= U_ZERO_ERROR
;
3031 Calendar
* cal
= Calendar::createInstance(Locale(localeID
), status
);
3032 if(U_FAILURE(status
)) {
3033 dataerrln("FAIL: Calendar::createInstance for localeID %s: %s", localeID
, u_errorName(status
));
3035 int32_t maxMonth
= cal
->getMaximum(UCAL_MONTH
);
3036 int32_t maxDayOfMonth
= cal
->getMaximum(UCAL_DATE
);
3037 int32_t jd
, year
, month
, dayOfMonth
;
3038 for (jd
= 73530872; jd
<= 73530876; jd
++) { // year 202002, int32_t overflow if jd >= 73530874
3039 status
= U_ZERO_ERROR
;
3041 cal
->set(UCAL_JULIAN_DAY
, jd
);
3042 year
= cal
->get(UCAL_YEAR
, status
);
3043 month
= cal
->get(UCAL_MONTH
, status
);
3044 dayOfMonth
= cal
->get(UCAL_DATE
, status
);
3045 if ( U_FAILURE(status
) ) {
3046 errln("FAIL: Calendar->get YEAR/MONTH/DATE for localeID %s, julianDay %d, status %s", localeID
, jd
, u_errorName(status
));
3047 } else if (month
> maxMonth
|| dayOfMonth
> maxDayOfMonth
) {
3048 errln("FAIL: localeID %s, julianDay %d; got year %d; maxMonth %d, got month %d; maxDayOfMonth %d, got dayOfMonth %d",
3049 localeID
, jd
, year
, maxMonth
, month
, maxDayOfMonth
, dayOfMonth
);
3056 void CalendarRegressionTest::TestWeekOfYear13548(void) {
3057 int32_t year
= 2000;
3058 UErrorCode status
= U_ZERO_ERROR
;
3059 LocalPointer
<Calendar
> cal(Calendar::createInstance(status
));
3060 failure(status
, "Calendar::createInstance(status)");
3062 cal
->set(UCAL_YEAR
, year
);
3063 cal
->set(UCAL_WEEK_OF_YEAR
, 4);
3065 int32_t resultYear
= cal
->get(UCAL_YEAR
, status
);
3066 failure(status
, "get(UCAL_YEAR, status)");
3067 if (year
!= resultYear
) {
3068 errln((UnicodeString
)"Fail: Expected year=" + year
+ ", actual=" + resultYear
);
3072 #endif /* #if !UCONFIG_NO_FORMATTING */