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