1 /************************************************************************ 2 * COPYRIGHT: 3 * Copyright (c) 1997-2014, International Business Machines Corporation 4 * and others. All Rights Reserved. 5 ************************************************************************/ 6 #include "unicode/utypes.h" 7 8 #if !UCONFIG_NO_FORMATTING 9 10 #include "caltest.h" 11 #include "unicode/dtfmtsym.h" 12 #include "unicode/gregocal.h" 13 #include "unicode/localpointer.h" 14 #include "hebrwcal.h" 15 #include "unicode/smpdtfmt.h" 16 #include "unicode/simpletz.h" 17 #include "dbgutil.h" 18 #include "unicode/udat.h" 19 #include "unicode/ustring.h" 20 #include "cstring.h" 21 #include "unicode/localpointer.h" 22 #include "islamcal.h" 23 24 #define mkcstr(U) u_austrcpy(calloc(8, u_strlen(U) + 1), U) 25 26 #define TEST_CHECK_STATUS { \ 27 if (U_FAILURE(status)) { \ 28 if (status == U_MISSING_RESOURCE_ERROR) { \ 29 dataerrln("%s:%d: Test failure. status=%s", __FILE__, __LINE__, u_errorName(status)); \ 30 } else { \ 31 errln("%s:%d: Test failure. status=%s", __FILE__, __LINE__, u_errorName(status)); \ 32 } return;}} 33 34 #define TEST_ASSERT(expr) {if ((expr)==FALSE) {errln("%s:%d: Test failure \n", __FILE__, __LINE__);};} 35 36 // ***************************************************************************** 37 // class CalendarTest 38 // ***************************************************************************** 39 40 UnicodeString CalendarTest::calToStr(const Calendar & cal) 41 { 42 UnicodeString out; 43 UErrorCode status = U_ZERO_ERROR; 44 int i; 45 UDate d; 46 for(i = 0;i<UCAL_FIELD_COUNT;i++) { 47 out += (UnicodeString("") + fieldName((UCalendarDateFields)i) + "=" + cal.get((UCalendarDateFields)i, status) + UnicodeString(" ")); 48 } 49 out += "[" + UnicodeString(cal.getType()) + "]"; 50 51 if(cal.inDaylightTime(status)) { 52 out += UnicodeString(" (in DST), zone="); 53 } 54 else { 55 out += UnicodeString(", zone="); 56 } 57 58 UnicodeString str2; 59 out += cal.getTimeZone().getDisplayName(str2); 60 d = cal.getTime(status); 61 out += UnicodeString(" :","") + d; 62 63 return out; 64 } 65 66 void CalendarTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ ) 67 { 68 if (exec) logln("TestSuite TestCalendar"); 69 switch (index) { 70 case 0: 71 name = "TestDOW943"; 72 if (exec) { 73 logln("TestDOW943---"); logln(""); 74 TestDOW943(); 75 } 76 break; 77 case 1: 78 name = "TestClonesUnique908"; 79 if (exec) { 80 logln("TestClonesUnique908---"); logln(""); 81 TestClonesUnique908(); 82 } 83 break; 84 case 2: 85 name = "TestGregorianChange768"; 86 if (exec) { 87 logln("TestGregorianChange768---"); logln(""); 88 TestGregorianChange768(); 89 } 90 break; 91 case 3: 92 name = "TestDisambiguation765"; 93 if (exec) { 94 logln("TestDisambiguation765---"); logln(""); 95 TestDisambiguation765(); 96 } 97 break; 98 case 4: 99 name = "TestGMTvsLocal4064654"; 100 if (exec) { 101 logln("TestGMTvsLocal4064654---"); logln(""); 102 TestGMTvsLocal4064654(); 103 } 104 break; 105 case 5: 106 name = "TestAddSetOrder621"; 107 if (exec) { 108 logln("TestAddSetOrder621---"); logln(""); 109 TestAddSetOrder621(); 110 } 111 break; 112 case 6: 113 name = "TestAdd520"; 114 if (exec) { 115 logln("TestAdd520---"); logln(""); 116 TestAdd520(); 117 } 118 break; 119 case 7: 120 name = "TestFieldSet4781"; 121 if (exec) { 122 logln("TestFieldSet4781---"); logln(""); 123 TestFieldSet4781(); 124 } 125 break; 126 case 8: 127 name = "TestSerialize337"; 128 if (exec) { 129 logln("TestSerialize337---"); logln(""); 130 // TestSerialize337(); 131 } 132 break; 133 case 9: 134 name = "TestSecondsZero121"; 135 if (exec) { 136 logln("TestSecondsZero121---"); logln(""); 137 TestSecondsZero121(); 138 } 139 break; 140 case 10: 141 name = "TestAddSetGet0610"; 142 if (exec) { 143 logln("TestAddSetGet0610---"); logln(""); 144 TestAddSetGet0610(); 145 } 146 break; 147 case 11: 148 name = "TestFields060"; 149 if (exec) { 150 logln("TestFields060---"); logln(""); 151 TestFields060(); 152 } 153 break; 154 case 12: 155 name = "TestEpochStartFields"; 156 if (exec) { 157 logln("TestEpochStartFields---"); logln(""); 158 TestEpochStartFields(); 159 } 160 break; 161 case 13: 162 name = "TestDOWProgression"; 163 if (exec) { 164 logln("TestDOWProgression---"); logln(""); 165 TestDOWProgression(); 166 } 167 break; 168 case 14: 169 name = "TestGenericAPI"; 170 if (exec) { 171 logln("TestGenericAPI---"); logln(""); 172 TestGenericAPI(); 173 } 174 break; 175 case 15: 176 name = "TestAddRollExtensive"; 177 if (exec) { 178 logln("TestAddRollExtensive---"); logln(""); 179 TestAddRollExtensive(); 180 } 181 break; 182 case 16: 183 name = "TestDOW_LOCALandYEAR_WOY"; 184 if (exec) { 185 logln("TestDOW_LOCALandYEAR_WOY---"); logln(""); 186 TestDOW_LOCALandYEAR_WOY(); 187 } 188 break; 189 case 17: 190 name = "TestWOY"; 191 if (exec) { 192 logln("TestWOY---"); logln(""); 193 TestWOY(); 194 } 195 break; 196 case 18: 197 name = "TestRog"; 198 if (exec) { 199 logln("TestRog---"); logln(""); 200 TestRog(); 201 } 202 break; 203 case 19: 204 name = "TestYWOY"; 205 if (exec) { 206 logln("TestYWOY---"); logln(""); 207 TestYWOY(); 208 } 209 break; 210 case 20: 211 name = "TestJD"; 212 if(exec) { 213 logln("TestJD---"); logln(""); 214 TestJD(); 215 } 216 break; 217 case 21: 218 name = "TestDebug"; 219 if(exec) { 220 logln("TestDebug---"); logln(""); 221 TestDebug(); 222 } 223 break; 224 case 22: 225 name = "Test6703"; 226 if(exec) { 227 logln("Test6703---"); logln(""); 228 Test6703(); 229 } 230 break; 231 case 23: 232 name = "Test3785"; 233 if(exec) { 234 logln("Test3785---"); logln(""); 235 Test3785(); 236 } 237 break; 238 case 24: 239 name = "Test1624"; 240 if(exec) { 241 logln("Test1624---"); logln(""); 242 Test1624(); 243 } 244 break; 245 case 25: 246 name = "TestTimeStamp"; 247 if(exec) { 248 logln("TestTimeStamp---"); logln(""); 249 TestTimeStamp(); 250 } 251 break; 252 case 26: 253 name = "TestISO8601"; 254 if(exec) { 255 logln("TestISO8601---"); logln(""); 256 TestISO8601(); 257 } 258 break; 259 case 27: 260 name = "TestAmbiguousWallTimeAPIs"; 261 if(exec) { 262 logln("TestAmbiguousWallTimeAPIs---"); logln(""); 263 TestAmbiguousWallTimeAPIs(); 264 } 265 break; 266 case 28: 267 name = "TestRepeatedWallTime"; 268 if(exec) { 269 logln("TestRepeatedWallTime---"); logln(""); 270 TestRepeatedWallTime(); 271 } 272 break; 273 case 29: 274 name = "TestSkippedWallTime"; 275 if(exec) { 276 logln("TestSkippedWallTime---"); logln(""); 277 TestSkippedWallTime(); 278 } 279 break; 280 case 30: 281 name = "TestCloneLocale"; 282 if(exec) { 283 logln("TestCloneLocale---"); logln(""); 284 TestCloneLocale(); 285 } 286 break; 287 case 31: 288 name = "TestIslamicUmAlQura"; 289 if(exec) { 290 logln("TestIslamicUmAlQura---"); logln(""); 291 TestIslamicUmAlQura(); 292 } 293 break; 294 case 32: 295 name = "TestIslamicTabularDates"; 296 if(exec) { 297 logln("TestIslamicTabularDates---"); logln(""); 298 TestIslamicTabularDates(); 299 } 300 break; 301 case 33: 302 name = "TestHebrewMonthValidation"; 303 if(exec) { 304 logln("TestHebrewMonthValidation---"); logln(""); 305 TestHebrewMonthValidation(); 306 } 307 break; 308 case 34: 309 name = "TestWeekData"; 310 if(exec) { 311 logln("TestWeekData---"); logln(""); 312 TestWeekData(); 313 } 314 break; 315 case 35: 316 name = "TestAddAcrossZoneTransition"; 317 if(exec) { 318 logln("TestAddAcrossZoneTransition---"); logln(""); 319 TestAddAcrossZoneTransition(); 320 } 321 break; 322 default: name = ""; break; 323 } 324 } 325 326 // --------------------------------------------------------------------------------- 327 328 UnicodeString CalendarTest::fieldName(UCalendarDateFields f) { 329 switch (f) { 330 #define FIELD_NAME_STR(x) case x: return (#x+5) 331 FIELD_NAME_STR( UCAL_ERA ); 332 FIELD_NAME_STR( UCAL_YEAR ); 333 FIELD_NAME_STR( UCAL_MONTH ); 334 FIELD_NAME_STR( UCAL_WEEK_OF_YEAR ); 335 FIELD_NAME_STR( UCAL_WEEK_OF_MONTH ); 336 FIELD_NAME_STR( UCAL_DATE ); 337 FIELD_NAME_STR( UCAL_DAY_OF_YEAR ); 338 FIELD_NAME_STR( UCAL_DAY_OF_WEEK ); 339 FIELD_NAME_STR( UCAL_DAY_OF_WEEK_IN_MONTH ); 340 FIELD_NAME_STR( UCAL_AM_PM ); 341 FIELD_NAME_STR( UCAL_HOUR ); 342 FIELD_NAME_STR( UCAL_HOUR_OF_DAY ); 343 FIELD_NAME_STR( UCAL_MINUTE ); 344 FIELD_NAME_STR( UCAL_SECOND ); 345 FIELD_NAME_STR( UCAL_MILLISECOND ); 346 FIELD_NAME_STR( UCAL_ZONE_OFFSET ); 347 FIELD_NAME_STR( UCAL_DST_OFFSET ); 348 FIELD_NAME_STR( UCAL_YEAR_WOY ); 349 FIELD_NAME_STR( UCAL_DOW_LOCAL ); 350 FIELD_NAME_STR( UCAL_EXTENDED_YEAR ); 351 FIELD_NAME_STR( UCAL_JULIAN_DAY ); 352 FIELD_NAME_STR( UCAL_MILLISECONDS_IN_DAY ); 353 #undef FIELD_NAME_STR 354 default: 355 return UnicodeString("") + ((int32_t)f); 356 } 357 } 358 359 /** 360 * Test various API methods for API completeness. 361 */ 362 void 363 CalendarTest::TestGenericAPI() 364 { 365 UErrorCode status = U_ZERO_ERROR; 366 UDate d; 367 UnicodeString str; 368 UBool eq = FALSE,b4 = FALSE,af = FALSE; 369 370 UDate when = date(90, UCAL_APRIL, 15); 371 372 UnicodeString tzid("TestZone"); 373 int32_t tzoffset = 123400; 374 375 SimpleTimeZone *zone = new SimpleTimeZone(tzoffset, tzid); 376 Calendar *cal = Calendar::createInstance(zone->clone(), status); 377 if (failure(status, "Calendar::createInstance", TRUE)) return; 378 379 if (*zone != cal->getTimeZone()) errln("FAIL: Calendar::getTimeZone failed"); 380 381 Calendar *cal2 = Calendar::createInstance(cal->getTimeZone(), status); 382 if (failure(status, "Calendar::createInstance")) return; 383 cal->setTime(when, status); 384 cal2->setTime(when, status); 385 if (failure(status, "Calendar::setTime")) return; 386 387 if (!(*cal == *cal2)) errln("FAIL: Calendar::operator== failed"); 388 if ((*cal != *cal2)) errln("FAIL: Calendar::operator!= failed"); 389 if (!cal->equals(*cal2, status) || 390 cal->before(*cal2, status) || 391 cal->after(*cal2, status) || 392 U_FAILURE(status)) errln("FAIL: equals/before/after failed"); 393 394 logln(UnicodeString("cal=") +cal->getTime(status) + UnicodeString(calToStr(*cal))); 395 logln(UnicodeString("cal2=") +cal2->getTime(status) + UnicodeString(calToStr(*cal2))); 396 logln("cal2->setTime(when+1000)"); 397 cal2->setTime(when + 1000, status); 398 logln(UnicodeString("cal2=") +cal2->getTime(status) + UnicodeString(calToStr(*cal2))); 399 400 if (failure(status, "Calendar::setTime")) return; 401 if (cal->equals(*cal2, status) || 402 cal2->before(*cal, status) || 403 cal->after(*cal2, status) || 404 U_FAILURE(status)) errln("FAIL: equals/before/after failed after setTime(+1000)"); 405 406 logln("cal->roll(UCAL_SECOND)"); 407 cal->roll(UCAL_SECOND, (UBool) TRUE, status); 408 logln(UnicodeString("cal=") +cal->getTime(status) + UnicodeString(calToStr(*cal))); 409 cal->roll(UCAL_SECOND, (int32_t)0, status); 410 logln(UnicodeString("cal=") +cal->getTime(status) + UnicodeString(calToStr(*cal))); 411 if (failure(status, "Calendar::roll")) return; 412 413 if (!(eq=cal->equals(*cal2, status)) || 414 (b4=cal->before(*cal2, status)) || 415 (af=cal->after(*cal2, status)) || 416 U_FAILURE(status)) { 417 errln("FAIL: equals[%c]/before[%c]/after[%c] failed after roll 1 second [should be T/F/F]", 418 eq?'T':'F', 419 b4?'T':'F', 420 af?'T':'F'); 421 logln(UnicodeString("cal=") +cal->getTime(status) + UnicodeString(calToStr(*cal))); 422 logln(UnicodeString("cal2=") +cal2->getTime(status) + UnicodeString(calToStr(*cal2))); 423 } 424 425 // Roll back to January 426 cal->roll(UCAL_MONTH, (int32_t)(1 + UCAL_DECEMBER - cal->get(UCAL_MONTH, status)), status); 427 if (failure(status, "Calendar::roll")) return; 428 if (cal->equals(*cal2, status) || 429 cal2->before(*cal, status) || 430 cal->after(*cal2, status) || 431 U_FAILURE(status)) errln("FAIL: equals/before/after failed after rollback to January"); 432 433 TimeZone *z = cal->orphanTimeZone(); 434 if (z->getID(str) != tzid || 435 z->getRawOffset() != tzoffset) 436 errln("FAIL: orphanTimeZone failed"); 437 438 int32_t i; 439 for (i=0; i<2; ++i) 440 { 441 UBool lenient = ( i > 0 ); 442 cal->setLenient(lenient); 443 if (lenient != cal->isLenient()) errln("FAIL: setLenient/isLenient failed"); 444 // Later: Check for lenient behavior 445 } 446 447 for (i=UCAL_SUNDAY; i<=UCAL_SATURDAY; ++i) 448 { 449 cal->setFirstDayOfWeek((UCalendarDaysOfWeek)i); 450 if (cal->getFirstDayOfWeek() != i) errln("FAIL: set/getFirstDayOfWeek failed"); 451 UErrorCode aStatus = U_ZERO_ERROR; 452 if (cal->getFirstDayOfWeek(aStatus) != i || U_FAILURE(aStatus)) errln("FAIL: getFirstDayOfWeek(status) failed"); 453 } 454 455 for (i=1; i<=7; ++i) 456 { 457 cal->setMinimalDaysInFirstWeek((uint8_t)i); 458 if (cal->getMinimalDaysInFirstWeek() != i) errln("FAIL: set/getFirstDayOfWeek failed"); 459 } 460 461 for (i=0; i<UCAL_FIELD_COUNT; ++i) 462 { 463 if (cal->getMinimum((UCalendarDateFields)i) > cal->getGreatestMinimum((UCalendarDateFields)i)) 464 errln(UnicodeString("FAIL: getMinimum larger than getGreatestMinimum for field ") + i); 465 if (cal->getLeastMaximum((UCalendarDateFields)i) > cal->getMaximum((UCalendarDateFields)i)) 466 errln(UnicodeString("FAIL: getLeastMaximum larger than getMaximum for field ") + i); 467 if (cal->getMinimum((UCalendarDateFields)i) >= cal->getMaximum((UCalendarDateFields)i)) 468 errln(UnicodeString("FAIL: getMinimum not less than getMaximum for field ") + i); 469 } 470 471 cal->adoptTimeZone(TimeZone::createDefault()); 472 cal->clear(); 473 cal->set(1984, 5, 24); 474 if (cal->getTime(status) != date(84, 5, 24) || U_FAILURE(status)) 475 errln("FAIL: Calendar::set(3 args) failed"); 476 477 cal->clear(); 478 cal->set(1985, 3, 2, 11, 49); 479 if (cal->getTime(status) != date(85, 3, 2, 11, 49) || U_FAILURE(status)) 480 errln("FAIL: Calendar::set(5 args) failed"); 481 482 cal->clear(); 483 cal->set(1995, 9, 12, 1, 39, 55); 484 if (cal->getTime(status) != date(95, 9, 12, 1, 39, 55) || U_FAILURE(status)) 485 errln("FAIL: Calendar::set(6 args) failed"); 486 487 cal->getTime(status); 488 if (failure(status, "Calendar::getTime")) return; 489 for (i=0; i<UCAL_FIELD_COUNT; ++i) 490 { 491 switch(i) { 492 case UCAL_YEAR: case UCAL_MONTH: case UCAL_DATE: 493 case UCAL_HOUR_OF_DAY: case UCAL_MINUTE: case UCAL_SECOND: 494 case UCAL_EXTENDED_YEAR: 495 if (!cal->isSet((UCalendarDateFields)i)) errln("FAIL: Calendar::isSet F, should be T " + fieldName((UCalendarDateFields)i)); 496 break; 497 default: 498 if (cal->isSet((UCalendarDateFields)i)) errln("FAIL: Calendar::isSet = T, should be F " + fieldName((UCalendarDateFields)i)); 499 } 500 cal->clear((UCalendarDateFields)i); 501 if (cal->isSet((UCalendarDateFields)i)) errln("FAIL: Calendar::clear/isSet failed " + fieldName((UCalendarDateFields)i)); 502 } 503 504 if(cal->getActualMinimum(Calendar::SECOND, status) != 0){ 505 errln("Calendar is suppose to return 0 for getActualMinimum"); 506 } 507 508 Calendar *cal3 = Calendar::createInstance(status); 509 cal3->roll(Calendar::SECOND, (int32_t)0, status); 510 if (failure(status, "Calendar::roll(EDateFields, int32_t, UErrorCode)")) return; 511 512 delete cal; 513 delete cal2; 514 delete cal3; 515 516 int32_t count; 517 const Locale* loc = Calendar::getAvailableLocales(count); 518 if (count < 1 || loc == 0) 519 { 520 dataerrln("FAIL: getAvailableLocales failed"); 521 } 522 else 523 { 524 for (i=0; i<count; ++i) 525 { 526 cal = Calendar::createInstance(loc[i], status); 527 if (failure(status, "Calendar::createInstance")) return; 528 delete cal; 529 } 530 } 531 532 cal = Calendar::createInstance(TimeZone::createDefault(), Locale::getEnglish(), status); 533 if (failure(status, "Calendar::createInstance")) return; 534 delete cal; 535 536 cal = Calendar::createInstance(*zone, Locale::getEnglish(), status); 537 if (failure(status, "Calendar::createInstance")) return; 538 delete cal; 539 540 GregorianCalendar *gc = new GregorianCalendar(*zone, status); 541 if (failure(status, "new GregorianCalendar")) return; 542 delete gc; 543 544 gc = new GregorianCalendar(Locale::getEnglish(), status); 545 if (failure(status, "new GregorianCalendar")) return; 546 delete gc; 547 548 gc = new GregorianCalendar(Locale::getEnglish(), status); 549 delete gc; 550 551 gc = new GregorianCalendar(*zone, Locale::getEnglish(), status); 552 if (failure(status, "new GregorianCalendar")) return; 553 delete gc; 554 555 gc = new GregorianCalendar(zone, status); 556 if (failure(status, "new GregorianCalendar")) return; 557 delete gc; 558 559 gc = new GregorianCalendar(1998, 10, 14, 21, 43, status); 560 if (gc->getTime(status) != (d =date(98, 10, 14, 21, 43) )|| U_FAILURE(status)) 561 errln("FAIL: new GregorianCalendar(ymdhm) failed with " + UnicodeString(u_errorName(status)) + ", cal=" + gc->getTime(status) + UnicodeString(calToStr(*gc)) + ", d=" + d); 562 else 563 logln(UnicodeString("GOOD: cal=") +gc->getTime(status) + UnicodeString(calToStr(*gc)) + ", d=" + d); 564 delete gc; 565 566 gc = new GregorianCalendar(1998, 10, 14, 21, 43, 55, status); 567 if (gc->getTime(status) != (d=date(98, 10, 14, 21, 43, 55)) || U_FAILURE(status)) 568 errln("FAIL: new GregorianCalendar(ymdhms) failed with " + UnicodeString(u_errorName(status))); 569 570 GregorianCalendar gc2(Locale::getEnglish(), status); 571 if (failure(status, "new GregorianCalendar")) return; 572 gc2 = *gc; 573 if (gc2 != *gc || !(gc2 == *gc)) errln("FAIL: GregorianCalendar assignment/operator==/operator!= failed"); 574 delete gc; 575 delete z; 576 577 /* Code coverage for Calendar class. */ 578 cal = Calendar::createInstance(status); 579 if (failure(status, "Calendar::createInstance")) { 580 return; 581 }else { 582 ((Calendar *)cal)->roll(UCAL_HOUR, (int32_t)100, status); 583 ((Calendar *)cal)->clear(UCAL_HOUR); 584 #if !UCONFIG_NO_SERVICE 585 URegistryKey key = cal->registerFactory(NULL, status); 586 cal->unregister(key, status); 587 #endif 588 } 589 delete cal; 590 591 status = U_ZERO_ERROR; 592 cal = Calendar::createInstance(Locale("he_IL@calendar=hebrew"), status); 593 if (failure(status, "Calendar::createInstance")) { 594 return; 595 } else { 596 cal->roll(Calendar::MONTH, (int32_t)100, status); 597 } 598 599 LocalPointer<StringEnumeration> values( 600 Calendar::getKeywordValuesForLocale("calendar", Locale("he"), FALSE, status)); 601 if (values.isNull() || U_FAILURE(status)) { 602 dataerrln("FAIL: Calendar::getKeywordValuesForLocale(he): %s", u_errorName(status)); 603 } else { 604 UBool containsHebrew = FALSE; 605 const char *charValue; 606 int32_t valueLength; 607 while ((charValue = values->next(&valueLength, status)) != NULL) { 608 if (valueLength == 6 && strcmp(charValue, "hebrew") == 0) { 609 containsHebrew = TRUE; 610 } 611 } 612 if (!containsHebrew) { 613 errln("Calendar::getKeywordValuesForLocale(he)->next() does not contain \"hebrew\""); 614 } 615 616 values->reset(status); 617 containsHebrew = FALSE; 618 UnicodeString hebrew = UNICODE_STRING_SIMPLE("hebrew"); 619 const UChar *ucharValue; 620 while ((ucharValue = values->unext(&valueLength, status)) != NULL) { 621 UnicodeString value(FALSE, ucharValue, valueLength); 622 if (value == hebrew) { 623 containsHebrew = TRUE; 624 } 625 } 626 if (!containsHebrew) { 627 errln("Calendar::getKeywordValuesForLocale(he)->unext() does not contain \"hebrew\""); 628 } 629 630 values->reset(status); 631 containsHebrew = FALSE; 632 const UnicodeString *stringValue; 633 while ((stringValue = values->snext(status)) != NULL) { 634 if (*stringValue == hebrew) { 635 containsHebrew = TRUE; 636 } 637 } 638 if (!containsHebrew) { 639 errln("Calendar::getKeywordValuesForLocale(he)->snext() does not contain \"hebrew\""); 640 } 641 } 642 delete cal; 643 } 644 645 // ------------------------------------- 646 647 /** 648 * This test confirms the correct behavior of add when incrementing 649 * through subsequent days. 650 */ 651 void 652 CalendarTest::TestRog() 653 { 654 UErrorCode status = U_ZERO_ERROR; 655 GregorianCalendar* gc = new GregorianCalendar(status); 656 if (failure(status, "new GregorianCalendar", TRUE)) return; 657 int32_t year = 1997, month = UCAL_APRIL, date = 1; 658 gc->set(year, month, date); 659 gc->set(UCAL_HOUR_OF_DAY, 23); 660 gc->set(UCAL_MINUTE, 0); 661 gc->set(UCAL_SECOND, 0); 662 gc->set(UCAL_MILLISECOND, 0); 663 for (int32_t i = 0; i < 9; i++, gc->add(UCAL_DATE, 1, status)) { 664 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; } 665 if (gc->get(UCAL_YEAR, status) != year || 666 gc->get(UCAL_MONTH, status) != month || 667 gc->get(UCAL_DATE, status) != (date + i)) errln("FAIL: Date wrong"); 668 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; } 669 } 670 delete gc; 671 } 672 673 // ------------------------------------- 674 675 /** 676 * Test the handling of the day of the week, checking for correctness and 677 * for correct minimum and maximum values. 678 */ 679 void 680 CalendarTest::TestDOW943() 681 { 682 dowTest(FALSE); 683 dowTest(TRUE); 684 } 685 686 void CalendarTest::dowTest(UBool lenient) 687 { 688 UErrorCode status = U_ZERO_ERROR; 689 GregorianCalendar* cal = new GregorianCalendar(status); 690 if (failure(status, "new GregorianCalendar", TRUE)) return; 691 logln("cal - Aug 12, 1997\n"); 692 cal->set(1997, UCAL_AUGUST, 12); 693 cal->getTime(status); 694 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; } 695 logln((lenient?UnicodeString("LENIENT0: "):UnicodeString("nonlenient0: ")) + UnicodeString(calToStr(*cal))); 696 cal->setLenient(lenient); 697 logln("cal - Dec 1, 1996\n"); 698 cal->set(1996, UCAL_DECEMBER, 1); 699 logln((lenient?UnicodeString("LENIENT: "):UnicodeString("nonlenient: ")) + UnicodeString(calToStr(*cal))); 700 int32_t dow = cal->get(UCAL_DAY_OF_WEEK, status); 701 if (U_FAILURE(status)) { errln("Calendar::get failed [%s]", u_errorName(status)); return; } 702 int32_t min = cal->getMinimum(UCAL_DAY_OF_WEEK); 703 int32_t max = cal->getMaximum(UCAL_DAY_OF_WEEK); 704 if (dow < min || 705 dow > max) errln(UnicodeString("FAIL: Day of week ") + (int32_t)dow + " out of range"); 706 if (dow != UCAL_SUNDAY) errln("FAIL: Day of week should be SUNDAY[%d] not %d", UCAL_SUNDAY, dow); 707 if (min != UCAL_SUNDAY || 708 max != UCAL_SATURDAY) errln("FAIL: Min/max bad"); 709 delete cal; 710 } 711 712 // ------------------------------------- 713 714 /** 715 * Confirm that cloned Calendar objects do not inadvertently share substructures. 716 */ 717 void 718 CalendarTest::TestClonesUnique908() 719 { 720 UErrorCode status = U_ZERO_ERROR; 721 Calendar *c = Calendar::createInstance(status); 722 if (failure(status, "Calendar::createInstance", TRUE)) return; 723 Calendar *d = (Calendar*) c->clone(); 724 c->set(UCAL_MILLISECOND, 123); 725 d->set(UCAL_MILLISECOND, 456); 726 if (c->get(UCAL_MILLISECOND, status) != 123 || 727 d->get(UCAL_MILLISECOND, status) != 456) { 728 errln("FAIL: Clones share fields"); 729 } 730 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; } 731 delete c; 732 delete d; 733 } 734 735 // ------------------------------------- 736 737 /** 738 * Confirm that the Gregorian cutoff value works as advertised. 739 */ 740 void 741 CalendarTest::TestGregorianChange768() 742 { 743 UBool b; 744 UErrorCode status = U_ZERO_ERROR; 745 UnicodeString str; 746 GregorianCalendar* c = new GregorianCalendar(status); 747 if (failure(status, "new GregorianCalendar", TRUE)) return; 748 logln(UnicodeString("With cutoff ") + dateToString(c->getGregorianChange(), str)); 749 b = c->isLeapYear(1800); 750 logln(UnicodeString(" isLeapYear(1800) = ") + (b ? "true" : "false")); 751 logln(UnicodeString(" (should be FALSE)")); 752 if (b) errln("FAIL"); 753 c->setGregorianChange(date(0, 0, 1), status); 754 if (U_FAILURE(status)) { errln("GregorianCalendar::setGregorianChange failed"); return; } 755 logln(UnicodeString("With cutoff ") + dateToString(c->getGregorianChange(), str)); 756 b = c->isLeapYear(1800); 757 logln(UnicodeString(" isLeapYear(1800) = ") + (b ? "true" : "false")); 758 logln(UnicodeString(" (should be TRUE)")); 759 if (!b) errln("FAIL"); 760 delete c; 761 } 762 763 // ------------------------------------- 764 765 /** 766 * Confirm the functioning of the field disambiguation algorithm. 767 */ 768 void 769 CalendarTest::TestDisambiguation765() 770 { 771 UErrorCode status = U_ZERO_ERROR; 772 Calendar *c = Calendar::createInstance("en_US", status); 773 if (failure(status, "Calendar::createInstance", TRUE)) return; 774 c->setLenient(FALSE); 775 c->clear(); 776 c->set(UCAL_YEAR, 1997); 777 c->set(UCAL_MONTH, UCAL_JUNE); 778 c->set(UCAL_DATE, 3); 779 verify765("1997 third day of June = ", c, 1997, UCAL_JUNE, 3); 780 c->clear(); 781 c->set(UCAL_YEAR, 1997); 782 c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY); 783 c->set(UCAL_MONTH, UCAL_JUNE); 784 c->set(UCAL_DAY_OF_WEEK_IN_MONTH, 1); 785 verify765("1997 first Tuesday in June = ", c, 1997, UCAL_JUNE, 3); 786 c->clear(); 787 c->set(UCAL_YEAR, 1997); 788 c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY); 789 c->set(UCAL_MONTH, UCAL_JUNE); 790 c->set(UCAL_DAY_OF_WEEK_IN_MONTH, - 1); 791 verify765("1997 last Tuesday in June = ", c, 1997, UCAL_JUNE, 24); 792 793 status = U_ZERO_ERROR; 794 c->clear(); 795 c->set(UCAL_YEAR, 1997); 796 c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY); 797 c->set(UCAL_MONTH, UCAL_JUNE); 798 c->set(UCAL_DAY_OF_WEEK_IN_MONTH, 0); 799 c->getTime(status); 800 verify765("1997 zero-th Tuesday in June = ", status); 801 802 c->clear(); 803 c->set(UCAL_YEAR, 1997); 804 c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY); 805 c->set(UCAL_MONTH, UCAL_JUNE); 806 c->set(UCAL_WEEK_OF_MONTH, 1); 807 verify765("1997 Tuesday in week 1 of June = ", c, 1997, UCAL_JUNE, 3); 808 c->clear(); 809 c->set(UCAL_YEAR, 1997); 810 c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY); 811 c->set(UCAL_MONTH, UCAL_JUNE); 812 c->set(UCAL_WEEK_OF_MONTH, 5); 813 verify765("1997 Tuesday in week 5 of June = ", c, 1997, UCAL_JULY, 1); 814 815 status = U_ZERO_ERROR; 816 c->clear(); 817 c->set(UCAL_YEAR, 1997); 818 c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY); 819 c->set(UCAL_MONTH, UCAL_JUNE); 820 c->set(UCAL_WEEK_OF_MONTH, 0); 821 c->setMinimalDaysInFirstWeek(1); 822 c->getTime(status); 823 verify765("1997 Tuesday in week 0 of June = ", status); 824 825 /* Note: The following test used to expect YEAR 1997, WOY 1 to 826 * resolve to a date in Dec 1996; that is, to behave as if 827 * YEAR_WOY were 1997. With the addition of a new explicit 828 * YEAR_WOY field, YEAR_WOY must itself be set if that is what is 829 * desired. Using YEAR in combination with WOY is ambiguous, and 830 * results in the first WOY/DOW day of the year satisfying the 831 * given fields (there may be up to two such days). In this case, 832 * it propertly resolves to Tue Dec 30 1997, which has a WOY value 833 * of 1 (for YEAR_WOY 1998) and a DOW of Tuesday, and falls in the 834 * _calendar_ year 1997, as specified. - aliu */ 835 c->clear(); 836 c->set(UCAL_YEAR_WOY, 1997); // aliu 837 c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY); 838 c->set(UCAL_WEEK_OF_YEAR, 1); 839 verify765("1997 Tuesday in week 1 of yearWOY = ", c, 1996, UCAL_DECEMBER, 31); 840 c->clear(); // - add test for YEAR 841 c->setMinimalDaysInFirstWeek(1); 842 c->set(UCAL_YEAR, 1997); 843 c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY); 844 c->set(UCAL_WEEK_OF_YEAR, 1); 845 verify765("1997 Tuesday in week 1 of year = ", c, 1997, UCAL_DECEMBER, 30); 846 c->clear(); 847 c->set(UCAL_YEAR, 1997); 848 c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY); 849 c->set(UCAL_WEEK_OF_YEAR, 10); 850 verify765("1997 Tuesday in week 10 of year = ", c, 1997, UCAL_MARCH, 4); 851 //try { 852 853 // {sfb} week 0 is no longer a valid week of year 854 /*c->clear(); 855 c->set(Calendar::YEAR, 1997); 856 c->set(Calendar::DAY_OF_WEEK, Calendar::TUESDAY); 857 //c->set(Calendar::WEEK_OF_YEAR, 0); 858 c->set(Calendar::WEEK_OF_YEAR, 1); 859 verify765("1997 Tuesday in week 0 of year = ", c, 1996, Calendar::DECEMBER, 24);*/ 860 861 //} 862 //catch(IllegalArgumentException ex) { 863 // errln("FAIL: Exception seen:"); 864 // ex.printStackTrace(log); 865 //} 866 delete c; 867 } 868 869 // ------------------------------------- 870 871 void 872 CalendarTest::verify765(const UnicodeString& msg, Calendar* c, int32_t year, int32_t month, int32_t day) 873 { 874 UnicodeString str; 875 UErrorCode status = U_ZERO_ERROR; 876 int32_t y = c->get(UCAL_YEAR, status); 877 int32_t m = c->get(UCAL_MONTH, status); 878 int32_t d = c->get(UCAL_DATE, status); 879 if ( y == year && 880 m == month && 881 d == day) { 882 if (U_FAILURE(status)) { errln("FAIL: Calendar::get failed"); return; } 883 logln("PASS: " + msg + dateToString(c->getTime(status), str)); 884 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; } 885 } 886 else { 887 errln("FAIL: " + msg + dateToString(c->getTime(status), str) + "; expected " + (int32_t)year + "/" + (int32_t)(month + 1) + "/" + (int32_t)day + 888 "; got " + (int32_t)y + "/" + (int32_t)(m + 1) + "/" + (int32_t)d + " for Locale: " + c->getLocaleID(ULOC_ACTUAL_LOCALE,status)); 889 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; } 890 } 891 } 892 893 // ------------------------------------- 894 895 void 896 CalendarTest::verify765(const UnicodeString& msg/*, IllegalArgumentException e*/, UErrorCode status) 897 { 898 if (status != U_ILLEGAL_ARGUMENT_ERROR) errln("FAIL: No IllegalArgumentException for " + msg); 899 else logln("PASS: " + msg + "IllegalArgument as expected"); 900 } 901 902 // ------------------------------------- 903 904 /** 905 * Confirm that the offset between local time and GMT behaves as expected. 906 */ 907 void 908 CalendarTest::TestGMTvsLocal4064654() 909 { 910 test4064654(1997, 1, 1, 12, 0, 0); 911 test4064654(1997, 4, 16, 18, 30, 0); 912 } 913 914 // ------------------------------------- 915 916 void 917 CalendarTest::test4064654(int32_t yr, int32_t mo, int32_t dt, int32_t hr, int32_t mn, int32_t sc) 918 { 919 UDate date; 920 UErrorCode status = U_ZERO_ERROR; 921 UnicodeString str; 922 Calendar *gmtcal = Calendar::createInstance(status); 923 if (failure(status, "Calendar::createInstance", TRUE)) return; 924 gmtcal->adoptTimeZone(TimeZone::createTimeZone("Africa/Casablanca")); 925 gmtcal->set(yr, mo - 1, dt, hr, mn, sc); 926 gmtcal->set(UCAL_MILLISECOND, 0); 927 date = gmtcal->getTime(status); 928 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; } 929 logln("date = " + dateToString(date, str)); 930 Calendar *cal = Calendar::createInstance(status); 931 if (U_FAILURE(status)) { errln("Calendar::createInstance failed"); return; } 932 cal->setTime(date, status); 933 if (U_FAILURE(status)) { errln("Calendar::setTime failed"); return; } 934 int32_t offset = cal->getTimeZone().getOffset((uint8_t)cal->get(UCAL_ERA, status), 935 cal->get(UCAL_YEAR, status), 936 cal->get(UCAL_MONTH, status), 937 cal->get(UCAL_DATE, status), 938 (uint8_t)cal->get(UCAL_DAY_OF_WEEK, status), 939 cal->get(UCAL_MILLISECOND, status), status); 940 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; } 941 logln("offset for " + dateToString(date, str) + "= " + (offset / 1000 / 60 / 60.0) + "hr"); 942 int32_t utc = ((cal->get(UCAL_HOUR_OF_DAY, status) * 60 + 943 cal->get(UCAL_MINUTE, status)) * 60 + 944 cal->get(UCAL_SECOND, status)) * 1000 + 945 cal->get(UCAL_MILLISECOND, status) - offset; 946 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; } 947 int32_t expected = ((hr * 60 + mn) * 60 + sc) * 1000; 948 if (utc != expected) errln(UnicodeString("FAIL: Discrepancy of ") + (utc - expected) + 949 " millis = " + ((utc - expected) / 1000 / 60 / 60.0) + " hr"); 950 delete gmtcal; 951 delete cal; 952 } 953 954 // ------------------------------------- 955 956 /** 957 * The operations of adding and setting should not exhibit pathological 958 * dependence on the order of operations. This test checks for this. 959 */ 960 void 961 CalendarTest::TestAddSetOrder621() 962 { 963 UDate d = date(97, 4, 14, 13, 23, 45); 964 UErrorCode status = U_ZERO_ERROR; 965 Calendar *cal = Calendar::createInstance(status); 966 if (failure(status, "Calendar::createInstance", TRUE)) return; 967 968 cal->setTime(d, status); 969 if (U_FAILURE(status)) { 970 errln("Calendar::setTime failed"); 971 delete cal; 972 return; 973 } 974 cal->add(UCAL_DATE, - 5, status); 975 if (U_FAILURE(status)) { 976 errln("Calendar::add failed"); 977 delete cal; 978 return; 979 } 980 cal->set(UCAL_HOUR_OF_DAY, 0); 981 cal->set(UCAL_MINUTE, 0); 982 cal->set(UCAL_SECOND, 0); 983 UnicodeString s; 984 dateToString(cal->getTime(status), s); 985 if (U_FAILURE(status)) { 986 errln("Calendar::getTime failed"); 987 delete cal; 988 return; 989 } 990 delete cal; 991 992 cal = Calendar::createInstance(status); 993 if (U_FAILURE(status)) { 994 errln("Calendar::createInstance failed"); 995 delete cal; 996 return; 997 } 998 cal->setTime(d, status); 999 if (U_FAILURE(status)) { 1000 errln("Calendar::setTime failed"); 1001 delete cal; 1002 return; 1003 } 1004 cal->set(UCAL_HOUR_OF_DAY, 0); 1005 cal->set(UCAL_MINUTE, 0); 1006 cal->set(UCAL_SECOND, 0); 1007 cal->add(UCAL_DATE, - 5, status); 1008 if (U_FAILURE(status)) { 1009 errln("Calendar::add failed"); 1010 delete cal; 1011 return; 1012 } 1013 UnicodeString s2; 1014 dateToString(cal->getTime(status), s2); 1015 if (U_FAILURE(status)) { 1016 errln("Calendar::getTime failed"); 1017 delete cal; 1018 return; 1019 } 1020 if (s == s2) 1021 logln("Pass: " + s + " == " + s2); 1022 else 1023 errln("FAIL: " + s + " != " + s2); 1024 delete cal; 1025 } 1026 1027 // ------------------------------------- 1028 1029 /** 1030 * Confirm that adding to various fields works. 1031 */ 1032 void 1033 CalendarTest::TestAdd520() 1034 { 1035 int32_t y = 1997, m = UCAL_FEBRUARY, d = 1; 1036 UErrorCode status = U_ZERO_ERROR; 1037 GregorianCalendar *temp = new GregorianCalendar(y, m, d, status); 1038 if (failure(status, "new GregorianCalendar", TRUE)) return; 1039 check520(temp, y, m, d); 1040 temp->add(UCAL_YEAR, 1, status); 1041 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; } 1042 y++; 1043 check520(temp, y, m, d); 1044 temp->add(UCAL_MONTH, 1, status); 1045 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; } 1046 m++; 1047 check520(temp, y, m, d); 1048 temp->add(UCAL_DATE, 1, status); 1049 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; } 1050 d++; 1051 check520(temp, y, m, d); 1052 temp->add(UCAL_DATE, 2, status); 1053 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; } 1054 d += 2; 1055 check520(temp, y, m, d); 1056 temp->add(UCAL_DATE, 28, status); 1057 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; } 1058 d = 1;++m; 1059 check520(temp, y, m, d); 1060 delete temp; 1061 } 1062 1063 // ------------------------------------- 1064 1065 /** 1066 * Execute adding and rolling in GregorianCalendar extensively, 1067 */ 1068 void 1069 CalendarTest::TestAddRollExtensive() 1070 { 1071 int32_t maxlimit = 40; 1072 int32_t y = 1997, m = UCAL_FEBRUARY, d = 1, hr = 1, min = 1, sec = 0, ms = 0; 1073 UErrorCode status = U_ZERO_ERROR; 1074 GregorianCalendar *temp = new GregorianCalendar(y, m, d, status); 1075 if (failure(status, "new GregorianCalendar", TRUE)) return; 1076 1077 temp->set(UCAL_HOUR, hr); 1078 temp->set(UCAL_MINUTE, min); 1079 temp->set(UCAL_SECOND, sec); 1080 temp->set(UCAL_MILLISECOND, ms); 1081 temp->setMinimalDaysInFirstWeek(1); 1082 1083 UCalendarDateFields e; 1084 1085 logln("Testing GregorianCalendar add..."); 1086 e = UCAL_YEAR; 1087 while (e < UCAL_FIELD_COUNT) { 1088 int32_t i; 1089 int32_t limit = maxlimit; 1090 status = U_ZERO_ERROR; 1091 for (i = 0; i < limit; i++) { 1092 temp->add(e, 1, status); 1093 if (U_FAILURE(status)) { limit = i; status = U_ZERO_ERROR; } 1094 } 1095 for (i = 0; i < limit; i++) { 1096 temp->add(e, -1, status); 1097 if (U_FAILURE(status)) { errln("GregorianCalendar::add -1 failed"); return; } 1098 } 1099 check520(temp, y, m, d, hr, min, sec, ms, e); 1100 1101 e = (UCalendarDateFields) ((int32_t) e + 1); 1102 } 1103 1104 logln("Testing GregorianCalendar roll..."); 1105 e = UCAL_YEAR; 1106 while (e < UCAL_FIELD_COUNT) { 1107 int32_t i; 1108 int32_t limit = maxlimit; 1109 status = U_ZERO_ERROR; 1110 for (i = 0; i < limit; i++) { 1111 logln(calToStr(*temp) + UnicodeString(" " ) + fieldName(e) + UnicodeString("++") ); 1112 temp->roll(e, 1, status); 1113 if (U_FAILURE(status)) { 1114 logln("caltest.cpp:%d e=%d, i=%d - roll(+) err %s\n", __LINE__, (int) e, (int) i, u_errorName(status)); 1115 logln(calToStr(*temp)); 1116 limit = i; status = U_ZERO_ERROR; 1117 } 1118 } 1119 for (i = 0; i < limit; i++) { 1120 logln("caltest.cpp:%d e=%d, i=%d\n", __LINE__, (int) e, (int) i); 1121 logln(calToStr(*temp) + UnicodeString(" " ) + fieldName(e) + UnicodeString("--") ); 1122 temp->roll(e, -1, status); 1123 if (U_FAILURE(status)) { errln(UnicodeString("GregorianCalendar::roll ") + CalendarTest::fieldName(e) + " count=" + UnicodeString('@'+i) + " by -1 failed with " + u_errorName(status) ); return; } 1124 } 1125 check520(temp, y, m, d, hr, min, sec, ms, e); 1126 1127 e = (UCalendarDateFields) ((int32_t) e + 1); 1128 } 1129 1130 delete temp; 1131 } 1132 1133 // ------------------------------------- 1134 void 1135 CalendarTest::check520(Calendar* c, 1136 int32_t y, int32_t m, int32_t d, 1137 int32_t hr, int32_t min, int32_t sec, 1138 int32_t ms, UCalendarDateFields field) 1139 1140 { 1141 UErrorCode status = U_ZERO_ERROR; 1142 if (c->get(UCAL_YEAR, status) != y || 1143 c->get(UCAL_MONTH, status) != m || 1144 c->get(UCAL_DATE, status) != d || 1145 c->get(UCAL_HOUR, status) != hr || 1146 c->get(UCAL_MINUTE, status) != min || 1147 c->get(UCAL_SECOND, status) != sec || 1148 c->get(UCAL_MILLISECOND, status) != ms) { 1149 errln(UnicodeString("U_FAILURE for field ") + (int32_t)field + 1150 ": Expected y/m/d h:m:s:ms of " + 1151 y + "/" + (m + 1) + "/" + d + " " + 1152 hr + ":" + min + ":" + sec + ":" + ms + 1153 "; got " + c->get(UCAL_YEAR, status) + 1154 "/" + (c->get(UCAL_MONTH, status) + 1) + 1155 "/" + c->get(UCAL_DATE, status) + 1156 " " + c->get(UCAL_HOUR, status) + ":" + 1157 c->get(UCAL_MINUTE, status) + ":" + 1158 c->get(UCAL_SECOND, status) + ":" + 1159 c->get(UCAL_MILLISECOND, status) 1160 ); 1161 1162 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; } 1163 } 1164 else 1165 logln(UnicodeString("Confirmed: ") + y + "/" + 1166 (m + 1) + "/" + d + " " + 1167 hr + ":" + min + ":" + sec + ":" + ms); 1168 } 1169 1170 // ------------------------------------- 1171 void 1172 CalendarTest::check520(Calendar* c, 1173 int32_t y, int32_t m, int32_t d) 1174 1175 { 1176 UErrorCode status = U_ZERO_ERROR; 1177 if (c->get(UCAL_YEAR, status) != y || 1178 c->get(UCAL_MONTH, status) != m || 1179 c->get(UCAL_DATE, status) != d) { 1180 errln(UnicodeString("FAILURE: Expected y/m/d of ") + 1181 y + "/" + (m + 1) + "/" + d + " " + 1182 "; got " + c->get(UCAL_YEAR, status) + 1183 "/" + (c->get(UCAL_MONTH, status) + 1) + 1184 "/" + c->get(UCAL_DATE, status) 1185 ); 1186 1187 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; } 1188 } 1189 else 1190 logln(UnicodeString("Confirmed: ") + y + "/" + 1191 (m + 1) + "/" + d); 1192 } 1193 1194 // ------------------------------------- 1195 1196 /** 1197 * Test that setting of fields works. In particular, make sure that all instances 1198 * of GregorianCalendar don't share a static instance of the fields array. 1199 */ 1200 void 1201 CalendarTest::TestFieldSet4781() 1202 { 1203 // try { 1204 UErrorCode status = U_ZERO_ERROR; 1205 GregorianCalendar *g = new GregorianCalendar(status); 1206 if (failure(status, "new GregorianCalendar", TRUE)) return; 1207 GregorianCalendar *g2 = new GregorianCalendar(status); 1208 if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; } 1209 g2->set(UCAL_HOUR, 12, status); 1210 g2->set(UCAL_MINUTE, 0, status); 1211 g2->set(UCAL_SECOND, 0, status); 1212 if (U_FAILURE(status)) { errln("Calendar::set failed"); return; } 1213 if (*g == *g2) logln("Same"); 1214 else logln("Different"); 1215 //} 1216 //catch(IllegalArgumentException e) { 1217 //errln("Unexpected exception seen: " + e); 1218 //} 1219 delete g; 1220 delete g2; 1221 } 1222 1223 // ------------------------------------- 1224 1225 /* We don't support serialization on C++ 1226 void 1227 CalendarTest::TestSerialize337() 1228 { 1229 Calendar cal = Calendar::getInstance(); 1230 UBool ok = FALSE; 1231 try { 1232 FileOutputStream f = new FileOutputStream(FILENAME); 1233 ObjectOutput s = new ObjectOutputStream(f); 1234 s.writeObject(PREFIX); 1235 s.writeObject(cal); 1236 s.writeObject(POSTFIX); 1237 f.close(); 1238 FileInputStream in = new FileInputStream(FILENAME); 1239 ObjectInputStream t = new ObjectInputStream(in); 1240 UnicodeString& pre = (UnicodeString&) t.readObject(); 1241 Calendar c = (Calendar) t.readObject(); 1242 UnicodeString& post = (UnicodeString&) t.readObject(); 1243 in.close(); 1244 ok = pre.equals(PREFIX) && 1245 post.equals(POSTFIX) && 1246 cal->equals(c); 1247 File fl = new File(FILENAME); 1248 fl.delete(); 1249 } 1250 catch(IOException e) { 1251 errln("FAIL: Exception received:"); 1252 e.printStackTrace(log); 1253 } 1254 catch(ClassNotFoundException e) { 1255 errln("FAIL: Exception received:"); 1256 e.printStackTrace(log); 1257 } 1258 if (!ok) errln("Serialization of Calendar object failed."); 1259 } 1260 1261 UnicodeString& CalendarTest::PREFIX = "abc"; 1262 1263 UnicodeString& CalendarTest::POSTFIX = "def"; 1264 1265 UnicodeString& CalendarTest::FILENAME = "tmp337.bin"; 1266 */ 1267 1268 // ------------------------------------- 1269 1270 /** 1271 * Verify that the seconds of a Calendar can be zeroed out through the 1272 * expected sequence of operations. 1273 */ 1274 void 1275 CalendarTest::TestSecondsZero121() 1276 { 1277 UErrorCode status = U_ZERO_ERROR; 1278 Calendar *cal = new GregorianCalendar(status); 1279 if (failure(status, "new GregorianCalendar", TRUE)) return; 1280 cal->setTime(Calendar::getNow(), status); 1281 if (U_FAILURE(status)) { errln("Calendar::setTime failed"); return; } 1282 cal->set(UCAL_SECOND, 0); 1283 if (U_FAILURE(status)) { errln("Calendar::set failed"); return; } 1284 UDate d = cal->getTime(status); 1285 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; } 1286 UnicodeString s; 1287 dateToString(d, s); 1288 if (s.indexOf("DATE_FORMAT_FAILURE") >= 0) { 1289 dataerrln("Got: \"DATE_FORMAT_FAILURE\"."); 1290 } else if (s.indexOf(":00 ") < 0) { 1291 errln("Expected to see :00 in " + s); 1292 } 1293 delete cal; 1294 } 1295 1296 // ------------------------------------- 1297 1298 /** 1299 * Verify that a specific sequence of adding and setting works as expected; 1300 * it should not vary depending on when and whether the get method is 1301 * called. 1302 */ 1303 void 1304 CalendarTest::TestAddSetGet0610() 1305 { 1306 UnicodeString EXPECTED_0610("1993/0/5", ""); 1307 UErrorCode status = U_ZERO_ERROR; 1308 { 1309 Calendar *calendar = new GregorianCalendar(status); 1310 if (failure(status, "new GregorianCalendar", TRUE)) return; 1311 calendar->set(1993, UCAL_JANUARY, 4); 1312 logln("1A) " + value(calendar)); 1313 calendar->add(UCAL_DATE, 1, status); 1314 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; } 1315 UnicodeString v = value(calendar); 1316 logln("1B) " + v); 1317 logln("--) 1993/0/5"); 1318 if (!(v == EXPECTED_0610)) errln("Expected " + EXPECTED_0610 + "; saw " + v); 1319 delete calendar; 1320 } 1321 { 1322 Calendar *calendar = new GregorianCalendar(1993, UCAL_JANUARY, 4, status); 1323 if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; } 1324 logln("2A) " + value(calendar)); 1325 calendar->add(UCAL_DATE, 1, status); 1326 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; } 1327 UnicodeString v = value(calendar); 1328 logln("2B) " + v); 1329 logln("--) 1993/0/5"); 1330 if (!(v == EXPECTED_0610)) errln("Expected " + EXPECTED_0610 + "; saw " + v); 1331 delete calendar; 1332 } 1333 { 1334 Calendar *calendar = new GregorianCalendar(1993, UCAL_JANUARY, 4, status); 1335 if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; } 1336 logln("3A) " + value(calendar)); 1337 calendar->getTime(status); 1338 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; } 1339 calendar->add(UCAL_DATE, 1, status); 1340 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; } 1341 UnicodeString v = value(calendar); 1342 logln("3B) " + v); 1343 logln("--) 1993/0/5"); 1344 if (!(v == EXPECTED_0610)) errln("Expected " + EXPECTED_0610 + "; saw " + v); 1345 delete calendar; 1346 } 1347 } 1348 1349 // ------------------------------------- 1350 1351 UnicodeString 1352 CalendarTest::value(Calendar* calendar) 1353 { 1354 UErrorCode status = U_ZERO_ERROR; 1355 return UnicodeString("") + (int32_t)calendar->get(UCAL_YEAR, status) + 1356 "/" + (int32_t)calendar->get(UCAL_MONTH, status) + 1357 "/" + (int32_t)calendar->get(UCAL_DATE, status) + 1358 (U_FAILURE(status) ? " FAIL: Calendar::get failed" : ""); 1359 } 1360 1361 1362 // ------------------------------------- 1363 1364 /** 1365 * Verify that various fields on a known date are set correctly. 1366 */ 1367 void 1368 CalendarTest::TestFields060() 1369 { 1370 UErrorCode status = U_ZERO_ERROR; 1371 int32_t year = 1997; 1372 int32_t month = UCAL_OCTOBER; 1373 int32_t dDate = 22; 1374 GregorianCalendar *calendar = 0; 1375 calendar = new GregorianCalendar(year, month, dDate, status); 1376 if (failure(status, "new GregorianCalendar", TRUE)) return; 1377 for (int32_t i = 0; i < EXPECTED_FIELDS_length;) { 1378 UCalendarDateFields field = (UCalendarDateFields)EXPECTED_FIELDS[i++]; 1379 int32_t expected = EXPECTED_FIELDS[i++]; 1380 if (calendar->get(field, status) != expected) { 1381 errln(UnicodeString("Expected field ") + (int32_t)field + " to have value " + (int32_t)expected + 1382 "; received " + (int32_t)calendar->get(field, status) + " instead"); 1383 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; } 1384 } 1385 } 1386 delete calendar; 1387 } 1388 1389 int32_t CalendarTest::EXPECTED_FIELDS[] = { 1390 UCAL_YEAR, 1997, 1391 UCAL_MONTH, UCAL_OCTOBER, 1392 UCAL_DATE, 22, 1393 UCAL_DAY_OF_WEEK, UCAL_WEDNESDAY, 1394 UCAL_DAY_OF_WEEK_IN_MONTH, 4, 1395 UCAL_DAY_OF_YEAR, 295 1396 }; 1397 1398 const int32_t CalendarTest::EXPECTED_FIELDS_length = (int32_t)(sizeof(CalendarTest::EXPECTED_FIELDS) / 1399 sizeof(CalendarTest::EXPECTED_FIELDS[0])); 1400 1401 // ------------------------------------- 1402 1403 /** 1404 * Verify that various fields on a known date are set correctly. In this 1405 * case, the start of the epoch (January 1 1970). 1406 */ 1407 void 1408 CalendarTest::TestEpochStartFields() 1409 { 1410 UErrorCode status = U_ZERO_ERROR; 1411 TimeZone *z = TimeZone::createDefault(); 1412 Calendar *c = Calendar::createInstance(status); 1413 if (failure(status, "Calendar::createInstance", TRUE)) return; 1414 UDate d = - z->getRawOffset(); 1415 GregorianCalendar *gc = new GregorianCalendar(status); 1416 if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; } 1417 gc->setTimeZone(*z); 1418 gc->setTime(d, status); 1419 if (U_FAILURE(status)) { errln("Calendar::setTime failed"); return; } 1420 UBool idt = gc->inDaylightTime(status); 1421 if (U_FAILURE(status)) { errln("GregorianCalendar::inDaylightTime failed"); return; } 1422 if (idt) { 1423 UnicodeString str; 1424 logln("Warning: Skipping test because " + dateToString(d, str) + " is in DST."); 1425 } 1426 else { 1427 c->setTime(d, status); 1428 if (U_FAILURE(status)) { errln("Calendar::setTime failed"); return; } 1429 for (int32_t i = 0; i < UCAL_ZONE_OFFSET;++i) { 1430 if (c->get((UCalendarDateFields)i, status) != EPOCH_FIELDS[i]) 1431 dataerrln(UnicodeString("Expected field ") + i + " to have value " + EPOCH_FIELDS[i] + 1432 "; saw " + c->get((UCalendarDateFields)i, status) + " instead"); 1433 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; } 1434 } 1435 if (c->get(UCAL_ZONE_OFFSET, status) != z->getRawOffset()) 1436 { 1437 errln(UnicodeString("Expected field ZONE_OFFSET to have value ") + z->getRawOffset() + 1438 "; saw " + c->get(UCAL_ZONE_OFFSET, status) + " instead"); 1439 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; } 1440 } 1441 if (c->get(UCAL_DST_OFFSET, status) != 0) 1442 { 1443 errln(UnicodeString("Expected field DST_OFFSET to have value 0") + 1444 "; saw " + c->get(UCAL_DST_OFFSET, status) + " instead"); 1445 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; } 1446 } 1447 } 1448 delete c; 1449 delete z; 1450 delete gc; 1451 } 1452 1453 int32_t CalendarTest::EPOCH_FIELDS[] = { 1454 1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, - 28800000, 0 1455 }; 1456 1457 // ------------------------------------- 1458 1459 /** 1460 * Test that the days of the week progress properly when add is called repeatedly 1461 * for increments of 24 days. 1462 */ 1463 void 1464 CalendarTest::TestDOWProgression() 1465 { 1466 UErrorCode status = U_ZERO_ERROR; 1467 Calendar *cal = new GregorianCalendar(1972, UCAL_OCTOBER, 26, status); 1468 if (failure(status, "new GregorianCalendar", TRUE)) return; 1469 marchByDelta(cal, 24); 1470 delete cal; 1471 } 1472 1473 // ------------------------------------- 1474 1475 void 1476 CalendarTest::TestDOW_LOCALandYEAR_WOY() 1477 { 1478 /* Note: I've commented out the loop_addroll tests for YEAR and 1479 * YEAR_WOY below because these two fields should NOT behave 1480 * identically when adding. YEAR should keep the month/dom 1481 * invariant. YEAR_WOY should keep the woy/dow invariant. I've 1482 * added a new test that checks for this in place of the old call 1483 * to loop_addroll. - aliu */ 1484 UErrorCode status = U_ZERO_ERROR; 1485 int32_t times = 20; 1486 Calendar *cal=Calendar::createInstance(Locale::getGermany(), status); 1487 if (failure(status, "Calendar::createInstance", TRUE)) return; 1488 SimpleDateFormat *sdf=new SimpleDateFormat(UnicodeString("YYYY'-W'ww-ee"), Locale::getGermany(), status); 1489 if (U_FAILURE(status)) { dataerrln("Couldn't create SimpleDateFormat - %s", u_errorName(status)); return; } 1490 1491 // ICU no longer use localized date-time pattern characters by default. 1492 // So we set pattern chars using 'J' instead of 'Y'. 1493 DateFormatSymbols *dfs = new DateFormatSymbols(Locale::getGermany(), status); 1494 dfs->setLocalPatternChars(UnicodeString("GyMdkHmsSEDFwWahKzJeugAZvcLQq")); 1495 sdf->adoptDateFormatSymbols(dfs); 1496 sdf->applyLocalizedPattern(UnicodeString("JJJJ'-W'ww-ee"), status); 1497 if (U_FAILURE(status)) { errln("Couldn't apply localized pattern"); return; } 1498 1499 cal->clear(); 1500 cal->set(1997, UCAL_DECEMBER, 25); 1501 doYEAR_WOYLoop(cal, sdf, times, status); 1502 //loop_addroll(cal, /*sdf,*/ times, UCAL_YEAR_WOY, UCAL_YEAR, status); 1503 yearAddTest(*cal, status); // aliu 1504 loop_addroll(cal, /*sdf,*/ times, UCAL_DOW_LOCAL, UCAL_DAY_OF_WEEK, status); 1505 if (U_FAILURE(status)) { errln("Error in parse/calculate test for 1997"); return; } 1506 1507 cal->clear(); 1508 cal->set(1998, UCAL_DECEMBER, 25); 1509 doYEAR_WOYLoop(cal, sdf, times, status); 1510 //loop_addroll(cal, /*sdf,*/ times, UCAL_YEAR_WOY, UCAL_YEAR, status); 1511 yearAddTest(*cal, status); // aliu 1512 loop_addroll(cal, /*sdf,*/ times, UCAL_DOW_LOCAL, UCAL_DAY_OF_WEEK, status); 1513 if (U_FAILURE(status)) { errln("Error in parse/calculate test for 1998"); return; } 1514 1515 cal->clear(); 1516 cal->set(1582, UCAL_OCTOBER, 1); 1517 doYEAR_WOYLoop(cal, sdf, times, status); 1518 //loop_addroll(cal, /*sdf,*/ times, Calendar::YEAR_WOY, Calendar::YEAR, status); 1519 yearAddTest(*cal, status); // aliu 1520 loop_addroll(cal, /*sdf,*/ times, UCAL_DOW_LOCAL, UCAL_DAY_OF_WEEK, status); 1521 if (U_FAILURE(status)) { errln("Error in parse/calculate test for 1582"); return; } 1522 delete sdf; 1523 delete cal; 1524 1525 return; 1526 } 1527 1528 /** 1529 * Confirm that adding a YEAR and adding a YEAR_WOY work properly for 1530 * the given Calendar at its current setting. 1531 */ 1532 void CalendarTest::yearAddTest(Calendar& cal, UErrorCode& status) { 1533 /** 1534 * When adding the YEAR, the month and day should remain constant. 1535 * When adding the YEAR_WOY, the WOY and DOW should remain constant. - aliu 1536 * Examples: 1537 * Wed Jan 14 1998 / 1998-W03-03 Add(YEAR_WOY, 1) -> Wed Jan 20 1999 / 1999-W03-03 1538 * Add(YEAR, 1) -> Thu Jan 14 1999 / 1999-W02-04 1539 * Thu Jan 14 1999 / 1999-W02-04 Add(YEAR_WOY, 1) -> Thu Jan 13 2000 / 2000-W02-04 1540 * Add(YEAR, 1) -> Fri Jan 14 2000 / 2000-W02-05 1541 * Sun Oct 31 1582 / 1582-W42-07 Add(YEAR_WOY, 1) -> Sun Oct 23 1583 / 1583-W42-07 1542 * Add(YEAR, 1) -> Mon Oct 31 1583 / 1583-W44-01 1543 */ 1544 int32_t y = cal.get(UCAL_YEAR, status); 1545 int32_t mon = cal.get(UCAL_MONTH, status); 1546 int32_t day = cal.get(UCAL_DATE, status); 1547 int32_t ywy = cal.get(UCAL_YEAR_WOY, status); 1548 int32_t woy = cal.get(UCAL_WEEK_OF_YEAR, status); 1549 int32_t dow = cal.get(UCAL_DOW_LOCAL, status); 1550 UDate t = cal.getTime(status); 1551 1552 if(U_FAILURE(status)){ 1553 errln(UnicodeString("Failed to create Calendar for locale. Error: ") + UnicodeString(u_errorName(status))); 1554 return; 1555 } 1556 UnicodeString str, str2; 1557 SimpleDateFormat fmt(UnicodeString("EEE MMM dd yyyy / YYYY'-W'ww-ee"), status); 1558 fmt.setCalendar(cal); 1559 1560 fmt.format(t, str.remove()); 1561 str += ".add(YEAR, 1) =>"; 1562 cal.add(UCAL_YEAR, 1, status); 1563 int32_t y2 = cal.get(UCAL_YEAR, status); 1564 int32_t mon2 = cal.get(UCAL_MONTH, status); 1565 int32_t day2 = cal.get(UCAL_DATE, status); 1566 fmt.format(cal.getTime(status), str); 1567 if (y2 != (y+1) || mon2 != mon || day2 != day) { 1568 str += (UnicodeString)", expected year " + 1569 (y+1) + ", month " + (mon+1) + ", day " + day; 1570 errln((UnicodeString)"FAIL: " + str); 1571 logln( UnicodeString(" -> ") + CalendarTest::calToStr(cal) ); 1572 } else { 1573 logln(str); 1574 } 1575 1576 fmt.format(t, str.remove()); 1577 str += ".add(YEAR_WOY, 1)=>"; 1578 cal.setTime(t, status); 1579 logln( UnicodeString(" <- ") + CalendarTest::calToStr(cal) ); 1580 cal.add(UCAL_YEAR_WOY, 1, status); 1581 int32_t ywy2 = cal.get(UCAL_YEAR_WOY, status); 1582 int32_t woy2 = cal.get(UCAL_WEEK_OF_YEAR, status); 1583 int32_t dow2 = cal.get(UCAL_DOW_LOCAL, status); 1584 fmt.format(cal.getTime(status), str); 1585 if (ywy2 != (ywy+1) || woy2 != woy || dow2 != dow) { 1586 str += (UnicodeString)", expected yearWOY " + 1587 (ywy+1) + ", woy " + woy + ", dowLocal " + dow; 1588 errln((UnicodeString)"FAIL: " + str); 1589 logln( UnicodeString(" -> ") + CalendarTest::calToStr(cal) ); 1590 } else { 1591 logln(str); 1592 } 1593 } 1594 1595 // ------------------------------------- 1596 1597 void CalendarTest::loop_addroll(Calendar *cal, /*SimpleDateFormat *sdf,*/ int times, UCalendarDateFields field, UCalendarDateFields field2, UErrorCode& errorCode) { 1598 Calendar *calclone; 1599 SimpleDateFormat fmt(UnicodeString("EEE MMM dd yyyy / YYYY'-W'ww-ee"), errorCode); 1600 fmt.setCalendar(*cal); 1601 int i; 1602 1603 for(i = 0; i<times; i++) { 1604 calclone = cal->clone(); 1605 UDate start = cal->getTime(errorCode); 1606 cal->add(field,1,errorCode); 1607 if (U_FAILURE(errorCode)) { errln("Error in add"); delete calclone; return; } 1608 calclone->add(field2,1,errorCode); 1609 if (U_FAILURE(errorCode)) { errln("Error in add"); delete calclone; return; } 1610 if(cal->getTime(errorCode) != calclone->getTime(errorCode)) { 1611 UnicodeString str("FAIL: Results of add differ. "), str2; 1612 str += fmt.format(start, str2) + " "; 1613 str += UnicodeString("Add(") + fieldName(field) + ", 1) -> " + 1614 fmt.format(cal->getTime(errorCode), str2.remove()) + "; "; 1615 str += UnicodeString("Add(") + fieldName(field2) + ", 1) -> " + 1616 fmt.format(calclone->getTime(errorCode), str2.remove()); 1617 errln(str); 1618 delete calclone; 1619 return; 1620 } 1621 delete calclone; 1622 } 1623 1624 for(i = 0; i<times; i++) { 1625 calclone = cal->clone(); 1626 cal->roll(field,(int32_t)1,errorCode); 1627 if (U_FAILURE(errorCode)) { errln("Error in roll"); delete calclone; return; } 1628 calclone->roll(field2,(int32_t)1,errorCode); 1629 if (U_FAILURE(errorCode)) { errln("Error in roll"); delete calclone; return; } 1630 if(cal->getTime(errorCode) != calclone->getTime(errorCode)) { 1631 delete calclone; 1632 errln("Results of roll differ!"); 1633 return; 1634 } 1635 delete calclone; 1636 } 1637 } 1638 1639 // ------------------------------------- 1640 1641 void 1642 CalendarTest::doYEAR_WOYLoop(Calendar *cal, SimpleDateFormat *sdf, 1643 int32_t times, UErrorCode& errorCode) { 1644 1645 UnicodeString us; 1646 UDate tst, original; 1647 Calendar *tstres = new GregorianCalendar(Locale::getGermany(), errorCode); 1648 for(int i=0; i<times; ++i) { 1649 sdf->format(Formattable(cal->getTime(errorCode),Formattable::kIsDate), us, errorCode); 1650 //logln("expected: "+us); 1651 if (U_FAILURE(errorCode)) { errln("Format error"); return; } 1652 tst=sdf->parse(us,errorCode); 1653 if (U_FAILURE(errorCode)) { errln("Parse error"); return; } 1654 tstres->clear(); 1655 tstres->setTime(tst, errorCode); 1656 //logln((UnicodeString)"Parsed week of year is "+tstres->get(UCAL_WEEK_OF_YEAR, errorCode)); 1657 if (U_FAILURE(errorCode)) { errln("Set time error"); return; } 1658 original = cal->getTime(errorCode); 1659 us.remove(); 1660 sdf->format(Formattable(tst,Formattable::kIsDate), us, errorCode); 1661 //logln("got: "+us); 1662 if (U_FAILURE(errorCode)) { errln("Get time error"); return; } 1663 if(original!=tst) { 1664 us.remove(); 1665 sdf->format(Formattable(original, Formattable::kIsDate), us, errorCode); 1666 errln("FAIL: Parsed time doesn't match with regular"); 1667 logln("expected "+us + " " + calToStr(*cal)); 1668 us.remove(); 1669 sdf->format(Formattable(tst, Formattable::kIsDate), us, errorCode); 1670 logln("got "+us + " " + calToStr(*tstres)); 1671 } 1672 tstres->clear(); 1673 tstres->set(UCAL_YEAR_WOY, cal->get(UCAL_YEAR_WOY, errorCode)); 1674 tstres->set(UCAL_WEEK_OF_YEAR, cal->get(UCAL_WEEK_OF_YEAR, errorCode)); 1675 tstres->set(UCAL_DOW_LOCAL, cal->get(UCAL_DOW_LOCAL, errorCode)); 1676 if(cal->get(UCAL_YEAR, errorCode) != tstres->get(UCAL_YEAR, errorCode)) { 1677 errln("FAIL: Different Year!"); 1678 logln((UnicodeString)"Expected "+cal->get(UCAL_YEAR, errorCode)); 1679 logln((UnicodeString)"Got "+tstres->get(UCAL_YEAR, errorCode)); 1680 return; 1681 } 1682 if(cal->get(UCAL_DAY_OF_YEAR, errorCode) != tstres->get(UCAL_DAY_OF_YEAR, errorCode)) { 1683 errln("FAIL: Different Day Of Year!"); 1684 logln((UnicodeString)"Expected "+cal->get(UCAL_DAY_OF_YEAR, errorCode)); 1685 logln((UnicodeString)"Got "+tstres->get(UCAL_DAY_OF_YEAR, errorCode)); 1686 return; 1687 } 1688 //logln(calToStr(*cal)); 1689 cal->add(UCAL_DATE, 1, errorCode); 1690 if (U_FAILURE(errorCode)) { errln("Add error"); return; } 1691 us.remove(); 1692 } 1693 delete (tstres); 1694 } 1695 // ------------------------------------- 1696 1697 void 1698 CalendarTest::marchByDelta(Calendar* cal, int32_t delta) 1699 { 1700 UErrorCode status = U_ZERO_ERROR; 1701 Calendar *cur = (Calendar*) cal->clone(); 1702 int32_t initialDOW = cur->get(UCAL_DAY_OF_WEEK, status); 1703 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; } 1704 int32_t DOW, newDOW = initialDOW; 1705 do { 1706 UnicodeString str; 1707 DOW = newDOW; 1708 logln(UnicodeString("DOW = ") + DOW + " " + dateToString(cur->getTime(status), str)); 1709 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; } 1710 cur->add(UCAL_DAY_OF_WEEK, delta, status); 1711 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; } 1712 newDOW = cur->get(UCAL_DAY_OF_WEEK, status); 1713 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; } 1714 int32_t expectedDOW = 1 + (DOW + delta - 1) % 7; 1715 if (newDOW != expectedDOW) { 1716 errln(UnicodeString("Day of week should be ") + expectedDOW + " instead of " + newDOW + 1717 " on " + dateToString(cur->getTime(status), str)); 1718 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; } 1719 return; 1720 } 1721 } 1722 while (newDOW != initialDOW); 1723 delete cur; 1724 } 1725 1726 #define CHECK(status, msg) \ 1727 if (U_FAILURE(status)) { \ 1728 errcheckln(status, msg); \ 1729 return; \ 1730 } 1731 1732 void CalendarTest::TestWOY(void) { 1733 /* 1734 FDW = Mon, MDFW = 4: 1735 Sun Dec 26 1999, WOY 51 1736 Mon Dec 27 1999, WOY 52 1737 Tue Dec 28 1999, WOY 52 1738 Wed Dec 29 1999, WOY 52 1739 Thu Dec 30 1999, WOY 52 1740 Fri Dec 31 1999, WOY 52 1741 Sat Jan 01 2000, WOY 52 *** 1742 Sun Jan 02 2000, WOY 52 *** 1743 Mon Jan 03 2000, WOY 1 1744 Tue Jan 04 2000, WOY 1 1745 Wed Jan 05 2000, WOY 1 1746 Thu Jan 06 2000, WOY 1 1747 Fri Jan 07 2000, WOY 1 1748 Sat Jan 08 2000, WOY 1 1749 Sun Jan 09 2000, WOY 1 1750 Mon Jan 10 2000, WOY 2 1751 1752 FDW = Mon, MDFW = 2: 1753 Sun Dec 26 1999, WOY 52 1754 Mon Dec 27 1999, WOY 1 *** 1755 Tue Dec 28 1999, WOY 1 *** 1756 Wed Dec 29 1999, WOY 1 *** 1757 Thu Dec 30 1999, WOY 1 *** 1758 Fri Dec 31 1999, WOY 1 *** 1759 Sat Jan 01 2000, WOY 1 1760 Sun Jan 02 2000, WOY 1 1761 Mon Jan 03 2000, WOY 2 1762 Tue Jan 04 2000, WOY 2 1763 Wed Jan 05 2000, WOY 2 1764 Thu Jan 06 2000, WOY 2 1765 Fri Jan 07 2000, WOY 2 1766 Sat Jan 08 2000, WOY 2 1767 Sun Jan 09 2000, WOY 2 1768 Mon Jan 10 2000, WOY 3 1769 */ 1770 1771 UnicodeString str; 1772 UErrorCode status = U_ZERO_ERROR; 1773 int32_t i; 1774 1775 GregorianCalendar cal(status); 1776 SimpleDateFormat fmt(UnicodeString("EEE MMM dd yyyy', WOY' w"), status); 1777 if (failure(status, "Cannot construct calendar/format", TRUE)) return; 1778 1779 UCalendarDaysOfWeek fdw = (UCalendarDaysOfWeek) 0; 1780 1781 //for (int8_t pass=2; pass<=2; ++pass) { 1782 for (int8_t pass=1; pass<=2; ++pass) { 1783 switch (pass) { 1784 case 1: 1785 fdw = UCAL_MONDAY; 1786 cal.setFirstDayOfWeek(fdw); 1787 cal.setMinimalDaysInFirstWeek(4); 1788 fmt.adoptCalendar(cal.clone()); 1789 break; 1790 case 2: 1791 fdw = UCAL_MONDAY; 1792 cal.setFirstDayOfWeek(fdw); 1793 cal.setMinimalDaysInFirstWeek(2); 1794 fmt.adoptCalendar(cal.clone()); 1795 break; 1796 } 1797 1798 //for (i=2; i<=6; ++i) { 1799 for (i=0; i<16; ++i) { 1800 UDate t, t2; 1801 int32_t t_y, t_woy, t_dow; 1802 cal.clear(); 1803 cal.set(1999, UCAL_DECEMBER, 26 + i); 1804 fmt.format(t = cal.getTime(status), str.remove()); 1805 CHECK(status, "Fail: getTime failed"); 1806 logln(UnicodeString("* ") + str); 1807 int32_t dow = cal.get(UCAL_DAY_OF_WEEK, status); 1808 int32_t woy = cal.get(UCAL_WEEK_OF_YEAR, status); 1809 int32_t year = cal.get(UCAL_YEAR, status); 1810 int32_t mon = cal.get(UCAL_MONTH, status); 1811 logln(calToStr(cal)); 1812 CHECK(status, "Fail: get failed"); 1813 int32_t dowLocal = dow - fdw; 1814 if (dowLocal < 0) dowLocal += 7; 1815 dowLocal++; 1816 int32_t yearWoy = year; 1817 if (mon == UCAL_JANUARY) { 1818 if (woy >= 52) --yearWoy; 1819 } else { 1820 if (woy == 1) ++yearWoy; 1821 } 1822 1823 // Basic fields->time check y/woy/dow 1824 // Since Y/WOY is ambiguous, we do a check of the fields, 1825 // not of the specific time. 1826 cal.clear(); 1827 cal.set(UCAL_YEAR, year); 1828 cal.set(UCAL_WEEK_OF_YEAR, woy); 1829 cal.set(UCAL_DAY_OF_WEEK, dow); 1830 t_y = cal.get(UCAL_YEAR, status); 1831 t_woy = cal.get(UCAL_WEEK_OF_YEAR, status); 1832 t_dow = cal.get(UCAL_DAY_OF_WEEK, status); 1833 CHECK(status, "Fail: get failed"); 1834 if (t_y != year || t_woy != woy || t_dow != dow) { 1835 str = "Fail: y/woy/dow fields->time => "; 1836 fmt.format(cal.getTime(status), str); 1837 errln(str); 1838 logln(calToStr(cal)); 1839 logln("[get!=set] Y%d!=%d || woy%d!=%d || dow%d!=%d\n", 1840 t_y, year, t_woy, woy, t_dow, dow); 1841 } else { 1842 logln("y/woy/dow fields->time OK"); 1843 } 1844 1845 // Basic fields->time check y/woy/dow_local 1846 // Since Y/WOY is ambiguous, we do a check of the fields, 1847 // not of the specific time. 1848 cal.clear(); 1849 cal.set(UCAL_YEAR, year); 1850 cal.set(UCAL_WEEK_OF_YEAR, woy); 1851 cal.set(UCAL_DOW_LOCAL, dowLocal); 1852 t_y = cal.get(UCAL_YEAR, status); 1853 t_woy = cal.get(UCAL_WEEK_OF_YEAR, status); 1854 t_dow = cal.get(UCAL_DOW_LOCAL, status); 1855 CHECK(status, "Fail: get failed"); 1856 if (t_y != year || t_woy != woy || t_dow != dowLocal) { 1857 str = "Fail: y/woy/dow_local fields->time => "; 1858 fmt.format(cal.getTime(status), str); 1859 errln(str); 1860 } 1861 1862 // Basic fields->time check y_woy/woy/dow 1863 cal.clear(); 1864 cal.set(UCAL_YEAR_WOY, yearWoy); 1865 cal.set(UCAL_WEEK_OF_YEAR, woy); 1866 cal.set(UCAL_DAY_OF_WEEK, dow); 1867 t2 = cal.getTime(status); 1868 CHECK(status, "Fail: getTime failed"); 1869 if (t != t2) { 1870 str = "Fail: y_woy/woy/dow fields->time => "; 1871 fmt.format(t2, str); 1872 errln(str); 1873 logln(calToStr(cal)); 1874 logln("%.f != %.f\n", t, t2); 1875 } else { 1876 logln("y_woy/woy/dow OK"); 1877 } 1878 1879 // Basic fields->time check y_woy/woy/dow_local 1880 cal.clear(); 1881 cal.set(UCAL_YEAR_WOY, yearWoy); 1882 cal.set(UCAL_WEEK_OF_YEAR, woy); 1883 cal.set(UCAL_DOW_LOCAL, dowLocal); 1884 t2 = cal.getTime(status); 1885 CHECK(status, "Fail: getTime failed"); 1886 if (t != t2) { 1887 str = "Fail: y_woy/woy/dow_local fields->time => "; 1888 fmt.format(t2, str); 1889 errln(str); 1890 } 1891 1892 logln("Testing DOW_LOCAL.. dow%d\n", dow); 1893 // Make sure DOW_LOCAL disambiguates over DOW 1894 int32_t wrongDow = dow - 3; 1895 if (wrongDow < 1) wrongDow += 7; 1896 cal.setTime(t, status); 1897 cal.set(UCAL_DAY_OF_WEEK, wrongDow); 1898 cal.set(UCAL_DOW_LOCAL, dowLocal); 1899 t2 = cal.getTime(status); 1900 CHECK(status, "Fail: set/getTime failed"); 1901 if (t != t2) { 1902 str = "Fail: DOW_LOCAL fields->time => "; 1903 fmt.format(t2, str); 1904 errln(str); 1905 logln(calToStr(cal)); 1906 logln("%.f : DOW%d, DOW_LOCAL%d -> %.f\n", 1907 t, wrongDow, dowLocal, t2); 1908 } 1909 1910 // Make sure DOW disambiguates over DOW_LOCAL 1911 int32_t wrongDowLocal = dowLocal - 3; 1912 if (wrongDowLocal < 1) wrongDowLocal += 7; 1913 cal.setTime(t, status); 1914 cal.set(UCAL_DOW_LOCAL, wrongDowLocal); 1915 cal.set(UCAL_DAY_OF_WEEK, dow); 1916 t2 = cal.getTime(status); 1917 CHECK(status, "Fail: set/getTime failed"); 1918 if (t != t2) { 1919 str = "Fail: DOW fields->time => "; 1920 fmt.format(t2, str); 1921 errln(str); 1922 } 1923 1924 // Make sure YEAR_WOY disambiguates over YEAR 1925 cal.setTime(t, status); 1926 cal.set(UCAL_YEAR, year - 2); 1927 cal.set(UCAL_YEAR_WOY, yearWoy); 1928 t2 = cal.getTime(status); 1929 CHECK(status, "Fail: set/getTime failed"); 1930 if (t != t2) { 1931 str = "Fail: YEAR_WOY fields->time => "; 1932 fmt.format(t2, str); 1933 errln(str); 1934 } 1935 1936 // Make sure YEAR disambiguates over YEAR_WOY 1937 cal.setTime(t, status); 1938 cal.set(UCAL_YEAR_WOY, yearWoy - 2); 1939 cal.set(UCAL_YEAR, year); 1940 t2 = cal.getTime(status); 1941 CHECK(status, "Fail: set/getTime failed"); 1942 if (t != t2) { 1943 str = "Fail: YEAR fields->time => "; 1944 fmt.format(t2, str); 1945 errln(str); 1946 } 1947 } 1948 } 1949 1950 /* 1951 FDW = Mon, MDFW = 4: 1952 Sun Dec 26 1999, WOY 51 1953 Mon Dec 27 1999, WOY 52 1954 Tue Dec 28 1999, WOY 52 1955 Wed Dec 29 1999, WOY 52 1956 Thu Dec 30 1999, WOY 52 1957 Fri Dec 31 1999, WOY 52 1958 Sat Jan 01 2000, WOY 52 1959 Sun Jan 02 2000, WOY 52 1960 */ 1961 1962 // Roll the DOW_LOCAL within week 52 1963 for (i=27; i<=33; ++i) { 1964 int32_t amount; 1965 for (amount=-7; amount<=7; ++amount) { 1966 str = "roll("; 1967 cal.set(1999, UCAL_DECEMBER, i); 1968 UDate t, t2; 1969 fmt.format(cal.getTime(status), str); 1970 CHECK(status, "Fail: getTime failed"); 1971 str += UnicodeString(", ") + amount + ") = "; 1972 1973 cal.roll(UCAL_DOW_LOCAL, amount, status); 1974 CHECK(status, "Fail: roll failed"); 1975 1976 t = cal.getTime(status); 1977 int32_t newDom = i + amount; 1978 while (newDom < 27) newDom += 7; 1979 while (newDom > 33) newDom -= 7; 1980 cal.set(1999, UCAL_DECEMBER, newDom); 1981 t2 = cal.getTime(status); 1982 CHECK(status, "Fail: getTime failed"); 1983 fmt.format(t, str); 1984 1985 if (t != t2) { 1986 str.append(", exp "); 1987 fmt.format(t2, str); 1988 errln(str); 1989 } else { 1990 logln(str); 1991 } 1992 } 1993 } 1994 } 1995 1996 void CalendarTest::TestYWOY() 1997 { 1998 UnicodeString str; 1999 UErrorCode status = U_ZERO_ERROR; 2000 2001 GregorianCalendar cal(status); 2002 if (failure(status, "construct GregorianCalendar", TRUE)) return; 2003 2004 cal.setFirstDayOfWeek(UCAL_SUNDAY); 2005 cal.setMinimalDaysInFirstWeek(1); 2006 2007 logln("Setting: ywoy=2004, woy=1, dow=MONDAY"); 2008 cal.clear(); 2009 cal.set(UCAL_YEAR_WOY,2004); 2010 cal.set(UCAL_WEEK_OF_YEAR,1); 2011 cal.set(UCAL_DAY_OF_WEEK, UCAL_MONDAY); 2012 2013 logln(calToStr(cal)); 2014 if(cal.get(UCAL_YEAR, status) != 2003) { 2015 errln("year not 2003"); 2016 } 2017 2018 logln("+ setting DOW to THURSDAY"); 2019 cal.clear(); 2020 cal.set(UCAL_YEAR_WOY,2004); 2021 cal.set(UCAL_WEEK_OF_YEAR,1); 2022 cal.set(UCAL_DAY_OF_WEEK, UCAL_THURSDAY); 2023 2024 logln(calToStr(cal)); 2025 if(cal.get(UCAL_YEAR, status) != 2004) { 2026 errln("year not 2004"); 2027 } 2028 2029 logln("+ setting DOW_LOCAL to 1"); 2030 cal.clear(); 2031 cal.set(UCAL_YEAR_WOY,2004); 2032 cal.set(UCAL_WEEK_OF_YEAR,1); 2033 cal.set(UCAL_DAY_OF_WEEK, UCAL_THURSDAY); 2034 cal.set(UCAL_DOW_LOCAL, 1); 2035 2036 logln(calToStr(cal)); 2037 if(cal.get(UCAL_YEAR, status) != 2003) { 2038 errln("year not 2003"); 2039 } 2040 2041 cal.setFirstDayOfWeek(UCAL_MONDAY); 2042 cal.setMinimalDaysInFirstWeek(4); 2043 UDate t = 946713600000.; 2044 cal.setTime(t, status); 2045 cal.set(UCAL_DAY_OF_WEEK, 4); 2046 cal.set(UCAL_DOW_LOCAL, 6); 2047 if(cal.getTime(status) != t) { 2048 logln(calToStr(cal)); 2049 errln("FAIL: DOW_LOCAL did not take precedence"); 2050 } 2051 2052 } 2053 2054 void CalendarTest::TestJD() 2055 { 2056 int32_t jd; 2057 static const int32_t kEpochStartAsJulianDay = 2440588; 2058 UErrorCode status = U_ZERO_ERROR; 2059 GregorianCalendar cal(status); 2060 if (failure(status, "construct GregorianCalendar", TRUE)) return; 2061 cal.setTimeZone(*TimeZone::getGMT()); 2062 cal.clear(); 2063 jd = cal.get(UCAL_JULIAN_DAY, status); 2064 if(jd != kEpochStartAsJulianDay) { 2065 errln("Wanted JD of %d at time=0, [epoch 1970] but got %d\n", kEpochStartAsJulianDay, jd); 2066 } else { 2067 logln("Wanted JD of %d at time=0, [epoch 1970], got %d\n", kEpochStartAsJulianDay, jd); 2068 } 2069 2070 cal.setTime(Calendar::getNow(), status); 2071 cal.clear(); 2072 cal.set(UCAL_JULIAN_DAY, kEpochStartAsJulianDay); 2073 UDate epochTime = cal.getTime(status); 2074 if(epochTime != 0) { 2075 errln("Wanted time of 0 at jd=%d, got %.1lf\n", kEpochStartAsJulianDay, epochTime); 2076 } else { 2077 logln("Wanted time of 0 at jd=%d, got %.1lf\n", kEpochStartAsJulianDay, epochTime); 2078 } 2079 2080 } 2081 2082 // make sure the ctestfw utilities are in sync with the Calendar 2083 void CalendarTest::TestDebug() 2084 { 2085 for(int32_t t=0;t<=UDBG_ENUM_COUNT;t++) { 2086 int32_t count = udbg_enumCount((UDebugEnumType)t); 2087 if(count == -1) { 2088 logln("enumCount(%d) returned -1", count); 2089 continue; 2090 } 2091 for(int32_t i=0;i<=count;i++) { 2092 if(t<=UDBG_HIGHEST_CONTIGUOUS_ENUM && i<count) { 2093 if( i!=udbg_enumArrayValue((UDebugEnumType)t, i)) { 2094 errln("FAIL: udbg_enumArrayValue(%d,%d) returned %d, expected %d", t, i, udbg_enumArrayValue((UDebugEnumType)t,i), i); 2095 } 2096 } else { 2097 logln("Testing count+1:"); 2098 } 2099 const char *name = udbg_enumName((UDebugEnumType)t,i); 2100 if(name==NULL) { 2101 if(i==count || t>UDBG_HIGHEST_CONTIGUOUS_ENUM ) { 2102 logln(" null name - expected.\n"); 2103 } else { 2104 errln("FAIL: udbg_enumName(%d,%d) returned NULL", t, i); 2105 } 2106 name = "(null)"; 2107 } 2108 logln("udbg_enumArrayValue(%d,%d) = %s, returned %d", t, i, 2109 name, udbg_enumArrayValue((UDebugEnumType)t,i)); 2110 logln("udbg_enumString = " + udbg_enumString((UDebugEnumType)t,i)); 2111 } 2112 if(udbg_enumExpectedCount((UDebugEnumType)t) != count && t<=UDBG_HIGHEST_CONTIGUOUS_ENUM) { 2113 errln("FAIL: udbg_enumExpectedCount(%d): %d, != UCAL_FIELD_COUNT=%d ", t, udbg_enumExpectedCount((UDebugEnumType)t), count); 2114 } else { 2115 logln("udbg_ucal_fieldCount: %d, UCAL_FIELD_COUNT=udbg_enumCount %d ", udbg_enumExpectedCount((UDebugEnumType)t), count); 2116 } 2117 } 2118 } 2119 2120 2121 #undef CHECK 2122 2123 // List of interesting locales 2124 const char *CalendarTest::testLocaleID(int32_t i) 2125 { 2126 switch(i) { 2127 case 0: return "he_IL@calendar=hebrew"; 2128 case 1: return "en_US@calendar=hebrew"; 2129 case 2: return "fr_FR@calendar=hebrew"; 2130 case 3: return "fi_FI@calendar=hebrew"; 2131 case 4: return "nl_NL@calendar=hebrew"; 2132 case 5: return "hu_HU@calendar=hebrew"; 2133 case 6: return "nl_BE@currency=MTL;calendar=islamic"; 2134 case 7: return "th_TH_TRADITIONAL@calendar=gregorian"; 2135 case 8: return "ar_JO@calendar=islamic-civil"; 2136 case 9: return "fi_FI@calendar=islamic"; 2137 case 10: return "fr_CH@calendar=islamic-civil"; 2138 case 11: return "he_IL@calendar=islamic-civil"; 2139 case 12: return "hu_HU@calendar=buddhist"; 2140 case 13: return "hu_HU@calendar=islamic"; 2141 case 14: return "en_US@calendar=japanese"; 2142 default: return NULL; 2143 } 2144 } 2145 2146 int32_t CalendarTest::testLocaleCount() 2147 { 2148 static int32_t gLocaleCount = -1; 2149 if(gLocaleCount < 0) { 2150 int32_t i; 2151 for(i=0;testLocaleID(i) != NULL;i++) { 2152 ; 2153 } 2154 gLocaleCount = i; 2155 } 2156 return gLocaleCount; 2157 } 2158 2159 static UDate doMinDateOfCalendar(Calendar* adopt, UBool &isGregorian, UErrorCode& status) { 2160 if(U_FAILURE(status)) return 0.0; 2161 2162 adopt->clear(); 2163 adopt->set(UCAL_EXTENDED_YEAR, adopt->getActualMinimum(UCAL_EXTENDED_YEAR, status)); 2164 UDate ret = adopt->getTime(status); 2165 isGregorian = dynamic_cast<GregorianCalendar*>(adopt) != NULL; 2166 delete adopt; 2167 return ret; 2168 } 2169 2170 UDate CalendarTest::minDateOfCalendar(const Locale& locale, UBool &isGregorian, UErrorCode& status) { 2171 if(U_FAILURE(status)) return 0.0; 2172 return doMinDateOfCalendar(Calendar::createInstance(locale, status), isGregorian, status); 2173 } 2174 2175 UDate CalendarTest::minDateOfCalendar(const Calendar& cal, UBool &isGregorian, UErrorCode& status) { 2176 if(U_FAILURE(status)) return 0.0; 2177 return doMinDateOfCalendar(cal.clone(), isGregorian, status); 2178 } 2179 2180 void CalendarTest::Test6703() 2181 { 2182 UErrorCode status = U_ZERO_ERROR; 2183 Calendar *cal; 2184 2185 Locale loc1("en@calendar=fubar"); 2186 cal = Calendar::createInstance(loc1, status); 2187 if (failure(status, "Calendar::createInstance", TRUE)) return; 2188 delete cal; 2189 2190 status = U_ZERO_ERROR; 2191 Locale loc2("en"); 2192 cal = Calendar::createInstance(loc2, status); 2193 if (failure(status, "Calendar::createInstance")) return; 2194 delete cal; 2195 2196 status = U_ZERO_ERROR; 2197 Locale loc3("en@calendar=roc"); 2198 cal = Calendar::createInstance(loc3, status); 2199 if (failure(status, "Calendar::createInstance")) return; 2200 delete cal; 2201 2202 return; 2203 } 2204 2205 void CalendarTest::Test3785() 2206 { 2207 UErrorCode status = U_ZERO_ERROR; 2208 UnicodeString uzone = UNICODE_STRING_SIMPLE("Europe/Paris"); 2209 UnicodeString exp1 = UNICODE_STRING_SIMPLE("Mon 30 Jumada II 1433 AH, 01:47:03"); 2210 UnicodeString exp2 = UNICODE_STRING_SIMPLE("Mon 1 Rajab 1433 AH, 01:47:04"); 2211 2212 LocalUDateFormatPointer df(udat_open(UDAT_NONE, UDAT_NONE, "en@calendar=islamic", uzone.getTerminatedBuffer(), 2213 uzone.length(), NULL, 0, &status)); 2214 if (df.isNull() || U_FAILURE(status)) return; 2215 2216 UChar upattern[64]; 2217 u_uastrcpy(upattern, "EEE d MMMM y G, HH:mm:ss"); 2218 udat_applyPattern(df.getAlias(), FALSE, upattern, u_strlen(upattern)); 2219 2220 UChar ubuffer[1024]; 2221 UDate ud0 = 1337557623000.0; 2222 2223 status = U_ZERO_ERROR; 2224 udat_format(df.getAlias(), ud0, ubuffer, 1024, NULL, &status); 2225 if (U_FAILURE(status)) { 2226 errln("Error formatting date 1\n"); 2227 return; 2228 } 2229 //printf("formatted: '%s'\n", mkcstr(ubuffer)); 2230 2231 UnicodeString act1(ubuffer); 2232 if ( act1 != exp1 ) { 2233 errln("Unexpected result from date 1 format\n"); 2234 } 2235 ud0 += 1000.0; // add one second 2236 2237 status = U_ZERO_ERROR; 2238 udat_format(df.getAlias(), ud0, ubuffer, 1024, NULL, &status); 2239 if (U_FAILURE(status)) { 2240 errln("Error formatting date 2\n"); 2241 return; 2242 } 2243 //printf("formatted: '%s'\n", mkcstr(ubuffer)); 2244 UnicodeString act2(ubuffer); 2245 if ( act2 != exp2 ) { 2246 errln("Unexpected result from date 2 format\n"); 2247 } 2248 2249 return; 2250 } 2251 2252 void CalendarTest::Test1624() { 2253 UErrorCode status = U_ZERO_ERROR; 2254 Locale loc("he_IL@calendar=hebrew"); 2255 HebrewCalendar hc(loc,status); 2256 2257 for (int32_t year = 5600; year < 5800; year++ ) { 2258 2259 for (int32_t month = HebrewCalendar::TISHRI; month <= HebrewCalendar::ELUL; month++) { 2260 // skip the adar 1 month if year is not a leap year 2261 if (HebrewCalendar::isLeapYear(year) == FALSE && month == HebrewCalendar::ADAR_1) { 2262 continue; 2263 } 2264 int32_t day = 15; 2265 hc.set(year,month,day); 2266 int32_t dayHC = hc.get(UCAL_DATE,status); 2267 int32_t monthHC = hc.get(UCAL_MONTH,status); 2268 int32_t yearHC = hc.get(UCAL_YEAR,status); 2269 2270 if (failure(status, "HebrewCalendar.get()", TRUE)) continue; 2271 2272 if (dayHC != day) { 2273 errln(" ==> day %d incorrect, should be: %d\n",dayHC,day); 2274 break; 2275 } 2276 if (monthHC != month) { 2277 errln(" ==> month %d incorrect, should be: %d\n",monthHC,month); 2278 break; 2279 } 2280 if (yearHC != year) { 2281 errln(" ==> day %d incorrect, should be: %d\n",yearHC,year); 2282 break; 2283 } 2284 } 2285 } 2286 return; 2287 } 2288 2289 void CalendarTest::TestTimeStamp() { 2290 UErrorCode status = U_ZERO_ERROR; 2291 UDate start = 0.0, time; 2292 Calendar *cal; 2293 2294 // Create a new Gregorian Calendar. 2295 cal = Calendar::createInstance("en_US@calender=gregorian", status); 2296 if (U_FAILURE(status)) { 2297 dataerrln("Error creating Gregorian calendar."); 2298 return; 2299 } 2300 2301 for (int i = 0; i < 20000; i++) { 2302 // Set the Gregorian Calendar to a specific date for testing. 2303 cal->set(2009, UCAL_JULY, 3, 0, 49, 46); 2304 2305 time = cal->getTime(status); 2306 if (U_FAILURE(status)) { 2307 errln("Error calling getTime()"); 2308 break; 2309 } 2310 2311 if (i == 0) { 2312 start = time; 2313 } else { 2314 if (start != time) { 2315 errln("start and time not equal."); 2316 break; 2317 } 2318 } 2319 } 2320 2321 delete cal; 2322 } 2323 2324 void CalendarTest::TestISO8601() { 2325 const char* TEST_LOCALES[] = { 2326 "en_US@calendar=iso8601", 2327 "en_US@calendar=Iso8601", 2328 "th_TH@calendar=iso8601", 2329 "ar_EG@calendar=iso8601", 2330 NULL 2331 }; 2332 2333 int32_t TEST_DATA[][3] = { 2334 {2008, 1, 2008}, 2335 {2009, 1, 2009}, 2336 {2010, 53, 2009}, 2337 {2011, 52, 2010}, 2338 {2012, 52, 2011}, 2339 {2013, 1, 2013}, 2340 {2014, 1, 2014}, 2341 {0, 0, 0}, 2342 }; 2343 2344 for (int i = 0; TEST_LOCALES[i] != NULL; i++) { 2345 UErrorCode status = U_ZERO_ERROR; 2346 Calendar *cal = Calendar::createInstance(TEST_LOCALES[i], status); 2347 if (U_FAILURE(status)) { 2348 errln("Error: Failed to create a calendar for locale: %s", TEST_LOCALES[i]); 2349 continue; 2350 } 2351 if (uprv_strcmp(cal->getType(), "gregorian") != 0) { 2352 errln("Error: Gregorian calendar is not used for locale: %s", TEST_LOCALES[i]); 2353 continue; 2354 } 2355 for (int j = 0; TEST_DATA[j][0] != 0; j++) { 2356 cal->set(TEST_DATA[j][0], UCAL_JANUARY, 1); 2357 int32_t weekNum = cal->get(UCAL_WEEK_OF_YEAR, status); 2358 int32_t weekYear = cal->get(UCAL_YEAR_WOY, status); 2359 if (U_FAILURE(status)) { 2360 errln("Error: Failed to get week of year"); 2361 break; 2362 } 2363 if (weekNum != TEST_DATA[j][1] || weekYear != TEST_DATA[j][2]) { 2364 errln("Error: Incorrect week of year on January 1st, %d for locale %s: Returned [weekNum=%d, weekYear=%d], Expected [weekNum=%d, weekYear=%d]", 2365 TEST_DATA[j][0], TEST_LOCALES[i], weekNum, weekYear, TEST_DATA[j][1], TEST_DATA[j][2]); 2366 } 2367 } 2368 delete cal; 2369 } 2370 2371 } 2372 2373 void 2374 CalendarTest::TestAmbiguousWallTimeAPIs(void) { 2375 UErrorCode status = U_ZERO_ERROR; 2376 Calendar* cal = Calendar::createInstance(status); 2377 if (U_FAILURE(status)) { 2378 errln("Fail: Error creating a calendar instance."); 2379 return; 2380 } 2381 2382 if (cal->getRepeatedWallTimeOption() != UCAL_WALLTIME_LAST) { 2383 errln("Fail: Default repeted time option is not UCAL_WALLTIME_LAST"); 2384 } 2385 if (cal->getSkippedWallTimeOption() != UCAL_WALLTIME_LAST) { 2386 errln("Fail: Default skipped time option is not UCAL_WALLTIME_LAST"); 2387 } 2388 2389 Calendar* cal2 = cal->clone(); 2390 2391 if (*cal != *cal2) { 2392 errln("Fail: Cloned calendar != the original"); 2393 } 2394 if (!cal->equals(*cal2, status)) { 2395 errln("Fail: The time of cloned calendar is not equal to the original"); 2396 } else if (U_FAILURE(status)) { 2397 errln("Fail: Error equals"); 2398 } 2399 status = U_ZERO_ERROR; 2400 2401 cal2->setRepeatedWallTimeOption(UCAL_WALLTIME_FIRST); 2402 cal2->setSkippedWallTimeOption(UCAL_WALLTIME_FIRST); 2403 2404 if (*cal == *cal2) { 2405 errln("Fail: Cloned and modified calendar == the original"); 2406 } 2407 if (!cal->equals(*cal2, status)) { 2408 errln("Fail: The time of cloned calendar is not equal to the original after changing wall time options"); 2409 } else if (U_FAILURE(status)) { 2410 errln("Fail: Error equals after changing wall time options"); 2411 } 2412 status = U_ZERO_ERROR; 2413 2414 if (cal2->getRepeatedWallTimeOption() != UCAL_WALLTIME_FIRST) { 2415 errln("Fail: Repeted time option is not UCAL_WALLTIME_FIRST"); 2416 } 2417 if (cal2->getSkippedWallTimeOption() != UCAL_WALLTIME_FIRST) { 2418 errln("Fail: Skipped time option is not UCAL_WALLTIME_FIRST"); 2419 } 2420 2421 cal2->setRepeatedWallTimeOption(UCAL_WALLTIME_NEXT_VALID); 2422 if (cal2->getRepeatedWallTimeOption() != UCAL_WALLTIME_FIRST) { 2423 errln("Fail: Repeated wall time option was updated other than UCAL_WALLTIME_FIRST"); 2424 } 2425 2426 delete cal; 2427 delete cal2; 2428 } 2429 2430 class CalFields { 2431 public: 2432 CalFields(int32_t year, int32_t month, int32_t day, int32_t hour, int32_t min, int32_t sec, int32_t ms = 0); 2433 CalFields(const Calendar& cal, UErrorCode& status); 2434 void setTo(Calendar& cal) const; 2435 char* toString(char* buf, int32_t len) const; 2436 UBool operator==(const CalFields& rhs) const; 2437 UBool operator!=(const CalFields& rhs) const; 2438 UBool isEquivalentTo(const Calendar& cal, UErrorCode& status) const; 2439 2440 private: 2441 int32_t year; 2442 int32_t month; 2443 int32_t day; 2444 int32_t hour; 2445 int32_t min; 2446 int32_t sec; 2447 int32_t ms; 2448 }; 2449 2450 CalFields::CalFields(int32_t year, int32_t month, int32_t day, int32_t hour, int32_t min, int32_t sec, int32_t ms) 2451 : year(year), month(month), day(day), hour(hour), min(min), sec(sec), ms(ms) { 2452 } 2453 2454 CalFields::CalFields(const Calendar& cal, UErrorCode& status) { 2455 year = cal.get(UCAL_YEAR, status); 2456 month = cal.get(UCAL_MONTH, status) + 1; 2457 day = cal.get(UCAL_DAY_OF_MONTH, status); 2458 hour = cal.get(UCAL_HOUR_OF_DAY, status); 2459 min = cal.get(UCAL_MINUTE, status); 2460 sec = cal.get(UCAL_SECOND, status); 2461 ms = cal.get(UCAL_MILLISECOND, status); 2462 } 2463 2464 void 2465 CalFields::setTo(Calendar& cal) const { 2466 cal.clear(); 2467 cal.set(year, month - 1, day, hour, min, sec); 2468 cal.set(UCAL_MILLISECOND, ms); 2469 } 2470 2471 char* 2472 CalFields::toString(char* buf, int32_t len) const { 2473 char local[32]; 2474 sprintf(local, "%04d-%02d-%02d %02d:%02d:%02d.%03d", year, month, day, hour, min, sec, ms); 2475 uprv_strncpy(buf, local, len - 1); 2476 buf[len - 1] = 0; 2477 return buf; 2478 } 2479 2480 UBool 2481 CalFields::operator==(const CalFields& rhs) const { 2482 return year == rhs.year 2483 && month == rhs.month 2484 && day == rhs.day 2485 && hour == rhs.hour 2486 && min == rhs.min 2487 && sec == rhs.sec 2488 && ms == rhs.ms; 2489 } 2490 2491 UBool 2492 CalFields::operator!=(const CalFields& rhs) const { 2493 return !(*this == rhs); 2494 } 2495 2496 UBool 2497 CalFields::isEquivalentTo(const Calendar& cal, UErrorCode& status) const { 2498 return year == cal.get(UCAL_YEAR, status) 2499 && month == cal.get(UCAL_MONTH, status) + 1 2500 && day == cal.get(UCAL_DAY_OF_MONTH, status) 2501 && hour == cal.get(UCAL_HOUR_OF_DAY, status) 2502 && min == cal.get(UCAL_MINUTE, status) 2503 && sec == cal.get(UCAL_SECOND, status) 2504 && ms == cal.get(UCAL_MILLISECOND, status); 2505 } 2506 2507 typedef struct { 2508 const char* tzid; 2509 const CalFields in; 2510 const CalFields expLastGMT; 2511 const CalFields expFirstGMT; 2512 } RepeatedWallTimeTestData; 2513 2514 static const RepeatedWallTimeTestData RPDATA[] = 2515 { 2516 // Time zone Input wall time WALLTIME_LAST in GMT WALLTIME_FIRST in GMT 2517 {"America/New_York", CalFields(2011,11,6,0,59,59), CalFields(2011,11,6,4,59,59), CalFields(2011,11,6,4,59,59)}, 2518 {"America/New_York", CalFields(2011,11,6,1,0,0), CalFields(2011,11,6,6,0,0), CalFields(2011,11,6,5,0,0)}, 2519 {"America/New_York", CalFields(2011,11,6,1,0,1), CalFields(2011,11,6,6,0,1), CalFields(2011,11,6,5,0,1)}, 2520 {"America/New_York", CalFields(2011,11,6,1,30,0), CalFields(2011,11,6,6,30,0), CalFields(2011,11,6,5,30,0)}, 2521 {"America/New_York", CalFields(2011,11,6,1,59,59), CalFields(2011,11,6,6,59,59), CalFields(2011,11,6,5,59,59)}, 2522 {"America/New_York", CalFields(2011,11,6,2,0,0), CalFields(2011,11,6,7,0,0), CalFields(2011,11,6,7,0,0)}, 2523 {"America/New_York", CalFields(2011,11,6,2,0,1), CalFields(2011,11,6,7,0,1), CalFields(2011,11,6,7,0,1)}, 2524 2525 {"Australia/Lord_Howe", CalFields(2011,4,3,1,29,59), CalFields(2011,4,2,14,29,59), CalFields(2011,4,2,14,29,59)}, 2526 {"Australia/Lord_Howe", CalFields(2011,4,3,1,30,0), CalFields(2011,4,2,15,0,0), CalFields(2011,4,2,14,30,0)}, 2527 {"Australia/Lord_Howe", CalFields(2011,4,3,1,45,0), CalFields(2011,4,2,15,15,0), CalFields(2011,4,2,14,45,0)}, 2528 {"Australia/Lord_Howe", CalFields(2011,4,3,1,59,59), CalFields(2011,4,2,15,29,59), CalFields(2011,4,2,14,59,59)}, 2529 {"Australia/Lord_Howe", CalFields(2011,4,3,2,0,0), CalFields(2011,4,2,15,30,0), CalFields(2011,4,2,15,30,0)}, 2530 {"Australia/Lord_Howe", CalFields(2011,4,3,2,0,1), CalFields(2011,4,2,15,30,1), CalFields(2011,4,2,15,30,1)}, 2531 2532 {NULL, CalFields(0,0,0,0,0,0), CalFields(0,0,0,0,0,0), CalFields(0,0,0,0,0,0)} 2533 }; 2534 2535 void CalendarTest::TestRepeatedWallTime(void) { 2536 UErrorCode status = U_ZERO_ERROR; 2537 GregorianCalendar calGMT((const TimeZone&)*TimeZone::getGMT(), status); 2538 GregorianCalendar calDefault(status); 2539 GregorianCalendar calLast(status); 2540 GregorianCalendar calFirst(status); 2541 2542 if (U_FAILURE(status)) { 2543 errln("Fail: Failed to create a calendar object."); 2544 return; 2545 } 2546 2547 calLast.setRepeatedWallTimeOption(UCAL_WALLTIME_LAST); 2548 calFirst.setRepeatedWallTimeOption(UCAL_WALLTIME_FIRST); 2549 2550 for (int32_t i = 0; RPDATA[i].tzid != NULL; i++) { 2551 char buf[32]; 2552 TimeZone *tz = TimeZone::createTimeZone(RPDATA[i].tzid); 2553 2554 // UCAL_WALLTIME_LAST 2555 status = U_ZERO_ERROR; 2556 calLast.setTimeZone(*tz); 2557 RPDATA[i].in.setTo(calLast); 2558 calGMT.setTime(calLast.getTime(status), status); 2559 CalFields outLastGMT(calGMT, status); 2560 if (U_FAILURE(status)) { 2561 errln(UnicodeString("Fail: Failed to get/set time calLast/calGMT (UCAL_WALLTIME_LAST) - ") 2562 + RPDATA[i].in.toString(buf, sizeof(buf)) + "[" + RPDATA[i].tzid + "]"); 2563 } else { 2564 if (outLastGMT != RPDATA[i].expLastGMT) { 2565 dataerrln(UnicodeString("Fail: UCAL_WALLTIME_LAST ") + RPDATA[i].in.toString(buf, sizeof(buf)) + "[" + RPDATA[i].tzid + "] is parsed as " 2566 + outLastGMT.toString(buf, sizeof(buf)) + "[GMT]. Expected: " + RPDATA[i].expLastGMT.toString(buf, sizeof(buf)) + "[GMT]"); 2567 } 2568 } 2569 2570 // default 2571 status = U_ZERO_ERROR; 2572 calDefault.setTimeZone(*tz); 2573 RPDATA[i].in.setTo(calDefault); 2574 calGMT.setTime(calDefault.getTime(status), status); 2575 CalFields outDefGMT(calGMT, status); 2576 if (U_FAILURE(status)) { 2577 errln(UnicodeString("Fail: Failed to get/set time calLast/calGMT (default) - ") 2578 + RPDATA[i].in.toString(buf, sizeof(buf)) + "[" + RPDATA[i].tzid + "]"); 2579 } else { 2580 if (outDefGMT != RPDATA[i].expLastGMT) { 2581 dataerrln(UnicodeString("Fail: (default) ") + RPDATA[i].in.toString(buf, sizeof(buf)) + "[" + RPDATA[i].tzid + "] is parsed as " 2582 + outDefGMT.toString(buf, sizeof(buf)) + "[GMT]. Expected: " + RPDATA[i].expLastGMT.toString(buf, sizeof(buf)) + "[GMT]"); 2583 } 2584 } 2585 2586 // UCAL_WALLTIME_FIRST 2587 status = U_ZERO_ERROR; 2588 calFirst.setTimeZone(*tz); 2589 RPDATA[i].in.setTo(calFirst); 2590 calGMT.setTime(calFirst.getTime(status), status); 2591 CalFields outFirstGMT(calGMT, status); 2592 if (U_FAILURE(status)) { 2593 errln(UnicodeString("Fail: Failed to get/set time calLast/calGMT (UCAL_WALLTIME_FIRST) - ") 2594 + RPDATA[i].in.toString(buf, sizeof(buf)) + "[" + RPDATA[i].tzid + "]"); 2595 } else { 2596 if (outFirstGMT != RPDATA[i].expFirstGMT) { 2597 dataerrln(UnicodeString("Fail: UCAL_WALLTIME_FIRST ") + RPDATA[i].in.toString(buf, sizeof(buf)) + "[" + RPDATA[i].tzid + "] is parsed as " 2598 + outFirstGMT.toString(buf, sizeof(buf)) + "[GMT]. Expected: " + RPDATA[i].expFirstGMT.toString(buf, sizeof(buf)) + "[GMT]"); 2599 } 2600 } 2601 delete tz; 2602 } 2603 } 2604 2605 typedef struct { 2606 const char* tzid; 2607 const CalFields in; 2608 UBool isValid; 2609 const CalFields expLastGMT; 2610 const CalFields expFirstGMT; 2611 const CalFields expNextAvailGMT; 2612 } SkippedWallTimeTestData; 2613 2614 static SkippedWallTimeTestData SKDATA[] = 2615 { 2616 // Time zone Input wall time valid? WALLTIME_LAST in GMT WALLTIME_FIRST in GMT WALLTIME_NEXT_VALID in GMT 2617 {"America/New_York", CalFields(2011,3,13,1,59,59), TRUE, CalFields(2011,3,13,6,59,59), CalFields(2011,3,13,6,59,59), CalFields(2011,3,13,6,59,59)}, 2618 {"America/New_York", CalFields(2011,3,13,2,0,0), FALSE, CalFields(2011,3,13,7,0,0), CalFields(2011,3,13,6,0,0), CalFields(2011,3,13,7,0,0)}, 2619 {"America/New_York", CalFields(2011,3,13,2,1,0), FALSE, CalFields(2011,3,13,7,1,0), CalFields(2011,3,13,6,1,0), CalFields(2011,3,13,7,0,0)}, 2620 {"America/New_York", CalFields(2011,3,13,2,30,0), FALSE, CalFields(2011,3,13,7,30,0), CalFields(2011,3,13,6,30,0), CalFields(2011,3,13,7,0,0)}, 2621 {"America/New_York", CalFields(2011,3,13,2,59,59), FALSE, CalFields(2011,3,13,7,59,59), CalFields(2011,3,13,6,59,59), CalFields(2011,3,13,7,0,0)}, 2622 {"America/New_York", CalFields(2011,3,13,3,0,0), TRUE, CalFields(2011,3,13,7,0,0), CalFields(2011,3,13,7,0,0), CalFields(2011,3,13,7,0,0)}, 2623 2624 {"Pacific/Apia", CalFields(2011,12,29,23,59,59), TRUE, CalFields(2011,12,30,9,59,59), CalFields(2011,12,30,9,59,59), CalFields(2011,12,30,9,59,59)}, 2625 {"Pacific/Apia", CalFields(2011,12,30,0,0,0), FALSE, CalFields(2011,12,30,10,0,0), CalFields(2011,12,29,10,0,0), CalFields(2011,12,30,10,0,0)}, 2626 {"Pacific/Apia", CalFields(2011,12,30,12,0,0), FALSE, CalFields(2011,12,30,22,0,0), CalFields(2011,12,29,22,0,0), CalFields(2011,12,30,10,0,0)}, 2627 {"Pacific/Apia", CalFields(2011,12,30,23,59,59), FALSE, CalFields(2011,12,31,9,59,59), CalFields(2011,12,30,9,59,59), CalFields(2011,12,30,10,0,0)}, 2628 {"Pacific/Apia", CalFields(2011,12,31,0,0,0), TRUE, CalFields(2011,12,30,10,0,0), CalFields(2011,12,30,10,0,0), CalFields(2011,12,30,10,0,0)}, 2629 2630 {NULL, CalFields(0,0,0,0,0,0), TRUE, CalFields(0,0,0,0,0,0), CalFields(0,0,0,0,0,0), CalFields(0,0,0,0,0,0)} 2631 }; 2632 2633 2634 void CalendarTest::TestSkippedWallTime(void) { 2635 UErrorCode status = U_ZERO_ERROR; 2636 GregorianCalendar calGMT((const TimeZone&)*TimeZone::getGMT(), status); 2637 GregorianCalendar calDefault(status); 2638 GregorianCalendar calLast(status); 2639 GregorianCalendar calFirst(status); 2640 GregorianCalendar calNextAvail(status); 2641 2642 if (U_FAILURE(status)) { 2643 errln("Fail: Failed to create a calendar object."); 2644 return; 2645 } 2646 2647 calLast.setSkippedWallTimeOption(UCAL_WALLTIME_LAST); 2648 calFirst.setSkippedWallTimeOption(UCAL_WALLTIME_FIRST); 2649 calNextAvail.setSkippedWallTimeOption(UCAL_WALLTIME_NEXT_VALID); 2650 2651 for (int32_t i = 0; SKDATA[i].tzid != NULL; i++) { 2652 UDate d; 2653 char buf[32]; 2654 TimeZone *tz = TimeZone::createTimeZone(SKDATA[i].tzid); 2655 2656 for (int32_t j = 0; j < 2; j++) { 2657 UBool bLenient = (j == 0); 2658 2659 // UCAL_WALLTIME_LAST 2660 status = U_ZERO_ERROR; 2661 calLast.setLenient(bLenient); 2662 calLast.setTimeZone(*tz); 2663 SKDATA[i].in.setTo(calLast); 2664 d = calLast.getTime(status); 2665 if (bLenient || SKDATA[i].isValid) { 2666 calGMT.setTime(d, status); 2667 CalFields outLastGMT(calGMT, status); 2668 if (U_FAILURE(status)) { 2669 errln(UnicodeString("Fail: Failed to get/set time calLast/calGMT (UCAL_WALLTIME_LAST) - ") 2670 + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "]"); 2671 } else { 2672 if (outLastGMT != SKDATA[i].expLastGMT) { 2673 dataerrln(UnicodeString("Fail: UCAL_WALLTIME_LAST ") + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "] is parsed as " 2674 + outLastGMT.toString(buf, sizeof(buf)) + "[GMT]. Expected: " + SKDATA[i].expLastGMT.toString(buf, sizeof(buf)) + "[GMT]"); 2675 } 2676 } 2677 } else if (U_SUCCESS(status)) { 2678 // strict, invalid wall time - must report an error 2679 dataerrln(UnicodeString("Fail: An error expected (UCAL_WALLTIME_LAST)") + 2680 + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "]"); 2681 } 2682 2683 // default 2684 status = U_ZERO_ERROR; 2685 calDefault.setLenient(bLenient); 2686 calDefault.setTimeZone(*tz); 2687 SKDATA[i].in.setTo(calDefault); 2688 d = calDefault.getTime(status); 2689 if (bLenient || SKDATA[i].isValid) { 2690 calGMT.setTime(d, status); 2691 CalFields outDefGMT(calGMT, status); 2692 if (U_FAILURE(status)) { 2693 errln(UnicodeString("Fail: Failed to get/set time calDefault/calGMT (default) - ") 2694 + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "]"); 2695 } else { 2696 if (outDefGMT != SKDATA[i].expLastGMT) { 2697 dataerrln(UnicodeString("Fail: (default) ") + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "] is parsed as " 2698 + outDefGMT.toString(buf, sizeof(buf)) + "[GMT]. Expected: " + SKDATA[i].expLastGMT.toString(buf, sizeof(buf)) + "[GMT]"); 2699 } 2700 } 2701 } else if (U_SUCCESS(status)) { 2702 // strict, invalid wall time - must report an error 2703 dataerrln(UnicodeString("Fail: An error expected (default)") + 2704 + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "]"); 2705 } 2706 2707 // UCAL_WALLTIME_FIRST 2708 status = U_ZERO_ERROR; 2709 calFirst.setLenient(bLenient); 2710 calFirst.setTimeZone(*tz); 2711 SKDATA[i].in.setTo(calFirst); 2712 d = calFirst.getTime(status); 2713 if (bLenient || SKDATA[i].isValid) { 2714 calGMT.setTime(d, status); 2715 CalFields outFirstGMT(calGMT, status); 2716 if (U_FAILURE(status)) { 2717 errln(UnicodeString("Fail: Failed to get/set time calFirst/calGMT (UCAL_WALLTIME_FIRST) - ") 2718 + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "]"); 2719 } else { 2720 if (outFirstGMT != SKDATA[i].expFirstGMT) { 2721 dataerrln(UnicodeString("Fail: UCAL_WALLTIME_FIRST ") + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "] is parsed as " 2722 + outFirstGMT.toString(buf, sizeof(buf)) + "[GMT]. Expected: " + SKDATA[i].expFirstGMT.toString(buf, sizeof(buf)) + "[GMT]"); 2723 } 2724 } 2725 } else if (U_SUCCESS(status)) { 2726 // strict, invalid wall time - must report an error 2727 dataerrln(UnicodeString("Fail: An error expected (UCAL_WALLTIME_FIRST)") + 2728 + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "]"); 2729 } 2730 2731 // UCAL_WALLTIME_NEXT_VALID 2732 status = U_ZERO_ERROR; 2733 calNextAvail.setLenient(bLenient); 2734 calNextAvail.setTimeZone(*tz); 2735 SKDATA[i].in.setTo(calNextAvail); 2736 d = calNextAvail.getTime(status); 2737 if (bLenient || SKDATA[i].isValid) { 2738 calGMT.setTime(d, status); 2739 CalFields outNextAvailGMT(calGMT, status); 2740 if (U_FAILURE(status)) { 2741 errln(UnicodeString("Fail: Failed to get/set time calNextAvail/calGMT (UCAL_WALLTIME_NEXT_VALID) - ") 2742 + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "]"); 2743 } else { 2744 if (outNextAvailGMT != SKDATA[i].expNextAvailGMT) { 2745 dataerrln(UnicodeString("Fail: UCAL_WALLTIME_NEXT_VALID ") + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "] is parsed as " 2746 + outNextAvailGMT.toString(buf, sizeof(buf)) + "[GMT]. Expected: " + SKDATA[i].expNextAvailGMT.toString(buf, sizeof(buf)) + "[GMT]"); 2747 } 2748 } 2749 } else if (U_SUCCESS(status)) { 2750 // strict, invalid wall time - must report an error 2751 dataerrln(UnicodeString("Fail: An error expected (UCAL_WALLTIME_NEXT_VALID)") + 2752 + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "]"); 2753 } 2754 } 2755 2756 delete tz; 2757 } 2758 } 2759 2760 void CalendarTest::TestCloneLocale(void) { 2761 UErrorCode status = U_ZERO_ERROR; 2762 LocalPointer<Calendar> cal(Calendar::createInstance(TimeZone::getGMT()->clone(), 2763 Locale::createFromName("en"), status)); 2764 TEST_CHECK_STATUS; 2765 Locale l0 = cal->getLocale(ULOC_VALID_LOCALE, status); 2766 TEST_CHECK_STATUS; 2767 LocalPointer<Calendar> cal2(cal->clone()); 2768 Locale l = cal2->getLocale(ULOC_VALID_LOCALE, status); 2769 if(l0!=l) { 2770 errln("Error: cloned locale %s != original locale %s, status %s\n", l0.getName(), l.getName(), u_errorName(status)); 2771 } 2772 TEST_CHECK_STATUS; 2773 } 2774 2775 void CalendarTest::setAndTestCalendar(Calendar* cal, int32_t initMonth, int32_t initDay, int32_t initYear, UErrorCode& status) { 2776 cal->clear(); 2777 cal->setLenient(FALSE); 2778 cal->set(initYear, initMonth, initDay); 2779 int32_t day = cal->get(UCAL_DAY_OF_MONTH, status); 2780 int32_t month = cal->get(UCAL_MONTH, status); 2781 int32_t year = cal->get(UCAL_YEAR, status); 2782 if(U_FAILURE(status)) 2783 return; 2784 2785 if(initDay != day || initMonth != month || initYear != year) 2786 { 2787 errln(" year init values:\tmonth %i\tday %i\tyear %i", initMonth, initDay, initYear); 2788 errln("values post set():\tmonth %i\tday %i\tyear %i",month, day, year); 2789 } 2790 } 2791 2792 void CalendarTest::setAndTestWholeYear(Calendar* cal, int32_t startYear, UErrorCode& status) { 2793 for(int32_t startMonth = 0; startMonth < 12; startMonth++) { 2794 for(int32_t startDay = 1; startDay < 31; startDay++ ) { 2795 setAndTestCalendar(cal, startMonth, startDay, startYear, status); 2796 if(U_FAILURE(status) && startDay == 30) { 2797 status = U_ZERO_ERROR; 2798 continue; 2799 } 2800 TEST_CHECK_STATUS; 2801 } 2802 } 2803 } 2804 2805 2806 void CalendarTest::TestIslamicUmAlQura() { 2807 2808 UErrorCode status = U_ZERO_ERROR; 2809 Locale islamicLoc("ar_SA@calendar=islamic-umalqura"); 2810 Calendar* tstCal = Calendar::createInstance(islamicLoc, status); 2811 2812 IslamicCalendar* iCal = (IslamicCalendar*)tstCal; 2813 if(strcmp(iCal->getType(), "islamic-umalqura") != 0) { 2814 errln("wrong type of calendar created - %s", iCal->getType()); 2815 } 2816 2817 2818 int32_t firstYear = 1318; 2819 int32_t lastYear = 1368; // just enough to be pretty sure 2820 //int32_t lastYear = 1480; // the whole shootin' match 2821 2822 tstCal->clear(); 2823 tstCal->setLenient(FALSE); 2824 2825 int32_t day=0, month=0, year=0, initDay = 27, initMonth = IslamicCalendar::RAJAB, initYear = 1434; 2826 2827 for( int32_t startYear = firstYear; startYear <= lastYear; startYear++) { 2828 setAndTestWholeYear(tstCal, startYear, status); 2829 status = U_ZERO_ERROR; 2830 } 2831 2832 initMonth = IslamicCalendar::RABI_2; 2833 initDay = 5; 2834 int32_t loopCnt = 25; 2835 tstCal->clear(); 2836 setAndTestCalendar( tstCal, initMonth, initDay, initYear, status); 2837 TEST_CHECK_STATUS; 2838 2839 for(int x=1; x<=loopCnt; x++) { 2840 day = tstCal->get(UCAL_DAY_OF_MONTH,status); 2841 month = tstCal->get(UCAL_MONTH,status); 2842 year = tstCal->get(UCAL_YEAR,status); 2843 TEST_CHECK_STATUS; 2844 tstCal->roll(UCAL_DAY_OF_MONTH, (UBool)TRUE, status); 2845 TEST_CHECK_STATUS; 2846 } 2847 2848 if(day != (initDay + loopCnt - 1) || month != IslamicCalendar::RABI_2 || year != 1434) 2849 errln("invalid values for RABI_2 date after roll of %d", loopCnt); 2850 2851 status = U_ZERO_ERROR; 2852 tstCal->clear(); 2853 initMonth = 2; 2854 initDay = 30; 2855 setAndTestCalendar( tstCal, initMonth, initDay, initYear, status); 2856 if(U_SUCCESS(status)) { 2857 errln("error NOT detected status %i",status); 2858 errln(" init values:\tmonth %i\tday %i\tyear %i", initMonth, initDay, initYear); 2859 int32_t day = tstCal->get(UCAL_DAY_OF_MONTH, status); 2860 int32_t month = tstCal->get(UCAL_MONTH, status); 2861 int32_t year = tstCal->get(UCAL_YEAR, status); 2862 errln("values post set():\tmonth %i\tday %i\tyear %i",month, day, year); 2863 } 2864 2865 status = U_ZERO_ERROR; 2866 tstCal->clear(); 2867 initMonth = 3; 2868 initDay = 30; 2869 setAndTestCalendar( tstCal, initMonth, initDay, initYear, status); 2870 TEST_CHECK_STATUS; 2871 2872 SimpleDateFormat* formatter = new SimpleDateFormat("yyyy-MM-dd", Locale::getUS(), status); 2873 UDate date = formatter->parse("1975-05-06", status); 2874 Calendar* is_cal = Calendar::createInstance(islamicLoc, status); 2875 is_cal->setTime(date, status); 2876 int32_t is_day = is_cal->get(UCAL_DAY_OF_MONTH,status); 2877 int32_t is_month = is_cal->get(UCAL_MONTH,status); 2878 int32_t is_year = is_cal->get(UCAL_YEAR,status); 2879 TEST_CHECK_STATUS; 2880 if(is_day != 29 || is_month != IslamicCalendar::RABI_2 || is_year != 1395) 2881 errln("unexpected conversion date month %i not %i or day %i not 20 or year %i not 1395", is_month, IslamicCalendar::RABI_2, is_day, is_year); 2882 2883 UDate date2 = is_cal->getTime(status); 2884 TEST_CHECK_STATUS; 2885 if(date2 != date) { 2886 errln("before(%f) and after(%f) dates don't match up!",date, date2); 2887 } 2888 2889 delete is_cal; 2890 delete formatter; 2891 delete tstCal; 2892 } 2893 2894 void CalendarTest::TestIslamicTabularDates() { 2895 UErrorCode status = U_ZERO_ERROR; 2896 Locale islamicLoc("ar_SA@calendar=islamic-civil"); 2897 Locale tblaLoc("ar_SA@calendar=islamic-tbla"); 2898 SimpleDateFormat* formatter = new SimpleDateFormat("yyyy-MM-dd", Locale::getUS(), status); 2899 UDate date = formatter->parse("1975-05-06", status); 2900 2901 Calendar* tstCal = Calendar::createInstance(islamicLoc, status); 2902 tstCal->setTime(date, status); 2903 int32_t is_day = tstCal->get(UCAL_DAY_OF_MONTH,status); 2904 int32_t is_month = tstCal->get(UCAL_MONTH,status); 2905 int32_t is_year = tstCal->get(UCAL_YEAR,status); 2906 TEST_CHECK_STATUS; 2907 delete tstCal; 2908 2909 tstCal = Calendar::createInstance(tblaLoc, status); 2910 tstCal->setTime(date, status); 2911 int32_t tbla_day = tstCal->get(UCAL_DAY_OF_MONTH,status); 2912 int32_t tbla_month = tstCal->get(UCAL_MONTH,status); 2913 int32_t tbla_year = tstCal->get(UCAL_YEAR,status); 2914 TEST_CHECK_STATUS; 2915 2916 if(tbla_month != is_month || tbla_year != is_year) 2917 errln("unexpected difference between islamic and tbla month %d : %d and/or year %d : %d",tbla_month,is_month,tbla_year,is_year); 2918 2919 if(tbla_day - is_day != 1) 2920 errln("unexpected day difference between islamic and tbla: %d : %d ",tbla_day,is_day); 2921 delete tstCal; 2922 delete formatter; 2923 } 2924 2925 void CalendarTest::TestHebrewMonthValidation() { 2926 UErrorCode status = U_ZERO_ERROR; 2927 LocalPointer<Calendar> cal(Calendar::createInstance(Locale::createFromName("he_IL@calendar=hebrew"), status)); 2928 if (failure(status, "Calendar::createInstance, locale:he_IL@calendar=hebrew", TRUE)) return; 2929 Calendar *pCal = cal.getAlias(); 2930 2931 UDate d; 2932 pCal->setLenient(FALSE); 2933 2934 // 5776 is a leap year and has month Adar I 2935 pCal->set(5776, HebrewCalendar::ADAR_1, 1); 2936 d = pCal->getTime(status); 2937 if (U_FAILURE(status)) { 2938 errln("Fail: 5776 Adar I 1 is a valid date."); 2939 } 2940 status = U_ZERO_ERROR; 2941 2942 // 5777 is NOT a lear year and does not have month Adar I 2943 pCal->set(5777, HebrewCalendar::ADAR_1, 1); 2944 d = pCal->getTime(status); 2945 (void)d; 2946 if (status == U_ILLEGAL_ARGUMENT_ERROR) { 2947 logln("Info: U_ILLEGAL_ARGUMENT_ERROR, because 5777 Adar I 1 is not a valid date."); 2948 } else { 2949 errln("Fail: U_ILLEGAL_ARGUMENT_ERROR should be set for input date 5777 Adar I 1."); 2950 } 2951 } 2952 2953 void CalendarTest::TestWeekData() { 2954 // Each line contains two locales using the same set of week rule data. 2955 const char* LOCALE_PAIRS[] = { 2956 "en", "en_US", 2957 "de", "de_DE", 2958 "de_DE", "en_DE", 2959 "en_GB", "und_GB", 2960 "ar_EG", "en_EG", 2961 "ar_SA", "fr_SA", 2962 0 2963 }; 2964 2965 UErrorCode status; 2966 2967 for (int32_t i = 0; LOCALE_PAIRS[i] != 0; i += 2) { 2968 status = U_ZERO_ERROR; 2969 LocalPointer<Calendar> cal1(Calendar::createInstance(LOCALE_PAIRS[i], status)); 2970 LocalPointer<Calendar> cal2(Calendar::createInstance(LOCALE_PAIRS[i + 1], status)); 2971 TEST_CHECK_STATUS; 2972 2973 // First day of week 2974 UCalendarDaysOfWeek dow1 = cal1->getFirstDayOfWeek(status); 2975 UCalendarDaysOfWeek dow2 = cal2->getFirstDayOfWeek(status); 2976 TEST_CHECK_STATUS; 2977 TEST_ASSERT(dow1 == dow2); 2978 2979 // Minimum days in first week 2980 uint8_t minDays1 = cal1->getMinimalDaysInFirstWeek(); 2981 uint8_t minDays2 = cal2->getMinimalDaysInFirstWeek(); 2982 TEST_ASSERT(minDays1 == minDays2); 2983 2984 // Weekdays and Weekends 2985 for (int32_t d = UCAL_SUNDAY; d <= UCAL_SATURDAY; d++) { 2986 status = U_ZERO_ERROR; 2987 UCalendarWeekdayType wdt1 = cal1->getDayOfWeekType((UCalendarDaysOfWeek)d, status); 2988 UCalendarWeekdayType wdt2 = cal2->getDayOfWeekType((UCalendarDaysOfWeek)d, status); 2989 TEST_CHECK_STATUS; 2990 TEST_ASSERT(wdt1 == wdt2); 2991 } 2992 } 2993 } 2994 2995 typedef struct { 2996 const char* zone; 2997 const CalFields base; 2998 int32_t deltaDays; 2999 UCalendarWallTimeOption skippedWTOpt; 3000 const CalFields expected; 3001 } TestAddAcrossZoneTransitionData; 3002 3003 static const TestAddAcrossZoneTransitionData AAZTDATA[] = 3004 { 3005 // Time zone Base wall time day(s) Skipped time options 3006 // Expected wall time 3007 3008 // Add 1 day, from the date before DST transition 3009 {"America/Los_Angeles", CalFields(2014,3,8,1,59,59,999), 1, UCAL_WALLTIME_FIRST, 3010 CalFields(2014,3,9,1,59,59,999)}, 3011 3012 {"America/Los_Angeles", CalFields(2014,3,8,1,59,59,999), 1, UCAL_WALLTIME_LAST, 3013 CalFields(2014,3,9,1,59,59,999)}, 3014 3015 {"America/Los_Angeles", CalFields(2014,3,8,1,59,59,999), 1, UCAL_WALLTIME_NEXT_VALID, 3016 CalFields(2014,3,9,1,59,59,999)}, 3017 3018 3019 {"America/Los_Angeles", CalFields(2014,3,8,2,0,0,0), 1, UCAL_WALLTIME_FIRST, 3020 CalFields(2014,3,9,1,0,0,0)}, 3021 3022 {"America/Los_Angeles", CalFields(2014,3,8,2,0,0,0), 1, UCAL_WALLTIME_LAST, 3023 CalFields(2014,3,9,3,0,0,0)}, 3024 3025 {"America/Los_Angeles", CalFields(2014,3,8,2,0,0,0), 1, UCAL_WALLTIME_NEXT_VALID, 3026 CalFields(2014,3,9,3,0,0,0)}, 3027 3028 3029 {"America/Los_Angeles", CalFields(2014,3,8,2,30,0,0), 1, UCAL_WALLTIME_FIRST, 3030 CalFields(2014,3,9,1,30,0,0)}, 3031 3032 {"America/Los_Angeles", CalFields(2014,3,8,2,30,0,0), 1, UCAL_WALLTIME_LAST, 3033 CalFields(2014,3,9,3,30,0,0)}, 3034 3035 {"America/Los_Angeles", CalFields(2014,3,8,2,30,0,0), 1, UCAL_WALLTIME_NEXT_VALID, 3036 CalFields(2014,3,9,3,0,0,0)}, 3037 3038 3039 {"America/Los_Angeles", CalFields(2014,3,8,3,0,0,0), 1, UCAL_WALLTIME_FIRST, 3040 CalFields(2014,3,9,3,0,0,0)}, 3041 3042 {"America/Los_Angeles", CalFields(2014,3,8,3,0,0,0), 1, UCAL_WALLTIME_LAST, 3043 CalFields(2014,3,9,3,0,0,0)}, 3044 3045 {"America/Los_Angeles", CalFields(2014,3,8,3,0,0,0), 1, UCAL_WALLTIME_NEXT_VALID, 3046 CalFields(2014,3,9,3,0,0,0)}, 3047 3048 // Subtract 1 day, from one day after DST transition 3049 {"America/Los_Angeles", CalFields(2014,3,10,1,59,59,999), -1, UCAL_WALLTIME_FIRST, 3050 CalFields(2014,3,9,1,59,59,999)}, 3051 3052 {"America/Los_Angeles", CalFields(2014,3,10,1,59,59,999), -1, UCAL_WALLTIME_LAST, 3053 CalFields(2014,3,9,1,59,59,999)}, 3054 3055 {"America/Los_Angeles", CalFields(2014,3,10,1,59,59,999), -1, UCAL_WALLTIME_NEXT_VALID, 3056 CalFields(2014,3,9,1,59,59,999)}, 3057 3058 3059 {"America/Los_Angeles", CalFields(2014,3,10,2,0,0,0), -1, UCAL_WALLTIME_FIRST, 3060 CalFields(2014,3,9,1,0,0,0)}, 3061 3062 {"America/Los_Angeles", CalFields(2014,3,10,2,0,0,0), -1, UCAL_WALLTIME_LAST, 3063 CalFields(2014,3,9,3,0,0,0)}, 3064 3065 {"America/Los_Angeles", CalFields(2014,3,10,2,0,0,0), -1, UCAL_WALLTIME_NEXT_VALID, 3066 CalFields(2014,3,9,3,0,0,0)}, 3067 3068 3069 {"America/Los_Angeles", CalFields(2014,3,10,2,30,0,0), -1, UCAL_WALLTIME_FIRST, 3070 CalFields(2014,3,9,1,30,0,0)}, 3071 3072 {"America/Los_Angeles", CalFields(2014,3,10,2,30,0,0), -1, UCAL_WALLTIME_LAST, 3073 CalFields(2014,3,9,3,30,0,0)}, 3074 3075 {"America/Los_Angeles", CalFields(2014,3,10,2,30,0,0), -1, UCAL_WALLTIME_NEXT_VALID, 3076 CalFields(2014,3,9,3,0,0,0)}, 3077 3078 3079 {"America/Los_Angeles", CalFields(2014,3,10,3,0,0,0), -1, UCAL_WALLTIME_FIRST, 3080 CalFields(2014,3,9,3,0,0,0)}, 3081 3082 {"America/Los_Angeles", CalFields(2014,3,10,3,0,0,0), -1, UCAL_WALLTIME_LAST, 3083 CalFields(2014,3,9,3,0,0,0)}, 3084 3085 {"America/Los_Angeles", CalFields(2014,3,10,3,0,0,0), -1, UCAL_WALLTIME_NEXT_VALID, 3086 CalFields(2014,3,9,3,0,0,0)}, 3087 3088 3089 // Test case for ticket#10544 3090 {"America/Santiago", CalFields(2013,4,27,0,0,0,0), 134, UCAL_WALLTIME_FIRST, 3091 CalFields(2013,9,7,23,0,0,0)}, 3092 3093 {"America/Santiago", CalFields(2013,4,27,0,0,0,0), 134, UCAL_WALLTIME_LAST, 3094 CalFields(2013,9,8,1,0,0,0)}, 3095 3096 {"America/Santiago", CalFields(2013,4,27,0,0,0,0), 134, UCAL_WALLTIME_NEXT_VALID, 3097 CalFields(2013,9,8,1,0,0,0)}, 3098 3099 3100 {"America/Santiago", CalFields(2013,4,27,0,30,0,0), 134, UCAL_WALLTIME_FIRST, 3101 CalFields(2013,9,7,23,30,0,0)}, 3102 3103 {"America/Santiago", CalFields(2013,4,27,0,30,0,0), 134, UCAL_WALLTIME_LAST, 3104 CalFields(2013,9,8,1,30,0,0)}, 3105 3106 {"America/Santiago", CalFields(2013,4,27,0,30,0,0), 134, UCAL_WALLTIME_NEXT_VALID, 3107 CalFields(2013,9,8,1,0,0,0)}, 3108 3109 3110 // Extreme transition - Pacific/Apia completely skips 2011-12-30 3111 {"Pacific/Apia", CalFields(2011,12,29,0,0,0,0), 1, UCAL_WALLTIME_FIRST, 3112 CalFields(2011,12,31,0,0,0,0)}, 3113 3114 {"Pacific/Apia", CalFields(2011,12,29,0,0,0,0), 1, UCAL_WALLTIME_LAST, 3115 CalFields(2011,12,31,0,0,0,0)}, 3116 3117 {"Pacific/Apia", CalFields(2011,12,29,0,0,0,0), 1, UCAL_WALLTIME_NEXT_VALID, 3118 CalFields(2011,12,31,0,0,0,0)}, 3119 3120 3121 {"Pacific/Apia", CalFields(2011,12,31,12,0,0,0), -1, UCAL_WALLTIME_FIRST, 3122 CalFields(2011,12,29,12,0,0,0)}, 3123 3124 {"Pacific/Apia", CalFields(2011,12,31,12,0,0,0), -1, UCAL_WALLTIME_LAST, 3125 CalFields(2011,12,29,12,0,0,0)}, 3126 3127 {"Pacific/Apia", CalFields(2011,12,31,12,0,0,0), -1, UCAL_WALLTIME_NEXT_VALID, 3128 CalFields(2011,12,29,12,0,0,0)}, 3129 3130 3131 // 30 minutes DST - Australia/Lord_Howe 3132 {"Australia/Lord_Howe", CalFields(2013,10,5,2,15,0,0), 1, UCAL_WALLTIME_FIRST, 3133 CalFields(2013,10,6,1,45,0,0)}, 3134 3135 {"Australia/Lord_Howe", CalFields(2013,10,5,2,15,0,0), 1, UCAL_WALLTIME_LAST, 3136 CalFields(2013,10,6,2,45,0,0)}, 3137 3138 {"Australia/Lord_Howe", CalFields(2013,10,5,2,15,0,0), 1, UCAL_WALLTIME_NEXT_VALID, 3139 CalFields(2013,10,6,2,30,0,0)}, 3140 3141 {NULL, CalFields(0,0,0,0,0,0,0), 0, UCAL_WALLTIME_LAST, CalFields(0,0,0,0,0,0,0)} 3142 }; 3143 3144 void CalendarTest::TestAddAcrossZoneTransition() { 3145 UErrorCode status = U_ZERO_ERROR; 3146 GregorianCalendar cal(status); 3147 TEST_CHECK_STATUS; 3148 3149 for (int32_t i = 0; AAZTDATA[i].zone; i++) { 3150 status = U_ZERO_ERROR; 3151 TimeZone *tz = TimeZone::createTimeZone(AAZTDATA[i].zone); 3152 cal.adoptTimeZone(tz); 3153 cal.setSkippedWallTimeOption(AAZTDATA[i].skippedWTOpt); 3154 AAZTDATA[i].base.setTo(cal); 3155 cal.add(UCAL_DATE, AAZTDATA[i].deltaDays, status); 3156 TEST_CHECK_STATUS; 3157 3158 if (!AAZTDATA[i].expected.isEquivalentTo(cal, status)) { 3159 CalFields res(cal, status); 3160 TEST_CHECK_STATUS; 3161 char buf[32]; 3162 const char *optDisp = AAZTDATA[i].skippedWTOpt == UCAL_WALLTIME_FIRST ? "FIRST" : 3163 AAZTDATA[i].skippedWTOpt == UCAL_WALLTIME_LAST ? "LAST" : "NEXT_VALID"; 3164 dataerrln(UnicodeString("Error: base:") + AAZTDATA[i].base.toString(buf, sizeof(buf)) + ", tz:" + AAZTDATA[i].zone 3165 + ", delta:" + AAZTDATA[i].deltaDays + " day(s), opt:" + optDisp 3166 + ", result:" + res.toString(buf, sizeof(buf)) 3167 + " - expected:" + AAZTDATA[i].expected.toString(buf, sizeof(buf))); 3168 } 3169 } 3170 } 3171 3172 #endif /* #if !UCONFIG_NO_FORMATTING */ 3173 3174 //eof 3175