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