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