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