]>
Commit | Line | Data |
---|---|---|
b75a7d8f A |
1 | /******************************************************************** |
2 | * COPYRIGHT: | |
3 | * Copyright (c) 1997-2003, International Business Machines Corporation and | |
4 | * others. All Rights Reserved. | |
5 | ********************************************************************/ | |
6 | ||
7 | #include "unicode/utypes.h" | |
8 | ||
9 | #if !UCONFIG_NO_FORMATTING | |
10 | ||
11 | #include "caltest.h" | |
12 | #include "unicode/gregocal.h" | |
13 | #include "unicode/smpdtfmt.h" | |
14 | #include "unicode/simpletz.h" | |
15 | ||
16 | // ***************************************************************************** | |
17 | // class CalendarTest | |
18 | // ***************************************************************************** | |
19 | ||
20 | static UnicodeString fieldName(UCalendarDateFields f); | |
21 | ||
22 | static UnicodeString calToStr(const Calendar & cal) | |
23 | { | |
24 | UnicodeString out; | |
25 | UErrorCode status = U_ZERO_ERROR; | |
26 | int i; | |
27 | for(i = 0;i<UCAL_FIELD_COUNT;i++) { | |
28 | out += (UnicodeString("+") + fieldName((UCalendarDateFields)i) + "=" + cal.get((UCalendarDateFields)i, status) + UnicodeString(", ")); | |
29 | } | |
30 | ||
31 | return out; | |
32 | } | |
33 | ||
34 | void CalendarTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ ) | |
35 | { | |
36 | if (exec) logln("TestSuite TestCalendar"); | |
37 | switch (index) { | |
38 | case 0: | |
39 | name = "TestDOW943"; | |
40 | if (exec) { | |
41 | logln("TestDOW943---"); logln(""); | |
42 | TestDOW943(); | |
43 | } | |
44 | break; | |
45 | case 1: | |
46 | name = "TestClonesUnique908"; | |
47 | if (exec) { | |
48 | logln("TestClonesUnique908---"); logln(""); | |
49 | TestClonesUnique908(); | |
50 | } | |
51 | break; | |
52 | case 2: | |
53 | name = "TestGregorianChange768"; | |
54 | if (exec) { | |
55 | logln("TestGregorianChange768---"); logln(""); | |
56 | TestGregorianChange768(); | |
57 | } | |
58 | break; | |
59 | case 3: | |
60 | name = "TestDisambiguation765"; | |
61 | if (exec) { | |
62 | logln("TestDisambiguation765---"); logln(""); | |
63 | TestDisambiguation765(); | |
64 | } | |
65 | break; | |
66 | case 4: | |
67 | name = "TestGMTvsLocal4064654"; | |
68 | if (exec) { | |
69 | logln("TestGMTvsLocal4064654---"); logln(""); | |
70 | TestGMTvsLocal4064654(); | |
71 | } | |
72 | break; | |
73 | case 5: | |
74 | name = "TestAddSetOrder621"; | |
75 | if (exec) { | |
76 | logln("TestAddSetOrder621---"); logln(""); | |
77 | TestAddSetOrder621(); | |
78 | } | |
79 | break; | |
80 | case 6: | |
81 | name = "TestAdd520"; | |
82 | if (exec) { | |
83 | logln("TestAdd520---"); logln(""); | |
84 | TestAdd520(); | |
85 | } | |
86 | break; | |
87 | case 7: | |
88 | name = "TestFieldSet4781"; | |
89 | if (exec) { | |
90 | logln("TestFieldSet4781---"); logln(""); | |
91 | TestFieldSet4781(); | |
92 | } | |
93 | break; | |
94 | case 8: | |
95 | name = "TestSerialize337"; | |
96 | if (exec) { | |
97 | logln("TestSerialize337---"); logln(""); | |
98 | // TestSerialize337(); | |
99 | } | |
100 | break; | |
101 | case 9: | |
102 | name = "TestSecondsZero121"; | |
103 | if (exec) { | |
104 | logln("TestSecondsZero121---"); logln(""); | |
105 | TestSecondsZero121(); | |
106 | } | |
107 | break; | |
108 | case 10: | |
109 | name = "TestAddSetGet0610"; | |
110 | if (exec) { | |
111 | logln("TestAddSetGet0610---"); logln(""); | |
112 | TestAddSetGet0610(); | |
113 | } | |
114 | break; | |
115 | case 11: | |
116 | name = "TestFields060"; | |
117 | if (exec) { | |
118 | logln("TestFields060---"); logln(""); | |
119 | TestFields060(); | |
120 | } | |
121 | break; | |
122 | case 12: | |
123 | name = "TestEpochStartFields"; | |
124 | if (exec) { | |
125 | logln("TestEpochStartFields---"); logln(""); | |
126 | TestEpochStartFields(); | |
127 | } | |
128 | break; | |
129 | case 13: | |
130 | name = "TestDOWProgression"; | |
131 | if (exec) { | |
132 | logln("TestDOWProgression---"); logln(""); | |
133 | TestDOWProgression(); | |
134 | } | |
135 | break; | |
136 | case 14: | |
137 | name = "TestGenericAPI"; | |
138 | if (exec) { | |
139 | logln("TestGenericAPI---"); logln(""); | |
140 | TestGenericAPI(); | |
141 | } | |
142 | break; | |
143 | case 15: | |
144 | name = "TestAddRollExtensive"; | |
145 | if (exec) { | |
146 | logln("TestAddRollExtensive---"); logln(""); | |
147 | TestAddRollExtensive(); | |
148 | } | |
149 | break; | |
150 | case 16: | |
151 | name = "TestDOW_LOCALandYEAR_WOY"; | |
152 | if (exec) { | |
153 | logln("TestDOW_LOCALandYEAR_WOY---"); logln(""); | |
154 | TestDOW_LOCALandYEAR_WOY(); | |
155 | } | |
156 | break; | |
157 | case 17: | |
158 | name = "TestWOY"; | |
159 | if (exec) { | |
160 | logln("TestWOY---"); logln(""); | |
161 | TestWOY(); | |
162 | } | |
163 | break; | |
164 | case 18: | |
165 | name = "TestRog"; | |
166 | if (exec) { | |
167 | logln("TestRog---"); logln(""); | |
168 | TestRog(); | |
169 | } | |
170 | break; | |
171 | default: name = ""; break; | |
172 | } | |
173 | } | |
174 | ||
175 | // --------------------------------------------------------------------------------- | |
176 | ||
177 | static UnicodeString fieldName(UCalendarDateFields f) { | |
178 | switch (f) { | |
179 | case UCAL_ERA: return "ERA"; | |
180 | case UCAL_YEAR: return "YEAR"; | |
181 | case UCAL_MONTH: return "MONTH"; | |
182 | case UCAL_WEEK_OF_YEAR: return "WEEK_OF_YEAR"; | |
183 | case UCAL_WEEK_OF_MONTH: return "WEEK_OF_MONTH"; | |
184 | case UCAL_DATE: return "DAY_OF_MONTH"; // DATE is synonym for DAY_OF_MONTH | |
185 | case UCAL_DAY_OF_YEAR: return "DAY_OF_YEAR"; | |
186 | case UCAL_DAY_OF_WEEK: return "DAY_OF_WEEK"; | |
187 | case UCAL_DAY_OF_WEEK_IN_MONTH: return "DAY_OF_WEEK_IN_MONTH"; | |
188 | case UCAL_AM_PM: return "AM_PM"; | |
189 | case UCAL_HOUR: return "HOUR"; | |
190 | case UCAL_HOUR_OF_DAY: return "HOUR_OF_DAY"; | |
191 | case UCAL_MINUTE: return "MINUTE"; | |
192 | case UCAL_SECOND: return "SECOND"; | |
193 | case UCAL_MILLISECOND: return "MILLISECOND"; | |
194 | case UCAL_ZONE_OFFSET: return "ZONE_OFFSET"; | |
195 | case UCAL_DST_OFFSET: return "DST_OFFSET"; | |
196 | case UCAL_YEAR_WOY: return "YEAR_WOY"; | |
197 | case UCAL_DOW_LOCAL: return "DOW_LOCAL"; | |
198 | case UCAL_FIELD_COUNT: return "FIELD_COUNT"; | |
199 | default: | |
200 | return UnicodeString("") + ((int32_t)f); | |
201 | } | |
202 | } | |
203 | ||
204 | /** | |
205 | * Test various API methods for API completeness. | |
206 | */ | |
207 | void | |
208 | CalendarTest::TestGenericAPI() | |
209 | { | |
210 | UErrorCode status = U_ZERO_ERROR; | |
211 | UDate d; | |
212 | UnicodeString str; | |
213 | ||
214 | UDate when = date(90, UCAL_APRIL, 15); | |
215 | ||
216 | UnicodeString tzid("TestZone"); | |
217 | int32_t tzoffset = 123400; | |
218 | ||
219 | SimpleTimeZone *zone = new SimpleTimeZone(tzoffset, tzid); | |
220 | Calendar *cal = Calendar::createInstance(zone->clone(), status); | |
221 | if (failure(status, "Calendar::createInstance")) return; | |
222 | ||
223 | if (*zone != cal->getTimeZone()) errln("FAIL: Calendar::getTimeZone failed"); | |
224 | ||
225 | Calendar *cal2 = Calendar::createInstance(cal->getTimeZone(), status); | |
226 | if (failure(status, "Calendar::createInstance")) return; | |
227 | cal->setTime(when, status); | |
228 | cal2->setTime(when, status); | |
229 | if (failure(status, "Calendar::setTime")) return; | |
230 | ||
231 | if (!(*cal == *cal2)) errln("FAIL: Calendar::operator== failed"); | |
232 | if ((*cal != *cal2)) errln("FAIL: Calendar::operator!= failed"); | |
233 | if (!cal->equals(*cal2, status) || | |
234 | cal->before(*cal2, status) || | |
235 | cal->after(*cal2, status) || | |
236 | U_FAILURE(status)) errln("FAIL: equals/before/after failed"); | |
237 | ||
238 | cal2->setTime(when + 1000, status); | |
239 | if (failure(status, "Calendar::setTime")) return; | |
240 | if (cal->equals(*cal2, status) || | |
241 | cal2->before(*cal, status) || | |
242 | cal->after(*cal2, status) || | |
243 | U_FAILURE(status)) errln("FAIL: equals/before/after failed"); | |
244 | ||
245 | cal->roll(UCAL_SECOND, (UBool) TRUE, status); | |
246 | if (failure(status, "Calendar::roll")) return; | |
247 | if (!cal->equals(*cal2, status) || | |
248 | cal->before(*cal2, status) || | |
249 | cal->after(*cal2, status) || | |
250 | U_FAILURE(status)) errln("FAIL: equals/before/after failed"); | |
251 | ||
252 | // Roll back to January | |
253 | cal->roll(UCAL_MONTH, (int32_t)(1 + UCAL_DECEMBER - cal->get(UCAL_MONTH, status)), status); | |
254 | if (failure(status, "Calendar::roll")) return; | |
255 | if (cal->equals(*cal2, status) || | |
256 | cal2->before(*cal, status) || | |
257 | cal->after(*cal2, status) || | |
258 | U_FAILURE(status)) errln("FAIL: equals/before/after failed"); | |
259 | ||
260 | TimeZone *z = cal->orphanTimeZone(); | |
261 | if (z->getID(str) != tzid || | |
262 | z->getRawOffset() != tzoffset) | |
263 | errln("FAIL: orphanTimeZone failed"); | |
264 | ||
265 | int32_t i; | |
266 | for (i=0; i<2; ++i) | |
267 | { | |
268 | UBool lenient = ( i > 0 ); | |
269 | cal->setLenient(lenient); | |
270 | if (lenient != cal->isLenient()) errln("FAIL: setLenient/isLenient failed"); | |
271 | // Later: Check for lenient behavior | |
272 | } | |
273 | ||
274 | for (i=UCAL_SUNDAY; i<=UCAL_SATURDAY; ++i) | |
275 | { | |
276 | cal->setFirstDayOfWeek((UCalendarDaysOfWeek)i); | |
277 | if (cal->getFirstDayOfWeek() != i) errln("FAIL: set/getFirstDayOfWeek failed"); | |
278 | UErrorCode aStatus = U_ZERO_ERROR; | |
279 | if (cal->getFirstDayOfWeek(aStatus) != i || U_FAILURE(aStatus)) errln("FAIL: getFirstDayOfWeek(status) failed"); | |
280 | } | |
281 | ||
282 | for (i=1; i<=7; ++i) | |
283 | { | |
284 | cal->setMinimalDaysInFirstWeek((uint8_t)i); | |
285 | if (cal->getMinimalDaysInFirstWeek() != i) errln("FAIL: set/getFirstDayOfWeek failed"); | |
286 | } | |
287 | ||
288 | for (i=0; i<UCAL_FIELD_COUNT; ++i) | |
289 | { | |
290 | if (cal->getMinimum((UCalendarDateFields)i) != cal->getGreatestMinimum((UCalendarDateFields)i)) | |
291 | errln("FAIL: getMinimum doesn't match getGreatestMinimum for field " + i); | |
292 | if (cal->getLeastMaximum((UCalendarDateFields)i) > cal->getMaximum((UCalendarDateFields)i)) | |
293 | errln("FAIL: getLeastMaximum larger than getMaximum for field " + i); | |
294 | if (cal->getMinimum((UCalendarDateFields)i) >= cal->getMaximum((UCalendarDateFields)i)) | |
295 | errln("FAIL: getMinimum not less than getMaximum for field " + i); | |
296 | } | |
297 | ||
298 | cal->adoptTimeZone(TimeZone::createDefault()); | |
299 | cal->clear(); | |
300 | cal->set(1984, 5, 24); | |
301 | if (cal->getTime(status) != date(84, 5, 24) || U_FAILURE(status)) | |
302 | errln("FAIL: Calendar::set(3 args) failed"); | |
303 | ||
304 | cal->clear(); | |
305 | cal->set(1985, 3, 2, 11, 49); | |
306 | if (cal->getTime(status) != date(85, 3, 2, 11, 49) || U_FAILURE(status)) | |
307 | errln("FAIL: Calendar::set(5 args) failed"); | |
308 | ||
309 | cal->clear(); | |
310 | cal->set(1995, 9, 12, 1, 39, 55); | |
311 | if (cal->getTime(status) != date(95, 9, 12, 1, 39, 55) || U_FAILURE(status)) | |
312 | errln("FAIL: Calendar::set(6 args) failed"); | |
313 | ||
314 | cal->getTime(status); | |
315 | if (failure(status, "Calendar::getTime")) return; | |
316 | for (i=0; i<UCAL_FIELD_COUNT; ++i) | |
317 | { | |
318 | switch(i) { | |
319 | case UCAL_YEAR: case UCAL_MONTH: case UCAL_DATE: | |
320 | case UCAL_HOUR_OF_DAY: case UCAL_MINUTE: case UCAL_SECOND: | |
321 | if (!cal->isSet((UCalendarDateFields)i)) errln("FAIL: Calendar::isSet failed"); | |
322 | break; | |
323 | default: | |
324 | if (cal->isSet((UCalendarDateFields)i)) errln("FAIL: Calendar::isSet failed"); | |
325 | } | |
326 | cal->clear((UCalendarDateFields)i); | |
327 | if (cal->isSet((UCalendarDateFields)i)) errln("FAIL: Calendar::clear/isSet failed"); | |
328 | } | |
329 | ||
330 | delete cal; | |
331 | delete cal2; | |
332 | ||
333 | int32_t count; | |
334 | const Locale* loc = Calendar::getAvailableLocales(count); | |
335 | if (count < 1 || loc == 0) | |
336 | { | |
337 | errln("FAIL: getAvailableLocales failed"); | |
338 | } | |
339 | else | |
340 | { | |
341 | for (i=0; i<count; ++i) | |
342 | { | |
343 | cal = Calendar::createInstance(loc[i], status); | |
344 | if (failure(status, "Calendar::createInstance")) return; | |
345 | delete cal; | |
346 | } | |
347 | } | |
348 | ||
349 | cal = Calendar::createInstance(TimeZone::createDefault(), Locale::getEnglish(), status); | |
350 | if (failure(status, "Calendar::createInstance")) return; | |
351 | delete cal; | |
352 | ||
353 | cal = Calendar::createInstance(*zone, Locale::getEnglish(), status); | |
354 | if (failure(status, "Calendar::createInstance")) return; | |
355 | delete cal; | |
356 | ||
357 | GregorianCalendar *gc = new GregorianCalendar(*zone, status); | |
358 | if (failure(status, "new GregorianCalendar")) return; | |
359 | delete gc; | |
360 | ||
361 | gc = new GregorianCalendar(Locale::getEnglish(), status); | |
362 | if (failure(status, "new GregorianCalendar")) return; | |
363 | delete gc; | |
364 | ||
365 | gc = new GregorianCalendar(Locale::getEnglish(), status); | |
366 | delete gc; | |
367 | ||
368 | gc = new GregorianCalendar(*zone, Locale::getEnglish(), status); | |
369 | if (failure(status, "new GregorianCalendar")) return; | |
370 | delete gc; | |
371 | ||
372 | gc = new GregorianCalendar(zone, status); | |
373 | if (failure(status, "new GregorianCalendar")) return; | |
374 | delete gc; | |
375 | ||
376 | gc = new GregorianCalendar(1998, 10, 14, 21, 43, status); | |
377 | if (gc->getTime(status) != (d =date(98, 10, 14, 21, 43) )|| U_FAILURE(status)) | |
378 | errln("FAIL: new GregorianCalendar(ymdhm) failed with " + UnicodeString(u_errorName(status)) + ", cal=" + gc->getTime(status) + UnicodeString(calToStr(*gc)) + ", d=" + d); | |
379 | else | |
380 | logln(UnicodeString("GOOD: cal=") +gc->getTime(status) + UnicodeString(calToStr(*gc)) + ", d=" + d); | |
381 | delete gc; | |
382 | ||
383 | gc = new GregorianCalendar(1998, 10, 14, 21, 43, 55, status); | |
384 | if (gc->getTime(status) != (d=date(98, 10, 14, 21, 43, 55)) || U_FAILURE(status)) | |
385 | errln("FAIL: new GregorianCalendar(ymdhms) failed with " + UnicodeString(u_errorName(status))); | |
386 | ||
387 | GregorianCalendar gc2(Locale::getEnglish(), status); | |
388 | if (failure(status, "new GregorianCalendar")) return; | |
389 | gc2 = *gc; | |
390 | if (gc2 != *gc || !(gc2 == *gc)) errln("FAIL: GregorianCalendar assignment/operator==/operator!= failed"); | |
391 | delete gc; | |
392 | delete z; | |
393 | } | |
394 | ||
395 | // ------------------------------------- | |
396 | ||
397 | /** | |
398 | * This test confirms the correct behavior of add when incrementing | |
399 | * through subsequent days. | |
400 | */ | |
401 | void | |
402 | CalendarTest::TestRog() | |
403 | { | |
404 | UErrorCode status = U_ZERO_ERROR; | |
405 | GregorianCalendar* gc = new GregorianCalendar(status); | |
406 | if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; } | |
407 | int32_t year = 1997, month = UCAL_APRIL, date = 1; | |
408 | gc->set(year, month, date); | |
409 | gc->set(UCAL_HOUR_OF_DAY, 23); | |
410 | gc->set(UCAL_MINUTE, 0); | |
411 | gc->set(UCAL_SECOND, 0); | |
412 | gc->set(UCAL_MILLISECOND, 0); | |
413 | for (int32_t i = 0; i < 9; i++, gc->add(UCAL_DATE, 1, status)) { | |
414 | if (U_FAILURE(status)) { errln("Calendar::add failed"); return; } | |
415 | if (gc->get(UCAL_YEAR, status) != year || | |
416 | gc->get(UCAL_MONTH, status) != month || | |
417 | gc->get(UCAL_DATE, status) != (date + i)) errln("FAIL: Date wrong"); | |
418 | if (U_FAILURE(status)) { errln("Calendar::get failed"); return; } | |
419 | } | |
420 | delete gc; | |
421 | } | |
422 | ||
423 | // ------------------------------------- | |
424 | ||
425 | /** | |
426 | * Test the handling of the day of the week, checking for correctness and | |
427 | * for correct minimum and maximum values. | |
428 | */ | |
429 | void | |
430 | CalendarTest::TestDOW943() | |
431 | { | |
432 | dowTest(FALSE); | |
433 | dowTest(TRUE); | |
434 | } | |
435 | ||
436 | void CalendarTest::dowTest(UBool lenient) | |
437 | { | |
438 | UErrorCode status = U_ZERO_ERROR; | |
439 | GregorianCalendar* cal = new GregorianCalendar(status); | |
440 | if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; } | |
441 | cal->set(1997, UCAL_AUGUST, 12); | |
442 | cal->getTime(status); | |
443 | if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; } | |
444 | cal->setLenient(lenient); | |
445 | cal->set(1996, UCAL_DECEMBER, 1); | |
446 | int32_t dow = cal->get(UCAL_DAY_OF_WEEK, status); | |
447 | if (U_FAILURE(status)) { errln("Calendar::get failed"); return; } | |
448 | int32_t min = cal->getMinimum(UCAL_DAY_OF_WEEK); | |
449 | int32_t max = cal->getMaximum(UCAL_DAY_OF_WEEK); | |
450 | if (dow < min || | |
451 | dow > max) errln(UnicodeString("FAIL: Day of week ") + (int32_t)dow + " out of range"); | |
452 | if (dow != UCAL_SUNDAY) errln("FAIL: Day of week should be SUNDAY"); | |
453 | if (min != UCAL_SUNDAY || | |
454 | max != UCAL_SATURDAY) errln("FAIL: Min/max bad"); | |
455 | delete cal; | |
456 | } | |
457 | ||
458 | // ------------------------------------- | |
459 | ||
460 | /** | |
461 | * Confirm that cloned Calendar objects do not inadvertently share substructures. | |
462 | */ | |
463 | void | |
464 | CalendarTest::TestClonesUnique908() | |
465 | { | |
466 | UErrorCode status = U_ZERO_ERROR; | |
467 | Calendar *c = Calendar::createInstance(status); | |
468 | if (U_FAILURE(status)) { errln("Calendar::createInstance failed"); return; } | |
469 | Calendar *d = (Calendar*) c->clone(); | |
470 | c->set(UCAL_MILLISECOND, 123); | |
471 | d->set(UCAL_MILLISECOND, 456); | |
472 | if (c->get(UCAL_MILLISECOND, status) != 123 || | |
473 | d->get(UCAL_MILLISECOND, status) != 456) { | |
474 | errln("FAIL: Clones share fields"); | |
475 | } | |
476 | if (U_FAILURE(status)) { errln("Calendar::get failed"); return; } | |
477 | delete c; | |
478 | delete d; | |
479 | } | |
480 | ||
481 | // ------------------------------------- | |
482 | ||
483 | /** | |
484 | * Confirm that the Gregorian cutoff value works as advertised. | |
485 | */ | |
486 | void | |
487 | CalendarTest::TestGregorianChange768() | |
488 | { | |
489 | UBool b; | |
490 | UErrorCode status = U_ZERO_ERROR; | |
491 | UnicodeString str; | |
492 | GregorianCalendar* c = new GregorianCalendar(status); | |
493 | if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; } | |
494 | logln(UnicodeString("With cutoff ") + dateToString(c->getGregorianChange(), str)); | |
495 | b = c->isLeapYear(1800); | |
496 | logln(UnicodeString(" isLeapYear(1800) = ") + (b ? "true" : "false")); | |
497 | logln(UnicodeString(" (should be FALSE)")); | |
498 | if (b) errln("FAIL"); | |
499 | c->setGregorianChange(date(0, 0, 1), status); | |
500 | if (U_FAILURE(status)) { errln("GregorianCalendar::setGregorianChange failed"); return; } | |
501 | logln(UnicodeString("With cutoff ") + dateToString(c->getGregorianChange(), str)); | |
502 | b = c->isLeapYear(1800); | |
503 | logln(UnicodeString(" isLeapYear(1800) = ") + (b ? "true" : "false")); | |
504 | logln(UnicodeString(" (should be TRUE)")); | |
505 | if (!b) errln("FAIL"); | |
506 | delete c; | |
507 | } | |
508 | ||
509 | // ------------------------------------- | |
510 | ||
511 | /** | |
512 | * Confirm the functioning of the field disambiguation algorithm. | |
513 | */ | |
514 | void | |
515 | CalendarTest::TestDisambiguation765() | |
516 | { | |
517 | UErrorCode status = U_ZERO_ERROR; | |
518 | Calendar *c = Calendar::createInstance(status); | |
519 | if (U_FAILURE(status)) { errln("Calendar::createInstance failed"); return; } | |
520 | c->setLenient(FALSE); | |
521 | c->clear(); | |
522 | c->set(UCAL_YEAR, 1997); | |
523 | c->set(UCAL_MONTH, UCAL_JUNE); | |
524 | c->set(UCAL_DATE, 3); | |
525 | verify765("1997 third day of June = ", c, 1997, UCAL_JUNE, 3); | |
526 | c->clear(); | |
527 | c->set(UCAL_YEAR, 1997); | |
528 | c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY); | |
529 | c->set(UCAL_MONTH, UCAL_JUNE); | |
530 | c->set(UCAL_DAY_OF_WEEK_IN_MONTH, 1); | |
531 | verify765("1997 first Tuesday in June = ", c, 1997, UCAL_JUNE, 3); | |
532 | c->clear(); | |
533 | c->set(UCAL_YEAR, 1997); | |
534 | c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY); | |
535 | c->set(UCAL_MONTH, UCAL_JUNE); | |
536 | c->set(UCAL_DAY_OF_WEEK_IN_MONTH, - 1); | |
537 | verify765("1997 last Tuesday in June = ", c, 1997, UCAL_JUNE, 24); | |
538 | // IllegalArgumentException e = null; | |
539 | status = U_ZERO_ERROR; | |
540 | //try { | |
541 | c->clear(); | |
542 | c->set(UCAL_YEAR, 1997); | |
543 | c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY); | |
544 | c->set(UCAL_MONTH, UCAL_JUNE); | |
545 | c->set(UCAL_DAY_OF_WEEK_IN_MONTH, 0); | |
546 | c->getTime(status); | |
547 | //} | |
548 | //catch(IllegalArgumentException ex) { | |
549 | // e = ex; | |
550 | //} | |
551 | verify765("1997 zero-th Tuesday in June = ", status); | |
552 | c->clear(); | |
553 | c->set(UCAL_YEAR, 1997); | |
554 | c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY); | |
555 | c->set(UCAL_MONTH, UCAL_JUNE); | |
556 | c->set(UCAL_WEEK_OF_MONTH, 1); | |
557 | verify765("1997 Tuesday in week 1 of June = ", c, 1997, UCAL_JUNE, 3); | |
558 | c->clear(); | |
559 | c->set(UCAL_YEAR, 1997); | |
560 | c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY); | |
561 | c->set(UCAL_MONTH, UCAL_JUNE); | |
562 | c->set(UCAL_WEEK_OF_MONTH, 5); | |
563 | verify765("1997 Tuesday in week 5 of June = ", c, 1997, UCAL_JULY, 1); | |
564 | status = U_ZERO_ERROR; | |
565 | //try { | |
566 | c->clear(); | |
567 | c->set(UCAL_YEAR, 1997); | |
568 | c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY); | |
569 | c->set(UCAL_MONTH, UCAL_JUNE); | |
570 | c->set(UCAL_WEEK_OF_MONTH, 0); | |
571 | verify765("1997 Tuesday in week 0 of June = ", c, 1997, UCAL_MAY, 27); | |
572 | //} | |
573 | //catch(IllegalArgumentException ex) { | |
574 | // errln("FAIL: Exception seen:"); | |
575 | // ex.printStackTrace(log); | |
576 | //} | |
577 | /* Note: The following test used to expect YEAR 1997, WOY 1 to | |
578 | * resolve to a date in Dec 1996; that is, to behave as if | |
579 | * YEAR_WOY were 1997. With the addition of a new explicit | |
580 | * YEAR_WOY field, YEAR_WOY must itself be set if that is what is | |
581 | * desired. Using YEAR in combination with WOY is ambiguous, and | |
582 | * results in the first WOY/DOW day of the year satisfying the | |
583 | * given fields (there may be up to two such days). In this case, | |
584 | * it propertly resolves to Tue Dec 30 1997, which has a WOY value | |
585 | * of 1 (for YEAR_WOY 1998) and a DOW of Tuesday, and falls in the | |
586 | * _calendar_ year 1997, as specified. - aliu */ | |
587 | c->clear(); | |
588 | c->set(UCAL_YEAR_WOY, 1997); // aliu | |
589 | c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY); | |
590 | c->set(UCAL_WEEK_OF_YEAR, 1); | |
591 | verify765("1997 Tuesday in week 1 of yearWOY = ", c, 1996, UCAL_DECEMBER, 31); | |
592 | c->clear(); // - add test for YEAR | |
593 | c->set(UCAL_YEAR, 1997); | |
594 | c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY); | |
595 | c->set(UCAL_WEEK_OF_YEAR, 1); | |
596 | verify765("1997 Tuesday in week 1 of year = ", c, 1997, UCAL_DECEMBER, 30); | |
597 | c->clear(); | |
598 | c->set(UCAL_YEAR, 1997); | |
599 | c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY); | |
600 | c->set(UCAL_WEEK_OF_YEAR, 10); | |
601 | verify765("1997 Tuesday in week 10 of year = ", c, 1997, UCAL_MARCH, 4); | |
602 | //try { | |
603 | ||
604 | // {sfb} week 0 is no longer a valid week of year | |
605 | /*c->clear(); | |
606 | c->set(Calendar::YEAR, 1997); | |
607 | c->set(Calendar::DAY_OF_WEEK, Calendar::TUESDAY); | |
608 | //c->set(Calendar::WEEK_OF_YEAR, 0); | |
609 | c->set(Calendar::WEEK_OF_YEAR, 1); | |
610 | verify765("1997 Tuesday in week 0 of year = ", c, 1996, Calendar::DECEMBER, 24);*/ | |
611 | ||
612 | //} | |
613 | //catch(IllegalArgumentException ex) { | |
614 | // errln("FAIL: Exception seen:"); | |
615 | // ex.printStackTrace(log); | |
616 | //} | |
617 | delete c; | |
618 | } | |
619 | ||
620 | // ------------------------------------- | |
621 | ||
622 | void | |
623 | CalendarTest::verify765(const UnicodeString& msg, Calendar* c, int32_t year, int32_t month, int32_t day) | |
624 | { | |
625 | UnicodeString str; | |
626 | UErrorCode status = U_ZERO_ERROR; | |
627 | if (c->get(UCAL_YEAR, status) == year && | |
628 | c->get(UCAL_MONTH, status) == month && | |
629 | c->get(UCAL_DATE, status) == day) { | |
630 | if (U_FAILURE(status)) { errln("FAIL: Calendar::get failed"); return; } | |
631 | logln("PASS: " + msg + dateToString(c->getTime(status), str)); | |
632 | if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; } | |
633 | } | |
634 | else { | |
635 | errln("FAIL: " + msg + dateToString(c->getTime(status), str) + "; expected " + (int32_t)year + "/" + (int32_t)(month + 1) + "/" + (int32_t)day); | |
636 | if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; } | |
637 | } | |
638 | } | |
639 | ||
640 | // ------------------------------------- | |
641 | ||
642 | void | |
643 | CalendarTest::verify765(const UnicodeString& msg/*, IllegalArgumentException e*/, UErrorCode status) | |
644 | { | |
645 | if (status != U_ILLEGAL_ARGUMENT_ERROR) errln("FAIL: No IllegalArgumentException for " + msg); | |
646 | else logln("PASS: " + msg + "IllegalArgument as expected"); | |
647 | } | |
648 | ||
649 | // ------------------------------------- | |
650 | ||
651 | /** | |
652 | * Confirm that the offset between local time and GMT behaves as expected. | |
653 | */ | |
654 | void | |
655 | CalendarTest::TestGMTvsLocal4064654() | |
656 | { | |
657 | test4064654(1997, 1, 1, 12, 0, 0); | |
658 | test4064654(1997, 4, 16, 18, 30, 0); | |
659 | } | |
660 | ||
661 | // ------------------------------------- | |
662 | ||
663 | void | |
664 | CalendarTest::test4064654(int32_t yr, int32_t mo, int32_t dt, int32_t hr, int32_t mn, int32_t sc) | |
665 | { | |
666 | UDate date; | |
667 | UErrorCode status = U_ZERO_ERROR; | |
668 | UnicodeString str; | |
669 | Calendar *gmtcal = Calendar::createInstance(status); | |
670 | if (U_FAILURE(status)) { errln("Calendar::createInstance failed"); return; } | |
671 | gmtcal->adoptTimeZone(TimeZone::createTimeZone("Africa/Casablanca")); | |
672 | gmtcal->set(yr, mo - 1, dt, hr, mn, sc); | |
673 | gmtcal->set(UCAL_MILLISECOND, 0); | |
674 | date = gmtcal->getTime(status); | |
675 | if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; } | |
676 | logln("date = " + dateToString(date, str)); | |
677 | Calendar *cal = Calendar::createInstance(status); | |
678 | if (U_FAILURE(status)) { errln("Calendar::createInstance failed"); return; } | |
679 | cal->setTime(date, status); | |
680 | if (U_FAILURE(status)) { errln("Calendar::setTime failed"); return; } | |
681 | int32_t offset = cal->getTimeZone().getOffset((uint8_t)cal->get(UCAL_ERA, status), | |
682 | cal->get(UCAL_YEAR, status), | |
683 | cal->get(UCAL_MONTH, status), | |
684 | cal->get(UCAL_DATE, status), | |
685 | (uint8_t)cal->get(UCAL_DAY_OF_WEEK, status), | |
686 | cal->get(UCAL_MILLISECOND, status), status); | |
687 | if (U_FAILURE(status)) { errln("Calendar::get failed"); return; } | |
688 | logln("offset for " + dateToString(date, str) + "= " + (offset / 1000 / 60 / 60.0) + "hr"); | |
689 | int32_t utc = ((cal->get(UCAL_HOUR_OF_DAY, status) * 60 + | |
690 | cal->get(UCAL_MINUTE, status)) * 60 + | |
691 | cal->get(UCAL_SECOND, status)) * 1000 + | |
692 | cal->get(UCAL_MILLISECOND, status) - offset; | |
693 | if (U_FAILURE(status)) { errln("Calendar::get failed"); return; } | |
694 | int32_t expected = ((hr * 60 + mn) * 60 + sc) * 1000; | |
695 | if (utc != expected) errln(UnicodeString("FAIL: Discrepancy of ") + (utc - expected) + | |
696 | " millis = " + ((utc - expected) / 1000 / 60 / 60.0) + " hr"); | |
697 | delete gmtcal; | |
698 | delete cal; | |
699 | } | |
700 | ||
701 | // ------------------------------------- | |
702 | ||
703 | /** | |
704 | * The operations of adding and setting should not exhibit pathological | |
705 | * dependence on the order of operations. This test checks for this. | |
706 | */ | |
707 | void | |
708 | CalendarTest::TestAddSetOrder621() | |
709 | { | |
710 | UDate d = date(97, 4, 14, 13, 23, 45); | |
711 | UErrorCode status = U_ZERO_ERROR; | |
712 | Calendar *cal = Calendar::createInstance(status); | |
713 | if (U_FAILURE(status)) { | |
714 | errln("Calendar::createInstance failed"); | |
715 | delete cal; | |
716 | return; | |
717 | } | |
718 | cal->setTime(d, status); | |
719 | if (U_FAILURE(status)) { | |
720 | errln("Calendar::setTime failed"); | |
721 | delete cal; | |
722 | return; | |
723 | } | |
724 | cal->add(UCAL_DATE, - 5, status); | |
725 | if (U_FAILURE(status)) { | |
726 | errln("Calendar::add failed"); | |
727 | delete cal; | |
728 | return; | |
729 | } | |
730 | cal->set(UCAL_HOUR_OF_DAY, 0); | |
731 | cal->set(UCAL_MINUTE, 0); | |
732 | cal->set(UCAL_SECOND, 0); | |
733 | UnicodeString s; | |
734 | dateToString(cal->getTime(status), s); | |
735 | if (U_FAILURE(status)) { | |
736 | errln("Calendar::getTime failed"); | |
737 | delete cal; | |
738 | return; | |
739 | } | |
740 | delete cal; | |
741 | ||
742 | cal = Calendar::createInstance(status); | |
743 | if (U_FAILURE(status)) { | |
744 | errln("Calendar::createInstance failed"); | |
745 | delete cal; | |
746 | return; | |
747 | } | |
748 | cal->setTime(d, status); | |
749 | if (U_FAILURE(status)) { | |
750 | errln("Calendar::setTime failed"); | |
751 | delete cal; | |
752 | return; | |
753 | } | |
754 | cal->set(UCAL_HOUR_OF_DAY, 0); | |
755 | cal->set(UCAL_MINUTE, 0); | |
756 | cal->set(UCAL_SECOND, 0); | |
757 | cal->add(UCAL_DATE, - 5, status); | |
758 | if (U_FAILURE(status)) { | |
759 | errln("Calendar::add failed"); | |
760 | delete cal; | |
761 | return; | |
762 | } | |
763 | UnicodeString s2; | |
764 | dateToString(cal->getTime(status), s2); | |
765 | if (U_FAILURE(status)) { | |
766 | errln("Calendar::getTime failed"); | |
767 | delete cal; | |
768 | return; | |
769 | } | |
770 | if (s == s2) | |
771 | logln("Pass: " + s + " == " + s2); | |
772 | else | |
773 | errln("FAIL: " + s + " != " + s2); | |
774 | delete cal; | |
775 | } | |
776 | ||
777 | // ------------------------------------- | |
778 | ||
779 | /** | |
780 | * Confirm that adding to various fields works. | |
781 | */ | |
782 | void | |
783 | CalendarTest::TestAdd520() | |
784 | { | |
785 | int32_t y = 1997, m = UCAL_FEBRUARY, d = 1; | |
786 | UErrorCode status = U_ZERO_ERROR; | |
787 | GregorianCalendar *temp = new GregorianCalendar(y, m, d, status); | |
788 | if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; } | |
789 | check520(temp, y, m, d); | |
790 | temp->add(UCAL_YEAR, 1, status); | |
791 | if (U_FAILURE(status)) { errln("Calendar::add failed"); return; } | |
792 | y++; | |
793 | check520(temp, y, m, d); | |
794 | temp->add(UCAL_MONTH, 1, status); | |
795 | if (U_FAILURE(status)) { errln("Calendar::add failed"); return; } | |
796 | m++; | |
797 | check520(temp, y, m, d); | |
798 | temp->add(UCAL_DATE, 1, status); | |
799 | if (U_FAILURE(status)) { errln("Calendar::add failed"); return; } | |
800 | d++; | |
801 | check520(temp, y, m, d); | |
802 | temp->add(UCAL_DATE, 2, status); | |
803 | if (U_FAILURE(status)) { errln("Calendar::add failed"); return; } | |
804 | d += 2; | |
805 | check520(temp, y, m, d); | |
806 | temp->add(UCAL_DATE, 28, status); | |
807 | if (U_FAILURE(status)) { errln("Calendar::add failed"); return; } | |
808 | d = 1;++m; | |
809 | check520(temp, y, m, d); | |
810 | delete temp; | |
811 | } | |
812 | ||
813 | // ------------------------------------- | |
814 | ||
815 | /** | |
816 | * Execute adding and rolling in GregorianCalendar extensively, | |
817 | */ | |
818 | void | |
819 | CalendarTest::TestAddRollExtensive() | |
820 | { | |
821 | int32_t maxlimit = 40; | |
822 | int32_t y = 1997, m = UCAL_FEBRUARY, d = 1, hr = 1, min = 1, sec = 0, ms = 0; | |
823 | UErrorCode status = U_ZERO_ERROR; | |
824 | GregorianCalendar *temp = new GregorianCalendar(y, m, d, status); | |
825 | if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; } | |
826 | ||
827 | temp->set(UCAL_HOUR, hr); | |
828 | temp->set(UCAL_MINUTE, min); | |
829 | temp->set(UCAL_SECOND, sec); | |
830 | temp->set(UCAL_MILLISECOND, ms); | |
831 | ||
832 | UCalendarDateFields e; | |
833 | ||
834 | logln("Testing GregorianCalendar add..."); | |
835 | e = UCAL_YEAR; | |
836 | while (e < UCAL_FIELD_COUNT) { | |
837 | int32_t i; | |
838 | int32_t limit = maxlimit; | |
839 | status = U_ZERO_ERROR; | |
840 | for (i = 0; i < limit; i++) { | |
841 | temp->add(e, 1, status); | |
842 | if (U_FAILURE(status)) { limit = i; status = U_ZERO_ERROR; } | |
843 | } | |
844 | for (i = 0; i < limit; i++) { | |
845 | temp->add(e, -1, status); | |
846 | if (U_FAILURE(status)) { errln("GregorianCalendar::add -1 failed"); return; } | |
847 | } | |
848 | check520(temp, y, m, d, hr, min, sec, ms, e); | |
849 | ||
850 | e = (UCalendarDateFields) ((int32_t) e + 1); | |
851 | } | |
852 | ||
853 | logln("Testing GregorianCalendar roll..."); | |
854 | e = UCAL_YEAR; | |
855 | while (e < UCAL_FIELD_COUNT) { | |
856 | int32_t i; | |
857 | int32_t limit = maxlimit; | |
858 | status = U_ZERO_ERROR; | |
859 | for (i = 0; i < limit; i++) { | |
860 | temp->roll(e, 1, status); | |
861 | if (U_FAILURE(status)) { limit = i; status = U_ZERO_ERROR; } | |
862 | } | |
863 | for (i = 0; i < limit; i++) { | |
864 | temp->roll(e, -1, status); | |
865 | if (U_FAILURE(status)) { errln("GregorianCalendar::roll -1 failed"); return; } | |
866 | } | |
867 | check520(temp, y, m, d, hr, min, sec, ms, e); | |
868 | ||
869 | e = (UCalendarDateFields) ((int32_t) e + 1); | |
870 | } | |
871 | ||
872 | delete temp; | |
873 | } | |
874 | ||
875 | // ------------------------------------- | |
876 | void | |
877 | CalendarTest::check520(Calendar* c, | |
878 | int32_t y, int32_t m, int32_t d, | |
879 | int32_t hr, int32_t min, int32_t sec, | |
880 | int32_t ms, UCalendarDateFields field) | |
881 | ||
882 | { | |
883 | UErrorCode status = U_ZERO_ERROR; | |
884 | if (c->get(UCAL_YEAR, status) != y || | |
885 | c->get(UCAL_MONTH, status) != m || | |
886 | c->get(UCAL_DATE, status) != d || | |
887 | c->get(UCAL_HOUR, status) != hr || | |
888 | c->get(UCAL_MINUTE, status) != min || | |
889 | c->get(UCAL_SECOND, status) != sec || | |
890 | c->get(UCAL_MILLISECOND, status) != ms) { | |
891 | errln(UnicodeString("U_FAILURE for field ") + (int32_t)field + | |
892 | ": Expected y/m/d h:m:s:ms of " + | |
893 | y + "/" + (m + 1) + "/" + d + " " + | |
894 | hr + ":" + min + ":" + sec + ":" + ms + | |
895 | "; got " + c->get(UCAL_YEAR, status) + | |
896 | "/" + (c->get(UCAL_MONTH, status) + 1) + | |
897 | "/" + c->get(UCAL_DATE, status) + | |
898 | " " + c->get(UCAL_HOUR, status) + ":" + | |
899 | c->get(UCAL_MINUTE, status) + ":" + | |
900 | c->get(UCAL_SECOND, status) + ":" + | |
901 | c->get(UCAL_MILLISECOND, status) | |
902 | ); | |
903 | ||
904 | if (U_FAILURE(status)) { errln("Calendar::get failed"); return; } | |
905 | } | |
906 | else | |
907 | logln(UnicodeString("Confirmed: ") + y + "/" + | |
908 | (m + 1) + "/" + d + " " + | |
909 | hr + ":" + min + ":" + sec + ":" + ms); | |
910 | } | |
911 | ||
912 | // ------------------------------------- | |
913 | void | |
914 | CalendarTest::check520(Calendar* c, | |
915 | int32_t y, int32_t m, int32_t d) | |
916 | ||
917 | { | |
918 | UErrorCode status = U_ZERO_ERROR; | |
919 | if (c->get(UCAL_YEAR, status) != y || | |
920 | c->get(UCAL_MONTH, status) != m || | |
921 | c->get(UCAL_DATE, status) != d) { | |
922 | errln(UnicodeString("FAILURE: Expected y/m/d of ") + | |
923 | y + "/" + (m + 1) + "/" + d + " " + | |
924 | "; got " + c->get(UCAL_YEAR, status) + | |
925 | "/" + (c->get(UCAL_MONTH, status) + 1) + | |
926 | "/" + c->get(UCAL_DATE, status) | |
927 | ); | |
928 | ||
929 | if (U_FAILURE(status)) { errln("Calendar::get failed"); return; } | |
930 | } | |
931 | else | |
932 | logln(UnicodeString("Confirmed: ") + y + "/" + | |
933 | (m + 1) + "/" + d); | |
934 | } | |
935 | ||
936 | // ------------------------------------- | |
937 | ||
938 | /** | |
939 | * Test that setting of fields works. In particular, make sure that all instances | |
940 | * of GregorianCalendar don't share a static instance of the fields array. | |
941 | */ | |
942 | void | |
943 | CalendarTest::TestFieldSet4781() | |
944 | { | |
945 | // try { | |
946 | UErrorCode status = U_ZERO_ERROR; | |
947 | GregorianCalendar *g = new GregorianCalendar(status); | |
948 | if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; } | |
949 | GregorianCalendar *g2 = new GregorianCalendar(status); | |
950 | if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; } | |
951 | g2->set(UCAL_HOUR, 12, status); | |
952 | g2->set(UCAL_MINUTE, 0, status); | |
953 | g2->set(UCAL_SECOND, 0, status); | |
954 | if (U_FAILURE(status)) { errln("Calendar::set failed"); return; } | |
955 | if (*g == *g2) logln("Same"); | |
956 | else logln("Different"); | |
957 | //} | |
958 | //catch(IllegalArgumentException e) { | |
959 | //errln("Unexpected exception seen: " + e); | |
960 | //} | |
961 | delete g; | |
962 | delete g2; | |
963 | } | |
964 | ||
965 | // ------------------------------------- | |
966 | ||
967 | /* We don't support serialization on C++ | |
968 | void | |
969 | CalendarTest::TestSerialize337() | |
970 | { | |
971 | Calendar cal = Calendar::getInstance(); | |
972 | UBool ok = FALSE; | |
973 | try { | |
974 | FileOutputStream f = new FileOutputStream(FILENAME); | |
975 | ObjectOutput s = new ObjectOutputStream(f); | |
976 | s.writeObject(PREFIX); | |
977 | s.writeObject(cal); | |
978 | s.writeObject(POSTFIX); | |
979 | f.close(); | |
980 | FileInputStream in = new FileInputStream(FILENAME); | |
981 | ObjectInputStream t = new ObjectInputStream(in); | |
982 | UnicodeString& pre = (UnicodeString&) t.readObject(); | |
983 | Calendar c = (Calendar) t.readObject(); | |
984 | UnicodeString& post = (UnicodeString&) t.readObject(); | |
985 | in.close(); | |
986 | ok = pre.equals(PREFIX) && | |
987 | post.equals(POSTFIX) && | |
988 | cal->equals(c); | |
989 | File fl = new File(FILENAME); | |
990 | fl.delete(); | |
991 | } | |
992 | catch(IOException e) { | |
993 | errln("FAIL: Exception received:"); | |
994 | e.printStackTrace(log); | |
995 | } | |
996 | catch(ClassNotFoundException e) { | |
997 | errln("FAIL: Exception received:"); | |
998 | e.printStackTrace(log); | |
999 | } | |
1000 | if (!ok) errln("Serialization of Calendar object failed."); | |
1001 | } | |
1002 | ||
1003 | UnicodeString& CalendarTest::PREFIX = "abc"; | |
1004 | ||
1005 | UnicodeString& CalendarTest::POSTFIX = "def"; | |
1006 | ||
1007 | UnicodeString& CalendarTest::FILENAME = "tmp337.bin"; | |
1008 | */ | |
1009 | ||
1010 | // ------------------------------------- | |
1011 | ||
1012 | /** | |
1013 | * Verify that the seconds of a Calendar can be zeroed out through the | |
1014 | * expected sequence of operations. | |
1015 | */ | |
1016 | void | |
1017 | CalendarTest::TestSecondsZero121() | |
1018 | { | |
1019 | UErrorCode status = U_ZERO_ERROR; | |
1020 | Calendar *cal = new GregorianCalendar(status); | |
1021 | if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; } | |
1022 | cal->setTime(Calendar::getNow(), status); | |
1023 | if (U_FAILURE(status)) { errln("Calendar::setTime failed"); return; } | |
1024 | cal->set(UCAL_SECOND, 0); | |
1025 | if (U_FAILURE(status)) { errln("Calendar::set failed"); return; } | |
1026 | UDate d = cal->getTime(status); | |
1027 | if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; } | |
1028 | UnicodeString s; | |
1029 | dateToString(d, s); | |
1030 | if (s.indexOf(":00 ") < 0) errln("Expected to see :00 in " + s); | |
1031 | delete cal; | |
1032 | } | |
1033 | ||
1034 | // ------------------------------------- | |
1035 | ||
1036 | /** | |
1037 | * Verify that a specific sequence of adding and setting works as expected; | |
1038 | * it should not vary depending on when and whether the get method is | |
1039 | * called. | |
1040 | */ | |
1041 | void | |
1042 | CalendarTest::TestAddSetGet0610() | |
1043 | { | |
1044 | UnicodeString EXPECTED_0610("1993/0/5", ""); | |
1045 | UErrorCode status = U_ZERO_ERROR; | |
1046 | { | |
1047 | Calendar *calendar = new GregorianCalendar(status); | |
1048 | if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; } | |
1049 | calendar->set(1993, UCAL_JANUARY, 4); | |
1050 | logln("1A) " + value(calendar)); | |
1051 | calendar->add(UCAL_DATE, 1, status); | |
1052 | if (U_FAILURE(status)) { errln("Calendar::add failed"); return; } | |
1053 | UnicodeString v = value(calendar); | |
1054 | logln("1B) " + v); | |
1055 | logln("--) 1993/0/5"); | |
1056 | if (!(v == EXPECTED_0610)) errln("Expected " + EXPECTED_0610 + "; saw " + v); | |
1057 | delete calendar; | |
1058 | } | |
1059 | { | |
1060 | Calendar *calendar = new GregorianCalendar(1993, UCAL_JANUARY, 4, status); | |
1061 | if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; } | |
1062 | logln("2A) " + value(calendar)); | |
1063 | calendar->add(UCAL_DATE, 1, status); | |
1064 | if (U_FAILURE(status)) { errln("Calendar::add failed"); return; } | |
1065 | UnicodeString v = value(calendar); | |
1066 | logln("2B) " + v); | |
1067 | logln("--) 1993/0/5"); | |
1068 | if (!(v == EXPECTED_0610)) errln("Expected " + EXPECTED_0610 + "; saw " + v); | |
1069 | delete calendar; | |
1070 | } | |
1071 | { | |
1072 | Calendar *calendar = new GregorianCalendar(1993, UCAL_JANUARY, 4, status); | |
1073 | if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; } | |
1074 | logln("3A) " + value(calendar)); | |
1075 | calendar->getTime(status); | |
1076 | if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; } | |
1077 | calendar->add(UCAL_DATE, 1, status); | |
1078 | if (U_FAILURE(status)) { errln("Calendar::add failed"); return; } | |
1079 | UnicodeString v = value(calendar); | |
1080 | logln("3B) " + v); | |
1081 | logln("--) 1993/0/5"); | |
1082 | if (!(v == EXPECTED_0610)) errln("Expected " + EXPECTED_0610 + "; saw " + v); | |
1083 | delete calendar; | |
1084 | } | |
1085 | } | |
1086 | ||
1087 | // ------------------------------------- | |
1088 | ||
1089 | UnicodeString | |
1090 | CalendarTest::value(Calendar* calendar) | |
1091 | { | |
1092 | UErrorCode status = U_ZERO_ERROR; | |
1093 | return UnicodeString("") + (int32_t)calendar->get(UCAL_YEAR, status) + | |
1094 | "/" + (int32_t)calendar->get(UCAL_MONTH, status) + | |
1095 | "/" + (int32_t)calendar->get(UCAL_DATE, status) + | |
1096 | (U_FAILURE(status) ? " FAIL: Calendar::get failed" : ""); | |
1097 | } | |
1098 | ||
1099 | ||
1100 | // ------------------------------------- | |
1101 | ||
1102 | /** | |
1103 | * Verify that various fields on a known date are set correctly. | |
1104 | */ | |
1105 | void | |
1106 | CalendarTest::TestFields060() | |
1107 | { | |
1108 | UErrorCode status = U_ZERO_ERROR; | |
1109 | int32_t year = 1997; | |
1110 | int32_t month = UCAL_OCTOBER; | |
1111 | int32_t dDate = 22; | |
1112 | GregorianCalendar *calendar = 0; | |
1113 | calendar = new GregorianCalendar(year, month, dDate, status); | |
1114 | if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; } | |
1115 | for (int32_t i = 0; i < EXPECTED_FIELDS_length;) { | |
1116 | UCalendarDateFields field = (UCalendarDateFields)EXPECTED_FIELDS[i++]; | |
1117 | int32_t expected = EXPECTED_FIELDS[i++]; | |
1118 | if (calendar->get(field, status) != expected) { | |
1119 | errln(UnicodeString("Expected field ") + (int32_t)field + " to have value " + (int32_t)expected + | |
1120 | "; received " + (int32_t)calendar->get(field, status) + " instead"); | |
1121 | if (U_FAILURE(status)) { errln("Calendar::get failed"); return; } | |
1122 | } | |
1123 | } | |
1124 | delete calendar; | |
1125 | } | |
1126 | ||
1127 | int32_t CalendarTest::EXPECTED_FIELDS[] = { | |
1128 | UCAL_YEAR, 1997, | |
1129 | UCAL_MONTH, UCAL_OCTOBER, | |
1130 | UCAL_DATE, 22, | |
1131 | UCAL_DAY_OF_WEEK, UCAL_WEDNESDAY, | |
1132 | UCAL_DAY_OF_WEEK_IN_MONTH, 4, | |
1133 | UCAL_DAY_OF_YEAR, 295 | |
1134 | }; | |
1135 | ||
1136 | const int32_t CalendarTest::EXPECTED_FIELDS_length = (int32_t)(sizeof(CalendarTest::EXPECTED_FIELDS) / | |
1137 | sizeof(CalendarTest::EXPECTED_FIELDS[0])); | |
1138 | ||
1139 | // ------------------------------------- | |
1140 | ||
1141 | /** | |
1142 | * Verify that various fields on a known date are set correctly. In this | |
1143 | * case, the start of the epoch (January 1 1970). | |
1144 | */ | |
1145 | void | |
1146 | CalendarTest::TestEpochStartFields() | |
1147 | { | |
1148 | UErrorCode status = U_ZERO_ERROR; | |
1149 | TimeZone *z = TimeZone::createDefault(); | |
1150 | Calendar *c = Calendar::createInstance(status); | |
1151 | if (U_FAILURE(status)) { errln("Calendar::createInstance failed"); return; } | |
1152 | UDate d = - z->getRawOffset(); | |
1153 | GregorianCalendar *gc = new GregorianCalendar(status); | |
1154 | if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; } | |
1155 | gc->setTimeZone(*z); | |
1156 | gc->setTime(d, status); | |
1157 | if (U_FAILURE(status)) { errln("Calendar::setTime failed"); return; } | |
1158 | UBool idt = gc->inDaylightTime(status); | |
1159 | if (U_FAILURE(status)) { errln("GregorianCalendar::inDaylightTime failed"); return; } | |
1160 | if (idt) { | |
1161 | UnicodeString str; | |
1162 | logln("Warning: Skipping test because " + dateToString(d, str) + " is in DST."); | |
1163 | } | |
1164 | else { | |
1165 | c->setTime(d, status); | |
1166 | if (U_FAILURE(status)) { errln("Calendar::setTime failed"); return; } | |
1167 | for (int32_t i = 0; i < UCAL_ZONE_OFFSET;++i) { | |
1168 | if (c->get((UCalendarDateFields)i, status) != EPOCH_FIELDS[i]) | |
1169 | errln(UnicodeString("Expected field ") + i + " to have value " + EPOCH_FIELDS[i] + | |
1170 | "; saw " + c->get((UCalendarDateFields)i, status) + " instead"); | |
1171 | if (U_FAILURE(status)) { errln("Calendar::get failed"); return; } | |
1172 | } | |
1173 | if (c->get(UCAL_ZONE_OFFSET, status) != z->getRawOffset()) | |
1174 | { | |
1175 | errln(UnicodeString("Expected field ZONE_OFFSET to have value ") + z->getRawOffset() + | |
1176 | "; saw " + c->get(UCAL_ZONE_OFFSET, status) + " instead"); | |
1177 | if (U_FAILURE(status)) { errln("Calendar::get failed"); return; } | |
1178 | } | |
1179 | if (c->get(UCAL_DST_OFFSET, status) != 0) | |
1180 | { | |
1181 | errln(UnicodeString("Expected field DST_OFFSET to have value 0") + | |
1182 | "; saw " + c->get(UCAL_DST_OFFSET, status) + " instead"); | |
1183 | if (U_FAILURE(status)) { errln("Calendar::get failed"); return; } | |
1184 | } | |
1185 | } | |
1186 | delete c; | |
1187 | delete z; | |
1188 | delete gc; | |
1189 | } | |
1190 | ||
1191 | int32_t CalendarTest::EPOCH_FIELDS[] = { | |
1192 | 1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, - 28800000, 0 | |
1193 | }; | |
1194 | ||
1195 | // ------------------------------------- | |
1196 | ||
1197 | /** | |
1198 | * Test that the days of the week progress properly when add is called repeatedly | |
1199 | * for increments of 24 days. | |
1200 | */ | |
1201 | void | |
1202 | CalendarTest::TestDOWProgression() | |
1203 | { | |
1204 | UErrorCode status = U_ZERO_ERROR; | |
1205 | Calendar *cal = new GregorianCalendar(1972, UCAL_OCTOBER, 26, status); | |
1206 | if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; } | |
1207 | marchByDelta(cal, 24); | |
1208 | delete cal; | |
1209 | } | |
1210 | ||
1211 | // ------------------------------------- | |
1212 | ||
1213 | void | |
1214 | CalendarTest::TestDOW_LOCALandYEAR_WOY() | |
1215 | { | |
1216 | /* Note: I've commented out the loop_addroll tests for YEAR and | |
1217 | * YEAR_WOY below because these two fields should NOT behave | |
1218 | * identically when adding. YEAR should keep the month/dom | |
1219 | * invariant. YEAR_WOY should keep the woy/dow invariant. I've | |
1220 | * added a new test that checks for this in place of the old call | |
1221 | * to loop_addroll. - aliu */ | |
1222 | UErrorCode status = U_ZERO_ERROR; | |
1223 | int32_t times = 20; | |
1224 | Calendar *cal=Calendar::createInstance(Locale::getGermany(), status); | |
1225 | if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; } | |
1226 | SimpleDateFormat *sdf=new SimpleDateFormat(UnicodeString("YYYY'-W'ww-ee"), Locale::getGermany(), status); | |
1227 | if (U_FAILURE(status)) { errln("Couldn't create SimpleDateFormat"); return; } | |
1228 | sdf->applyLocalizedPattern(UnicodeString("JJJJ'-W'ww-ee"), status); | |
1229 | if (U_FAILURE(status)) { errln("Couldn't apply localized pattern"); return; } | |
1230 | cal->clear(); | |
1231 | cal->set(1997, UCAL_DECEMBER, 25); | |
1232 | doYEAR_WOYLoop(cal, sdf, times, status); | |
1233 | //loop_addroll(cal, /*sdf,*/ times, UCAL_YEAR_WOY, UCAL_YEAR, status); | |
1234 | yearAddTest(*cal, status); // aliu | |
1235 | loop_addroll(cal, /*sdf,*/ times, UCAL_DOW_LOCAL, UCAL_DAY_OF_WEEK, status); | |
1236 | if (U_FAILURE(status)) { errln("Error in parse/calculate test for 1997"); return; } | |
1237 | cal->clear(); | |
1238 | cal->set(1998, UCAL_DECEMBER, 25); | |
1239 | doYEAR_WOYLoop(cal, sdf, times, status); | |
1240 | //loop_addroll(cal, /*sdf,*/ times, UCAL_YEAR_WOY, UCAL_YEAR, status); | |
1241 | yearAddTest(*cal, status); // aliu | |
1242 | loop_addroll(cal, /*sdf,*/ times, UCAL_DOW_LOCAL, UCAL_DAY_OF_WEEK, status); | |
1243 | if (U_FAILURE(status)) { errln("Error in parse/calculate test for 1998"); return; } | |
1244 | cal->clear(); | |
1245 | cal->set(1582, UCAL_OCTOBER, 1); | |
1246 | doYEAR_WOYLoop(cal, sdf, times, status); | |
1247 | //loop_addroll(cal, /*sdf,*/ times, Calendar::YEAR_WOY, Calendar::YEAR, status); | |
1248 | yearAddTest(*cal, status); // aliu | |
1249 | loop_addroll(cal, /*sdf,*/ times, UCAL_DOW_LOCAL, UCAL_DAY_OF_WEEK, status); | |
1250 | if (U_FAILURE(status)) { errln("Error in parse/calculate test for 1582"); return; } | |
1251 | ||
1252 | delete sdf; | |
1253 | delete cal; | |
1254 | ||
1255 | return; | |
1256 | } | |
1257 | ||
1258 | /** | |
1259 | * Confirm that adding a YEAR and adding a YEAR_WOY work properly for | |
1260 | * the given Calendar at its current setting. | |
1261 | */ | |
1262 | void CalendarTest::yearAddTest(Calendar& cal, UErrorCode& status) { | |
1263 | /** | |
1264 | * When adding the YEAR, the month and day should remain constant. | |
1265 | * When adding the YEAR_WOY, the WOY and DOW should remain constant. - aliu | |
1266 | * Examples: | |
1267 | * Wed Jan 14 1998 / 1998-W03-03 Add(YEAR_WOY, 1) -> Wed Jan 20 1999 / 1999-W03-03 | |
1268 | * Add(YEAR, 1) -> Thu Jan 14 1999 / 1999-W02-04 | |
1269 | * Thu Jan 14 1999 / 1999-W02-04 Add(YEAR_WOY, 1) -> Thu Jan 13 2000 / 2000-W02-04 | |
1270 | * Add(YEAR, 1) -> Fri Jan 14 2000 / 2000-W02-05 | |
1271 | * Sun Oct 31 1582 / 1582-W42-07 Add(YEAR_WOY, 1) -> Sun Oct 23 1583 / 1583-W42-07 | |
1272 | * Add(YEAR, 1) -> Mon Oct 31 1583 / 1583-W44-01 | |
1273 | */ | |
1274 | int32_t y = cal.get(UCAL_YEAR, status); | |
1275 | int32_t mon = cal.get(UCAL_MONTH, status); | |
1276 | int32_t day = cal.get(UCAL_DATE, status); | |
1277 | int32_t ywy = cal.get(UCAL_YEAR_WOY, status); | |
1278 | int32_t woy = cal.get(UCAL_WEEK_OF_YEAR, status); | |
1279 | int32_t dow = cal.get(UCAL_DOW_LOCAL, status); | |
1280 | UDate t = cal.getTime(status); | |
1281 | ||
1282 | UnicodeString str, str2; | |
1283 | SimpleDateFormat fmt(UnicodeString("EEE MMM dd yyyy / YYYY'-W'ww-ee"), status); | |
1284 | fmt.setCalendar(cal); | |
1285 | ||
1286 | fmt.format(t, str.remove()); | |
1287 | str += ".add(YEAR, 1) =>"; | |
1288 | cal.add(UCAL_YEAR, 1, status); | |
1289 | int32_t y2 = cal.get(UCAL_YEAR, status); | |
1290 | int32_t mon2 = cal.get(UCAL_MONTH, status); | |
1291 | int32_t day2 = cal.get(UCAL_DATE, status); | |
1292 | fmt.format(cal.getTime(status), str); | |
1293 | if (y2 != (y+1) || mon2 != mon || day2 != day) { | |
1294 | str += (UnicodeString)", expected year " + | |
1295 | (y+1) + ", month " + (mon+1) + ", day " + day; | |
1296 | errln((UnicodeString)"FAIL: " + str); | |
1297 | } else { | |
1298 | logln(str); | |
1299 | } | |
1300 | ||
1301 | fmt.format(t, str.remove()); | |
1302 | str += ".add(YEAR_WOY, 1)=>"; | |
1303 | cal.setTime(t, status); | |
1304 | cal.add(UCAL_YEAR_WOY, 1, status); | |
1305 | int32_t ywy2 = cal.get(UCAL_YEAR_WOY, status); | |
1306 | int32_t woy2 = cal.get(UCAL_WEEK_OF_YEAR, status); | |
1307 | int32_t dow2 = cal.get(UCAL_DOW_LOCAL, status); | |
1308 | fmt.format(cal.getTime(status), str); | |
1309 | if (ywy2 != (ywy+1) || woy2 != woy || dow2 != dow) { | |
1310 | str += (UnicodeString)", expected yearWOY " + | |
1311 | (ywy+1) + ", woy " + woy + ", dowLocal " + dow; | |
1312 | errln((UnicodeString)"FAIL: " + str); | |
1313 | } else { | |
1314 | logln(str); | |
1315 | } | |
1316 | } | |
1317 | ||
1318 | // ------------------------------------- | |
1319 | ||
1320 | void CalendarTest::loop_addroll(Calendar *cal, /*SimpleDateFormat *sdf,*/ int times, UCalendarDateFields field, UCalendarDateFields field2, UErrorCode& errorCode) { | |
1321 | Calendar *calclone; | |
1322 | SimpleDateFormat fmt(UnicodeString("EEE MMM dd yyyy / YYYY'-W'ww-ee"), errorCode); | |
1323 | fmt.setCalendar(*cal); | |
1324 | int i; | |
1325 | ||
1326 | for(i = 0; i<times; i++) { | |
1327 | calclone = cal->clone(); | |
1328 | UDate start = cal->getTime(errorCode); | |
1329 | cal->add(field,1,errorCode); | |
1330 | if (U_FAILURE(errorCode)) { errln("Error in add"); delete calclone; return; } | |
1331 | calclone->add(field2,1,errorCode); | |
1332 | if (U_FAILURE(errorCode)) { errln("Error in add"); delete calclone; return; } | |
1333 | if(cal->getTime(errorCode) != calclone->getTime(errorCode)) { | |
1334 | UnicodeString str("FAIL: Results of add differ. "), str2; | |
1335 | str += fmt.format(start, str2) + " "; | |
1336 | str += UnicodeString("Add(") + fieldName(field) + ", 1) -> " + | |
1337 | fmt.format(cal->getTime(errorCode), str2.remove()) + "; "; | |
1338 | str += UnicodeString("Add(") + fieldName(field2) + ", 1) -> " + | |
1339 | fmt.format(calclone->getTime(errorCode), str2.remove()); | |
1340 | errln(str); | |
1341 | delete calclone; | |
1342 | return; | |
1343 | } | |
1344 | delete calclone; | |
1345 | } | |
1346 | ||
1347 | for(i = 0; i<times; i++) { | |
1348 | calclone = cal->clone(); | |
1349 | cal->roll(field,(int32_t)1,errorCode); | |
1350 | if (U_FAILURE(errorCode)) { errln("Error in roll"); delete calclone; return; } | |
1351 | calclone->roll(field2,(int32_t)1,errorCode); | |
1352 | if (U_FAILURE(errorCode)) { errln("Error in roll"); delete calclone; return; } | |
1353 | if(cal->getTime(errorCode) != calclone->getTime(errorCode)) { | |
1354 | delete calclone; | |
1355 | errln("Results of roll differ!"); | |
1356 | return; | |
1357 | } | |
1358 | delete calclone; | |
1359 | } | |
1360 | } | |
1361 | ||
1362 | // ------------------------------------- | |
1363 | ||
1364 | void | |
1365 | CalendarTest::doYEAR_WOYLoop(Calendar *cal, SimpleDateFormat *sdf, | |
1366 | int32_t times, UErrorCode& errorCode) { | |
1367 | ||
1368 | UnicodeString us; | |
1369 | UDate tst, original; | |
1370 | Calendar *tstres = new GregorianCalendar(Locale::getGermany(), errorCode); | |
1371 | for(int i=0; i<times; ++i) { | |
1372 | sdf->format(Formattable(cal->getTime(errorCode),Formattable::kIsDate), us, errorCode); | |
1373 | //logln("expected: "+us); | |
1374 | if (U_FAILURE(errorCode)) { errln("Format error"); return; } | |
1375 | tst=sdf->parse(us,errorCode); | |
1376 | if (U_FAILURE(errorCode)) { errln("Parse error"); return; } | |
1377 | tstres->clear(); | |
1378 | tstres->setTime(tst, errorCode); | |
1379 | //logln((UnicodeString)"Parsed week of year is "+tstres->get(UCAL_WEEK_OF_YEAR, errorCode)); | |
1380 | if (U_FAILURE(errorCode)) { errln("Set time error"); return; } | |
1381 | original = cal->getTime(errorCode); | |
1382 | us.remove(); | |
1383 | sdf->format(Formattable(tst,Formattable::kIsDate), us, errorCode); | |
1384 | //logln("got: "+us); | |
1385 | if (U_FAILURE(errorCode)) { errln("Get time error"); return; } | |
1386 | if(original!=tst) { | |
1387 | us.remove(); | |
1388 | sdf->format(Formattable(original, Formattable::kIsDate), us, errorCode); | |
1389 | errln("Parsed time doesn't match with regular"); | |
1390 | logln("expected "+us); | |
1391 | us.remove(); | |
1392 | sdf->format(Formattable(tst, Formattable::kIsDate), us, errorCode); | |
1393 | logln("got "+us); | |
1394 | } | |
1395 | tstres->clear(); | |
1396 | tstres->set(UCAL_YEAR_WOY, cal->get(UCAL_YEAR_WOY, errorCode)); | |
1397 | tstres->set(UCAL_WEEK_OF_YEAR, cal->get(UCAL_WEEK_OF_YEAR, errorCode)); | |
1398 | tstres->set(UCAL_DOW_LOCAL, cal->get(UCAL_DOW_LOCAL, errorCode)); | |
1399 | if(cal->get(UCAL_YEAR, errorCode) != tstres->get(UCAL_YEAR, errorCode)) { | |
1400 | errln("Different Year!"); | |
1401 | logln((UnicodeString)"Expected "+cal->get(UCAL_YEAR, errorCode)); | |
1402 | logln((UnicodeString)"Got "+tstres->get(UCAL_YEAR, errorCode)); | |
1403 | return; | |
1404 | } | |
1405 | if(cal->get(UCAL_DAY_OF_YEAR, errorCode) != tstres->get(UCAL_DAY_OF_YEAR, errorCode)) { | |
1406 | errln("Different Day Of Year!"); | |
1407 | logln((UnicodeString)"Expected "+cal->get(UCAL_DAY_OF_YEAR, errorCode)); | |
1408 | logln((UnicodeString)"Got "+tstres->get(UCAL_DAY_OF_YEAR, errorCode)); | |
1409 | return; | |
1410 | } | |
1411 | cal->add(UCAL_DATE, 1, errorCode); | |
1412 | if (U_FAILURE(errorCode)) { errln("Add error"); return; } | |
1413 | us.remove(); | |
1414 | } | |
1415 | delete (tstres); | |
1416 | } | |
1417 | // ------------------------------------- | |
1418 | ||
1419 | void | |
1420 | CalendarTest::marchByDelta(Calendar* cal, int32_t delta) | |
1421 | { | |
1422 | UErrorCode status = U_ZERO_ERROR; | |
1423 | Calendar *cur = (Calendar*) cal->clone(); | |
1424 | int32_t initialDOW = cur->get(UCAL_DAY_OF_WEEK, status); | |
1425 | if (U_FAILURE(status)) { errln("Calendar::get failed"); return; } | |
1426 | int32_t DOW, newDOW = initialDOW; | |
1427 | do { | |
1428 | UnicodeString str; | |
1429 | DOW = newDOW; | |
1430 | logln(UnicodeString("DOW = ") + DOW + " " + dateToString(cur->getTime(status), str)); | |
1431 | if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; } | |
1432 | cur->add(UCAL_DAY_OF_WEEK, delta, status); | |
1433 | if (U_FAILURE(status)) { errln("Calendar::add failed"); return; } | |
1434 | newDOW = cur->get(UCAL_DAY_OF_WEEK, status); | |
1435 | if (U_FAILURE(status)) { errln("Calendar::get failed"); return; } | |
1436 | int32_t expectedDOW = 1 + (DOW + delta - 1) % 7; | |
1437 | if (newDOW != expectedDOW) { | |
1438 | errln(UnicodeString("Day of week should be ") + expectedDOW + " instead of " + newDOW + | |
1439 | " on " + dateToString(cur->getTime(status), str)); | |
1440 | if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; } | |
1441 | return; | |
1442 | } | |
1443 | } | |
1444 | while (newDOW != initialDOW); | |
1445 | delete cur; | |
1446 | } | |
1447 | ||
1448 | #define CHECK(status, msg) \ | |
1449 | if (U_FAILURE(status)) { \ | |
1450 | errln(msg); \ | |
1451 | return; \ | |
1452 | } | |
1453 | ||
1454 | void CalendarTest::TestWOY(void) { | |
1455 | /* | |
1456 | FDW = Mon, MDFW = 4: | |
1457 | Sun Dec 26 1999, WOY 51 | |
1458 | Mon Dec 27 1999, WOY 52 | |
1459 | Tue Dec 28 1999, WOY 52 | |
1460 | Wed Dec 29 1999, WOY 52 | |
1461 | Thu Dec 30 1999, WOY 52 | |
1462 | Fri Dec 31 1999, WOY 52 | |
1463 | Sat Jan 01 2000, WOY 52 *** | |
1464 | Sun Jan 02 2000, WOY 52 *** | |
1465 | Mon Jan 03 2000, WOY 1 | |
1466 | Tue Jan 04 2000, WOY 1 | |
1467 | Wed Jan 05 2000, WOY 1 | |
1468 | Thu Jan 06 2000, WOY 1 | |
1469 | Fri Jan 07 2000, WOY 1 | |
1470 | Sat Jan 08 2000, WOY 1 | |
1471 | Sun Jan 09 2000, WOY 1 | |
1472 | Mon Jan 10 2000, WOY 2 | |
1473 | ||
1474 | FDW = Mon, MDFW = 2: | |
1475 | Sun Dec 26 1999, WOY 52 | |
1476 | Mon Dec 27 1999, WOY 1 *** | |
1477 | Tue Dec 28 1999, WOY 1 *** | |
1478 | Wed Dec 29 1999, WOY 1 *** | |
1479 | Thu Dec 30 1999, WOY 1 *** | |
1480 | Fri Dec 31 1999, WOY 1 *** | |
1481 | Sat Jan 01 2000, WOY 1 | |
1482 | Sun Jan 02 2000, WOY 1 | |
1483 | Mon Jan 03 2000, WOY 2 | |
1484 | Tue Jan 04 2000, WOY 2 | |
1485 | Wed Jan 05 2000, WOY 2 | |
1486 | Thu Jan 06 2000, WOY 2 | |
1487 | Fri Jan 07 2000, WOY 2 | |
1488 | Sat Jan 08 2000, WOY 2 | |
1489 | Sun Jan 09 2000, WOY 2 | |
1490 | Mon Jan 10 2000, WOY 3 | |
1491 | */ | |
1492 | ||
1493 | UnicodeString str; | |
1494 | UErrorCode status = U_ZERO_ERROR; | |
1495 | int32_t i; | |
1496 | ||
1497 | GregorianCalendar cal(status); | |
1498 | SimpleDateFormat fmt(UnicodeString("EEE MMM dd yyyy', WOY' w"), status); | |
1499 | CHECK(status, "Fail: Cannot construct calendar/format"); | |
1500 | ||
1501 | UCalendarDaysOfWeek fdw = (UCalendarDaysOfWeek) 0; | |
1502 | ||
1503 | for (int8_t pass=1; pass<=2; ++pass) { | |
1504 | switch (pass) { | |
1505 | case 1: | |
1506 | fdw = UCAL_MONDAY; | |
1507 | cal.setFirstDayOfWeek(fdw); | |
1508 | cal.setMinimalDaysInFirstWeek(4); | |
1509 | fmt.setCalendar(cal); | |
1510 | break; | |
1511 | case 2: | |
1512 | fdw = UCAL_MONDAY; | |
1513 | cal.setFirstDayOfWeek(fdw); | |
1514 | cal.setMinimalDaysInFirstWeek(2); | |
1515 | fmt.setCalendar(cal); | |
1516 | break; | |
1517 | } | |
1518 | ||
1519 | for (i=0; i<16; ++i) { | |
1520 | UDate t, t2; | |
1521 | int32_t t_y, t_woy, t_dow; | |
1522 | cal.clear(); | |
1523 | cal.set(1999, UCAL_DECEMBER, 26 + i); | |
1524 | fmt.format(t = cal.getTime(status), str.remove()); | |
1525 | CHECK(status, "Fail: getTime failed"); | |
1526 | logln(str); | |
1527 | ||
1528 | int32_t dow = cal.get(UCAL_DAY_OF_WEEK, status); | |
1529 | int32_t woy = cal.get(UCAL_WEEK_OF_YEAR, status); | |
1530 | int32_t year = cal.get(UCAL_YEAR, status); | |
1531 | int32_t mon = cal.get(UCAL_MONTH, status); | |
1532 | CHECK(status, "Fail: get failed"); | |
1533 | int32_t dowLocal = dow - fdw; | |
1534 | if (dowLocal < 0) dowLocal += 7; | |
1535 | dowLocal++; | |
1536 | int32_t yearWoy = year; | |
1537 | if (mon == UCAL_JANUARY) { | |
1538 | if (woy >= 52) --yearWoy; | |
1539 | } else { | |
1540 | if (woy == 1) ++yearWoy; | |
1541 | } | |
1542 | ||
1543 | // Basic fields->time check y/woy/dow | |
1544 | // Since Y/WOY is ambiguous, we do a check of the fields, | |
1545 | // not of the specific time. | |
1546 | cal.clear(); | |
1547 | cal.set(UCAL_YEAR, year); | |
1548 | cal.set(UCAL_WEEK_OF_YEAR, woy); | |
1549 | cal.set(UCAL_DAY_OF_WEEK, dow); | |
1550 | t_y = cal.get(UCAL_YEAR, status); | |
1551 | t_woy = cal.get(UCAL_WEEK_OF_YEAR, status); | |
1552 | t_dow = cal.get(UCAL_DAY_OF_WEEK, status); | |
1553 | CHECK(status, "Fail: get failed"); | |
1554 | if (t_y != year || t_woy != woy || t_dow != dow) { | |
1555 | str = "Fail: y/woy/dow fields->time => "; | |
1556 | fmt.format(cal.getTime(status), str); | |
1557 | errln(str); | |
1558 | } | |
1559 | ||
1560 | // Basic fields->time check y/woy/dow_local | |
1561 | // Since Y/WOY is ambiguous, we do a check of the fields, | |
1562 | // not of the specific time. | |
1563 | cal.clear(); | |
1564 | cal.set(UCAL_YEAR, year); | |
1565 | cal.set(UCAL_WEEK_OF_YEAR, woy); | |
1566 | cal.set(UCAL_DOW_LOCAL, dowLocal); | |
1567 | t_y = cal.get(UCAL_YEAR, status); | |
1568 | t_woy = cal.get(UCAL_WEEK_OF_YEAR, status); | |
1569 | t_dow = cal.get(UCAL_DOW_LOCAL, status); | |
1570 | CHECK(status, "Fail: get failed"); | |
1571 | if (t_y != year || t_woy != woy || t_dow != dowLocal) { | |
1572 | str = "Fail: y/woy/dow_local fields->time => "; | |
1573 | fmt.format(cal.getTime(status), str); | |
1574 | errln(str); | |
1575 | } | |
1576 | ||
1577 | // Basic fields->time check y_woy/woy/dow | |
1578 | cal.clear(); | |
1579 | cal.set(UCAL_YEAR_WOY, yearWoy); | |
1580 | cal.set(UCAL_WEEK_OF_YEAR, woy); | |
1581 | cal.set(UCAL_DAY_OF_WEEK, dow); | |
1582 | t2 = cal.getTime(status); | |
1583 | CHECK(status, "Fail: getTime failed"); | |
1584 | if (t != t2) { | |
1585 | str = "Fail: y_woy/woy/dow fields->time => "; | |
1586 | fmt.format(t2, str); | |
1587 | errln(str); | |
1588 | } | |
1589 | ||
1590 | // Basic fields->time check y_woy/woy/dow_local | |
1591 | cal.clear(); | |
1592 | cal.set(UCAL_YEAR_WOY, yearWoy); | |
1593 | cal.set(UCAL_WEEK_OF_YEAR, woy); | |
1594 | cal.set(UCAL_DOW_LOCAL, dowLocal); | |
1595 | t2 = cal.getTime(status); | |
1596 | CHECK(status, "Fail: getTime failed"); | |
1597 | if (t != t2) { | |
1598 | str = "Fail: y_woy/woy/dow_local fields->time => "; | |
1599 | fmt.format(t2, str); | |
1600 | errln(str); | |
1601 | } | |
1602 | ||
1603 | // Make sure DOW_LOCAL disambiguates over DOW | |
1604 | int32_t wrongDow = dow - 3; | |
1605 | if (wrongDow < 1) wrongDow += 7; | |
1606 | cal.setTime(t, status); | |
1607 | cal.set(UCAL_DAY_OF_WEEK, wrongDow); | |
1608 | cal.set(UCAL_DOW_LOCAL, dowLocal); | |
1609 | t2 = cal.getTime(status); | |
1610 | CHECK(status, "Fail: set/getTime failed"); | |
1611 | if (t != t2) { | |
1612 | str = "Fail: DOW_LOCAL fields->time => "; | |
1613 | fmt.format(t2, str); | |
1614 | errln(str); | |
1615 | } | |
1616 | ||
1617 | // Make sure DOW disambiguates over DOW_LOCAL | |
1618 | int32_t wrongDowLocal = dowLocal - 3; | |
1619 | if (wrongDowLocal < 1) wrongDowLocal += 7; | |
1620 | cal.setTime(t, status); | |
1621 | cal.set(UCAL_DOW_LOCAL, wrongDowLocal); | |
1622 | cal.set(UCAL_DAY_OF_WEEK, dow); | |
1623 | t2 = cal.getTime(status); | |
1624 | CHECK(status, "Fail: set/getTime failed"); | |
1625 | if (t != t2) { | |
1626 | str = "Fail: DOW fields->time => "; | |
1627 | fmt.format(t2, str); | |
1628 | errln(str); | |
1629 | } | |
1630 | ||
1631 | // Make sure YEAR_WOY disambiguates over YEAR | |
1632 | cal.setTime(t, status); | |
1633 | cal.set(UCAL_YEAR, year - 2); | |
1634 | cal.set(UCAL_YEAR_WOY, yearWoy); | |
1635 | t2 = cal.getTime(status); | |
1636 | CHECK(status, "Fail: set/getTime failed"); | |
1637 | if (t != t2) { | |
1638 | str = "Fail: YEAR_WOY fields->time => "; | |
1639 | fmt.format(t2, str); | |
1640 | errln(str); | |
1641 | } | |
1642 | ||
1643 | // Make sure YEAR disambiguates over YEAR_WOY | |
1644 | cal.setTime(t, status); | |
1645 | cal.set(UCAL_YEAR_WOY, yearWoy - 2); | |
1646 | cal.set(UCAL_YEAR, year); | |
1647 | t2 = cal.getTime(status); | |
1648 | CHECK(status, "Fail: set/getTime failed"); | |
1649 | if (t != t2) { | |
1650 | str = "Fail: YEAR fields->time => "; | |
1651 | fmt.format(t2, str); | |
1652 | errln(str); | |
1653 | } | |
1654 | } | |
1655 | } | |
1656 | ||
1657 | /* | |
1658 | FDW = Mon, MDFW = 4: | |
1659 | Sun Dec 26 1999, WOY 51 | |
1660 | Mon Dec 27 1999, WOY 52 | |
1661 | Tue Dec 28 1999, WOY 52 | |
1662 | Wed Dec 29 1999, WOY 52 | |
1663 | Thu Dec 30 1999, WOY 52 | |
1664 | Fri Dec 31 1999, WOY 52 | |
1665 | Sat Jan 01 2000, WOY 52 | |
1666 | Sun Jan 02 2000, WOY 52 | |
1667 | */ | |
1668 | ||
1669 | // Roll the DOW_LOCAL within week 52 | |
1670 | for (i=27; i<=33; ++i) { | |
1671 | int32_t amount; | |
1672 | for (amount=-7; amount<=7; ++amount) { | |
1673 | str = "roll("; | |
1674 | cal.set(1999, UCAL_DECEMBER, i); | |
1675 | UDate t, t2; | |
1676 | fmt.format(cal.getTime(status), str); | |
1677 | CHECK(status, "Fail: getTime failed"); | |
1678 | str += UnicodeString(", ") + amount + ") = "; | |
1679 | ||
1680 | cal.roll(UCAL_DOW_LOCAL, amount, status); | |
1681 | CHECK(status, "Fail: roll failed"); | |
1682 | ||
1683 | t = cal.getTime(status); | |
1684 | int32_t newDom = i + amount; | |
1685 | while (newDom < 27) newDom += 7; | |
1686 | while (newDom > 33) newDom -= 7; | |
1687 | cal.set(1999, UCAL_DECEMBER, newDom); | |
1688 | t2 = cal.getTime(status); | |
1689 | CHECK(status, "Fail: getTime failed"); | |
1690 | fmt.format(t, str); | |
1691 | ||
1692 | if (t != t2) { | |
1693 | str.append(", exp "); | |
1694 | fmt.format(t2, str); | |
1695 | errln(str); | |
1696 | } else { | |
1697 | logln(str); | |
1698 | } | |
1699 | } | |
1700 | } | |
1701 | } | |
1702 | ||
1703 | #undef CHECK | |
1704 | ||
1705 | #endif /* #if !UCONFIG_NO_FORMATTING */ | |
1706 | ||
1707 | //eof |