1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /***********************************************************************
5 * Copyright (c) 1997-2014, International Business Machines Corporation
6 * and others. All Rights Reserved.
7 ***********************************************************************/
9 /* Test Internationalized Calendars for C++ */
11 #include "unicode/utypes.h"
13 #include "unicode/locid.h"
15 #include "unicode/localpointer.h"
16 #include "unicode/datefmt.h"
17 #include "unicode/smpdtfmt.h"
18 #include "unicode/dtptngen.h"
20 #if !UCONFIG_NO_FORMATTING
25 #define CHECK(status, msg) \
26 if (U_FAILURE(status)) { \
27 dataerrln((UnicodeString(u_errorName(status)) + UnicodeString(" : " ) )+ msg); \
32 static UnicodeString
escape( const UnicodeString
&src
)
36 for (int32_t i
= 0; i
< src
.length(); ++i
) {
41 dst
+= UnicodeString("[");
43 sprintf(buf
, "%#x", c
);
44 dst
+= UnicodeString(buf
);
45 dst
+= UnicodeString("]");
54 #include "unicode/gregocal.h"
55 #include "unicode/smpdtfmt.h"
56 #include "unicode/simpletz.h"
58 // *****************************************************************************
59 // class IntlCalendarTest
60 // *****************************************************************************
61 //--- move to CalendarTest?
63 // Turn this on to dump the calendar fields
64 #define U_DEBUG_DUMPCALS
67 #define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); logln((UnicodeString)""); test(); } break
70 void IntlCalendarTest::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char* /*par*/ )
72 if (exec
) logln("TestSuite IntlCalendarTest");
75 CASE(1,TestGregorian
);
78 CASE(4,TestBuddhistFormat
);
79 CASE(5,TestJapaneseFormat
);
80 CASE(6,TestJapanese3860
);
81 CASE(7,TestForceGannenNumbering
);
83 CASE(9,TestPersianFormat
);
85 default: name
= ""; break;
91 // ---------------------------------------------------------------------------------
95 * Test various API methods for API completeness.
98 IntlCalendarTest::TestTypes()
101 UErrorCode status
= U_ZERO_ERROR
;
103 const char *locs
[40] = { "en_US_VALLEYGIRL",
104 "en_US_VALLEYGIRL@collation=phonebook;calendar=japanese",
105 "en_US_VALLEYGIRL@collation=phonebook;calendar=gregorian",
106 "ja_JP@calendar=japanese",
107 "th_TH@calendar=buddhist",
109 "th_TH_TRADITIONAL@calendar=gregorian",
111 "th_TH", // Default calendar for th_TH is buddhist
112 "th", // th's default region is TH and buddhist is used as default for TH
113 "en_TH", // Default calendar for any locales with region TH is buddhist
114 "en-TH-u-ca-gregory",
116 const char *types
[40] = { "gregorian",
130 for(j
=0;locs
[j
];j
++) {
131 logln(UnicodeString("Creating calendar of locale ") + locs
[j
]);
132 status
= U_ZERO_ERROR
;
133 c
= Calendar::createInstance(locs
[j
], status
);
134 CHECK(status
, "creating '" + UnicodeString(locs
[j
]) + "' calendar");
135 if(U_SUCCESS(status
)) {
136 logln(UnicodeString(" type is ") + c
->getType());
137 if(strcmp(c
->getType(), types
[j
])) {
138 dataerrln(UnicodeString(locs
[j
]) + UnicodeString("Calendar type ") + c
->getType() + " instead of " + types
[j
]);
148 * Run a test of a quasi-Gregorian calendar. This is a calendar
149 * that behaves like a Gregorian but has different year/era mappings.
150 * The int[] data array should have the format:
152 * { era, year, gregorianYear, month, dayOfMonth, ... ... , -1 }
154 void IntlCalendarTest::quasiGregorianTest(Calendar
& cal
, const Locale
& gcl
, const int32_t *data
) {
155 UErrorCode status
= U_ZERO_ERROR
;
156 // As of JDK 1.4.1_01, using the Sun JDK GregorianCalendar as
157 // a reference throws us off by one hour. This is most likely
158 // due to the JDK 1.4 incorporation of historical time zones.
159 //java.util.Calendar grego = java.util.Calendar.getInstance();
160 Calendar
*grego
= Calendar::createInstance(gcl
, status
);
161 if (U_FAILURE(status
)) {
162 dataerrln("Error calling Calendar::createInstance");
166 int32_t tz1
= cal
.get(UCAL_ZONE_OFFSET
,status
);
167 int32_t tz2
= grego
-> get (UCAL_ZONE_OFFSET
, status
);
169 errln((UnicodeString
)"cal's tz " + tz1
+ " != grego's tz " + tz2
);
172 for (int32_t i
=0; data
[i
]!=-1; ) {
173 int32_t era
= data
[i
++];
174 int32_t year
= data
[i
++];
175 int32_t gregorianYear
= data
[i
++];
176 int32_t month
= data
[i
++];
177 int32_t dayOfMonth
= data
[i
++];
180 grego
->set(gregorianYear
, month
, dayOfMonth
);
181 UDate D
= grego
->getTime(status
);
184 cal
.set(UCAL_ERA
, era
);
185 cal
.set(year
, month
, dayOfMonth
);
186 UDate d
= cal
.getTime(status
);
187 #ifdef U_DEBUG_DUMPCALS
188 logln((UnicodeString
)"cal : " + CalendarTest::calToStr(cal
));
189 logln((UnicodeString
)"grego: " + CalendarTest::calToStr(*grego
));
192 logln(UnicodeString("OK: ") + era
+ ":" + year
+ "/" + (month
+1) + "/" + dayOfMonth
+
193 " => " + d
+ " (" + UnicodeString(cal
.getType()) + ")");
195 errln(UnicodeString("Fail: (fields to millis)") + era
+ ":" + year
+ "/" + (month
+1) + "/" + dayOfMonth
+
196 " => " + d
+ ", expected " + D
+ " (" + UnicodeString(cal
.getType()) + "Off by: " + (d
-D
));
199 // Now, set the gregorian millis on the other calendar
201 cal
.setTime(D
, status
);
202 int e
= cal
.get(UCAL_ERA
, status
);
203 int y
= cal
.get(UCAL_YEAR
, status
);
204 #ifdef U_DEBUG_DUMPCALS
205 logln((UnicodeString
)"cal : " + CalendarTest::calToStr(cal
));
206 logln((UnicodeString
)"grego: " + CalendarTest::calToStr(*grego
));
208 if (y
== year
&& e
== era
) {
209 logln((UnicodeString
)"OK: " + D
+ " => " + cal
.get(UCAL_ERA
, status
) + ":" +
210 cal
.get(UCAL_YEAR
, status
) + "/" +
211 (cal
.get(UCAL_MONTH
, status
)+1) + "/" + cal
.get(UCAL_DATE
, status
) + " (" + UnicodeString(cal
.getType()) + ")");
213 errln((UnicodeString
)"Fail: (millis to fields)" + D
+ " => " + cal
.get(UCAL_ERA
, status
) + ":" +
214 cal
.get(UCAL_YEAR
, status
) + "/" +
215 (cal
.get(UCAL_MONTH
, status
)+1) + "/" + cal
.get(UCAL_DATE
, status
) +
216 ", expected " + era
+ ":" + year
+ "/" + (month
+1) + "/" +
217 dayOfMonth
+ " (" + UnicodeString(cal
.getType()));
221 CHECK(status
, "err during quasiGregorianTest()");
224 // Verify that Gregorian works like Gregorian
225 void IntlCalendarTest::TestGregorian() {
226 UDate timeA
= Calendar::getNow();
228 GregorianCalendar::AD
, 1868, 1868, UCAL_SEPTEMBER
, 8,
229 GregorianCalendar::AD
, 1868, 1868, UCAL_SEPTEMBER
, 9,
230 GregorianCalendar::AD
, 1869, 1869, UCAL_JUNE
, 4,
231 GregorianCalendar::AD
, 1912, 1912, UCAL_JULY
, 29,
232 GregorianCalendar::AD
, 1912, 1912, UCAL_JULY
, 30,
233 GregorianCalendar::AD
, 1912, 1912, UCAL_AUGUST
, 1,
234 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
238 UErrorCode status
= U_ZERO_ERROR
;
239 cal
= Calendar::createInstance(/*"de_DE", */ status
);
240 CHECK(status
, UnicodeString("Creating de_CH calendar"));
241 // Sanity check the calendar
242 UDate timeB
= Calendar::getNow();
243 UDate timeCal
= cal
->getTime(status
);
245 if(!(timeA
<= timeCal
) || !(timeCal
<= timeB
)) {
246 errln((UnicodeString
)"Error: Calendar time " + timeCal
+
247 " is not within sampled times [" + timeA
+ " to " + timeB
+ "]!");
251 // Note, the following is a good way to test the sanity of the constructed calendars,
252 // using Collation as a delay-loop:
254 // $ intltest format/IntlCalendarTest collate/G7CollationTest format/IntlCalendarTest
256 quasiGregorianTest(*cal
,Locale("fr_FR"),data
);
261 * Verify that BuddhistCalendar shifts years to Buddhist Era but otherwise
262 * behaves like GregorianCalendar.
264 void IntlCalendarTest::TestBuddhist() {
265 // BE 2542 == 1999 CE
266 UDate timeA
= Calendar::getNow();
269 0, // B. era [928479600000]
275 0, // B. era [-79204842000000]
278 UCAL_FEBRUARY
, // month
281 0, // test month calculation: 4795 BE = 4252 AD is a leap year, but 4795 AD is not.
282 4795, // BE [72018057600000]
287 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1
290 UErrorCode status
= U_ZERO_ERROR
;
291 cal
= Calendar::createInstance("th_TH@calendar=buddhist", status
);
292 CHECK(status
, UnicodeString("Creating th_TH@calendar=buddhist calendar"));
294 // Sanity check the calendar
295 UDate timeB
= Calendar::getNow();
296 UDate timeCal
= cal
->getTime(status
);
298 if(!(timeA
<= timeCal
) || !(timeCal
<= timeB
)) {
299 errln((UnicodeString
)"Error: Calendar time " + timeCal
+
300 " is not within sampled times [" + timeA
+ " to " + timeB
+ "]!");
305 quasiGregorianTest(*cal
,Locale("th_TH@calendar=gregorian"),data
);
311 * Verify that TaiWanCalendar shifts years to Minguo Era but otherwise
312 * behaves like GregorianCalendar.
314 void IntlCalendarTest::TestTaiwan() {
316 UDate timeA
= Calendar::getNow();
318 // TODO port these to the data items
320 1, // B. era [928479600000]
326 1, // B. era [-79204842000000]
329 UCAL_FEBRUARY
, // month
332 1, // B. era [-79204842000000]
335 UCAL_FEBRUARY
, // month
338 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1
341 UErrorCode status
= U_ZERO_ERROR
;
342 cal
= Calendar::createInstance("en_US@calendar=roc", status
);
343 CHECK(status
, UnicodeString("Creating en_US@calendar=roc calendar"));
345 // Sanity check the calendar
346 UDate timeB
= Calendar::getNow();
347 UDate timeCal
= cal
->getTime(status
);
349 if(!(timeA
<= timeCal
) || !(timeCal
<= timeB
)) {
350 errln((UnicodeString
)"Error: Calendar time " + timeCal
+
351 " is not within sampled times [" + timeA
+ " to " + timeB
+ "]!");
356 quasiGregorianTest(*cal
,Locale("en_US"),data
);
363 * Verify that JapaneseCalendar shifts years to Japanese Eras but otherwise
364 * behaves like GregorianCalendar.
366 void IntlCalendarTest::TestJapanese() {
367 UDate timeA
= Calendar::getNow();
369 /* Sorry.. japancal.h is private! */
370 #define JapaneseCalendar_MEIJI 232
371 #define JapaneseCalendar_TAISHO 233
372 #define JapaneseCalendar_SHOWA 234
373 #define JapaneseCalendar_HEISEI 235
375 // BE 2542 == 1999 CE
377 // Jera Jyr Gyear m d
378 JapaneseCalendar_MEIJI
, 1, 1868, UCAL_SEPTEMBER
, 8,
379 JapaneseCalendar_MEIJI
, 1, 1868, UCAL_SEPTEMBER
, 9,
380 JapaneseCalendar_MEIJI
, 2, 1869, UCAL_JUNE
, 4,
381 JapaneseCalendar_MEIJI
, 45, 1912, UCAL_JULY
, 29,
382 JapaneseCalendar_TAISHO
, 1, 1912, UCAL_JULY
, 30,
383 JapaneseCalendar_TAISHO
, 1, 1912, UCAL_AUGUST
, 1,
385 // new tests (not in java)
386 JapaneseCalendar_SHOWA
, 64, 1989, UCAL_JANUARY
, 7, // Test current era transition (different code path than others)
387 JapaneseCalendar_HEISEI
, 1, 1989, UCAL_JANUARY
, 8,
388 JapaneseCalendar_HEISEI
, 1, 1989, UCAL_JANUARY
, 9,
389 JapaneseCalendar_HEISEI
, 1, 1989, UCAL_DECEMBER
, 20,
390 JapaneseCalendar_HEISEI
, 15, 2003, UCAL_MAY
, 22,
391 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1
395 UErrorCode status
= U_ZERO_ERROR
;
396 cal
= Calendar::createInstance("ja_JP@calendar=japanese", status
);
397 CHECK(status
, UnicodeString("Creating ja_JP@calendar=japanese calendar"));
398 // Sanity check the calendar
399 UDate timeB
= Calendar::getNow();
400 UDate timeCal
= cal
->getTime(status
);
402 if(!(timeA
<= timeCal
) || !(timeCal
<= timeB
)) {
403 errln((UnicodeString
)"Error: Calendar time " + timeCal
+
404 " is not within sampled times [" + timeA
+ " to " + timeB
+ "]!");
407 quasiGregorianTest(*cal
,Locale("ja_JP"),data
);
413 void IntlCalendarTest::TestBuddhistFormat() {
414 UErrorCode status
= U_ZERO_ERROR
;
416 // Test simple parse/format with adopt
418 // First, a contrived English test..
419 UDate aDate
= 999932400000.0;
420 SimpleDateFormat
*fmt
= new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"), Locale("en_US@calendar=buddhist"), status
);
421 CHECK(status
, "creating date format instance");
422 SimpleDateFormat
*fmt2
= new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"), Locale("en_US@calendar=gregorian"), status
);
423 CHECK(status
, "creating gregorian date format instance");
425 errln("Couldn't create en_US instance");
428 fmt2
->format(aDate
, str
);
429 logln(UnicodeString() + "Test Date: " + str
);
431 fmt
->format(aDate
, str
);
432 logln(UnicodeString() + "as Buddhist Calendar: " + escape(str
));
433 UnicodeString
expected("September 8, 2544 BE");
434 if(str
!= expected
) {
435 errln("Expected " + escape(expected
) + " but got " + escape(str
));
437 UDate otherDate
= fmt
->parse(expected
, status
);
438 if(otherDate
!= aDate
) {
440 fmt
->format(otherDate
, str3
);
441 errln("Parse incorrect of " + escape(expected
) + " - wanted " + aDate
+ " but got " + otherDate
+ ", " + escape(str3
));
443 logln("Parsed OK: " + expected
);
449 CHECK(status
, "Error occurred testing Buddhist Calendar in English ");
451 status
= U_ZERO_ERROR
;
454 UnicodeString expect
= CharsToUnicodeString("\\u0E27\\u0E31\\u0E19\\u0E40\\u0E2A\\u0E32\\u0E23\\u0E4C\\u0E17\\u0E35\\u0E48"
455 " 8 \\u0E01\\u0E31\\u0e19\\u0e22\\u0e32\\u0e22\\u0e19 \\u0e1e.\\u0e28. 2544");
456 UDate expectDate
= 999932400000.0;
457 Locale
loc("th_TH_TRADITIONAL"); // legacy
459 simpleTest(loc
, expect
, expectDate
, status
);
461 status
= U_ZERO_ERROR
;
463 UnicodeString expect
= CharsToUnicodeString("\\u0E27\\u0E31\\u0E19\\u0E40\\u0E2A\\u0E32\\u0E23\\u0E4C\\u0E17\\u0E35\\u0E48"
464 " 8 \\u0E01\\u0E31\\u0e19\\u0e22\\u0e32\\u0e22\\u0e19 \\u0e1e.\\u0e28. 2544");
465 UDate expectDate
= 999932400000.0;
466 Locale
loc("th_TH@calendar=buddhist");
468 simpleTest(loc
, expect
, expectDate
, status
);
470 status
= U_ZERO_ERROR
;
472 UnicodeString expect
= CharsToUnicodeString("\\u0E27\\u0E31\\u0E19\\u0E40\\u0E2A\\u0E32\\u0E23\\u0E4C\\u0E17\\u0E35\\u0E48"
473 " 8 \\u0E01\\u0E31\\u0e19\\u0e22\\u0e32\\u0e22\\u0e19 \\u0e04.\\u0e28. 2001");
474 UDate expectDate
= 999932400000.0;
475 Locale
loc("th_TH@calendar=gregorian");
477 simpleTest(loc
, expect
, expectDate
, status
);
479 status
= U_ZERO_ERROR
;
481 UnicodeString expect
= CharsToUnicodeString("\\u0E27\\u0E31\\u0E19\\u0E40\\u0E2A\\u0E32\\u0E23\\u0E4C\\u0E17\\u0E35\\u0E48"
482 " 8 \\u0E01\\u0E31\\u0e19\\u0e22\\u0e32\\u0e22\\u0e19 \\u0e04.\\u0e28. 2001");
483 UDate expectDate
= 999932400000.0;
484 Locale
loc("th_TH_TRADITIONAL@calendar=gregorian");
486 simpleTest(loc
, expect
, expectDate
, status
);
490 // TaiwanFormat has been moved to testdata/format.txt
493 void IntlCalendarTest::TestJapaneseFormat() {
495 UErrorCode status
= U_ZERO_ERROR
;
496 cal
= Calendar::createInstance("ja_JP@calendar=japanese", status
);
497 CHECK(status
, UnicodeString("Creating ja_JP@calendar=japanese calendar"));
499 Calendar
*cal2
= cal
->clone();
503 // Test simple parse/format with adopt
505 UDate aDate
= 999932400000.0;
506 SimpleDateFormat
*fmt
= new SimpleDateFormat(UnicodeString("MMMM d, yy G"), Locale("en_US@calendar=japanese"), status
);
507 SimpleDateFormat
*fmt2
= new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"), Locale("en_US@calendar=gregorian"), status
);
508 CHECK(status
, "creating date format instance");
510 errln("Couldn't create en_US instance");
513 fmt2
->format(aDate
, str
);
514 logln(UnicodeString() + "Test Date: " + str
);
516 fmt
->format(aDate
, str
);
517 logln(UnicodeString() + "as Japanese Calendar: " + str
);
518 UnicodeString
expected("September 8, 13 Heisei");
519 if(str
!= expected
) {
520 errln("Expected " + expected
+ " but got " + str
);
522 UDate otherDate
= fmt
->parse(expected
, status
);
523 if(otherDate
!= aDate
) {
526 fmt
->parse(expected
, *cal2
, pp
);
527 fmt
->format(otherDate
, str3
);
528 errln("Parse incorrect of " + expected
+ " - wanted " + aDate
+ " but got " + " = " + otherDate
+ ", " + str3
+ " = " + CalendarTest::calToStr(*cal2
) );
531 logln("Parsed OK: " + expected
);
536 // Test parse with incomplete information
537 fmt
= new SimpleDateFormat(UnicodeString("G y"), Locale("en_US@calendar=japanese"), status
);
538 aDate
= -3197117222000.0;
539 CHECK(status
, "creating date format instance");
541 errln("Coudln't create en_US instance");
544 fmt2
->format(aDate
, str
);
545 logln(UnicodeString() + "Test Date: " + str
);
547 fmt
->format(aDate
, str
);
548 logln(UnicodeString() + "as Japanese Calendar: " + str
);
549 UnicodeString
expected("Meiji 1");
550 if(str
!= expected
) {
551 errln("Expected " + expected
+ " but got " + str
);
553 UDate otherDate
= fmt
->parse(expected
, status
);
554 if(otherDate
!= aDate
) {
557 fmt
->parse(expected
, *cal2
, pp
);
558 fmt
->format(otherDate
, str3
);
559 errln("Parse incorrect of " + expected
+ " - wanted " + aDate
+ " but got " + " = " +
560 otherDate
+ ", " + str3
+ " = " + CalendarTest::calToStr(*cal2
) );
562 logln("Parsed OK: " + expected
);
569 CHECK(status
, "Error occurred");
571 // Now, try in Japanese
573 UnicodeString expect
= CharsToUnicodeString("\\u5e73\\u621013\\u5e749\\u67088\\u65e5 \\u571f\\u66dc\\u65e5");
574 UDate expectDate
= 999932400000.0; // Testing a recent date
575 Locale
loc("ja_JP@calendar=japanese");
577 status
= U_ZERO_ERROR
;
578 simpleTest(loc
, expect
, expectDate
, status
);
581 UnicodeString expect
= CharsToUnicodeString("\\u5e73\\u621013\\u5e749\\u67088\\u65e5 \\u571f\\u66dc\\u65e5");
582 UDate expectDate
= 999932400000.0; // Testing a recent date
583 Locale
loc("ja_JP@calendar=japanese");
585 status
= U_ZERO_ERROR
;
586 simpleTest(loc
, expect
, expectDate
, status
);
589 UnicodeString expect
= CharsToUnicodeString("\\u5b89\\u6c385\\u5e747\\u67084\\u65e5 \\u6728\\u66dc\\u65e5");
590 UDate expectDate
= -6106032422000.0; // 1776-07-04T00:00:00Z-075258
591 Locale
loc("ja_JP@calendar=japanese");
593 status
= U_ZERO_ERROR
;
594 simpleTest(loc
, expect
, expectDate
, status
);
597 { // Jitterbug 1869 - this is an ambiguous era. (Showa 64 = Jan 6 1989, but Showa could be 2 other eras) )
598 UnicodeString expect
= CharsToUnicodeString("\\u662d\\u548c64\\u5e741\\u67086\\u65e5 \\u91d1\\u66dc\\u65e5");
599 UDate expectDate
= 600076800000.0;
600 Locale
loc("ja_JP@calendar=japanese");
602 status
= U_ZERO_ERROR
;
603 simpleTest(loc
, expect
, expectDate
, status
);
606 { // 1989 Jan 9 Monday = Heisei 1; full is Gy年M月d日EEEE => 平成元年1月9日月曜日
607 UnicodeString expect
= CharsToUnicodeString("\\u5E73\\u6210\\u5143\\u5E741\\u67089\\u65E5 \\u6708\\u66DC\\u65E5");
608 UDate expectDate
= 600336000000.0;
609 Locale
loc("ja_JP@calendar=japanese");
611 status
= U_ZERO_ERROR
;
612 simpleTest(loc
, expect
, expectDate
, status
);
615 { // This Feb 29th falls on a leap year by gregorian year, but not by Japanese year.
616 UnicodeString expect
= CharsToUnicodeString("\\u5EB7\\u6B632\\u5e742\\u670829\\u65e5 \\u65e5\\u66dc\\u65e5");
617 UDate expectDate
= -16214400422000.0; // 1456-03-09T00:00Z-075258
618 Locale
loc("ja_JP@calendar=japanese");
620 status
= U_ZERO_ERROR
;
621 simpleTest(loc
, expect
, expectDate
, status
);
626 void IntlCalendarTest::TestJapanese3860()
629 UErrorCode status
= U_ZERO_ERROR
;
630 cal
= Calendar::createInstance("ja_JP@calendar=japanese", status
);
631 CHECK(status
, UnicodeString("Creating ja_JP@calendar=japanese calendar"));
632 Calendar
*cal2
= cal
->clone();
633 SimpleDateFormat
*fmt2
= new SimpleDateFormat(UnicodeString("HH:mm:ss.S MMMM d, yyyy G"), Locale("en_US@calendar=gregorian"), status
);
638 // Test simple parse/format with adopt
641 // Test parse with missing era (should default to current era, heisei)
642 // Test parse with incomplete information
643 logln("Testing parse w/ missing era...");
644 SimpleDateFormat
*fmt
= new SimpleDateFormat(UnicodeString("y/M/d"), Locale("ja_JP@calendar=japanese"), status
);
645 CHECK(status
, "creating date format instance");
647 errln("Couldn't create en_US instance");
649 UErrorCode s2
= U_ZERO_ERROR
;
651 UnicodeString
samplestr("1/5/9");
652 logln(UnicodeString() + "Test Year: " + samplestr
);
653 aDate
= fmt
->parse(samplestr
, s2
);
655 fmt
->parse(samplestr
, *cal2
, pp
);
656 CHECK(s2
, "parsing the 1/5/9 string");
657 logln("*cal2 after 159 parse:");
659 fmt2
->format(aDate
, str
);
660 logln(UnicodeString() + "as Gregorian Calendar: " + str
);
662 cal2
->setTime(aDate
, s2
);
663 int32_t gotYear
= cal2
->get(UCAL_YEAR
, s2
);
664 int32_t gotEra
= cal2
->get(UCAL_ERA
, s2
);
665 int32_t expectYear
= 1;
666 int32_t expectEra
= JapaneseCalendar::getCurrentEra();
667 if((gotYear
!=1) || (gotEra
!= expectEra
)) {
668 errln(UnicodeString("parse "+samplestr
+" of 'y/M/d' as Japanese Calendar, expected year ") + expectYear
+
669 UnicodeString(" and era ") + expectEra
+", but got year " + gotYear
+ " and era " + gotEra
+ " (Gregorian:" + str
+")");
671 logln(UnicodeString() + " year: " + gotYear
+ ", era: " + gotEra
);
678 // Test simple parse/format with adopt
681 // Test parse with missing era (should default to current era, heisei)
682 // Test parse with incomplete information
683 logln("Testing parse w/ just year...");
684 SimpleDateFormat
*fmt
= new SimpleDateFormat(UnicodeString("y"), Locale("ja_JP@calendar=japanese"), status
);
685 CHECK(status
, "creating date format instance");
687 errln("Couldn't create en_US instance");
689 UErrorCode s2
= U_ZERO_ERROR
;
691 UnicodeString
samplestr("1");
692 logln(UnicodeString() + "Test Year: " + samplestr
);
693 aDate
= fmt
->parse(samplestr
, s2
);
695 fmt
->parse(samplestr
, *cal2
, pp
);
696 CHECK(s2
, "parsing the 1 string");
697 logln("*cal2 after 1 parse:");
699 fmt2
->format(aDate
, str
);
700 logln(UnicodeString() + "as Gregorian Calendar: " + str
);
702 cal2
->setTime(aDate
, s2
);
703 int32_t gotYear
= cal2
->get(UCAL_YEAR
, s2
);
704 int32_t gotEra
= cal2
->get(UCAL_ERA
, s2
);
705 int32_t expectYear
= 1;
706 int32_t expectEra
= JapaneseCalendar::getCurrentEra();
707 if((gotYear
!=1) || (gotEra
!= expectEra
)) {
708 errln(UnicodeString("parse "+samplestr
+" of 'y' as Japanese Calendar, expected year ") + expectYear
+
709 UnicodeString(" and era ") + expectEra
+", but got year " + gotYear
+ " and era " + gotEra
+ " (Gregorian:" + str
+")");
711 logln(UnicodeString() + " year: " + gotYear
+ ", era: " + gotEra
);
722 void IntlCalendarTest::TestForceGannenNumbering()
725 const char* locID
= "ja_JP@calendar=japanese";
727 UDate refDate
= 600336000000.0; // 1989 Jan 9 Monday = Heisei 1
728 UnicodeString
patText(u
"Gy年M月d日",-1);
729 UnicodeString
patNumr(u
"GGGGGy/MM/dd",-1);
730 UnicodeString
skelText(u
"yMMMM",-1);
732 // Test Gannen year forcing
733 status
= U_ZERO_ERROR
;
734 LocalPointer
<SimpleDateFormat
> testFmt1(new SimpleDateFormat(patText
, loc
, status
));
735 LocalPointer
<SimpleDateFormat
> testFmt2(new SimpleDateFormat(patNumr
, loc
, status
));
736 if (U_FAILURE(status
)) {
737 dataerrln("Fail in new SimpleDateFormat locale %s: %s", locID
, u_errorName(status
));
739 UnicodeString testString1
, testString2
;
740 testString1
= testFmt1
->format(refDate
, testString1
);
741 if (testString1
.length() < 3 || testString1
.charAt(2) != 0x5143) {
742 errln(UnicodeString("Formatting year 1 in created text style, got " + testString1
+ " but expected 3rd char to be 0x5143"));
744 testString2
= testFmt2
->format(refDate
, testString2
);
745 if (testString2
.length() < 2 || testString2
.charAt(1) != 0x0031) {
746 errln(UnicodeString("Formatting year 1 in created numeric style, got " + testString2
+ " but expected 2nd char to be 1"));
748 // Now switch the patterns and verify that Gannen use follows the pattern
749 testFmt1
->applyPattern(patNumr
);
750 testString1
.remove();
751 testString1
= testFmt1
->format(refDate
, testString1
);
752 if (testString1
.length() < 2 || testString1
.charAt(1) != 0x0031) {
753 errln(UnicodeString("Formatting year 1 in applied numeric style, got " + testString1
+ " but expected 2nd char to be 1"));
755 testFmt2
->applyPattern(patText
);
756 testString2
.remove();
757 testString2
= testFmt2
->format(refDate
, testString2
);
758 if (testString2
.length() < 3 || testString2
.charAt(2) != 0x5143) {
759 errln(UnicodeString("Formatting year 1 in applied text style, got " + testString2
+ " but expected 3rd char to be 0x5143"));
763 // Test disabling of Gannen year forcing
764 status
= U_ZERO_ERROR
;
765 LocalPointer
<DateTimePatternGenerator
> dtpgen(DateTimePatternGenerator::createInstance(loc
, status
));
766 if (U_FAILURE(status
)) {
767 dataerrln("Fail in DateTimePatternGenerator::createInstance locale %s: %s", locID
, u_errorName(status
));
769 UnicodeString pattern
= dtpgen
->getBestPattern(skelText
, status
);
770 if (U_FAILURE(status
)) {
771 dataerrln("Fail in DateTimePatternGenerator::getBestPattern locale %s: %s", locID
, u_errorName(status
));
773 // Use override string of ""
774 LocalPointer
<SimpleDateFormat
> testFmt3(new SimpleDateFormat(pattern
, UnicodeString(""), loc
, status
));
775 if (U_FAILURE(status
)) {
776 dataerrln("Fail in new SimpleDateFormat locale %s: %s", locID
, u_errorName(status
));
778 UnicodeString testString3
;
779 testString3
= testFmt3
->format(refDate
, testString3
);
780 if (testString3
.length() < 3 || testString3
.charAt(2) != 0x0031) {
781 errln(UnicodeString("Formatting year 1 with Gannen disabled, got " + testString3
+ " but expected 3rd char to be 1"));
789 * Verify the Persian Calendar.
791 void IntlCalendarTest::TestPersian() {
792 UDate timeA
= Calendar::getNow();
795 UErrorCode status
= U_ZERO_ERROR
;
796 cal
= Calendar::createInstance("fa_IR@calendar=persian", status
);
797 CHECK(status
, UnicodeString("Creating fa_IR@calendar=persian calendar"));
798 // Sanity check the calendar
799 UDate timeB
= Calendar::getNow();
800 UDate timeCal
= cal
->getTime(status
);
802 if(!(timeA
<= timeCal
) || !(timeCal
<= timeB
)) {
803 errln((UnicodeString
)"Error: Calendar time " + timeCal
+
804 " is not within sampled times [" + timeA
+ " to " + timeB
+ "]!");
808 // Test various dates to be sure of validity
810 1925, 4, 24, 1304, 2, 4,
811 2011, 1, 11, 1389, 10, 21,
812 1986, 2, 25, 1364, 12, 6,
813 1934, 3, 14, 1312, 12, 23,
815 2090, 3, 19, 1468, 12, 29,
816 2007, 2, 22, 1385, 12, 3,
817 1969, 12, 31, 1348, 10, 10,
818 1945, 11, 12, 1324, 8, 21,
819 1925, 3, 31, 1304, 1, 11,
821 1996, 3, 19, 1374, 12, 29,
822 1996, 3, 20, 1375, 1, 1,
823 1997, 3, 20, 1375, 12, 30,
824 1997, 3, 21, 1376, 1, 1,
826 2008, 3, 19, 1386, 12, 29,
827 2008, 3, 20, 1387, 1, 1,
828 2004, 3, 19, 1382, 12, 29,
829 2004, 3, 20, 1383, 1, 1,
831 2006, 3, 20, 1384, 12, 29,
832 2006, 3, 21, 1385, 1, 1,
834 2005, 4, 20, 1384, 1, 31,
835 2005, 4, 21, 1384, 2, 1,
836 2005, 5, 21, 1384, 2, 31,
837 2005, 5, 22, 1384, 3, 1,
838 2005, 6, 21, 1384, 3, 31,
839 2005, 6, 22, 1384, 4, 1,
840 2005, 7, 22, 1384, 4, 31,
841 2005, 7, 23, 1384, 5, 1,
842 2005, 8, 22, 1384, 5, 31,
843 2005, 8, 23, 1384, 6, 1,
844 2005, 9, 22, 1384, 6, 31,
845 2005, 9, 23, 1384, 7, 1,
846 2005, 10, 22, 1384, 7, 30,
847 2005, 10, 23, 1384, 8, 1,
848 2005, 11, 21, 1384, 8, 30,
849 2005, 11, 22, 1384, 9, 1,
850 2005, 12, 21, 1384, 9, 30,
851 2005, 12, 22, 1384, 10, 1,
852 2006, 1, 20, 1384, 10, 30,
853 2006, 1, 21, 1384, 11, 1,
854 2006, 2, 19, 1384, 11, 30,
855 2006, 2, 20, 1384, 12, 1,
856 2006, 3, 20, 1384, 12, 29,
857 2006, 3, 21, 1385, 1, 1,
859 // The 2820-year cycle arithmetical algorithm would fail this one.
860 2025, 3, 21, 1404, 1, 1,
862 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1
865 Calendar
*grego
= Calendar::createInstance("fa_IR@calendar=gregorian", status
);
866 for (int32_t i
=0; data
[i
]!=-1; ) {
867 int32_t gregYear
= data
[i
++];
868 int32_t gregMonth
= data
[i
++]-1;
869 int32_t gregDay
= data
[i
++];
870 int32_t persYear
= data
[i
++];
871 int32_t persMonth
= data
[i
++]-1;
872 int32_t persDay
= data
[i
++];
874 // Test conversion from Persian dates
876 grego
->set(gregYear
, gregMonth
, gregDay
);
879 cal
->set(persYear
, persMonth
, persDay
);
881 UDate persTime
= cal
->getTime(status
);
882 UDate gregTime
= grego
->getTime(status
);
884 if (persTime
!= gregTime
) {
885 errln(UnicodeString("Expected ") + gregTime
+ " but got " + persTime
);
888 // Test conversion to Persian dates
890 cal
->setTime(gregTime
, status
);
892 int32_t computedYear
= cal
->get(UCAL_YEAR
, status
);
893 int32_t computedMonth
= cal
->get(UCAL_MONTH
, status
);
894 int32_t computedDay
= cal
->get(UCAL_DATE
, status
);
896 if ((persYear
!= computedYear
) ||
897 (persMonth
!= computedMonth
) ||
898 (persDay
!= computedDay
)) {
899 errln(UnicodeString("Expected ") + persYear
+ "/" + (persMonth
+1) + "/" + persDay
+
900 " but got " + computedYear
+ "/" + (computedMonth
+1) + "/" + computedDay
);
909 void IntlCalendarTest::TestPersianFormat() {
910 UErrorCode status
= U_ZERO_ERROR
;
911 SimpleDateFormat
*fmt
= new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"), Locale(" en_US@calendar=persian"), status
);
912 CHECK(status
, "creating date format instance");
913 SimpleDateFormat
*fmt2
= new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"), Locale("en_US@calendar=gregorian"), status
);
914 CHECK(status
, "creating gregorian date format instance");
915 UnicodeString
gregorianDate("January 18, 2007 AD");
916 UDate aDate
= fmt2
->parse(gregorianDate
, status
);
918 errln("Couldn't create en_US instance");
921 fmt
->format(aDate
, str
);
922 logln(UnicodeString() + "as Persian Calendar: " + escape(str
));
923 UnicodeString
expected("Dey 28, 1385 AP");
924 if(str
!= expected
) {
925 errln("Expected " + escape(expected
) + " but got " + escape(str
));
927 UDate otherDate
= fmt
->parse(expected
, status
);
928 if(otherDate
!= aDate
) {
930 fmt
->format(otherDate
, str3
);
931 errln("Parse incorrect of " + escape(expected
) + " - wanted " + aDate
+ " but got " + otherDate
+ ", " + escape(str3
));
933 logln("Parsed OK: " + expected
);
935 // Two digit year parsing problem #4732
936 fmt
->applyPattern("yy-MM-dd");
938 fmt
->format(aDate
, str
);
939 expected
.setTo("85-10-28");
940 if(str
!= expected
) {
941 errln("Expected " + escape(expected
) + " but got " + escape(str
));
943 otherDate
= fmt
->parse(expected
, status
);
944 if (otherDate
!= aDate
) {
945 errln("Parse incorrect of " + escape(expected
) + " - wanted " + aDate
+ " but got " + otherDate
);
947 logln("Parsed OK: " + expected
);
953 CHECK(status
, "Error occured testing Persian Calendar in English ");
957 void IntlCalendarTest::simpleTest(const Locale
& loc
, const UnicodeString
& expect
, UDate expectDate
, UErrorCode
& status
)
961 DateFormat
*fmt0
= DateFormat::createDateTimeInstance(DateFormat::kFull
, DateFormat::kFull
);
963 logln("Try format/parse of " + (UnicodeString
)loc
.getName());
964 DateFormat
*fmt2
= DateFormat::createDateInstance(DateFormat::kFull
, loc
);
966 fmt2
->format(expectDate
, tmp
);
967 logln(escape(tmp
) + " ( in locale " + loc
.getName() + ")");
969 errln(UnicodeString("Failed to format " ) + loc
.getName() + " expected " + escape(expect
) + " got " + escape(tmp
) );
972 d
= fmt2
->parse(expect
,status
);
973 CHECK(status
, "Error occurred parsing " + UnicodeString(loc
.getName()));
974 if(d
!= expectDate
) {
976 errln(UnicodeString("Failed to parse " ) + escape(expect
) + ", " + loc
.getName() + " expect " + (double)expectDate
+ " got " + (double)d
+ " " + escape(tmp
));
977 logln( "wanted " + escape(fmt0
->format(expectDate
,tmp
.remove())) + " but got " + escape(fmt0
->format(d
,tmp
.remove())));
981 errln((UnicodeString
)"Can't create " + loc
.getName() + " date instance");
988 #endif /* #if !UCONFIG_NO_FORMATTING */