]>
Commit | Line | Data |
---|---|---|
374ca955 | 1 | /*********************************************************************** |
b75a7d8f | 2 | * COPYRIGHT: |
57a6839d | 3 | * Copyright (c) 1997-2014, 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 | ||
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 | // ***************************************************************************** | |
374ca955 A |
55 | //--- move to CalendarTest? |
56 | ||
b75a7d8f A |
57 | // Turn this on to dump the calendar fields |
58 | #define U_DEBUG_DUMPCALS | |
59 | ||
b75a7d8f A |
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); | |
73c04bcf | 74 | CASE(6,TestJapanese3860); |
46f4442e A |
75 | CASE(7,TestPersian); |
76 | CASE(8,TestPersianFormat); | |
77 | CASE(9,TestTaiwan); | |
b75a7d8f A |
78 | default: name = ""; break; |
79 | } | |
80 | } | |
81 | ||
82 | #undef CASE | |
83 | ||
84 | // --------------------------------------------------------------------------------- | |
85 | ||
b75a7d8f A |
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", | |
374ca955 A |
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", | |
b75a7d8f A |
101 | "ja_JP_TRADITIONAL", |
102 | "th_TH_TRADITIONAL", | |
374ca955 | 103 | "th_TH_TRADITIONAL@calendar=gregorian", |
729e4ab9 A |
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 }; | |
b75a7d8f | 110 | const char *types[40] = { "gregorian", |
374ca955 A |
111 | "japanese", |
112 | "gregorian", | |
113 | "japanese", | |
729e4ab9 | 114 | "buddhist", |
b75a7d8f A |
115 | "japanese", |
116 | "buddhist", | |
374ca955 | 117 | "gregorian", |
729e4ab9 A |
118 | "gregorian", |
119 | "buddhist", | |
120 | "buddhist", | |
121 | "buddhist", | |
122 | "gregorian", | |
123 | NULL }; | |
b75a7d8f A |
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])) { | |
729e4ab9 | 133 | dataerrln(UnicodeString(locs[j]) + UnicodeString("Calendar type ") + c->getType() + " instead of " + types[j]); |
b75a7d8f A |
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); | |
73c04bcf A |
156 | if (U_FAILURE(status)) { |
157 | dataerrln("Error calling Calendar::createInstance"); | |
158 | return; | |
159 | } | |
b75a7d8f A |
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 | |
374ca955 A |
183 | logln((UnicodeString)"cal : " + CalendarTest::calToStr(cal)); |
184 | logln((UnicodeString)"grego: " + CalendarTest::calToStr(*grego)); | |
b75a7d8f A |
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 | |
374ca955 A |
200 | logln((UnicodeString)"cal : " + CalendarTest::calToStr(cal)); |
201 | logln((UnicodeString)"grego: " + CalendarTest::calToStr(*grego)); | |
b75a7d8f A |
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[] = { | |
374ca955 | 264 | 0, // B. era [928479600000] |
b75a7d8f A |
265 | 2542, // B. year |
266 | 1999, // G. year | |
267 | UCAL_JUNE, // month | |
268 | 4, // day | |
269 | ||
374ca955 | 270 | 0, // B. era [-79204842000000] |
b75a7d8f A |
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. | |
374ca955 | 277 | 4795, // BE [72018057600000] |
b75a7d8f A |
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; | |
374ca955 A |
286 | cal = Calendar::createInstance("th_TH@calendar=buddhist", status); |
287 | CHECK(status, UnicodeString("Creating th_TH@calendar=buddhist calendar")); | |
b75a7d8f A |
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 | ||
46f4442e | 300 | quasiGregorianTest(*cal,Locale("th_TH@calendar=gregorian"),data); |
b75a7d8f A |
301 | delete cal; |
302 | } | |
303 | ||
46f4442e A |
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 | ||
b75a7d8f A |
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; | |
374ca955 A |
391 | cal = Calendar::createInstance("ja_JP@calendar=japanese", status); |
392 | CHECK(status, UnicodeString("Creating ja_JP@calendar=japanese calendar")); | |
b75a7d8f A |
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 | ||
46f4442e A |
406 | |
407 | ||
b75a7d8f | 408 | void IntlCalendarTest::TestBuddhistFormat() { |
b75a7d8f | 409 | UErrorCode status = U_ZERO_ERROR; |
b75a7d8f A |
410 | |
411 | // Test simple parse/format with adopt | |
412 | ||
413 | // First, a contrived english test.. | |
414 | UDate aDate = 999932400000.0; | |
374ca955 | 415 | SimpleDateFormat *fmt = new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"), Locale("en_US@calendar=buddhist"), status); |
b75a7d8f | 416 | CHECK(status, "creating date format instance"); |
374ca955 A |
417 | SimpleDateFormat *fmt2 = new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"), Locale("en_US@calendar=gregorian"), status); |
418 | CHECK(status, "creating gregorian date format instance"); | |
b75a7d8f A |
419 | if(!fmt) { |
420 | errln("Coudln't create en_US instance"); | |
421 | } else { | |
422 | UnicodeString str; | |
374ca955 | 423 | fmt2->format(aDate, str); |
b75a7d8f A |
424 | logln(UnicodeString() + "Test Date: " + str); |
425 | str.remove(); | |
b75a7d8f A |
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 | } | |
374ca955 | 442 | delete fmt2; |
b75a7d8f A |
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; | |
374ca955 A |
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"); | |
b75a7d8f A |
480 | |
481 | simpleTest(loc, expect, expectDate, status); | |
482 | } | |
483 | } | |
484 | ||
46f4442e A |
485 | // TaiwanFormat has been moved to testdata/format.txt |
486 | ||
b75a7d8f A |
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(); | |
374ca955 A |
495 | delete cal; |
496 | cal = NULL; | |
b75a7d8f A |
497 | |
498 | // Test simple parse/format with adopt | |
499 | ||
500 | UDate aDate = 999932400000.0; | |
374ca955 | 501 | SimpleDateFormat *fmt = new SimpleDateFormat(UnicodeString("MMMM d, yy G"), Locale("en_US@calendar=japanese"), status); |
73c04bcf | 502 | SimpleDateFormat *fmt2 = new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"), Locale("en_US@calendar=gregorian"), status); |
b75a7d8f A |
503 | CHECK(status, "creating date format instance"); |
504 | if(!fmt) { | |
505 | errln("Coudln't create en_US instance"); | |
506 | } else { | |
507 | UnicodeString str; | |
374ca955 | 508 | fmt2->format(aDate, str); |
b75a7d8f A |
509 | logln(UnicodeString() + "Test Date: " + str); |
510 | str.remove(); | |
b75a7d8f A |
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); | |
374ca955 | 523 | errln("Parse incorrect of " + expected + " - wanted " + aDate + " but got " + " = " + otherDate + ", " + str3 + " = " + CalendarTest::calToStr(*cal2) ); |
b75a7d8f A |
524 | |
525 | } else { | |
526 | logln("Parsed OK: " + expected); | |
527 | } | |
528 | delete fmt; | |
529 | } | |
530 | ||
531 | // Test parse with incomplete information | |
374ca955 | 532 | fmt = new SimpleDateFormat(UnicodeString("G y"), Locale("en_US@calendar=japanese"), status); |
729e4ab9 | 533 | aDate = -3197117222000.0; |
b75a7d8f A |
534 | CHECK(status, "creating date format instance"); |
535 | if(!fmt) { | |
536 | errln("Coudln't create en_US instance"); | |
537 | } else { | |
538 | UnicodeString str; | |
374ca955 | 539 | fmt2->format(aDate, str); |
b75a7d8f A |
540 | logln(UnicodeString() + "Test Date: " + str); |
541 | str.remove(); | |
b75a7d8f A |
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 " + " = " + | |
374ca955 | 555 | otherDate + ", " + str3 + " = " + CalendarTest::calToStr(*cal2) ); |
b75a7d8f A |
556 | } else { |
557 | logln("Parsed OK: " + expected); | |
558 | } | |
559 | delete fmt; | |
560 | } | |
561 | ||
b75a7d8f | 562 | delete cal2; |
374ca955 | 563 | delete fmt2; |
b75a7d8f A |
564 | CHECK(status, "Error occured"); |
565 | ||
566 | // Now, try in Japanese | |
567 | { | |
374ca955 A |
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"); | |
b75a7d8f | 577 | UDate expectDate = 999932400000.0; // Testing a recent date |
374ca955 | 578 | Locale loc("ja_JP_TRADITIONAL"); // legacy |
b75a7d8f A |
579 | |
580 | status = U_ZERO_ERROR; | |
581 | simpleTest(loc, expect, expectDate, status); | |
582 | } | |
583 | { | |
374ca955 | 584 | UnicodeString expect = CharsToUnicodeString("\\u5b89\\u6c385\\u5e747\\u67084\\u65e5\\u6728\\u66dc\\u65e5"); |
729e4ab9 | 585 | UDate expectDate = -6106032422000.0; // 1776-07-04T00:00:00Z-075258 |
374ca955 | 586 | Locale loc("ja_JP@calendar=japanese"); |
b75a7d8f A |
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) ) | |
374ca955 | 593 | UnicodeString expect = CharsToUnicodeString("\\u662d\\u548c64\\u5e741\\u67086\\u65e5\\u91d1\\u66dc\\u65e5"); |
b75a7d8f | 594 | UDate expectDate = 600076800000.0; |
374ca955 | 595 | Locale loc("ja_JP@calendar=japanese"); |
b75a7d8f A |
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. | |
374ca955 | 602 | UnicodeString expect = CharsToUnicodeString("\\u5EB7\\u6B632\\u5e742\\u670829\\u65e5\\u65e5\\u66dc\\u65e5"); |
729e4ab9 | 603 | UDate expectDate = -16214400422000.0; // 1456-03-09T00:00Z-075258 |
374ca955 | 604 | Locale loc("ja_JP@calendar=japanese"); |
b75a7d8f A |
605 | |
606 | status = U_ZERO_ERROR; | |
607 | simpleTest(loc, expect, expectDate, status); | |
608 | ||
609 | } | |
610 | } | |
611 | ||
73c04bcf A |
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; | |
46f4442e | 652 | int32_t expectEra = JapaneseCalendar::getCurrentEra(); |
73c04bcf A |
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 | ||
73c04bcf A |
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; | |
729e4ab9 | 692 | int32_t expectEra = 235; //JapaneseCalendar::kCurrentEra; |
73c04bcf A |
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 | } | |
729e4ab9 | 702 | |
73c04bcf A |
703 | delete cal2; |
704 | delete cal; | |
705 | delete fmt2; | |
706 | } | |
707 | ||
46f4442e A |
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 | |
51004dcb A |
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 | ||
46f4442e | 828 | delete cal; |
51004dcb | 829 | delete grego; |
46f4442e A |
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 | ||
b75a7d8f A |
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 |