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