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