1 /*********************************************************************** 2 * COPYRIGHT: 3 * Copyright (c) 1997-2009, International Business Machines Corporation 4 * and others. All Rights Reserved. 5 ***********************************************************************/ 6 7 /* Test Internationalized Calendars for C++ */ 8 9 #include "unicode/utypes.h" 10 #include "string.h" 11 #include "unicode/locid.h" 12 #include "japancal.h" 13 14 #if !UCONFIG_NO_FORMATTING 15 16 #include <stdio.h> 17 #include "caltest.h" 18 19 #define CHECK(status, msg) \ 20 if (U_FAILURE(status)) { \ 21 errcheckln(status, (UnicodeString(u_errorName(status)) + UnicodeString(" : " ) )+ msg); \ 22 return; \ 23 } 24 25 26 static UnicodeString escape( const UnicodeString&src) 27 { 28 UnicodeString dst; 29 dst.remove(); 30 for (int32_t i = 0; i < src.length(); ++i) { 31 UChar c = src[i]; 32 if(c < 0x0080) 33 dst += c; 34 else { 35 dst += UnicodeString("["); 36 char buf [8]; 37 sprintf(buf, "%#x", c); 38 dst += UnicodeString(buf); 39 dst += UnicodeString("]"); 40 } 41 } 42 43 return dst; 44 } 45 46 47 #include "incaltst.h" 48 #include "unicode/gregocal.h" 49 #include "unicode/smpdtfmt.h" 50 #include "unicode/simpletz.h" 51 52 // ***************************************************************************** 53 // class IntlCalendarTest 54 // ***************************************************************************** 55 //--- move to CalendarTest? 56 57 static const double JULIAN_EPOCH = -210866760000000.; 58 59 60 // Turn this on to dump the calendar fields 61 #define U_DEBUG_DUMPCALS 62 63 64 #define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); logln((UnicodeString)""); test(); } break 65 66 67 void IntlCalendarTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ ) 68 { 69 if (exec) logln("TestSuite IntlCalendarTest"); 70 switch (index) { 71 CASE(0,TestTypes); 72 CASE(1,TestGregorian); 73 CASE(2,TestBuddhist); 74 CASE(3,TestJapanese); 75 CASE(4,TestBuddhistFormat); 76 CASE(5,TestJapaneseFormat); 77 CASE(6,TestJapanese3860); 78 CASE(7,TestPersian); 79 CASE(8,TestPersianFormat); 80 CASE(9,TestTaiwan); 81 default: name = ""; break; 82 } 83 } 84 85 #undef CASE 86 87 // --------------------------------------------------------------------------------- 88 89 90 /** 91 * Test various API methods for API completeness. 92 */ 93 void 94 IntlCalendarTest::TestTypes() 95 { 96 Calendar *c = NULL; 97 UErrorCode status = U_ZERO_ERROR; 98 int j; 99 const char *locs [40] = { "en_US_VALLEYGIRL", 100 "en_US_VALLEYGIRL@collation=phonebook;calendar=japanese", 101 "en_US_VALLEYGIRL@collation=phonebook;calendar=gregorian", 102 "ja_JP@calendar=japanese", 103 "th_TH@calendar=buddhist", 104 "ja_JP_TRADITIONAL", 105 "th_TH_TRADITIONAL", 106 "th_TH_TRADITIONAL@calendar=gregorian", 107 "en_US", 108 "th_TH", // Default calendar for th_TH is buddhist 109 "th", // th's default region is TH and buddhist is used as default for TH 110 "en_TH", // Default calendar for any locales with region TH is buddhist 111 NULL }; 112 const char *types[40] = { "gregorian", 113 "japanese", 114 "gregorian", 115 "japanese", 116 "buddhist", 117 "japanese", 118 "buddhist", 119 "gregorian", 120 "gregorian", 121 "buddhist", 122 "buddhist", 123 "buddhist", 124 NULL }; 125 126 for(j=0;locs[j];j++) { 127 logln(UnicodeString("Creating calendar of locale ") + locs[j]); 128 status = U_ZERO_ERROR; 129 c = Calendar::createInstance(locs[j], status); 130 CHECK(status, "creating '" + UnicodeString(locs[j]) + "' calendar"); 131 if(U_SUCCESS(status)) { 132 logln(UnicodeString(" type is ") + c->getType()); 133 if(strcmp(c->getType(), types[j])) { 134 dataerrln(UnicodeString(locs[j]) + UnicodeString("Calendar type ") + c->getType() + " instead of " + types[j]); 135 } 136 } 137 delete c; 138 } 139 } 140 141 142 143 /** 144 * Run a test of a quasi-Gregorian calendar. This is a calendar 145 * that behaves like a Gregorian but has different year/era mappings. 146 * The int[] data array should have the format: 147 * 148 * { era, year, gregorianYear, month, dayOfMonth, ... ... , -1 } 149 */ 150 void IntlCalendarTest::quasiGregorianTest(Calendar& cal, const Locale& gcl, const int32_t *data) { 151 UErrorCode status = U_ZERO_ERROR; 152 // As of JDK 1.4.1_01, using the Sun JDK GregorianCalendar as 153 // a reference throws us off by one hour. This is most likely 154 // due to the JDK 1.4 incorporation of historical time zones. 155 //java.util.Calendar grego = java.util.Calendar.getInstance(); 156 Calendar *grego = Calendar::createInstance(gcl, status); 157 if (U_FAILURE(status)) { 158 dataerrln("Error calling Calendar::createInstance"); 159 return; 160 } 161 162 int32_t tz1 = cal.get(UCAL_ZONE_OFFSET,status); 163 int32_t tz2 = grego -> get (UCAL_ZONE_OFFSET, status); 164 if(tz1 != tz2) { 165 errln((UnicodeString)"cal's tz " + tz1 + " != grego's tz " + tz2); 166 } 167 168 for (int32_t i=0; data[i]!=-1; ) { 169 int32_t era = data[i++]; 170 int32_t year = data[i++]; 171 int32_t gregorianYear = data[i++]; 172 int32_t month = data[i++]; 173 int32_t dayOfMonth = data[i++]; 174 175 grego->clear(); 176 grego->set(gregorianYear, month, dayOfMonth); 177 UDate D = grego->getTime(status); 178 179 cal.clear(); 180 cal.set(UCAL_ERA, era); 181 cal.set(year, month, dayOfMonth); 182 UDate d = cal.getTime(status); 183 #ifdef U_DEBUG_DUMPCALS 184 logln((UnicodeString)"cal : " + CalendarTest::calToStr(cal)); 185 logln((UnicodeString)"grego: " + CalendarTest::calToStr(*grego)); 186 #endif 187 if (d == D) { 188 logln(UnicodeString("OK: ") + era + ":" + year + "/" + (month+1) + "/" + dayOfMonth + 189 " => " + d + " (" + UnicodeString(cal.getType()) + ")"); 190 } else { 191 errln(UnicodeString("Fail: (fields to millis)") + era + ":" + year + "/" + (month+1) + "/" + dayOfMonth + 192 " => " + d + ", expected " + D + " (" + UnicodeString(cal.getType()) + "Off by: " + (d-D)); 193 } 194 195 // Now, set the gregorian millis on the other calendar 196 cal.clear(); 197 cal.setTime(D, status); 198 int e = cal.get(UCAL_ERA, status); 199 int y = cal.get(UCAL_YEAR, status); 200 #ifdef U_DEBUG_DUMPCALS 201 logln((UnicodeString)"cal : " + CalendarTest::calToStr(cal)); 202 logln((UnicodeString)"grego: " + CalendarTest::calToStr(*grego)); 203 #endif 204 if (y == year && e == era) { 205 logln((UnicodeString)"OK: " + D + " => " + cal.get(UCAL_ERA, status) + ":" + 206 cal.get(UCAL_YEAR, status) + "/" + 207 (cal.get(UCAL_MONTH, status)+1) + "/" + cal.get(UCAL_DATE, status) + " (" + UnicodeString(cal.getType()) + ")"); 208 } else { 209 errln((UnicodeString)"Fail: (millis to fields)" + D + " => " + cal.get(UCAL_ERA, status) + ":" + 210 cal.get(UCAL_YEAR, status) + "/" + 211 (cal.get(UCAL_MONTH, status)+1) + "/" + cal.get(UCAL_DATE, status) + 212 ", expected " + era + ":" + year + "/" + (month+1) + "/" + 213 dayOfMonth + " (" + UnicodeString(cal.getType())); 214 } 215 } 216 delete grego; 217 CHECK(status, "err during quasiGregorianTest()"); 218 } 219 220 // Verify that Gregorian works like Gregorian 221 void IntlCalendarTest::TestGregorian() { 222 UDate timeA = Calendar::getNow(); 223 int32_t data[] = { 224 GregorianCalendar::AD, 1868, 1868, UCAL_SEPTEMBER, 8, 225 GregorianCalendar::AD, 1868, 1868, UCAL_SEPTEMBER, 9, 226 GregorianCalendar::AD, 1869, 1869, UCAL_JUNE, 4, 227 GregorianCalendar::AD, 1912, 1912, UCAL_JULY, 29, 228 GregorianCalendar::AD, 1912, 1912, UCAL_JULY, 30, 229 GregorianCalendar::AD, 1912, 1912, UCAL_AUGUST, 1, 230 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 231 }; 232 233 Calendar *cal; 234 UErrorCode status = U_ZERO_ERROR; 235 cal = Calendar::createInstance(/*"de_DE", */ status); 236 CHECK(status, UnicodeString("Creating de_CH calendar")); 237 // Sanity check the calendar 238 UDate timeB = Calendar::getNow(); 239 UDate timeCal = cal->getTime(status); 240 241 if(!(timeA <= timeCal) || !(timeCal <= timeB)) { 242 errln((UnicodeString)"Error: Calendar time " + timeCal + 243 " is not within sampled times [" + timeA + " to " + timeB + "]!"); 244 } 245 // end sanity check 246 247 // Note, the following is a good way to test the sanity of the constructed calendars, 248 // using Collation as a delay-loop: 249 // 250 // $ intltest format/IntlCalendarTest collate/G7CollationTest format/IntlCalendarTest 251 252 quasiGregorianTest(*cal,Locale("fr_FR"),data); 253 delete cal; 254 } 255 256 /** 257 * Verify that BuddhistCalendar shifts years to Buddhist Era but otherwise 258 * behaves like GregorianCalendar. 259 */ 260 void IntlCalendarTest::TestBuddhist() { 261 // BE 2542 == 1999 CE 262 UDate timeA = Calendar::getNow(); 263 264 int32_t data[] = { 265 0, // B. era [928479600000] 266 2542, // B. year 267 1999, // G. year 268 UCAL_JUNE, // month 269 4, // day 270 271 0, // B. era [-79204842000000] 272 3, // B. year 273 -540, // G. year 274 UCAL_FEBRUARY, // month 275 12, // day 276 277 0, // test month calculation: 4795 BE = 4252 AD is a leap year, but 4795 AD is not. 278 4795, // BE [72018057600000] 279 4252, // AD 280 UCAL_FEBRUARY, 281 29, 282 283 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1 284 }; 285 Calendar *cal; 286 UErrorCode status = U_ZERO_ERROR; 287 cal = Calendar::createInstance("th_TH@calendar=buddhist", status); 288 CHECK(status, UnicodeString("Creating th_TH@calendar=buddhist calendar")); 289 290 // Sanity check the calendar 291 UDate timeB = Calendar::getNow(); 292 UDate timeCal = cal->getTime(status); 293 294 if(!(timeA <= timeCal) || !(timeCal <= timeB)) { 295 errln((UnicodeString)"Error: Calendar time " + timeCal + 296 " is not within sampled times [" + timeA + " to " + timeB + "]!"); 297 } 298 // end sanity check 299 300 301 quasiGregorianTest(*cal,Locale("th_TH@calendar=gregorian"),data); 302 delete cal; 303 } 304 305 306 /** 307 * Verify that TaiWanCalendar shifts years to Minguo Era but otherwise 308 * behaves like GregorianCalendar. 309 */ 310 void IntlCalendarTest::TestTaiwan() { 311 // MG 1 == 1912 AD 312 UDate timeA = Calendar::getNow(); 313 314 // TODO port these to the data items 315 int32_t data[] = { 316 1, // B. era [928479600000] 317 1, // B. year 318 1912, // G. year 319 UCAL_JUNE, // month 320 4, // day 321 322 1, // B. era [-79204842000000] 323 3, // B. year 324 1914, // G. year 325 UCAL_FEBRUARY, // month 326 12, // day 327 328 1, // B. era [-79204842000000] 329 96, // B. year 330 2007, // G. year 331 UCAL_FEBRUARY, // month 332 12, // day 333 334 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1 335 }; 336 Calendar *cal; 337 UErrorCode status = U_ZERO_ERROR; 338 cal = Calendar::createInstance("en_US@calendar=roc", status); 339 CHECK(status, UnicodeString("Creating en_US@calendar=roc calendar")); 340 341 // Sanity check the calendar 342 UDate timeB = Calendar::getNow(); 343 UDate timeCal = cal->getTime(status); 344 345 if(!(timeA <= timeCal) || !(timeCal <= timeB)) { 346 errln((UnicodeString)"Error: Calendar time " + timeCal + 347 " is not within sampled times [" + timeA + " to " + timeB + "]!"); 348 } 349 // end sanity check 350 351 352 quasiGregorianTest(*cal,Locale("en_US"),data); 353 delete cal; 354 } 355 356 357 358 /** 359 * Verify that JapaneseCalendar shifts years to Japanese Eras but otherwise 360 * behaves like GregorianCalendar. 361 */ 362 void IntlCalendarTest::TestJapanese() { 363 UDate timeA = Calendar::getNow(); 364 365 /* Sorry.. japancal.h is private! */ 366 #define JapaneseCalendar_MEIJI 232 367 #define JapaneseCalendar_TAISHO 233 368 #define JapaneseCalendar_SHOWA 234 369 #define JapaneseCalendar_HEISEI 235 370 371 // BE 2542 == 1999 CE 372 int32_t data[] = { 373 // Jera Jyr Gyear m d 374 JapaneseCalendar_MEIJI, 1, 1868, UCAL_SEPTEMBER, 8, 375 JapaneseCalendar_MEIJI, 1, 1868, UCAL_SEPTEMBER, 9, 376 JapaneseCalendar_MEIJI, 2, 1869, UCAL_JUNE, 4, 377 JapaneseCalendar_MEIJI, 45, 1912, UCAL_JULY, 29, 378 JapaneseCalendar_TAISHO, 1, 1912, UCAL_JULY, 30, 379 JapaneseCalendar_TAISHO, 1, 1912, UCAL_AUGUST, 1, 380 381 // new tests (not in java) 382 JapaneseCalendar_SHOWA, 64, 1989, UCAL_JANUARY, 7, // Test current era transition (different code path than others) 383 JapaneseCalendar_HEISEI, 1, 1989, UCAL_JANUARY, 8, 384 JapaneseCalendar_HEISEI, 1, 1989, UCAL_JANUARY, 9, 385 JapaneseCalendar_HEISEI, 1, 1989, UCAL_DECEMBER, 20, 386 JapaneseCalendar_HEISEI, 15, 2003, UCAL_MAY, 22, 387 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1 388 }; 389 390 Calendar *cal; 391 UErrorCode status = U_ZERO_ERROR; 392 cal = Calendar::createInstance("ja_JP@calendar=japanese", status); 393 CHECK(status, UnicodeString("Creating ja_JP@calendar=japanese calendar")); 394 // Sanity check the calendar 395 UDate timeB = Calendar::getNow(); 396 UDate timeCal = cal->getTime(status); 397 398 if(!(timeA <= timeCal) || !(timeCal <= timeB)) { 399 errln((UnicodeString)"Error: Calendar time " + timeCal + 400 " is not within sampled times [" + timeA + " to " + timeB + "]!"); 401 } 402 // end sanity check 403 quasiGregorianTest(*cal,Locale("ja_JP"),data); 404 delete cal; 405 } 406 407 408 409 void IntlCalendarTest::TestBuddhistFormat() { 410 UErrorCode status = U_ZERO_ERROR; 411 412 // Test simple parse/format with adopt 413 414 // First, a contrived english test.. 415 UDate aDate = 999932400000.0; 416 SimpleDateFormat *fmt = new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"), Locale("en_US@calendar=buddhist"), status); 417 CHECK(status, "creating date format instance"); 418 SimpleDateFormat *fmt2 = new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"), Locale("en_US@calendar=gregorian"), status); 419 CHECK(status, "creating gregorian date format instance"); 420 if(!fmt) { 421 errln("Coudln't create en_US instance"); 422 } else { 423 UnicodeString str; 424 fmt2->format(aDate, str); 425 logln(UnicodeString() + "Test Date: " + str); 426 str.remove(); 427 fmt->format(aDate, str); 428 logln(UnicodeString() + "as Buddhist Calendar: " + escape(str)); 429 UnicodeString expected("September 8, 2544 BE"); 430 if(str != expected) { 431 errln("Expected " + escape(expected) + " but got " + escape(str)); 432 } 433 UDate otherDate = fmt->parse(expected, status); 434 if(otherDate != aDate) { 435 UnicodeString str3; 436 fmt->format(otherDate, str3); 437 errln("Parse incorrect of " + escape(expected) + " - wanted " + aDate + " but got " + otherDate + ", " + escape(str3)); 438 } else { 439 logln("Parsed OK: " + expected); 440 } 441 delete fmt; 442 } 443 delete fmt2; 444 445 CHECK(status, "Error occured testing Buddhist Calendar in English "); 446 447 status = U_ZERO_ERROR; 448 // Now, try in Thai 449 { 450 UnicodeString expect = CharsToUnicodeString("\\u0E27\\u0E31\\u0E19\\u0E40\\u0E2A\\u0E32\\u0E23\\u0E4C\\u0E17\\u0E35\\u0E48" 451 " 8 \\u0E01\\u0E31\\u0e19\\u0e22\\u0e32\\u0e22\\u0e19 \\u0e1e.\\u0e28. 2544"); 452 UDate expectDate = 999932400000.0; 453 Locale loc("th_TH_TRADITIONAL"); // legacy 454 455 simpleTest(loc, expect, expectDate, status); 456 } 457 status = U_ZERO_ERROR; 458 { 459 UnicodeString expect = CharsToUnicodeString("\\u0E27\\u0E31\\u0E19\\u0E40\\u0E2A\\u0E32\\u0E23\\u0E4C\\u0E17\\u0E35\\u0E48" 460 " 8 \\u0E01\\u0E31\\u0e19\\u0e22\\u0e32\\u0e22\\u0e19 \\u0e1e.\\u0e28. 2544"); 461 UDate expectDate = 999932400000.0; 462 Locale loc("th_TH@calendar=buddhist"); 463 464 simpleTest(loc, expect, expectDate, status); 465 } 466 status = U_ZERO_ERROR; 467 { 468 UnicodeString expect = CharsToUnicodeString("\\u0E27\\u0E31\\u0E19\\u0E40\\u0E2A\\u0E32\\u0E23\\u0E4C\\u0E17\\u0E35\\u0E48" 469 " 8 \\u0E01\\u0E31\\u0e19\\u0e22\\u0e32\\u0e22\\u0e19 \\u0e04.\\u0e28. 2001"); 470 UDate expectDate = 999932400000.0; 471 Locale loc("th_TH@calendar=gregorian"); 472 473 simpleTest(loc, expect, expectDate, status); 474 } 475 status = U_ZERO_ERROR; 476 { 477 UnicodeString expect = CharsToUnicodeString("\\u0E27\\u0E31\\u0E19\\u0E40\\u0E2A\\u0E32\\u0E23\\u0E4C\\u0E17\\u0E35\\u0E48" 478 " 8 \\u0E01\\u0E31\\u0e19\\u0e22\\u0e32\\u0e22\\u0e19 \\u0e04.\\u0e28. 2001"); 479 UDate expectDate = 999932400000.0; 480 Locale loc("th_TH_TRADITIONAL@calendar=gregorian"); 481 482 simpleTest(loc, expect, expectDate, status); 483 } 484 } 485 486 // TaiwanFormat has been moved to testdata/format.txt 487 488 489 void IntlCalendarTest::TestJapaneseFormat() { 490 Calendar *cal; 491 UErrorCode status = U_ZERO_ERROR; 492 cal = Calendar::createInstance("ja_JP_TRADITIONAL", status); 493 CHECK(status, UnicodeString("Creating ja_JP_TRADITIONAL calendar")); 494 495 Calendar *cal2 = cal->clone(); 496 delete cal; 497 cal = NULL; 498 499 // Test simple parse/format with adopt 500 501 UDate aDate = 999932400000.0; 502 SimpleDateFormat *fmt = new SimpleDateFormat(UnicodeString("MMMM d, yy G"), Locale("en_US@calendar=japanese"), status); 503 SimpleDateFormat *fmt2 = new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"), Locale("en_US@calendar=gregorian"), status); 504 CHECK(status, "creating date format instance"); 505 if(!fmt) { 506 errln("Coudln't create en_US instance"); 507 } else { 508 UnicodeString str; 509 fmt2->format(aDate, str); 510 logln(UnicodeString() + "Test Date: " + str); 511 str.remove(); 512 fmt->format(aDate, str); 513 logln(UnicodeString() + "as Japanese Calendar: " + str); 514 UnicodeString expected("September 8, 13 Heisei"); 515 if(str != expected) { 516 errln("Expected " + expected + " but got " + str); 517 } 518 UDate otherDate = fmt->parse(expected, status); 519 if(otherDate != aDate) { 520 UnicodeString str3; 521 ParsePosition pp; 522 fmt->parse(expected, *cal2, pp); 523 fmt->format(otherDate, str3); 524 errln("Parse incorrect of " + expected + " - wanted " + aDate + " but got " + " = " + otherDate + ", " + str3 + " = " + CalendarTest::calToStr(*cal2) ); 525 526 } else { 527 logln("Parsed OK: " + expected); 528 } 529 delete fmt; 530 } 531 532 // Test parse with incomplete information 533 fmt = new SimpleDateFormat(UnicodeString("G y"), Locale("en_US@calendar=japanese"), status); 534 /* The test data below should points to 1868-09-08T00:00:00 in America/Los_Angeles. 535 * The time calculated by original test code uses -7:00 UTC offset, because it assumes 536 * DST is observed (because of a timezone bug, DST is observed for early 20th century 537 * day to infinite past time). The bug was fixed and DST is no longer used for time before 538 * 1900 for any zones. However, ICU timezone transition data is represented by 32-bit integer 539 * (sec) and cannot represent transitions before 1901 defined in Olson tzdata. For example, 540 * based on Olson definition, offset -7:52:58 should be used for Nov 18, 1883 or older dates. 541 * If ICU properly capture entire Olson zone definition, the start time of "Meiji 1" is 542 * -3197117222000. -Yoshito 543 */ 544 /* TODO: When ICU support the Olson LMT offset for America/Los_Angeles, we need to update 545 * the reference data. 546 */ 547 //aDate = -3197120400000.; 548 aDate = -3197116800000.; 549 CHECK(status, "creating date format instance"); 550 if(!fmt) { 551 errln("Coudln't create en_US instance"); 552 } else { 553 UnicodeString str; 554 fmt2->format(aDate, str); 555 logln(UnicodeString() + "Test Date: " + str); 556 str.remove(); 557 fmt->format(aDate, str); 558 logln(UnicodeString() + "as Japanese Calendar: " + str); 559 UnicodeString expected("Meiji 1"); 560 if(str != expected) { 561 errln("Expected " + expected + " but got " + str); 562 } 563 UDate otherDate = fmt->parse(expected, status); 564 if(otherDate != aDate) { 565 UnicodeString str3; 566 ParsePosition pp; 567 fmt->parse(expected, *cal2, pp); 568 fmt->format(otherDate, str3); 569 errln("Parse incorrect of " + expected + " - wanted " + aDate + " but got " + " = " + 570 otherDate + ", " + str3 + " = " + CalendarTest::calToStr(*cal2) ); 571 } else { 572 logln("Parsed OK: " + expected); 573 } 574 delete fmt; 575 } 576 577 delete cal2; 578 delete fmt2; 579 CHECK(status, "Error occured"); 580 581 // Now, try in Japanese 582 { 583 UnicodeString expect = CharsToUnicodeString("\\u5e73\\u621013\\u5e749\\u67088\\u65e5\\u571f\\u66dc\\u65e5"); 584 UDate expectDate = 999932400000.0; // Testing a recent date 585 Locale loc("ja_JP@calendar=japanese"); 586 587 status = U_ZERO_ERROR; 588 simpleTest(loc, expect, expectDate, status); 589 } 590 { 591 UnicodeString expect = CharsToUnicodeString("\\u5e73\\u621013\\u5e749\\u67088\\u65e5\\u571f\\u66dc\\u65e5"); 592 UDate expectDate = 999932400000.0; // Testing a recent date 593 Locale loc("ja_JP_TRADITIONAL"); // legacy 594 595 status = U_ZERO_ERROR; 596 simpleTest(loc, expect, expectDate, status); 597 } 598 { 599 UnicodeString expect = CharsToUnicodeString("\\u5b89\\u6c385\\u5e747\\u67084\\u65e5\\u6728\\u66dc\\u65e5"); 600 //UDate expectDate = -6106035600000.0; 601 UDate expectDate = -6106032000000.0; // 1776-07-04T00:00:00Z-0800 602 Locale loc("ja_JP@calendar=japanese"); 603 604 status = U_ZERO_ERROR; 605 simpleTest(loc, expect, expectDate, status); 606 607 } 608 { // Jitterbug 1869 - this is an ambiguous era. (Showa 64 = Jan 6 1989, but Showa could be 2 other eras) ) 609 UnicodeString expect = CharsToUnicodeString("\\u662d\\u548c64\\u5e741\\u67086\\u65e5\\u91d1\\u66dc\\u65e5"); 610 UDate expectDate = 600076800000.0; 611 Locale loc("ja_JP@calendar=japanese"); 612 613 status = U_ZERO_ERROR; 614 simpleTest(loc, expect, expectDate, status); 615 616 } 617 { // This Feb 29th falls on a leap year by gregorian year, but not by Japanese year. 618 UnicodeString expect = CharsToUnicodeString("\\u5EB7\\u6B632\\u5e742\\u670829\\u65e5\\u65e5\\u66dc\\u65e5"); 619 // Add -1:00 to the following for historical TZ - aliu 620 //UDate expectDate = -16214403600000.0; // courtesy of date format round trip test 621 UDate expectDate = -16214400000000.0; // 1456-03-09T00:00:00Z-0800 622 Locale loc("ja_JP@calendar=japanese"); 623 624 status = U_ZERO_ERROR; 625 simpleTest(loc, expect, expectDate, status); 626 627 } 628 } 629 630 void IntlCalendarTest::TestJapanese3860() 631 { 632 Calendar *cal; 633 UErrorCode status = U_ZERO_ERROR; 634 cal = Calendar::createInstance("ja_JP@calendar=japanese", status); 635 CHECK(status, UnicodeString("Creating ja_JP@calendar=japanese calendar")); 636 Calendar *cal2 = cal->clone(); 637 SimpleDateFormat *fmt2 = new SimpleDateFormat(UnicodeString("HH:mm:ss.S MMMM d, yyyy G"), Locale("en_US@calendar=gregorian"), status); 638 UnicodeString str; 639 640 641 { 642 // Test simple parse/format with adopt 643 UDate aDate = 0; 644 645 // Test parse with missing era (should default to current era, heisei) 646 // Test parse with incomplete information 647 logln("Testing parse w/ missing era..."); 648 SimpleDateFormat *fmt = new SimpleDateFormat(UnicodeString("y.M.d"), Locale("ja_JP@calendar=japanese"), status); 649 CHECK(status, "creating date format instance"); 650 if(!fmt) { 651 errln("Coudln't create en_US instance"); 652 } else { 653 UErrorCode s2 = U_ZERO_ERROR; 654 cal2->clear(); 655 UnicodeString samplestr("1.1.9"); 656 logln(UnicodeString() + "Test Year: " + samplestr); 657 aDate = fmt->parse(samplestr, s2); 658 ParsePosition pp=0; 659 fmt->parse(samplestr, *cal2, pp); 660 CHECK(s2, "parsing the 1.1.9 string"); 661 logln("*cal2 after 119 parse:"); 662 str.remove(); 663 fmt2->format(aDate, str); 664 logln(UnicodeString() + "as Gregorian Calendar: " + str); 665 666 cal2->setTime(aDate, s2); 667 int32_t gotYear = cal2->get(UCAL_YEAR, s2); 668 int32_t gotEra = cal2->get(UCAL_ERA, s2); 669 int32_t expectYear = 1; 670 int32_t expectEra = JapaneseCalendar::getCurrentEra(); 671 if((gotYear!=1) || (gotEra != expectEra)) { 672 errln(UnicodeString("parse "+samplestr+" of 'y.m.d' as Japanese Calendar, expected year ") + expectYear + 673 UnicodeString(" and era ") + expectEra +", but got year " + gotYear + " and era " + gotEra + " (Gregorian:" + str +")"); 674 } else { 675 logln(UnicodeString() + " year: " + gotYear + ", era: " + gotEra); 676 } 677 delete fmt; 678 } 679 } 680 681 { 682 // Test simple parse/format with adopt 683 UDate aDate = 0; 684 685 // Test parse with missing era (should default to current era, heisei) 686 // Test parse with incomplete information 687 logln("Testing parse w/ just year..."); 688 SimpleDateFormat *fmt = new SimpleDateFormat(UnicodeString("y"), Locale("ja_JP@calendar=japanese"), status); 689 CHECK(status, "creating date format instance"); 690 if(!fmt) { 691 errln("Coudln't create en_US instance"); 692 } else { 693 UErrorCode s2 = U_ZERO_ERROR; 694 cal2->clear(); 695 UnicodeString samplestr("1"); 696 logln(UnicodeString() + "Test Year: " + samplestr); 697 aDate = fmt->parse(samplestr, s2); 698 ParsePosition pp=0; 699 fmt->parse(samplestr, *cal2, pp); 700 CHECK(s2, "parsing the 1 string"); 701 logln("*cal2 after 1 parse:"); 702 str.remove(); 703 fmt2->format(aDate, str); 704 logln(UnicodeString() + "as Gregorian Calendar: " + str); 705 706 cal2->setTime(aDate, s2); 707 int32_t gotYear = cal2->get(UCAL_YEAR, s2); 708 int32_t gotEra = cal2->get(UCAL_ERA, s2); 709 int32_t expectYear = 1; 710 int32_t expectEra = 235; //JapaneseCalendar::kCurrentEra; 711 if((gotYear!=1) || (gotEra != expectEra)) { 712 errln(UnicodeString("parse "+samplestr+" of 'y' as Japanese Calendar, expected year ") + expectYear + 713 UnicodeString(" and era ") + expectEra +", but got year " + gotYear + " and era " + gotEra + " (Gregorian:" + str +")"); 714 } else { 715 logln(UnicodeString() + " year: " + gotYear + ", era: " + gotEra); 716 } 717 delete fmt; 718 } 719 } 720 721 delete cal2; 722 delete cal; 723 delete fmt2; 724 } 725 726 727 728 729 /** 730 * Verify the Persian Calendar. 731 */ 732 void IntlCalendarTest::TestPersian() { 733 UDate timeA = Calendar::getNow(); 734 735 Calendar *cal; 736 UErrorCode status = U_ZERO_ERROR; 737 cal = Calendar::createInstance("fa_IR@calendar=persian", status); 738 CHECK(status, UnicodeString("Creating fa_IR@calendar=persian calendar")); 739 // Sanity check the calendar 740 UDate timeB = Calendar::getNow(); 741 UDate timeCal = cal->getTime(status); 742 743 if(!(timeA <= timeCal) || !(timeCal <= timeB)) { 744 errln((UnicodeString)"Error: Calendar time " + timeCal + 745 " is not within sampled times [" + timeA + " to " + timeB + "]!"); 746 } 747 // end sanity check 748 // quasiGregorianTest(*cal,Locale("ja_JP"),data); 749 delete cal; 750 } 751 752 void IntlCalendarTest::TestPersianFormat() { 753 UErrorCode status = U_ZERO_ERROR; 754 SimpleDateFormat *fmt = new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"), Locale(" en_US@calendar=persian"), status); 755 CHECK(status, "creating date format instance"); 756 SimpleDateFormat *fmt2 = new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"), Locale("en_US@calendar=gregorian"), status); 757 CHECK(status, "creating gregorian date format instance"); 758 UnicodeString gregorianDate("January 18, 2007 AD"); 759 UDate aDate = fmt2->parse(gregorianDate, status); 760 if(!fmt) { 761 errln("Coudln't create en_US instance"); 762 } else { 763 UnicodeString str; 764 fmt->format(aDate, str); 765 logln(UnicodeString() + "as Persian Calendar: " + escape(str)); 766 UnicodeString expected("Dey 28, 1385 AP"); 767 if(str != expected) { 768 errln("Expected " + escape(expected) + " but got " + escape(str)); 769 } 770 UDate otherDate = fmt->parse(expected, status); 771 if(otherDate != aDate) { 772 UnicodeString str3; 773 fmt->format(otherDate, str3); 774 errln("Parse incorrect of " + escape(expected) + " - wanted " + aDate + " but got " + otherDate + ", " + escape(str3)); 775 } else { 776 logln("Parsed OK: " + expected); 777 } 778 // Two digit year parsing problem #4732 779 fmt->applyPattern("yy-MM-dd"); 780 str.remove(); 781 fmt->format(aDate, str); 782 expected.setTo("85-10-28"); 783 if(str != expected) { 784 errln("Expected " + escape(expected) + " but got " + escape(str)); 785 } 786 otherDate = fmt->parse(expected, status); 787 if (otherDate != aDate) { 788 errln("Parse incorrect of " + escape(expected) + " - wanted " + aDate + " but got " + otherDate); 789 } else { 790 logln("Parsed OK: " + expected); 791 } 792 delete fmt; 793 } 794 delete fmt2; 795 796 CHECK(status, "Error occured testing Persian Calendar in English "); 797 } 798 799 800 void IntlCalendarTest::simpleTest(const Locale& loc, const UnicodeString& expect, UDate expectDate, UErrorCode& status) 801 { 802 UnicodeString tmp; 803 UDate d; 804 DateFormat *fmt0 = DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull); 805 806 logln("Try format/parse of " + (UnicodeString)loc.getName()); 807 DateFormat *fmt2 = DateFormat::createDateInstance(DateFormat::kFull, loc); 808 if(fmt2) { 809 fmt2->format(expectDate, tmp); 810 logln(escape(tmp) + " ( in locale " + loc.getName() + ")"); 811 if(tmp != expect) { 812 errln(UnicodeString("Failed to format " ) + loc.getName() + " expected " + escape(expect) + " got " + escape(tmp) ); 813 } 814 815 d = fmt2->parse(expect,status); 816 CHECK(status, "Error occured parsing " + UnicodeString(loc.getName())); 817 if(d != expectDate) { 818 fmt2->format(d,tmp); 819 errln(UnicodeString("Failed to parse " ) + escape(expect) + ", " + loc.getName() + " expect " + (double)expectDate + " got " + (double)d + " " + escape(tmp)); 820 logln( "wanted " + escape(fmt0->format(expectDate,tmp.remove())) + " but got " + escape(fmt0->format(d,tmp.remove()))); 821 } 822 delete fmt2; 823 } else { 824 errln((UnicodeString)"Can't create " + loc.getName() + " date instance"); 825 } 826 delete fmt0; 827 } 828 829 #undef CHECK 830 831 #endif /* #if !UCONFIG_NO_FORMATTING */ 832 833 //eof 834