]>
Commit | Line | Data |
---|---|---|
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 | ||
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 | ||
57 | static 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 | ||
67 | void 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 | */ | |
93 | void | |
94 | IntlCalendarTest::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 | */ | |
152 | void 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 | |
223 | void 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 | */ | |
262 | void 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 | */ | |
312 | void 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 | */ | |
364 | void 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 | 411 | void 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 | |
491 | void 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 |
615 | void 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 | */ | |
717 | void 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 | ||
835 | void 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 |
883 | void 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 |