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