]> git.saurik.com Git - apple/icu.git/blob - icuSources/test/intltest/incaltst.cpp
ICU-57149.0.1.tar.gz
[apple/icu.git] / icuSources / test / intltest / incaltst.cpp
1 /***********************************************************************
2 * COPYRIGHT:
3 * Copyright (c) 1997-2014, International Business Machines Corporation
4 * and others. All Rights Reserved.
5 ***********************************************************************/
6
7 /* Test Internationalized Calendars for C++ */
8
9 #include "unicode/utypes.h"
10 #include "string.h"
11 #include "unicode/locid.h"
12 #include "japancal.h"
13
14 #if !UCONFIG_NO_FORMATTING
15
16 #include <stdio.h>
17 #include "caltest.h"
18
19 #define CHECK(status, msg) \
20 if (U_FAILURE(status)) { \
21 dataerrln((UnicodeString(u_errorName(status)) + UnicodeString(" : " ) )+ msg); \
22 return; \
23 }
24
25
26 static UnicodeString escape( const UnicodeString&src)
27 {
28 UnicodeString dst;
29 dst.remove();
30 for (int32_t i = 0; i < src.length(); ++i) {
31 UChar c = src[i];
32 if(c < 0x0080)
33 dst += c;
34 else {
35 dst += UnicodeString("[");
36 char buf [8];
37 sprintf(buf, "%#x", c);
38 dst += UnicodeString(buf);
39 dst += UnicodeString("]");
40 }
41 }
42
43 return dst;
44 }
45
46
47 #include "incaltst.h"
48 #include "unicode/gregocal.h"
49 #include "unicode/smpdtfmt.h"
50 #include "unicode/simpletz.h"
51
52 // *****************************************************************************
53 // class IntlCalendarTest
54 // *****************************************************************************
55 //--- move to CalendarTest?
56
57 // Turn this on to dump the calendar fields
58 #define U_DEBUG_DUMPCALS
59
60
61 #define CASE(id,test) case id: name = #test; if (exec) { logln(#test "---"); logln((UnicodeString)""); test(); } break
62
63
64 void IntlCalendarTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
65 {
66 if (exec) logln("TestSuite IntlCalendarTest");
67 switch (index) {
68 CASE(0,TestTypes);
69 CASE(1,TestGregorian);
70 CASE(2,TestBuddhist);
71 CASE(3,TestJapanese);
72 CASE(4,TestBuddhistFormat);
73 CASE(5,TestJapaneseFormat);
74 CASE(6,TestJapanese3860);
75 CASE(7,TestPersian);
76 CASE(8,TestPersianFormat);
77 CASE(9,TestTaiwan);
78 default: name = ""; break;
79 }
80 }
81
82 #undef CASE
83
84 // ---------------------------------------------------------------------------------
85
86
87 /**
88 * Test various API methods for API completeness.
89 */
90 void
91 IntlCalendarTest::TestTypes()
92 {
93 Calendar *c = NULL;
94 UErrorCode status = U_ZERO_ERROR;
95 int j;
96 const char *locs [40] = { "en_US_VALLEYGIRL",
97 "en_US_VALLEYGIRL@collation=phonebook;calendar=japanese",
98 "en_US_VALLEYGIRL@collation=phonebook;calendar=gregorian",
99 "ja_JP@calendar=japanese",
100 "th_TH@calendar=buddhist",
101 "ja_JP_TRADITIONAL",
102 "th_TH_TRADITIONAL",
103 "th_TH_TRADITIONAL@calendar=gregorian",
104 "en_US",
105 "th_TH", // Default calendar for th_TH is buddhist
106 "th", // th's default region is TH and buddhist is used as default for TH
107 "en_TH", // Default calendar for any locales with region TH is buddhist
108 "en-TH-u-ca-gregory",
109 NULL };
110 const char *types[40] = { "gregorian",
111 "japanese",
112 "gregorian",
113 "japanese",
114 "buddhist",
115 "japanese",
116 "buddhist",
117 "gregorian",
118 "gregorian",
119 "buddhist",
120 "buddhist",
121 "buddhist",
122 "gregorian",
123 NULL };
124
125 for(j=0;locs[j];j++) {
126 logln(UnicodeString("Creating calendar of locale ") + locs[j]);
127 status = U_ZERO_ERROR;
128 c = Calendar::createInstance(locs[j], status);
129 CHECK(status, "creating '" + UnicodeString(locs[j]) + "' calendar");
130 if(U_SUCCESS(status)) {
131 logln(UnicodeString(" type is ") + c->getType());
132 if(strcmp(c->getType(), types[j])) {
133 dataerrln(UnicodeString(locs[j]) + UnicodeString("Calendar type ") + c->getType() + " instead of " + types[j]);
134 }
135 }
136 delete c;
137 }
138 }
139
140
141
142 /**
143 * Run a test of a quasi-Gregorian calendar. This is a calendar
144 * that behaves like a Gregorian but has different year/era mappings.
145 * The int[] data array should have the format:
146 *
147 * { era, year, gregorianYear, month, dayOfMonth, ... ... , -1 }
148 */
149 void IntlCalendarTest::quasiGregorianTest(Calendar& cal, const Locale& gcl, const int32_t *data) {
150 UErrorCode status = U_ZERO_ERROR;
151 // As of JDK 1.4.1_01, using the Sun JDK GregorianCalendar as
152 // a reference throws us off by one hour. This is most likely
153 // due to the JDK 1.4 incorporation of historical time zones.
154 //java.util.Calendar grego = java.util.Calendar.getInstance();
155 Calendar *grego = Calendar::createInstance(gcl, status);
156 if (U_FAILURE(status)) {
157 dataerrln("Error calling Calendar::createInstance");
158 return;
159 }
160
161 int32_t tz1 = cal.get(UCAL_ZONE_OFFSET,status);
162 int32_t tz2 = grego -> get (UCAL_ZONE_OFFSET, status);
163 if(tz1 != tz2) {
164 errln((UnicodeString)"cal's tz " + tz1 + " != grego's tz " + tz2);
165 }
166
167 for (int32_t i=0; data[i]!=-1; ) {
168 int32_t era = data[i++];
169 int32_t year = data[i++];
170 int32_t gregorianYear = data[i++];
171 int32_t month = data[i++];
172 int32_t dayOfMonth = data[i++];
173
174 grego->clear();
175 grego->set(gregorianYear, month, dayOfMonth);
176 UDate D = grego->getTime(status);
177
178 cal.clear();
179 cal.set(UCAL_ERA, era);
180 cal.set(year, month, dayOfMonth);
181 UDate d = cal.getTime(status);
182 #ifdef U_DEBUG_DUMPCALS
183 logln((UnicodeString)"cal : " + CalendarTest::calToStr(cal));
184 logln((UnicodeString)"grego: " + CalendarTest::calToStr(*grego));
185 #endif
186 if (d == D) {
187 logln(UnicodeString("OK: ") + era + ":" + year + "/" + (month+1) + "/" + dayOfMonth +
188 " => " + d + " (" + UnicodeString(cal.getType()) + ")");
189 } else {
190 errln(UnicodeString("Fail: (fields to millis)") + era + ":" + year + "/" + (month+1) + "/" + dayOfMonth +
191 " => " + d + ", expected " + D + " (" + UnicodeString(cal.getType()) + "Off by: " + (d-D));
192 }
193
194 // Now, set the gregorian millis on the other calendar
195 cal.clear();
196 cal.setTime(D, status);
197 int e = cal.get(UCAL_ERA, status);
198 int y = cal.get(UCAL_YEAR, status);
199 #ifdef U_DEBUG_DUMPCALS
200 logln((UnicodeString)"cal : " + CalendarTest::calToStr(cal));
201 logln((UnicodeString)"grego: " + CalendarTest::calToStr(*grego));
202 #endif
203 if (y == year && e == era) {
204 logln((UnicodeString)"OK: " + D + " => " + cal.get(UCAL_ERA, status) + ":" +
205 cal.get(UCAL_YEAR, status) + "/" +
206 (cal.get(UCAL_MONTH, status)+1) + "/" + cal.get(UCAL_DATE, status) + " (" + UnicodeString(cal.getType()) + ")");
207 } else {
208 errln((UnicodeString)"Fail: (millis to fields)" + D + " => " + cal.get(UCAL_ERA, status) + ":" +
209 cal.get(UCAL_YEAR, status) + "/" +
210 (cal.get(UCAL_MONTH, status)+1) + "/" + cal.get(UCAL_DATE, status) +
211 ", expected " + era + ":" + year + "/" + (month+1) + "/" +
212 dayOfMonth + " (" + UnicodeString(cal.getType()));
213 }
214 }
215 delete grego;
216 CHECK(status, "err during quasiGregorianTest()");
217 }
218
219 // Verify that Gregorian works like Gregorian
220 void IntlCalendarTest::TestGregorian() {
221 UDate timeA = Calendar::getNow();
222 int32_t data[] = {
223 GregorianCalendar::AD, 1868, 1868, UCAL_SEPTEMBER, 8,
224 GregorianCalendar::AD, 1868, 1868, UCAL_SEPTEMBER, 9,
225 GregorianCalendar::AD, 1869, 1869, UCAL_JUNE, 4,
226 GregorianCalendar::AD, 1912, 1912, UCAL_JULY, 29,
227 GregorianCalendar::AD, 1912, 1912, UCAL_JULY, 30,
228 GregorianCalendar::AD, 1912, 1912, UCAL_AUGUST, 1,
229 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
230 };
231
232 Calendar *cal;
233 UErrorCode status = U_ZERO_ERROR;
234 cal = Calendar::createInstance(/*"de_DE", */ status);
235 CHECK(status, UnicodeString("Creating de_CH calendar"));
236 // Sanity check the calendar
237 UDate timeB = Calendar::getNow();
238 UDate timeCal = cal->getTime(status);
239
240 if(!(timeA <= timeCal) || !(timeCal <= timeB)) {
241 errln((UnicodeString)"Error: Calendar time " + timeCal +
242 " is not within sampled times [" + timeA + " to " + timeB + "]!");
243 }
244 // end sanity check
245
246 // Note, the following is a good way to test the sanity of the constructed calendars,
247 // using Collation as a delay-loop:
248 //
249 // $ intltest format/IntlCalendarTest collate/G7CollationTest format/IntlCalendarTest
250
251 quasiGregorianTest(*cal,Locale("fr_FR"),data);
252 delete cal;
253 }
254
255 /**
256 * Verify that BuddhistCalendar shifts years to Buddhist Era but otherwise
257 * behaves like GregorianCalendar.
258 */
259 void IntlCalendarTest::TestBuddhist() {
260 // BE 2542 == 1999 CE
261 UDate timeA = Calendar::getNow();
262
263 int32_t data[] = {
264 0, // B. era [928479600000]
265 2542, // B. year
266 1999, // G. year
267 UCAL_JUNE, // month
268 4, // day
269
270 0, // B. era [-79204842000000]
271 3, // B. year
272 -540, // G. year
273 UCAL_FEBRUARY, // month
274 12, // day
275
276 0, // test month calculation: 4795 BE = 4252 AD is a leap year, but 4795 AD is not.
277 4795, // BE [72018057600000]
278 4252, // AD
279 UCAL_FEBRUARY,
280 29,
281
282 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1
283 };
284 Calendar *cal;
285 UErrorCode status = U_ZERO_ERROR;
286 cal = Calendar::createInstance("th_TH@calendar=buddhist", status);
287 CHECK(status, UnicodeString("Creating th_TH@calendar=buddhist calendar"));
288
289 // Sanity check the calendar
290 UDate timeB = Calendar::getNow();
291 UDate timeCal = cal->getTime(status);
292
293 if(!(timeA <= timeCal) || !(timeCal <= timeB)) {
294 errln((UnicodeString)"Error: Calendar time " + timeCal +
295 " is not within sampled times [" + timeA + " to " + timeB + "]!");
296 }
297 // end sanity check
298
299
300 quasiGregorianTest(*cal,Locale("th_TH@calendar=gregorian"),data);
301 delete cal;
302 }
303
304
305 /**
306 * Verify that TaiWanCalendar shifts years to Minguo Era but otherwise
307 * behaves like GregorianCalendar.
308 */
309 void IntlCalendarTest::TestTaiwan() {
310 // MG 1 == 1912 AD
311 UDate timeA = Calendar::getNow();
312
313 // TODO port these to the data items
314 int32_t data[] = {
315 1, // B. era [928479600000]
316 1, // B. year
317 1912, // G. year
318 UCAL_JUNE, // month
319 4, // day
320
321 1, // B. era [-79204842000000]
322 3, // B. year
323 1914, // G. year
324 UCAL_FEBRUARY, // month
325 12, // day
326
327 1, // B. era [-79204842000000]
328 96, // B. year
329 2007, // G. year
330 UCAL_FEBRUARY, // month
331 12, // day
332
333 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1
334 };
335 Calendar *cal;
336 UErrorCode status = U_ZERO_ERROR;
337 cal = Calendar::createInstance("en_US@calendar=roc", status);
338 CHECK(status, UnicodeString("Creating en_US@calendar=roc calendar"));
339
340 // Sanity check the calendar
341 UDate timeB = Calendar::getNow();
342 UDate timeCal = cal->getTime(status);
343
344 if(!(timeA <= timeCal) || !(timeCal <= timeB)) {
345 errln((UnicodeString)"Error: Calendar time " + timeCal +
346 " is not within sampled times [" + timeA + " to " + timeB + "]!");
347 }
348 // end sanity check
349
350
351 quasiGregorianTest(*cal,Locale("en_US"),data);
352 delete cal;
353 }
354
355
356
357 /**
358 * Verify that JapaneseCalendar shifts years to Japanese Eras but otherwise
359 * behaves like GregorianCalendar.
360 */
361 void IntlCalendarTest::TestJapanese() {
362 UDate timeA = Calendar::getNow();
363
364 /* Sorry.. japancal.h is private! */
365 #define JapaneseCalendar_MEIJI 232
366 #define JapaneseCalendar_TAISHO 233
367 #define JapaneseCalendar_SHOWA 234
368 #define JapaneseCalendar_HEISEI 235
369
370 // BE 2542 == 1999 CE
371 int32_t data[] = {
372 // Jera Jyr Gyear m d
373 JapaneseCalendar_MEIJI, 1, 1868, UCAL_SEPTEMBER, 8,
374 JapaneseCalendar_MEIJI, 1, 1868, UCAL_SEPTEMBER, 9,
375 JapaneseCalendar_MEIJI, 2, 1869, UCAL_JUNE, 4,
376 JapaneseCalendar_MEIJI, 45, 1912, UCAL_JULY, 29,
377 JapaneseCalendar_TAISHO, 1, 1912, UCAL_JULY, 30,
378 JapaneseCalendar_TAISHO, 1, 1912, UCAL_AUGUST, 1,
379
380 // new tests (not in java)
381 JapaneseCalendar_SHOWA, 64, 1989, UCAL_JANUARY, 7, // Test current era transition (different code path than others)
382 JapaneseCalendar_HEISEI, 1, 1989, UCAL_JANUARY, 8,
383 JapaneseCalendar_HEISEI, 1, 1989, UCAL_JANUARY, 9,
384 JapaneseCalendar_HEISEI, 1, 1989, UCAL_DECEMBER, 20,
385 JapaneseCalendar_HEISEI, 15, 2003, UCAL_MAY, 22,
386 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1
387 };
388
389 Calendar *cal;
390 UErrorCode status = U_ZERO_ERROR;
391 cal = Calendar::createInstance("ja_JP@calendar=japanese", status);
392 CHECK(status, UnicodeString("Creating ja_JP@calendar=japanese calendar"));
393 // Sanity check the calendar
394 UDate timeB = Calendar::getNow();
395 UDate timeCal = cal->getTime(status);
396
397 if(!(timeA <= timeCal) || !(timeCal <= timeB)) {
398 errln((UnicodeString)"Error: Calendar time " + timeCal +
399 " is not within sampled times [" + timeA + " to " + timeB + "]!");
400 }
401 // end sanity check
402 quasiGregorianTest(*cal,Locale("ja_JP"),data);
403 delete cal;
404 }
405
406
407
408 void IntlCalendarTest::TestBuddhistFormat() {
409 UErrorCode status = U_ZERO_ERROR;
410
411 // Test simple parse/format with adopt
412
413 // First, a contrived english test..
414 UDate aDate = 999932400000.0;
415 SimpleDateFormat *fmt = new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"), Locale("en_US@calendar=buddhist"), status);
416 CHECK(status, "creating date format instance");
417 SimpleDateFormat *fmt2 = new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"), Locale("en_US@calendar=gregorian"), status);
418 CHECK(status, "creating gregorian date format instance");
419 if(!fmt) {
420 errln("Coudln't create en_US instance");
421 } else {
422 UnicodeString str;
423 fmt2->format(aDate, str);
424 logln(UnicodeString() + "Test Date: " + str);
425 str.remove();
426 fmt->format(aDate, str);
427 logln(UnicodeString() + "as Buddhist Calendar: " + escape(str));
428 UnicodeString expected("September 8, 2544 BE");
429 if(str != expected) {
430 errln("Expected " + escape(expected) + " but got " + escape(str));
431 }
432 UDate otherDate = fmt->parse(expected, status);
433 if(otherDate != aDate) {
434 UnicodeString str3;
435 fmt->format(otherDate, str3);
436 errln("Parse incorrect of " + escape(expected) + " - wanted " + aDate + " but got " + otherDate + ", " + escape(str3));
437 } else {
438 logln("Parsed OK: " + expected);
439 }
440 delete fmt;
441 }
442 delete fmt2;
443
444 CHECK(status, "Error occured testing Buddhist Calendar in English ");
445
446 status = U_ZERO_ERROR;
447 // Now, try in Thai
448 {
449 UnicodeString expect = CharsToUnicodeString("\\u0E27\\u0E31\\u0E19\\u0E40\\u0E2A\\u0E32\\u0E23\\u0E4C\\u0E17\\u0E35\\u0E48"
450 " 8 \\u0E01\\u0E31\\u0e19\\u0e22\\u0e32\\u0e22\\u0e19 \\u0e1e.\\u0e28. 2544");
451 UDate expectDate = 999932400000.0;
452 Locale loc("th_TH_TRADITIONAL"); // legacy
453
454 simpleTest(loc, expect, expectDate, status);
455 }
456 status = U_ZERO_ERROR;
457 {
458 UnicodeString expect = CharsToUnicodeString("\\u0E27\\u0E31\\u0E19\\u0E40\\u0E2A\\u0E32\\u0E23\\u0E4C\\u0E17\\u0E35\\u0E48"
459 " 8 \\u0E01\\u0E31\\u0e19\\u0e22\\u0e32\\u0e22\\u0e19 \\u0e1e.\\u0e28. 2544");
460 UDate expectDate = 999932400000.0;
461 Locale loc("th_TH@calendar=buddhist");
462
463 simpleTest(loc, expect, expectDate, status);
464 }
465 status = U_ZERO_ERROR;
466 {
467 UnicodeString expect = CharsToUnicodeString("\\u0E27\\u0E31\\u0E19\\u0E40\\u0E2A\\u0E32\\u0E23\\u0E4C\\u0E17\\u0E35\\u0E48"
468 " 8 \\u0E01\\u0E31\\u0e19\\u0e22\\u0e32\\u0e22\\u0e19 \\u0e04.\\u0e28. 2001");
469 UDate expectDate = 999932400000.0;
470 Locale loc("th_TH@calendar=gregorian");
471
472 simpleTest(loc, expect, expectDate, status);
473 }
474 status = U_ZERO_ERROR;
475 {
476 UnicodeString expect = CharsToUnicodeString("\\u0E27\\u0E31\\u0E19\\u0E40\\u0E2A\\u0E32\\u0E23\\u0E4C\\u0E17\\u0E35\\u0E48"
477 " 8 \\u0E01\\u0E31\\u0e19\\u0e22\\u0e32\\u0e22\\u0e19 \\u0e04.\\u0e28. 2001");
478 UDate expectDate = 999932400000.0;
479 Locale loc("th_TH_TRADITIONAL@calendar=gregorian");
480
481 simpleTest(loc, expect, expectDate, status);
482 }
483 }
484
485 // TaiwanFormat has been moved to testdata/format.txt
486
487
488 void IntlCalendarTest::TestJapaneseFormat() {
489 Calendar *cal;
490 UErrorCode status = U_ZERO_ERROR;
491 cal = Calendar::createInstance("ja_JP_TRADITIONAL", status);
492 CHECK(status, UnicodeString("Creating ja_JP_TRADITIONAL calendar"));
493
494 Calendar *cal2 = cal->clone();
495 delete cal;
496 cal = NULL;
497
498 // Test simple parse/format with adopt
499
500 UDate aDate = 999932400000.0;
501 SimpleDateFormat *fmt = new SimpleDateFormat(UnicodeString("MMMM d, yy G"), Locale("en_US@calendar=japanese"), status);
502 SimpleDateFormat *fmt2 = new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"), Locale("en_US@calendar=gregorian"), status);
503 CHECK(status, "creating date format instance");
504 if(!fmt) {
505 errln("Coudln't create en_US instance");
506 } else {
507 UnicodeString str;
508 fmt2->format(aDate, str);
509 logln(UnicodeString() + "Test Date: " + str);
510 str.remove();
511 fmt->format(aDate, str);
512 logln(UnicodeString() + "as Japanese Calendar: " + str);
513 UnicodeString expected("September 8, 13 Heisei");
514 if(str != expected) {
515 errln("Expected " + expected + " but got " + str);
516 }
517 UDate otherDate = fmt->parse(expected, status);
518 if(otherDate != aDate) {
519 UnicodeString str3;
520 ParsePosition pp;
521 fmt->parse(expected, *cal2, pp);
522 fmt->format(otherDate, str3);
523 errln("Parse incorrect of " + expected + " - wanted " + aDate + " but got " + " = " + otherDate + ", " + str3 + " = " + CalendarTest::calToStr(*cal2) );
524
525 } else {
526 logln("Parsed OK: " + expected);
527 }
528 delete fmt;
529 }
530
531 // Test parse with incomplete information
532 fmt = new SimpleDateFormat(UnicodeString("G y"), Locale("en_US@calendar=japanese"), status);
533 aDate = -3197117222000.0;
534 CHECK(status, "creating date format instance");
535 if(!fmt) {
536 errln("Coudln't create en_US instance");
537 } else {
538 UnicodeString str;
539 fmt2->format(aDate, str);
540 logln(UnicodeString() + "Test Date: " + str);
541 str.remove();
542 fmt->format(aDate, str);
543 logln(UnicodeString() + "as Japanese Calendar: " + str);
544 UnicodeString expected("Meiji 1");
545 if(str != expected) {
546 errln("Expected " + expected + " but got " + str);
547 }
548 UDate otherDate = fmt->parse(expected, status);
549 if(otherDate != aDate) {
550 UnicodeString str3;
551 ParsePosition pp;
552 fmt->parse(expected, *cal2, pp);
553 fmt->format(otherDate, str3);
554 errln("Parse incorrect of " + expected + " - wanted " + aDate + " but got " + " = " +
555 otherDate + ", " + str3 + " = " + CalendarTest::calToStr(*cal2) );
556 } else {
557 logln("Parsed OK: " + expected);
558 }
559 delete fmt;
560 }
561
562 delete cal2;
563 delete fmt2;
564 CHECK(status, "Error occured");
565
566 // Now, try in Japanese
567 {
568 UnicodeString expect = CharsToUnicodeString("\\u5e73\\u621013\\u5e749\\u67088\\u65e5\\u571f\\u66dc\\u65e5");
569 UDate expectDate = 999932400000.0; // Testing a recent date
570 Locale loc("ja_JP@calendar=japanese");
571
572 status = U_ZERO_ERROR;
573 simpleTest(loc, expect, expectDate, status);
574 }
575 {
576 UnicodeString expect = CharsToUnicodeString("\\u5e73\\u621013\\u5e749\\u67088\\u65e5\\u571f\\u66dc\\u65e5");
577 UDate expectDate = 999932400000.0; // Testing a recent date
578 Locale loc("ja_JP_TRADITIONAL"); // legacy
579
580 status = U_ZERO_ERROR;
581 simpleTest(loc, expect, expectDate, status);
582 }
583 {
584 UnicodeString expect = CharsToUnicodeString("\\u5b89\\u6c385\\u5e747\\u67084\\u65e5\\u6728\\u66dc\\u65e5");
585 UDate expectDate = -6106032422000.0; // 1776-07-04T00:00:00Z-075258
586 Locale loc("ja_JP@calendar=japanese");
587
588 status = U_ZERO_ERROR;
589 simpleTest(loc, expect, expectDate, status);
590
591 }
592 { // Jitterbug 1869 - this is an ambiguous era. (Showa 64 = Jan 6 1989, but Showa could be 2 other eras) )
593 UnicodeString expect = CharsToUnicodeString("\\u662d\\u548c64\\u5e741\\u67086\\u65e5\\u91d1\\u66dc\\u65e5");
594 UDate expectDate = 600076800000.0;
595 Locale loc("ja_JP@calendar=japanese");
596
597 status = U_ZERO_ERROR;
598 simpleTest(loc, expect, expectDate, status);
599
600 }
601 { // This Feb 29th falls on a leap year by gregorian year, but not by Japanese year.
602 UnicodeString expect = CharsToUnicodeString("\\u5EB7\\u6B632\\u5e742\\u670829\\u65e5\\u65e5\\u66dc\\u65e5");
603 UDate expectDate = -16214400422000.0; // 1456-03-09T00:00Z-075258
604 Locale loc("ja_JP@calendar=japanese");
605
606 status = U_ZERO_ERROR;
607 simpleTest(loc, expect, expectDate, status);
608
609 }
610 }
611
612 void IntlCalendarTest::TestJapanese3860()
613 {
614 Calendar *cal;
615 UErrorCode status = U_ZERO_ERROR;
616 cal = Calendar::createInstance("ja_JP@calendar=japanese", status);
617 CHECK(status, UnicodeString("Creating ja_JP@calendar=japanese calendar"));
618 Calendar *cal2 = cal->clone();
619 SimpleDateFormat *fmt2 = new SimpleDateFormat(UnicodeString("HH:mm:ss.S MMMM d, yyyy G"), Locale("en_US@calendar=gregorian"), status);
620 UnicodeString str;
621
622
623 {
624 // Test simple parse/format with adopt
625 UDate aDate = 0;
626
627 // Test parse with missing era (should default to current era, heisei)
628 // Test parse with incomplete information
629 logln("Testing parse w/ missing era...");
630 SimpleDateFormat *fmt = new SimpleDateFormat(UnicodeString("y.M.d"), Locale("ja_JP@calendar=japanese"), status);
631 CHECK(status, "creating date format instance");
632 if(!fmt) {
633 errln("Coudln't create en_US instance");
634 } else {
635 UErrorCode s2 = U_ZERO_ERROR;
636 cal2->clear();
637 UnicodeString samplestr("1.1.9");
638 logln(UnicodeString() + "Test Year: " + samplestr);
639 aDate = fmt->parse(samplestr, s2);
640 ParsePosition pp=0;
641 fmt->parse(samplestr, *cal2, pp);
642 CHECK(s2, "parsing the 1.1.9 string");
643 logln("*cal2 after 119 parse:");
644 str.remove();
645 fmt2->format(aDate, str);
646 logln(UnicodeString() + "as Gregorian Calendar: " + str);
647
648 cal2->setTime(aDate, s2);
649 int32_t gotYear = cal2->get(UCAL_YEAR, s2);
650 int32_t gotEra = cal2->get(UCAL_ERA, s2);
651 int32_t expectYear = 1;
652 int32_t expectEra = JapaneseCalendar::getCurrentEra();
653 if((gotYear!=1) || (gotEra != expectEra)) {
654 errln(UnicodeString("parse "+samplestr+" of 'y.m.d' as Japanese Calendar, expected year ") + expectYear +
655 UnicodeString(" and era ") + expectEra +", but got year " + gotYear + " and era " + gotEra + " (Gregorian:" + str +")");
656 } else {
657 logln(UnicodeString() + " year: " + gotYear + ", era: " + gotEra);
658 }
659 delete fmt;
660 }
661 }
662
663 {
664 // Test simple parse/format with adopt
665 UDate aDate = 0;
666
667 // Test parse with missing era (should default to current era, heisei)
668 // Test parse with incomplete information
669 logln("Testing parse w/ just year...");
670 SimpleDateFormat *fmt = new SimpleDateFormat(UnicodeString("y"), Locale("ja_JP@calendar=japanese"), status);
671 CHECK(status, "creating date format instance");
672 if(!fmt) {
673 errln("Coudln't create en_US instance");
674 } else {
675 UErrorCode s2 = U_ZERO_ERROR;
676 cal2->clear();
677 UnicodeString samplestr("1");
678 logln(UnicodeString() + "Test Year: " + samplestr);
679 aDate = fmt->parse(samplestr, s2);
680 ParsePosition pp=0;
681 fmt->parse(samplestr, *cal2, pp);
682 CHECK(s2, "parsing the 1 string");
683 logln("*cal2 after 1 parse:");
684 str.remove();
685 fmt2->format(aDate, str);
686 logln(UnicodeString() + "as Gregorian Calendar: " + str);
687
688 cal2->setTime(aDate, s2);
689 int32_t gotYear = cal2->get(UCAL_YEAR, s2);
690 int32_t gotEra = cal2->get(UCAL_ERA, s2);
691 int32_t expectYear = 1;
692 int32_t expectEra = 235; //JapaneseCalendar::kCurrentEra;
693 if((gotYear!=1) || (gotEra != expectEra)) {
694 errln(UnicodeString("parse "+samplestr+" of 'y' as Japanese Calendar, expected year ") + expectYear +
695 UnicodeString(" and era ") + expectEra +", but got year " + gotYear + " and era " + gotEra + " (Gregorian:" + str +")");
696 } else {
697 logln(UnicodeString() + " year: " + gotYear + ", era: " + gotEra);
698 }
699 delete fmt;
700 }
701 }
702
703 delete cal2;
704 delete cal;
705 delete fmt2;
706 }
707
708
709
710
711 /**
712 * Verify the Persian Calendar.
713 */
714 void IntlCalendarTest::TestPersian() {
715 UDate timeA = Calendar::getNow();
716
717 Calendar *cal;
718 UErrorCode status = U_ZERO_ERROR;
719 cal = Calendar::createInstance("fa_IR@calendar=persian", status);
720 CHECK(status, UnicodeString("Creating fa_IR@calendar=persian calendar"));
721 // Sanity check the calendar
722 UDate timeB = Calendar::getNow();
723 UDate timeCal = cal->getTime(status);
724
725 if(!(timeA <= timeCal) || !(timeCal <= timeB)) {
726 errln((UnicodeString)"Error: Calendar time " + timeCal +
727 " is not within sampled times [" + timeA + " to " + timeB + "]!");
728 }
729 // end sanity check
730
731 // Test various dates to be sure of validity
732 int32_t data[] = {
733 1925, 4, 24, 1304, 2, 4,
734 2011, 1, 11, 1389, 10, 21,
735 1986, 2, 25, 1364, 12, 6,
736 1934, 3, 14, 1312, 12, 23,
737
738 2090, 3, 19, 1468, 12, 29,
739 2007, 2, 22, 1385, 12, 3,
740 1969, 12, 31, 1348, 10, 10,
741 1945, 11, 12, 1324, 8, 21,
742 1925, 3, 31, 1304, 1, 11,
743
744 1996, 3, 19, 1374, 12, 29,
745 1996, 3, 20, 1375, 1, 1,
746 1997, 3, 20, 1375, 12, 30,
747 1997, 3, 21, 1376, 1, 1,
748
749 2008, 3, 19, 1386, 12, 29,
750 2008, 3, 20, 1387, 1, 1,
751 2004, 3, 19, 1382, 12, 29,
752 2004, 3, 20, 1383, 1, 1,
753
754 2006, 3, 20, 1384, 12, 29,
755 2006, 3, 21, 1385, 1, 1,
756
757 2005, 4, 20, 1384, 1, 31,
758 2005, 4, 21, 1384, 2, 1,
759 2005, 5, 21, 1384, 2, 31,
760 2005, 5, 22, 1384, 3, 1,
761 2005, 6, 21, 1384, 3, 31,
762 2005, 6, 22, 1384, 4, 1,
763 2005, 7, 22, 1384, 4, 31,
764 2005, 7, 23, 1384, 5, 1,
765 2005, 8, 22, 1384, 5, 31,
766 2005, 8, 23, 1384, 6, 1,
767 2005, 9, 22, 1384, 6, 31,
768 2005, 9, 23, 1384, 7, 1,
769 2005, 10, 22, 1384, 7, 30,
770 2005, 10, 23, 1384, 8, 1,
771 2005, 11, 21, 1384, 8, 30,
772 2005, 11, 22, 1384, 9, 1,
773 2005, 12, 21, 1384, 9, 30,
774 2005, 12, 22, 1384, 10, 1,
775 2006, 1, 20, 1384, 10, 30,
776 2006, 1, 21, 1384, 11, 1,
777 2006, 2, 19, 1384, 11, 30,
778 2006, 2, 20, 1384, 12, 1,
779 2006, 3, 20, 1384, 12, 29,
780 2006, 3, 21, 1385, 1, 1,
781
782 // The 2820-year cycle arithmetical algorithm would fail this one.
783 2025, 3, 21, 1404, 1, 1,
784
785 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1
786 };
787
788 Calendar *grego = Calendar::createInstance("fa_IR@calendar=gregorian", status);
789 for (int32_t i=0; data[i]!=-1; ) {
790 int32_t gregYear = data[i++];
791 int32_t gregMonth = data[i++]-1;
792 int32_t gregDay = data[i++];
793 int32_t persYear = data[i++];
794 int32_t persMonth = data[i++]-1;
795 int32_t persDay = data[i++];
796
797 // Test conversion from Persian dates
798 grego->clear();
799 grego->set(gregYear, gregMonth, gregDay);
800
801 cal->clear();
802 cal->set(persYear, persMonth, persDay);
803
804 UDate persTime = cal->getTime(status);
805 UDate gregTime = grego->getTime(status);
806
807 if (persTime != gregTime) {
808 errln(UnicodeString("Expected ") + gregTime + " but got " + persTime);
809 }
810
811 // Test conversion to Persian dates
812 cal->clear();
813 cal->setTime(gregTime, status);
814
815 int32_t computedYear = cal->get(UCAL_YEAR, status);
816 int32_t computedMonth = cal->get(UCAL_MONTH, status);
817 int32_t computedDay = cal->get(UCAL_DATE, status);
818
819 if ((persYear != computedYear) ||
820 (persMonth != computedMonth) ||
821 (persDay != computedDay)) {
822 errln(UnicodeString("Expected ") + persYear + "/" + (persMonth+1) + "/" + persDay +
823 " but got " + computedYear + "/" + (computedMonth+1) + "/" + computedDay);
824 }
825
826 }
827
828 delete cal;
829 delete grego;
830 }
831
832 void IntlCalendarTest::TestPersianFormat() {
833 UErrorCode status = U_ZERO_ERROR;
834 SimpleDateFormat *fmt = new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"), Locale(" en_US@calendar=persian"), status);
835 CHECK(status, "creating date format instance");
836 SimpleDateFormat *fmt2 = new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"), Locale("en_US@calendar=gregorian"), status);
837 CHECK(status, "creating gregorian date format instance");
838 UnicodeString gregorianDate("January 18, 2007 AD");
839 UDate aDate = fmt2->parse(gregorianDate, status);
840 if(!fmt) {
841 errln("Coudln't create en_US instance");
842 } else {
843 UnicodeString str;
844 fmt->format(aDate, str);
845 logln(UnicodeString() + "as Persian Calendar: " + escape(str));
846 UnicodeString expected("Dey 28, 1385 AP");
847 if(str != expected) {
848 errln("Expected " + escape(expected) + " but got " + escape(str));
849 }
850 UDate otherDate = fmt->parse(expected, status);
851 if(otherDate != aDate) {
852 UnicodeString str3;
853 fmt->format(otherDate, str3);
854 errln("Parse incorrect of " + escape(expected) + " - wanted " + aDate + " but got " + otherDate + ", " + escape(str3));
855 } else {
856 logln("Parsed OK: " + expected);
857 }
858 // Two digit year parsing problem #4732
859 fmt->applyPattern("yy-MM-dd");
860 str.remove();
861 fmt->format(aDate, str);
862 expected.setTo("85-10-28");
863 if(str != expected) {
864 errln("Expected " + escape(expected) + " but got " + escape(str));
865 }
866 otherDate = fmt->parse(expected, status);
867 if (otherDate != aDate) {
868 errln("Parse incorrect of " + escape(expected) + " - wanted " + aDate + " but got " + otherDate);
869 } else {
870 logln("Parsed OK: " + expected);
871 }
872 delete fmt;
873 }
874 delete fmt2;
875
876 CHECK(status, "Error occured testing Persian Calendar in English ");
877 }
878
879
880 void IntlCalendarTest::simpleTest(const Locale& loc, const UnicodeString& expect, UDate expectDate, UErrorCode& status)
881 {
882 UnicodeString tmp;
883 UDate d;
884 DateFormat *fmt0 = DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull);
885
886 logln("Try format/parse of " + (UnicodeString)loc.getName());
887 DateFormat *fmt2 = DateFormat::createDateInstance(DateFormat::kFull, loc);
888 if(fmt2) {
889 fmt2->format(expectDate, tmp);
890 logln(escape(tmp) + " ( in locale " + loc.getName() + ")");
891 if(tmp != expect) {
892 errln(UnicodeString("Failed to format " ) + loc.getName() + " expected " + escape(expect) + " got " + escape(tmp) );
893 }
894
895 d = fmt2->parse(expect,status);
896 CHECK(status, "Error occured parsing " + UnicodeString(loc.getName()));
897 if(d != expectDate) {
898 fmt2->format(d,tmp);
899 errln(UnicodeString("Failed to parse " ) + escape(expect) + ", " + loc.getName() + " expect " + (double)expectDate + " got " + (double)d + " " + escape(tmp));
900 logln( "wanted " + escape(fmt0->format(expectDate,tmp.remove())) + " but got " + escape(fmt0->format(d,tmp.remove())));
901 }
902 delete fmt2;
903 } else {
904 errln((UnicodeString)"Can't create " + loc.getName() + " date instance");
905 }
906 delete fmt0;
907 }
908
909 #undef CHECK
910
911 #endif /* #if !UCONFIG_NO_FORMATTING */
912
913 //eof