1 // 2016 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html 3 /******************************************************************** 4 * COPYRIGHT: 5 * Copyright (c) 1997-2016, International Business Machines Corporation 6 * and others. All Rights Reserved. 7 ********************************************************************/ 8 9 #include "unicode/utypes.h" 10 11 #if !UCONFIG_NO_FORMATTING 12 13 #include "calregts.h" 14 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" 21 #include "cmemory.h" 22 #include "caltest.h" 23 #include "unicode/localpointer.h" 24 25 #include <float.h> 26 27 // ***************************************************************************** 28 // class CalendarRegressionTest 29 // ***************************************************************************** 30 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; 35 36 #define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); logln((UnicodeString)""); test(); } break 37 38 void 39 CalendarRegressionTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ ) 40 { 41 // if (exec) logln((UnicodeString)"TestSuite NumberFormatRegressionTest"); 42 switch (index) { 43 CASE(0,test4100311); 44 CASE(1,test4074758); 45 CASE(2,test4028518); 46 CASE(3,test4031502); 47 CASE(4,test4035301); 48 CASE(5,test4040996); 49 CASE(6,test4051765); 50 CASE(7,test4061476); 51 CASE(8,test4070502); 52 CASE(9,test4071197); 53 CASE(10,test4071385); 54 CASE(11,test4073929); 55 CASE(12,test4083167); 56 CASE(13,test4086724); 57 CASE(14,test4095407); 58 CASE(15,test4096231); 59 CASE(16,test4096539); 60 CASE(17,test41003112); 61 CASE(18,test4103271); 62 CASE(19,test4106136); 63 CASE(20,test4108764); 64 CASE(21,test4114578); 65 CASE(22,test4118384); 66 CASE(23,test4125881); 67 CASE(24,test4125892); 68 CASE(25,test4141665); 69 CASE(26,test4142933); 70 CASE(27,test4145158); 71 CASE(28,test4145983); 72 CASE(29,test4147269); 73 74 CASE(30,Test4149677); 75 CASE(31,Test4162587); 76 CASE(32,Test4165343); 77 CASE(33,Test4166109); 78 CASE(34,Test4167060); 79 CASE(35,Test4197699); 80 CASE(36,TestJ81); 81 CASE(37,TestJ438); 82 CASE(38,TestLeapFieldDifference); 83 CASE(39,TestMalaysianInstance); 84 CASE(40,test4059654); 85 CASE(41,test4092362); 86 CASE(42,TestWeekShift); 87 CASE(43,TestTimeZoneTransitionAdd); 88 CASE(44,TestDeprecates); 89 CASE(45,TestT5555); 90 CASE(46,TestT6745); 91 CASE(47,TestT8057); 92 CASE(48,TestT8596); 93 CASE(49,Test9019); 94 CASE(50,TestT9452); 95 CASE(51,TestT11632); 96 CASE(52,TestPersianCalOverflow); 97 CASE(53,TestIslamicCalOverflow); 98 CASE(54,TestWeekOfYear13548); 99 default: name = ""; break; 100 } 101 } 102 103 const char* CalendarRegressionTest::FIELD_NAME [] = { 104 "ERA", 105 "YEAR", 106 "MONTH", 107 "WEEK_OF_YEAR", 108 "WEEK_OF_MONTH", 109 "DAY_OF_MONTH", 110 "DAY_OF_YEAR", 111 "DAY_OF_WEEK", 112 "DAY_OF_WEEK_IN_MONTH", 113 "AM_PM", 114 "HOUR", 115 "HOUR_OF_DAY", 116 "MINUTE", 117 "SECOND", 118 "MILLISECOND", 119 "ZONE_OFFSET", 120 "DST_OFFSET", 121 "YEAR_WOY", 122 "DOW_LOCAL" 123 }; 124 125 UBool 126 CalendarRegressionTest::failure(UErrorCode status, const char* msg) 127 { 128 if(U_FAILURE(status)) { 129 errcheckln(status, UnicodeString("FAIL: ") + msg + " failed, error " + u_errorName(status)); 130 return TRUE; 131 } 132 133 return FALSE; 134 } 135 136 /* 137 * bug 4100311 138 */ 139 void 140 CalendarRegressionTest::test4100311() 141 { 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)); 146 delete cal; 147 return; 148 } 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); 155 delete cal; 156 } 157 158 159 /** 160 * @bug 4074758 161 */ 162 void 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)); 169 delete cal; 170 return; 171 } 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"); 180 } 181 182 delete cal; 183 } 184 185 void 186 CalendarRegressionTest::test4028518() 187 { 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)); 192 delete cal1; 193 return; 194 } 195 failure(status, "new GregorianCalendar"); 196 GregorianCalendar *cal2 = (GregorianCalendar*) cal1->clone() ; 197 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:") ; 204 delete cal1; 205 delete cal2; 206 } 207 208 209 void 210 CalendarRegressionTest::Test9019() 211 { 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)); 217 return; 218 } 219 cal1->set(UCAL_HOUR, 1); 220 cal2->set(UCAL_HOUR,2); 221 cal1->clear(); 222 cal2->clear(); 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):") ; 232 233 if(!cal1->equals(*cal2,status)) { 234 errln("Error: cal1 != cal2.\n"); 235 } 236 failure(status, "equals"); 237 } 238 239 void 240 CalendarRegressionTest::printdate(GregorianCalendar *cal, const char *string) 241 { 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"); 251 } 252 253 /** 254 * @bug 4031502 255 */ 256 void 257 CalendarRegressionTest::test4031502() 258 { 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(); 263 if (ids == NULL) { 264 dataerrln("Unable to create TimeZone Enumeration."); 265 return; 266 } 267 UBool bad = FALSE; 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)); 273 delete tz; 274 return; 275 } 276 cl->clear(); 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; 281 delete cl; 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"); 286 cal->clear(); 287 cal->set(1900, 15, 5, 5, 8, 13); 288 if (cal->get(UCAL_HOUR, status) != 5 || U_FAILURE(status)) { 289 UnicodeString temp; 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)); 295 bad = TRUE; 296 } 297 delete cal; 298 } 299 if (bad) 300 errln("TimeZone problems with GC"); 301 // delete [] ids; // TODO: bad APIs 302 delete ids; 303 } 304 305 /** 306 * @bug 4035301 307 */ 308 void CalendarRegressionTest::test4035301() 309 { 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) || 317 *c != *c || 318 *c != *d) 319 dataerrln("Fail"); 320 delete c; 321 delete d; 322 } 323 324 /** 325 * @bug 4040996 326 */ 327 void CalendarRegressionTest::test4040996() 328 { 329 int32_t count = 0; 330 StringEnumeration* ids = TimeZone::createEnumeration(-8 * 60 * 60 * 1000); 331 if (ids == NULL) { 332 dataerrln("Unable to create TimeZone enumeration."); 333 return; 334 } 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)); 344 return; 345 } 346 calendar->set(UCAL_MONTH,3); 347 calendar->set(UCAL_DATE,18); 348 calendar->set(UCAL_SECOND, 30); 349 350 logln(UnicodeString("MONTH: ") + calendar->get(UCAL_MONTH, status)); 351 logln(UnicodeString("DAY_OF_MONTH: ") + 352 calendar->get(UCAL_DATE, status)); 353 logln(UnicodeString("MINUTE: ") + calendar->get(UCAL_MINUTE, status)); 354 logln(UnicodeString("SECOND: ") + calendar->get(UCAL_SECOND, status)); 355 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")); 369 370 delete calendar; 371 delete ids; 372 // delete ids; // TODO: BAD API 373 } 374 375 /** 376 * @bug 4051765 377 */ 378 void CalendarRegressionTest::test4051765() 379 { 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)); 384 delete cal; 385 return; 386 } 387 cal->setLenient(FALSE); 388 cal->set(UCAL_DAY_OF_WEEK, 0); 389 //try { 390 cal->getTime(status); 391 if( ! U_FAILURE(status)) 392 errln("Fail: DAY_OF_WEEK 0 should be disallowed"); 393 /*} 394 catch (IllegalArgumentException e) { 395 return; 396 }*/ 397 398 delete cal; 399 } 400 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))); 428 logln("DST_OFFSET: " 429 + (Calendar::get(Calendar::DST_OFFSET)/(60*60*1000))); 430 calendar = new GregorianCalendar(1997,3,10); 431 Calendar::getTime(); 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 454 logln("DST_OFFSET: " 455 + (Calendar::get(Calendar::DST_OFFSET)/(60*60*1000))); // in hours 456 } 457 */ 458 459 /** 460 * @bug 4059654 461 */ 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)); 467 delete gc; 468 return; 469 } 470 471 gc->set(1997, 3, 1, 15, 16, 17); // April 1, 1997 472 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); 478 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)); 483 484 delete gc; 485 delete exp; 486 } 487 488 /** 489 * @bug 4061476 490 */ 491 void CalendarRegressionTest::test4061476() 492 { 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)); 499 delete cal; 500 delete fmt; 501 return; 502 } 503 fmt->adoptCalendar(cal); 504 // try { 505 UDate date = fmt->parse("29MAY97", status); 506 failure(status, "fmt->parse"); 507 cal->setTime(date, status); 508 failure(status, "cal->setTime"); 509 // } 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)); 517 518 delete fmt; 519 } 520 521 /** 522 * @bug 4070502 523 */ 524 void CalendarRegressionTest::test4070502() 525 { 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)); 530 delete cal; 531 return; 532 } 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); 538 539 delete cal; 540 } 541 542 /** 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) 546 * <p> 547 * @param date The date to start from 548 */ 549 UDate 550 CalendarRegressionTest::getAssociatedDate(UDate d, UErrorCode& status) 551 { 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 556 for (;;) { 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); 560 // cal.getTime(); 561 } 562 else 563 break; 564 } 565 566 UDate dd = cal->getTime(status); 567 delete cal; 568 return dd; 569 } 570 571 /** 572 * @bug 4071197 573 */ 574 void CalendarRegressionTest::test4071197() 575 { 576 dowTest(FALSE); 577 dowTest(TRUE); 578 } 579 580 void CalendarRegressionTest::dowTest(UBool lenient) 581 { 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)); 586 delete cal; 587 return; 588 } 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); 603 604 if(U_FAILURE(status)) { 605 errln("Error checking Calendar: %s", u_errorName(status)); 606 delete cal; 607 return; 608 } 609 610 if(cal->getActualMinimum(UCAL_DAY_OF_WEEK, status) != min) { 611 errln("FAIL: actual minimum differs from minimum"); 612 } 613 if(cal->getActualMinimum(Calendar::DAY_OF_WEEK, status) != min) { 614 errln("FAIL: actual minimum (Calendar::DAY_OF_WEEK, status) differs from minimum"); 615 } 616 if(cal->getActualMinimum(Calendar::DAY_OF_WEEK) != min) { 617 errln("FAIL: actual minimum (Calendar::DAY_OF_WEEK) differs from minimum"); 618 } 619 if(((Calendar*)cal)->getActualMinimum(UCAL_DAY_OF_WEEK, status) != min) { 620 errln("FAIL: actual minimum (UCAL_DAY_OF_WEEK, status) differs from minimum"); 621 } 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"); 625 // } 626 if(U_FAILURE(status)) { 627 errln("Error getting actual minimum: %s", u_errorName(status)); 628 return; 629 } 630 631 delete cal; 632 } 633 634 /** 635 * @bug 4071385 636 */ 637 void CalendarRegressionTest::test4071385() 638 { 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)); 643 delete cal; 644 return; 645 } 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)) 650 errln("Fail"); 651 652 delete cal; 653 } 654 655 /** 656 * @bug 4073929 657 */ 658 void CalendarRegressionTest::test4073929() 659 { 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)); 664 delete foo1; 665 return; 666 } 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)); 693 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 || 699 testmonth != 8 || 700 testday != 28) 701 errln("Fail: Calendar not initialized"); 702 703 delete foo1; 704 } 705 706 /** 707 * @bug 4083167 708 */ 709 void CalendarRegressionTest::test4083167() 710 { 711 UErrorCode status = U_ZERO_ERROR; 712 TimeZone *saveZone = TimeZone::createDefault(); 713 //try { 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)); 720 delete cal; 721 return; 722 } 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; 729 730 //logln("Current time: " + firstDate.toString()); 731 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); 742 } 743 //} 744 //finally { 745 TimeZone::setDefault(*saveZone); 746 //} 747 748 delete saveZone; 749 delete newZone; 750 delete cal; 751 } 752 753 /** 754 * @bug 4086724 755 */ 756 void CalendarRegressionTest::test4086724() 757 { 758 UErrorCode status = U_ZERO_ERROR; 759 SimpleDateFormat *date; 760 TimeZone *saveZone = TimeZone::createDefault(); 761 Locale saveLocale = Locale::getDefault(); 762 //try { 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)); 770 delete cal; 771 delete newZone; 772 delete date; 773 return; 774 } 775 cal->set(1997,UCAL_SEPTEMBER,30); 776 UDate now = cal->getTime(status); 777 UnicodeString temp; 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)); 789 //} 790 //finally { 791 Locale::setDefault(saveLocale,status); 792 TimeZone::setDefault(*saveZone); 793 //} 794 logln("*** THE RESULTS OF THIS TEST MUST BE VERIFIED MANUALLY ***"); 795 796 delete newZone; 797 delete cal; 798 delete date; 799 delete saveZone; 800 } 801 802 /** 803 * @bug 4092362 804 */ 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)); 810 delete cal1; 811 return; 812 } 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 ); */ 819 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++) 823 ; 824 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 ); */ 832 833 logln( UnicodeString(" Cal2 = ") + cal2->getTime(status) ); 834 logln( UnicodeString(" Cal2 time in ms = ") + cal2->get(UCAL_MILLISECOND,status) ); 835 if( *cal1 != *cal2 ) 836 errln("Fail: Milliseconds randomized"); 837 838 delete cal1; 839 delete cal2; 840 } 841 842 /** 843 * @bug 4095407 844 */ 845 void CalendarRegressionTest::test4095407() 846 { 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)); 851 delete a; 852 return; 853 } 854 int32_t dow = a->get(UCAL_DAY_OF_WEEK, status); 855 if (dow != UCAL_THURSDAY) 856 errln(UnicodeString("Fail: Want THURSDAY Got ") + dow); 857 858 delete a; 859 } 860 861 /** 862 * @bug 4096231 863 */ 864 void CalendarRegressionTest::test4096231() 865 { 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; 870 871 Calendar *cal1 = new GregorianCalendar(*PST,status); 872 if (U_FAILURE(status)) { 873 dataerrln("Failure new GregorianCalendar: %s", u_errorName(status)); 874 delete GMT; 875 delete PST; 876 delete cal1; 877 return; 878 } 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. 884 int32_t h1,h2; 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"); 890 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); 895 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)); 902 903 double t1,t2,t3,t4; 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))); 919 if (t1 == t2 || 920 t1 != t4 || 921 t2 != t3) 922 errln("Fail: Calendar zone behavior faulty"); 923 924 delete cal1; 925 delete cal2; 926 delete cal3; 927 delete GMT; 928 delete PST; 929 } 930 931 /** 932 * @bug 4096539 933 */ 934 void CalendarRegressionTest::test4096539() 935 { 936 UErrorCode status = U_ZERO_ERROR; 937 int32_t y [] = {31,28,31,30,31,30,31,31,30,31,30,31}; 938 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)); 944 delete gc; 945 return; 946 } 947 int32_t m1,m2; 948 log(UnicodeString("") + (m1=gc->get(UCAL_MONTH,status)+1)+UnicodeString("/")+ 949 gc->get(UCAL_DATE,status)+"/"+gc->get(UCAL_YEAR,status)+ 950 " + 1mo = "); 951 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) 955 ); 956 int32_t m = (m1 % 12) + 1; 957 if (m2 != m) 958 errln(UnicodeString("Fail: Want ") + m + " Got " + m2); 959 delete gc; 960 } 961 962 } 963 964 /** 965 * @bug 4100311 966 */ 967 void CalendarRegressionTest::test41003112() 968 { 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)); 973 delete cal; 974 return; 975 } 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"); 982 delete cal; 983 } 984 985 /** 986 * @bug 4103271 987 */ 988 void CalendarRegressionTest::test4103271() 989 { 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)); 997 delete testCal; 998 return; 999 } 1000 testCal->clear(); 1001 sdf.adoptCalendar(testCal); 1002 sdf.applyPattern("EEE dd MMM yyyy 'WOY'ww'-'YYYY 'DOY'DDD"); 1003 UBool fail = FALSE; 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=" + 1010 firstDay + 1011 ", minimum days in first week=" + 1012 minDays); 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); 1022 UnicodeString temp; 1023 FieldPosition pos(FieldPosition::DONT_CARE); 1024 output = testDesc + " - " + sdf.format(d,temp,pos) + "\t"; 1025 output = output + "\t" + actWOY; 1026 logln(output); 1027 fail = TRUE; 1028 } 1029 } 1030 } 1031 } 1032 } 1033 1034 int32_t DATA [] = { 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, 1041 }; 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); 1050 str.remove(); 1051 log(UnicodeString("") + sdf.format(testCal->getTime(status), str) + 1052 UnicodeString(" ") + woy); 1053 if (woy != DATA[j + 1 + i]) { 1054 log(" ERROR"); 1055 fail = TRUE; 1056 } 1057 logln(""); 1058 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); 1062 testCal->clear(); 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) { 1067 str.remove(); 1068 logln(UnicodeString(" Parse failed: ") + 1069 sdf.format(testCal->getTime(status), str)); 1070 fail= TRUE; 1071 } 1072 1073 testCal->setTime(save,status); 1074 testCal->add(UCAL_DATE, 1,status); 1075 } 1076 } 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 [] = { 1080 // y y_woy woy dow 1081 1997, 1998, 1, UCAL_SUNDAY, 1082 (1998), (1998), (2), (UCAL_SATURDAY), 1083 (1998), (1998), (53), (UCAL_THURSDAY), 1084 (1999), (1998), (53), (UCAL_FRIDAY) 1085 }; 1086 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) 1092 }; 1093 1094 testCal->setMinimalDaysInFirstWeek(3); 1095 testCal->setFirstDayOfWeek(UCAL_SUNDAY); 1096 int32_t i = 0; 1097 1098 /* Enable this code to display various WOY values 1099 testCal->clear(); 1100 for (i=25; i<38; ++i) { 1101 testCal->set(1996, Calendar::DECEMBER, i); 1102 UDate got = testCal->getTime(status); 1103 str.remove(); 1104 logln(UnicodeString("") + sdf.format(got, str)); 1105 } 1106 for (i=25; i<38; ++i) { 1107 testCal->set(1997, Calendar::DECEMBER, i); 1108 UDate got = testCal->getTime(status); 1109 str.remove(); 1110 logln(UnicodeString("") + sdf.format(got, str)); 1111 } 1112 for (i=25; i<38; ++i) { 1113 testCal->set(1998, UCAL_DECEMBER, i); 1114 UDate got = testCal->getTime(status); 1115 str.remove(); 1116 logln(UnicodeString("") + sdf.format(got, str)); 1117 } 1118 */ 1119 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]; 1126 testCal->clear(); 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); 1131 str.remove(); 1132 str2.remove(); 1133 log(UnicodeString("Y") + y + "-W" + woy + 1134 "-DOW" + dow + " expect:" + sdf.format(exp, str) + 1135 " got:" + sdf.format(got, str2)); 1136 if (got != exp) { 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 ")); 1141 fail = TRUE; 1142 } 1143 logln(""); 1144 1145 testCal->clear(); 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); 1150 str.remove(); 1151 str2.remove(); 1152 log(UnicodeString("YWOY") + ywoy + "-W" + woy + 1153 "-DOW" + dow + " expect:" + sdf.format(exp, str) + 1154 " got:" + sdf.format(got, str2)); 1155 if (got != exp) { 1156 log(" FAIL"); 1157 fail = TRUE; 1158 } 1159 logln(""); 1160 } 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), 1167 }; 1168 1169 int32_t ADDROLL_int []= { 1170 (1), 1171 (1), 1172 (1), 1173 (1) 1174 }; 1175 1176 1177 UBool ADDROLL_bool [] = { 1178 TRUE,//ADD, 1179 TRUE, 1180 FALSE, 1181 FALSE 1182 }; 1183 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]; 1190 1191 testCal->setTime(before,status); 1192 if (ADDROLL_bool[i/2]) 1193 testCal->add(UCAL_WEEK_OF_YEAR, amount,status); 1194 else 1195 testCal->roll(UCAL_WEEK_OF_YEAR, amount,status); 1196 UDate got = testCal->getTime(status); 1197 str.remove(); 1198 str2.remove(); 1199 UnicodeString opTypeStr; 1200 if (ADDROLL_bool[i/2]) { 1201 opTypeStr = UnicodeString("add(WOY,", ""); 1202 } else { 1203 opTypeStr = UnicodeString("roll(WOY,", ""); 1204 } 1205 log(opTypeStr + amount + ") " + sdf.format(before, str) + " => " + 1206 sdf.format(got, str2)); 1207 if (after != got) { 1208 str.remove(); 1209 logln(UnicodeString(" exp:") + sdf.format(after, str) + " FAIL"); 1210 fail = TRUE; 1211 } 1212 else logln(" ok"); 1213 1214 testCal->setTime(after,status); 1215 if (ADDROLL_bool[i/2]) 1216 testCal->add(UCAL_WEEK_OF_YEAR, -amount,status); 1217 else 1218 testCal->roll(UCAL_WEEK_OF_YEAR, -amount,status); 1219 got = testCal->getTime(status); 1220 str.remove(); 1221 str2.remove(); 1222 log(opTypeStr + (-amount) + ") " + sdf.format(after, str) + " => " + 1223 sdf.format(got, str2)); 1224 if (before != got) { 1225 str.remove(); 1226 logln(UnicodeString(" exp:") + sdf.format(before, str) + " FAIL"); 1227 fail = TRUE; 1228 } 1229 else logln(" ok"); 1230 } 1231 if (fail) 1232 errln("Fail: Week of year misbehaving"); 1233 } 1234 1235 /** 1236 * @bug 4106136 1237 */ 1238 void CalendarRegressionTest::test4106136() 1239 { 1240 UErrorCode status = U_ZERO_ERROR; 1241 Locale saveLocale = Locale::getDefault(); 1242 //try { 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); 1251 int32_t n [] = { 1252 count1, count2, count3 1253 }; 1254 for (int32_t j=0; j<3; ++j) { 1255 UnicodeString temp; 1256 if (n[j] == 0) 1257 dataerrln(UnicodeString("Fail: No locales for ") + locales[i].getName()); 1258 } 1259 } 1260 //} 1261 //finally { 1262 Locale::setDefault(saveLocale,status); 1263 //} 1264 } 1265 1266 /** 1267 * @bug 4108764 1268 */ 1269 void CalendarRegressionTest::test4108764() 1270 { 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)); 1275 delete cal; 1276 return; 1277 } 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); 1283 1284 cal->setTime(d11,status); 1285 1286 cal->clear( UCAL_MINUTE ); 1287 logln(UnicodeString("") + cal->getTime(status)); 1288 if (cal->getTime(status) != d01) 1289 errln("Fail: clear(MINUTE) broken"); 1290 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"); 1295 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"); 1301 1302 cal->clear( UCAL_MINUTE ); 1303 logln(UnicodeString("") + cal->getTime(status)); 1304 if (cal->getTime(status) != d00) 1305 errln("Fail: clear(MINUTE) broken #2"); 1306 1307 cal->clear(); 1308 logln(UnicodeString("") + cal->getTime(status)); 1309 if (cal->getTime(status) != epoch) 1310 errln(UnicodeString("Fail: clear() broken Want ") + epoch); 1311 1312 delete cal; 1313 } 1314 1315 /** 1316 * @bug 4114578 1317 */ 1318 void CalendarRegressionTest::test4114578() 1319 { 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)); 1325 delete cal; 1326 return; 1327 } 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; 1331 1332 UBool fail = FALSE; 1333 1334 const int32_t ADD = 1; 1335 const int32_t ROLL = 2; 1336 1337 double DATA []= { 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, 1347 }; 1348 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]; 1353 1354 log(UnicodeString("") + date); 1355 cal->setTime(date,status); 1356 1357 switch ((int32_t) DATA[i+1]) { 1358 case ADD: 1359 log(UnicodeString(" add (HOUR,") + (amt<0?"":"+")+amt + ")= "); 1360 cal->add(UCAL_HOUR, amt,status); 1361 break; 1362 case ROLL: 1363 log(UnicodeString(" roll(HOUR,") + (amt<0?"":"+")+amt + ")= "); 1364 cal->roll(UCAL_HOUR, amt,status); 1365 break; 1366 } 1367 1368 log(UnicodeString("") + cal->getTime(status)); 1369 1370 double change = cal->getTime(status) - date; 1371 if (change != expectedChange) { 1372 fail = TRUE; 1373 logln(" FAIL"); 1374 } 1375 else logln(" OK"); 1376 } 1377 1378 if (fail) errln("Fail: roll/add misbehaves around DST onset/cease"); 1379 1380 delete cal; 1381 } 1382 1383 /** 1384 * @bug 4118384 1385 * Make sure maximum for HOUR field is 11, not 12. 1386 */ 1387 void CalendarRegressionTest::test4118384() 1388 { 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)); 1393 delete cal; 1394 return; 1395 } 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"); 1400 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"); 1405 } 1406 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"); 1410 } 1411 1412 delete cal; 1413 cal = Calendar::createInstance(Locale("th_TH@calendar=buddhist"),status); 1414 if(U_FAILURE(status)) { 1415 dataerrln("Error creating calendar %s", u_errorName(status)); 1416 delete cal; 1417 return; 1418 } 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"); 1423 } 1424 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"); 1428 } 1429 1430 delete cal; 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)); 1435 delete cal; 1436 return; 1437 } 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"); 1441 } 1442 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"); 1446 } 1447 1448 delete cal; 1449 } 1450 1451 /** 1452 * @bug 4125881 1453 * Check isLeapYear for BC years. 1454 */ 1455 void CalendarRegressionTest::test4125881() 1456 { 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)); 1461 delete cal; 1462 return; 1463 } 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)); 1467 delete cal; 1468 return; 1469 } 1470 cal->clear(); 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); 1474 UnicodeString temp; 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"); 1479 } 1480 1481 delete cal; 1482 delete fmt; 1483 } 1484 1485 /** 1486 * @bug 4125892 1487 * Prove that GregorianCalendar is proleptic (it used to cut off 1488 * at 45 BC, and not have leap years before then). 1489 */ 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)); 1495 delete cal; 1496 return; 1497 } 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)); 1501 delete cal; 1502 return; 1503 } 1504 cal->clear(); 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"); 1515 1516 delete cal; 1517 delete fmt; 1518 } 1519 1520 /** 1521 * @bug 4141665 1522 * GregorianCalendar::equals() ignores cutover date 1523 */ 1524 void CalendarRegressionTest::test4141665() 1525 { 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)); 1530 delete cal; 1531 return; 1532 } 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"); 1538 } 1539 cal2->setGregorianChange(cut2,status); 1540 if ( *cal == *cal2) { 1541 errln("GregorianCalendar::equals() ignores cutover"); 1542 } 1543 1544 delete cal; 1545 delete cal2; 1546 } 1547 1548 /** 1549 * @bug 4142933 1550 * Bug states that ArrayIndexOutOfBoundsException is thrown by GregorianCalendar::roll() 1551 * when IllegalArgumentException should be. 1552 */ 1553 void CalendarRegressionTest::test4142933() 1554 { 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)); 1559 delete calendar; 1560 return; 1561 } 1562 //try { 1563 calendar->roll((UCalendarDateFields)-1, TRUE, status); 1564 if(U_SUCCESS(status)) 1565 errln("Test failed, no exception thrown"); 1566 //} 1567 //catch (IllegalArgumentException e) { 1568 // OK: Do nothing 1569 // logln("Test passed"); 1570 //} 1571 //catch (Exception e) { 1572 //errln("Test failed. Unexpected exception is thrown: " + e); 1573 //e.printStackTrace(); 1574 //} 1575 1576 delete calendar; 1577 } 1578 1579 /** 1580 * @bug 4145158 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 1585 * offset zone. 1586 */ 1587 void CalendarRegressionTest::test4145158() 1588 { 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)); 1593 delete calendar; 1594 return; 1595 } 1596 1597 calendar->adoptTimeZone(TimeZone::createTimeZone("GMT")); 1598 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); 1602 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); 1606 1607 if (year1 == year2 && era1 == era2) { 1608 errln("Fail: Long.MIN_VALUE or Long.MAX_VALUE wrapping around"); 1609 } 1610 1611 delete calendar; 1612 } 1613 1614 /** 1615 * @bug 4145983 1616 * Maximum value for YEAR field wrong. 1617 */ 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() 1627 { 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)); 1632 delete calendar; 1633 return; 1634 } 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); 1644 } 1645 } 1646 1647 delete calendar; 1648 } 1649 1650 /** 1651 * @bug 4147269 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 1656 */ 1657 void CalendarRegressionTest::test4147269() 1658 { 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)); 1663 delete calendar; 1664 return; 1665 } 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); 1676 //try { 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) {} 1686 } 1687 1688 delete calendar; 1689 } 1690 1691 /** 1692 * @bug 4149677 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 1696 */ 1697 void 1698 CalendarRegressionTest::Test4149677() 1699 { 1700 UErrorCode status = U_ZERO_ERROR; 1701 1702 TimeZone *zones [] = { 1703 TimeZone::createTimeZone("GMT"), 1704 TimeZone::createTimeZone("PST"), 1705 TimeZone::createTimeZone("EAT") 1706 }; 1707 if(U_FAILURE(status)) { 1708 errln("Couldn't create zones"); 1709 return; 1710 // could leak memory 1711 } 1712 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)); 1717 return; 1718 } 1719 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"); 1726 } 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"); 1732 } 1733 1734 calendar->setGregorianChange(LATEST_SUPPORTED_MILLIS, status); 1735 if(U_FAILURE(status)) 1736 errln("setGregorianChange failed"); 1737 // to obtain a pure Julian calendar 1738 1739 UBool is100Leap = calendar->isLeapYear(100); 1740 if (!is100Leap) { 1741 UnicodeString temp; 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); 1745 } 1746 delete calendar; 1747 } 1748 1749 // no need for cleanup- zones were adopted 1750 } 1751 1752 /** 1753 * @bug 4162587 1754 * Calendar and Date HOUR broken. If HOUR is out-of-range, Calendar 1755 * and Date classes will misbehave. 1756 */ 1757 void 1758 CalendarRegressionTest::Test4162587() 1759 { 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); 1765 1766 GregorianCalendar *cal = new GregorianCalendar(tz, status); 1767 if(U_FAILURE(status)) { 1768 dataerrln("Couldn't create calendar.: %s", u_errorName(status)); 1769 return; 1770 } 1771 UDate d0, dPlus, dMinus; 1772 1773 for(int32_t i=0; i<5; ++i) { 1774 if (i>0) logln("---"); 1775 1776 cal->clear(); 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*/); 1783 1784 cal->clear(); 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*/); 1791 1792 cal->clear(); 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*/); 1799 1800 if (d0 != dPlus || d0 != dMinus) { 1801 errln("Fail: All three lines must match"); 1802 } 1803 } 1804 TimeZone::setDefault(*savedef); 1805 //delete tz; 1806 delete cal; 1807 delete savedef; 1808 } 1809 1810 /** 1811 * @bug 4165343 1812 * Adding 12 months behaves differently from adding 1 year 1813 */ 1814 void 1815 CalendarRegressionTest::Test4165343() 1816 { 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)); 1821 return; 1822 } 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"); 1846 } else { 1847 errln("Test failed"); 1848 } 1849 delete calendar; 1850 } 1851 1852 /** 1853 * @bug 4166109 1854 * GregorianCalendar.getActualMaximum() does not account for first day of week. 1855 */ 1856 void 1857 CalendarRegressionTest::Test4166109() 1858 { 1859 /* Test month: 1860 * 1861 * March 1998 1862 * Su Mo Tu We Th Fr Sa 1863 * 1 2 3 4 5 6 7 1864 * 8 9 10 11 12 13 14 1865 * 15 16 17 18 19 20 21 1866 * 22 23 24 25 26 27 28 1867 * 29 30 31 1868 */ 1869 UBool passed = TRUE; 1870 UErrorCode status = U_ZERO_ERROR; 1871 UCalendarDateFields field = UCAL_WEEK_OF_MONTH; 1872 1873 GregorianCalendar *calendar = new GregorianCalendar(Locale::getUS(), status); 1874 if(U_FAILURE(status)) { 1875 dataerrln("Couldn't create calendar.: %s", u_errorName(status)); 1876 return; 1877 } 1878 calendar->set(1998, UCAL_MARCH, 1); 1879 calendar->setMinimalDaysInFirstWeek(1); 1880 logln(UnicodeString("Date: ") + calendar->getTime(status)); // 888817448000 1881 1882 int32_t firstInMonth = calendar->get(UCAL_DATE, status); 1883 if(U_FAILURE(status)) 1884 errln("get(D_O_M) failed"); 1885 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; 1890 1891 logln(UnicodeString("First day of week = ") + firstInWeek + 1892 " getActualMaximum(WEEK_OF_MONTH, status) = " + returned + 1893 " expected = " + expected + 1894 ((returned == expected) ? " ok" : " FAIL")); 1895 1896 if (returned != expected) { 1897 passed = FALSE; 1898 } 1899 } 1900 if (!passed) { 1901 errln("Test failed"); 1902 } 1903 1904 delete calendar; 1905 } 1906 1907 /** 1908 * @bug 4167060 1909 * Calendar.getActualMaximum(YEAR) works wrong. 1910 */ 1911 void 1912 CalendarRegressionTest::Test4167060() 1913 { 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)); 1920 return; 1921 } 1922 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), 1927 }; 1928 if(U_FAILURE(status)) { 1929 errln("Couldn't create GregorianCalendars"); 1930 return; 1931 // could leak 1932 } 1933 1934 UnicodeString id [] = { "Hybrid", "Gregorian", "Julian" }; 1935 1936 for (int32_t k=0; k<3; ++k) { 1937 logln("--- " + id[k] + " ---"); 1938 1939 for (int32_t j=0; j < 3; ++j) { 1940 GregorianCalendar *calendar = calendars[j]; 1941 if (k == 1) { 1942 calendar->setGregorianChange(EARLIEST_SUPPORTED_MILLIS, status); 1943 } 1944 else if (k == 2) { 1945 calendar->setGregorianChange(LATEST_SUPPORTED_MILLIS, status); 1946 } 1947 1948 if(U_FAILURE(status)) 1949 errln("setGregorianChange() failed"); 1950 format->adoptCalendar((Calendar*)calendar->clone()); 1951 1952 UDate dateBefore = calendar->getTime(status); 1953 if(U_FAILURE(status)) 1954 errln("getTime() failed"); 1955 1956 int32_t maxYear = calendar->getActualMaximum(field, status); 1957 UnicodeString temp; 1958 logln(UnicodeString("maxYear: ") + maxYear + " for " + format->format(calendar->getTime(status), temp)); 1959 temp.remove(); 1960 logln("date before: " + format->format(dateBefore, temp)); 1961 1962 int32_t years[] = {2000, maxYear-1, maxYear, maxYear+1}; 1963 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"); 1976 1977 temp.remove(); 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"); 1982 } 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"); 1987 } 1988 } 1989 } 1990 } 1991 1992 delete format; 1993 delete calendars[0]; 1994 delete calendars[1]; 1995 delete calendars[2]; 1996 } 1997 1998 /** 1999 * Week of year is wrong at the start and end of the year. 2000 */ 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)); 2011 return; 2012 } 2013 2014 int32_t DATA[] = { 2015 2000, UCAL_JANUARY, 1, 52, 2016 2001, UCAL_DECEMBER, 31, 1, 2017 }; 2018 int32_t DATA_length = UPRV_LENGTHOF(DATA); 2019 2020 UnicodeString str; 2021 DateFormat& dfmt = *(DateFormat*)&fmt; 2022 for (int32_t i=0; i<DATA_length; ) { 2023 cal.clear(); 2024 cal.set(DATA[i], DATA[i+1], DATA[i+2]); 2025 i += 3; 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())); 2030 } else { 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())); 2037 } 2038 } 2039 if (U_FAILURE(status)) { 2040 errln("FAIL: Unexpected error from Calendar"); 2041 return; 2042 } 2043 } 2044 } 2045 2046 enum Action { ADD=1, ROLL=2 }; 2047 enum Sign { PLUS=1, MINUS=2 }; 2048 2049 #define ONE_HOUR (60*60*1000) 2050 #define ONE_DAY (24*ONE_HOUR) 2051 2052 typedef struct { 2053 UCalendarDateFields field; 2054 int8_t actionMask; // ADD or ROLL or both 2055 int8_t signMask; // PLUS or MINUS or both 2056 int32_t amount; 2057 int32_t before; // ms before cutover 2058 int32_t after; // ms after cutover 2059 } J81_DATA; 2060 2061 /** 2062 * Rolling and adding across the Gregorian cutover should work as expected. 2063 * Jitterbug 81. 2064 */ 2065 void CalendarRegressionTest::TestJ81() { 2066 UErrorCode status = U_ZERO_ERROR; 2067 UnicodeString temp, temp2, temp3; 2068 int32_t i; 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)); 2073 return; 2074 } 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) +")"); 2082 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[] = { 2107 // dom, woy, doy 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 2120 }; 2121 int32_t DOY_DATA_length = UPRV_LENGTHOF(DOY_DATA); 2122 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"); 2131 break; 2132 } 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; 2140 } else { 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; 2146 } 2147 // Test fields->time for WOY 2148 cal.clear(); 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"); 2155 break; 2156 } 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; 2164 } 2165 2166 // Test fields->time for DOY 2167 cal.clear(); 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"); 2173 break; 2174 } 2175 if (dom != DOY_DATA[i]) { 2176 errln((UnicodeString)"Fail: set doy=" + DOY_DATA[i+2] + 2177 " => " + 2178 fmt.format(cal.getTime(status), temp.remove()) + 2179 ", expected 1582 Oct " + DOY_DATA[i]); 2180 status = U_ZERO_ERROR; 2181 } 2182 } 2183 status = U_ZERO_ERROR; 2184 2185 #define ADD_ROLL ADD|ROLL 2186 #define PLUS_MINUS PLUS|MINUS 2187 // Test cases 2188 J81_DATA DATA[] = { 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 } 2210 }; 2211 int32_t DATA_length = UPRV_LENGTHOF(DATA); 2212 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)) { 2217 continue; 2218 } 2219 for (Sign sign=PLUS; sign<=MINUS; sign=(Sign)(sign+1)) { 2220 if (!(DATA[i].signMask & sign)) { 2221 continue; 2222 } 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)); 2232 continue; 2233 } 2234 if (action == ADD) { 2235 cal.add(DATA[i].field, amount, status); 2236 } else { 2237 cal.roll(DATA[i].field, amount, status); 2238 } 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)); 2243 continue; 2244 } 2245 UDate result = cal.getTime(status); 2246 if (U_FAILURE(status)) { 2247 errln((UnicodeString)"FAIL: getTime returned error code " + u_errorName(status)); 2248 continue; 2249 } 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 + ")"); 2258 } else { 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 + ")"); 2268 } 2269 } 2270 } 2271 } 2272 } 2273 2274 /** 2275 * Test fieldDifference(). 2276 */ 2277 void CalendarRegressionTest::TestJ438(void) { 2278 UErrorCode ec = U_ZERO_ERROR; 2279 int32_t DATA[] = { 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, 2284 }; 2285 int32_t DATA_length = UPRV_LENGTHOF(DATA); 2286 Calendar* pcal = Calendar::createInstance(Locale::getUS(), ec); 2287 if(U_FAILURE(ec)) { 2288 dataerrln("Error creating calendar %s", u_errorName(ec)); 2289 delete pcal; 2290 return; 2291 } 2292 Calendar& cal = *pcal; 2293 int32_t i; 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]; 2305 2306 cal.clear(); 2307 cal.set(y1, m1, d1); 2308 UDate date1 = cal.getTime(ec); 2309 if (failure(ec, "getTime")) 2310 break; 2311 cal.set(y2, m2, d2); 2312 UDate date2 = cal.getTime(ec); 2313 if (failure(ec, "getTime")) 2314 break; 2315 2316 cal.setTime(date1, ec); 2317 if (failure(ec, "setTime")) 2318 break; 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")) 2323 break; 2324 2325 { 2326 Calendar *cal2 = cal.clone(); 2327 UErrorCode ec2 = U_ZERO_ERROR; 2328 2329 cal2->setTime(date1, ec2); 2330 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)")) 2335 break; 2336 if( (dd2 != dd) || 2337 (dm2 != dm) || 2338 (dy2 != dy)){ 2339 errln("fieldDifference(UCAL_...) and fieldDifference(Calendar::...) give different results!\n"); 2340 } 2341 delete cal2; 2342 } 2343 2344 2345 logln(UnicodeString("") + 2346 fmt.format(date2, s.remove()) + " - " + 2347 fmt.format(date1, t.remove()) + " = " + 2348 dy + "y " + dm + "m " + dd + "d"); 2349 2350 cal.setTime(date1, ec); 2351 if (failure(ec, "setTime")) 2352 break; 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")) 2357 break; 2358 UDate date22 = cal.getTime(ec); 2359 if (failure(ec, "getTime")) 2360 break; 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())); 2367 } else { 2368 logln(UnicodeString("Ok: ") + 2369 fmt.format(date1, s.remove()) + " + " + 2370 dy + "y " + dm + "m " + dd + "d = " + 2371 fmt.format(date22, t.remove())); 2372 } 2373 } 2374 } else { 2375 dataerrln("Error creating SimpleDateFormat - %s", u_errorName(ec)); 2376 } 2377 delete pcal; 2378 } 2379 2380 void CalendarRegressionTest::TestT5555() 2381 { 2382 UErrorCode ec = U_ZERO_ERROR; 2383 Calendar *cal = Calendar::createInstance(ec); 2384 2385 if (cal == NULL || U_FAILURE(ec)) { 2386 dataerrln("FAIL: Calendar::createInstance(): %s", u_errorName(ec)); 2387 delete cal; 2388 return; 2389 } 2390 2391 // Set to Wednesday, February 21, 2007 2392 cal->set(2007, UCAL_FEBRUARY, 21); 2393 2394 // Advance three years 2395 cal->add(UCAL_MONTH, 36, ec); 2396 2397 // Set to last Wednesday of the month 2398 cal->set(UCAL_DAY_OF_WEEK_IN_MONTH, -1); 2399 2400 cal->getTime(ec); 2401 2402 int32_t yy, mm, dd, ee; 2403 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); 2408 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); 2412 } 2413 delete cal; 2414 } 2415 2416 typedef struct { 2417 int32_t startYear; 2418 int32_t startMonth; // 0-based 2419 int32_t startDay; // 1-based 2420 UCalendarDateFields fieldToChange; 2421 int32_t fieldDelta; 2422 int32_t endYear; 2423 int32_t endMonth; // 0-based 2424 int32_t endDay; // 1-based 2425 } CoptEthCalTestItem; 2426 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 2442 }; 2443 2444 typedef struct { 2445 const char * locale; 2446 int32_t yearOffset; 2447 } CoptEthCalLocale; 2448 2449 static const CoptEthCalLocale copEthCalLocales[] = { 2450 { "en@calendar=coptic", 0 }, 2451 { "en@calendar=ethiopic", 276 }, 2452 { NULL, 0 } // terminator 2453 }; 2454 2455 void CalendarRegressionTest::TestT6745() 2456 { 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)); 2463 continue; 2464 } 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)); 2473 continue; 2474 } 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 ); 2484 } 2485 } 2486 delete cal; 2487 } 2488 } 2489 2490 /** 2491 * Test behavior of fieldDifference around leap years. Also test a large 2492 * field difference to check binary search. 2493 */ 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)); 2499 delete cal; 2500 return; 2501 } 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()"); 2508 delete cal; 2509 return; 2510 } 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()"); 2515 delete cal; 2516 return; 2517 } 2518 if (d == 0) { 2519 logln((UnicodeString)"Ok: 2004/Feb/29 - 2000/Feb/29 = " + y + " years, " + d + " days"); 2520 } else { 2521 errln((UnicodeString)"FAIL: 2004/Feb/29 - 2000/Feb/29 = " + y + " years, " + d + " days"); 2522 } 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()"); 2528 delete cal; 2529 return; 2530 } 2531 if (d == 0) { 2532 logln((UnicodeString)"Ok: 2000/Feb/29 - 2004/Feb/29 = " + y + " years, " + d + " days"); 2533 } else { 2534 errln((UnicodeString)"FAIL: 2000/Feb/29 - 2004/Feb/29 = " + y + " years, " + d + " days"); 2535 } 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()"); 2543 delete cal; 2544 return; 2545 } 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()"); 2551 delete cal; 2552 return; 2553 } 2554 if (d == -d2 && d == 13359) { 2555 logln((UnicodeString)"Ok: large field difference symmetrical " + d); 2556 } else { 2557 logln((UnicodeString)"FAIL: large field difference incorrect " + d + ", " + d2 + 2558 ", expect +/- 13359"); 2559 } 2560 delete cal; 2561 } 2562 2563 /** 2564 * Test ms_MY "Malay (Malaysia)" locale. Bug 1543. 2565 */ 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)); 2572 } 2573 delete cal; 2574 } 2575 2576 /** 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. 2580 */ 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)); 2587 return; 2588 } 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. 2593 // August 2001 2594 // Su Mo Tu We Th Fr Sa 2595 // 1 2 3 4 2596 // 5 6 7 8 9 10 11 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) { 2601 if (pass==0) { 2602 cal.setFirstDayOfWeek(UCAL_WEDNESDAY); 2603 cal.setMinimalDaysInFirstWeek(4); 2604 } else { 2605 cal.setFirstDayOfWeek(UCAL_SUNDAY); 2606 cal.setMinimalDaysInFirstWeek(4); 2607 } 2608 cal.add(UCAL_DATE, 1, ec); // Force recalc 2609 cal.add(UCAL_DATE, -1, ec); 2610 2611 UDate time1 = cal.getTime(ec); // Get time -- should not change 2612 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. 2616 if (pass==0) { 2617 cal.setFirstDayOfWeek(UCAL_THURSDAY); 2618 } else { 2619 cal.setMinimalDaysInFirstWeek(5); 2620 } 2621 2622 int32_t woy1 = cal.get(UCAL_WEEK_OF_YEAR, ec); 2623 int32_t wom1 = cal.get(UCAL_WEEK_OF_MONTH, ec); 2624 2625 cal.add(UCAL_DATE, 1, ec); // Force recalc 2626 cal.add(UCAL_DATE, -1, ec); 2627 2628 int32_t woy2 = cal.get(UCAL_WEEK_OF_YEAR, ec); 2629 int32_t wom2 = cal.get(UCAL_WEEK_OF_MONTH, ec); 2630 2631 UDate time2 = cal.getTime(ec); 2632 2633 if (U_FAILURE(ec)) { 2634 errln("FAIL: internal test error"); 2635 return; 2636 } 2637 2638 if (time1 != time2) { 2639 errln("FAIL: shifting week should not alter time"); 2640 } else { 2641 // logln(time1); 2642 } 2643 if (woy1 == woy2 && wom1 == wom2) { 2644 logln((UnicodeString)"Ok: WEEK_OF_YEAR: " + woy1 + 2645 ", WEEK_OF_MONTH: " + wom1); 2646 } else { 2647 errln((UnicodeString)"FAIL: WEEK_OF_YEAR: " + woy1 + " => " + woy2 + 2648 ", WEEK_OF_MONTH: " + wom1 + " => " + wom2 + 2649 " after week shift"); 2650 } 2651 } 2652 } 2653 2654 /** 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. 2658 */ 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); 2663 2664 StringEnumeration *tz = TimeZone::createEnumeration(); 2665 if (tz == NULL) { 2666 dataerrln("FAIL: TimeZone::createEnumeration"); 2667 return; 2668 } 2669 2670 UnicodeString buf1, buf2; 2671 2672 const UChar* id; 2673 while ((id = tz->unext(NULL, ec)) != NULL && U_SUCCESS(ec)) { 2674 if (U_FAILURE(ec)) { 2675 errln("FAIL: StringEnumeration::unext"); 2676 break; 2677 } 2678 2679 TimeZone *t = TimeZone::createTimeZone(id); 2680 if (t == NULL) { 2681 errln("FAIL: TimeZone::createTimeZone"); 2682 break; 2683 } 2684 dateFormat.setTimeZone(*t); 2685 2686 Calendar *cal = Calendar::createInstance(t, locale, ec); 2687 if (cal == NULL || U_FAILURE(ec)) { 2688 errln("FAIL: Calendar::createTimeZone"); 2689 delete cal; 2690 break; 2691 } 2692 2693 cal->clear(); 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); 2698 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)); 2707 buf1.truncate(0); 2708 buf2.truncate(0); 2709 } 2710 } 2711 delete cal; 2712 } 2713 2714 if (U_FAILURE(ec)) { 2715 dataerrln("FAIL: %s", u_errorName(ec)); 2716 } 2717 2718 delete tz; 2719 } 2720 2721 UDate 2722 CalendarRegressionTest::makeDate(int32_t y, int32_t m, int32_t d, 2723 int32_t hr, int32_t min, int32_t sec) 2724 { 2725 UDate result; 2726 2727 UErrorCode status = U_ZERO_ERROR; 2728 Calendar *cal = Calendar::createInstance(status); 2729 cal->clear(); 2730 2731 cal->set(UCAL_YEAR, y); 2732 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); 2738 2739 result = cal->getTime(status); 2740 2741 delete cal; 2742 2743 return result; 2744 } 2745 2746 void CalendarRegressionTest::TestDeprecates(void) 2747 { 2748 UErrorCode status = U_ZERO_ERROR; 2749 Calendar *c1 = Calendar::createInstance("ja_JP@calendar=japanese",status); 2750 Calendar *c2 = Calendar::createInstance("ja_JP_TRADITIONAL",status); 2751 2752 if(!c1 || !c2 || U_FAILURE(status)) { 2753 dataerrln("Couldn't create calendars for roll of HOUR: %s", u_errorName(status)); 2754 return; 2755 } 2756 2757 c2->set(UCAL_HOUR,2); 2758 c1->setTime(c2->getTime(status),status); 2759 // *c1 = *c2; 2760 2761 c1->roll(Calendar::HOUR,(int32_t)3,status); 2762 c2->roll(UCAL_HOUR,(int32_t)3,status); 2763 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)"); 2768 } 2769 2770 c1->setTime(c2->getTime(status),status); 2771 c1->roll(Calendar::HOUR,(UBool)FALSE,status); 2772 c2->roll(UCAL_HOUR,(UBool)FALSE,status); 2773 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)"); 2778 } 2779 2780 delete c1; 2781 delete c2; 2782 2783 status = U_ZERO_ERROR; 2784 2785 c1 = Calendar::createInstance("th_TH_TRADITIONAL",status); 2786 c2 = Calendar::createInstance("th_TH@calendar=buddhist",status); 2787 2788 if(!c1 || !c2 || U_FAILURE(status)) { 2789 errln("Couldn't create calendars for add of HOUR"); 2790 return; 2791 } 2792 2793 c2->set(UCAL_HOUR,2); 2794 c1->setTime(c2->getTime(status),status); 2795 //*c1 = *c2; 2796 2797 c1->add(Calendar::HOUR,(int32_t)1,status); 2798 2799 if(U_FAILURE(status)) { 2800 errln("Error code when trying to add Calendar::HOUR - %s", u_errorName(status)); 2801 } 2802 2803 c2->add(UCAL_HOUR,(int32_t)1,status); 2804 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)"); 2809 } 2810 2811 delete c1; 2812 delete c2; 2813 2814 status = U_ZERO_ERROR; 2815 2816 c1 = Calendar::createInstance("es_ES",status); 2817 c2 = Calendar::createInstance("es_ES",status); 2818 2819 if(!c1 || !c2 || U_FAILURE(status)) { 2820 errln("Couldn't create calendars for add of YEAR"); 2821 return; 2822 } 2823 2824 c2->set(UCAL_YEAR,1900); 2825 c1->setTime(c2->getTime(status),status); 2826 //*c1 = *c2; 2827 2828 c1->add(Calendar::YEAR,(int32_t)9,status); 2829 c2->add(UCAL_YEAR,(int32_t)9,status); 2830 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)"); 2835 } 2836 2837 delete c1; 2838 delete c2; 2839 2840 } 2841 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)); 2848 delete cal; 2849 return; 2850 } 2851 cal->setLenient(FALSE); 2852 cal->clear(); 2853 cal->set(2008, UCAL_DECEMBER, 31); 2854 2855 // Force calculating then fields once. 2856 UDate t = cal->getTime(status); 2857 if(U_FAILURE(status)) { 2858 errln("Error while calculating the date"); 2859 delete cal; 2860 return; 2861 } 2862 2863 UDate expected = 1262246400000.0; // 2009-12-31 00:00 PST 2864 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); 2870 } 2871 } else { 2872 errln("FAIL: error while adding one year"); 2873 } 2874 2875 delete cal; 2876 } 2877 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); 2884 2885 if (U_FAILURE(status)) { 2886 dataerrln("Error creating Calendar: %s", u_errorName(status)); 2887 delete gc; 2888 return; 2889 } 2890 2891 gc->setFirstDayOfWeek(UCAL_MONDAY); 2892 gc->setMinimalDaysInFirstWeek(4); 2893 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); 2898 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); 2902 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); 2907 2908 if (U_FAILURE(status)) { 2909 errln("Error calendar calculation: %s", u_errorName(status)); 2910 delete gc; 2911 return; 2912 } 2913 2914 if (maxWeeks != 53) { 2915 errln((UnicodeString)"FAIL: Max week in 2009 in ISO calendar is 53, but got " + maxWeeks); 2916 } 2917 2918 delete gc; 2919 } 2920 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"); 2927 2928 SimpleDateFormat sdf(UnicodeString("y-MM-dd'T'HH:mm:ssZZZZZ"), status); 2929 failure(status, "initializing SimpleDateFormat"); 2930 sdf.setCalendar(cal); 2931 2932 UnicodeString dstr; 2933 2934 // Set date to 2011-12-29 00:00 2935 cal.clear(); 2936 cal.set(2011, UCAL_DECEMBER, 29, 0, 0, 0); 2937 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); 2942 2943 // Add 1 day 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"); 2948 dstr.remove(); 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); 2952 2953 // Subtract 1 day 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"); 2958 dstr.remove(); 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); 2962 } 2963 } 2964 2965 /** 2966 * @bug ticket 11632 2967 */ 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)); 2973 return; 2974 } 2975 failure(status, "Calendar::createInstance(status)"); 2976 cal.clear(); 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); 2983 UnicodeString dstr; 2984 UDate d = cal.getTime(status); 2985 if (!failure(status, "getTime for date")) { 2986 sdf.format(d, dstr); 2987 std::string utf8; 2988 dstr.toUTF8String(utf8); 2989 assertEquals("correct datetime displayed for hour value", UnicodeString("1970-01-25T21:00:00"), dstr); 2990 cal.clear(); 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")) { 2997 dstr.remove(); 2998 sdf.format(d, dstr); 2999 dstr.toUTF8String(utf8); 3000 assertEquals("correct datetime displayed for hour value", UnicodeString("1970-01-13T12:00:00"), dstr); 3001 } 3002 } 3003 } 3004 3005 /** 3006 * @bug ticket 13454 3007 */ 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)); 3014 } else { 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; 3020 cal->clear(); 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); 3029 } 3030 } 3031 delete cal; 3032 } 3033 } 3034 3035 /** 3036 * @bug tickets 12661, 13538 3037 */ 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)); 3044 } else { 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; 3050 cal->clear(); 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); 3060 } 3061 } 3062 delete cal; 3063 } 3064 } 3065 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)"); 3071 3072 cal->set(UCAL_YEAR, year); 3073 cal->set(UCAL_WEEK_OF_YEAR, 4); 3074 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); 3079 } 3080 } 3081 3082 #endif /* #if !UCONFIG_NO_FORMATTING */ 3083