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",
110 "th_TH_TRADITIONAL@calendar=gregorian",
112 "th_TH", // Default calendar for th_TH is buddhist
113 "th", // th's default region is TH and buddhist is used as default for TH
114 "en_TH", // Default calendar for any locales with region TH is buddhist
115 "en-TH-u-ca-gregory",
117 const char *types
[40] = { "gregorian",
132 for(j
=0;locs
[j
];j
++) {
133 logln(UnicodeString("Creating calendar of locale ") + locs
[j
]);
134 status
= U_ZERO_ERROR
;
135 c
= Calendar::createInstance(locs
[j
], status
);
136 CHECK(status
, "creating '" + UnicodeString(locs
[j
]) + "' calendar");
137 if(U_SUCCESS(status
)) {
138 logln(UnicodeString(" type is ") + c
->getType());
139 if(strcmp(c
->getType(), types
[j
])) {
140 dataerrln(UnicodeString(locs
[j
]) + UnicodeString("Calendar type ") + c
->getType() + " instead of " + types
[j
]);
150 * Run a test of a quasi-Gregorian calendar. This is a calendar
151 * that behaves like a Gregorian but has different year/era mappings.
152 * The int[] data array should have the format:
154 * { era, year, gregorianYear, month, dayOfMonth, ... ... , -1 }
156 void IntlCalendarTest::quasiGregorianTest(Calendar
& cal
, const Locale
& gcl
, const int32_t *data
) {
157 UErrorCode status
= U_ZERO_ERROR
;
158 // As of JDK 1.4.1_01, using the Sun JDK GregorianCalendar as
159 // a reference throws us off by one hour. This is most likely
160 // due to the JDK 1.4 incorporation of historical time zones.
161 //java.util.Calendar grego = java.util.Calendar.getInstance();
162 Calendar
*grego
= Calendar::createInstance(gcl
, status
);
163 if (U_FAILURE(status
)) {
164 dataerrln("Error calling Calendar::createInstance");
168 int32_t tz1
= cal
.get(UCAL_ZONE_OFFSET
,status
);
169 int32_t tz2
= grego
-> get (UCAL_ZONE_OFFSET
, status
);
171 errln((UnicodeString
)"cal's tz " + tz1
+ " != grego's tz " + tz2
);
174 for (int32_t i
=0; data
[i
]!=-1; ) {
175 int32_t era
= data
[i
++];
176 int32_t year
= data
[i
++];
177 int32_t gregorianYear
= data
[i
++];
178 int32_t month
= data
[i
++];
179 int32_t dayOfMonth
= data
[i
++];
182 grego
->set(gregorianYear
, month
, dayOfMonth
);
183 UDate D
= grego
->getTime(status
);
186 cal
.set(UCAL_ERA
, era
);
187 cal
.set(year
, month
, dayOfMonth
);
188 UDate d
= cal
.getTime(status
);
189 #ifdef U_DEBUG_DUMPCALS
190 logln((UnicodeString
)"cal : " + CalendarTest::calToStr(cal
));
191 logln((UnicodeString
)"grego: " + CalendarTest::calToStr(*grego
));
194 logln(UnicodeString("OK: ") + era
+ ":" + year
+ "/" + (month
+1) + "/" + dayOfMonth
+
195 " => " + d
+ " (" + UnicodeString(cal
.getType()) + ")");
197 errln(UnicodeString("Fail: (fields to millis)") + era
+ ":" + year
+ "/" + (month
+1) + "/" + dayOfMonth
+
198 " => " + d
+ ", expected " + D
+ " (" + UnicodeString(cal
.getType()) + "Off by: " + (d
-D
));
201 // Now, set the gregorian millis on the other calendar
203 cal
.setTime(D
, status
);
204 int e
= cal
.get(UCAL_ERA
, status
);
205 int y
= cal
.get(UCAL_YEAR
, status
);
206 #ifdef U_DEBUG_DUMPCALS
207 logln((UnicodeString
)"cal : " + CalendarTest::calToStr(cal
));
208 logln((UnicodeString
)"grego: " + CalendarTest::calToStr(*grego
));
210 if (y
== year
&& e
== era
) {
211 logln((UnicodeString
)"OK: " + D
+ " => " + cal
.get(UCAL_ERA
, status
) + ":" +
212 cal
.get(UCAL_YEAR
, status
) + "/" +
213 (cal
.get(UCAL_MONTH
, status
)+1) + "/" + cal
.get(UCAL_DATE
, status
) + " (" + UnicodeString(cal
.getType()) + ")");
215 errln((UnicodeString
)"Fail: (millis to fields)" + D
+ " => " + cal
.get(UCAL_ERA
, status
) + ":" +
216 cal
.get(UCAL_YEAR
, status
) + "/" +
217 (cal
.get(UCAL_MONTH
, status
)+1) + "/" + cal
.get(UCAL_DATE
, status
) +
218 ", expected " + era
+ ":" + year
+ "/" + (month
+1) + "/" +
219 dayOfMonth
+ " (" + UnicodeString(cal
.getType()));
223 CHECK(status
, "err during quasiGregorianTest()");
226 // Verify that Gregorian works like Gregorian
227 void IntlCalendarTest::TestGregorian() {
228 UDate timeA
= Calendar::getNow();
230 GregorianCalendar::AD
, 1868, 1868, UCAL_SEPTEMBER
, 8,
231 GregorianCalendar::AD
, 1868, 1868, UCAL_SEPTEMBER
, 9,
232 GregorianCalendar::AD
, 1869, 1869, UCAL_JUNE
, 4,
233 GregorianCalendar::AD
, 1912, 1912, UCAL_JULY
, 29,
234 GregorianCalendar::AD
, 1912, 1912, UCAL_JULY
, 30,
235 GregorianCalendar::AD
, 1912, 1912, UCAL_AUGUST
, 1,
236 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
240 UErrorCode status
= U_ZERO_ERROR
;
241 cal
= Calendar::createInstance(/*"de_DE", */ status
);
242 CHECK(status
, UnicodeString("Creating de_CH calendar"));
243 // Sanity check the calendar
244 UDate timeB
= Calendar::getNow();
245 UDate timeCal
= cal
->getTime(status
);
247 if(!(timeA
<= timeCal
) || !(timeCal
<= timeB
)) {
248 errln((UnicodeString
)"Error: Calendar time " + timeCal
+
249 " is not within sampled times [" + timeA
+ " to " + timeB
+ "]!");
253 // Note, the following is a good way to test the sanity of the constructed calendars,
254 // using Collation as a delay-loop:
256 // $ intltest format/IntlCalendarTest collate/G7CollationTest format/IntlCalendarTest
258 quasiGregorianTest(*cal
,Locale("fr_FR"),data
);
263 * Verify that BuddhistCalendar shifts years to Buddhist Era but otherwise
264 * behaves like GregorianCalendar.
266 void IntlCalendarTest::TestBuddhist() {
267 // BE 2542 == 1999 CE
268 UDate timeA
= Calendar::getNow();
271 0, // B. era [928479600000]
277 0, // B. era [-79204842000000]
280 UCAL_FEBRUARY
, // month
283 0, // test month calculation: 4795 BE = 4252 AD is a leap year, but 4795 AD is not.
284 4795, // BE [72018057600000]
289 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1
292 UErrorCode status
= U_ZERO_ERROR
;
293 cal
= Calendar::createInstance("th_TH@calendar=buddhist", status
);
294 CHECK(status
, UnicodeString("Creating th_TH@calendar=buddhist calendar"));
296 // Sanity check the calendar
297 UDate timeB
= Calendar::getNow();
298 UDate timeCal
= cal
->getTime(status
);
300 if(!(timeA
<= timeCal
) || !(timeCal
<= timeB
)) {
301 errln((UnicodeString
)"Error: Calendar time " + timeCal
+
302 " is not within sampled times [" + timeA
+ " to " + timeB
+ "]!");
307 quasiGregorianTest(*cal
,Locale("th_TH@calendar=gregorian"),data
);
313 * Verify that TaiWanCalendar shifts years to Minguo Era but otherwise
314 * behaves like GregorianCalendar.
316 void IntlCalendarTest::TestTaiwan() {
318 UDate timeA
= Calendar::getNow();
320 // TODO port these to the data items
322 1, // B. era [928479600000]
328 1, // B. era [-79204842000000]
331 UCAL_FEBRUARY
, // month
334 1, // B. era [-79204842000000]
337 UCAL_FEBRUARY
, // month
340 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1
343 UErrorCode status
= U_ZERO_ERROR
;
344 cal
= Calendar::createInstance("en_US@calendar=roc", status
);
345 CHECK(status
, UnicodeString("Creating en_US@calendar=roc calendar"));
347 // Sanity check the calendar
348 UDate timeB
= Calendar::getNow();
349 UDate timeCal
= cal
->getTime(status
);
351 if(!(timeA
<= timeCal
) || !(timeCal
<= timeB
)) {
352 errln((UnicodeString
)"Error: Calendar time " + timeCal
+
353 " is not within sampled times [" + timeA
+ " to " + timeB
+ "]!");
358 quasiGregorianTest(*cal
,Locale("en_US"),data
);
365 * Verify that JapaneseCalendar shifts years to Japanese Eras but otherwise
366 * behaves like GregorianCalendar.
368 void IntlCalendarTest::TestJapanese() {
369 UDate timeA
= Calendar::getNow();
371 /* Sorry.. japancal.h is private! */
372 #define JapaneseCalendar_MEIJI 232
373 #define JapaneseCalendar_TAISHO 233
374 #define JapaneseCalendar_SHOWA 234
375 #define JapaneseCalendar_HEISEI 235
377 // BE 2542 == 1999 CE
379 // Jera Jyr Gyear m d
380 JapaneseCalendar_MEIJI
, 1, 1868, UCAL_SEPTEMBER
, 8,
381 JapaneseCalendar_MEIJI
, 1, 1868, UCAL_SEPTEMBER
, 9,
382 JapaneseCalendar_MEIJI
, 2, 1869, UCAL_JUNE
, 4,
383 JapaneseCalendar_MEIJI
, 45, 1912, UCAL_JULY
, 29,
384 JapaneseCalendar_TAISHO
, 1, 1912, UCAL_JULY
, 30,
385 JapaneseCalendar_TAISHO
, 1, 1912, UCAL_AUGUST
, 1,
387 // new tests (not in java)
388 JapaneseCalendar_SHOWA
, 64, 1989, UCAL_JANUARY
, 7, // Test current era transition (different code path than others)
389 JapaneseCalendar_HEISEI
, 1, 1989, UCAL_JANUARY
, 8,
390 JapaneseCalendar_HEISEI
, 1, 1989, UCAL_JANUARY
, 9,
391 JapaneseCalendar_HEISEI
, 1, 1989, UCAL_DECEMBER
, 20,
392 JapaneseCalendar_HEISEI
, 15, 2003, UCAL_MAY
, 22,
393 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1
397 UErrorCode status
= U_ZERO_ERROR
;
398 cal
= Calendar::createInstance("ja_JP@calendar=japanese", status
);
399 CHECK(status
, UnicodeString("Creating ja_JP@calendar=japanese calendar"));
400 // Sanity check the calendar
401 UDate timeB
= Calendar::getNow();
402 UDate timeCal
= cal
->getTime(status
);
404 if(!(timeA
<= timeCal
) || !(timeCal
<= timeB
)) {
405 errln((UnicodeString
)"Error: Calendar time " + timeCal
+
406 " is not within sampled times [" + timeA
+ " to " + timeB
+ "]!");
409 quasiGregorianTest(*cal
,Locale("ja_JP"),data
);
415 void IntlCalendarTest::TestBuddhistFormat() {
416 UErrorCode status
= U_ZERO_ERROR
;
418 // Test simple parse/format with adopt
420 // First, a contrived English test..
421 UDate aDate
= 999932400000.0;
422 SimpleDateFormat
*fmt
= new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"), Locale("en_US@calendar=buddhist"), status
);
423 CHECK(status
, "creating date format instance");
424 SimpleDateFormat
*fmt2
= new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"), Locale("en_US@calendar=gregorian"), status
);
425 CHECK(status
, "creating gregorian date format instance");
427 errln("Couldn't create en_US instance");
430 fmt2
->format(aDate
, str
);
431 logln(UnicodeString() + "Test Date: " + str
);
433 fmt
->format(aDate
, str
);
434 logln(UnicodeString() + "as Buddhist Calendar: " + escape(str
));
435 UnicodeString
expected("September 8, 2544 BE");
436 if(str
!= expected
) {
437 errln("Expected " + escape(expected
) + " but got " + escape(str
));
439 UDate otherDate
= fmt
->parse(expected
, status
);
440 if(otherDate
!= aDate
) {
442 fmt
->format(otherDate
, str3
);
443 errln("Parse incorrect of " + escape(expected
) + " - wanted " + aDate
+ " but got " + otherDate
+ ", " + escape(str3
));
445 logln("Parsed OK: " + expected
);
451 CHECK(status
, "Error occurred testing Buddhist Calendar in English ");
453 status
= U_ZERO_ERROR
;
456 UnicodeString expect
= CharsToUnicodeString("\\u0E27\\u0E31\\u0E19\\u0E40\\u0E2A\\u0E32\\u0E23\\u0E4C\\u0E17\\u0E35\\u0E48"
457 " 8 \\u0E01\\u0E31\\u0e19\\u0e22\\u0e32\\u0e22\\u0e19 \\u0e1e.\\u0e28. 2544");
458 UDate expectDate
= 999932400000.0;
459 Locale
loc("th_TH_TRADITIONAL"); // legacy
461 simpleTest(loc
, expect
, expectDate
, status
);
463 status
= U_ZERO_ERROR
;
465 UnicodeString expect
= CharsToUnicodeString("\\u0E27\\u0E31\\u0E19\\u0E40\\u0E2A\\u0E32\\u0E23\\u0E4C\\u0E17\\u0E35\\u0E48"
466 " 8 \\u0E01\\u0E31\\u0e19\\u0e22\\u0e32\\u0e22\\u0e19 \\u0e1e.\\u0e28. 2544");
467 UDate expectDate
= 999932400000.0;
468 Locale
loc("th_TH@calendar=buddhist");
470 simpleTest(loc
, expect
, expectDate
, status
);
472 status
= U_ZERO_ERROR
;
474 UnicodeString expect
= CharsToUnicodeString("\\u0E27\\u0E31\\u0E19\\u0E40\\u0E2A\\u0E32\\u0E23\\u0E4C\\u0E17\\u0E35\\u0E48"
475 " 8 \\u0E01\\u0E31\\u0e19\\u0e22\\u0e32\\u0e22\\u0e19 \\u0e04.\\u0e28. 2001");
476 UDate expectDate
= 999932400000.0;
477 Locale
loc("th_TH@calendar=gregorian");
479 simpleTest(loc
, expect
, expectDate
, status
);
481 status
= U_ZERO_ERROR
;
483 UnicodeString expect
= CharsToUnicodeString("\\u0E27\\u0E31\\u0E19\\u0E40\\u0E2A\\u0E32\\u0E23\\u0E4C\\u0E17\\u0E35\\u0E48"
484 " 8 \\u0E01\\u0E31\\u0e19\\u0e22\\u0e32\\u0e22\\u0e19 \\u0e04.\\u0e28. 2001");
485 UDate expectDate
= 999932400000.0;
486 Locale
loc("th_TH_TRADITIONAL@calendar=gregorian");
488 simpleTest(loc
, expect
, expectDate
, status
);
492 // TaiwanFormat has been moved to testdata/format.txt
495 void IntlCalendarTest::TestJapaneseFormat() {
497 UErrorCode status
= U_ZERO_ERROR
;
498 cal
= Calendar::createInstance("ja_JP_TRADITIONAL", status
);
499 CHECK(status
, UnicodeString("Creating ja_JP_TRADITIONAL calendar"));
501 Calendar
*cal2
= cal
->clone();
505 // Test simple parse/format with adopt
507 UDate aDate
= 999932400000.0;
508 SimpleDateFormat
*fmt
= new SimpleDateFormat(UnicodeString("MMMM d, yy G"), Locale("en_US@calendar=japanese"), status
);
509 SimpleDateFormat
*fmt2
= new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"), Locale("en_US@calendar=gregorian"), status
);
510 CHECK(status
, "creating date format instance");
512 errln("Couldn't create en_US instance");
515 fmt2
->format(aDate
, str
);
516 logln(UnicodeString() + "Test Date: " + str
);
518 fmt
->format(aDate
, str
);
519 logln(UnicodeString() + "as Japanese Calendar: " + str
);
520 UnicodeString
expected("September 8, 13 Heisei");
521 if(str
!= expected
) {
522 errln("Expected " + expected
+ " but got " + str
);
524 UDate otherDate
= fmt
->parse(expected
, status
);
525 if(otherDate
!= aDate
) {
528 fmt
->parse(expected
, *cal2
, pp
);
529 fmt
->format(otherDate
, str3
);
530 errln("Parse incorrect of " + expected
+ " - wanted " + aDate
+ " but got " + " = " + otherDate
+ ", " + str3
+ " = " + CalendarTest::calToStr(*cal2
) );
533 logln("Parsed OK: " + expected
);
538 // Test parse with incomplete information
539 fmt
= new SimpleDateFormat(UnicodeString("G y"), Locale("en_US@calendar=japanese"), status
);
540 aDate
= -3197117222000.0;
541 CHECK(status
, "creating date format instance");
543 errln("Coudln't create en_US instance");
546 fmt2
->format(aDate
, str
);
547 logln(UnicodeString() + "Test Date: " + str
);
549 fmt
->format(aDate
, str
);
550 logln(UnicodeString() + "as Japanese Calendar: " + str
);
551 UnicodeString
expected("Meiji 1");
552 if(str
!= expected
) {
553 errln("Expected " + expected
+ " but got " + str
);
555 UDate otherDate
= fmt
->parse(expected
, status
);
556 if(otherDate
!= aDate
) {
559 fmt
->parse(expected
, *cal2
, pp
);
560 fmt
->format(otherDate
, str3
);
561 errln("Parse incorrect of " + expected
+ " - wanted " + aDate
+ " but got " + " = " +
562 otherDate
+ ", " + str3
+ " = " + CalendarTest::calToStr(*cal2
) );
564 logln("Parsed OK: " + expected
);
571 CHECK(status
, "Error occurred");
573 // Now, try in Japanese
575 UnicodeString expect
= CharsToUnicodeString("\\u5e73\\u621013\\u5e749\\u67088\\u65e5 \\u571f\\u66dc\\u65e5");
576 UDate expectDate
= 999932400000.0; // Testing a recent date
577 Locale
loc("ja_JP@calendar=japanese");
579 status
= U_ZERO_ERROR
;
580 simpleTest(loc
, expect
, expectDate
, status
);
583 UnicodeString expect
= CharsToUnicodeString("\\u5e73\\u621013\\u5e749\\u67088\\u65e5 \\u571f\\u66dc\\u65e5");
584 UDate expectDate
= 999932400000.0; // Testing a recent date
585 Locale
loc("ja_JP_TRADITIONAL"); // legacy
587 status
= U_ZERO_ERROR
;
588 simpleTest(loc
, expect
, expectDate
, status
);
591 UnicodeString expect
= CharsToUnicodeString("\\u5b89\\u6c385\\u5e747\\u67084\\u65e5 \\u6728\\u66dc\\u65e5");
592 UDate expectDate
= -6106032422000.0; // 1776-07-04T00:00:00Z-075258
593 Locale
loc("ja_JP@calendar=japanese");
595 status
= U_ZERO_ERROR
;
596 simpleTest(loc
, expect
, expectDate
, status
);
599 { // Jitterbug 1869 - this is an ambiguous era. (Showa 64 = Jan 6 1989, but Showa could be 2 other eras) )
600 UnicodeString expect
= CharsToUnicodeString("\\u662d\\u548c64\\u5e741\\u67086\\u65e5 \\u91d1\\u66dc\\u65e5");
601 UDate expectDate
= 600076800000.0;
602 Locale
loc("ja_JP@calendar=japanese");
604 status
= U_ZERO_ERROR
;
605 simpleTest(loc
, expect
, expectDate
, status
);
608 { // 1989 Jan 9 Monday = Heisei 1; full is Gy年M月d日EEEE => 平成元年1月9日月曜日
609 UnicodeString expect
= CharsToUnicodeString("\\u5E73\\u6210\\u5143\\u5E741\\u67089\\u65E5 \\u6708\\u66DC\\u65E5");
610 UDate expectDate
= 600336000000.0;
611 Locale
loc("ja_JP@calendar=japanese");
613 status
= U_ZERO_ERROR
;
614 simpleTest(loc
, expect
, expectDate
, status
);
617 { // This Feb 29th falls on a leap year by gregorian year, but not by Japanese year.
618 UnicodeString expect
= CharsToUnicodeString("\\u5EB7\\u6B632\\u5e742\\u670829\\u65e5 \\u65e5\\u66dc\\u65e5");
619 UDate expectDate
= -16214400422000.0; // 1456-03-09T00:00Z-075258
620 Locale
loc("ja_JP@calendar=japanese");
622 status
= U_ZERO_ERROR
;
623 simpleTest(loc
, expect
, expectDate
, status
);
628 void IntlCalendarTest::TestJapanese3860()
631 UErrorCode status
= U_ZERO_ERROR
;
632 cal
= Calendar::createInstance("ja_JP@calendar=japanese", status
);
633 CHECK(status
, UnicodeString("Creating ja_JP@calendar=japanese calendar"));
634 Calendar
*cal2
= cal
->clone();
635 SimpleDateFormat
*fmt2
= new SimpleDateFormat(UnicodeString("HH:mm:ss.S MMMM d, yyyy G"), Locale("en_US@calendar=gregorian"), status
);
640 // Test simple parse/format with adopt
643 // Test parse with missing era (should default to current era, heisei)
644 // Test parse with incomplete information
645 logln("Testing parse w/ missing era...");
646 SimpleDateFormat
*fmt
= new SimpleDateFormat(UnicodeString("y/M/d"), Locale("ja_JP@calendar=japanese"), status
);
647 CHECK(status
, "creating date format instance");
649 errln("Couldn't create en_US instance");
651 UErrorCode s2
= U_ZERO_ERROR
;
653 UnicodeString
samplestr("1/5/9");
654 logln(UnicodeString() + "Test Year: " + samplestr
);
655 aDate
= fmt
->parse(samplestr
, s2
);
657 fmt
->parse(samplestr
, *cal2
, pp
);
658 CHECK(s2
, "parsing the 1/5/9 string");
659 logln("*cal2 after 159 parse:");
661 fmt2
->format(aDate
, str
);
662 logln(UnicodeString() + "as Gregorian Calendar: " + str
);
664 cal2
->setTime(aDate
, s2
);
665 int32_t gotYear
= cal2
->get(UCAL_YEAR
, s2
);
666 int32_t gotEra
= cal2
->get(UCAL_ERA
, s2
);
667 int32_t expectYear
= 1;
668 int32_t expectEra
= JapaneseCalendar::getCurrentEra();
669 if((gotYear
!=1) || (gotEra
!= expectEra
)) {
670 errln(UnicodeString("parse "+samplestr
+" of 'y/M/d' as Japanese Calendar, expected year ") + expectYear
+
671 UnicodeString(" and era ") + expectEra
+", but got year " + gotYear
+ " and era " + gotEra
+ " (Gregorian:" + str
+")");
673 logln(UnicodeString() + " year: " + gotYear
+ ", era: " + gotEra
);
680 // Test simple parse/format with adopt
683 // Test parse with missing era (should default to current era, heisei)
684 // Test parse with incomplete information
685 logln("Testing parse w/ just year...");
686 SimpleDateFormat
*fmt
= new SimpleDateFormat(UnicodeString("y"), Locale("ja_JP@calendar=japanese"), status
);
687 CHECK(status
, "creating date format instance");
689 errln("Couldn't create en_US instance");
691 UErrorCode s2
= U_ZERO_ERROR
;
693 UnicodeString
samplestr("1");
694 logln(UnicodeString() + "Test Year: " + samplestr
);
695 aDate
= fmt
->parse(samplestr
, s2
);
697 fmt
->parse(samplestr
, *cal2
, pp
);
698 CHECK(s2
, "parsing the 1 string");
699 logln("*cal2 after 1 parse:");
701 fmt2
->format(aDate
, str
);
702 logln(UnicodeString() + "as Gregorian Calendar: " + str
);
704 cal2
->setTime(aDate
, s2
);
705 int32_t gotYear
= cal2
->get(UCAL_YEAR
, s2
);
706 int32_t gotEra
= cal2
->get(UCAL_ERA
, s2
);
707 int32_t expectYear
= 1;
708 int32_t expectEra
= JapaneseCalendar::getCurrentEra();
709 if((gotYear
!=1) || (gotEra
!= expectEra
)) {
710 errln(UnicodeString("parse "+samplestr
+" of 'y' as Japanese Calendar, expected year ") + expectYear
+
711 UnicodeString(" and era ") + expectEra
+", but got year " + gotYear
+ " and era " + gotEra
+ " (Gregorian:" + str
+")");
713 logln(UnicodeString() + " year: " + gotYear
+ ", era: " + gotEra
);
724 void IntlCalendarTest::TestForceGannenNumbering()
727 const char* locID
= "ja_JP@calendar=japanese";
729 UDate refDate
= 600336000000.0; // 1989 Jan 9 Monday = Heisei 1
730 UnicodeString
patText(u
"Gy年M月d日",-1);
731 UnicodeString
patNumr(u
"GGGGGy/MM/dd",-1);
732 UnicodeString
skelText(u
"yMMMM",-1);
734 // Test Gannen year forcing
735 status
= U_ZERO_ERROR
;
736 LocalPointer
<SimpleDateFormat
> testFmt1(new SimpleDateFormat(patText
, loc
, status
));
737 LocalPointer
<SimpleDateFormat
> testFmt2(new SimpleDateFormat(patNumr
, loc
, status
));
738 if (U_FAILURE(status
)) {
739 dataerrln("Fail in new SimpleDateFormat locale %s: %s", locID
, u_errorName(status
));
741 UnicodeString testString1
, testString2
;
742 testString1
= testFmt1
->format(refDate
, testString1
);
743 if (testString1
.length() < 3 || testString1
.charAt(2) != 0x5143) {
744 errln(UnicodeString("Formatting year 1 in created text style, got " + testString1
+ " but expected 3rd char to be 0x5143"));
746 testString2
= testFmt2
->format(refDate
, testString2
);
747 if (testString2
.length() < 2 || testString2
.charAt(1) != 0x0031) {
748 errln(UnicodeString("Formatting year 1 in created numeric style, got " + testString2
+ " but expected 2nd char to be 1"));
750 // Now switch the patterns and verify that Gannen use follows the pattern
751 testFmt1
->applyPattern(patNumr
);
752 testString1
.remove();
753 testString1
= testFmt1
->format(refDate
, testString1
);
754 if (testString1
.length() < 2 || testString1
.charAt(1) != 0x0031) {
755 errln(UnicodeString("Formatting year 1 in applied numeric style, got " + testString1
+ " but expected 2nd char to be 1"));
757 testFmt2
->applyPattern(patText
);
758 testString2
.remove();
759 testString2
= testFmt2
->format(refDate
, testString2
);
760 if (testString2
.length() < 3 || testString2
.charAt(2) != 0x5143) {
761 errln(UnicodeString("Formatting year 1 in applied text style, got " + testString2
+ " but expected 3rd char to be 0x5143"));
765 // Test disabling of Gannen year forcing
766 status
= U_ZERO_ERROR
;
767 LocalPointer
<DateTimePatternGenerator
> dtpgen(DateTimePatternGenerator::createInstance(loc
, status
));
768 if (U_FAILURE(status
)) {
769 dataerrln("Fail in DateTimePatternGenerator::createInstance locale %s: %s", locID
, u_errorName(status
));
771 UnicodeString pattern
= dtpgen
->getBestPattern(skelText
, status
);
772 if (U_FAILURE(status
)) {
773 dataerrln("Fail in DateTimePatternGenerator::getBestPattern locale %s: %s", locID
, u_errorName(status
));
775 // Use override string of ""
776 LocalPointer
<SimpleDateFormat
> testFmt3(new SimpleDateFormat(pattern
, UnicodeString(""), loc
, status
));
777 if (U_FAILURE(status
)) {
778 dataerrln("Fail in new SimpleDateFormat locale %s: %s", locID
, u_errorName(status
));
780 UnicodeString testString3
;
781 testString3
= testFmt3
->format(refDate
, testString3
);
782 if (testString3
.length() < 3 || testString3
.charAt(2) != 0x0031) {
783 errln(UnicodeString("Formatting year 1 with Gannen disabled, got " + testString3
+ " but expected 3rd char to be 1"));
791 * Verify the Persian Calendar.
793 void IntlCalendarTest::TestPersian() {
794 UDate timeA
= Calendar::getNow();
797 UErrorCode status
= U_ZERO_ERROR
;
798 cal
= Calendar::createInstance("fa_IR@calendar=persian", status
);
799 CHECK(status
, UnicodeString("Creating fa_IR@calendar=persian calendar"));
800 // Sanity check the calendar
801 UDate timeB
= Calendar::getNow();
802 UDate timeCal
= cal
->getTime(status
);
804 if(!(timeA
<= timeCal
) || !(timeCal
<= timeB
)) {
805 errln((UnicodeString
)"Error: Calendar time " + timeCal
+
806 " is not within sampled times [" + timeA
+ " to " + timeB
+ "]!");
810 // Test various dates to be sure of validity
812 1925, 4, 24, 1304, 2, 4,
813 2011, 1, 11, 1389, 10, 21,
814 1986, 2, 25, 1364, 12, 6,
815 1934, 3, 14, 1312, 12, 23,
817 2090, 3, 19, 1468, 12, 29,
818 2007, 2, 22, 1385, 12, 3,
819 1969, 12, 31, 1348, 10, 10,
820 1945, 11, 12, 1324, 8, 21,
821 1925, 3, 31, 1304, 1, 11,
823 1996, 3, 19, 1374, 12, 29,
824 1996, 3, 20, 1375, 1, 1,
825 1997, 3, 20, 1375, 12, 30,
826 1997, 3, 21, 1376, 1, 1,
828 2008, 3, 19, 1386, 12, 29,
829 2008, 3, 20, 1387, 1, 1,
830 2004, 3, 19, 1382, 12, 29,
831 2004, 3, 20, 1383, 1, 1,
833 2006, 3, 20, 1384, 12, 29,
834 2006, 3, 21, 1385, 1, 1,
836 2005, 4, 20, 1384, 1, 31,
837 2005, 4, 21, 1384, 2, 1,
838 2005, 5, 21, 1384, 2, 31,
839 2005, 5, 22, 1384, 3, 1,
840 2005, 6, 21, 1384, 3, 31,
841 2005, 6, 22, 1384, 4, 1,
842 2005, 7, 22, 1384, 4, 31,
843 2005, 7, 23, 1384, 5, 1,
844 2005, 8, 22, 1384, 5, 31,
845 2005, 8, 23, 1384, 6, 1,
846 2005, 9, 22, 1384, 6, 31,
847 2005, 9, 23, 1384, 7, 1,
848 2005, 10, 22, 1384, 7, 30,
849 2005, 10, 23, 1384, 8, 1,
850 2005, 11, 21, 1384, 8, 30,
851 2005, 11, 22, 1384, 9, 1,
852 2005, 12, 21, 1384, 9, 30,
853 2005, 12, 22, 1384, 10, 1,
854 2006, 1, 20, 1384, 10, 30,
855 2006, 1, 21, 1384, 11, 1,
856 2006, 2, 19, 1384, 11, 30,
857 2006, 2, 20, 1384, 12, 1,
858 2006, 3, 20, 1384, 12, 29,
859 2006, 3, 21, 1385, 1, 1,
861 // The 2820-year cycle arithmetical algorithm would fail this one.
862 2025, 3, 21, 1404, 1, 1,
864 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1
867 Calendar
*grego
= Calendar::createInstance("fa_IR@calendar=gregorian", status
);
868 for (int32_t i
=0; data
[i
]!=-1; ) {
869 int32_t gregYear
= data
[i
++];
870 int32_t gregMonth
= data
[i
++]-1;
871 int32_t gregDay
= data
[i
++];
872 int32_t persYear
= data
[i
++];
873 int32_t persMonth
= data
[i
++]-1;
874 int32_t persDay
= data
[i
++];
876 // Test conversion from Persian dates
878 grego
->set(gregYear
, gregMonth
, gregDay
);
881 cal
->set(persYear
, persMonth
, persDay
);
883 UDate persTime
= cal
->getTime(status
);
884 UDate gregTime
= grego
->getTime(status
);
886 if (persTime
!= gregTime
) {
887 errln(UnicodeString("Expected ") + gregTime
+ " but got " + persTime
);
890 // Test conversion to Persian dates
892 cal
->setTime(gregTime
, status
);
894 int32_t computedYear
= cal
->get(UCAL_YEAR
, status
);
895 int32_t computedMonth
= cal
->get(UCAL_MONTH
, status
);
896 int32_t computedDay
= cal
->get(UCAL_DATE
, status
);
898 if ((persYear
!= computedYear
) ||
899 (persMonth
!= computedMonth
) ||
900 (persDay
!= computedDay
)) {
901 errln(UnicodeString("Expected ") + persYear
+ "/" + (persMonth
+1) + "/" + persDay
+
902 " but got " + computedYear
+ "/" + (computedMonth
+1) + "/" + computedDay
);
911 void IntlCalendarTest::TestPersianFormat() {
912 UErrorCode status
= U_ZERO_ERROR
;
913 SimpleDateFormat
*fmt
= new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"), Locale(" en_US@calendar=persian"), status
);
914 CHECK(status
, "creating date format instance");
915 SimpleDateFormat
*fmt2
= new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"), Locale("en_US@calendar=gregorian"), status
);
916 CHECK(status
, "creating gregorian date format instance");
917 UnicodeString
gregorianDate("January 18, 2007 AD");
918 UDate aDate
= fmt2
->parse(gregorianDate
, status
);
920 errln("Couldn't create en_US instance");
923 fmt
->format(aDate
, str
);
924 logln(UnicodeString() + "as Persian Calendar: " + escape(str
));
925 UnicodeString
expected("Dey 28, 1385 AP");
926 if(str
!= expected
) {
927 errln("Expected " + escape(expected
) + " but got " + escape(str
));
929 UDate otherDate
= fmt
->parse(expected
, status
);
930 if(otherDate
!= aDate
) {
932 fmt
->format(otherDate
, str3
);
933 errln("Parse incorrect of " + escape(expected
) + " - wanted " + aDate
+ " but got " + otherDate
+ ", " + escape(str3
));
935 logln("Parsed OK: " + expected
);
937 // Two digit year parsing problem #4732
938 fmt
->applyPattern("yy-MM-dd");
940 fmt
->format(aDate
, str
);
941 expected
.setTo("85-10-28");
942 if(str
!= expected
) {
943 errln("Expected " + escape(expected
) + " but got " + escape(str
));
945 otherDate
= fmt
->parse(expected
, status
);
946 if (otherDate
!= aDate
) {
947 errln("Parse incorrect of " + escape(expected
) + " - wanted " + aDate
+ " but got " + otherDate
);
949 logln("Parsed OK: " + expected
);
955 CHECK(status
, "Error occured testing Persian Calendar in English ");
959 void IntlCalendarTest::simpleTest(const Locale
& loc
, const UnicodeString
& expect
, UDate expectDate
, UErrorCode
& status
)
963 DateFormat
*fmt0
= DateFormat::createDateTimeInstance(DateFormat::kFull
, DateFormat::kFull
);
965 logln("Try format/parse of " + (UnicodeString
)loc
.getName());
966 DateFormat
*fmt2
= DateFormat::createDateInstance(DateFormat::kFull
, loc
);
968 fmt2
->format(expectDate
, tmp
);
969 logln(escape(tmp
) + " ( in locale " + loc
.getName() + ")");
971 errln(UnicodeString("Failed to format " ) + loc
.getName() + " expected " + escape(expect
) + " got " + escape(tmp
) );
974 d
= fmt2
->parse(expect
,status
);
975 CHECK(status
, "Error occurred parsing " + UnicodeString(loc
.getName()));
976 if(d
!= expectDate
) {
978 errln(UnicodeString("Failed to parse " ) + escape(expect
) + ", " + loc
.getName() + " expect " + (double)expectDate
+ " got " + (double)d
+ " " + escape(tmp
));
979 logln( "wanted " + escape(fmt0
->format(expectDate
,tmp
.remove())) + " but got " + escape(fmt0
->format(d
,tmp
.remove())));
983 errln((UnicodeString
)"Can't create " + loc
.getName() + " date instance");
990 #endif /* #if !UCONFIG_NO_FORMATTING */