1 /************************************************************************ 2 * COPYRIGHT: 3 * Copyright (c) 1997-2010, 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 "hebrwcal.h" 15 #include "unicode/smpdtfmt.h" 16 #include "unicode/simpletz.h" 17 #include "dbgutil.h" 18 #include "unicode/udat.h" 19 #include "unicode/ustring.h" 20 21 #define mkcstr(U) u_austrcpy(calloc(8, u_strlen(U) + 1), U) 22 23 // ***************************************************************************** 24 // class CalendarTest 25 // ***************************************************************************** 26 27 UnicodeString CalendarTest::calToStr(const Calendar & cal) 28 { 29 UnicodeString out; 30 UErrorCode status = U_ZERO_ERROR; 31 int i; 32 UDate d; 33 for(i = 0;i<UCAL_FIELD_COUNT;i++) { 34 out += (UnicodeString("") + fieldName((UCalendarDateFields)i) + "=" + cal.get((UCalendarDateFields)i, status) + UnicodeString(" ")); 35 } 36 out += "[" + UnicodeString(cal.getType()) + "]"; 37 38 if(cal.inDaylightTime(status)) { 39 out += UnicodeString(" (in DST), zone="); 40 } 41 else { 42 out += UnicodeString(", zone="); 43 } 44 45 UnicodeString str2; 46 out += cal.getTimeZone().getDisplayName(str2); 47 d = cal.getTime(status); 48 out += UnicodeString(" :","") + d; 49 50 return out; 51 } 52 53 void CalendarTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ ) 54 { 55 if (exec) logln("TestSuite TestCalendar"); 56 switch (index) { 57 case 0: 58 name = "TestDOW943"; 59 if (exec) { 60 logln("TestDOW943---"); logln(""); 61 TestDOW943(); 62 } 63 break; 64 case 1: 65 name = "TestClonesUnique908"; 66 if (exec) { 67 logln("TestClonesUnique908---"); logln(""); 68 TestClonesUnique908(); 69 } 70 break; 71 case 2: 72 name = "TestGregorianChange768"; 73 if (exec) { 74 logln("TestGregorianChange768---"); logln(""); 75 TestGregorianChange768(); 76 } 77 break; 78 case 3: 79 name = "TestDisambiguation765"; 80 if (exec) { 81 logln("TestDisambiguation765---"); logln(""); 82 TestDisambiguation765(); 83 } 84 break; 85 case 4: 86 name = "TestGMTvsLocal4064654"; 87 if (exec) { 88 logln("TestGMTvsLocal4064654---"); logln(""); 89 TestGMTvsLocal4064654(); 90 } 91 break; 92 case 5: 93 name = "TestAddSetOrder621"; 94 if (exec) { 95 logln("TestAddSetOrder621---"); logln(""); 96 TestAddSetOrder621(); 97 } 98 break; 99 case 6: 100 name = "TestAdd520"; 101 if (exec) { 102 logln("TestAdd520---"); logln(""); 103 TestAdd520(); 104 } 105 break; 106 case 7: 107 name = "TestFieldSet4781"; 108 if (exec) { 109 logln("TestFieldSet4781---"); logln(""); 110 TestFieldSet4781(); 111 } 112 break; 113 case 8: 114 name = "TestSerialize337"; 115 if (exec) { 116 logln("TestSerialize337---"); logln(""); 117 // TestSerialize337(); 118 } 119 break; 120 case 9: 121 name = "TestSecondsZero121"; 122 if (exec) { 123 logln("TestSecondsZero121---"); logln(""); 124 TestSecondsZero121(); 125 } 126 break; 127 case 10: 128 name = "TestAddSetGet0610"; 129 if (exec) { 130 logln("TestAddSetGet0610---"); logln(""); 131 TestAddSetGet0610(); 132 } 133 break; 134 case 11: 135 name = "TestFields060"; 136 if (exec) { 137 logln("TestFields060---"); logln(""); 138 TestFields060(); 139 } 140 break; 141 case 12: 142 name = "TestEpochStartFields"; 143 if (exec) { 144 logln("TestEpochStartFields---"); logln(""); 145 TestEpochStartFields(); 146 } 147 break; 148 case 13: 149 name = "TestDOWProgression"; 150 if (exec) { 151 logln("TestDOWProgression---"); logln(""); 152 TestDOWProgression(); 153 } 154 break; 155 case 14: 156 name = "TestGenericAPI"; 157 if (exec) { 158 logln("TestGenericAPI---"); logln(""); 159 TestGenericAPI(); 160 } 161 break; 162 case 15: 163 name = "TestAddRollExtensive"; 164 if (exec) { 165 logln("TestAddRollExtensive---"); logln(""); 166 TestAddRollExtensive(); 167 } 168 break; 169 case 16: 170 name = "TestDOW_LOCALandYEAR_WOY"; 171 if (exec) { 172 logln("TestDOW_LOCALandYEAR_WOY---"); logln(""); 173 TestDOW_LOCALandYEAR_WOY(); 174 } 175 break; 176 case 17: 177 name = "TestWOY"; 178 if (exec) { 179 logln("TestWOY---"); logln(""); 180 TestWOY(); 181 } 182 break; 183 case 18: 184 name = "TestRog"; 185 if (exec) { 186 logln("TestRog---"); logln(""); 187 TestRog(); 188 } 189 break; 190 case 19: 191 name = "TestYWOY"; 192 if (exec) { 193 logln("TestYWOY---"); logln(""); 194 TestYWOY(); 195 } 196 break; 197 case 20: 198 name = "TestJD"; 199 if(exec) { 200 logln("TestJD---"); logln(""); 201 TestJD(); 202 } 203 break; 204 case 21: 205 name = "TestDebug"; 206 if(exec) { 207 logln("TestDebug---"); logln(""); 208 TestDebug(); 209 } 210 break; 211 case 22: 212 name = "Test6703"; 213 if(exec) { 214 logln("Test6703---"); logln(""); 215 Test6703(); 216 } 217 break; 218 case 23: 219 name = "Test3785"; 220 if(exec) { 221 logln("Test3785---"); logln(""); 222 Test3785(); 223 } 224 break; 225 case 24: 226 name = "Test1624"; 227 if(exec) { 228 logln("Test1624---"); logln(""); 229 Test1624(); 230 } 231 break; 232 default: name = ""; break; 233 } 234 } 235 236 // --------------------------------------------------------------------------------- 237 238 UnicodeString CalendarTest::fieldName(UCalendarDateFields f) { 239 switch (f) { 240 #define FIELD_NAME_STR(x) case x: return (#x+5) 241 FIELD_NAME_STR( UCAL_ERA ); 242 FIELD_NAME_STR( UCAL_YEAR ); 243 FIELD_NAME_STR( UCAL_MONTH ); 244 FIELD_NAME_STR( UCAL_WEEK_OF_YEAR ); 245 FIELD_NAME_STR( UCAL_WEEK_OF_MONTH ); 246 FIELD_NAME_STR( UCAL_DATE ); 247 FIELD_NAME_STR( UCAL_DAY_OF_YEAR ); 248 FIELD_NAME_STR( UCAL_DAY_OF_WEEK ); 249 FIELD_NAME_STR( UCAL_DAY_OF_WEEK_IN_MONTH ); 250 FIELD_NAME_STR( UCAL_AM_PM ); 251 FIELD_NAME_STR( UCAL_HOUR ); 252 FIELD_NAME_STR( UCAL_HOUR_OF_DAY ); 253 FIELD_NAME_STR( UCAL_MINUTE ); 254 FIELD_NAME_STR( UCAL_SECOND ); 255 FIELD_NAME_STR( UCAL_MILLISECOND ); 256 FIELD_NAME_STR( UCAL_ZONE_OFFSET ); 257 FIELD_NAME_STR( UCAL_DST_OFFSET ); 258 FIELD_NAME_STR( UCAL_YEAR_WOY ); 259 FIELD_NAME_STR( UCAL_DOW_LOCAL ); 260 FIELD_NAME_STR( UCAL_EXTENDED_YEAR ); 261 FIELD_NAME_STR( UCAL_JULIAN_DAY ); 262 FIELD_NAME_STR( UCAL_MILLISECONDS_IN_DAY ); 263 #undef FIELD_NAME_STR 264 default: 265 return UnicodeString("") + ((int32_t)f); 266 } 267 } 268 269 /** 270 * Test various API methods for API completeness. 271 */ 272 void 273 CalendarTest::TestGenericAPI() 274 { 275 UErrorCode status = U_ZERO_ERROR; 276 UDate d; 277 UnicodeString str; 278 UBool eq = FALSE,b4 = FALSE,af = FALSE; 279 280 UDate when = date(90, UCAL_APRIL, 15); 281 282 UnicodeString tzid("TestZone"); 283 int32_t tzoffset = 123400; 284 285 SimpleTimeZone *zone = new SimpleTimeZone(tzoffset, tzid); 286 Calendar *cal = Calendar::createInstance(zone->clone(), status); 287 if (failure(status, "Calendar::createInstance", TRUE)) return; 288 289 if (*zone != cal->getTimeZone()) errln("FAIL: Calendar::getTimeZone failed"); 290 291 Calendar *cal2 = Calendar::createInstance(cal->getTimeZone(), status); 292 if (failure(status, "Calendar::createInstance")) return; 293 cal->setTime(when, status); 294 cal2->setTime(when, status); 295 if (failure(status, "Calendar::setTime")) return; 296 297 if (!(*cal == *cal2)) errln("FAIL: Calendar::operator== failed"); 298 if ((*cal != *cal2)) errln("FAIL: Calendar::operator!= failed"); 299 if (!cal->equals(*cal2, status) || 300 cal->before(*cal2, status) || 301 cal->after(*cal2, status) || 302 U_FAILURE(status)) errln("FAIL: equals/before/after failed"); 303 304 logln(UnicodeString("cal=") +cal->getTime(status) + UnicodeString(calToStr(*cal))); 305 logln(UnicodeString("cal2=") +cal2->getTime(status) + UnicodeString(calToStr(*cal2))); 306 logln("cal2->setTime(when+1000)"); 307 cal2->setTime(when + 1000, status); 308 logln(UnicodeString("cal2=") +cal2->getTime(status) + UnicodeString(calToStr(*cal2))); 309 310 if (failure(status, "Calendar::setTime")) return; 311 if (cal->equals(*cal2, status) || 312 cal2->before(*cal, status) || 313 cal->after(*cal2, status) || 314 U_FAILURE(status)) errln("FAIL: equals/before/after failed after setTime(+1000)"); 315 316 logln("cal->roll(UCAL_SECOND)"); 317 cal->roll(UCAL_SECOND, (UBool) TRUE, status); 318 logln(UnicodeString("cal=") +cal->getTime(status) + UnicodeString(calToStr(*cal))); 319 cal->roll(UCAL_SECOND, (int32_t)0, status); 320 logln(UnicodeString("cal=") +cal->getTime(status) + UnicodeString(calToStr(*cal))); 321 if (failure(status, "Calendar::roll")) return; 322 323 if (!(eq=cal->equals(*cal2, status)) || 324 (b4=cal->before(*cal2, status)) || 325 (af=cal->after(*cal2, status)) || 326 U_FAILURE(status)) { 327 errln("FAIL: equals[%c]/before[%c]/after[%c] failed after roll 1 second [should be T/F/F]", 328 eq?'T':'F', 329 b4?'T':'F', 330 af?'T':'F'); 331 logln(UnicodeString("cal=") +cal->getTime(status) + UnicodeString(calToStr(*cal))); 332 logln(UnicodeString("cal2=") +cal2->getTime(status) + UnicodeString(calToStr(*cal2))); 333 } 334 335 // Roll back to January 336 cal->roll(UCAL_MONTH, (int32_t)(1 + UCAL_DECEMBER - cal->get(UCAL_MONTH, status)), status); 337 if (failure(status, "Calendar::roll")) return; 338 if (cal->equals(*cal2, status) || 339 cal2->before(*cal, status) || 340 cal->after(*cal2, status) || 341 U_FAILURE(status)) errln("FAIL: equals/before/after failed after rollback to January"); 342 343 TimeZone *z = cal->orphanTimeZone(); 344 if (z->getID(str) != tzid || 345 z->getRawOffset() != tzoffset) 346 errln("FAIL: orphanTimeZone failed"); 347 348 int32_t i; 349 for (i=0; i<2; ++i) 350 { 351 UBool lenient = ( i > 0 ); 352 cal->setLenient(lenient); 353 if (lenient != cal->isLenient()) errln("FAIL: setLenient/isLenient failed"); 354 // Later: Check for lenient behavior 355 } 356 357 for (i=UCAL_SUNDAY; i<=UCAL_SATURDAY; ++i) 358 { 359 cal->setFirstDayOfWeek((UCalendarDaysOfWeek)i); 360 if (cal->getFirstDayOfWeek() != i) errln("FAIL: set/getFirstDayOfWeek failed"); 361 UErrorCode aStatus = U_ZERO_ERROR; 362 if (cal->getFirstDayOfWeek(aStatus) != i || U_FAILURE(aStatus)) errln("FAIL: getFirstDayOfWeek(status) failed"); 363 } 364 365 for (i=1; i<=7; ++i) 366 { 367 cal->setMinimalDaysInFirstWeek((uint8_t)i); 368 if (cal->getMinimalDaysInFirstWeek() != i) errln("FAIL: set/getFirstDayOfWeek failed"); 369 } 370 371 for (i=0; i<UCAL_FIELD_COUNT; ++i) 372 { 373 if (cal->getMinimum((UCalendarDateFields)i) > cal->getGreatestMinimum((UCalendarDateFields)i)) 374 errln("FAIL: getMinimum larger than getGreatestMinimum for field " + i); 375 if (cal->getLeastMaximum((UCalendarDateFields)i) > cal->getMaximum((UCalendarDateFields)i)) 376 errln("FAIL: getLeastMaximum larger than getMaximum for field " + i); 377 if (cal->getMinimum((UCalendarDateFields)i) >= cal->getMaximum((UCalendarDateFields)i)) 378 errln("FAIL: getMinimum not less than getMaximum for field " + i); 379 } 380 381 cal->adoptTimeZone(TimeZone::createDefault()); 382 cal->clear(); 383 cal->set(1984, 5, 24); 384 if (cal->getTime(status) != date(84, 5, 24) || U_FAILURE(status)) 385 errln("FAIL: Calendar::set(3 args) failed"); 386 387 cal->clear(); 388 cal->set(1985, 3, 2, 11, 49); 389 if (cal->getTime(status) != date(85, 3, 2, 11, 49) || U_FAILURE(status)) 390 errln("FAIL: Calendar::set(5 args) failed"); 391 392 cal->clear(); 393 cal->set(1995, 9, 12, 1, 39, 55); 394 if (cal->getTime(status) != date(95, 9, 12, 1, 39, 55) || U_FAILURE(status)) 395 errln("FAIL: Calendar::set(6 args) failed"); 396 397 cal->getTime(status); 398 if (failure(status, "Calendar::getTime")) return; 399 for (i=0; i<UCAL_FIELD_COUNT; ++i) 400 { 401 switch(i) { 402 case UCAL_YEAR: case UCAL_MONTH: case UCAL_DATE: 403 case UCAL_HOUR_OF_DAY: case UCAL_MINUTE: case UCAL_SECOND: 404 case UCAL_EXTENDED_YEAR: 405 if (!cal->isSet((UCalendarDateFields)i)) errln("FAIL: Calendar::isSet F, should be T " + fieldName((UCalendarDateFields)i)); 406 break; 407 default: 408 if (cal->isSet((UCalendarDateFields)i)) errln("FAIL: Calendar::isSet = T, should be F " + fieldName((UCalendarDateFields)i)); 409 } 410 cal->clear((UCalendarDateFields)i); 411 if (cal->isSet((UCalendarDateFields)i)) errln("FAIL: Calendar::clear/isSet failed " + fieldName((UCalendarDateFields)i)); 412 } 413 414 if(cal->getActualMinimum(Calendar::SECOND, status) != 0){ 415 errln("Calendar is suppose to return 0 for getActualMinimum"); 416 } 417 418 Calendar *cal3 = Calendar::createInstance(status); 419 cal3->roll(Calendar::SECOND, (int32_t)0, status); 420 if (failure(status, "Calendar::roll(EDateFields, int32_t, UErrorCode)")) return; 421 422 delete cal; 423 delete cal2; 424 delete cal3; 425 426 int32_t count; 427 const Locale* loc = Calendar::getAvailableLocales(count); 428 if (count < 1 || loc == 0) 429 { 430 dataerrln("FAIL: getAvailableLocales failed"); 431 } 432 else 433 { 434 for (i=0; i<count; ++i) 435 { 436 cal = Calendar::createInstance(loc[i], status); 437 if (failure(status, "Calendar::createInstance")) return; 438 delete cal; 439 } 440 } 441 442 cal = Calendar::createInstance(TimeZone::createDefault(), Locale::getEnglish(), status); 443 if (failure(status, "Calendar::createInstance")) return; 444 delete cal; 445 446 cal = Calendar::createInstance(*zone, Locale::getEnglish(), status); 447 if (failure(status, "Calendar::createInstance")) return; 448 delete cal; 449 450 GregorianCalendar *gc = new GregorianCalendar(*zone, status); 451 if (failure(status, "new GregorianCalendar")) return; 452 delete gc; 453 454 gc = new GregorianCalendar(Locale::getEnglish(), status); 455 if (failure(status, "new GregorianCalendar")) return; 456 delete gc; 457 458 gc = new GregorianCalendar(Locale::getEnglish(), status); 459 delete gc; 460 461 gc = new GregorianCalendar(*zone, Locale::getEnglish(), status); 462 if (failure(status, "new GregorianCalendar")) return; 463 delete gc; 464 465 gc = new GregorianCalendar(zone, status); 466 if (failure(status, "new GregorianCalendar")) return; 467 delete gc; 468 469 gc = new GregorianCalendar(1998, 10, 14, 21, 43, status); 470 if (gc->getTime(status) != (d =date(98, 10, 14, 21, 43) )|| U_FAILURE(status)) 471 errln("FAIL: new GregorianCalendar(ymdhm) failed with " + UnicodeString(u_errorName(status)) + ", cal=" + gc->getTime(status) + UnicodeString(calToStr(*gc)) + ", d=" + d); 472 else 473 logln(UnicodeString("GOOD: cal=") +gc->getTime(status) + UnicodeString(calToStr(*gc)) + ", d=" + d); 474 delete gc; 475 476 gc = new GregorianCalendar(1998, 10, 14, 21, 43, 55, status); 477 if (gc->getTime(status) != (d=date(98, 10, 14, 21, 43, 55)) || U_FAILURE(status)) 478 errln("FAIL: new GregorianCalendar(ymdhms) failed with " + UnicodeString(u_errorName(status))); 479 480 GregorianCalendar gc2(Locale::getEnglish(), status); 481 if (failure(status, "new GregorianCalendar")) return; 482 gc2 = *gc; 483 if (gc2 != *gc || !(gc2 == *gc)) errln("FAIL: GregorianCalendar assignment/operator==/operator!= failed"); 484 delete gc; 485 delete z; 486 487 /* Code coverage for Calendar class. */ 488 cal = Calendar::createInstance(status); 489 if (failure(status, "Calendar::createInstance")) { 490 return; 491 }else { 492 ((Calendar *)cal)->roll(UCAL_HOUR, (int32_t)100, status); 493 ((Calendar *)cal)->clear(UCAL_HOUR); 494 #if !UCONFIG_NO_SERVICE 495 URegistryKey key = cal->registerFactory(NULL, status); 496 cal->unregister(key, status); 497 #endif 498 } 499 delete cal; 500 501 status = U_ZERO_ERROR; 502 cal = Calendar::createInstance(Locale("he_IL@calendar=hebrew"), status); 503 if (failure(status, "Calendar::createInstance")) { 504 return; 505 } else { 506 cal->roll(Calendar::MONTH, (int32_t)100, status); 507 } 508 509 StringEnumeration *en = Calendar::getKeywordValuesForLocale(NULL, Locale::getDefault(),FALSE, status); 510 if (en == NULL || U_FAILURE(status)) { 511 dataerrln("FAIL: getKeywordValuesForLocale for Calendar. : %s", u_errorName(status)); 512 } 513 delete en; 514 delete cal; 515 } 516 517 // ------------------------------------- 518 519 /** 520 * This test confirms the correct behavior of add when incrementing 521 * through subsequent days. 522 */ 523 void 524 CalendarTest::TestRog() 525 { 526 UErrorCode status = U_ZERO_ERROR; 527 GregorianCalendar* gc = new GregorianCalendar(status); 528 if (failure(status, "new GregorianCalendar", TRUE)) return; 529 int32_t year = 1997, month = UCAL_APRIL, date = 1; 530 gc->set(year, month, date); 531 gc->set(UCAL_HOUR_OF_DAY, 23); 532 gc->set(UCAL_MINUTE, 0); 533 gc->set(UCAL_SECOND, 0); 534 gc->set(UCAL_MILLISECOND, 0); 535 for (int32_t i = 0; i < 9; i++, gc->add(UCAL_DATE, 1, status)) { 536 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; } 537 if (gc->get(UCAL_YEAR, status) != year || 538 gc->get(UCAL_MONTH, status) != month || 539 gc->get(UCAL_DATE, status) != (date + i)) errln("FAIL: Date wrong"); 540 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; } 541 } 542 delete gc; 543 } 544 545 // ------------------------------------- 546 547 /** 548 * Test the handling of the day of the week, checking for correctness and 549 * for correct minimum and maximum values. 550 */ 551 void 552 CalendarTest::TestDOW943() 553 { 554 dowTest(FALSE); 555 dowTest(TRUE); 556 } 557 558 void CalendarTest::dowTest(UBool lenient) 559 { 560 UErrorCode status = U_ZERO_ERROR; 561 GregorianCalendar* cal = new GregorianCalendar(status); 562 if (failure(status, "new GregorianCalendar", TRUE)) return; 563 logln("cal - Aug 12, 1997\n"); 564 cal->set(1997, UCAL_AUGUST, 12); 565 cal->getTime(status); 566 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; } 567 logln((lenient?UnicodeString("LENIENT0: "):UnicodeString("nonlenient0: ")) + UnicodeString(calToStr(*cal))); 568 cal->setLenient(lenient); 569 logln("cal - Dec 1, 1996\n"); 570 cal->set(1996, UCAL_DECEMBER, 1); 571 logln((lenient?UnicodeString("LENIENT: "):UnicodeString("nonlenient: ")) + UnicodeString(calToStr(*cal))); 572 int32_t dow = cal->get(UCAL_DAY_OF_WEEK, status); 573 if (U_FAILURE(status)) { errln("Calendar::get failed [%s]", u_errorName(status)); return; } 574 int32_t min = cal->getMinimum(UCAL_DAY_OF_WEEK); 575 int32_t max = cal->getMaximum(UCAL_DAY_OF_WEEK); 576 if (dow < min || 577 dow > max) errln(UnicodeString("FAIL: Day of week ") + (int32_t)dow + " out of range"); 578 if (dow != UCAL_SUNDAY) errln("FAIL: Day of week should be SUNDAY[%d] not %d", UCAL_SUNDAY, dow); 579 if (min != UCAL_SUNDAY || 580 max != UCAL_SATURDAY) errln("FAIL: Min/max bad"); 581 delete cal; 582 } 583 584 // ------------------------------------- 585 586 /** 587 * Confirm that cloned Calendar objects do not inadvertently share substructures. 588 */ 589 void 590 CalendarTest::TestClonesUnique908() 591 { 592 UErrorCode status = U_ZERO_ERROR; 593 Calendar *c = Calendar::createInstance(status); 594 if (failure(status, "Calendar::createInstance", TRUE)) return; 595 Calendar *d = (Calendar*) c->clone(); 596 c->set(UCAL_MILLISECOND, 123); 597 d->set(UCAL_MILLISECOND, 456); 598 if (c->get(UCAL_MILLISECOND, status) != 123 || 599 d->get(UCAL_MILLISECOND, status) != 456) { 600 errln("FAIL: Clones share fields"); 601 } 602 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; } 603 delete c; 604 delete d; 605 } 606 607 // ------------------------------------- 608 609 /** 610 * Confirm that the Gregorian cutoff value works as advertised. 611 */ 612 void 613 CalendarTest::TestGregorianChange768() 614 { 615 UBool b; 616 UErrorCode status = U_ZERO_ERROR; 617 UnicodeString str; 618 GregorianCalendar* c = new GregorianCalendar(status); 619 if (failure(status, "new GregorianCalendar", TRUE)) return; 620 logln(UnicodeString("With cutoff ") + dateToString(c->getGregorianChange(), str)); 621 b = c->isLeapYear(1800); 622 logln(UnicodeString(" isLeapYear(1800) = ") + (b ? "true" : "false")); 623 logln(UnicodeString(" (should be FALSE)")); 624 if (b) errln("FAIL"); 625 c->setGregorianChange(date(0, 0, 1), status); 626 if (U_FAILURE(status)) { errln("GregorianCalendar::setGregorianChange failed"); return; } 627 logln(UnicodeString("With cutoff ") + dateToString(c->getGregorianChange(), str)); 628 b = c->isLeapYear(1800); 629 logln(UnicodeString(" isLeapYear(1800) = ") + (b ? "true" : "false")); 630 logln(UnicodeString(" (should be TRUE)")); 631 if (!b) errln("FAIL"); 632 delete c; 633 } 634 635 // ------------------------------------- 636 637 /** 638 * Confirm the functioning of the field disambiguation algorithm. 639 */ 640 void 641 CalendarTest::TestDisambiguation765() 642 { 643 UErrorCode status = U_ZERO_ERROR; 644 Calendar *c = Calendar::createInstance("en_US", status); 645 if (failure(status, "Calendar::createInstance", TRUE)) return; 646 c->setLenient(FALSE); 647 c->clear(); 648 c->set(UCAL_YEAR, 1997); 649 c->set(UCAL_MONTH, UCAL_JUNE); 650 c->set(UCAL_DATE, 3); 651 verify765("1997 third day of June = ", c, 1997, UCAL_JUNE, 3); 652 c->clear(); 653 c->set(UCAL_YEAR, 1997); 654 c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY); 655 c->set(UCAL_MONTH, UCAL_JUNE); 656 c->set(UCAL_DAY_OF_WEEK_IN_MONTH, 1); 657 verify765("1997 first Tuesday in June = ", c, 1997, UCAL_JUNE, 3); 658 c->clear(); 659 c->set(UCAL_YEAR, 1997); 660 c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY); 661 c->set(UCAL_MONTH, UCAL_JUNE); 662 c->set(UCAL_DAY_OF_WEEK_IN_MONTH, - 1); 663 verify765("1997 last Tuesday in June = ", c, 1997, UCAL_JUNE, 24); 664 665 status = U_ZERO_ERROR; 666 c->clear(); 667 c->set(UCAL_YEAR, 1997); 668 c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY); 669 c->set(UCAL_MONTH, UCAL_JUNE); 670 c->set(UCAL_DAY_OF_WEEK_IN_MONTH, 0); 671 c->getTime(status); 672 verify765("1997 zero-th Tuesday in June = ", status); 673 674 c->clear(); 675 c->set(UCAL_YEAR, 1997); 676 c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY); 677 c->set(UCAL_MONTH, UCAL_JUNE); 678 c->set(UCAL_WEEK_OF_MONTH, 1); 679 verify765("1997 Tuesday in week 1 of June = ", c, 1997, UCAL_JUNE, 3); 680 c->clear(); 681 c->set(UCAL_YEAR, 1997); 682 c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY); 683 c->set(UCAL_MONTH, UCAL_JUNE); 684 c->set(UCAL_WEEK_OF_MONTH, 5); 685 verify765("1997 Tuesday in week 5 of June = ", c, 1997, UCAL_JULY, 1); 686 687 status = U_ZERO_ERROR; 688 c->clear(); 689 c->set(UCAL_YEAR, 1997); 690 c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY); 691 c->set(UCAL_MONTH, UCAL_JUNE); 692 c->set(UCAL_WEEK_OF_MONTH, 0); 693 c->setMinimalDaysInFirstWeek(1); 694 c->getTime(status); 695 verify765("1997 Tuesday in week 0 of June = ", status); 696 697 /* Note: The following test used to expect YEAR 1997, WOY 1 to 698 * resolve to a date in Dec 1996; that is, to behave as if 699 * YEAR_WOY were 1997. With the addition of a new explicit 700 * YEAR_WOY field, YEAR_WOY must itself be set if that is what is 701 * desired. Using YEAR in combination with WOY is ambiguous, and 702 * results in the first WOY/DOW day of the year satisfying the 703 * given fields (there may be up to two such days). In this case, 704 * it propertly resolves to Tue Dec 30 1997, which has a WOY value 705 * of 1 (for YEAR_WOY 1998) and a DOW of Tuesday, and falls in the 706 * _calendar_ year 1997, as specified. - aliu */ 707 c->clear(); 708 c->set(UCAL_YEAR_WOY, 1997); // aliu 709 c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY); 710 c->set(UCAL_WEEK_OF_YEAR, 1); 711 verify765("1997 Tuesday in week 1 of yearWOY = ", c, 1996, UCAL_DECEMBER, 31); 712 c->clear(); // - add test for YEAR 713 c->setMinimalDaysInFirstWeek(1); 714 c->set(UCAL_YEAR, 1997); 715 c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY); 716 c->set(UCAL_WEEK_OF_YEAR, 1); 717 verify765("1997 Tuesday in week 1 of year = ", c, 1997, UCAL_DECEMBER, 30); 718 c->clear(); 719 c->set(UCAL_YEAR, 1997); 720 c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY); 721 c->set(UCAL_WEEK_OF_YEAR, 10); 722 verify765("1997 Tuesday in week 10 of year = ", c, 1997, UCAL_MARCH, 4); 723 //try { 724 725 // {sfb} week 0 is no longer a valid week of year 726 /*c->clear(); 727 c->set(Calendar::YEAR, 1997); 728 c->set(Calendar::DAY_OF_WEEK, Calendar::TUESDAY); 729 //c->set(Calendar::WEEK_OF_YEAR, 0); 730 c->set(Calendar::WEEK_OF_YEAR, 1); 731 verify765("1997 Tuesday in week 0 of year = ", c, 1996, Calendar::DECEMBER, 24);*/ 732 733 //} 734 //catch(IllegalArgumentException ex) { 735 // errln("FAIL: Exception seen:"); 736 // ex.printStackTrace(log); 737 //} 738 delete c; 739 } 740 741 // ------------------------------------- 742 743 void 744 CalendarTest::verify765(const UnicodeString& msg, Calendar* c, int32_t year, int32_t month, int32_t day) 745 { 746 UnicodeString str; 747 UErrorCode status = U_ZERO_ERROR; 748 int32_t y = c->get(UCAL_YEAR, status); 749 int32_t m = c->get(UCAL_MONTH, status); 750 int32_t d = c->get(UCAL_DATE, status); 751 if ( y == year && 752 m == month && 753 d == day) { 754 if (U_FAILURE(status)) { errln("FAIL: Calendar::get failed"); return; } 755 logln("PASS: " + msg + dateToString(c->getTime(status), str)); 756 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; } 757 } 758 else { 759 errln("FAIL: " + msg + dateToString(c->getTime(status), str) + "; expected " + (int32_t)year + "/" + (int32_t)(month + 1) + "/" + (int32_t)day + 760 "; got " + (int32_t)y + "/" + (int32_t)(m + 1) + "/" + (int32_t)d + " for Locale: " + c->getLocaleID(ULOC_ACTUAL_LOCALE,status)); 761 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; } 762 } 763 } 764 765 // ------------------------------------- 766 767 void 768 CalendarTest::verify765(const UnicodeString& msg/*, IllegalArgumentException e*/, UErrorCode status) 769 { 770 if (status != U_ILLEGAL_ARGUMENT_ERROR) errln("FAIL: No IllegalArgumentException for " + msg); 771 else logln("PASS: " + msg + "IllegalArgument as expected"); 772 } 773 774 // ------------------------------------- 775 776 /** 777 * Confirm that the offset between local time and GMT behaves as expected. 778 */ 779 void 780 CalendarTest::TestGMTvsLocal4064654() 781 { 782 test4064654(1997, 1, 1, 12, 0, 0); 783 test4064654(1997, 4, 16, 18, 30, 0); 784 } 785 786 // ------------------------------------- 787 788 void 789 CalendarTest::test4064654(int32_t yr, int32_t mo, int32_t dt, int32_t hr, int32_t mn, int32_t sc) 790 { 791 UDate date; 792 UErrorCode status = U_ZERO_ERROR; 793 UnicodeString str; 794 Calendar *gmtcal = Calendar::createInstance(status); 795 if (failure(status, "Calendar::createInstance", TRUE)) return; 796 gmtcal->adoptTimeZone(TimeZone::createTimeZone("Africa/Casablanca")); 797 gmtcal->set(yr, mo - 1, dt, hr, mn, sc); 798 gmtcal->set(UCAL_MILLISECOND, 0); 799 date = gmtcal->getTime(status); 800 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; } 801 logln("date = " + dateToString(date, str)); 802 Calendar *cal = Calendar::createInstance(status); 803 if (U_FAILURE(status)) { errln("Calendar::createInstance failed"); return; } 804 cal->setTime(date, status); 805 if (U_FAILURE(status)) { errln("Calendar::setTime failed"); return; } 806 int32_t offset = cal->getTimeZone().getOffset((uint8_t)cal->get(UCAL_ERA, status), 807 cal->get(UCAL_YEAR, status), 808 cal->get(UCAL_MONTH, status), 809 cal->get(UCAL_DATE, status), 810 (uint8_t)cal->get(UCAL_DAY_OF_WEEK, status), 811 cal->get(UCAL_MILLISECOND, status), status); 812 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; } 813 logln("offset for " + dateToString(date, str) + "= " + (offset / 1000 / 60 / 60.0) + "hr"); 814 int32_t utc = ((cal->get(UCAL_HOUR_OF_DAY, status) * 60 + 815 cal->get(UCAL_MINUTE, status)) * 60 + 816 cal->get(UCAL_SECOND, status)) * 1000 + 817 cal->get(UCAL_MILLISECOND, status) - offset; 818 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; } 819 int32_t expected = ((hr * 60 + mn) * 60 + sc) * 1000; 820 if (utc != expected) errln(UnicodeString("FAIL: Discrepancy of ") + (utc - expected) + 821 " millis = " + ((utc - expected) / 1000 / 60 / 60.0) + " hr"); 822 delete gmtcal; 823 delete cal; 824 } 825 826 // ------------------------------------- 827 828 /** 829 * The operations of adding and setting should not exhibit pathological 830 * dependence on the order of operations. This test checks for this. 831 */ 832 void 833 CalendarTest::TestAddSetOrder621() 834 { 835 UDate d = date(97, 4, 14, 13, 23, 45); 836 UErrorCode status = U_ZERO_ERROR; 837 Calendar *cal = Calendar::createInstance(status); 838 if (failure(status, "Calendar::createInstance", TRUE)) return; 839 840 cal->setTime(d, status); 841 if (U_FAILURE(status)) { 842 errln("Calendar::setTime failed"); 843 delete cal; 844 return; 845 } 846 cal->add(UCAL_DATE, - 5, status); 847 if (U_FAILURE(status)) { 848 errln("Calendar::add failed"); 849 delete cal; 850 return; 851 } 852 cal->set(UCAL_HOUR_OF_DAY, 0); 853 cal->set(UCAL_MINUTE, 0); 854 cal->set(UCAL_SECOND, 0); 855 UnicodeString s; 856 dateToString(cal->getTime(status), s); 857 if (U_FAILURE(status)) { 858 errln("Calendar::getTime failed"); 859 delete cal; 860 return; 861 } 862 delete cal; 863 864 cal = Calendar::createInstance(status); 865 if (U_FAILURE(status)) { 866 errln("Calendar::createInstance failed"); 867 delete cal; 868 return; 869 } 870 cal->setTime(d, status); 871 if (U_FAILURE(status)) { 872 errln("Calendar::setTime failed"); 873 delete cal; 874 return; 875 } 876 cal->set(UCAL_HOUR_OF_DAY, 0); 877 cal->set(UCAL_MINUTE, 0); 878 cal->set(UCAL_SECOND, 0); 879 cal->add(UCAL_DATE, - 5, status); 880 if (U_FAILURE(status)) { 881 errln("Calendar::add failed"); 882 delete cal; 883 return; 884 } 885 UnicodeString s2; 886 dateToString(cal->getTime(status), s2); 887 if (U_FAILURE(status)) { 888 errln("Calendar::getTime failed"); 889 delete cal; 890 return; 891 } 892 if (s == s2) 893 logln("Pass: " + s + " == " + s2); 894 else 895 errln("FAIL: " + s + " != " + s2); 896 delete cal; 897 } 898 899 // ------------------------------------- 900 901 /** 902 * Confirm that adding to various fields works. 903 */ 904 void 905 CalendarTest::TestAdd520() 906 { 907 int32_t y = 1997, m = UCAL_FEBRUARY, d = 1; 908 UErrorCode status = U_ZERO_ERROR; 909 GregorianCalendar *temp = new GregorianCalendar(y, m, d, status); 910 if (failure(status, "new GregorianCalendar", TRUE)) return; 911 check520(temp, y, m, d); 912 temp->add(UCAL_YEAR, 1, status); 913 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; } 914 y++; 915 check520(temp, y, m, d); 916 temp->add(UCAL_MONTH, 1, status); 917 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; } 918 m++; 919 check520(temp, y, m, d); 920 temp->add(UCAL_DATE, 1, status); 921 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; } 922 d++; 923 check520(temp, y, m, d); 924 temp->add(UCAL_DATE, 2, status); 925 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; } 926 d += 2; 927 check520(temp, y, m, d); 928 temp->add(UCAL_DATE, 28, status); 929 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; } 930 d = 1;++m; 931 check520(temp, y, m, d); 932 delete temp; 933 } 934 935 // ------------------------------------- 936 937 /** 938 * Execute adding and rolling in GregorianCalendar extensively, 939 */ 940 void 941 CalendarTest::TestAddRollExtensive() 942 { 943 int32_t maxlimit = 40; 944 int32_t y = 1997, m = UCAL_FEBRUARY, d = 1, hr = 1, min = 1, sec = 0, ms = 0; 945 UErrorCode status = U_ZERO_ERROR; 946 GregorianCalendar *temp = new GregorianCalendar(y, m, d, status); 947 if (failure(status, "new GregorianCalendar", TRUE)) return; 948 949 temp->set(UCAL_HOUR, hr); 950 temp->set(UCAL_MINUTE, min); 951 temp->set(UCAL_SECOND, sec); 952 temp->set(UCAL_MILLISECOND, ms); 953 temp->setMinimalDaysInFirstWeek(1); 954 955 UCalendarDateFields e; 956 957 logln("Testing GregorianCalendar add..."); 958 e = UCAL_YEAR; 959 while (e < UCAL_FIELD_COUNT) { 960 int32_t i; 961 int32_t limit = maxlimit; 962 status = U_ZERO_ERROR; 963 for (i = 0; i < limit; i++) { 964 temp->add(e, 1, status); 965 if (U_FAILURE(status)) { limit = i; status = U_ZERO_ERROR; } 966 } 967 for (i = 0; i < limit; i++) { 968 temp->add(e, -1, status); 969 if (U_FAILURE(status)) { errln("GregorianCalendar::add -1 failed"); return; } 970 } 971 check520(temp, y, m, d, hr, min, sec, ms, e); 972 973 e = (UCalendarDateFields) ((int32_t) e + 1); 974 } 975 976 logln("Testing GregorianCalendar roll..."); 977 e = UCAL_YEAR; 978 while (e < UCAL_FIELD_COUNT) { 979 int32_t i; 980 int32_t limit = maxlimit; 981 status = U_ZERO_ERROR; 982 for (i = 0; i < limit; i++) { 983 logln(calToStr(*temp) + UnicodeString(" " ) + fieldName(e) + UnicodeString("++") ); 984 temp->roll(e, 1, status); 985 if (U_FAILURE(status)) { 986 logln("caltest.cpp:%d e=%d, i=%d - roll(+) err %s\n", __LINE__, (int) e, (int) i, u_errorName(status)); 987 logln(calToStr(*temp)); 988 limit = i; status = U_ZERO_ERROR; 989 } 990 } 991 for (i = 0; i < limit; i++) { 992 logln("caltest.cpp:%d e=%d, i=%d\n", __LINE__, (int) e, (int) i); 993 logln(calToStr(*temp) + UnicodeString(" " ) + fieldName(e) + UnicodeString("--") ); 994 temp->roll(e, -1, status); 995 if (U_FAILURE(status)) { errln(UnicodeString("GregorianCalendar::roll ") + CalendarTest::fieldName(e) + " count=" + UnicodeString('@'+i) + " by -1 failed with " + u_errorName(status) ); return; } 996 } 997 check520(temp, y, m, d, hr, min, sec, ms, e); 998 999 e = (UCalendarDateFields) ((int32_t) e + 1); 1000 } 1001 1002 delete temp; 1003 } 1004 1005 // ------------------------------------- 1006 void 1007 CalendarTest::check520(Calendar* c, 1008 int32_t y, int32_t m, int32_t d, 1009 int32_t hr, int32_t min, int32_t sec, 1010 int32_t ms, UCalendarDateFields field) 1011 1012 { 1013 UErrorCode status = U_ZERO_ERROR; 1014 if (c->get(UCAL_YEAR, status) != y || 1015 c->get(UCAL_MONTH, status) != m || 1016 c->get(UCAL_DATE, status) != d || 1017 c->get(UCAL_HOUR, status) != hr || 1018 c->get(UCAL_MINUTE, status) != min || 1019 c->get(UCAL_SECOND, status) != sec || 1020 c->get(UCAL_MILLISECOND, status) != ms) { 1021 errln(UnicodeString("U_FAILURE for field ") + (int32_t)field + 1022 ": Expected y/m/d h:m:s:ms of " + 1023 y + "/" + (m + 1) + "/" + d + " " + 1024 hr + ":" + min + ":" + sec + ":" + ms + 1025 "; got " + c->get(UCAL_YEAR, status) + 1026 "/" + (c->get(UCAL_MONTH, status) + 1) + 1027 "/" + c->get(UCAL_DATE, status) + 1028 " " + c->get(UCAL_HOUR, status) + ":" + 1029 c->get(UCAL_MINUTE, status) + ":" + 1030 c->get(UCAL_SECOND, status) + ":" + 1031 c->get(UCAL_MILLISECOND, status) 1032 ); 1033 1034 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; } 1035 } 1036 else 1037 logln(UnicodeString("Confirmed: ") + y + "/" + 1038 (m + 1) + "/" + d + " " + 1039 hr + ":" + min + ":" + sec + ":" + ms); 1040 } 1041 1042 // ------------------------------------- 1043 void 1044 CalendarTest::check520(Calendar* c, 1045 int32_t y, int32_t m, int32_t d) 1046 1047 { 1048 UErrorCode status = U_ZERO_ERROR; 1049 if (c->get(UCAL_YEAR, status) != y || 1050 c->get(UCAL_MONTH, status) != m || 1051 c->get(UCAL_DATE, status) != d) { 1052 errln(UnicodeString("FAILURE: Expected y/m/d of ") + 1053 y + "/" + (m + 1) + "/" + d + " " + 1054 "; got " + c->get(UCAL_YEAR, status) + 1055 "/" + (c->get(UCAL_MONTH, status) + 1) + 1056 "/" + c->get(UCAL_DATE, status) 1057 ); 1058 1059 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; } 1060 } 1061 else 1062 logln(UnicodeString("Confirmed: ") + y + "/" + 1063 (m + 1) + "/" + d); 1064 } 1065 1066 // ------------------------------------- 1067 1068 /** 1069 * Test that setting of fields works. In particular, make sure that all instances 1070 * of GregorianCalendar don't share a static instance of the fields array. 1071 */ 1072 void 1073 CalendarTest::TestFieldSet4781() 1074 { 1075 // try { 1076 UErrorCode status = U_ZERO_ERROR; 1077 GregorianCalendar *g = new GregorianCalendar(status); 1078 if (failure(status, "new GregorianCalendar", TRUE)) return; 1079 GregorianCalendar *g2 = new GregorianCalendar(status); 1080 if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; } 1081 g2->set(UCAL_HOUR, 12, status); 1082 g2->set(UCAL_MINUTE, 0, status); 1083 g2->set(UCAL_SECOND, 0, status); 1084 if (U_FAILURE(status)) { errln("Calendar::set failed"); return; } 1085 if (*g == *g2) logln("Same"); 1086 else logln("Different"); 1087 //} 1088 //catch(IllegalArgumentException e) { 1089 //errln("Unexpected exception seen: " + e); 1090 //} 1091 delete g; 1092 delete g2; 1093 } 1094 1095 // ------------------------------------- 1096 1097 /* We don't support serialization on C++ 1098 void 1099 CalendarTest::TestSerialize337() 1100 { 1101 Calendar cal = Calendar::getInstance(); 1102 UBool ok = FALSE; 1103 try { 1104 FileOutputStream f = new FileOutputStream(FILENAME); 1105 ObjectOutput s = new ObjectOutputStream(f); 1106 s.writeObject(PREFIX); 1107 s.writeObject(cal); 1108 s.writeObject(POSTFIX); 1109 f.close(); 1110 FileInputStream in = new FileInputStream(FILENAME); 1111 ObjectInputStream t = new ObjectInputStream(in); 1112 UnicodeString& pre = (UnicodeString&) t.readObject(); 1113 Calendar c = (Calendar) t.readObject(); 1114 UnicodeString& post = (UnicodeString&) t.readObject(); 1115 in.close(); 1116 ok = pre.equals(PREFIX) && 1117 post.equals(POSTFIX) && 1118 cal->equals(c); 1119 File fl = new File(FILENAME); 1120 fl.delete(); 1121 } 1122 catch(IOException e) { 1123 errln("FAIL: Exception received:"); 1124 e.printStackTrace(log); 1125 } 1126 catch(ClassNotFoundException e) { 1127 errln("FAIL: Exception received:"); 1128 e.printStackTrace(log); 1129 } 1130 if (!ok) errln("Serialization of Calendar object failed."); 1131 } 1132 1133 UnicodeString& CalendarTest::PREFIX = "abc"; 1134 1135 UnicodeString& CalendarTest::POSTFIX = "def"; 1136 1137 UnicodeString& CalendarTest::FILENAME = "tmp337.bin"; 1138 */ 1139 1140 // ------------------------------------- 1141 1142 /** 1143 * Verify that the seconds of a Calendar can be zeroed out through the 1144 * expected sequence of operations. 1145 */ 1146 void 1147 CalendarTest::TestSecondsZero121() 1148 { 1149 UErrorCode status = U_ZERO_ERROR; 1150 Calendar *cal = new GregorianCalendar(status); 1151 if (failure(status, "new GregorianCalendar", TRUE)) return; 1152 cal->setTime(Calendar::getNow(), status); 1153 if (U_FAILURE(status)) { errln("Calendar::setTime failed"); return; } 1154 cal->set(UCAL_SECOND, 0); 1155 if (U_FAILURE(status)) { errln("Calendar::set failed"); return; } 1156 UDate d = cal->getTime(status); 1157 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; } 1158 UnicodeString s; 1159 dateToString(d, s); 1160 if (s.indexOf("DATE_FORMAT_FAILURE") >= 0) { 1161 dataerrln("Got: \"DATE_FORMAT_FAILURE\"."); 1162 } else if (s.indexOf(":00 ") < 0) { 1163 errln("Expected to see :00 in " + s); 1164 } 1165 delete cal; 1166 } 1167 1168 // ------------------------------------- 1169 1170 /** 1171 * Verify that a specific sequence of adding and setting works as expected; 1172 * it should not vary depending on when and whether the get method is 1173 * called. 1174 */ 1175 void 1176 CalendarTest::TestAddSetGet0610() 1177 { 1178 UnicodeString EXPECTED_0610("1993/0/5", ""); 1179 UErrorCode status = U_ZERO_ERROR; 1180 { 1181 Calendar *calendar = new GregorianCalendar(status); 1182 if (failure(status, "new GregorianCalendar", TRUE)) return; 1183 calendar->set(1993, UCAL_JANUARY, 4); 1184 logln("1A) " + value(calendar)); 1185 calendar->add(UCAL_DATE, 1, status); 1186 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; } 1187 UnicodeString v = value(calendar); 1188 logln("1B) " + v); 1189 logln("--) 1993/0/5"); 1190 if (!(v == EXPECTED_0610)) errln("Expected " + EXPECTED_0610 + "; saw " + v); 1191 delete calendar; 1192 } 1193 { 1194 Calendar *calendar = new GregorianCalendar(1993, UCAL_JANUARY, 4, status); 1195 if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; } 1196 logln("2A) " + value(calendar)); 1197 calendar->add(UCAL_DATE, 1, status); 1198 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; } 1199 UnicodeString v = value(calendar); 1200 logln("2B) " + v); 1201 logln("--) 1993/0/5"); 1202 if (!(v == EXPECTED_0610)) errln("Expected " + EXPECTED_0610 + "; saw " + v); 1203 delete calendar; 1204 } 1205 { 1206 Calendar *calendar = new GregorianCalendar(1993, UCAL_JANUARY, 4, status); 1207 if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; } 1208 logln("3A) " + value(calendar)); 1209 calendar->getTime(status); 1210 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; } 1211 calendar->add(UCAL_DATE, 1, status); 1212 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; } 1213 UnicodeString v = value(calendar); 1214 logln("3B) " + v); 1215 logln("--) 1993/0/5"); 1216 if (!(v == EXPECTED_0610)) errln("Expected " + EXPECTED_0610 + "; saw " + v); 1217 delete calendar; 1218 } 1219 } 1220 1221 // ------------------------------------- 1222 1223 UnicodeString 1224 CalendarTest::value(Calendar* calendar) 1225 { 1226 UErrorCode status = U_ZERO_ERROR; 1227 return UnicodeString("") + (int32_t)calendar->get(UCAL_YEAR, status) + 1228 "/" + (int32_t)calendar->get(UCAL_MONTH, status) + 1229 "/" + (int32_t)calendar->get(UCAL_DATE, status) + 1230 (U_FAILURE(status) ? " FAIL: Calendar::get failed" : ""); 1231 } 1232 1233 1234 // ------------------------------------- 1235 1236 /** 1237 * Verify that various fields on a known date are set correctly. 1238 */ 1239 void 1240 CalendarTest::TestFields060() 1241 { 1242 UErrorCode status = U_ZERO_ERROR; 1243 int32_t year = 1997; 1244 int32_t month = UCAL_OCTOBER; 1245 int32_t dDate = 22; 1246 GregorianCalendar *calendar = 0; 1247 calendar = new GregorianCalendar(year, month, dDate, status); 1248 if (failure(status, "new GregorianCalendar", TRUE)) return; 1249 for (int32_t i = 0; i < EXPECTED_FIELDS_length;) { 1250 UCalendarDateFields field = (UCalendarDateFields)EXPECTED_FIELDS[i++]; 1251 int32_t expected = EXPECTED_FIELDS[i++]; 1252 if (calendar->get(field, status) != expected) { 1253 errln(UnicodeString("Expected field ") + (int32_t)field + " to have value " + (int32_t)expected + 1254 "; received " + (int32_t)calendar->get(field, status) + " instead"); 1255 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; } 1256 } 1257 } 1258 delete calendar; 1259 } 1260 1261 int32_t CalendarTest::EXPECTED_FIELDS[] = { 1262 UCAL_YEAR, 1997, 1263 UCAL_MONTH, UCAL_OCTOBER, 1264 UCAL_DATE, 22, 1265 UCAL_DAY_OF_WEEK, UCAL_WEDNESDAY, 1266 UCAL_DAY_OF_WEEK_IN_MONTH, 4, 1267 UCAL_DAY_OF_YEAR, 295 1268 }; 1269 1270 const int32_t CalendarTest::EXPECTED_FIELDS_length = (int32_t)(sizeof(CalendarTest::EXPECTED_FIELDS) / 1271 sizeof(CalendarTest::EXPECTED_FIELDS[0])); 1272 1273 // ------------------------------------- 1274 1275 /** 1276 * Verify that various fields on a known date are set correctly. In this 1277 * case, the start of the epoch (January 1 1970). 1278 */ 1279 void 1280 CalendarTest::TestEpochStartFields() 1281 { 1282 UErrorCode status = U_ZERO_ERROR; 1283 TimeZone *z = TimeZone::createDefault(); 1284 Calendar *c = Calendar::createInstance(status); 1285 if (failure(status, "Calendar::createInstance", TRUE)) return; 1286 UDate d = - z->getRawOffset(); 1287 GregorianCalendar *gc = new GregorianCalendar(status); 1288 if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; } 1289 gc->setTimeZone(*z); 1290 gc->setTime(d, status); 1291 if (U_FAILURE(status)) { errln("Calendar::setTime failed"); return; } 1292 UBool idt = gc->inDaylightTime(status); 1293 if (U_FAILURE(status)) { errln("GregorianCalendar::inDaylightTime failed"); return; } 1294 if (idt) { 1295 UnicodeString str; 1296 logln("Warning: Skipping test because " + dateToString(d, str) + " is in DST."); 1297 } 1298 else { 1299 c->setTime(d, status); 1300 if (U_FAILURE(status)) { errln("Calendar::setTime failed"); return; } 1301 for (int32_t i = 0; i < UCAL_ZONE_OFFSET;++i) { 1302 if (c->get((UCalendarDateFields)i, status) != EPOCH_FIELDS[i]) 1303 errln(UnicodeString("Expected field ") + i + " to have value " + EPOCH_FIELDS[i] + 1304 "; saw " + c->get((UCalendarDateFields)i, status) + " instead"); 1305 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; } 1306 } 1307 if (c->get(UCAL_ZONE_OFFSET, status) != z->getRawOffset()) 1308 { 1309 errln(UnicodeString("Expected field ZONE_OFFSET to have value ") + z->getRawOffset() + 1310 "; saw " + c->get(UCAL_ZONE_OFFSET, status) + " instead"); 1311 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; } 1312 } 1313 if (c->get(UCAL_DST_OFFSET, status) != 0) 1314 { 1315 errln(UnicodeString("Expected field DST_OFFSET to have value 0") + 1316 "; saw " + c->get(UCAL_DST_OFFSET, status) + " instead"); 1317 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; } 1318 } 1319 } 1320 delete c; 1321 delete z; 1322 delete gc; 1323 } 1324 1325 int32_t CalendarTest::EPOCH_FIELDS[] = { 1326 1, 1970, 0, 53, 0, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, - 28800000, 0 1327 }; 1328 1329 // ------------------------------------- 1330 1331 /** 1332 * Test that the days of the week progress properly when add is called repeatedly 1333 * for increments of 24 days. 1334 */ 1335 void 1336 CalendarTest::TestDOWProgression() 1337 { 1338 UErrorCode status = U_ZERO_ERROR; 1339 Calendar *cal = new GregorianCalendar(1972, UCAL_OCTOBER, 26, status); 1340 if (failure(status, "new GregorianCalendar", TRUE)) return; 1341 marchByDelta(cal, 24); 1342 delete cal; 1343 } 1344 1345 // ------------------------------------- 1346 1347 void 1348 CalendarTest::TestDOW_LOCALandYEAR_WOY() 1349 { 1350 /* Note: I've commented out the loop_addroll tests for YEAR and 1351 * YEAR_WOY below because these two fields should NOT behave 1352 * identically when adding. YEAR should keep the month/dom 1353 * invariant. YEAR_WOY should keep the woy/dow invariant. I've 1354 * added a new test that checks for this in place of the old call 1355 * to loop_addroll. - aliu */ 1356 UErrorCode status = U_ZERO_ERROR; 1357 int32_t times = 20; 1358 Calendar *cal=Calendar::createInstance(Locale::getGermany(), status); 1359 if (failure(status, "Calendar::createInstance", TRUE)) return; 1360 SimpleDateFormat *sdf=new SimpleDateFormat(UnicodeString("YYYY'-W'ww-ee"), Locale::getGermany(), status); 1361 if (U_FAILURE(status)) { errcheckln(status, "Couldn't create SimpleDateFormat - %s", u_errorName(status)); return; } 1362 1363 // ICU no longer use localized date-time pattern characters by default. 1364 // So we set pattern chars using 'J' instead of 'Y'. 1365 DateFormatSymbols *dfs = new DateFormatSymbols(Locale::getGermany(), status); 1366 dfs->setLocalPatternChars(UnicodeString("GyMdkHmsSEDFwWahKzJeugAZvcLQq")); 1367 sdf->adoptDateFormatSymbols(dfs); 1368 sdf->applyLocalizedPattern(UnicodeString("JJJJ'-W'ww-ee"), status); 1369 if (U_FAILURE(status)) { errln("Couldn't apply localized pattern"); return; } 1370 1371 cal->clear(); 1372 cal->set(1997, UCAL_DECEMBER, 25); 1373 doYEAR_WOYLoop(cal, sdf, times, status); 1374 //loop_addroll(cal, /*sdf,*/ times, UCAL_YEAR_WOY, UCAL_YEAR, status); 1375 yearAddTest(*cal, status); // aliu 1376 loop_addroll(cal, /*sdf,*/ times, UCAL_DOW_LOCAL, UCAL_DAY_OF_WEEK, status); 1377 if (U_FAILURE(status)) { errln("Error in parse/calculate test for 1997"); return; } 1378 1379 cal->clear(); 1380 cal->set(1998, UCAL_DECEMBER, 25); 1381 doYEAR_WOYLoop(cal, sdf, times, status); 1382 //loop_addroll(cal, /*sdf,*/ times, UCAL_YEAR_WOY, UCAL_YEAR, status); 1383 yearAddTest(*cal, status); // aliu 1384 loop_addroll(cal, /*sdf,*/ times, UCAL_DOW_LOCAL, UCAL_DAY_OF_WEEK, status); 1385 if (U_FAILURE(status)) { errln("Error in parse/calculate test for 1998"); return; } 1386 1387 cal->clear(); 1388 cal->set(1582, UCAL_OCTOBER, 1); 1389 doYEAR_WOYLoop(cal, sdf, times, status); 1390 //loop_addroll(cal, /*sdf,*/ times, Calendar::YEAR_WOY, Calendar::YEAR, status); 1391 yearAddTest(*cal, status); // aliu 1392 loop_addroll(cal, /*sdf,*/ times, UCAL_DOW_LOCAL, UCAL_DAY_OF_WEEK, status); 1393 if (U_FAILURE(status)) { errln("Error in parse/calculate test for 1582"); return; } 1394 delete sdf; 1395 delete cal; 1396 1397 return; 1398 } 1399 1400 /** 1401 * Confirm that adding a YEAR and adding a YEAR_WOY work properly for 1402 * the given Calendar at its current setting. 1403 */ 1404 void CalendarTest::yearAddTest(Calendar& cal, UErrorCode& status) { 1405 /** 1406 * When adding the YEAR, the month and day should remain constant. 1407 * When adding the YEAR_WOY, the WOY and DOW should remain constant. - aliu 1408 * Examples: 1409 * Wed Jan 14 1998 / 1998-W03-03 Add(YEAR_WOY, 1) -> Wed Jan 20 1999 / 1999-W03-03 1410 * Add(YEAR, 1) -> Thu Jan 14 1999 / 1999-W02-04 1411 * Thu Jan 14 1999 / 1999-W02-04 Add(YEAR_WOY, 1) -> Thu Jan 13 2000 / 2000-W02-04 1412 * Add(YEAR, 1) -> Fri Jan 14 2000 / 2000-W02-05 1413 * Sun Oct 31 1582 / 1582-W42-07 Add(YEAR_WOY, 1) -> Sun Oct 23 1583 / 1583-W42-07 1414 * Add(YEAR, 1) -> Mon Oct 31 1583 / 1583-W44-01 1415 */ 1416 int32_t y = cal.get(UCAL_YEAR, status); 1417 int32_t mon = cal.get(UCAL_MONTH, status); 1418 int32_t day = cal.get(UCAL_DATE, status); 1419 int32_t ywy = cal.get(UCAL_YEAR_WOY, status); 1420 int32_t woy = cal.get(UCAL_WEEK_OF_YEAR, status); 1421 int32_t dow = cal.get(UCAL_DOW_LOCAL, status); 1422 UDate t = cal.getTime(status); 1423 1424 if(U_FAILURE(status)){ 1425 errln(UnicodeString("Failed to create Calendar for locale. Error: ") + UnicodeString(u_errorName(status))); 1426 return; 1427 } 1428 UnicodeString str, str2; 1429 SimpleDateFormat fmt(UnicodeString("EEE MMM dd yyyy / YYYY'-W'ww-ee"), status); 1430 fmt.setCalendar(cal); 1431 1432 fmt.format(t, str.remove()); 1433 str += ".add(YEAR, 1) =>"; 1434 cal.add(UCAL_YEAR, 1, status); 1435 int32_t y2 = cal.get(UCAL_YEAR, status); 1436 int32_t mon2 = cal.get(UCAL_MONTH, status); 1437 int32_t day2 = cal.get(UCAL_DATE, status); 1438 fmt.format(cal.getTime(status), str); 1439 if (y2 != (y+1) || mon2 != mon || day2 != day) { 1440 str += (UnicodeString)", expected year " + 1441 (y+1) + ", month " + (mon+1) + ", day " + day; 1442 errln((UnicodeString)"FAIL: " + str); 1443 logln( UnicodeString(" -> ") + CalendarTest::calToStr(cal) ); 1444 } else { 1445 logln(str); 1446 } 1447 1448 fmt.format(t, str.remove()); 1449 str += ".add(YEAR_WOY, 1)=>"; 1450 cal.setTime(t, status); 1451 logln( UnicodeString(" <- ") + CalendarTest::calToStr(cal) ); 1452 cal.add(UCAL_YEAR_WOY, 1, status); 1453 int32_t ywy2 = cal.get(UCAL_YEAR_WOY, status); 1454 int32_t woy2 = cal.get(UCAL_WEEK_OF_YEAR, status); 1455 int32_t dow2 = cal.get(UCAL_DOW_LOCAL, status); 1456 fmt.format(cal.getTime(status), str); 1457 if (ywy2 != (ywy+1) || woy2 != woy || dow2 != dow) { 1458 str += (UnicodeString)", expected yearWOY " + 1459 (ywy+1) + ", woy " + woy + ", dowLocal " + dow; 1460 errln((UnicodeString)"FAIL: " + str); 1461 logln( UnicodeString(" -> ") + CalendarTest::calToStr(cal) ); 1462 } else { 1463 logln(str); 1464 } 1465 } 1466 1467 // ------------------------------------- 1468 1469 void CalendarTest::loop_addroll(Calendar *cal, /*SimpleDateFormat *sdf,*/ int times, UCalendarDateFields field, UCalendarDateFields field2, UErrorCode& errorCode) { 1470 Calendar *calclone; 1471 SimpleDateFormat fmt(UnicodeString("EEE MMM dd yyyy / YYYY'-W'ww-ee"), errorCode); 1472 fmt.setCalendar(*cal); 1473 int i; 1474 1475 for(i = 0; i<times; i++) { 1476 calclone = cal->clone(); 1477 UDate start = cal->getTime(errorCode); 1478 cal->add(field,1,errorCode); 1479 if (U_FAILURE(errorCode)) { errln("Error in add"); delete calclone; return; } 1480 calclone->add(field2,1,errorCode); 1481 if (U_FAILURE(errorCode)) { errln("Error in add"); delete calclone; return; } 1482 if(cal->getTime(errorCode) != calclone->getTime(errorCode)) { 1483 UnicodeString str("FAIL: Results of add differ. "), str2; 1484 str += fmt.format(start, str2) + " "; 1485 str += UnicodeString("Add(") + fieldName(field) + ", 1) -> " + 1486 fmt.format(cal->getTime(errorCode), str2.remove()) + "; "; 1487 str += UnicodeString("Add(") + fieldName(field2) + ", 1) -> " + 1488 fmt.format(calclone->getTime(errorCode), str2.remove()); 1489 errln(str); 1490 delete calclone; 1491 return; 1492 } 1493 delete calclone; 1494 } 1495 1496 for(i = 0; i<times; i++) { 1497 calclone = cal->clone(); 1498 cal->roll(field,(int32_t)1,errorCode); 1499 if (U_FAILURE(errorCode)) { errln("Error in roll"); delete calclone; return; } 1500 calclone->roll(field2,(int32_t)1,errorCode); 1501 if (U_FAILURE(errorCode)) { errln("Error in roll"); delete calclone; return; } 1502 if(cal->getTime(errorCode) != calclone->getTime(errorCode)) { 1503 delete calclone; 1504 errln("Results of roll differ!"); 1505 return; 1506 } 1507 delete calclone; 1508 } 1509 } 1510 1511 // ------------------------------------- 1512 1513 void 1514 CalendarTest::doYEAR_WOYLoop(Calendar *cal, SimpleDateFormat *sdf, 1515 int32_t times, UErrorCode& errorCode) { 1516 1517 UnicodeString us; 1518 UDate tst, original; 1519 Calendar *tstres = new GregorianCalendar(Locale::getGermany(), errorCode); 1520 for(int i=0; i<times; ++i) { 1521 sdf->format(Formattable(cal->getTime(errorCode),Formattable::kIsDate), us, errorCode); 1522 //logln("expected: "+us); 1523 if (U_FAILURE(errorCode)) { errln("Format error"); return; } 1524 tst=sdf->parse(us,errorCode); 1525 if (U_FAILURE(errorCode)) { errln("Parse error"); return; } 1526 tstres->clear(); 1527 tstres->setTime(tst, errorCode); 1528 //logln((UnicodeString)"Parsed week of year is "+tstres->get(UCAL_WEEK_OF_YEAR, errorCode)); 1529 if (U_FAILURE(errorCode)) { errln("Set time error"); return; } 1530 original = cal->getTime(errorCode); 1531 us.remove(); 1532 sdf->format(Formattable(tst,Formattable::kIsDate), us, errorCode); 1533 //logln("got: "+us); 1534 if (U_FAILURE(errorCode)) { errln("Get time error"); return; } 1535 if(original!=tst) { 1536 us.remove(); 1537 sdf->format(Formattable(original, Formattable::kIsDate), us, errorCode); 1538 errln("FAIL: Parsed time doesn't match with regular"); 1539 logln("expected "+us + " " + calToStr(*cal)); 1540 us.remove(); 1541 sdf->format(Formattable(tst, Formattable::kIsDate), us, errorCode); 1542 logln("got "+us + " " + calToStr(*tstres)); 1543 } 1544 tstres->clear(); 1545 tstres->set(UCAL_YEAR_WOY, cal->get(UCAL_YEAR_WOY, errorCode)); 1546 tstres->set(UCAL_WEEK_OF_YEAR, cal->get(UCAL_WEEK_OF_YEAR, errorCode)); 1547 tstres->set(UCAL_DOW_LOCAL, cal->get(UCAL_DOW_LOCAL, errorCode)); 1548 if(cal->get(UCAL_YEAR, errorCode) != tstres->get(UCAL_YEAR, errorCode)) { 1549 errln("FAIL: Different Year!"); 1550 logln((UnicodeString)"Expected "+cal->get(UCAL_YEAR, errorCode)); 1551 logln((UnicodeString)"Got "+tstres->get(UCAL_YEAR, errorCode)); 1552 return; 1553 } 1554 if(cal->get(UCAL_DAY_OF_YEAR, errorCode) != tstres->get(UCAL_DAY_OF_YEAR, errorCode)) { 1555 errln("FAIL: Different Day Of Year!"); 1556 logln((UnicodeString)"Expected "+cal->get(UCAL_DAY_OF_YEAR, errorCode)); 1557 logln((UnicodeString)"Got "+tstres->get(UCAL_DAY_OF_YEAR, errorCode)); 1558 return; 1559 } 1560 //logln(calToStr(*cal)); 1561 cal->add(UCAL_DATE, 1, errorCode); 1562 if (U_FAILURE(errorCode)) { errln("Add error"); return; } 1563 us.remove(); 1564 } 1565 delete (tstres); 1566 } 1567 // ------------------------------------- 1568 1569 void 1570 CalendarTest::marchByDelta(Calendar* cal, int32_t delta) 1571 { 1572 UErrorCode status = U_ZERO_ERROR; 1573 Calendar *cur = (Calendar*) cal->clone(); 1574 int32_t initialDOW = cur->get(UCAL_DAY_OF_WEEK, status); 1575 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; } 1576 int32_t DOW, newDOW = initialDOW; 1577 do { 1578 UnicodeString str; 1579 DOW = newDOW; 1580 logln(UnicodeString("DOW = ") + DOW + " " + dateToString(cur->getTime(status), str)); 1581 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; } 1582 cur->add(UCAL_DAY_OF_WEEK, delta, status); 1583 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; } 1584 newDOW = cur->get(UCAL_DAY_OF_WEEK, status); 1585 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; } 1586 int32_t expectedDOW = 1 + (DOW + delta - 1) % 7; 1587 if (newDOW != expectedDOW) { 1588 errln(UnicodeString("Day of week should be ") + expectedDOW + " instead of " + newDOW + 1589 " on " + dateToString(cur->getTime(status), str)); 1590 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; } 1591 return; 1592 } 1593 } 1594 while (newDOW != initialDOW); 1595 delete cur; 1596 } 1597 1598 #define CHECK(status, msg) \ 1599 if (U_FAILURE(status)) { \ 1600 errcheckln(status, msg); \ 1601 return; \ 1602 } 1603 1604 void CalendarTest::TestWOY(void) { 1605 /* 1606 FDW = Mon, MDFW = 4: 1607 Sun Dec 26 1999, WOY 51 1608 Mon Dec 27 1999, WOY 52 1609 Tue Dec 28 1999, WOY 52 1610 Wed Dec 29 1999, WOY 52 1611 Thu Dec 30 1999, WOY 52 1612 Fri Dec 31 1999, WOY 52 1613 Sat Jan 01 2000, WOY 52 *** 1614 Sun Jan 02 2000, WOY 52 *** 1615 Mon Jan 03 2000, WOY 1 1616 Tue Jan 04 2000, WOY 1 1617 Wed Jan 05 2000, WOY 1 1618 Thu Jan 06 2000, WOY 1 1619 Fri Jan 07 2000, WOY 1 1620 Sat Jan 08 2000, WOY 1 1621 Sun Jan 09 2000, WOY 1 1622 Mon Jan 10 2000, WOY 2 1623 1624 FDW = Mon, MDFW = 2: 1625 Sun Dec 26 1999, WOY 52 1626 Mon Dec 27 1999, WOY 1 *** 1627 Tue Dec 28 1999, WOY 1 *** 1628 Wed Dec 29 1999, WOY 1 *** 1629 Thu Dec 30 1999, WOY 1 *** 1630 Fri Dec 31 1999, WOY 1 *** 1631 Sat Jan 01 2000, WOY 1 1632 Sun Jan 02 2000, WOY 1 1633 Mon Jan 03 2000, WOY 2 1634 Tue Jan 04 2000, WOY 2 1635 Wed Jan 05 2000, WOY 2 1636 Thu Jan 06 2000, WOY 2 1637 Fri Jan 07 2000, WOY 2 1638 Sat Jan 08 2000, WOY 2 1639 Sun Jan 09 2000, WOY 2 1640 Mon Jan 10 2000, WOY 3 1641 */ 1642 1643 UnicodeString str; 1644 UErrorCode status = U_ZERO_ERROR; 1645 int32_t i; 1646 1647 GregorianCalendar cal(status); 1648 SimpleDateFormat fmt(UnicodeString("EEE MMM dd yyyy', WOY' w"), status); 1649 if (failure(status, "Cannot construct calendar/format", TRUE)) return; 1650 1651 UCalendarDaysOfWeek fdw = (UCalendarDaysOfWeek) 0; 1652 1653 //for (int8_t pass=2; pass<=2; ++pass) { 1654 for (int8_t pass=1; pass<=2; ++pass) { 1655 switch (pass) { 1656 case 1: 1657 fdw = UCAL_MONDAY; 1658 cal.setFirstDayOfWeek(fdw); 1659 cal.setMinimalDaysInFirstWeek(4); 1660 fmt.adoptCalendar(cal.clone()); 1661 break; 1662 case 2: 1663 fdw = UCAL_MONDAY; 1664 cal.setFirstDayOfWeek(fdw); 1665 cal.setMinimalDaysInFirstWeek(2); 1666 fmt.adoptCalendar(cal.clone()); 1667 break; 1668 } 1669 1670 //for (i=2; i<=6; ++i) { 1671 for (i=0; i<16; ++i) { 1672 UDate t, t2; 1673 int32_t t_y, t_woy, t_dow; 1674 cal.clear(); 1675 cal.set(1999, UCAL_DECEMBER, 26 + i); 1676 fmt.format(t = cal.getTime(status), str.remove()); 1677 CHECK(status, "Fail: getTime failed"); 1678 logln(UnicodeString("* ") + str); 1679 int32_t dow = cal.get(UCAL_DAY_OF_WEEK, status); 1680 int32_t woy = cal.get(UCAL_WEEK_OF_YEAR, status); 1681 int32_t year = cal.get(UCAL_YEAR, status); 1682 int32_t mon = cal.get(UCAL_MONTH, status); 1683 logln(calToStr(cal)); 1684 CHECK(status, "Fail: get failed"); 1685 int32_t dowLocal = dow - fdw; 1686 if (dowLocal < 0) dowLocal += 7; 1687 dowLocal++; 1688 int32_t yearWoy = year; 1689 if (mon == UCAL_JANUARY) { 1690 if (woy >= 52) --yearWoy; 1691 } else { 1692 if (woy == 1) ++yearWoy; 1693 } 1694 1695 // Basic fields->time check y/woy/dow 1696 // Since Y/WOY is ambiguous, we do a check of the fields, 1697 // not of the specific time. 1698 cal.clear(); 1699 cal.set(UCAL_YEAR, year); 1700 cal.set(UCAL_WEEK_OF_YEAR, woy); 1701 cal.set(UCAL_DAY_OF_WEEK, dow); 1702 t_y = cal.get(UCAL_YEAR, status); 1703 t_woy = cal.get(UCAL_WEEK_OF_YEAR, status); 1704 t_dow = cal.get(UCAL_DAY_OF_WEEK, status); 1705 CHECK(status, "Fail: get failed"); 1706 if (t_y != year || t_woy != woy || t_dow != dow) { 1707 str = "Fail: y/woy/dow fields->time => "; 1708 fmt.format(cal.getTime(status), str); 1709 errln(str); 1710 logln(calToStr(cal)); 1711 logln("[get!=set] Y%d!=%d || woy%d!=%d || dow%d!=%d\n", 1712 t_y, year, t_woy, woy, t_dow, dow); 1713 } else { 1714 logln("y/woy/dow fields->time OK"); 1715 } 1716 1717 // Basic fields->time check y/woy/dow_local 1718 // Since Y/WOY is ambiguous, we do a check of the fields, 1719 // not of the specific time. 1720 cal.clear(); 1721 cal.set(UCAL_YEAR, year); 1722 cal.set(UCAL_WEEK_OF_YEAR, woy); 1723 cal.set(UCAL_DOW_LOCAL, dowLocal); 1724 t_y = cal.get(UCAL_YEAR, status); 1725 t_woy = cal.get(UCAL_WEEK_OF_YEAR, status); 1726 t_dow = cal.get(UCAL_DOW_LOCAL, status); 1727 CHECK(status, "Fail: get failed"); 1728 if (t_y != year || t_woy != woy || t_dow != dowLocal) { 1729 str = "Fail: y/woy/dow_local fields->time => "; 1730 fmt.format(cal.getTime(status), str); 1731 errln(str); 1732 } 1733 1734 // Basic fields->time check y_woy/woy/dow 1735 cal.clear(); 1736 cal.set(UCAL_YEAR_WOY, yearWoy); 1737 cal.set(UCAL_WEEK_OF_YEAR, woy); 1738 cal.set(UCAL_DAY_OF_WEEK, dow); 1739 t2 = cal.getTime(status); 1740 CHECK(status, "Fail: getTime failed"); 1741 if (t != t2) { 1742 str = "Fail: y_woy/woy/dow fields->time => "; 1743 fmt.format(t2, str); 1744 errln(str); 1745 logln(calToStr(cal)); 1746 logln("%.f != %.f\n", t, t2); 1747 } else { 1748 logln("y_woy/woy/dow OK"); 1749 } 1750 1751 // Basic fields->time check y_woy/woy/dow_local 1752 cal.clear(); 1753 cal.set(UCAL_YEAR_WOY, yearWoy); 1754 cal.set(UCAL_WEEK_OF_YEAR, woy); 1755 cal.set(UCAL_DOW_LOCAL, dowLocal); 1756 t2 = cal.getTime(status); 1757 CHECK(status, "Fail: getTime failed"); 1758 if (t != t2) { 1759 str = "Fail: y_woy/woy/dow_local fields->time => "; 1760 fmt.format(t2, str); 1761 errln(str); 1762 } 1763 1764 logln("Testing DOW_LOCAL.. dow%d\n", dow); 1765 // Make sure DOW_LOCAL disambiguates over DOW 1766 int32_t wrongDow = dow - 3; 1767 if (wrongDow < 1) wrongDow += 7; 1768 cal.setTime(t, status); 1769 cal.set(UCAL_DAY_OF_WEEK, wrongDow); 1770 cal.set(UCAL_DOW_LOCAL, dowLocal); 1771 t2 = cal.getTime(status); 1772 CHECK(status, "Fail: set/getTime failed"); 1773 if (t != t2) { 1774 str = "Fail: DOW_LOCAL fields->time => "; 1775 fmt.format(t2, str); 1776 errln(str); 1777 logln(calToStr(cal)); 1778 logln("%.f : DOW%d, DOW_LOCAL%d -> %.f\n", 1779 t, wrongDow, dowLocal, t2); 1780 } 1781 1782 // Make sure DOW disambiguates over DOW_LOCAL 1783 int32_t wrongDowLocal = dowLocal - 3; 1784 if (wrongDowLocal < 1) wrongDowLocal += 7; 1785 cal.setTime(t, status); 1786 cal.set(UCAL_DOW_LOCAL, wrongDowLocal); 1787 cal.set(UCAL_DAY_OF_WEEK, dow); 1788 t2 = cal.getTime(status); 1789 CHECK(status, "Fail: set/getTime failed"); 1790 if (t != t2) { 1791 str = "Fail: DOW fields->time => "; 1792 fmt.format(t2, str); 1793 errln(str); 1794 } 1795 1796 // Make sure YEAR_WOY disambiguates over YEAR 1797 cal.setTime(t, status); 1798 cal.set(UCAL_YEAR, year - 2); 1799 cal.set(UCAL_YEAR_WOY, yearWoy); 1800 t2 = cal.getTime(status); 1801 CHECK(status, "Fail: set/getTime failed"); 1802 if (t != t2) { 1803 str = "Fail: YEAR_WOY fields->time => "; 1804 fmt.format(t2, str); 1805 errln(str); 1806 } 1807 1808 // Make sure YEAR disambiguates over YEAR_WOY 1809 cal.setTime(t, status); 1810 cal.set(UCAL_YEAR_WOY, yearWoy - 2); 1811 cal.set(UCAL_YEAR, year); 1812 t2 = cal.getTime(status); 1813 CHECK(status, "Fail: set/getTime failed"); 1814 if (t != t2) { 1815 str = "Fail: YEAR fields->time => "; 1816 fmt.format(t2, str); 1817 errln(str); 1818 } 1819 } 1820 } 1821 1822 /* 1823 FDW = Mon, MDFW = 4: 1824 Sun Dec 26 1999, WOY 51 1825 Mon Dec 27 1999, WOY 52 1826 Tue Dec 28 1999, WOY 52 1827 Wed Dec 29 1999, WOY 52 1828 Thu Dec 30 1999, WOY 52 1829 Fri Dec 31 1999, WOY 52 1830 Sat Jan 01 2000, WOY 52 1831 Sun Jan 02 2000, WOY 52 1832 */ 1833 1834 // Roll the DOW_LOCAL within week 52 1835 for (i=27; i<=33; ++i) { 1836 int32_t amount; 1837 for (amount=-7; amount<=7; ++amount) { 1838 str = "roll("; 1839 cal.set(1999, UCAL_DECEMBER, i); 1840 UDate t, t2; 1841 fmt.format(cal.getTime(status), str); 1842 CHECK(status, "Fail: getTime failed"); 1843 str += UnicodeString(", ") + amount + ") = "; 1844 1845 cal.roll(UCAL_DOW_LOCAL, amount, status); 1846 CHECK(status, "Fail: roll failed"); 1847 1848 t = cal.getTime(status); 1849 int32_t newDom = i + amount; 1850 while (newDom < 27) newDom += 7; 1851 while (newDom > 33) newDom -= 7; 1852 cal.set(1999, UCAL_DECEMBER, newDom); 1853 t2 = cal.getTime(status); 1854 CHECK(status, "Fail: getTime failed"); 1855 fmt.format(t, str); 1856 1857 if (t != t2) { 1858 str.append(", exp "); 1859 fmt.format(t2, str); 1860 errln(str); 1861 } else { 1862 logln(str); 1863 } 1864 } 1865 } 1866 } 1867 1868 void CalendarTest::TestYWOY() 1869 { 1870 UnicodeString str; 1871 UErrorCode status = U_ZERO_ERROR; 1872 1873 GregorianCalendar cal(status); 1874 if (failure(status, "construct GregorianCalendar", TRUE)) return; 1875 1876 cal.setFirstDayOfWeek(UCAL_SUNDAY); 1877 cal.setMinimalDaysInFirstWeek(1); 1878 1879 logln("Setting: ywoy=2004, woy=1, dow=MONDAY"); 1880 cal.clear(); 1881 cal.set(UCAL_YEAR_WOY,2004); 1882 cal.set(UCAL_WEEK_OF_YEAR,1); 1883 cal.set(UCAL_DAY_OF_WEEK, UCAL_MONDAY); 1884 1885 logln(calToStr(cal)); 1886 if(cal.get(UCAL_YEAR, status) != 2003) { 1887 errln("year not 2003"); 1888 } 1889 1890 logln("+ setting DOW to THURSDAY"); 1891 cal.clear(); 1892 cal.set(UCAL_YEAR_WOY,2004); 1893 cal.set(UCAL_WEEK_OF_YEAR,1); 1894 cal.set(UCAL_DAY_OF_WEEK, UCAL_THURSDAY); 1895 1896 logln(calToStr(cal)); 1897 if(cal.get(UCAL_YEAR, status) != 2004) { 1898 errln("year not 2004"); 1899 } 1900 1901 logln("+ setting DOW_LOCAL to 1"); 1902 cal.clear(); 1903 cal.set(UCAL_YEAR_WOY,2004); 1904 cal.set(UCAL_WEEK_OF_YEAR,1); 1905 cal.set(UCAL_DAY_OF_WEEK, UCAL_THURSDAY); 1906 cal.set(UCAL_DOW_LOCAL, 1); 1907 1908 logln(calToStr(cal)); 1909 if(cal.get(UCAL_YEAR, status) != 2003) { 1910 errln("year not 2003"); 1911 } 1912 1913 cal.setFirstDayOfWeek(UCAL_MONDAY); 1914 cal.setMinimalDaysInFirstWeek(4); 1915 UDate t = 946713600000.; 1916 cal.setTime(t, status); 1917 cal.set(UCAL_DAY_OF_WEEK, 4); 1918 cal.set(UCAL_DOW_LOCAL, 6); 1919 if(cal.getTime(status) != t) { 1920 logln(calToStr(cal)); 1921 errln("FAIL: DOW_LOCAL did not take precedence"); 1922 } 1923 1924 } 1925 1926 void CalendarTest::TestJD() 1927 { 1928 int32_t jd; 1929 static const int32_t kEpochStartAsJulianDay = 2440588; 1930 UErrorCode status = U_ZERO_ERROR; 1931 GregorianCalendar cal(status); 1932 if (failure(status, "construct GregorianCalendar", TRUE)) return; 1933 cal.setTimeZone(*TimeZone::getGMT()); 1934 cal.clear(); 1935 jd = cal.get(UCAL_JULIAN_DAY, status); 1936 if(jd != kEpochStartAsJulianDay) { 1937 errln("Wanted JD of %d at time=0, [epoch 1970] but got %d\n", kEpochStartAsJulianDay, jd); 1938 } else { 1939 logln("Wanted JD of %d at time=0, [epoch 1970], got %d\n", kEpochStartAsJulianDay, jd); 1940 } 1941 1942 cal.setTime(Calendar::getNow(), status); 1943 cal.clear(); 1944 cal.set(UCAL_JULIAN_DAY, kEpochStartAsJulianDay); 1945 UDate epochTime = cal.getTime(status); 1946 if(epochTime != 0) { 1947 errln("Wanted time of 0 at jd=%d, got %.1lf\n", kEpochStartAsJulianDay, epochTime); 1948 } else { 1949 logln("Wanted time of 0 at jd=%d, got %.1lf\n", kEpochStartAsJulianDay, epochTime); 1950 } 1951 1952 } 1953 1954 // make sure the ctestfw utilities are in sync with the Calendar 1955 void CalendarTest::TestDebug() 1956 { 1957 for(int32_t t=0;t<=UDBG_ENUM_COUNT;t++) { 1958 int32_t count = udbg_enumCount((UDebugEnumType)t); 1959 if(count == -1) { 1960 logln("enumCount(%d) returned -1", count); 1961 continue; 1962 } 1963 for(int32_t i=0;i<=count;i++) { 1964 if(t<=UDBG_HIGHEST_CONTIGUOUS_ENUM && i<count) { 1965 if( i!=udbg_enumArrayValue((UDebugEnumType)t, i)) { 1966 errln("FAIL: udbg_enumArrayValue(%d,%d) returned %d, expected %d", t, i, udbg_enumArrayValue((UDebugEnumType)t,i), i); 1967 } 1968 } else { 1969 logln("Testing count+1:"); 1970 } 1971 const char *name = udbg_enumName((UDebugEnumType)t,i); 1972 if(name==NULL) { 1973 if(i==count || t>UDBG_HIGHEST_CONTIGUOUS_ENUM ) { 1974 logln(" null name - expected.\n"); 1975 } else { 1976 errln("FAIL: udbg_enumName(%d,%d) returned NULL", t, i); 1977 } 1978 name = "(null)"; 1979 } 1980 logln("udbg_enumArrayValue(%d,%d) = %s, returned %d", t, i, 1981 name, udbg_enumArrayValue((UDebugEnumType)t,i)); 1982 logln("udbg_enumString = " + udbg_enumString((UDebugEnumType)t,i)); 1983 } 1984 if(udbg_enumExpectedCount((UDebugEnumType)t) != count && t<=UDBG_HIGHEST_CONTIGUOUS_ENUM) { 1985 errln("FAIL: udbg_enumExpectedCount(%d): %d, != UCAL_FIELD_COUNT=%d ", t, udbg_enumExpectedCount((UDebugEnumType)t), count); 1986 } else { 1987 logln("udbg_ucal_fieldCount: %d, UCAL_FIELD_COUNT=udbg_enumCount %d ", udbg_enumExpectedCount((UDebugEnumType)t), count); 1988 } 1989 } 1990 } 1991 1992 1993 #undef CHECK 1994 1995 // List of interesting locales 1996 const char *CalendarTest::testLocaleID(int32_t i) 1997 { 1998 switch(i) { 1999 case 0: return "he_IL@calendar=hebrew"; 2000 case 1: return "en_US@calendar=hebrew"; 2001 case 2: return "fr_FR@calendar=hebrew"; 2002 case 3: return "fi_FI@calendar=hebrew"; 2003 case 4: return "nl_NL@calendar=hebrew"; 2004 case 5: return "hu_HU@calendar=hebrew"; 2005 case 6: return "nl_BE@currency=MTL;calendar=islamic"; 2006 case 7: return "th_TH_TRADITIONAL@calendar=gregorian"; 2007 case 8: return "ar_JO@calendar=islamic-civil"; 2008 case 9: return "fi_FI@calendar=islamic"; 2009 case 10: return "fr_CH@calendar=islamic-civil"; 2010 case 11: return "he_IL@calendar=islamic-civil"; 2011 case 12: return "hu_HU@calendar=buddhist"; 2012 case 13: return "hu_HU@calendar=islamic"; 2013 case 14: return "en_US@calendar=japanese"; 2014 default: return NULL; 2015 } 2016 } 2017 2018 int32_t CalendarTest::testLocaleCount() 2019 { 2020 static int32_t gLocaleCount = -1; 2021 if(gLocaleCount < 0) { 2022 int32_t i; 2023 for(i=0;testLocaleID(i) != NULL;i++) { 2024 ; 2025 } 2026 gLocaleCount = i; 2027 } 2028 return gLocaleCount; 2029 } 2030 2031 static UDate doMinDateOfCalendar(Calendar* adopt, UBool &isGregorian, UErrorCode& status) { 2032 if(U_FAILURE(status)) return 0.0; 2033 2034 adopt->clear(); 2035 adopt->set(UCAL_EXTENDED_YEAR, adopt->getActualMinimum(UCAL_EXTENDED_YEAR, status)); 2036 UDate ret = adopt->getTime(status); 2037 isGregorian = dynamic_cast<GregorianCalendar*>(adopt) != NULL; 2038 delete adopt; 2039 return ret; 2040 } 2041 2042 UDate CalendarTest::minDateOfCalendar(const Locale& locale, UBool &isGregorian, UErrorCode& status) { 2043 if(U_FAILURE(status)) return 0.0; 2044 return doMinDateOfCalendar(Calendar::createInstance(locale, status), isGregorian, status); 2045 } 2046 2047 UDate CalendarTest::minDateOfCalendar(const Calendar& cal, UBool &isGregorian, UErrorCode& status) { 2048 if(U_FAILURE(status)) return 0.0; 2049 return doMinDateOfCalendar(cal.clone(), isGregorian, status); 2050 } 2051 2052 void CalendarTest::Test6703() 2053 { 2054 UErrorCode status = U_ZERO_ERROR; 2055 Calendar *cal; 2056 2057 Locale loc1("en@calendar=fubar"); 2058 cal = Calendar::createInstance(loc1, status); 2059 if (failure(status, "Calendar::createInstance", TRUE)) return; 2060 delete cal; 2061 2062 status = U_ZERO_ERROR; 2063 Locale loc2("en"); 2064 cal = Calendar::createInstance(loc2, status); 2065 if (failure(status, "Calendar::createInstance")) return; 2066 delete cal; 2067 2068 status = U_ZERO_ERROR; 2069 Locale loc3("en@calendar=roc"); 2070 cal = Calendar::createInstance(loc3, status); 2071 if (failure(status, "Calendar::createInstance")) return; 2072 delete cal; 2073 2074 return; 2075 } 2076 2077 void CalendarTest::Test3785() 2078 { 2079 UErrorCode status = U_ZERO_ERROR; 2080 UnicodeString uzone = UNICODE_STRING_SIMPLE("Europe/Paris"); 2081 UnicodeString exp1 = UNICODE_STRING_SIMPLE("Mon 30 Jumada II 1433 AH, 01:47:03"); 2082 UnicodeString exp2 = UNICODE_STRING_SIMPLE("Mon 1 Rajab 1433 AH, 01:47:04"); 2083 2084 LocalUDateFormatPointer df(udat_open(UDAT_NONE, UDAT_NONE, "en@calendar=islamic", uzone.getTerminatedBuffer(), 2085 uzone.length(), NULL, 0, &status)); 2086 if (df.isNull() || U_FAILURE(status)) return; 2087 2088 UChar upattern[64]; 2089 u_uastrcpy(upattern, "EEE d MMMM y G, HH:mm:ss"); 2090 udat_applyPattern(df.getAlias(), FALSE, upattern, u_strlen(upattern)); 2091 2092 UChar ubuffer[1024]; 2093 UDate ud0 = 1337557623000.0; 2094 2095 status = U_ZERO_ERROR; 2096 udat_format(df.getAlias(), ud0, ubuffer, 1024, NULL, &status); 2097 if (U_FAILURE(status)) { 2098 errln("Error formatting date 1\n"); 2099 return; 2100 } 2101 //printf("formatted: '%s'\n", mkcstr(ubuffer)); 2102 2103 UnicodeString act1(ubuffer); 2104 if ( act1 != exp1 ) { 2105 errln("Unexpected result from date 1 format\n"); 2106 } 2107 ud0 += 1000.0; // add one second 2108 2109 status = U_ZERO_ERROR; 2110 udat_format(df.getAlias(), ud0, ubuffer, 1024, NULL, &status); 2111 if (U_FAILURE(status)) { 2112 errln("Error formatting date 2\n"); 2113 return; 2114 } 2115 //printf("formatted: '%s'\n", mkcstr(ubuffer)); 2116 UnicodeString act2(ubuffer); 2117 if ( act2 != exp2 ) { 2118 errln("Unexpected result from date 2 format\n"); 2119 } 2120 2121 return; 2122 } 2123 2124 void CalendarTest::Test1624() { 2125 UErrorCode status = U_ZERO_ERROR; 2126 Locale loc("he_IL@calendar=hebrew"); 2127 HebrewCalendar hc(loc,status); 2128 2129 for (int32_t year = 5600; year < 5800; year++ ) { 2130 2131 for (int32_t month = HebrewCalendar::TISHRI; month <= HebrewCalendar::ELUL; month++) { 2132 // skip the adar 1 month if year is not a leap year 2133 if (HebrewCalendar::isLeapYear(year) == FALSE && month == HebrewCalendar::ADAR_1) { 2134 continue; 2135 } 2136 int32_t day = 15; 2137 hc.set(year,month,day); 2138 int32_t dayHC = hc.get(UCAL_DATE,status); 2139 int32_t monthHC = hc.get(UCAL_MONTH,status); 2140 int32_t yearHC = hc.get(UCAL_YEAR,status); 2141 2142 if (failure(status, "HebrewCalendar.get()", TRUE)) continue; 2143 2144 if (dayHC != day) { 2145 errln(" ==> day %d incorrect, should be: %d\n",dayHC,day); 2146 break; 2147 } 2148 if (monthHC != month) { 2149 errln(" ==> month %d incorrect, should be: %d\n",monthHC,month); 2150 break; 2151 } 2152 if (yearHC != year) { 2153 errln(" ==> day %d incorrect, should be: %d\n",yearHC,year); 2154 break; 2155 } 2156 } 2157 } 2158 return; 2159 } 2160 2161 #endif /* #if !UCONFIG_NO_FORMATTING */ 2162 2163 //eof 2164