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