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