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                             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     aDate = -3197117222000.0;
    535     CHECK(status, "creating date format instance");
    536     if(!fmt) {
    537         errln("Coudln't create en_US instance");
    538     } else {
    539         UnicodeString str;
    540         fmt2->format(aDate, str);
    541         logln(UnicodeString() + "Test Date: " + str);
    542         str.remove();
    543         fmt->format(aDate, str);
    544         logln(UnicodeString() + "as Japanese Calendar: " + str);
    545         UnicodeString expected("Meiji 1");
    546         if(str != expected) {
    547             errln("Expected " + expected + " but got " + str);
    548         }
    549         UDate otherDate = fmt->parse(expected, status);
    550         if(otherDate != aDate) {
    551             UnicodeString str3;
    552             ParsePosition pp;
    553             fmt->parse(expected, *cal2, pp);
    554             fmt->format(otherDate, str3);
    555             errln("Parse incorrect of " + expected + " - wanted " + aDate + " but got " +  " = " +
    556                 otherDate + ", " + str3 + " = " + CalendarTest::calToStr(*cal2) );
    557         } else {
    558             logln("Parsed OK: " + expected);
    559         }
    560         delete fmt;
    561     }
    562 
    563     delete cal2;
    564     delete fmt2;
    565     CHECK(status, "Error occured");
    566 
    567     // Now, try in Japanese
    568     {
    569         UnicodeString expect = CharsToUnicodeString("\\u5e73\\u621013\\u5e749\\u67088\\u65e5\\u571f\\u66dc\\u65e5");
    570         UDate         expectDate = 999932400000.0; // Testing a recent date
    571         Locale        loc("ja_JP@calendar=japanese");
    572 
    573         status = U_ZERO_ERROR;
    574         simpleTest(loc, expect, expectDate, status);
    575     }
    576     {
    577         UnicodeString expect = CharsToUnicodeString("\\u5e73\\u621013\\u5e749\\u67088\\u65e5\\u571f\\u66dc\\u65e5");
    578         UDate         expectDate = 999932400000.0; // Testing a recent date
    579         Locale        loc("ja_JP_TRADITIONAL"); // legacy
    580 
    581         status = U_ZERO_ERROR;
    582         simpleTest(loc, expect, expectDate, status);
    583     }
    584     {
    585         UnicodeString expect = CharsToUnicodeString("\\u5b89\\u6c385\\u5e747\\u67084\\u65e5\\u6728\\u66dc\\u65e5");
    586         UDate         expectDate = -6106032422000.0; // 1776-07-04T00:00:00Z-075258
    587         Locale        loc("ja_JP@calendar=japanese");
    588 
    589         status = U_ZERO_ERROR;
    590         simpleTest(loc, expect, expectDate, status);
    591 
    592     }
    593     {   // Jitterbug 1869 - this is an ambiguous era. (Showa 64 = Jan 6 1989, but Showa could be 2 other eras) )
    594         UnicodeString expect = CharsToUnicodeString("\\u662d\\u548c64\\u5e741\\u67086\\u65e5\\u91d1\\u66dc\\u65e5");
    595         UDate         expectDate = 600076800000.0;
    596         Locale        loc("ja_JP@calendar=japanese");
    597 
    598         status = U_ZERO_ERROR;
    599         simpleTest(loc, expect, expectDate, status);
    600 
    601     }
    602     {   // This Feb 29th falls on a leap year by gregorian year, but not by Japanese year.
    603         UnicodeString expect = CharsToUnicodeString("\\u5EB7\\u6B632\\u5e742\\u670829\\u65e5\\u65e5\\u66dc\\u65e5");
    604         UDate         expectDate =  -16214400422000.0;  // 1456-03-09T00:00Z-075258
    605         Locale        loc("ja_JP@calendar=japanese");
    606 
    607         status = U_ZERO_ERROR;
    608         simpleTest(loc, expect, expectDate, status);
    609 
    610     }
    611 }
    612 
    613 void IntlCalendarTest::TestJapanese3860()
    614 {
    615     Calendar *cal;
    616     UErrorCode status = U_ZERO_ERROR;
    617     cal = Calendar::createInstance("ja_JP@calendar=japanese", status);
    618     CHECK(status, UnicodeString("Creating ja_JP@calendar=japanese calendar"));
    619     Calendar *cal2 = cal->clone();
    620     SimpleDateFormat *fmt2 = new SimpleDateFormat(UnicodeString("HH:mm:ss.S MMMM d, yyyy G"), Locale("en_US@calendar=gregorian"), status);
    621     UnicodeString str;
    622 
    623 
    624     {
    625         // Test simple parse/format with adopt
    626         UDate aDate = 0;
    627 
    628         // Test parse with missing era (should default to current era, heisei)
    629         // Test parse with incomplete information
    630         logln("Testing parse w/ missing era...");
    631         SimpleDateFormat *fmt = new SimpleDateFormat(UnicodeString("y.M.d"), Locale("ja_JP@calendar=japanese"), status);
    632         CHECK(status, "creating date format instance");
    633         if(!fmt) {
    634             errln("Coudln't create en_US instance");
    635         } else {
    636             UErrorCode s2 = U_ZERO_ERROR;
    637             cal2->clear();
    638             UnicodeString samplestr("1.1.9");
    639             logln(UnicodeString() + "Test Year: " + samplestr);
    640             aDate = fmt->parse(samplestr, s2);
    641             ParsePosition pp=0;
    642             fmt->parse(samplestr, *cal2, pp);
    643             CHECK(s2, "parsing the 1.1.9 string");
    644             logln("*cal2 after 119 parse:");
    645             str.remove();
    646             fmt2->format(aDate, str);
    647             logln(UnicodeString() + "as Gregorian Calendar: " + str);
    648 
    649             cal2->setTime(aDate, s2);
    650             int32_t gotYear = cal2->get(UCAL_YEAR, s2);
    651             int32_t gotEra = cal2->get(UCAL_ERA, s2);
    652             int32_t expectYear = 1;
    653             int32_t expectEra = JapaneseCalendar::getCurrentEra();
    654             if((gotYear!=1) || (gotEra != expectEra)) {
    655                 errln(UnicodeString("parse "+samplestr+" of 'y.m.d' as Japanese Calendar, expected year ") + expectYear +
    656                     UnicodeString(" and era ") + expectEra +", but got year " + gotYear + " and era " + gotEra + " (Gregorian:" + str +")");
    657             } else {
    658                 logln(UnicodeString() + " year: " + gotYear + ", era: " + gotEra);
    659             }
    660             delete fmt;
    661         }
    662     }
    663 
    664     {
    665         // Test simple parse/format with adopt
    666         UDate aDate = 0;
    667 
    668         // Test parse with missing era (should default to current era, heisei)
    669         // Test parse with incomplete information
    670         logln("Testing parse w/ just year...");
    671         SimpleDateFormat *fmt = new SimpleDateFormat(UnicodeString("y"), Locale("ja_JP@calendar=japanese"), status);
    672         CHECK(status, "creating date format instance");
    673         if(!fmt) {
    674             errln("Coudln't create en_US instance");
    675         } else {
    676             UErrorCode s2 = U_ZERO_ERROR;
    677             cal2->clear();
    678             UnicodeString samplestr("1");
    679             logln(UnicodeString() + "Test Year: " + samplestr);
    680             aDate = fmt->parse(samplestr, s2);
    681             ParsePosition pp=0;
    682             fmt->parse(samplestr, *cal2, pp);
    683             CHECK(s2, "parsing the 1 string");
    684             logln("*cal2 after 1 parse:");
    685             str.remove();
    686             fmt2->format(aDate, str);
    687             logln(UnicodeString() + "as Gregorian Calendar: " + str);
    688 
    689             cal2->setTime(aDate, s2);
    690             int32_t gotYear = cal2->get(UCAL_YEAR, s2);
    691             int32_t gotEra = cal2->get(UCAL_ERA, s2);
    692             int32_t expectYear = 1;
    693             int32_t expectEra = 235; //JapaneseCalendar::kCurrentEra;
    694             if((gotYear!=1) || (gotEra != expectEra)) {
    695                 errln(UnicodeString("parse "+samplestr+" of 'y' as Japanese Calendar, expected year ") + expectYear +
    696                     UnicodeString(" and era ") + expectEra +", but got year " + gotYear + " and era " + gotEra + " (Gregorian:" + str +")");
    697             } else {
    698                 logln(UnicodeString() + " year: " + gotYear + ", era: " + gotEra);
    699             }
    700             delete fmt;
    701         }
    702     }
    703 
    704     delete cal2;
    705     delete cal;
    706     delete fmt2;
    707 }
    708 
    709 
    710 
    711 
    712 /**
    713  * Verify the Persian Calendar.
    714  */
    715 void IntlCalendarTest::TestPersian() {
    716     UDate timeA = Calendar::getNow();
    717 
    718     Calendar *cal;
    719     UErrorCode status = U_ZERO_ERROR;
    720     cal = Calendar::createInstance("fa_IR@calendar=persian", status);
    721     CHECK(status, UnicodeString("Creating fa_IR@calendar=persian calendar"));
    722     // Sanity check the calendar
    723     UDate timeB = Calendar::getNow();
    724     UDate timeCal = cal->getTime(status);
    725 
    726     if(!(timeA <= timeCal) || !(timeCal <= timeB)) {
    727       errln((UnicodeString)"Error: Calendar time " + timeCal +
    728             " is not within sampled times [" + timeA + " to " + timeB + "]!");
    729     }
    730     // end sanity check
    731 // quasiGregorianTest(*cal,Locale("ja_JP"),data);
    732     delete cal;
    733 }
    734 
    735 void IntlCalendarTest::TestPersianFormat() {
    736     UErrorCode status = U_ZERO_ERROR;
    737     SimpleDateFormat *fmt = new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"), Locale(" en_US@calendar=persian"), status);
    738     CHECK(status, "creating date format instance");
    739     SimpleDateFormat *fmt2 = new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"), Locale("en_US@calendar=gregorian"), status);
    740     CHECK(status, "creating gregorian date format instance");
    741     UnicodeString gregorianDate("January 18, 2007 AD");
    742     UDate aDate = fmt2->parse(gregorianDate, status);
    743     if(!fmt) {
    744         errln("Coudln't create en_US instance");
    745     } else {
    746         UnicodeString str;
    747         fmt->format(aDate, str);
    748         logln(UnicodeString() + "as Persian Calendar: " + escape(str));
    749         UnicodeString expected("Dey 28, 1385 AP");
    750         if(str != expected) {
    751             errln("Expected " + escape(expected) + " but got " + escape(str));
    752         }
    753         UDate otherDate = fmt->parse(expected, status);
    754         if(otherDate != aDate) {
    755             UnicodeString str3;
    756             fmt->format(otherDate, str3);
    757             errln("Parse incorrect of " + escape(expected) + " - wanted " + aDate + " but got " +  otherDate + ", " + escape(str3));
    758         } else {
    759             logln("Parsed OK: " + expected);
    760         }
    761         // Two digit year parsing problem #4732
    762         fmt->applyPattern("yy-MM-dd");
    763         str.remove();
    764         fmt->format(aDate, str);
    765         expected.setTo("85-10-28");
    766         if(str != expected) {
    767             errln("Expected " + escape(expected) + " but got " + escape(str));
    768         }
    769         otherDate = fmt->parse(expected, status);
    770         if (otherDate != aDate) {
    771             errln("Parse incorrect of " + escape(expected) + " - wanted " + aDate + " but got " + otherDate);
    772         } else {
    773             logln("Parsed OK: " + expected);
    774         }
    775         delete fmt;
    776     }
    777     delete fmt2;
    778 
    779     CHECK(status, "Error occured testing Persian Calendar in English ");
    780 }
    781 
    782 
    783 void IntlCalendarTest::simpleTest(const Locale& loc, const UnicodeString& expect, UDate expectDate, UErrorCode& status)
    784 {
    785     UnicodeString tmp;
    786     UDate         d;
    787     DateFormat *fmt0 = DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull);
    788 
    789     logln("Try format/parse of " + (UnicodeString)loc.getName());
    790     DateFormat *fmt2 = DateFormat::createDateInstance(DateFormat::kFull, loc);
    791     if(fmt2) {
    792         fmt2->format(expectDate, tmp);
    793         logln(escape(tmp) + " ( in locale " + loc.getName() + ")");
    794         if(tmp != expect) {
    795             errln(UnicodeString("Failed to format " ) + loc.getName() + " expected " + escape(expect) + " got " + escape(tmp) );
    796         }
    797 
    798         d = fmt2->parse(expect,status);
    799         CHECK(status, "Error occured parsing " + UnicodeString(loc.getName()));
    800         if(d != expectDate) {
    801             fmt2->format(d,tmp);
    802             errln(UnicodeString("Failed to parse " ) + escape(expect) + ", " + loc.getName() + " expect " + (double)expectDate + " got " + (double)d  + " " + escape(tmp));
    803             logln( "wanted " + escape(fmt0->format(expectDate,tmp.remove())) + " but got " + escape(fmt0->format(d,tmp.remove())));
    804         }
    805         delete fmt2;
    806     } else {
    807         errln((UnicodeString)"Can't create " + loc.getName() + " date instance");
    808     }
    809     delete fmt0;
    810 }
    811 
    812 #undef CHECK
    813 
    814 #endif /* #if !UCONFIG_NO_FORMATTING */
    815 
    816 //eof
    817