1 /******************************************************************** 2 * COPYRIGHT: 3 * Copyright (c) 1997-2012, International Business Machines Corporation 4 * and others. All Rights Reserved. 5 ********************************************************************/ 6 7 #include "unicode/utypes.h" 8 9 #if !UCONFIG_NO_FORMATTING 10 11 #include "calregts.h" 12 13 #include "unicode/gregocal.h" 14 #include "unicode/simpletz.h" 15 #include "unicode/smpdtfmt.h" 16 #include "unicode/strenum.h" 17 #include "cmemory.h" 18 #include "caltest.h" 19 #include "unicode/localpointer.h" 20 21 #include <float.h> 22 23 // ***************************************************************************** 24 // class CalendarRegressionTest 25 // ***************************************************************************** 26 27 // these numbers correspond to using LONG_MIN and LONG_MAX in Java 28 // this is 2^52 - 1, the largest allowable mantissa with a 0 exponent in a 64-bit double 29 const UDate CalendarRegressionTest::EARLIEST_SUPPORTED_MILLIS = - 4503599627370495.0; 30 const UDate CalendarRegressionTest::LATEST_SUPPORTED_MILLIS = 4503599627370495.0; 31 32 #define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); logln((UnicodeString)""); test(); } break 33 34 void 35 CalendarRegressionTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ ) 36 { 37 // if (exec) logln((UnicodeString)"TestSuite NumberFormatRegressionTest"); 38 switch (index) { 39 CASE(0,test4100311); 40 CASE(1,test4074758); 41 CASE(2,test4028518); 42 CASE(3,test4031502); 43 CASE(4,test4035301); 44 CASE(5,test4040996); 45 CASE(6,test4051765); 46 CASE(7,test4061476); 47 CASE(8,test4070502); 48 CASE(9,test4071197); 49 CASE(10,test4071385); 50 CASE(11,test4073929); 51 CASE(12,test4083167); 52 CASE(13,test4086724); 53 CASE(14,test4095407); 54 CASE(15,test4096231); 55 CASE(16,test4096539); 56 CASE(17,test41003112); 57 CASE(18,test4103271); 58 CASE(19,test4106136); 59 CASE(20,test4108764); 60 CASE(21,test4114578); 61 CASE(22,test4118384); 62 CASE(23,test4125881); 63 CASE(24,test4125892); 64 CASE(25,test4141665); 65 CASE(26,test4142933); 66 CASE(27,test4145158); 67 CASE(28,test4145983); 68 CASE(29,test4147269); 69 70 CASE(30,Test4149677); 71 CASE(31,Test4162587); 72 CASE(32,Test4165343); 73 CASE(33,Test4166109); 74 CASE(34,Test4167060); 75 CASE(35,Test4197699); 76 CASE(36,TestJ81); 77 CASE(37,TestJ438); 78 CASE(38,TestLeapFieldDifference); 79 CASE(39,TestMalaysianInstance); 80 CASE(40,test4059654); 81 CASE(41,test4092362); 82 CASE(42,TestWeekShift); 83 CASE(43,TestTimeZoneTransitionAdd); 84 CASE(44,TestDeprecates); 85 CASE(45,TestT5555); 86 CASE(46,TestT6745); 87 CASE(47,TestT8057); 88 CASE(48,TestT8596); 89 CASE(49,Test9019); 90 CASE(50,TestT9452); 91 default: name = ""; break; 92 } 93 } 94 95 const char* CalendarRegressionTest::FIELD_NAME [] = { 96 "ERA", 97 "YEAR", 98 "MONTH", 99 "WEEK_OF_YEAR", 100 "WEEK_OF_MONTH", 101 "DAY_OF_MONTH", 102 "DAY_OF_YEAR", 103 "DAY_OF_WEEK", 104 "DAY_OF_WEEK_IN_MONTH", 105 "AM_PM", 106 "HOUR", 107 "HOUR_OF_DAY", 108 "MINUTE", 109 "SECOND", 110 "MILLISECOND", 111 "ZONE_OFFSET", 112 "DST_OFFSET", 113 "YEAR_WOY", 114 "DOW_LOCAL" 115 }; 116 117 UBool 118 CalendarRegressionTest::failure(UErrorCode status, const char* msg) 119 { 120 if(U_FAILURE(status)) { 121 errcheckln(status, UnicodeString("FAIL: ") + msg + " failed, error " + u_errorName(status)); 122 return TRUE; 123 } 124 125 return FALSE; 126 } 127 128 /* 129 * bug 4100311 130 */ 131 void 132 CalendarRegressionTest::test4100311() 133 { 134 UErrorCode status = U_ZERO_ERROR; 135 GregorianCalendar *cal = (GregorianCalendar*)Calendar::createInstance(status); 136 if(U_FAILURE(status)) { 137 dataerrln("Error creating Calendar: %s", u_errorName(status)); 138 delete cal; 139 return; 140 } 141 failure(status, "Calendar::createInstance(status)"); 142 cal->set(UCAL_YEAR, 1997); 143 cal->set(UCAL_DAY_OF_YEAR, 1); 144 UDate d = cal->getTime(status); // Should be Jan 1 145 failure(status, "cal->getTime"); 146 logln(UnicodeString("") + d); 147 delete cal; 148 } 149 150 151 /** 152 * @bug 4074758 153 */ 154 void 155 CalendarRegressionTest::test4074758() 156 { //Set system time to between 12-1 (am or pm) and then run 157 UErrorCode status = U_ZERO_ERROR; 158 GregorianCalendar *cal = new GregorianCalendar(status); 159 if(U_FAILURE(status)) { 160 dataerrln("Error creating Calendar: %s", u_errorName(status)); 161 delete cal; 162 return; 163 } 164 failure(status, "new GregorianCalendar"); 165 for (int32_t h=0; h<25; ++h) { 166 cal->set(97, UCAL_JANUARY, 1, h, 34); 167 //System.out.print(d); 168 logln(UnicodeString("HOUR=") + cal->get(UCAL_HOUR, status)); //prints 0 169 failure(status, "cal->get"); 170 logln(UnicodeString("HOUR_OF_DAY=") + cal->get(UCAL_HOUR_OF_DAY, status)); 171 failure(status, "cal->get"); 172 } 173 174 delete cal; 175 } 176 177 void 178 CalendarRegressionTest::test4028518() 179 { 180 UErrorCode status = U_ZERO_ERROR; 181 GregorianCalendar *cal1 = new GregorianCalendar(status) ; 182 if(U_FAILURE(status)) { 183 dataerrln("Error creating Calendar: %s", u_errorName(status)); 184 delete cal1; 185 return; 186 } 187 failure(status, "new GregorianCalendar"); 188 GregorianCalendar *cal2 = (GregorianCalendar*) cal1->clone() ; 189 190 printdate(cal1, "cal1: ") ; 191 printdate(cal2, "cal2 - cloned(): ") ; 192 cal1->add(UCAL_DATE, 1, status) ; 193 failure(status, "cal1->add"); 194 printdate(cal1, "cal1 after adding 1 day:") ; 195 printdate(cal2, "cal2 should be unmodified:") ; 196 delete cal1; 197 delete cal2; 198 } 199 200 201 void 202 CalendarRegressionTest::Test9019() 203 { 204 UErrorCode status = U_ZERO_ERROR; 205 LocalPointer<GregorianCalendar> cal1(new GregorianCalendar(status)); 206 LocalPointer<GregorianCalendar> cal2(new GregorianCalendar(status)); 207 cal1->set(UCAL_HOUR, 1); 208 cal2->set(UCAL_HOUR,2); 209 cal1->clear(); 210 cal2->clear(); 211 if(U_FAILURE(status)) { 212 dataerrln("Error creating Calendar: %s", u_errorName(status)); 213 return; 214 } 215 failure(status, "new GregorianCalendar"); 216 cal1->set(2011,UCAL_MAY,06); 217 cal2->set(2012,UCAL_JANUARY,06); 218 printdate(cal1.getAlias(), "cal1: ") ; 219 cal1->setLenient(FALSE); 220 cal1->add(UCAL_MONTH,8,status); 221 failure(status, "->add(UCAL_MONTH,8)"); 222 printdate(cal1.getAlias(), "cal1 (lenient) after adding 8 months:") ; 223 printdate(cal2.getAlias(), "cal2 (expected date):") ; 224 225 if(!cal1->equals(*cal2,status)) { 226 errln("Error: cal1 != cal2.\n"); 227 } 228 failure(status, "equals"); 229 } 230 231 void 232 CalendarRegressionTest::printdate(GregorianCalendar *cal, const char *string) 233 { 234 UErrorCode status = U_ZERO_ERROR; 235 logln(UnicodeString(string, "")); 236 log(UnicodeString("") + cal->get(UCAL_MONTH, status)) ; 237 failure(status, "cal->get"); 238 int32_t date = cal->get(UCAL_DATE, status) + 1 ; 239 failure(status, "cal->get"); 240 log(UnicodeString("/") + date) ; 241 logln(UnicodeString("/") + cal->get(UCAL_YEAR, status)) ; 242 failure(status, "cal->get"); 243 } 244 245 /** 246 * @bug 4031502 247 */ 248 void 249 CalendarRegressionTest::test4031502() 250 { 251 // This bug actually occurs on Windows NT as well, and doesn't 252 // require the host zone to be set; it can be set in Java. 253 UErrorCode status = U_ZERO_ERROR; 254 StringEnumeration* ids = TimeZone::createEnumeration(); 255 if (ids == NULL) { 256 dataerrln("Unable to create TimeZone Enumeration."); 257 return; 258 } 259 UBool bad = FALSE; 260 TimeZone* tz =TimeZone::createTimeZone("Asia/Riyadh87"); 261 failure(status, "new TimeZone"); 262 GregorianCalendar *cl = new GregorianCalendar(tz, status); 263 if (U_FAILURE(status)) { 264 dataerrln("Fail new GregorianCalendar: %s", u_errorName(status)); 265 delete tz; 266 return; 267 } 268 cl->clear(); 269 cl->set(1900, 15, 5, 5, 8, 13); 270 cl->get(UCAL_HOUR, status); 271 failure(status, "cl->get(UCAL_HOUR, status)"); 272 status = U_ZERO_ERROR; 273 delete cl; 274 for (int32_t i=0; i<ids->count(status); ++i) { 275 TimeZone *zone = TimeZone::createTimeZone(*ids->snext(status)); 276 GregorianCalendar *cal = new GregorianCalendar(zone, status); 277 failure(status, "new GregorianCalendar"); 278 cal->clear(); 279 cal->set(1900, 15, 5, 5, 8, 13); 280 if (cal->get(UCAL_HOUR, status) != 5 || U_FAILURE(status)) { 281 UnicodeString temp; 282 logln(zone->getID(temp) + " " + 283 //zone.useDaylightTime() + " " + 284 cal->get(UCAL_DST_OFFSET,status) / (60*60*1000) + " " + 285 zone->getRawOffset() / (60*60*1000) + 286 ": HOUR = " + cal->get(UCAL_HOUR,status)); 287 bad = TRUE; 288 } 289 delete cal; 290 } 291 if (bad) 292 errln("TimeZone problems with GC"); 293 // delete [] ids; // TODO: bad APIs 294 delete ids; 295 } 296 297 /** 298 * @bug 4035301 299 */ 300 void CalendarRegressionTest::test4035301() 301 { 302 UErrorCode status = U_ZERO_ERROR; 303 GregorianCalendar *c = new GregorianCalendar(98, 8, 7,status); 304 GregorianCalendar *d = new GregorianCalendar(98, 8, 7,status); 305 if (c->after(*d,status) || 306 c->after(*c,status) || 307 c->before(*d,status) || 308 c->before(*c,status) || 309 *c != *c || 310 *c != *d) 311 dataerrln("Fail"); 312 delete c; 313 delete d; 314 } 315 316 /** 317 * @bug 4040996 318 */ 319 void CalendarRegressionTest::test4040996() 320 { 321 int32_t count = 0; 322 StringEnumeration* ids = TimeZone::createEnumeration(-8 * 60 * 60 * 1000); 323 if (ids == NULL) { 324 dataerrln("Unable to create TimeZone enumeration."); 325 return; 326 } 327 UErrorCode status = U_ZERO_ERROR; 328 count = ids->count(status); 329 SimpleTimeZone *pdt = new SimpleTimeZone(-8 * 60 * 60 * 1000, *ids->snext(status)); 330 pdt->setStartRule(UCAL_APRIL, 1, UCAL_SUNDAY, 2 * 60 * 60 * 1000, status); 331 pdt->setEndRule(UCAL_OCTOBER, -1, UCAL_SUNDAY, 2 * 60 * 60 * 1000, status); 332 Calendar *calendar = new GregorianCalendar(pdt, status); 333 if (U_FAILURE(status)) { 334 dataerrln("Fail new GregorianCalendar: %s", u_errorName(status)); 335 return; 336 } 337 calendar->set(UCAL_MONTH,3); 338 calendar->set(UCAL_DATE,18); 339 calendar->set(UCAL_SECOND, 30); 340 341 logln(UnicodeString("MONTH: ") + calendar->get(UCAL_MONTH, status)); 342 logln(UnicodeString("DAY_OF_MONTH: ") + 343 calendar->get(UCAL_DATE, status)); 344 logln(UnicodeString("MINUTE: ") + calendar->get(UCAL_MINUTE, status)); 345 logln(UnicodeString("SECOND: ") + calendar->get(UCAL_SECOND, status)); 346 347 calendar->add(UCAL_SECOND,6, status); 348 //This will print out todays date for MONTH and DAY_OF_MONTH 349 //instead of the date it was set to. 350 //This happens when adding MILLISECOND or MINUTE also 351 logln(UnicodeString("MONTH: ") + calendar->get(UCAL_MONTH, status)); 352 logln(UnicodeString("DAY_OF_MONTH: ") + 353 calendar->get(UCAL_DATE, status)); 354 logln(UnicodeString("MINUTE: ") + calendar->get(UCAL_MINUTE, status)); 355 logln(UnicodeString("SECOND: ") + calendar->get(UCAL_SECOND, status)); 356 if (calendar->get(UCAL_MONTH, status) != 3 || 357 calendar->get(UCAL_DATE, status) != 18 || 358 calendar->get(UCAL_SECOND, status) != 36) 359 errln(UnicodeString("Fail: Calendar::add misbehaves")); 360 361 delete calendar; 362 delete ids; 363 // delete ids; // TODO: BAD API 364 } 365 366 /** 367 * @bug 4051765 368 */ 369 void CalendarRegressionTest::test4051765() 370 { 371 UErrorCode status = U_ZERO_ERROR; 372 Calendar *cal = Calendar::createInstance(status); 373 if(U_FAILURE(status)) { 374 dataerrln("Error creating Calendar: %s", u_errorName(status)); 375 delete cal; 376 return; 377 } 378 cal->setLenient(FALSE); 379 cal->set(UCAL_DAY_OF_WEEK, 0); 380 //try { 381 cal->getTime(status); 382 if( ! U_FAILURE(status)) 383 errln("Fail: DAY_OF_WEEK 0 should be disallowed"); 384 /*} 385 catch (IllegalArgumentException e) { 386 return; 387 }*/ 388 389 delete cal; 390 } 391 392 /* User error - no bug here 393 void CalendarRegressionTest::test4059524() { 394 // Create calendar for April 10, 1997 395 GregorianCalendar calendar = new GregorianCalendar(status); 396 // print out a bunch of interesting things 397 logln("ERA: " + Calendar::get(Calendar::ERA)); 398 logln("YEAR: " + Calendar::get(Calendar::YEAR)); 399 logln("MONTH: " + Calendar::get(Calendar::MONTH)); 400 logln("WEEK_OF_YEAR: " + 401 Calendar::get(Calendar::WEEK_OF_YEAR)); 402 logln("WEEK_OF_MONTH: " + 403 Calendar::get(Calendar::WEEK_OF_MONTH)); 404 logln("DATE: " + Calendar::get(Calendar::DATE)); 405 logln("DAY_OF_MONTH: " + 406 Calendar::get(Calendar::DAY_OF_MONTH)); 407 logln("DAY_OF_YEAR: " + Calendar::get(Calendar::DAY_OF_YEAR)); 408 logln("DAY_OF_WEEK: " + Calendar::get(Calendar::DAY_OF_WEEK)); 409 logln("DAY_OF_WEEK_IN_MONTH: " + 410 Calendar::get(Calendar::DAY_OF_WEEK_IN_MONTH)); 411 logln("AM_PM: " + Calendar::get(Calendar::AM_PM)); 412 logln("HOUR: " + Calendar::get(Calendar::HOUR)); 413 logln("HOUR_OF_DAY: " + Calendar::get(Calendar::HOUR_OF_DAY)); 414 logln("MINUTE: " + Calendar::get(Calendar::MINUTE)); 415 logln("SECOND: " + Calendar::get(Calendar::SECOND)); 416 logln("MILLISECOND: " + Calendar::get(Calendar::MILLISECOND)); 417 logln("ZONE_OFFSET: " 418 + (Calendar::get(Calendar::ZONE_OFFSET)/(60*60*1000))); 419 logln("DST_OFFSET: " 420 + (Calendar::get(Calendar::DST_OFFSET)/(60*60*1000))); 421 calendar = new GregorianCalendar(1997,3,10); 422 Calendar::getTime(); 423 logln("April 10, 1997"); 424 logln("ERA: " + Calendar::get(Calendar::ERA)); 425 logln("YEAR: " + Calendar::get(Calendar::YEAR)); 426 logln("MONTH: " + Calendar::get(Calendar::MONTH)); 427 logln("WEEK_OF_YEAR: " + 428 Calendar::get(Calendar::WEEK_OF_YEAR)); 429 logln("WEEK_OF_MONTH: " + 430 Calendar::get(Calendar::WEEK_OF_MONTH)); 431 logln("DATE: " + Calendar::get(Calendar::DATE)); 432 logln("DAY_OF_MONTH: " + 433 Calendar::get(Calendar::DAY_OF_MONTH)); 434 logln("DAY_OF_YEAR: " + Calendar::get(Calendar::DAY_OF_YEAR)); 435 logln("DAY_OF_WEEK: " + Calendar::get(Calendar::DAY_OF_WEEK)); 436 logln("DAY_OF_WEEK_IN_MONTH: " + Calendar::get(Calendar::DAY_OF_WEEK_IN_MONTH)); 437 logln("AM_PM: " + Calendar::get(Calendar::AM_PM)); 438 logln("HOUR: " + Calendar::get(Calendar::HOUR)); 439 logln("HOUR_OF_DAY: " + Calendar::get(Calendar::HOUR_OF_DAY)); 440 logln("MINUTE: " + Calendar::get(Calendar::MINUTE)); 441 logln("SECOND: " + Calendar::get(Calendar::SECOND)); 442 logln("MILLISECOND: " + Calendar::get(Calendar::MILLISECOND)); 443 logln("ZONE_OFFSET: " 444 + (Calendar::get(Calendar::ZONE_OFFSET)/(60*60*1000))); // in hours 445 logln("DST_OFFSET: " 446 + (Calendar::get(Calendar::DST_OFFSET)/(60*60*1000))); // in hours 447 } 448 */ 449 450 /** 451 * @bug 4059654 452 */ 453 void CalendarRegressionTest::test4059654() { 454 UErrorCode status = U_ZERO_ERROR; 455 GregorianCalendar *gc = new GregorianCalendar(status); 456 if(U_FAILURE(status)) { 457 dataerrln("Error creating Calendar: %s", u_errorName(status)); 458 delete gc; 459 return; 460 } 461 462 gc->set(1997, 3, 1, 15, 16, 17); // April 1, 1997 463 464 gc->set(UCAL_HOUR, 0); 465 gc->set(UCAL_AM_PM, UCAL_AM); 466 gc->set(UCAL_MINUTE, 0); 467 gc->set(UCAL_SECOND, 0); 468 gc->set(UCAL_MILLISECOND, 0); 469 470 UDate cd = gc->getTime(status); 471 GregorianCalendar *exp = new GregorianCalendar(1997, 3, 1, 0, 0, 0, status); 472 if (cd != exp->getTime(status)) 473 errln(UnicodeString("Fail: Calendar::set broken. Got ") + cd + " Want " + exp->getTime(status)); 474 475 delete gc; 476 delete exp; 477 } 478 479 /** 480 * @bug 4061476 481 */ 482 void CalendarRegressionTest::test4061476() 483 { 484 UErrorCode status = U_ZERO_ERROR; 485 SimpleDateFormat *fmt = new SimpleDateFormat(UnicodeString("ddMMMyy"), Locale::getUK(),status); 486 Calendar *cal = Calendar::createInstance(TimeZone::createTimeZone("GMT"), 487 Locale::getUK(),status); 488 if(U_FAILURE(status)) { 489 dataerrln("Error creating Calendar: %s", u_errorName(status)); 490 delete cal; 491 delete fmt; 492 return; 493 } 494 fmt->adoptCalendar(cal); 495 // try { 496 UDate date = fmt->parse("29MAY97", status); 497 failure(status, "fmt->parse"); 498 cal->setTime(date, status); 499 failure(status, "cal->setTime"); 500 // } 501 //catch (Exception e) {;} 502 cal->set(UCAL_HOUR_OF_DAY, 13); 503 logln(UnicodeString("Hour: ")+cal->get(UCAL_HOUR_OF_DAY, status)); 504 cal->add(UCAL_HOUR_OF_DAY, 6,status); 505 logln(UnicodeString("Hour: ")+cal->get(UCAL_HOUR_OF_DAY, status)); 506 if (cal->get(UCAL_HOUR_OF_DAY, status) != 19) 507 errln(UnicodeString("Fail: Want 19 Got ") + cal->get(UCAL_HOUR_OF_DAY, status)); 508 509 delete fmt; 510 } 511 512 /** 513 * @bug 4070502 514 */ 515 void CalendarRegressionTest::test4070502() 516 { 517 UErrorCode status = U_ZERO_ERROR; 518 Calendar *cal = new GregorianCalendar(status); 519 if(status == U_USING_FALLBACK_WARNING || U_FAILURE(status)) { 520 dataerrln("Error creating Calendar: %s", u_errorName(status)); 521 delete cal; 522 return; 523 } 524 UDate d = getAssociatedDate(makeDate(1998,0,30), status); 525 cal->setTime(d,status); 526 if (cal->get(UCAL_DAY_OF_WEEK,status) == UCAL_SATURDAY || 527 cal->get(UCAL_DAY_OF_WEEK,status) == UCAL_SUNDAY) 528 errln(UnicodeString("Fail: Want weekday Got ") + d); 529 530 delete cal; 531 } 532 533 /** 534 * Get the associated date starting from a specified date 535 * NOTE: the unnecessary "getTime()'s" below are a work-around for a 536 * bug in jdk 1.1.3 (and probably earlier versions also) 537 * <p> 538 * @param date The date to start from 539 */ 540 UDate 541 CalendarRegressionTest::getAssociatedDate(UDate d, UErrorCode& status) 542 { 543 GregorianCalendar *cal = new GregorianCalendar(status); 544 cal->setTime(d,status); 545 //cal.add(field, amount); //<-- PROBLEM SEEN WITH field = DATE,MONTH 546 // cal.getTime(); // <--- REMOVE THIS TO SEE BUG 547 for (;;) { 548 int32_t wd = cal->get(UCAL_DAY_OF_WEEK, status); 549 if (wd == UCAL_SATURDAY || wd == UCAL_SUNDAY) { 550 cal->add(UCAL_DATE, 1, status); 551 // cal.getTime(); 552 } 553 else 554 break; 555 } 556 557 UDate dd = cal->getTime(status); 558 delete cal; 559 return dd; 560 } 561 562 /** 563 * @bug 4071197 564 */ 565 void CalendarRegressionTest::test4071197() 566 { 567 dowTest(FALSE); 568 dowTest(TRUE); 569 } 570 571 void CalendarRegressionTest::dowTest(UBool lenient) 572 { 573 UErrorCode status = U_ZERO_ERROR; 574 GregorianCalendar *cal = new GregorianCalendar(status); 575 if(U_FAILURE(status)) { 576 dataerrln("Error creating Calendar: %s", u_errorName(status)); 577 delete cal; 578 return; 579 } 580 cal->set(1997, UCAL_AUGUST, 12); // Wednesday 581 // cal.getTime(); // Force update 582 cal->setLenient(lenient); 583 cal->set(1996, UCAL_DECEMBER, 1); // Set the date to be December 1, 1996 584 int32_t dow = cal->get(UCAL_DAY_OF_WEEK, status); 585 int32_t min = cal->getMinimum(UCAL_DAY_OF_WEEK); 586 int32_t max = cal->getMaximum(UCAL_DAY_OF_WEEK); 587 //logln(cal.getTime().toString()); 588 if (min != UCAL_SUNDAY || max != UCAL_SATURDAY) 589 errln("FAIL: Min/max bad"); 590 if (dow < min || dow > max) 591 errln("FAIL: Day of week %d out of range [%d,%d]\n", dow, min, max); 592 if (dow != UCAL_SUNDAY) 593 errln("FAIL: Day of week should be SUNDAY Got " + dow); 594 595 if(U_FAILURE(status)) { 596 errln("Error checking Calendar: %s", u_errorName(status)); 597 delete cal; 598 return; 599 } 600 601 if(cal->getActualMinimum(UCAL_DAY_OF_WEEK, status) != min) { 602 errln("FAIL: actual minimum differs from minimum"); 603 } 604 if(cal->getActualMinimum(Calendar::DAY_OF_WEEK, status) != min) { 605 errln("FAIL: actual minimum (Calendar::DAY_OF_WEEK, status) differs from minimum"); 606 } 607 if(cal->getActualMinimum(Calendar::DAY_OF_WEEK) != min) { 608 errln("FAIL: actual minimum (Calendar::DAY_OF_WEEK) differs from minimum"); 609 } 610 if(((Calendar*)cal)->getActualMinimum(UCAL_DAY_OF_WEEK, status) != min) { 611 errln("FAIL: actual minimum (UCAL_DAY_OF_WEEK, status) differs from minimum"); 612 } 613 // NOTE: This function does not exist! jitterbug #3016 614 // if(((Calendar*)cal)->getActualMinimum(Calendar::DAY_OF_WEEK, status) != min) { 615 // errln("FAIL: actual minimum (Calendar::DAY_OF_WEEK, status) differs from minimum"); 616 // } 617 if(U_FAILURE(status)) { 618 errln("Error getting actual minimum: %s", u_errorName(status)); 619 return; 620 } 621 622 delete cal; 623 } 624 625 /** 626 * @bug 4071385 627 */ 628 void CalendarRegressionTest::test4071385() 629 { 630 UErrorCode status = U_ZERO_ERROR; 631 Calendar *cal = Calendar::createInstance(status); 632 if(U_FAILURE(status)) { 633 dataerrln("Error creating Calendar: %s", u_errorName(status)); 634 delete cal; 635 return; 636 } 637 cal->setTime(makeDate(1998, UCAL_JUNE, 24),status); 638 cal->set(UCAL_MONTH, UCAL_NOVEMBER); // change a field 639 //logln(cal.getTime().toString()); 640 if (cal->getTime(status) != makeDate(1998, UCAL_NOVEMBER, 24)) 641 errln("Fail"); 642 643 delete cal; 644 } 645 646 /** 647 * @bug 4073929 648 */ 649 void CalendarRegressionTest::test4073929() 650 { 651 UErrorCode status = U_ZERO_ERROR; 652 GregorianCalendar *foo1 = new GregorianCalendar(1997, 8, 27,status); 653 if(U_FAILURE(status)) { 654 dataerrln("Error creating Calendar: %s", u_errorName(status)); 655 delete foo1; 656 return; 657 } 658 logln("foo1@%.0f - %d-%d-%d %d:%d:%d.%ds\n", foo1->getTime(status), 659 foo1->get(UCAL_YEAR, status), 660 foo1->get(UCAL_MONTH, status), 661 foo1->get(UCAL_DATE, status), 662 foo1->get(UCAL_HOUR, status), 663 foo1->get(UCAL_MINUTE, status), 664 foo1->get(UCAL_SECOND, status), 665 foo1->get(UCAL_MILLISECOND,status)); 666 foo1->add(UCAL_DATE, + 1, status); 667 logln("foo1@%.0f - %d-%d-%d %d:%d:%d.%ds after +\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 685 foo1->add(UCAL_DATE, + 1, status); 686 int32_t testyear = foo1->get(UCAL_YEAR, status); 687 int32_t testmonth = foo1->get(UCAL_MONTH, status); 688 int32_t testday = foo1->get(UCAL_DATE, status); 689 if (testyear != 1997 || 690 testmonth != 8 || 691 testday != 28) 692 errln("Fail: Calendar not initialized"); 693 694 delete foo1; 695 } 696 697 /** 698 * @bug 4083167 699 */ 700 void CalendarRegressionTest::test4083167() 701 { 702 UErrorCode status = U_ZERO_ERROR; 703 TimeZone *saveZone = TimeZone::createDefault(); 704 //try { 705 TimeZone *newZone = TimeZone::createTimeZone("UTC"); 706 TimeZone::setDefault(*newZone); 707 UDate firstDate = Calendar::getNow(); 708 Calendar *cal = new GregorianCalendar(status); 709 if(U_FAILURE(status)) { 710 dataerrln("Error creating Calendar: %s", u_errorName(status)); 711 delete cal; 712 return; 713 } 714 cal->setTime(firstDate,status); 715 int32_t hr = cal->get(UCAL_HOUR_OF_DAY, status); 716 int32_t min = cal->get(UCAL_MINUTE, status); 717 int32_t sec = cal->get(UCAL_SECOND, status); 718 int32_t msec = cal->get(UCAL_MILLISECOND, status); 719 double firstMillisInDay = hr * 3600000 + min * 60000 + sec * 1000 + msec; 720 721 //logln("Current time: " + firstDate.toString()); 722 723 for (int32_t validity=0; validity<30; validity++) { 724 UDate lastDate = firstDate + validity*1000*24*60*60.0; 725 cal->setTime(lastDate, status); 726 hr = cal->get(UCAL_HOUR_OF_DAY, status); 727 min = cal->get(UCAL_MINUTE, status); 728 sec = cal->get(UCAL_SECOND, status); 729 msec = cal->get(UCAL_MILLISECOND, status); 730 double millisInDay = hr * 3600000.0 + min * 60000.0 + sec * 1000.0 + msec; 731 if (firstMillisInDay != millisInDay) 732 errln(UnicodeString("Day has shifted ") + lastDate); 733 } 734 //} 735 //finally { 736 TimeZone::setDefault(*saveZone); 737 //} 738 739 delete saveZone; 740 delete newZone; 741 delete cal; 742 } 743 744 /** 745 * @bug 4086724 746 */ 747 void CalendarRegressionTest::test4086724() 748 { 749 UErrorCode status = U_ZERO_ERROR; 750 SimpleDateFormat *date; 751 TimeZone *saveZone = TimeZone::createDefault(); 752 Locale saveLocale = Locale::getDefault(); 753 //try { 754 Locale::setDefault(Locale::getUK(),status); 755 TimeZone *newZone = TimeZone::createTimeZone("GMT"); 756 TimeZone::setDefault(*newZone); 757 date = new SimpleDateFormat(UnicodeString("dd MMM yyy (zzzz) 'is in week' ww"),status); 758 Calendar *cal = Calendar::createInstance(status); 759 if(U_FAILURE(status)) { 760 dataerrln("Error creating Calendar: %s", u_errorName(status)); 761 delete cal; 762 delete newZone; 763 delete date; 764 return; 765 } 766 cal->set(1997,UCAL_SEPTEMBER,30); 767 UDate now = cal->getTime(status); 768 UnicodeString temp; 769 FieldPosition pos(FieldPosition::DONT_CARE); 770 logln(date->format(now, temp, pos)); 771 cal->set(1997,UCAL_JANUARY,1); 772 now=cal->getTime(status); 773 logln(date->format(now,temp, pos)); 774 cal->set(1997,UCAL_JANUARY,8); 775 now=cal->getTime(status); 776 logln(date->format(now,temp, pos)); 777 cal->set(1996,UCAL_DECEMBER,31); 778 now=cal->getTime(status); 779 logln(date->format(now,temp, pos)); 780 //} 781 //finally { 782 Locale::setDefault(saveLocale,status); 783 TimeZone::setDefault(*saveZone); 784 //} 785 logln("*** THE RESULTS OF THIS TEST MUST BE VERIFIED MANUALLY ***"); 786 787 delete newZone; 788 delete cal; 789 delete date; 790 delete saveZone; 791 } 792 793 /** 794 * @bug 4092362 795 */ 796 void CalendarRegressionTest::test4092362() { 797 UErrorCode status = U_ZERO_ERROR; 798 GregorianCalendar *cal1 = new GregorianCalendar(1997, 10, 11, 10, 20, 40,status); 799 if (U_FAILURE(status)) { 800 dataerrln("Fail new GregorianCalendar: %s", u_errorName(status)); 801 delete cal1; 802 return; 803 } 804 /*cal1.set( Calendar::YEAR, 1997 ); 805 cal1.set( Calendar::MONTH, 10 ); 806 cal1.set( Calendar::DATE, 11 ); 807 cal1.set( Calendar::HOUR, 10 ); 808 cal1.set( Calendar::MINUTE, 20 ); 809 cal1.set( Calendar::SECOND, 40 ); */ 810 811 logln( UnicodeString(" Cal1 = ") + cal1->getTime(status) ); 812 logln( UnicodeString(" Cal1 time in ms = ") + cal1->get(UCAL_MILLISECOND,status) ); 813 for (int32_t k = 0; k < 100 ; k++) 814 ; 815 816 GregorianCalendar *cal2 = new GregorianCalendar(1997, 10, 11, 10, 20, 40,status); 817 /*cal2.set( Calendar::YEAR, 1997 ); 818 cal2.set( Calendar::MONTH, 10 ); 819 cal2.set( Calendar::DATE, 11 ); 820 cal2.set( Calendar::HOUR, 10 ); 821 cal2.set( Calendar::MINUTE, 20 ); 822 cal2.set( Calendar::SECOND, 40 ); */ 823 824 logln( UnicodeString(" Cal2 = ") + cal2->getTime(status) ); 825 logln( UnicodeString(" Cal2 time in ms = ") + cal2->get(UCAL_MILLISECOND,status) ); 826 if( *cal1 != *cal2 ) 827 errln("Fail: Milliseconds randomized"); 828 829 delete cal1; 830 delete cal2; 831 } 832 833 /** 834 * @bug 4095407 835 */ 836 void CalendarRegressionTest::test4095407() 837 { 838 UErrorCode status = U_ZERO_ERROR; 839 GregorianCalendar *a = new GregorianCalendar(1997,UCAL_NOVEMBER, 13,status); 840 if (U_FAILURE(status)) { 841 dataerrln("Fail new GregorianCalendar: %s", u_errorName(status)); 842 delete a; 843 return; 844 } 845 int32_t dow = a->get(UCAL_DAY_OF_WEEK, status); 846 if (dow != UCAL_THURSDAY) 847 errln("Fail: Want THURSDAY Got " + dow); 848 849 delete a; 850 } 851 852 /** 853 * @bug 4096231 854 */ 855 void CalendarRegressionTest::test4096231() 856 { 857 UErrorCode status = U_ZERO_ERROR; 858 TimeZone *GMT = TimeZone::createTimeZone("GMT"); 859 TimeZone *PST = TimeZone::createTimeZone("PST"); 860 int32_t sec = 0, min = 0, hr = 0, day = 1, month = 10, year = 1997; 861 862 Calendar *cal1 = new GregorianCalendar(*PST,status); 863 if (U_FAILURE(status)) { 864 dataerrln("Failure new GregorianCalendar: %s", u_errorName(status)); 865 delete GMT; 866 delete PST; 867 delete cal1; 868 return; 869 } 870 cal1->setTime(880698639000.0,status); 871 // Issue 1: Changing the timezone doesn't change the 872 // represented time. The old API, pre 1.2.2a requires 873 // setTime to be called in order to update the time fields after the time 874 // zone has been set. 875 int32_t h1,h2; 876 logln(UnicodeString("PST 1 is: ") + (h1=cal1->get(UCAL_HOUR_OF_DAY, status))); 877 cal1->setTimeZone(*GMT); 878 logln(UnicodeString("GMT 2 is: ") + (h2=cal1->get(UCAL_HOUR_OF_DAY, status))); 879 if ((*GMT != *PST) && (h1 == h2)) 880 errln("Fail: Hour same in different zones"); 881 882 Calendar *cal2 = new GregorianCalendar(*GMT,status); 883 Calendar *cal3 = new GregorianCalendar(*PST,status); 884 cal2->set(UCAL_MILLISECOND, 0); 885 cal3->set(UCAL_MILLISECOND, 0); 886 887 cal2->set(cal1->get(UCAL_YEAR,status), 888 cal1->get(UCAL_MONTH,status), 889 cal1->get(UCAL_DATE,status), 890 cal1->get(UCAL_HOUR_OF_DAY,status), 891 cal1->get(UCAL_MINUTE,status), 892 cal1->get(UCAL_SECOND,status)); 893 894 double t1,t2,t3,t4; 895 logln(UnicodeString("RGMT 1 is: ") + (t1=cal2->getTime(status))); 896 cal3->set(year, month, day, hr, min, sec); 897 logln(UnicodeString("RPST 1 is: ") + (t2=cal3->getTime(status))); 898 cal3->setTimeZone(*GMT); 899 logln(UnicodeString("RGMT 2 is: ") + (t3=cal3->getTime(status))); 900 cal3->set(cal1->get(UCAL_YEAR,status), 901 cal1->get(UCAL_MONTH,status), 902 cal1->get(UCAL_DATE,status), 903 cal1->get(UCAL_HOUR_OF_DAY,status), 904 cal1->get(UCAL_MINUTE,status), 905 cal1->get(UCAL_SECOND,status)); 906 // Issue 2: Calendar continues to use the timezone in its 907 // constructor for set() conversions, regardless 908 // of calls to setTimeZone() 909 logln(UnicodeString("RGMT 3 is: ") + (t4=cal3->getTime(status))); 910 if (t1 == t2 || 911 t1 != t4 || 912 t2 != t3) 913 errln("Fail: Calendar zone behavior faulty"); 914 915 delete cal1; 916 delete cal2; 917 delete cal3; 918 delete GMT; 919 delete PST; 920 } 921 922 /** 923 * @bug 4096539 924 */ 925 void CalendarRegressionTest::test4096539() 926 { 927 UErrorCode status = U_ZERO_ERROR; 928 int32_t y [] = {31,28,31,30,31,30,31,31,30,31,30,31}; 929 930 for (int32_t x=0;x<12;x++) { 931 GregorianCalendar *gc = new 932 GregorianCalendar(1997,x,y[x], status); 933 if (U_FAILURE(status)) { 934 dataerrln("Fail new GregorianCalendar: %s", u_errorName(status)); 935 delete gc; 936 return; 937 } 938 int32_t m1,m2; 939 log(UnicodeString("") + (m1=gc->get(UCAL_MONTH,status)+1)+UnicodeString("/")+ 940 gc->get(UCAL_DATE,status)+"/"+gc->get(UCAL_YEAR,status)+ 941 " + 1mo = "); 942 943 gc->add(UCAL_MONTH, 1,status); 944 logln(UnicodeString("") + (m2=gc->get(UCAL_MONTH,status)+1)+UnicodeString("/")+ 945 gc->get(UCAL_DATE,status)+"/"+gc->get(UCAL_YEAR,status) 946 ); 947 int32_t m = (m1 % 12) + 1; 948 if (m2 != m) 949 errln(UnicodeString("Fail: Want ") + m + " Got " + m2); 950 delete gc; 951 } 952 953 } 954 955 /** 956 * @bug 4100311 957 */ 958 void CalendarRegressionTest::test41003112() 959 { 960 UErrorCode status = U_ZERO_ERROR; 961 GregorianCalendar *cal = (GregorianCalendar*)Calendar::createInstance(status); 962 if(U_FAILURE(status)) { 963 dataerrln("Error creating calendar: %s", u_errorName(status)); 964 delete cal; 965 return; 966 } 967 cal->set(UCAL_YEAR, 1997); 968 cal->set(UCAL_DAY_OF_YEAR, 1); 969 //UDate d = cal->getTime(status); // Should be Jan 1 970 //logln(d.toString()); 971 if (cal->get(UCAL_DAY_OF_YEAR, status) != 1) 972 errln("Fail: DAY_OF_YEAR not set"); 973 delete cal; 974 } 975 976 /** 977 * @bug 4103271 978 */ 979 void CalendarRegressionTest::test4103271() 980 { 981 UErrorCode status = U_ZERO_ERROR; 982 SimpleDateFormat sdf(status); 983 int32_t numYears=40, startYear=1997, numDays=15; 984 UnicodeString output, testDesc, str, str2; 985 GregorianCalendar *testCal = (GregorianCalendar*)Calendar::createInstance(status); 986 if(U_FAILURE(status)) { 987 dataerrln("Error creating calendar: %s", u_errorName(status)); 988 delete testCal; 989 return; 990 } 991 testCal->clear(); 992 sdf.adoptCalendar(testCal); 993 sdf.applyPattern("EEE dd MMM yyyy 'WOY'ww'-'YYYY 'DOY'DDD"); 994 UBool fail = FALSE; 995 for (int32_t firstDay=1; firstDay<=2; firstDay++) { 996 for (int32_t minDays=1; minDays<=7; minDays++) { 997 testCal->setMinimalDaysInFirstWeek((uint8_t)minDays); 998 testCal->setFirstDayOfWeek((UCalendarDaysOfWeek)firstDay); 999 testDesc = (UnicodeString("Test") + firstDay + minDays); 1000 logln(testDesc + " => 1st day of week=" + 1001 firstDay + 1002 ", minimum days in first week=" + 1003 minDays); 1004 for (int32_t j=startYear; j<=startYear+numYears; j++) { 1005 testCal->set(j,11,25); 1006 for(int32_t i=0; i<numDays; i++) { 1007 testCal->add(UCAL_DATE,1,status); 1008 UnicodeString calWOY; 1009 int32_t actWOY = testCal->get(UCAL_WEEK_OF_YEAR,status); 1010 if (actWOY < 1 || actWOY > 53) { 1011 UDate d = testCal->getTime(status); 1012 //calWOY = String.valueOf(actWOY); 1013 UnicodeString temp; 1014 FieldPosition pos(FieldPosition::DONT_CARE); 1015 output = testDesc + " - " + sdf.format(d,temp,pos) + "\t"; 1016 output = output + "\t" + actWOY; 1017 logln(output); 1018 fail = TRUE; 1019 } 1020 } 1021 } 1022 } 1023 } 1024 1025 int32_t DATA [] = { 1026 3, 52, 52, 52, 52, 52, 52, 52, 1027 1, 1, 1, 1, 1, 1, 1, 1028 2, 2, 2, 2, 2, 2, 2, 1029 4, 52, 52, 52, 52, 52, 52, 52, 1030 53, 53, 53, 53, 53, 53, 53, 1031 1, 1, 1, 1, 1, 1, 1, 1032 }; 1033 testCal->setFirstDayOfWeek(UCAL_SUNDAY); 1034 for (int32_t j=0; j<44; j+=22) { 1035 logln(UnicodeString("Minimal days in first week = ") + DATA[j] + 1036 " Week starts on Sunday"); 1037 testCal->setMinimalDaysInFirstWeek((uint8_t)DATA[j]); 1038 testCal->set(1997, UCAL_DECEMBER, 21); 1039 for (int32_t i=0; i<21; ++i) { 1040 int32_t woy = testCal->get(UCAL_WEEK_OF_YEAR,status); 1041 str.remove(); 1042 log(UnicodeString("") + sdf.format(testCal->getTime(status), str) + 1043 UnicodeString(" ") + woy); 1044 if (woy != DATA[j + 1 + i]) { 1045 log(" ERROR"); 1046 fail = TRUE; 1047 } 1048 logln(""); 1049 1050 // Now compute the time from the fields, and make sure we 1051 // get the same answer back. This is a round-trip test. 1052 UDate save = testCal->getTime(status); 1053 testCal->clear(); 1054 testCal->set(UCAL_YEAR_WOY, DATA[j+1+i] < 25 ? 1998 : 1997); 1055 testCal->set(UCAL_WEEK_OF_YEAR, DATA[j+1+i]); 1056 testCal->set(UCAL_DAY_OF_WEEK, (i%7) + UCAL_SUNDAY); 1057 if (testCal->getTime(status) != save) { 1058 str.remove(); 1059 logln(UnicodeString(" Parse failed: ") + 1060 sdf.format(testCal->getTime(status), str)); 1061 fail= TRUE; 1062 } 1063 1064 testCal->setTime(save,status); 1065 testCal->add(UCAL_DATE, 1,status); 1066 } 1067 } 1068 // Test field disambiguation with a few special hard-coded cases. 1069 // This shouldn't fail if the above cases aren't failing. 1070 int32_t DISAM_int [] = { 1071 // y y_woy woy dow 1072 1997, 1998, 1, UCAL_SUNDAY, 1073 (1998), (1998), (2), (UCAL_SATURDAY), 1074 (1998), (1998), (53), (UCAL_THURSDAY), 1075 (1999), (1998), (53), (UCAL_FRIDAY) 1076 }; 1077 1078 UDate DISAM_date [] = { 1079 makeDate(1997, UCAL_DECEMBER, 28), 1080 makeDate(1998, UCAL_JANUARY, 10), 1081 makeDate(1998, UCAL_DECEMBER, 31), 1082 makeDate(1999, UCAL_JANUARY, 1) 1083 }; 1084 1085 testCal->setMinimalDaysInFirstWeek(3); 1086 testCal->setFirstDayOfWeek(UCAL_SUNDAY); 1087 int32_t i = 0; 1088 1089 /* Enable this code to display various WOY values 1090 testCal->clear(); 1091 for (i=25; i<38; ++i) { 1092 testCal->set(1996, Calendar::DECEMBER, i); 1093 UDate got = testCal->getTime(status); 1094 str.remove(); 1095 logln(UnicodeString("") + sdf.format(got, str)); 1096 } 1097 for (i=25; i<38; ++i) { 1098 testCal->set(1997, Calendar::DECEMBER, i); 1099 UDate got = testCal->getTime(status); 1100 str.remove(); 1101 logln(UnicodeString("") + sdf.format(got, str)); 1102 } 1103 for (i=25; i<38; ++i) { 1104 testCal->set(1998, UCAL_DECEMBER, i); 1105 UDate got = testCal->getTime(status); 1106 str.remove(); 1107 logln(UnicodeString("") + sdf.format(got, str)); 1108 } 1109 */ 1110 1111 for (i=0; i < 16; i += 4) { 1112 int32_t y = DISAM_int[i]; 1113 int32_t ywoy = DISAM_int[i+1]; 1114 int32_t woy = DISAM_int[i+2]; 1115 int32_t dow = DISAM_int[i+3]; 1116 UDate exp = DISAM_date[i/4]; 1117 testCal->clear(); 1118 testCal->set(UCAL_YEAR, y); 1119 testCal->set(UCAL_WEEK_OF_YEAR, woy); 1120 testCal->set(UCAL_DAY_OF_WEEK, dow); 1121 UDate got = testCal->getTime(status); 1122 str.remove(); 1123 str2.remove(); 1124 log(UnicodeString("Y") + y + "-W" + woy + 1125 "-DOW" + dow + " expect:" + sdf.format(exp, str) + 1126 " got:" + sdf.format(got, str2)); 1127 if (got != exp) { 1128 log(" FAIL (%s:%d, i=%d)", __FILE__, __LINE__, i); 1129 logln(CalendarTest::calToStr(*testCal)); 1130 testCal->setTime(exp, status); 1131 logln(CalendarTest::calToStr(*testCal) + UnicodeString( " <<< expected ")); 1132 fail = TRUE; 1133 } 1134 logln(""); 1135 1136 testCal->clear(); 1137 testCal->set(UCAL_YEAR_WOY, ywoy); 1138 testCal->set(UCAL_WEEK_OF_YEAR, woy); 1139 testCal->set(UCAL_DAY_OF_WEEK, dow); 1140 got = testCal->getTime(status); 1141 str.remove(); 1142 str2.remove(); 1143 log(UnicodeString("YWOY") + ywoy + "-W" + woy + 1144 "-DOW" + dow + " expect:" + sdf.format(exp, str) + 1145 " got:" + sdf.format(got, str2)); 1146 if (got != exp) { 1147 log(" FAIL"); 1148 fail = TRUE; 1149 } 1150 logln(""); 1151 } 1152 // Now try adding and rolling 1153 UDate ADDROLL_date [] = { 1154 makeDate(1998, UCAL_DECEMBER, 25), makeDate(1999, UCAL_JANUARY, 1), 1155 makeDate(1997, UCAL_DECEMBER, 28), makeDate(1998, UCAL_JANUARY, 4), 1156 makeDate(1998, UCAL_DECEMBER, 27), makeDate(1997, UCAL_DECEMBER, 28), 1157 makeDate(1999, UCAL_JANUARY, 2), makeDate(1998, UCAL_JANUARY, 3), 1158 }; 1159 1160 int32_t ADDROLL_int []= { 1161 (1), 1162 (1), 1163 (1), 1164 (1) 1165 }; 1166 1167 1168 UBool ADDROLL_bool [] = { 1169 TRUE,//ADD, 1170 TRUE, 1171 FALSE, 1172 FALSE 1173 }; 1174 1175 testCal->setMinimalDaysInFirstWeek(3); 1176 testCal->setFirstDayOfWeek(UCAL_SUNDAY); 1177 for (i=0; i<8; i += 2) { 1178 int32_t amount = ADDROLL_int[i/2]; 1179 UDate before = ADDROLL_date[i]; 1180 UDate after = ADDROLL_date[i+1]; 1181 1182 testCal->setTime(before,status); 1183 if (ADDROLL_bool[i/2]) 1184 testCal->add(UCAL_WEEK_OF_YEAR, amount,status); 1185 else 1186 testCal->roll(UCAL_WEEK_OF_YEAR, amount,status); 1187 UDate got = testCal->getTime(status); 1188 str.remove(); 1189 str2.remove(); 1190 UnicodeString opTypeStr; 1191 if (ADDROLL_bool[i/2]) { 1192 opTypeStr = UnicodeString("add(WOY,", ""); 1193 } else { 1194 opTypeStr = UnicodeString("roll(WOY,", ""); 1195 } 1196 log(opTypeStr + amount + ") " + sdf.format(before, str) + " => " + 1197 sdf.format(got, str2)); 1198 if (after != got) { 1199 str.remove(); 1200 logln(UnicodeString(" exp:") + sdf.format(after, str) + " FAIL"); 1201 fail = TRUE; 1202 } 1203 else logln(" ok"); 1204 1205 testCal->setTime(after,status); 1206 if (ADDROLL_bool[i/2]) 1207 testCal->add(UCAL_WEEK_OF_YEAR, -amount,status); 1208 else 1209 testCal->roll(UCAL_WEEK_OF_YEAR, -amount,status); 1210 got = testCal->getTime(status); 1211 str.remove(); 1212 str2.remove(); 1213 log(opTypeStr + (-amount) + ") " + sdf.format(after, str) + " => " + 1214 sdf.format(got, str2)); 1215 if (before != got) { 1216 str.remove(); 1217 logln(UnicodeString(" exp:") + sdf.format(before, str) + " FAIL"); 1218 fail = TRUE; 1219 } 1220 else logln(" ok"); 1221 } 1222 if (fail) 1223 errln("Fail: Week of year misbehaving"); 1224 } 1225 1226 /** 1227 * @bug 4106136 1228 */ 1229 void CalendarRegressionTest::test4106136() 1230 { 1231 UErrorCode status = U_ZERO_ERROR; 1232 Locale saveLocale = Locale::getDefault(); 1233 //try { 1234 Locale locales [] = { Locale::getChinese(), Locale::getChina() }; 1235 for (int32_t i=0; i<2; ++i) { 1236 Locale::setDefault(locales[i], status); 1237 failure(status, "Locale::setDefault"); 1238 int32_t count1, count2, count3; 1239 Calendar::getAvailableLocales(count1); 1240 DateFormat::getAvailableLocales(count2); 1241 NumberFormat::getAvailableLocales(count3); 1242 int32_t n [] = { 1243 count1, count2, count3 1244 }; 1245 for (int32_t j=0; j<3; ++j) { 1246 UnicodeString temp; 1247 if (n[j] == 0) 1248 dataerrln(UnicodeString("Fail: No locales for ") + locales[i].getName()); 1249 } 1250 } 1251 //} 1252 //finally { 1253 Locale::setDefault(saveLocale,status); 1254 //} 1255 } 1256 1257 /** 1258 * @bug 4108764 1259 */ 1260 void CalendarRegressionTest::test4108764() 1261 { 1262 UErrorCode status = U_ZERO_ERROR; 1263 Calendar *cal = Calendar::createInstance(status); 1264 if(U_FAILURE(status)) { 1265 dataerrln("Error creating calendar %s", u_errorName(status)); 1266 delete cal; 1267 return; 1268 } 1269 UDate d00 = makeDate(1997, UCAL_MARCH, 15, 12, 00, 00); 1270 UDate d01 = makeDate(1997, UCAL_MARCH, 15, 12, 00, 56); 1271 UDate d10 = makeDate(1997, UCAL_MARCH, 15, 12, 34, 00); 1272 UDate d11 = makeDate(1997, UCAL_MARCH, 15, 12, 34, 56); 1273 UDate epoch = makeDate(1970, UCAL_JANUARY, 1); 1274 1275 cal->setTime(d11,status); 1276 1277 cal->clear( UCAL_MINUTE ); 1278 logln(UnicodeString("") + cal->getTime(status)); 1279 if (cal->getTime(status) != d01) 1280 errln("Fail: clear(MINUTE) broken"); 1281 1282 cal->set( UCAL_SECOND, 0 ); 1283 logln(UnicodeString("") + cal->getTime(status)); 1284 if (cal->getTime(status) != d00) 1285 errln("Fail: set(SECOND, 0) broken"); 1286 1287 cal->setTime(d11,status); 1288 cal->set( UCAL_SECOND, 0 ); 1289 logln(UnicodeString("") + cal->getTime(status)); 1290 if (cal->getTime(status) != d10) 1291 errln("Fail: set(SECOND, 0) broken #2"); 1292 1293 cal->clear( UCAL_MINUTE ); 1294 logln(UnicodeString("") + cal->getTime(status)); 1295 if (cal->getTime(status) != d00) 1296 errln("Fail: clear(MINUTE) broken #2"); 1297 1298 cal->clear(); 1299 logln(UnicodeString("") + cal->getTime(status)); 1300 if (cal->getTime(status) != epoch) 1301 errln(UnicodeString("Fail: clear() broken Want ") + epoch); 1302 1303 delete cal; 1304 } 1305 1306 /** 1307 * @bug 4114578 1308 */ 1309 void CalendarRegressionTest::test4114578() 1310 { 1311 UErrorCode status = U_ZERO_ERROR; 1312 double ONE_HOUR = 60*60*1000; 1313 Calendar *cal = Calendar::createInstance(status); 1314 if(U_FAILURE(status)) { 1315 dataerrln("Error creating calendar %s", u_errorName(status)); 1316 delete cal; 1317 return; 1318 } 1319 cal->adoptTimeZone(TimeZone::createTimeZone("PST")); 1320 UDate onset = makeDate(1998, UCAL_APRIL, 5, 1, 0) + ONE_HOUR; 1321 UDate cease = makeDate(1998, UCAL_OCTOBER, 25, 0, 0) + 2*ONE_HOUR; 1322 1323 UBool fail = FALSE; 1324 1325 const int32_t ADD = 1; 1326 const int32_t ROLL = 2; 1327 1328 double DATA []= { 1329 // Start Action Amt Expected_change 1330 onset - ONE_HOUR, ADD, 1, ONE_HOUR, 1331 onset, ADD, -1, -ONE_HOUR, 1332 onset - ONE_HOUR, ROLL, 1, ONE_HOUR, 1333 onset, ROLL, -1, -ONE_HOUR, 1334 cease - ONE_HOUR, ADD, 1, ONE_HOUR, 1335 cease, ADD, -1, -ONE_HOUR, 1336 cease - ONE_HOUR, ROLL, 1, ONE_HOUR, 1337 cease, ROLL, -1, -ONE_HOUR, 1338 }; 1339 1340 for (int32_t i=0; i<32; i+=4) { 1341 UDate date = DATA[i]; 1342 int32_t amt = (int32_t) DATA[i+2]; 1343 double expectedChange = DATA[i+3]; 1344 1345 log(UnicodeString("") + date); 1346 cal->setTime(date,status); 1347 1348 switch ((int32_t) DATA[i+1]) { 1349 case ADD: 1350 log(UnicodeString(" add (HOUR,") + (amt<0?"":"+")+amt + ")= "); 1351 cal->add(UCAL_HOUR, amt,status); 1352 break; 1353 case ROLL: 1354 log(UnicodeString(" roll(HOUR,") + (amt<0?"":"+")+amt + ")= "); 1355 cal->roll(UCAL_HOUR, amt,status); 1356 break; 1357 } 1358 1359 log(UnicodeString("") + cal->getTime(status)); 1360 1361 double change = cal->getTime(status) - date; 1362 if (change != expectedChange) { 1363 fail = TRUE; 1364 logln(" FAIL"); 1365 } 1366 else logln(" OK"); 1367 } 1368 1369 if (fail) errln("Fail: roll/add misbehaves around DST onset/cease"); 1370 1371 delete cal; 1372 } 1373 1374 /** 1375 * @bug 4118384 1376 * Make sure maximum for HOUR field is 11, not 12. 1377 */ 1378 void CalendarRegressionTest::test4118384() 1379 { 1380 UErrorCode status = U_ZERO_ERROR; 1381 Calendar *cal = Calendar::createInstance(status); 1382 if(U_FAILURE(status)) { 1383 dataerrln("Error creating calendar %s", u_errorName(status)); 1384 delete cal; 1385 return; 1386 } 1387 if (cal->getMaximum(UCAL_HOUR) != 11 || 1388 cal->getLeastMaximum(UCAL_HOUR) != 11 || 1389 cal->getActualMaximum(UCAL_HOUR,status) != 11) 1390 errln("Fail: maximum of HOUR field should be 11"); 1391 1392 // test deprecated functions 1393 if (cal->getLeastMaximum(Calendar::HOUR) != 11 || 1394 cal->getMaximum(Calendar::HOUR) != 11) { 1395 errln("Fail: [deprecated functions] maximum of HOUR field should be 11\n"); 1396 } 1397 1398 if (cal->getGreatestMinimum(Calendar::HOUR) != 0 || 1399 cal->getMinimum(Calendar::HOUR) != 0) { 1400 errln("Fail: [deprecated functions] minimum of HOUR field should be 1\n"); 1401 } 1402 1403 delete cal; 1404 cal = Calendar::createInstance(Locale("th_TH@calendar=buddhist"),status); 1405 // test deprecated functions 1406 if (cal->getLeastMaximum(Calendar::HOUR) != 11 || 1407 cal->getMaximum(Calendar::HOUR) != 11) { 1408 errln("Fail: Buddhist:[deprecated functions] maximum of HOUR field should be 11\n"); 1409 } 1410 1411 if (cal->getGreatestMinimum(Calendar::HOUR) != 0 || 1412 cal->getMinimum(Calendar::HOUR) != 0) { 1413 errln("Fail: Buddhist:[deprecated functions] minimum of HOUR field should be 1\n"); 1414 } 1415 1416 delete cal; 1417 // test deprecated functions 1418 cal = Calendar::createInstance(Locale("ja_JP@calendar=japanese"),status); 1419 if (cal->getLeastMaximum(Calendar::HOUR) != 11 || 1420 cal->getMaximum(Calendar::HOUR) != 11) { 1421 errln("Fail: Japanese:[deprecated functions] maximum of HOUR field should be 11\n"); 1422 } 1423 1424 if (cal->getGreatestMinimum(Calendar::HOUR) != 0 || 1425 cal->getMinimum(Calendar::HOUR) != 0) { 1426 errln("Fail: Japanese:[deprecated functions] minimum of HOUR field should be 1\n"); 1427 } 1428 1429 delete cal; 1430 } 1431 1432 /** 1433 * @bug 4125881 1434 * Check isLeapYear for BC years. 1435 */ 1436 void CalendarRegressionTest::test4125881() 1437 { 1438 UErrorCode status = U_ZERO_ERROR; 1439 GregorianCalendar *cal = (GregorianCalendar*) Calendar::createInstance(status); 1440 if(U_FAILURE(status)) { 1441 dataerrln("Error creating calendar %s", u_errorName(status)); 1442 delete cal; 1443 return; 1444 } 1445 DateFormat *fmt = new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"),status); 1446 if(U_FAILURE(status)) { 1447 dataerrln("Error creating SimpleDateFormat - %s", u_errorName(status)); 1448 delete cal; 1449 return; 1450 } 1451 cal->clear(); 1452 for (int32_t y=-20; y<=10; ++y) { 1453 cal->set(UCAL_ERA, y < 1 ? GregorianCalendar::BC : GregorianCalendar::AD); 1454 cal->set(UCAL_YEAR, y < 1 ? 1 - y : y); 1455 UnicodeString temp; 1456 logln(UnicodeString("") + y + UnicodeString(" = ") + fmt->format(cal->getTime(status), temp) + " " + 1457 cal->isLeapYear(y)); 1458 if (cal->isLeapYear(y) != ((y+40)%4 == 0)) 1459 errln("Leap years broken"); 1460 } 1461 1462 delete cal; 1463 delete fmt; 1464 } 1465 1466 /** 1467 * @bug 4125892 1468 * Prove that GregorianCalendar is proleptic (it used to cut off 1469 * at 45 BC, and not have leap years before then). 1470 */ 1471 void CalendarRegressionTest::test4125892() { 1472 UErrorCode status = U_ZERO_ERROR; 1473 GregorianCalendar *cal = (GregorianCalendar*) Calendar::createInstance(status); 1474 if(U_FAILURE(status)) { 1475 dataerrln("Error creating calendar %s", u_errorName(status)); 1476 delete cal; 1477 return; 1478 } 1479 DateFormat *fmt = new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"),status); 1480 if(U_FAILURE(status)) { 1481 dataerrln("Error creating SimpleDateFormat - %s", u_errorName(status)); 1482 delete cal; 1483 return; 1484 } 1485 cal->clear(); 1486 cal->set(UCAL_ERA, GregorianCalendar::BC); 1487 cal->set(UCAL_YEAR, 81); // 81 BC is a leap year (proleptically) 1488 cal->set(UCAL_MONTH, UCAL_FEBRUARY); 1489 cal->set(UCAL_DATE, 28); 1490 cal->add(UCAL_DATE, 1,status); 1491 if(U_FAILURE(status)) 1492 errln("add(DATE,1) failed"); 1493 if (cal->get(UCAL_DATE,status) != 29 || 1494 !cal->isLeapYear(-80)) // -80 == 81 BC 1495 errln("Calendar not proleptic"); 1496 1497 delete cal; 1498 delete fmt; 1499 } 1500 1501 /** 1502 * @bug 4141665 1503 * GregorianCalendar::equals() ignores cutover date 1504 */ 1505 void CalendarRegressionTest::test4141665() 1506 { 1507 UErrorCode status = U_ZERO_ERROR; 1508 GregorianCalendar *cal = new GregorianCalendar(status); 1509 if(U_FAILURE(status)) { 1510 dataerrln("Error creating calendar %s", u_errorName(status)); 1511 delete cal; 1512 return; 1513 } 1514 GregorianCalendar *cal2 = (GregorianCalendar*)cal->clone(); 1515 UDate cut = cal->getGregorianChange(); 1516 UDate cut2 = cut + 100*24*60*60*1000.0; // 100 days later 1517 if (*cal != *cal2) { 1518 errln("Cloned GregorianCalendars not equal"); 1519 } 1520 cal2->setGregorianChange(cut2,status); 1521 if ( *cal == *cal2) { 1522 errln("GregorianCalendar::equals() ignores cutover"); 1523 } 1524 1525 delete cal; 1526 delete cal2; 1527 } 1528 1529 /** 1530 * @bug 4142933 1531 * Bug states that ArrayIndexOutOfBoundsException is thrown by GregorianCalendar::roll() 1532 * when IllegalArgumentException should be. 1533 */ 1534 void CalendarRegressionTest::test4142933() 1535 { 1536 UErrorCode status = U_ZERO_ERROR; 1537 GregorianCalendar *calendar = new GregorianCalendar(status); 1538 if(U_FAILURE(status)) { 1539 dataerrln("Error creating calendar %s", u_errorName(status)); 1540 delete calendar; 1541 return; 1542 } 1543 //try { 1544 calendar->roll((UCalendarDateFields)-1, TRUE, status); 1545 if(U_SUCCESS(status)) 1546 errln("Test failed, no exception thrown"); 1547 //} 1548 //catch (IllegalArgumentException e) { 1549 // OK: Do nothing 1550 // logln("Test passed"); 1551 //} 1552 //catch (Exception e) { 1553 //errln("Test failed. Unexpected exception is thrown: " + e); 1554 //e.printStackTrace(); 1555 //} 1556 1557 delete calendar; 1558 } 1559 1560 /** 1561 * @bug 4145158 1562 * GregorianCalendar handling of Dates Long.MIN_VALUE and Long.MAX_VALUE is 1563 * confusing; unless the time zone has a raw offset of zero, one or the 1564 * other of these will wrap. We've modified the test given in the bug 1565 * report to therefore only check the behavior of a calendar with a zero raw 1566 * offset zone. 1567 */ 1568 void CalendarRegressionTest::test4145158() 1569 { 1570 UErrorCode status = U_ZERO_ERROR; 1571 GregorianCalendar *calendar = new GregorianCalendar(status); 1572 if(status == U_USING_FALLBACK_WARNING || U_FAILURE(status)) { 1573 dataerrln("Error creating calendar %s", u_errorName(status)); 1574 delete calendar; 1575 return; 1576 } 1577 1578 calendar->adoptTimeZone(TimeZone::createTimeZone("GMT")); 1579 1580 calendar->setTime(makeDate(INT32_MIN),status); 1581 int32_t year1 = calendar->get(UCAL_YEAR,status); 1582 int32_t era1 = calendar->get(UCAL_ERA,status); 1583 1584 calendar->setTime(makeDate(INT32_MAX),status); 1585 int32_t year2 = calendar->get(UCAL_YEAR,status); 1586 int32_t era2 = calendar->get(UCAL_ERA,status); 1587 1588 if (year1 == year2 && era1 == era2) { 1589 errln("Fail: Long.MIN_VALUE or Long.MAX_VALUE wrapping around"); 1590 } 1591 1592 delete calendar; 1593 } 1594 1595 /** 1596 * @bug 4145983 1597 * Maximum value for YEAR field wrong. 1598 */ 1599 // {sfb} this is not directly applicable in C++, since all 1600 // possible doubles are not representable by our Calendar. 1601 // In Java, all longs are representable. 1602 // We can determine limits programmatically 1603 // Using DBL_MAX is a bit of a hack, since for large doubles 1604 // Calendar gets squirrely and doesn't behave in any sort 1605 // of linear fashion (ie years jump around, up/down, etc) for a 1606 // small change in millis. 1607 void CalendarRegressionTest::test4145983() 1608 { 1609 UErrorCode status = U_ZERO_ERROR; 1610 GregorianCalendar *calendar = new GregorianCalendar(status); 1611 if(U_FAILURE(status)) { 1612 dataerrln("Error creating calendar %s", u_errorName(status)); 1613 delete calendar; 1614 return; 1615 } 1616 calendar->adoptTimeZone(TimeZone::createTimeZone("GMT")); 1617 UDate DATES [] = { LATEST_SUPPORTED_MILLIS, EARLIEST_SUPPORTED_MILLIS }; 1618 for (int32_t i=0; i<2; ++i) { 1619 calendar->setTime(DATES[i], status); 1620 int32_t year = calendar->get(UCAL_YEAR,status); 1621 int32_t maxYear = calendar->getMaximum(UCAL_YEAR); 1622 if (year > maxYear) { 1623 errln(UnicodeString("Failed for ")+DATES[i]+" ms: year=" + 1624 year + ", maxYear=" + maxYear); 1625 } 1626 } 1627 1628 delete calendar; 1629 } 1630 1631 /** 1632 * @bug 4147269 1633 * This is a bug in the validation code of GregorianCalendar:: As reported, 1634 * the bug seems worse than it really is, due to a bug in the way the bug 1635 * report test was written. In reality the bug is restricted to the DAY_OF_YEAR 1636 * field. - liu 6/29/98 1637 */ 1638 void CalendarRegressionTest::test4147269() 1639 { 1640 UErrorCode status = U_ZERO_ERROR; 1641 GregorianCalendar *calendar = new GregorianCalendar(status); 1642 if(status == U_USING_FALLBACK_WARNING || U_FAILURE(status)) { 1643 dataerrln("Error creating calendar %s", u_errorName(status)); 1644 delete calendar; 1645 return; 1646 } 1647 calendar->setLenient(FALSE); 1648 UDate date = makeDate(1996, UCAL_JANUARY, 3); // Arbitrary date 1649 for (int32_t field = 0; field < UCAL_FIELD_COUNT; field++) { 1650 calendar->setTime(date,status); 1651 // Note: In the bug report, getActualMaximum() was called instead 1652 // of getMaximum() -- this was an error. The validation code doesn't 1653 // use getActualMaximum(), since that's too costly. 1654 int32_t max = calendar->getMaximum((UCalendarDateFields)field); 1655 int32_t value = max+1; 1656 calendar->set((UCalendarDateFields)field, value); 1657 //try { 1658 calendar->getTime(status); // Force time computation 1659 // We expect an exception to be thrown. If we fall through 1660 // to the next line, then we have a bug. 1661 if(U_SUCCESS(status)) 1662 errln(UnicodeString("Test failed with field ") + FIELD_NAME[field] + 1663 ", date before: " + date + 1664 ", date after: " + calendar->getTime(status) + 1665 ", value: " + value + " (max = " + max +")"); 1666 //} catch (IllegalArgumentException e) {} 1667 } 1668 1669 delete calendar; 1670 } 1671 1672 /** 1673 * @bug 4149677 1674 * Reported bug is that a GregorianCalendar with a cutover of Date(Long.MAX_VALUE) 1675 * doesn't behave as a pure Julian calendar. 1676 * CANNOT REPRODUCE THIS BUG 1677 */ 1678 void 1679 CalendarRegressionTest::Test4149677() 1680 { 1681 UErrorCode status = U_ZERO_ERROR; 1682 1683 TimeZone *zones [] = { 1684 TimeZone::createTimeZone("GMT"), 1685 TimeZone::createTimeZone("PST"), 1686 TimeZone::createTimeZone("EAT") 1687 }; 1688 if(U_FAILURE(status)) { 1689 errln("Couldn't create zones"); 1690 return; 1691 // could leak memory 1692 } 1693 1694 for (int32_t i=0; i < 3; ++i) { 1695 GregorianCalendar *calendar = new GregorianCalendar(zones[i], status); 1696 if(U_FAILURE(status)) { 1697 dataerrln("Couldnt' create calendar.: %s", u_errorName(status)); 1698 return; 1699 } 1700 1701 // Make sure extreme values don't wrap around 1702 calendar->setTime(EARLIEST_SUPPORTED_MILLIS, status); 1703 if(U_FAILURE(status)) 1704 errln("setTime failed"); 1705 if (calendar->get(UCAL_ERA, status) != GregorianCalendar::BC || U_FAILURE(status)) { 1706 errln("Fail: Date(EARLIEST_SUPPORTED_MILLIS) has an AD year"); 1707 } 1708 calendar->setTime(LATEST_SUPPORTED_MILLIS, status); 1709 if(U_FAILURE(status)) 1710 errln("setTime failed"); 1711 if (calendar->get(UCAL_ERA, status) != GregorianCalendar::AD || U_FAILURE(status)) { 1712 errln("Fail: Date(LATEST_SUPPORTED_MILLIS) has a BC year"); 1713 } 1714 1715 calendar->setGregorianChange(LATEST_SUPPORTED_MILLIS, status); 1716 if(U_FAILURE(status)) 1717 errln("setGregorianChange failed"); 1718 // to obtain a pure Julian calendar 1719 1720 UBool is100Leap = calendar->isLeapYear(100); 1721 if (!is100Leap) { 1722 UnicodeString temp; 1723 errln("test failed with zone " + zones[i]->getID(temp)); 1724 errln(" cutover date is Date(Long.MAX_VALUE)"); 1725 errln(" isLeapYear(100) returns: " + is100Leap); 1726 } 1727 delete calendar; 1728 } 1729 1730 // no need for cleanup- zones were adopted 1731 } 1732 1733 /** 1734 * @bug 4162587 1735 * Calendar and Date HOUR broken. If HOUR is out-of-range, Calendar 1736 * and Date classes will misbehave. 1737 */ 1738 void 1739 CalendarRegressionTest::Test4162587() 1740 { 1741 UErrorCode status = U_ZERO_ERROR; 1742 TimeZone *savedef = TimeZone::createDefault(); 1743 TimeZone *tz = TimeZone::createTimeZone("PST"); 1744 //TimeZone::adoptDefault(tz); 1745 TimeZone::setDefault(*tz); 1746 1747 GregorianCalendar *cal = new GregorianCalendar(tz, status); 1748 if(U_FAILURE(status)) { 1749 dataerrln("Couldn't create calendar.: %s", u_errorName(status)); 1750 return; 1751 } 1752 UDate d0, dPlus, dMinus; 1753 1754 for(int32_t i=0; i<5; ++i) { 1755 if (i>0) logln("---"); 1756 1757 cal->clear(); 1758 cal->set(1998, UCAL_APRIL, 5, i, 0); 1759 d0 = cal->getTime(status); 1760 if(U_FAILURE(status)) 1761 errln("Coudln't get time (1)"); 1762 //String s0 = d.toString(); 1763 logln(UnicodeString("0 ") + i + ": " + d0/*s0*/); 1764 1765 cal->clear(); 1766 cal->set(1998, UCAL_APRIL, 4, i+24, 0); 1767 dPlus = cal->getTime(status); 1768 if(U_FAILURE(status)) 1769 errln("Coudln't get time (2)"); 1770 //String sPlus = d.toString(); 1771 logln(UnicodeString("+ ") + i + ": " + dPlus/*sPlus*/); 1772 1773 cal->clear(); 1774 cal->set(1998, UCAL_APRIL, 6, i-24, 0); 1775 dMinus = cal->getTime(status); 1776 if(U_FAILURE(status)) 1777 errln("Coudln't get time (3)"); 1778 //String sMinus = d.toString(); 1779 logln(UnicodeString("- ") + i + ": " + dMinus/*sMinus*/); 1780 1781 if (d0 != dPlus || d0 != dMinus) { 1782 errln("Fail: All three lines must match"); 1783 } 1784 } 1785 TimeZone::setDefault(*savedef); 1786 //delete tz; 1787 delete cal; 1788 delete savedef; 1789 } 1790 1791 /** 1792 * @bug 4165343 1793 * Adding 12 months behaves differently from adding 1 year 1794 */ 1795 void 1796 CalendarRegressionTest::Test4165343() 1797 { 1798 UErrorCode status = U_ZERO_ERROR; 1799 GregorianCalendar *calendar = new GregorianCalendar(1996, UCAL_FEBRUARY, 29, status); 1800 if(U_FAILURE(status)) { 1801 dataerrln("Couldn't create calendar.: %s", u_errorName(status)); 1802 return; 1803 } 1804 UDate start = calendar->getTime(status); 1805 if(U_FAILURE(status)) 1806 errln("Couldn't getTime (1)"); 1807 logln(UnicodeString("init date: ") + start); 1808 calendar->add(UCAL_MONTH, 12, status); 1809 if(U_FAILURE(status)) 1810 errln("Couldn't add(MONTH, 12)"); 1811 UDate date1 = calendar->getTime(status); 1812 if(U_FAILURE(status)) 1813 errln("Couldn't getTime (2)"); 1814 logln(UnicodeString("after adding 12 months: ") + date1); 1815 calendar->setTime(start, status); 1816 if(U_FAILURE(status)) 1817 errln("Couldn't setTime"); 1818 calendar->add(UCAL_YEAR, 1, status); 1819 if(U_FAILURE(status)) 1820 errln("Couldn't add(YEAR, 1)"); 1821 UDate date2 = calendar->getTime(status); 1822 if(U_FAILURE(status)) 1823 errln("Couldn't getTime (3)"); 1824 logln(UnicodeString("after adding one year : ") + date2); 1825 if (date1 == date2) { 1826 logln("Test passed"); 1827 } else { 1828 errln("Test failed"); 1829 } 1830 delete calendar; 1831 } 1832 1833 /** 1834 * @bug 4166109 1835 * GregorianCalendar.getActualMaximum() does not account for first day of week. 1836 */ 1837 void 1838 CalendarRegressionTest::Test4166109() 1839 { 1840 /* Test month: 1841 * 1842 * March 1998 1843 * Su Mo Tu We Th Fr Sa 1844 * 1 2 3 4 5 6 7 1845 * 8 9 10 11 12 13 14 1846 * 15 16 17 18 19 20 21 1847 * 22 23 24 25 26 27 28 1848 * 29 30 31 1849 */ 1850 UBool passed = TRUE; 1851 UErrorCode status = U_ZERO_ERROR; 1852 UCalendarDateFields field = UCAL_WEEK_OF_MONTH; 1853 1854 GregorianCalendar *calendar = new GregorianCalendar(Locale::getUS(), status); 1855 if(U_FAILURE(status)) { 1856 dataerrln("Couldn't create calendar.: %s", u_errorName(status)); 1857 return; 1858 } 1859 calendar->set(1998, UCAL_MARCH, 1); 1860 calendar->setMinimalDaysInFirstWeek(1); 1861 logln(UnicodeString("Date: ") + calendar->getTime(status)); // 888817448000 1862 1863 int32_t firstInMonth = calendar->get(UCAL_DATE, status); 1864 if(U_FAILURE(status)) 1865 errln("get(D_O_M) failed"); 1866 1867 for(int32_t firstInWeek = UCAL_SUNDAY; firstInWeek <= UCAL_SATURDAY; firstInWeek++) { 1868 calendar->setFirstDayOfWeek((UCalendarDaysOfWeek)firstInWeek); 1869 int32_t returned = calendar->getActualMaximum(field, status); 1870 int32_t expected = (31 + ((firstInMonth - firstInWeek + 7)% 7) + 6) / 7; 1871 1872 logln(UnicodeString("First day of week = ") + firstInWeek + 1873 " getActualMaximum(WEEK_OF_MONTH, status) = " + returned + 1874 " expected = " + expected + 1875 ((returned == expected) ? " ok" : " FAIL")); 1876 1877 if (returned != expected) { 1878 passed = FALSE; 1879 } 1880 } 1881 if (!passed) { 1882 errln("Test failed"); 1883 } 1884 1885 delete calendar; 1886 } 1887 1888 /** 1889 * @bug 4167060 1890 * Calendar.getActualMaximum(YEAR) works wrong. 1891 */ 1892 void 1893 CalendarRegressionTest::Test4167060() 1894 { 1895 UErrorCode status = U_ZERO_ERROR; 1896 UCalendarDateFields field = UCAL_YEAR; 1897 DateFormat *format = new SimpleDateFormat(UnicodeString("EEE MMM dd HH:mm:ss zzz yyyy G"), 1898 Locale::getUS(), status); 1899 if(U_FAILURE(status)) { 1900 dataerrln("Couldn't create SimpleDateFormat - %s", u_errorName(status)); 1901 return; 1902 } 1903 1904 GregorianCalendar *calendars [] = { 1905 new GregorianCalendar(100, UCAL_NOVEMBER, 1, status), 1906 new GregorianCalendar(-99 /*100BC*/, UCAL_JANUARY, 1, status), 1907 new GregorianCalendar(1996, UCAL_FEBRUARY, 29, status), 1908 }; 1909 if(U_FAILURE(status)) { 1910 errln("Couldn't create GregorianCalendars"); 1911 return; 1912 // could leak 1913 } 1914 1915 UnicodeString id [] = { "Hybrid", "Gregorian", "Julian" }; 1916 1917 for (int32_t k=0; k<3; ++k) { 1918 logln("--- " + id[k] + " ---"); 1919 1920 for (int32_t j=0; j < 3; ++j) { 1921 GregorianCalendar *calendar = calendars[j]; 1922 if (k == 1) { 1923 calendar->setGregorianChange(EARLIEST_SUPPORTED_MILLIS, status); 1924 } 1925 else if (k == 2) { 1926 calendar->setGregorianChange(LATEST_SUPPORTED_MILLIS, status); 1927 } 1928 1929 if(U_FAILURE(status)) 1930 errln("setGregorianChange() failed"); 1931 format->adoptCalendar((Calendar*)calendar->clone()); 1932 1933 UDate dateBefore = calendar->getTime(status); 1934 if(U_FAILURE(status)) 1935 errln("getTime() failed"); 1936 1937 int32_t maxYear = calendar->getActualMaximum(field, status); 1938 UnicodeString temp; 1939 logln(UnicodeString("maxYear: ") + maxYear + " for " + format->format(calendar->getTime(status), temp)); 1940 temp.remove(); 1941 logln("date before: " + format->format(dateBefore, temp)); 1942 1943 int32_t years[] = {2000, maxYear-1, maxYear, maxYear+1}; 1944 1945 for (int32_t i = 0; i < 4; i++) { 1946 UBool valid = years[i] <= maxYear; 1947 calendar->set(field, years[i]); 1948 UDate dateAfter = calendar->getTime(status); 1949 if(U_FAILURE(status)) 1950 errln("getTime() failed"); 1951 int32_t newYear = calendar->get(field, status); 1952 if(U_FAILURE(status)) 1953 errln(UnicodeString("get(") + (int32_t)field + ") failed"); 1954 calendar->setTime(dateBefore, status); // restore calendar for next use 1955 if(U_FAILURE(status)) 1956 errln("setTime() failed"); 1957 1958 temp.remove(); 1959 logln(UnicodeString(" Year ") + years[i] + (valid? " ok " : " bad") + 1960 " => " + format->format(dateAfter, temp)); 1961 if (valid && newYear != years[i]) { 1962 errln(UnicodeString(" FAIL: ") + newYear + " should be valid; date, month and time shouldn't change"); 1963 } 1964 // {sfb} this next line is a hack, but it should work since if a 1965 // double has an exponent, adding 1 should not yield the same double 1966 else if (!valid && /*newYear == years[i]*/ dateAfter + 1.0 == dateAfter) { 1967 errln(UnicodeString(" FAIL: ") + newYear + " should be invalid"); 1968 } 1969 } 1970 } 1971 } 1972 1973 delete format; 1974 delete calendars[0]; 1975 delete calendars[1]; 1976 delete calendars[2]; 1977 } 1978 1979 /** 1980 * Week of year is wrong at the start and end of the year. 1981 */ 1982 void CalendarRegressionTest::Test4197699() { 1983 UErrorCode status = U_ZERO_ERROR; 1984 GregorianCalendar cal(status); 1985 cal.setFirstDayOfWeek(UCAL_MONDAY); 1986 cal.setMinimalDaysInFirstWeek(4); 1987 SimpleDateFormat fmt("E dd MMM yyyy 'DOY='D 'WOY='w", 1988 Locale::getUS(), status); 1989 fmt.setCalendar(cal); 1990 if (U_FAILURE(status)) { 1991 dataerrln("Couldn't initialize test - %s", u_errorName(status)); 1992 return; 1993 } 1994 1995 int32_t DATA[] = { 1996 2000, UCAL_JANUARY, 1, 52, 1997 2001, UCAL_DECEMBER, 31, 1, 1998 }; 1999 int32_t DATA_length = (int32_t)(sizeof(DATA) / sizeof(DATA[0])); 2000 2001 UnicodeString str; 2002 DateFormat& dfmt = *(DateFormat*)&fmt; 2003 for (int32_t i=0; i<DATA_length; ) { 2004 cal.clear(); 2005 cal.set(DATA[i], DATA[i+1], DATA[i+2]); 2006 i += 3; 2007 int32_t expWOY = DATA[i++]; 2008 int32_t actWOY = cal.get(UCAL_WEEK_OF_YEAR, status); 2009 if (expWOY == actWOY) { 2010 logln(UnicodeString("Ok: ") + dfmt.format(cal.getTime(status), str.remove())); 2011 } else { 2012 errln(UnicodeString("FAIL: ") + dfmt.format(cal.getTime(status), str.remove()) 2013 + ", expected WOY=" + expWOY); 2014 cal.add(UCAL_DATE, -8, status); 2015 for (int j=0; j<14; ++j) { 2016 cal.add(UCAL_DATE, 1, status); 2017 logln(dfmt.format(cal.getTime(status), str.remove())); 2018 } 2019 } 2020 if (U_FAILURE(status)) { 2021 errln("FAIL: Unexpected error from Calendar"); 2022 return; 2023 } 2024 } 2025 } 2026 2027 enum Action { ADD=1, ROLL=2 }; 2028 enum Sign { PLUS=1, MINUS=2 }; 2029 2030 #define ONE_HOUR (60*60*1000) 2031 #define ONE_DAY (24*ONE_HOUR) 2032 2033 typedef struct { 2034 UCalendarDateFields field; 2035 int8_t actionMask; // ADD or ROLL or both 2036 int8_t signMask; // PLUS or MINUS or both 2037 int32_t amount; 2038 int32_t before; // ms before cutover 2039 int32_t after; // ms after cutover 2040 } J81_DATA; 2041 2042 /** 2043 * Rolling and adding across the Gregorian cutover should work as expected. 2044 * Jitterbug 81. 2045 */ 2046 void CalendarRegressionTest::TestJ81() { 2047 UErrorCode status = U_ZERO_ERROR; 2048 UnicodeString temp, temp2, temp3; 2049 int32_t i; 2050 GregorianCalendar cal(TimeZone::createTimeZone("GMT"), Locale::getUS(), status); 2051 SimpleDateFormat fmt("HH:mm 'w'w 'd'D E d MMM yyyy", Locale::getUS(), status); 2052 if (U_FAILURE(status)) { 2053 dataerrln("Error: Cannot create calendar or format - %s", u_errorName(status)); 2054 return; 2055 } 2056 fmt.setCalendar(cal); 2057 // Get the Gregorian cutover 2058 UDate cutover = cal.getGregorianChange(); 2059 UDate days = ONE_DAY; 2060 days = cutover/days; 2061 logln(UnicodeString("Cutover: {") + 2062 fmt.format(cutover, temp) + "}(epoch days-" + (int)days + ", jd" + (2440588 + days) +")"); 2063 2064 // Check woy and doy handling. Reference data: 2065 /* w40 d274 Mon 1 Oct 1582 2066 w40 d275 Tue 2 Oct 1582 2067 w40 d276 Wed 3 Oct 1582 2068 w40 d277 Thu 4 Oct 1582 2069 w40 d278 Fri 15 Oct 1582 2070 w40 d279 Sat 16 Oct 1582 2071 w41 d280 Sun 17 Oct 1582 2072 w41 d281 Mon 18 Oct 1582 2073 w41 d282 Tue 19 Oct 1582 2074 w41 d283 Wed 20 Oct 1582 2075 w41 d284 Thu 21 Oct 1582 2076 w41 d285 Fri 22 Oct 1582 2077 w41 d286 Sat 23 Oct 1582 2078 w42 d287 Sun 24 Oct 1582 2079 w42 d288 Mon 25 Oct 1582 2080 w42 d289 Tue 26 Oct 1582 2081 w42 d290 Wed 27 Oct 1582 2082 w42 d291 Thu 28 Oct 1582 2083 w42 d292 Fri 29 Oct 1582 2084 w42 d293 Sat 30 Oct 1582 2085 w43 d294 Sun 31 Oct 1582 2086 w43 d295 Mon 1 Nov 1582 */ 2087 int32_t DOY_DATA[] = { 2088 // dom, woy, doy 2089 1, 40, 274, UCAL_MONDAY, 2090 4, 40, 277, UCAL_THURSDAY, 2091 15, 40, 278, UCAL_FRIDAY, 2092 17, 41, 280, UCAL_SUNDAY, 2093 24, 42, 287, UCAL_SUNDAY, 2094 25, 42, 288, UCAL_MONDAY, 2095 26, 42, 289, UCAL_TUESDAY, 2096 27, 42, 290, UCAL_WEDNESDAY, 2097 28, 42, 291, UCAL_THURSDAY, 2098 29, 42, 292, UCAL_FRIDAY, 2099 30, 42, 293, UCAL_SATURDAY, 2100 31, 43, 294, UCAL_SUNDAY 2101 }; 2102 int32_t DOY_DATA_length = (int32_t)(sizeof(DOY_DATA) / sizeof(DOY_DATA[0])); 2103 2104 for (i=0; i<DOY_DATA_length; i+=4) { 2105 // Test time->fields 2106 cal.set(1582, UCAL_OCTOBER, DOY_DATA[i]); 2107 int32_t woy = cal.get(UCAL_WEEK_OF_YEAR, status); 2108 int32_t doy = cal.get(UCAL_DAY_OF_YEAR, status); 2109 int32_t dow = cal.get(UCAL_DAY_OF_WEEK, status); 2110 if (U_FAILURE(status)) { 2111 errln("Error: get() failed"); 2112 break; 2113 } 2114 if (woy != DOY_DATA[i+1] || doy != DOY_DATA[i+2] || dow != DOY_DATA[i+3]) { 2115 errln((UnicodeString)"Fail: expect woy=" + DOY_DATA[i+1] + 2116 ", doy=" + DOY_DATA[i+2] + ", dow=" + DOY_DATA[i+3] + " on " + 2117 fmt.format(cal.getTime(status), temp.remove()) + 2118 " set(1582,OCTOBER, " + DOY_DATA[i] + ")"); 2119 logln(CalendarTest::calToStr(cal)); 2120 status = U_ZERO_ERROR; 2121 } else { 2122 logln((UnicodeString)"PASS: expect woy=" + DOY_DATA[i+1] + 2123 ", doy=" + DOY_DATA[i+2] + ", dow=" + DOY_DATA[i+3] + " on " + 2124 fmt.format(cal.getTime(status), temp.remove())); 2125 logln(CalendarTest::calToStr(cal)); 2126 status = U_ZERO_ERROR; 2127 } 2128 // Test fields->time for WOY 2129 cal.clear(); 2130 cal.set(UCAL_YEAR, 1582); 2131 cal.set(UCAL_WEEK_OF_YEAR, DOY_DATA[i+1]); 2132 cal.set(UCAL_DAY_OF_WEEK, DOY_DATA[i+3]); 2133 int32_t dom = cal.get(UCAL_DATE, status); 2134 if (U_FAILURE(status)) { 2135 errln("Error: get() failed"); 2136 break; 2137 } 2138 if (dom != DOY_DATA[i]) { 2139 errln((UnicodeString)"Fail: set woy=" + DOY_DATA[i+1] + 2140 " dow=" + DOY_DATA[i+3] + " => " + 2141 fmt.format(cal.getTime(status), temp.remove()) + 2142 ", expected 1582 Oct " + DOY_DATA[i]); 2143 logln(CalendarTest::calToStr(cal)); 2144 status = U_ZERO_ERROR; 2145 } 2146 2147 // Test fields->time for DOY 2148 cal.clear(); 2149 cal.set(UCAL_YEAR, 1582); 2150 cal.set(UCAL_DAY_OF_YEAR, DOY_DATA[i+2]); 2151 dom = cal.get(UCAL_DATE, status); 2152 if (U_FAILURE(status)) { 2153 errln("Error: get() failed"); 2154 break; 2155 } 2156 if (dom != DOY_DATA[i]) { 2157 errln((UnicodeString)"Fail: set doy=" + DOY_DATA[i+2] + 2158 " => " + 2159 fmt.format(cal.getTime(status), temp.remove()) + 2160 ", expected 1582 Oct " + DOY_DATA[i]); 2161 status = U_ZERO_ERROR; 2162 } 2163 } 2164 status = U_ZERO_ERROR; 2165 2166 #define ADD_ROLL ADD|ROLL 2167 #define PLUS_MINUS PLUS|MINUS 2168 // Test cases 2169 J81_DATA DATA[] = { 2170 { UCAL_WEEK_OF_YEAR, ADD_ROLL, PLUS_MINUS, 1, -ONE_DAY, +6*ONE_DAY }, 2171 { UCAL_WEEK_OF_YEAR, ADD_ROLL, PLUS_MINUS, 1, -ONE_DAY, +6*ONE_DAY }, 2172 { UCAL_WEEK_OF_MONTH, ADD|ROLL, PLUS|MINUS, 1, -ONE_DAY, +6*ONE_DAY }, 2173 { UCAL_DATE, ADD|ROLL, PLUS|MINUS, 2, -ONE_DAY, +1*ONE_DAY }, 2174 { UCAL_DATE, ROLL, PLUS, -6, -ONE_DAY, +14*ONE_DAY }, 2175 { UCAL_DATE, ROLL, PLUS, -7, 0, +14*ONE_DAY }, 2176 { UCAL_DATE, ROLL, PLUS, -7, +ONE_DAY, +15*ONE_DAY }, 2177 { UCAL_DATE, ROLL, PLUS, +18, -ONE_DAY, -4*ONE_DAY }, 2178 { UCAL_DAY_OF_YEAR, ADD|ROLL, PLUS|MINUS, 2, -ONE_DAY, +1*ONE_DAY }, 2179 { UCAL_DAY_OF_WEEK, ADD|ROLL, PLUS|MINUS, 2, -ONE_DAY, +1*ONE_DAY }, 2180 { UCAL_DAY_OF_WEEK_IN_MONTH, ADD|ROLL, PLUS|MINUS, 1, -ONE_DAY, +6*ONE_DAY }, 2181 { UCAL_AM_PM, ADD, PLUS|MINUS, 4, -12*ONE_HOUR, +36*ONE_HOUR }, 2182 { UCAL_HOUR, ADD, PLUS|MINUS, 48, -12*ONE_HOUR, +36*ONE_HOUR }, 2183 { UCAL_HOUR_OF_DAY, ADD, PLUS|MINUS, 48, -12*ONE_HOUR, +36*ONE_HOUR }, 2184 { UCAL_MINUTE, ADD, PLUS|MINUS, 48*60, -12*ONE_HOUR, +36*ONE_HOUR }, 2185 { UCAL_SECOND, ADD, PLUS|MINUS, 48*60*60, -12*ONE_HOUR, +36*ONE_HOUR }, 2186 { UCAL_MILLISECOND, ADD, PLUS|MINUS, 48*ONE_HOUR, -12*ONE_HOUR, +36*ONE_HOUR }, 2187 // NOTE: These are not supported yet. See jitterbug 180. 2188 // Uncomment these lines when add/roll supported on these fields. 2189 // { Calendar::YEAR_WOY, ADD|ROLL, 1, -ONE_DAY, +6*ONE_DAY }, 2190 // { Calendar::DOW_LOCAL, ADD|ROLL, 2, -ONE_DAY, +1*ONE_DAY } 2191 }; 2192 int32_t DATA_length = (int32_t)(sizeof(DATA) / sizeof(DATA[0])); 2193 2194 // Now run the tests 2195 for (i=0; i<DATA_length; ++i) { 2196 for (Action action=ADD; action<=ROLL; action=(Action)(action+1)) { 2197 if (!(DATA[i].actionMask & action)) { 2198 continue; 2199 } 2200 for (Sign sign=PLUS; sign<=MINUS; sign=(Sign)(sign+1)) { 2201 if (!(DATA[i].signMask & sign)) { 2202 continue; 2203 } 2204 status = U_ZERO_ERROR; 2205 int32_t amount = DATA[i].amount * (sign==MINUS?-1:1); 2206 UDate date = cutover + 2207 (sign==PLUS ? DATA[i].before : DATA[i].after); 2208 UDate expected = cutover + 2209 (sign==PLUS ? DATA[i].after : DATA[i].before); 2210 cal.setTime(date, status); 2211 if (U_FAILURE(status)) { 2212 errln((UnicodeString)"FAIL: setTime returned error code " + u_errorName(status)); 2213 continue; 2214 } 2215 if (action == ADD) { 2216 cal.add(DATA[i].field, amount, status); 2217 } else { 2218 cal.roll(DATA[i].field, amount, status); 2219 } 2220 if (U_FAILURE(status)) { 2221 errln((UnicodeString)"FAIL: " + 2222 (action==ADD?"add ":"roll ") + FIELD_NAME[DATA[i].field] + 2223 " returned error code " + u_errorName(status)); 2224 continue; 2225 } 2226 UDate result = cal.getTime(status); 2227 if (U_FAILURE(status)) { 2228 errln((UnicodeString)"FAIL: getTime returned error code " + u_errorName(status)); 2229 continue; 2230 } 2231 if (result == expected) { 2232 logln((UnicodeString)"Ok: {" + 2233 fmt.format(date, temp.remove()) + 2234 "}(" + date/ONE_DAY + 2235 (action==ADD?") add ":") roll ") + 2236 amount + " " + FIELD_NAME[DATA[i].field] + " -> {" + 2237 fmt.format(result, temp2.remove()) + 2238 "}(" + result/ONE_DAY + ")"); 2239 } else { 2240 errln((UnicodeString)"FAIL: {" + 2241 fmt.format(date, temp.remove()) + 2242 "}(" + date/ONE_DAY + 2243 (action==ADD?") add ":") roll ") + 2244 amount + " " + FIELD_NAME[DATA[i].field] + " -> {" + 2245 fmt.format(result, temp2.remove()) + 2246 "}(" + result/ONE_DAY + "), expect {" + 2247 fmt.format(expected, temp3.remove()) + 2248 "}(" + expected/ONE_DAY + ")"); 2249 } 2250 } 2251 } 2252 } 2253 } 2254 2255 /** 2256 * Test fieldDifference(). 2257 */ 2258 void CalendarRegressionTest::TestJ438(void) { 2259 UErrorCode ec = U_ZERO_ERROR; 2260 int32_t DATA[] = { 2261 2000, UCAL_JANUARY, 20, 2010, UCAL_JUNE, 15, 2262 2010, UCAL_JUNE, 15, 2000, UCAL_JANUARY, 20, 2263 1964, UCAL_SEPTEMBER, 7, 1999, UCAL_JUNE, 4, 2264 1999, UCAL_JUNE, 4, 1964, UCAL_SEPTEMBER, 7, 2265 }; 2266 int32_t DATA_length = (int32_t)(sizeof(DATA)/sizeof(DATA[0])); 2267 Calendar* pcal = Calendar::createInstance(Locale::getUS(), ec); 2268 if(U_FAILURE(ec)) { 2269 dataerrln("Error creating calendar %s", u_errorName(ec)); 2270 delete pcal; 2271 return; 2272 } 2273 Calendar& cal = *pcal; 2274 int32_t i; 2275 SimpleDateFormat fmt(UnicodeString("MMM dd yyyy",""), ec); 2276 fmt.setCalendar(cal); 2277 UnicodeString s, t, u; 2278 if (U_SUCCESS(ec)) { 2279 for (i=0; i<DATA_length; i+=6) { 2280 int32_t y1 = DATA[i]; 2281 int32_t m1 = DATA[i+1]; 2282 int32_t d1 = DATA[i+2]; 2283 int32_t y2 = DATA[i+3]; 2284 int32_t m2 = DATA[i+4]; 2285 int32_t d2 = DATA[i+5]; 2286 2287 cal.clear(); 2288 cal.set(y1, m1, d1); 2289 UDate date1 = cal.getTime(ec); 2290 if (failure(ec, "getTime")) 2291 break; 2292 cal.set(y2, m2, d2); 2293 UDate date2 = cal.getTime(ec); 2294 if (failure(ec, "getTime")) 2295 break; 2296 2297 cal.setTime(date1, ec); 2298 if (failure(ec, "setTime")) 2299 break; 2300 int32_t dy = cal.fieldDifference(date2, UCAL_YEAR, ec); 2301 int32_t dm = cal.fieldDifference(date2, UCAL_MONTH, ec); 2302 int32_t dd = cal.fieldDifference(date2, UCAL_DATE, ec); 2303 if (failure(ec, "fieldDifference")) 2304 break; 2305 2306 { 2307 Calendar *cal2 = cal.clone(); 2308 UErrorCode ec2 = U_ZERO_ERROR; 2309 2310 cal2->setTime(date1, ec2); 2311 2312 int32_t dy2 = cal2->fieldDifference(date2, Calendar::YEAR, ec2); 2313 int32_t dm2 = cal2->fieldDifference(date2, Calendar::MONTH, ec2); 2314 int32_t dd2 = cal2->fieldDifference(date2, Calendar::DATE, ec2); 2315 if (failure(ec2, "fieldDifference(date, Calendar::DATE, ec)")) 2316 break; 2317 if( (dd2 != dd) || 2318 (dm2 != dm) || 2319 (dy2 != dy)){ 2320 errln("fieldDifference(UCAL_...) and fieldDifference(Calendar::...) give different results!\n"); 2321 } 2322 delete cal2; 2323 } 2324 2325 2326 logln(UnicodeString("") + 2327 fmt.format(date2, s.remove()) + " - " + 2328 fmt.format(date1, t.remove()) + " = " + 2329 dy + "y " + dm + "m " + dd + "d"); 2330 2331 cal.setTime(date1, ec); 2332 if (failure(ec, "setTime")) 2333 break; 2334 cal.add(UCAL_YEAR, dy, ec); 2335 cal.add(UCAL_MONTH, dm, ec); 2336 cal.add(UCAL_DATE, dd, ec); 2337 if (failure(ec, "add")) 2338 break; 2339 UDate date22 = cal.getTime(ec); 2340 if (failure(ec, "getTime")) 2341 break; 2342 if (date2 != date22) { 2343 errln(UnicodeString("FAIL: ") + 2344 fmt.format(date1, s.remove()) + " + " + 2345 dy + "y " + dm + "m " + dd + "d = " + 2346 fmt.format(date22, t.remove()) + ", exp " + 2347 fmt.format(date2, u.remove())); 2348 } else { 2349 logln(UnicodeString("Ok: ") + 2350 fmt.format(date1, s.remove()) + " + " + 2351 dy + "y " + dm + "m " + dd + "d = " + 2352 fmt.format(date22, t.remove())); 2353 } 2354 } 2355 } else { 2356 dataerrln("Error creating SimpleDateFormat - %s", u_errorName(ec)); 2357 } 2358 delete pcal; 2359 } 2360 2361 void CalendarRegressionTest::TestT5555() 2362 { 2363 UErrorCode ec = U_ZERO_ERROR; 2364 Calendar *cal = Calendar::createInstance(ec); 2365 2366 if (cal == NULL || U_FAILURE(ec)) { 2367 dataerrln("FAIL: Calendar::createInstance(): %s", u_errorName(ec)); 2368 delete cal; 2369 return; 2370 } 2371 2372 // Set to Wednesday, February 21, 2007 2373 cal->set(2007, UCAL_FEBRUARY, 21); 2374 2375 // Advance three years 2376 cal->add(UCAL_MONTH, 36, ec); 2377 2378 // Set to last Wednesday of the month 2379 cal->set(UCAL_DAY_OF_WEEK_IN_MONTH, -1); 2380 2381 cal->getTime(ec); 2382 2383 int32_t yy, mm, dd, ee; 2384 2385 yy = cal->get(UCAL_YEAR, ec); 2386 mm = cal->get(UCAL_MONTH, ec); 2387 dd = cal->get(UCAL_DATE, ec); 2388 ee = cal->get(UCAL_DAY_OF_WEEK, ec); 2389 2390 // Should be set to Wednesday, February 24, 2010 2391 if (U_FAILURE(ec) || yy != 2010 || mm != UCAL_FEBRUARY || dd != 24 || ee != UCAL_WEDNESDAY) { 2392 errln("FAIL: got date %4d/%02d/%02d, expected 210/02/24: ", yy, mm + 1, dd); 2393 } 2394 delete cal; 2395 } 2396 2397 typedef struct { 2398 int32_t startYear; 2399 int32_t startMonth; // 0-based 2400 int32_t startDay; // 1-based 2401 UCalendarDateFields fieldToChange; 2402 int32_t fieldDelta; 2403 int32_t endYear; 2404 int32_t endMonth; // 0-based 2405 int32_t endDay; // 1-based 2406 } CoptEthCalTestItem; 2407 2408 // year 1724 in coptic calendar = 2409 // year 2000 in ethiopic calendar (276 more than coptic) = 2410 // year 7500 in ethiopic-amete-alem calendar (5776 more than coptic) 2411 // (2007-2008 in gregorian calendar depending on month) 2412 static const CoptEthCalTestItem coptEthCalTestItems[] = { 2413 { 1724, 12, 1, UCAL_MONTH, +1, 1725, 0, 1 }, 2414 { 1724, 12, 1, UCAL_MONTH, +9, 1725, 8, 1 }, 2415 { 1723, 12, 2, UCAL_MONTH, +1, 1724, 0, 2 }, // 1723 is a leap year 2416 { 1723, 12, 2, UCAL_MONTH, +9, 1724, 8, 2 }, 2417 { 1725, 0, 1, UCAL_MONTH, -1, 1724, 12, 1 }, 2418 { 1725, 0, 1, UCAL_MONTH, -6, 1724, 7, 1 }, 2419 { 1724, 12, 1, UCAL_DATE, +8, 1725, 0, 4 }, 2420 { 1723, 12, 1, UCAL_DATE, +8, 1724, 0, 3 }, // 1723 is a leap year 2421 { 1724, 0, 1, UCAL_DATE, -1, 1723, 12, 6 }, // 1723 is a leap year 2422 { 0, 0, 0, (UCalendarDateFields)0, 0, 0, 0, 0 } // terminator 2423 }; 2424 2425 typedef struct { 2426 const char * locale; 2427 int32_t yearOffset; 2428 } CoptEthCalLocale; 2429 2430 static const CoptEthCalLocale copEthCalLocales[] = { 2431 { "en@calendar=coptic", 0 }, 2432 { "en@calendar=ethiopic", 276 }, 2433 { NULL, 0 } // terminator 2434 }; 2435 2436 void CalendarRegressionTest::TestT6745() 2437 { 2438 const CoptEthCalLocale * testLocalePtr; 2439 for ( testLocalePtr = copEthCalLocales; testLocalePtr->locale != NULL; ++testLocalePtr) { 2440 UErrorCode status = U_ZERO_ERROR; 2441 Calendar *cal = Calendar::createInstance(Locale(testLocalePtr->locale), status); 2442 if ( U_FAILURE(status) ) { 2443 dataerrln((UnicodeString)"FAIL: Calendar::createInstance, locale " + testLocalePtr->locale + ", status " + u_errorName(status)); 2444 continue; 2445 } 2446 const CoptEthCalTestItem * testItemPtr; 2447 for (testItemPtr = coptEthCalTestItems; testItemPtr->fieldDelta != 0; ++testItemPtr) { 2448 status = U_ZERO_ERROR; 2449 cal->set( testItemPtr->startYear + testLocalePtr->yearOffset, testItemPtr->startMonth, testItemPtr->startDay, 9, 0 ); 2450 cal->add( testItemPtr->fieldToChange, testItemPtr->fieldDelta, status ); 2451 if ( U_FAILURE(status) ) { 2452 errln((UnicodeString)"FAIL: Calendar::add, locale " + testLocalePtr->locale + ", field/delta " + 2453 testItemPtr->fieldToChange + "/" + testItemPtr->fieldDelta + ", status " + u_errorName(status)); 2454 continue; 2455 } 2456 int32_t endYear = testItemPtr->endYear + testLocalePtr->yearOffset; 2457 int32_t year = cal->get(UCAL_YEAR, status); 2458 int32_t month = cal->get(UCAL_MONTH, status); 2459 int32_t day = cal->get(UCAL_DATE, status); 2460 if ( U_FAILURE(status) || year != endYear || month != testItemPtr->endMonth || day != testItemPtr->endDay ) { 2461 errln((UnicodeString)"ERROR: Calendar::add, locale " + testLocalePtr->locale + ", field/delta " + 2462 testItemPtr->fieldToChange + "/" + testItemPtr->fieldDelta + ", status " + u_errorName(status) + 2463 ", expected " + endYear + "/" + testItemPtr->endMonth + "/" + testItemPtr->endDay + 2464 ", got " + year + "/" + month + "/" + day ); 2465 } 2466 } 2467 delete cal; 2468 } 2469 } 2470 2471 /** 2472 * Test behavior of fieldDifference around leap years. Also test a large 2473 * field difference to check binary search. 2474 */ 2475 void CalendarRegressionTest::TestLeapFieldDifference() { 2476 UErrorCode ec = U_ZERO_ERROR; 2477 Calendar* cal = Calendar::createInstance(ec); 2478 if (cal == NULL || U_FAILURE(ec)) { 2479 dataerrln("FAIL: Calendar::createInstance(): %s", u_errorName(ec)); 2480 delete cal; 2481 return; 2482 } 2483 cal->set(2004, UCAL_FEBRUARY, 29); 2484 UDate date2004 = cal->getTime(ec); 2485 cal->set(2000, UCAL_FEBRUARY, 29); 2486 UDate date2000 = cal->getTime(ec); 2487 if (U_FAILURE(ec)) { 2488 errln("FAIL: getTime()"); 2489 delete cal; 2490 return; 2491 } 2492 int32_t y = cal->fieldDifference(date2004, UCAL_YEAR, ec); 2493 int32_t d = cal->fieldDifference(date2004, UCAL_DAY_OF_YEAR, ec); 2494 if (U_FAILURE(ec)) { 2495 errln("FAIL: fieldDifference()"); 2496 delete cal; 2497 return; 2498 } 2499 if (d == 0) { 2500 logln((UnicodeString)"Ok: 2004/Feb/29 - 2000/Feb/29 = " + y + " years, " + d + " days"); 2501 } else { 2502 errln((UnicodeString)"FAIL: 2004/Feb/29 - 2000/Feb/29 = " + y + " years, " + d + " days"); 2503 } 2504 cal->setTime(date2004, ec); 2505 y = cal->fieldDifference(date2000, UCAL_YEAR, ec); 2506 d = cal->fieldDifference(date2000, UCAL_DAY_OF_YEAR, ec); 2507 if (U_FAILURE(ec)) { 2508 errln("FAIL: setTime() / fieldDifference()"); 2509 delete cal; 2510 return; 2511 } 2512 if (d == 0) { 2513 logln((UnicodeString)"Ok: 2000/Feb/29 - 2004/Feb/29 = " + y + " years, " + d + " days"); 2514 } else { 2515 errln((UnicodeString)"FAIL: 2000/Feb/29 - 2004/Feb/29 = " + y + " years, " + d + " days"); 2516 } 2517 // Test large difference 2518 cal->set(2001, UCAL_APRIL, 5); // 2452005 2519 UDate ayl = cal->getTime(ec); 2520 cal->set(1964, UCAL_SEPTEMBER, 7); // 2438646 2521 UDate asl = cal->getTime(ec); 2522 if (U_FAILURE(ec)) { 2523 errln("FAIL: getTime()"); 2524 delete cal; 2525 return; 2526 } 2527 d = cal->fieldDifference(ayl, UCAL_DATE, ec); 2528 cal->setTime(ayl, ec); 2529 int32_t d2 = cal->fieldDifference(asl, UCAL_DATE, ec); 2530 if (U_FAILURE(ec)) { 2531 errln("FAIL: setTime() / fieldDifference()"); 2532 delete cal; 2533 return; 2534 } 2535 if (d == -d2 && d == 13359) { 2536 logln((UnicodeString)"Ok: large field difference symmetrical " + d); 2537 } else { 2538 logln((UnicodeString)"FAIL: large field difference incorrect " + d + ", " + d2 + 2539 ", expect +/- 13359"); 2540 } 2541 delete cal; 2542 } 2543 2544 /** 2545 * Test ms_MY "Malay (Malaysia)" locale. Bug 1543. 2546 */ 2547 void CalendarRegressionTest::TestMalaysianInstance() { 2548 Locale loc("ms", "MY"); // Malay (Malaysia) 2549 UErrorCode ec = U_ZERO_ERROR; 2550 Calendar* cal = Calendar::createInstance(loc, ec); 2551 if (U_FAILURE(ec)) { 2552 dataerrln("FAIL: Can't construct calendar for ms_MY: %s", u_errorName(ec)); 2553 } 2554 delete cal; 2555 } 2556 2557 /** 2558 * setFirstDayOfWeek and setMinimalDaysInFirstWeek may change the 2559 * field <=> time mapping, since they affect the interpretation of 2560 * the WEEK_OF_MONTH or WEEK_OF_YEAR fields. 2561 */ 2562 void CalendarRegressionTest::TestWeekShift() { 2563 UErrorCode ec = U_ZERO_ERROR; 2564 GregorianCalendar cal(TimeZone::createTimeZone("America/Los_Angeles"), 2565 Locale("en", "US"), ec); 2566 if (U_FAILURE(ec)) { 2567 dataerrln("Fail GregorianCalendar: %s", u_errorName(ec)); 2568 return; 2569 } 2570 cal.setTime(UDate(997257600000.0), ec); // Wed Aug 08 01:00:00 PDT 2001 2571 // In pass one, change the first day of week so that the weeks 2572 // shift in August 2001. In pass two, change the minimal days 2573 // in the first week so that the weeks shift in August 2001. 2574 // August 2001 2575 // Su Mo Tu We Th Fr Sa 2576 // 1 2 3 4 2577 // 5 6 7 8 9 10 11 2578 // 12 13 14 15 16 17 18 2579 // 19 20 21 22 23 24 25 2580 // 26 27 28 29 30 31 2581 for (int32_t pass=0; pass<2; ++pass) { 2582 if (pass==0) { 2583 cal.setFirstDayOfWeek(UCAL_WEDNESDAY); 2584 cal.setMinimalDaysInFirstWeek(4); 2585 } else { 2586 cal.setFirstDayOfWeek(UCAL_SUNDAY); 2587 cal.setMinimalDaysInFirstWeek(4); 2588 } 2589 cal.add(UCAL_DATE, 1, ec); // Force recalc 2590 cal.add(UCAL_DATE, -1, ec); 2591 2592 UDate time1 = cal.getTime(ec); // Get time -- should not change 2593 2594 // Now change a week parameter and then force a recalc. 2595 // The bug is that the recalc should not be necessary -- 2596 // calendar should do so automatically. 2597 if (pass==0) { 2598 cal.setFirstDayOfWeek(UCAL_THURSDAY); 2599 } else { 2600 cal.setMinimalDaysInFirstWeek(5); 2601 } 2602 2603 int32_t woy1 = cal.get(UCAL_WEEK_OF_YEAR, ec); 2604 int32_t wom1 = cal.get(UCAL_WEEK_OF_MONTH, ec); 2605 2606 cal.add(UCAL_DATE, 1, ec); // Force recalc 2607 cal.add(UCAL_DATE, -1, ec); 2608 2609 int32_t woy2 = cal.get(UCAL_WEEK_OF_YEAR, ec); 2610 int32_t wom2 = cal.get(UCAL_WEEK_OF_MONTH, ec); 2611 2612 UDate time2 = cal.getTime(ec); 2613 2614 if (U_FAILURE(ec)) { 2615 errln("FAIL: internal test error"); 2616 return; 2617 } 2618 2619 if (time1 != time2) { 2620 errln("FAIL: shifting week should not alter time"); 2621 } else { 2622 // logln(time1); 2623 } 2624 if (woy1 == woy2 && wom1 == wom2) { 2625 logln((UnicodeString)"Ok: WEEK_OF_YEAR: " + woy1 + 2626 ", WEEK_OF_MONTH: " + wom1); 2627 } else { 2628 errln((UnicodeString)"FAIL: WEEK_OF_YEAR: " + woy1 + " => " + woy2 + 2629 ", WEEK_OF_MONTH: " + wom1 + " => " + wom2 + 2630 " after week shift"); 2631 } 2632 } 2633 } 2634 2635 /** 2636 * Make sure that when adding a day, we actually wind up in a 2637 * different day. The DST adjustments we use to keep the hour 2638 * constant across DST changes can backfire and change the day. 2639 */ 2640 void CalendarRegressionTest::TestTimeZoneTransitionAdd() { 2641 UErrorCode ec = U_ZERO_ERROR; 2642 Locale locale(Locale::getUS()); // could also be CHINA 2643 SimpleDateFormat dateFormat("MM/dd/yyyy HH:mm z", locale, ec); 2644 2645 StringEnumeration *tz = TimeZone::createEnumeration(); 2646 if (tz == NULL) { 2647 dataerrln("FAIL: TimeZone::createEnumeration"); 2648 return; 2649 } 2650 2651 UnicodeString buf1, buf2; 2652 2653 const UChar* id; 2654 while ((id = tz->unext(NULL, ec)) != NULL && U_SUCCESS(ec)) { 2655 if (U_FAILURE(ec)) { 2656 errln("FAIL: StringEnumeration::unext"); 2657 break; 2658 } 2659 2660 TimeZone *t = TimeZone::createTimeZone(id); 2661 if (t == NULL) { 2662 errln("FAIL: TimeZone::createTimeZone"); 2663 break; 2664 } 2665 dateFormat.setTimeZone(*t); 2666 2667 Calendar *cal = Calendar::createInstance(t, locale, ec); 2668 if (cal == NULL || U_FAILURE(ec)) { 2669 errln("FAIL: Calendar::createTimeZone"); 2670 delete cal; 2671 break; 2672 } 2673 2674 cal->clear(); 2675 // Scan the year 2003, overlapping the edges of the year 2676 cal->set(UCAL_YEAR, 2002); 2677 cal->set(UCAL_MONTH, UCAL_DECEMBER); 2678 cal->set(UCAL_DATE, 25); 2679 2680 for (int32_t i=0; i<365+10 && U_SUCCESS(ec); ++i) { 2681 UDate yesterday = cal->getTime(ec); 2682 int32_t yesterday_day = cal->get(UCAL_DATE, ec); 2683 cal->add(UCAL_DATE, 1, ec); 2684 if (yesterday_day == cal->get(UCAL_DATE, ec)) { 2685 errln(UnicodeString(id) + " " + 2686 dateFormat.format(yesterday, buf1) + " +1d= " + 2687 dateFormat.format(cal->getTime(ec), buf2)); 2688 buf1.truncate(0); 2689 buf2.truncate(0); 2690 } 2691 } 2692 delete cal; 2693 } 2694 2695 if (U_FAILURE(ec)) { 2696 dataerrln("FAIL: %s", u_errorName(ec)); 2697 } 2698 2699 delete tz; 2700 } 2701 2702 UDate 2703 CalendarRegressionTest::makeDate(int32_t y, int32_t m, int32_t d, 2704 int32_t hr, int32_t min, int32_t sec) 2705 { 2706 UDate result; 2707 2708 UErrorCode status = U_ZERO_ERROR; 2709 Calendar *cal = Calendar::createInstance(status); 2710 cal->clear(); 2711 2712 cal->set(UCAL_YEAR, y); 2713 2714 if(m != 0) cal->set(UCAL_MONTH, m); 2715 if(d != 0) cal->set(UCAL_DATE, d); 2716 if(hr != 0) cal->set(UCAL_HOUR, hr); 2717 if(min != 0) cal->set(UCAL_MINUTE, min); 2718 if(sec != 0) cal->set(UCAL_SECOND, sec); 2719 2720 result = cal->getTime(status); 2721 2722 delete cal; 2723 2724 return result; 2725 } 2726 2727 void CalendarRegressionTest::TestDeprecates(void) 2728 { 2729 UErrorCode status = U_ZERO_ERROR; 2730 Calendar *c1 = Calendar::createInstance("ja_JP@calendar=japanese",status); 2731 Calendar *c2 = Calendar::createInstance("ja_JP_TRADITIONAL",status); 2732 2733 if(!c1 || !c2 || U_FAILURE(status)) { 2734 dataerrln("Couldn't create calendars for roll of HOUR: %s", u_errorName(status)); 2735 return; 2736 } 2737 2738 c2->set(UCAL_HOUR,2); 2739 c1->setTime(c2->getTime(status),status); 2740 // *c1 = *c2; 2741 2742 c1->roll(Calendar::HOUR,(int32_t)3,status); 2743 c2->roll(UCAL_HOUR,(int32_t)3,status); 2744 2745 if(U_FAILURE(status)) { 2746 errln("Error code when trying to roll"); 2747 } else if(*c1 != *c2) { 2748 errln("roll(EDateField, int32_t) had different effect than roll(UCalendarField, int32_t)"); 2749 } 2750 2751 c1->setTime(c2->getTime(status),status); 2752 c1->roll(Calendar::HOUR,(UBool)FALSE,status); 2753 c2->roll(UCAL_HOUR,(UBool)FALSE,status); 2754 2755 if(U_FAILURE(status)) { 2756 errln("Error code when trying to roll(UBool)"); 2757 } else if(*c1 != *c2) { 2758 errln("roll(EDateField, UBool) had different effect than roll(UCalendarField, UBool)"); 2759 } 2760 2761 delete c1; 2762 delete c2; 2763 2764 status = U_ZERO_ERROR; 2765 2766 c1 = Calendar::createInstance("th_TH_TRADITIONAL",status); 2767 c2 = Calendar::createInstance("th_TH@calendar=buddhist",status); 2768 2769 if(!c1 || !c2 || U_FAILURE(status)) { 2770 errln("Couldn't create calendars for add of HOUR"); 2771 return; 2772 } 2773 2774 c2->set(UCAL_HOUR,2); 2775 c1->setTime(c2->getTime(status),status); 2776 //*c1 = *c2; 2777 2778 c1->add(Calendar::HOUR,(int32_t)1,status); 2779 2780 if(U_FAILURE(status)) { 2781 errln("Error code when trying to add Calendar::HOUR - %s", u_errorName(status)); 2782 } 2783 2784 c2->add(UCAL_HOUR,(int32_t)1,status); 2785 2786 if(U_FAILURE(status)) { 2787 errln("Error code when trying to add - UCAL_HOUR %s", u_errorName(status)); 2788 } else if(*c1 != *c2) { 2789 errln("add(EDateField) had different effect than add(UCalendarField)"); 2790 } 2791 2792 delete c1; 2793 delete c2; 2794 2795 status = U_ZERO_ERROR; 2796 2797 c1 = Calendar::createInstance("es_ES",status); 2798 c2 = Calendar::createInstance("es_ES",status); 2799 2800 if(!c1 || !c2 || U_FAILURE(status)) { 2801 errln("Couldn't create calendars for add of YEAR"); 2802 return; 2803 } 2804 2805 c2->set(UCAL_YEAR,1900); 2806 c1->setTime(c2->getTime(status),status); 2807 //*c1 = *c2; 2808 2809 c1->add(Calendar::YEAR,(int32_t)9,status); 2810 c2->add(UCAL_YEAR,(int32_t)9,status); 2811 2812 if(U_FAILURE(status)) { 2813 errln("Error code when trying to add YEARs"); 2814 } else if(*c1 != *c2) { 2815 errln("add(EDateField YEAR) had different effect than add(UCalendarField YEAR)"); 2816 } 2817 2818 delete c1; 2819 delete c2; 2820 2821 } 2822 2823 void CalendarRegressionTest::TestT8057(void) { 2824 // Set the calendar to the last day in a leap year 2825 UErrorCode status = U_ZERO_ERROR; 2826 GregorianCalendar *cal = (GregorianCalendar*)Calendar::createInstance(status); 2827 if(U_FAILURE(status)) { 2828 errln("Error creating Calendar: %s", u_errorName(status)); 2829 delete cal; 2830 return; 2831 } 2832 cal->setLenient(FALSE); 2833 cal->clear(); 2834 cal->set(2008, UCAL_DECEMBER, 31); 2835 2836 // Force calculating then fields once. 2837 UDate t = cal->getTime(status); 2838 if(U_FAILURE(status)) { 2839 errln("Error while calculating the date"); 2840 delete cal; 2841 return; 2842 } 2843 2844 UDate expected = 1262246400000.0; // 2009-12-31 00:00 PST 2845 2846 cal->add(UCAL_YEAR, 1, status); 2847 t = cal->getTime(status); 2848 if (U_SUCCESS(status)) { 2849 if (t != expected) { 2850 dataerrln((UnicodeString)"FAIL: wrong date after add: expected=" + expected + " returned=" + t); 2851 } 2852 } else { 2853 errln("FAIL: error while adding one year"); 2854 } 2855 2856 delete cal; 2857 } 2858 2859 // Test case for ticket#8596. 2860 // Setting an year followed by getActualMaximum(Calendar.WEEK_OF_YEAR) 2861 // may result wrong maximum week. 2862 void CalendarRegressionTest::TestT8596(void) { 2863 UErrorCode status = U_ZERO_ERROR; 2864 GregorianCalendar *gc = new GregorianCalendar(*TimeZone::getGMT(), status); 2865 2866 if (U_FAILURE(status)) { 2867 dataerrln("Error creating Calendar: %s", u_errorName(status)); 2868 delete gc; 2869 return; 2870 } 2871 2872 gc->setFirstDayOfWeek(UCAL_MONDAY); 2873 gc->setMinimalDaysInFirstWeek(4); 2874 2875 // Force the calender to resolve the fields once. 2876 // The maximum week number in 2011 is 52. 2877 gc->set(UCAL_YEAR, 2011); 2878 gc->get(UCAL_YEAR, status); 2879 2880 // Set a date in year 2009, but not calling get to resolve 2881 // the calendar's internal field yet. 2882 gc->set(2009, UCAL_JULY, 1); 2883 2884 // Then call getActuamMaximum for week of year. 2885 // #8596 was caused by conflict between year set 2886 // above and internal work calendar field resolution. 2887 int32_t maxWeeks = gc->getActualMaximum(UCAL_WEEK_OF_YEAR, status); 2888 2889 if (U_FAILURE(status)) { 2890 errln("Error calendar calculation: %s", u_errorName(status)); 2891 delete gc; 2892 return; 2893 } 2894 2895 if (maxWeeks != 53) { 2896 errln((UnicodeString)"FAIL: Max week in 2009 in ISO calendar is 53, but got " + maxWeeks); 2897 } 2898 2899 delete gc; 2900 } 2901 2902 // Test case for ticket 9452 2903 // Calendar addition fall onto the missing date - 2011-12-30 in Samoa 2904 void CalendarRegressionTest::TestT9452(void) { 2905 UErrorCode status = U_ZERO_ERROR; 2906 GregorianCalendar cal(TimeZone::createTimeZone("Pacific/Apia"), status); 2907 failure(status, "initializing GregorianCalendar"); 2908 2909 SimpleDateFormat sdf(UnicodeString("y-MM-dd'T'HH:mm:ssZZZZZ"), status); 2910 failure(status, "initializing SimpleDateFormat"); 2911 sdf.setCalendar(cal); 2912 2913 UnicodeString dstr; 2914 2915 // Set date to 2011-12-29 00:00 2916 cal.clear(); 2917 cal.set(2011, UCAL_DECEMBER, 29, 0, 0, 0); 2918 2919 UDate d = cal.getTime(status); 2920 if (!failure(status, "getTime for initial date")) { 2921 sdf.format(d, dstr); 2922 logln(UnicodeString("Initial date: ") + dstr); 2923 2924 // Add 1 day 2925 cal.add(UCAL_DATE, 1, status); 2926 failure(status, "add 1 day"); 2927 d = cal.getTime(status); 2928 failure(status, "getTime after +1 day"); 2929 dstr.remove(); 2930 sdf.format(d, dstr); 2931 logln(UnicodeString("+1 day: ") + dstr); 2932 assertEquals("Add 1 day", UnicodeString("2011-12-31T00:00:00+14:00"), dstr); 2933 2934 // Subtract 1 day 2935 cal.add(UCAL_DATE, -1, status); 2936 failure(status, "subtract 1 day"); 2937 d = cal.getTime(status); 2938 failure(status, "getTime after -1 day"); 2939 dstr.remove(); 2940 sdf.format(d, dstr); 2941 logln(UnicodeString("-1 day: ") + dstr); 2942 assertEquals("Subtract 1 day", UnicodeString("2011-12-29T00:00:00-10:00"), dstr); 2943 } 2944 } 2945 2946 #endif /* #if !UCONFIG_NO_FORMATTING */ 2947