Home | History | Annotate | Download | only in intltest
      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