• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
escape(const UnicodeString & src)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 
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)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
TestTypes()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  */
quasiGregorianTest(Calendar & cal,const Locale & gcl,const int32_t * data)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
TestGregorian()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  */
TestBuddhist()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  */
TestTaiwan()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  */
TestJapanese()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 
TestBuddhistFormat()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 
TestJapaneseFormat()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 
TestJapanese3860()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  */
TestPersian()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 
TestPersianFormat()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 
simpleTest(const Locale & loc,const UnicodeString & expect,UDate expectDate,UErrorCode & status)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