]>
Commit | Line | Data |
---|---|---|
374ca955 | 1 | /*********************************************************************** |
b75a7d8f | 2 | * COPYRIGHT: |
46f4442e | 3 | * Copyright (c) 1997-2008, 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)) { \ | |
21 | errln((UnicodeString(u_errorName(status)) + UnicodeString(" : " ) )+ msg); \ | |
22 | return; \ | |
23 | } | |
24 | ||
25 | ||
26 | static UnicodeString escape( const UnicodeString&src) | |
27 | { | |
28 | UnicodeString dst; | |
29 | dst.remove(); | |
30 | for (int32_t i = 0; i < src.length(); ++i) { | |
31 | UChar c = src[i]; | |
32 | if(c < 0x0080) | |
33 | dst += c; | |
34 | else { | |
35 | dst += UnicodeString("["); | |
36 | char buf [8]; | |
37 | sprintf(buf, "%#x", c); | |
38 | dst += UnicodeString(buf); | |
39 | dst += UnicodeString("]"); | |
40 | } | |
41 | } | |
42 | ||
43 | return dst; | |
44 | } | |
45 | ||
46 | ||
47 | #include "incaltst.h" | |
48 | #include "unicode/gregocal.h" | |
49 | #include "unicode/smpdtfmt.h" | |
50 | #include "unicode/simpletz.h" | |
51 | ||
52 | // ***************************************************************************** | |
53 | // class IntlCalendarTest | |
54 | // ***************************************************************************** | |
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", |
b75a7d8f A |
107 | "en_US", NULL }; |
108 | const char *types[40] = { "gregorian", | |
374ca955 A |
109 | "japanese", |
110 | "gregorian", | |
111 | "japanese", | |
112 | "buddhist", | |
b75a7d8f A |
113 | "japanese", |
114 | "buddhist", | |
374ca955 | 115 | "gregorian", |
b75a7d8f A |
116 | "gregorian", NULL }; |
117 | ||
118 | for(j=0;locs[j];j++) { | |
119 | logln(UnicodeString("Creating calendar of locale ") + locs[j]); | |
120 | status = U_ZERO_ERROR; | |
121 | c = Calendar::createInstance(locs[j], status); | |
122 | CHECK(status, "creating '" + UnicodeString(locs[j]) + "' calendar"); | |
123 | if(U_SUCCESS(status)) { | |
124 | logln(UnicodeString(" type is ") + c->getType()); | |
125 | if(strcmp(c->getType(), types[j])) { | |
126 | errln(UnicodeString(locs[j]) + UnicodeString("Calendar type ") + c->getType() + " instead of " + types[j]); | |
127 | } | |
128 | } | |
129 | delete c; | |
130 | } | |
131 | } | |
132 | ||
133 | ||
134 | ||
135 | /** | |
136 | * Run a test of a quasi-Gregorian calendar. This is a calendar | |
137 | * that behaves like a Gregorian but has different year/era mappings. | |
138 | * The int[] data array should have the format: | |
139 | * | |
140 | * { era, year, gregorianYear, month, dayOfMonth, ... ... , -1 } | |
141 | */ | |
142 | void IntlCalendarTest::quasiGregorianTest(Calendar& cal, const Locale& gcl, const int32_t *data) { | |
143 | UErrorCode status = U_ZERO_ERROR; | |
144 | // As of JDK 1.4.1_01, using the Sun JDK GregorianCalendar as | |
145 | // a reference throws us off by one hour. This is most likely | |
146 | // due to the JDK 1.4 incorporation of historical time zones. | |
147 | //java.util.Calendar grego = java.util.Calendar.getInstance(); | |
148 | Calendar *grego = Calendar::createInstance(gcl, status); | |
73c04bcf A |
149 | if (U_FAILURE(status)) { |
150 | dataerrln("Error calling Calendar::createInstance"); | |
151 | return; | |
152 | } | |
b75a7d8f A |
153 | |
154 | int32_t tz1 = cal.get(UCAL_ZONE_OFFSET,status); | |
155 | int32_t tz2 = grego -> get (UCAL_ZONE_OFFSET, status); | |
156 | if(tz1 != tz2) { | |
157 | errln((UnicodeString)"cal's tz " + tz1 + " != grego's tz " + tz2); | |
158 | } | |
159 | ||
160 | for (int32_t i=0; data[i]!=-1; ) { | |
161 | int32_t era = data[i++]; | |
162 | int32_t year = data[i++]; | |
163 | int32_t gregorianYear = data[i++]; | |
164 | int32_t month = data[i++]; | |
165 | int32_t dayOfMonth = data[i++]; | |
166 | ||
167 | grego->clear(); | |
168 | grego->set(gregorianYear, month, dayOfMonth); | |
169 | UDate D = grego->getTime(status); | |
170 | ||
171 | cal.clear(); | |
172 | cal.set(UCAL_ERA, era); | |
173 | cal.set(year, month, dayOfMonth); | |
174 | UDate d = cal.getTime(status); | |
175 | #ifdef U_DEBUG_DUMPCALS | |
374ca955 A |
176 | logln((UnicodeString)"cal : " + CalendarTest::calToStr(cal)); |
177 | logln((UnicodeString)"grego: " + CalendarTest::calToStr(*grego)); | |
b75a7d8f A |
178 | #endif |
179 | if (d == D) { | |
180 | logln(UnicodeString("OK: ") + era + ":" + year + "/" + (month+1) + "/" + dayOfMonth + | |
181 | " => " + d + " (" + UnicodeString(cal.getType()) + ")"); | |
182 | } else { | |
183 | errln(UnicodeString("Fail: (fields to millis)") + era + ":" + year + "/" + (month+1) + "/" + dayOfMonth + | |
184 | " => " + d + ", expected " + D + " (" + UnicodeString(cal.getType()) + "Off by: " + (d-D)); | |
185 | } | |
186 | ||
187 | // Now, set the gregorian millis on the other calendar | |
188 | cal.clear(); | |
189 | cal.setTime(D, status); | |
190 | int e = cal.get(UCAL_ERA, status); | |
191 | int y = cal.get(UCAL_YEAR, status); | |
192 | #ifdef U_DEBUG_DUMPCALS | |
374ca955 A |
193 | logln((UnicodeString)"cal : " + CalendarTest::calToStr(cal)); |
194 | logln((UnicodeString)"grego: " + CalendarTest::calToStr(*grego)); | |
b75a7d8f A |
195 | #endif |
196 | if (y == year && e == era) { | |
197 | logln((UnicodeString)"OK: " + D + " => " + cal.get(UCAL_ERA, status) + ":" + | |
198 | cal.get(UCAL_YEAR, status) + "/" + | |
199 | (cal.get(UCAL_MONTH, status)+1) + "/" + cal.get(UCAL_DATE, status) + " (" + UnicodeString(cal.getType()) + ")"); | |
200 | } else { | |
201 | errln((UnicodeString)"Fail: (millis to fields)" + D + " => " + cal.get(UCAL_ERA, status) + ":" + | |
202 | cal.get(UCAL_YEAR, status) + "/" + | |
203 | (cal.get(UCAL_MONTH, status)+1) + "/" + cal.get(UCAL_DATE, status) + | |
204 | ", expected " + era + ":" + year + "/" + (month+1) + "/" + | |
205 | dayOfMonth + " (" + UnicodeString(cal.getType())); | |
206 | } | |
207 | } | |
208 | delete grego; | |
209 | CHECK(status, "err during quasiGregorianTest()"); | |
210 | } | |
211 | ||
212 | // Verify that Gregorian works like Gregorian | |
213 | void IntlCalendarTest::TestGregorian() { | |
214 | UDate timeA = Calendar::getNow(); | |
215 | int32_t data[] = { | |
216 | GregorianCalendar::AD, 1868, 1868, UCAL_SEPTEMBER, 8, | |
217 | GregorianCalendar::AD, 1868, 1868, UCAL_SEPTEMBER, 9, | |
218 | GregorianCalendar::AD, 1869, 1869, UCAL_JUNE, 4, | |
219 | GregorianCalendar::AD, 1912, 1912, UCAL_JULY, 29, | |
220 | GregorianCalendar::AD, 1912, 1912, UCAL_JULY, 30, | |
221 | GregorianCalendar::AD, 1912, 1912, UCAL_AUGUST, 1, | |
222 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 | |
223 | }; | |
224 | ||
225 | Calendar *cal; | |
226 | UErrorCode status = U_ZERO_ERROR; | |
227 | cal = Calendar::createInstance(/*"de_DE", */ status); | |
228 | CHECK(status, UnicodeString("Creating de_CH calendar")); | |
229 | // Sanity check the calendar | |
230 | UDate timeB = Calendar::getNow(); | |
231 | UDate timeCal = cal->getTime(status); | |
232 | ||
233 | if(!(timeA <= timeCal) || !(timeCal <= timeB)) { | |
234 | errln((UnicodeString)"Error: Calendar time " + timeCal + | |
235 | " is not within sampled times [" + timeA + " to " + timeB + "]!"); | |
236 | } | |
237 | // end sanity check | |
238 | ||
239 | // Note, the following is a good way to test the sanity of the constructed calendars, | |
240 | // using Collation as a delay-loop: | |
241 | // | |
242 | // $ intltest format/IntlCalendarTest collate/G7CollationTest format/IntlCalendarTest | |
243 | ||
244 | quasiGregorianTest(*cal,Locale("fr_FR"),data); | |
245 | delete cal; | |
246 | } | |
247 | ||
248 | /** | |
249 | * Verify that BuddhistCalendar shifts years to Buddhist Era but otherwise | |
250 | * behaves like GregorianCalendar. | |
251 | */ | |
252 | void IntlCalendarTest::TestBuddhist() { | |
253 | // BE 2542 == 1999 CE | |
254 | UDate timeA = Calendar::getNow(); | |
255 | ||
256 | int32_t data[] = { | |
374ca955 | 257 | 0, // B. era [928479600000] |
b75a7d8f A |
258 | 2542, // B. year |
259 | 1999, // G. year | |
260 | UCAL_JUNE, // month | |
261 | 4, // day | |
262 | ||
374ca955 | 263 | 0, // B. era [-79204842000000] |
b75a7d8f A |
264 | 3, // B. year |
265 | -540, // G. year | |
266 | UCAL_FEBRUARY, // month | |
267 | 12, // day | |
268 | ||
269 | 0, // test month calculation: 4795 BE = 4252 AD is a leap year, but 4795 AD is not. | |
374ca955 | 270 | 4795, // BE [72018057600000] |
b75a7d8f A |
271 | 4252, // AD |
272 | UCAL_FEBRUARY, | |
273 | 29, | |
274 | ||
275 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1 | |
276 | }; | |
277 | Calendar *cal; | |
278 | UErrorCode status = U_ZERO_ERROR; | |
374ca955 A |
279 | cal = Calendar::createInstance("th_TH@calendar=buddhist", status); |
280 | CHECK(status, UnicodeString("Creating th_TH@calendar=buddhist calendar")); | |
b75a7d8f A |
281 | |
282 | // Sanity check the calendar | |
283 | UDate timeB = Calendar::getNow(); | |
284 | UDate timeCal = cal->getTime(status); | |
285 | ||
286 | if(!(timeA <= timeCal) || !(timeCal <= timeB)) { | |
287 | errln((UnicodeString)"Error: Calendar time " + timeCal + | |
288 | " is not within sampled times [" + timeA + " to " + timeB + "]!"); | |
289 | } | |
290 | // end sanity check | |
291 | ||
292 | ||
46f4442e | 293 | quasiGregorianTest(*cal,Locale("th_TH@calendar=gregorian"),data); |
b75a7d8f A |
294 | delete cal; |
295 | } | |
296 | ||
46f4442e A |
297 | |
298 | /** | |
299 | * Verify that TaiWanCalendar shifts years to Minguo Era but otherwise | |
300 | * behaves like GregorianCalendar. | |
301 | */ | |
302 | void IntlCalendarTest::TestTaiwan() { | |
303 | // MG 1 == 1912 AD | |
304 | UDate timeA = Calendar::getNow(); | |
305 | ||
306 | // TODO port these to the data items | |
307 | int32_t data[] = { | |
308 | 1, // B. era [928479600000] | |
309 | 1, // B. year | |
310 | 1912, // G. year | |
311 | UCAL_JUNE, // month | |
312 | 4, // day | |
313 | ||
314 | 1, // B. era [-79204842000000] | |
315 | 3, // B. year | |
316 | 1914, // G. year | |
317 | UCAL_FEBRUARY, // month | |
318 | 12, // day | |
319 | ||
320 | 1, // B. era [-79204842000000] | |
321 | 96, // B. year | |
322 | 2007, // G. year | |
323 | UCAL_FEBRUARY, // month | |
324 | 12, // day | |
325 | ||
326 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1 | |
327 | }; | |
328 | Calendar *cal; | |
329 | UErrorCode status = U_ZERO_ERROR; | |
330 | cal = Calendar::createInstance("en_US@calendar=roc", status); | |
331 | CHECK(status, UnicodeString("Creating en_US@calendar=roc calendar")); | |
332 | ||
333 | // Sanity check the calendar | |
334 | UDate timeB = Calendar::getNow(); | |
335 | UDate timeCal = cal->getTime(status); | |
336 | ||
337 | if(!(timeA <= timeCal) || !(timeCal <= timeB)) { | |
338 | errln((UnicodeString)"Error: Calendar time " + timeCal + | |
339 | " is not within sampled times [" + timeA + " to " + timeB + "]!"); | |
340 | } | |
341 | // end sanity check | |
342 | ||
343 | ||
344 | quasiGregorianTest(*cal,Locale("en_US"),data); | |
345 | delete cal; | |
346 | } | |
347 | ||
348 | ||
349 | ||
b75a7d8f A |
350 | /** |
351 | * Verify that JapaneseCalendar shifts years to Japanese Eras but otherwise | |
352 | * behaves like GregorianCalendar. | |
353 | */ | |
354 | void IntlCalendarTest::TestJapanese() { | |
355 | UDate timeA = Calendar::getNow(); | |
356 | ||
357 | /* Sorry.. japancal.h is private! */ | |
358 | #define JapaneseCalendar_MEIJI 232 | |
359 | #define JapaneseCalendar_TAISHO 233 | |
360 | #define JapaneseCalendar_SHOWA 234 | |
361 | #define JapaneseCalendar_HEISEI 235 | |
362 | ||
363 | // BE 2542 == 1999 CE | |
364 | int32_t data[] = { | |
365 | // Jera Jyr Gyear m d | |
366 | JapaneseCalendar_MEIJI, 1, 1868, UCAL_SEPTEMBER, 8, | |
367 | JapaneseCalendar_MEIJI, 1, 1868, UCAL_SEPTEMBER, 9, | |
368 | JapaneseCalendar_MEIJI, 2, 1869, UCAL_JUNE, 4, | |
369 | JapaneseCalendar_MEIJI, 45, 1912, UCAL_JULY, 29, | |
370 | JapaneseCalendar_TAISHO, 1, 1912, UCAL_JULY, 30, | |
371 | JapaneseCalendar_TAISHO, 1, 1912, UCAL_AUGUST, 1, | |
372 | ||
373 | // new tests (not in java) | |
374 | JapaneseCalendar_SHOWA, 64, 1989, UCAL_JANUARY, 7, // Test current era transition (different code path than others) | |
375 | JapaneseCalendar_HEISEI, 1, 1989, UCAL_JANUARY, 8, | |
376 | JapaneseCalendar_HEISEI, 1, 1989, UCAL_JANUARY, 9, | |
377 | JapaneseCalendar_HEISEI, 1, 1989, UCAL_DECEMBER, 20, | |
378 | JapaneseCalendar_HEISEI, 15, 2003, UCAL_MAY, 22, | |
379 | -1,-1,-1,-1,-1,-1,-1,-1,-1,-1 | |
380 | }; | |
381 | ||
382 | Calendar *cal; | |
383 | UErrorCode status = U_ZERO_ERROR; | |
374ca955 A |
384 | cal = Calendar::createInstance("ja_JP@calendar=japanese", status); |
385 | CHECK(status, UnicodeString("Creating ja_JP@calendar=japanese calendar")); | |
b75a7d8f A |
386 | // Sanity check the calendar |
387 | UDate timeB = Calendar::getNow(); | |
388 | UDate timeCal = cal->getTime(status); | |
389 | ||
390 | if(!(timeA <= timeCal) || !(timeCal <= timeB)) { | |
391 | errln((UnicodeString)"Error: Calendar time " + timeCal + | |
392 | " is not within sampled times [" + timeA + " to " + timeB + "]!"); | |
393 | } | |
394 | // end sanity check | |
395 | quasiGregorianTest(*cal,Locale("ja_JP"),data); | |
396 | delete cal; | |
397 | } | |
398 | ||
46f4442e A |
399 | |
400 | ||
b75a7d8f | 401 | void IntlCalendarTest::TestBuddhistFormat() { |
b75a7d8f | 402 | UErrorCode status = U_ZERO_ERROR; |
b75a7d8f A |
403 | |
404 | // Test simple parse/format with adopt | |
405 | ||
406 | // First, a contrived english test.. | |
407 | UDate aDate = 999932400000.0; | |
374ca955 | 408 | SimpleDateFormat *fmt = new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"), Locale("en_US@calendar=buddhist"), status); |
b75a7d8f | 409 | CHECK(status, "creating date format instance"); |
374ca955 A |
410 | SimpleDateFormat *fmt2 = new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"), Locale("en_US@calendar=gregorian"), status); |
411 | CHECK(status, "creating gregorian date format instance"); | |
b75a7d8f A |
412 | if(!fmt) { |
413 | errln("Coudln't create en_US instance"); | |
414 | } else { | |
415 | UnicodeString str; | |
374ca955 | 416 | fmt2->format(aDate, str); |
b75a7d8f A |
417 | logln(UnicodeString() + "Test Date: " + str); |
418 | str.remove(); | |
b75a7d8f A |
419 | fmt->format(aDate, str); |
420 | logln(UnicodeString() + "as Buddhist Calendar: " + escape(str)); | |
421 | UnicodeString expected("September 8, 2544 BE"); | |
422 | if(str != expected) { | |
423 | errln("Expected " + escape(expected) + " but got " + escape(str)); | |
424 | } | |
425 | UDate otherDate = fmt->parse(expected, status); | |
426 | if(otherDate != aDate) { | |
427 | UnicodeString str3; | |
428 | fmt->format(otherDate, str3); | |
429 | errln("Parse incorrect of " + escape(expected) + " - wanted " + aDate + " but got " + otherDate + ", " + escape(str3)); | |
430 | } else { | |
431 | logln("Parsed OK: " + expected); | |
432 | } | |
433 | delete fmt; | |
434 | } | |
374ca955 | 435 | delete fmt2; |
b75a7d8f A |
436 | |
437 | CHECK(status, "Error occured testing Buddhist Calendar in English "); | |
438 | ||
439 | status = U_ZERO_ERROR; | |
440 | // Now, try in Thai | |
441 | { | |
442 | UnicodeString expect = CharsToUnicodeString("\\u0E27\\u0E31\\u0E19\\u0E40\\u0E2A\\u0E32\\u0E23\\u0E4C\\u0E17\\u0E35\\u0E48" | |
443 | " 8 \\u0E01\\u0E31\\u0e19\\u0e22\\u0e32\\u0e22\\u0e19 \\u0e1e.\\u0e28. 2544"); | |
444 | UDate expectDate = 999932400000.0; | |
374ca955 A |
445 | Locale loc("th_TH_TRADITIONAL"); // legacy |
446 | ||
447 | simpleTest(loc, expect, expectDate, status); | |
448 | } | |
449 | status = U_ZERO_ERROR; | |
450 | { | |
451 | UnicodeString expect = CharsToUnicodeString("\\u0E27\\u0E31\\u0E19\\u0E40\\u0E2A\\u0E32\\u0E23\\u0E4C\\u0E17\\u0E35\\u0E48" | |
452 | " 8 \\u0E01\\u0E31\\u0e19\\u0e22\\u0e32\\u0e22\\u0e19 \\u0e1e.\\u0e28. 2544"); | |
453 | UDate expectDate = 999932400000.0; | |
454 | Locale loc("th_TH@calendar=buddhist"); | |
455 | ||
456 | simpleTest(loc, expect, expectDate, status); | |
457 | } | |
458 | status = U_ZERO_ERROR; | |
459 | { | |
460 | UnicodeString expect = CharsToUnicodeString("\\u0E27\\u0E31\\u0E19\\u0E40\\u0E2A\\u0E32\\u0E23\\u0E4C\\u0E17\\u0E35\\u0E48" | |
461 | " 8 \\u0E01\\u0E31\\u0e19\\u0e22\\u0e32\\u0e22\\u0e19 \\u0e04.\\u0e28. 2001"); | |
462 | UDate expectDate = 999932400000.0; | |
463 | Locale loc("th_TH@calendar=gregorian"); | |
464 | ||
465 | simpleTest(loc, expect, expectDate, status); | |
466 | } | |
467 | status = U_ZERO_ERROR; | |
468 | { | |
469 | UnicodeString expect = CharsToUnicodeString("\\u0E27\\u0E31\\u0E19\\u0E40\\u0E2A\\u0E32\\u0E23\\u0E4C\\u0E17\\u0E35\\u0E48" | |
470 | " 8 \\u0E01\\u0E31\\u0e19\\u0e22\\u0e32\\u0e22\\u0e19 \\u0e04.\\u0e28. 2001"); | |
471 | UDate expectDate = 999932400000.0; | |
472 | Locale loc("th_TH_TRADITIONAL@calendar=gregorian"); | |
b75a7d8f A |
473 | |
474 | simpleTest(loc, expect, expectDate, status); | |
475 | } | |
476 | } | |
477 | ||
46f4442e A |
478 | // TaiwanFormat has been moved to testdata/format.txt |
479 | ||
b75a7d8f A |
480 | |
481 | void IntlCalendarTest::TestJapaneseFormat() { | |
482 | Calendar *cal; | |
483 | UErrorCode status = U_ZERO_ERROR; | |
484 | cal = Calendar::createInstance("ja_JP_TRADITIONAL", status); | |
485 | CHECK(status, UnicodeString("Creating ja_JP_TRADITIONAL calendar")); | |
486 | ||
487 | Calendar *cal2 = cal->clone(); | |
374ca955 A |
488 | delete cal; |
489 | cal = NULL; | |
b75a7d8f A |
490 | |
491 | // Test simple parse/format with adopt | |
492 | ||
493 | UDate aDate = 999932400000.0; | |
374ca955 | 494 | SimpleDateFormat *fmt = new SimpleDateFormat(UnicodeString("MMMM d, yy G"), Locale("en_US@calendar=japanese"), status); |
73c04bcf | 495 | SimpleDateFormat *fmt2 = new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"), Locale("en_US@calendar=gregorian"), status); |
b75a7d8f A |
496 | CHECK(status, "creating date format instance"); |
497 | if(!fmt) { | |
498 | errln("Coudln't create en_US instance"); | |
499 | } else { | |
500 | UnicodeString str; | |
374ca955 | 501 | fmt2->format(aDate, str); |
b75a7d8f A |
502 | logln(UnicodeString() + "Test Date: " + str); |
503 | str.remove(); | |
b75a7d8f A |
504 | fmt->format(aDate, str); |
505 | logln(UnicodeString() + "as Japanese Calendar: " + str); | |
506 | UnicodeString expected("September 8, 13 Heisei"); | |
507 | if(str != expected) { | |
508 | errln("Expected " + expected + " but got " + str); | |
509 | } | |
510 | UDate otherDate = fmt->parse(expected, status); | |
511 | if(otherDate != aDate) { | |
512 | UnicodeString str3; | |
513 | ParsePosition pp; | |
514 | fmt->parse(expected, *cal2, pp); | |
515 | fmt->format(otherDate, str3); | |
374ca955 | 516 | errln("Parse incorrect of " + expected + " - wanted " + aDate + " but got " + " = " + otherDate + ", " + str3 + " = " + CalendarTest::calToStr(*cal2) ); |
b75a7d8f A |
517 | |
518 | } else { | |
519 | logln("Parsed OK: " + expected); | |
520 | } | |
521 | delete fmt; | |
522 | } | |
523 | ||
524 | // Test parse with incomplete information | |
374ca955 | 525 | fmt = new SimpleDateFormat(UnicodeString("G y"), Locale("en_US@calendar=japanese"), status); |
4162bf98 A |
526 | /* The test data below should points to 1868-09-08T00:00:00 in America/Los_Angeles. |
527 | * The time calculated by original test code uses -7:00 UTC offset, because it assumes | |
528 | * DST is observed (because of a timezone bug, DST is observed for early 20th century | |
529 | * day to infinite past time). The bug was fixed and DST is no longer used for time before | |
530 | * 1900 for any zones. However, ICU timezone transition data is represented by 32-bit integer | |
531 | * (sec) and cannot represent transitions before 1901 defined in Olson tzdata. For example, | |
532 | * based on Olson definition, offset -7:52:58 should be used for Nov 18, 1883 or older dates. | |
533 | * If ICU properly capture entire Olson zone definition, the start time of "Meiji 1" is | |
534 | * -3197117222000. -Yoshito | |
535 | */ | |
536 | /* TODO: When ICU support the Olson LMT offset for America/Los_Angeles, we need to update | |
537 | * the reference data. | |
538 | */ | |
539 | //aDate = -3197120400000.; | |
540 | aDate = -3197116800000.; | |
b75a7d8f A |
541 | CHECK(status, "creating date format instance"); |
542 | if(!fmt) { | |
543 | errln("Coudln't create en_US instance"); | |
544 | } else { | |
545 | UnicodeString str; | |
374ca955 | 546 | fmt2->format(aDate, str); |
b75a7d8f A |
547 | logln(UnicodeString() + "Test Date: " + str); |
548 | str.remove(); | |
b75a7d8f A |
549 | fmt->format(aDate, str); |
550 | logln(UnicodeString() + "as Japanese Calendar: " + str); | |
551 | UnicodeString expected("Meiji 1"); | |
552 | if(str != expected) { | |
553 | errln("Expected " + expected + " but got " + str); | |
554 | } | |
555 | UDate otherDate = fmt->parse(expected, status); | |
556 | if(otherDate != aDate) { | |
557 | UnicodeString str3; | |
558 | ParsePosition pp; | |
559 | fmt->parse(expected, *cal2, pp); | |
560 | fmt->format(otherDate, str3); | |
561 | errln("Parse incorrect of " + expected + " - wanted " + aDate + " but got " + " = " + | |
374ca955 | 562 | otherDate + ", " + str3 + " = " + CalendarTest::calToStr(*cal2) ); |
b75a7d8f A |
563 | } else { |
564 | logln("Parsed OK: " + expected); | |
565 | } | |
566 | delete fmt; | |
567 | } | |
568 | ||
b75a7d8f | 569 | delete cal2; |
374ca955 | 570 | delete fmt2; |
b75a7d8f A |
571 | CHECK(status, "Error occured"); |
572 | ||
573 | // Now, try in Japanese | |
574 | { | |
374ca955 A |
575 | UnicodeString expect = CharsToUnicodeString("\\u5e73\\u621013\\u5e749\\u67088\\u65e5\\u571f\\u66dc\\u65e5"); |
576 | UDate expectDate = 999932400000.0; // Testing a recent date | |
577 | Locale loc("ja_JP@calendar=japanese"); | |
578 | ||
579 | status = U_ZERO_ERROR; | |
580 | simpleTest(loc, expect, expectDate, status); | |
581 | } | |
582 | { | |
583 | UnicodeString expect = CharsToUnicodeString("\\u5e73\\u621013\\u5e749\\u67088\\u65e5\\u571f\\u66dc\\u65e5"); | |
b75a7d8f | 584 | UDate expectDate = 999932400000.0; // Testing a recent date |
374ca955 | 585 | Locale loc("ja_JP_TRADITIONAL"); // legacy |
b75a7d8f A |
586 | |
587 | status = U_ZERO_ERROR; | |
588 | simpleTest(loc, expect, expectDate, status); | |
589 | } | |
590 | { | |
374ca955 | 591 | UnicodeString expect = CharsToUnicodeString("\\u5b89\\u6c385\\u5e747\\u67084\\u65e5\\u6728\\u66dc\\u65e5"); |
4162bf98 A |
592 | //UDate expectDate = -6106035600000.0; |
593 | UDate expectDate = -6106032000000.0; // 1776-07-04T00:00:00Z-0800 | |
374ca955 | 594 | Locale loc("ja_JP@calendar=japanese"); |
b75a7d8f A |
595 | |
596 | status = U_ZERO_ERROR; | |
597 | simpleTest(loc, expect, expectDate, status); | |
598 | ||
599 | } | |
600 | { // Jitterbug 1869 - this is an ambiguous era. (Showa 64 = Jan 6 1989, but Showa could be 2 other eras) ) | |
374ca955 | 601 | UnicodeString expect = CharsToUnicodeString("\\u662d\\u548c64\\u5e741\\u67086\\u65e5\\u91d1\\u66dc\\u65e5"); |
b75a7d8f | 602 | UDate expectDate = 600076800000.0; |
374ca955 | 603 | Locale loc("ja_JP@calendar=japanese"); |
b75a7d8f A |
604 | |
605 | status = U_ZERO_ERROR; | |
606 | simpleTest(loc, expect, expectDate, status); | |
607 | ||
608 | } | |
609 | { // This Feb 29th falls on a leap year by gregorian year, but not by Japanese year. | |
374ca955 A |
610 | UnicodeString expect = CharsToUnicodeString("\\u5EB7\\u6B632\\u5e742\\u670829\\u65e5\\u65e5\\u66dc\\u65e5"); |
611 | // Add -1:00 to the following for historical TZ - aliu | |
4162bf98 A |
612 | //UDate expectDate = -16214403600000.0; // courtesy of date format round trip test |
613 | UDate expectDate = -16214400000000.0; // 1456-03-09T00:00:00Z-0800 | |
374ca955 | 614 | Locale loc("ja_JP@calendar=japanese"); |
b75a7d8f A |
615 | |
616 | status = U_ZERO_ERROR; | |
617 | simpleTest(loc, expect, expectDate, status); | |
618 | ||
619 | } | |
620 | } | |
621 | ||
73c04bcf A |
622 | void IntlCalendarTest::TestJapanese3860() |
623 | { | |
624 | Calendar *cal; | |
625 | UErrorCode status = U_ZERO_ERROR; | |
626 | cal = Calendar::createInstance("ja_JP@calendar=japanese", status); | |
627 | CHECK(status, UnicodeString("Creating ja_JP@calendar=japanese calendar")); | |
628 | Calendar *cal2 = cal->clone(); | |
629 | SimpleDateFormat *fmt2 = new SimpleDateFormat(UnicodeString("HH:mm:ss.S MMMM d, yyyy G"), Locale("en_US@calendar=gregorian"), status); | |
630 | UnicodeString str; | |
631 | ||
632 | ||
633 | { | |
634 | // Test simple parse/format with adopt | |
635 | UDate aDate = 0; | |
636 | ||
637 | // Test parse with missing era (should default to current era, heisei) | |
638 | // Test parse with incomplete information | |
639 | logln("Testing parse w/ missing era..."); | |
640 | SimpleDateFormat *fmt = new SimpleDateFormat(UnicodeString("y.M.d"), Locale("ja_JP@calendar=japanese"), status); | |
641 | CHECK(status, "creating date format instance"); | |
642 | if(!fmt) { | |
643 | errln("Coudln't create en_US instance"); | |
644 | } else { | |
645 | UErrorCode s2 = U_ZERO_ERROR; | |
646 | cal2->clear(); | |
647 | UnicodeString samplestr("1.1.9"); | |
648 | logln(UnicodeString() + "Test Year: " + samplestr); | |
649 | aDate = fmt->parse(samplestr, s2); | |
650 | ParsePosition pp=0; | |
651 | fmt->parse(samplestr, *cal2, pp); | |
652 | CHECK(s2, "parsing the 1.1.9 string"); | |
653 | logln("*cal2 after 119 parse:"); | |
654 | str.remove(); | |
655 | fmt2->format(aDate, str); | |
656 | logln(UnicodeString() + "as Gregorian Calendar: " + str); | |
657 | ||
658 | cal2->setTime(aDate, s2); | |
659 | int32_t gotYear = cal2->get(UCAL_YEAR, s2); | |
660 | int32_t gotEra = cal2->get(UCAL_ERA, s2); | |
661 | int32_t expectYear = 1; | |
46f4442e | 662 | int32_t expectEra = JapaneseCalendar::getCurrentEra(); |
73c04bcf A |
663 | if((gotYear!=1) || (gotEra != expectEra)) { |
664 | errln(UnicodeString("parse "+samplestr+" of 'y.m.d' as Japanese Calendar, expected year ") + expectYear + | |
665 | UnicodeString(" and era ") + expectEra +", but got year " + gotYear + " and era " + gotEra + " (Gregorian:" + str +")"); | |
666 | } else { | |
667 | logln(UnicodeString() + " year: " + gotYear + ", era: " + gotEra); | |
668 | } | |
669 | delete fmt; | |
670 | } | |
671 | } | |
672 | ||
673 | #if 0 | |
674 | // this will NOT work - *all the time*. If it is the 1st of the month, for example it will get Jan 1 heisei 1 => jan 1 showa 64, wrong era. | |
675 | { | |
676 | // Test simple parse/format with adopt | |
677 | UDate aDate = 0; | |
678 | ||
679 | // Test parse with missing era (should default to current era, heisei) | |
680 | // Test parse with incomplete information | |
681 | logln("Testing parse w/ just year..."); | |
682 | SimpleDateFormat *fmt = new SimpleDateFormat(UnicodeString("y"), Locale("ja_JP@calendar=japanese"), status); | |
683 | CHECK(status, "creating date format instance"); | |
684 | if(!fmt) { | |
685 | errln("Coudln't create en_US instance"); | |
686 | } else { | |
687 | UErrorCode s2 = U_ZERO_ERROR; | |
688 | cal2->clear(); | |
689 | UnicodeString samplestr("1"); | |
690 | logln(UnicodeString() + "Test Year: " + samplestr); | |
691 | aDate = fmt->parse(samplestr, s2); | |
692 | ParsePosition pp=0; | |
693 | fmt->parse(samplestr, *cal2, pp); | |
694 | CHECK(s2, "parsing the 1 string"); | |
695 | logln("*cal2 after 1 parse:"); | |
696 | str.remove(); | |
697 | fmt2->format(aDate, str); | |
698 | logln(UnicodeString() + "as Gregorian Calendar: " + str); | |
699 | ||
700 | cal2->setTime(aDate, s2); | |
701 | int32_t gotYear = cal2->get(UCAL_YEAR, s2); | |
702 | int32_t gotEra = cal2->get(UCAL_ERA, s2); | |
703 | int32_t expectYear = 1; | |
704 | int32_t expectEra = JapaneseCalendar::kCurrentEra; | |
705 | if((gotYear!=1) || (gotEra != expectEra)) { | |
706 | errln(UnicodeString("parse "+samplestr+" of 'y' as Japanese Calendar, expected year ") + expectYear + | |
707 | UnicodeString(" and era ") + expectEra +", but got year " + gotYear + " and era " + gotEra + " (Gregorian:" + str +")"); | |
708 | } else { | |
709 | logln(UnicodeString() + " year: " + gotYear + ", era: " + gotEra); | |
710 | } | |
711 | delete fmt; | |
712 | } | |
713 | } | |
714 | #endif | |
715 | delete cal2; | |
716 | delete cal; | |
717 | delete fmt2; | |
718 | } | |
719 | ||
46f4442e A |
720 | |
721 | ||
722 | ||
723 | /** | |
724 | * Verify the Persian Calendar. | |
725 | */ | |
726 | void IntlCalendarTest::TestPersian() { | |
727 | UDate timeA = Calendar::getNow(); | |
728 | ||
729 | Calendar *cal; | |
730 | UErrorCode status = U_ZERO_ERROR; | |
731 | cal = Calendar::createInstance("fa_IR@calendar=persian", status); | |
732 | CHECK(status, UnicodeString("Creating fa_IR@calendar=persian calendar")); | |
733 | // Sanity check the calendar | |
734 | UDate timeB = Calendar::getNow(); | |
735 | UDate timeCal = cal->getTime(status); | |
736 | ||
737 | if(!(timeA <= timeCal) || !(timeCal <= timeB)) { | |
738 | errln((UnicodeString)"Error: Calendar time " + timeCal + | |
739 | " is not within sampled times [" + timeA + " to " + timeB + "]!"); | |
740 | } | |
741 | // end sanity check | |
742 | // quasiGregorianTest(*cal,Locale("ja_JP"),data); | |
743 | delete cal; | |
744 | } | |
745 | ||
746 | void IntlCalendarTest::TestPersianFormat() { | |
747 | UErrorCode status = U_ZERO_ERROR; | |
748 | SimpleDateFormat *fmt = new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"), Locale(" en_US@calendar=persian"), status); | |
749 | CHECK(status, "creating date format instance"); | |
750 | SimpleDateFormat *fmt2 = new SimpleDateFormat(UnicodeString("MMMM d, yyyy G"), Locale("en_US@calendar=gregorian"), status); | |
751 | CHECK(status, "creating gregorian date format instance"); | |
752 | UnicodeString gregorianDate("January 18, 2007 AD"); | |
753 | UDate aDate = fmt2->parse(gregorianDate, status); | |
754 | if(!fmt) { | |
755 | errln("Coudln't create en_US instance"); | |
756 | } else { | |
757 | UnicodeString str; | |
758 | fmt->format(aDate, str); | |
759 | logln(UnicodeString() + "as Persian Calendar: " + escape(str)); | |
760 | UnicodeString expected("Dey 28, 1385 AP"); | |
761 | if(str != expected) { | |
762 | errln("Expected " + escape(expected) + " but got " + escape(str)); | |
763 | } | |
764 | UDate otherDate = fmt->parse(expected, status); | |
765 | if(otherDate != aDate) { | |
766 | UnicodeString str3; | |
767 | fmt->format(otherDate, str3); | |
768 | errln("Parse incorrect of " + escape(expected) + " - wanted " + aDate + " but got " + otherDate + ", " + escape(str3)); | |
769 | } else { | |
770 | logln("Parsed OK: " + expected); | |
771 | } | |
772 | // Two digit year parsing problem #4732 | |
773 | fmt->applyPattern("yy-MM-dd"); | |
774 | str.remove(); | |
775 | fmt->format(aDate, str); | |
776 | expected.setTo("85-10-28"); | |
777 | if(str != expected) { | |
778 | errln("Expected " + escape(expected) + " but got " + escape(str)); | |
779 | } | |
780 | otherDate = fmt->parse(expected, status); | |
781 | if (otherDate != aDate) { | |
782 | errln("Parse incorrect of " + escape(expected) + " - wanted " + aDate + " but got " + otherDate); | |
783 | } else { | |
784 | logln("Parsed OK: " + expected); | |
785 | } | |
786 | delete fmt; | |
787 | } | |
788 | delete fmt2; | |
789 | ||
790 | CHECK(status, "Error occured testing Persian Calendar in English "); | |
791 | } | |
792 | ||
793 | ||
b75a7d8f A |
794 | void IntlCalendarTest::simpleTest(const Locale& loc, const UnicodeString& expect, UDate expectDate, UErrorCode& status) |
795 | { | |
796 | UnicodeString tmp; | |
797 | UDate d; | |
798 | DateFormat *fmt0 = DateFormat::createDateTimeInstance(DateFormat::kFull, DateFormat::kFull); | |
799 | ||
800 | logln("Try format/parse of " + (UnicodeString)loc.getName()); | |
801 | DateFormat *fmt2 = DateFormat::createDateInstance(DateFormat::kFull, loc); | |
802 | if(fmt2) { | |
803 | fmt2->format(expectDate, tmp); | |
804 | logln(escape(tmp) + " ( in locale " + loc.getName() + ")"); | |
805 | if(tmp != expect) { | |
806 | errln(UnicodeString("Failed to format " ) + loc.getName() + " expected " + escape(expect) + " got " + escape(tmp) ); | |
807 | } | |
808 | ||
809 | d = fmt2->parse(expect,status); | |
810 | CHECK(status, "Error occured parsing " + UnicodeString(loc.getName())); | |
811 | if(d != expectDate) { | |
812 | fmt2->format(d,tmp); | |
813 | errln(UnicodeString("Failed to parse " ) + escape(expect) + ", " + loc.getName() + " expect " + (double)expectDate + " got " + (double)d + " " + escape(tmp)); | |
814 | logln( "wanted " + escape(fmt0->format(expectDate,tmp.remove())) + " but got " + escape(fmt0->format(d,tmp.remove()))); | |
815 | } | |
816 | delete fmt2; | |
817 | } else { | |
818 | errln((UnicodeString)"Can't create " + loc.getName() + " date instance"); | |
819 | } | |
820 | delete fmt0; | |
821 | } | |
822 | ||
823 | #undef CHECK | |
824 | ||
825 | #endif /* #if !UCONFIG_NO_FORMATTING */ | |
826 | ||
827 | //eof |