1 /************************************************************************
2 * COPYRIGHT:
3 * Copyright (c) 1997-2012, 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/localpointer.h"
15 #include "hebrwcal.h"
16 #include "unicode/smpdtfmt.h"
17 #include "unicode/simpletz.h"
18 #include "dbgutil.h"
19 #include "unicode/udat.h"
20 #include "unicode/ustring.h"
21 #include "cstring.h"
22 #include "unicode/localpointer.h"
23
24 #define mkcstr(U) u_austrcpy(calloc(8, u_strlen(U) + 1), U)
25
26 #define TEST_CHECK_STATUS {if (U_FAILURE(status)) {errln("%s:%d: Test failure. status=%s", \
27 __FILE__, __LINE__, u_errorName(status)); return;}}
28
29 #define TEST_ASSERT(expr) {if ((expr)==FALSE) {errln("%s:%d: Test failure \n", __FILE__, __LINE__);};}
30
31 // *****************************************************************************
32 // class CalendarTest
33 // *****************************************************************************
34
calToStr(const Calendar & cal)35 UnicodeString CalendarTest::calToStr(const Calendar & cal)
36 {
37 UnicodeString out;
38 UErrorCode status = U_ZERO_ERROR;
39 int i;
40 UDate d;
41 for(i = 0;i<UCAL_FIELD_COUNT;i++) {
42 out += (UnicodeString("") + fieldName((UCalendarDateFields)i) + "=" + cal.get((UCalendarDateFields)i, status) + UnicodeString(" "));
43 }
44 out += "[" + UnicodeString(cal.getType()) + "]";
45
46 if(cal.inDaylightTime(status)) {
47 out += UnicodeString(" (in DST), zone=");
48 }
49 else {
50 out += UnicodeString(", zone=");
51 }
52
53 UnicodeString str2;
54 out += cal.getTimeZone().getDisplayName(str2);
55 d = cal.getTime(status);
56 out += UnicodeString(" :","") + d;
57
58 return out;
59 }
60
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)61 void CalendarTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
62 {
63 if (exec) logln("TestSuite TestCalendar");
64 switch (index) {
65 case 0:
66 name = "TestDOW943";
67 if (exec) {
68 logln("TestDOW943---"); logln("");
69 TestDOW943();
70 }
71 break;
72 case 1:
73 name = "TestClonesUnique908";
74 if (exec) {
75 logln("TestClonesUnique908---"); logln("");
76 TestClonesUnique908();
77 }
78 break;
79 case 2:
80 name = "TestGregorianChange768";
81 if (exec) {
82 logln("TestGregorianChange768---"); logln("");
83 TestGregorianChange768();
84 }
85 break;
86 case 3:
87 name = "TestDisambiguation765";
88 if (exec) {
89 logln("TestDisambiguation765---"); logln("");
90 TestDisambiguation765();
91 }
92 break;
93 case 4:
94 name = "TestGMTvsLocal4064654";
95 if (exec) {
96 logln("TestGMTvsLocal4064654---"); logln("");
97 TestGMTvsLocal4064654();
98 }
99 break;
100 case 5:
101 name = "TestAddSetOrder621";
102 if (exec) {
103 logln("TestAddSetOrder621---"); logln("");
104 TestAddSetOrder621();
105 }
106 break;
107 case 6:
108 name = "TestAdd520";
109 if (exec) {
110 logln("TestAdd520---"); logln("");
111 TestAdd520();
112 }
113 break;
114 case 7:
115 name = "TestFieldSet4781";
116 if (exec) {
117 logln("TestFieldSet4781---"); logln("");
118 TestFieldSet4781();
119 }
120 break;
121 case 8:
122 name = "TestSerialize337";
123 if (exec) {
124 logln("TestSerialize337---"); logln("");
125 // TestSerialize337();
126 }
127 break;
128 case 9:
129 name = "TestSecondsZero121";
130 if (exec) {
131 logln("TestSecondsZero121---"); logln("");
132 TestSecondsZero121();
133 }
134 break;
135 case 10:
136 name = "TestAddSetGet0610";
137 if (exec) {
138 logln("TestAddSetGet0610---"); logln("");
139 TestAddSetGet0610();
140 }
141 break;
142 case 11:
143 name = "TestFields060";
144 if (exec) {
145 logln("TestFields060---"); logln("");
146 TestFields060();
147 }
148 break;
149 case 12:
150 name = "TestEpochStartFields";
151 if (exec) {
152 logln("TestEpochStartFields---"); logln("");
153 TestEpochStartFields();
154 }
155 break;
156 case 13:
157 name = "TestDOWProgression";
158 if (exec) {
159 logln("TestDOWProgression---"); logln("");
160 TestDOWProgression();
161 }
162 break;
163 case 14:
164 name = "TestGenericAPI";
165 if (exec) {
166 logln("TestGenericAPI---"); logln("");
167 TestGenericAPI();
168 }
169 break;
170 case 15:
171 name = "TestAddRollExtensive";
172 if (exec) {
173 logln("TestAddRollExtensive---"); logln("");
174 TestAddRollExtensive();
175 }
176 break;
177 case 16:
178 name = "TestDOW_LOCALandYEAR_WOY";
179 if (exec) {
180 logln("TestDOW_LOCALandYEAR_WOY---"); logln("");
181 TestDOW_LOCALandYEAR_WOY();
182 }
183 break;
184 case 17:
185 name = "TestWOY";
186 if (exec) {
187 logln("TestWOY---"); logln("");
188 TestWOY();
189 }
190 break;
191 case 18:
192 name = "TestRog";
193 if (exec) {
194 logln("TestRog---"); logln("");
195 TestRog();
196 }
197 break;
198 case 19:
199 name = "TestYWOY";
200 if (exec) {
201 logln("TestYWOY---"); logln("");
202 TestYWOY();
203 }
204 break;
205 case 20:
206 name = "TestJD";
207 if(exec) {
208 logln("TestJD---"); logln("");
209 TestJD();
210 }
211 break;
212 case 21:
213 name = "TestDebug";
214 if(exec) {
215 logln("TestDebug---"); logln("");
216 TestDebug();
217 }
218 break;
219 case 22:
220 name = "Test6703";
221 if(exec) {
222 logln("Test6703---"); logln("");
223 Test6703();
224 }
225 break;
226 case 23:
227 name = "Test3785";
228 if(exec) {
229 logln("Test3785---"); logln("");
230 Test3785();
231 }
232 break;
233 case 24:
234 name = "Test1624";
235 if(exec) {
236 logln("Test1624---"); logln("");
237 Test1624();
238 }
239 break;
240 case 25:
241 name = "TestTimeStamp";
242 if(exec) {
243 logln("TestTimeStamp---"); logln("");
244 TestTimeStamp();
245 }
246 break;
247 case 26:
248 name = "TestISO8601";
249 if(exec) {
250 logln("TestISO8601---"); logln("");
251 TestISO8601();
252 }
253 break;
254 case 27:
255 name = "TestAmbiguousWallTimeAPIs";
256 if(exec) {
257 logln("TestAmbiguousWallTimeAPIs---"); logln("");
258 TestAmbiguousWallTimeAPIs();
259 }
260 break;
261 case 28:
262 name = "TestRepeatedWallTime";
263 if(exec) {
264 logln("TestRepeatedWallTime---"); logln("");
265 TestRepeatedWallTime();
266 }
267 break;
268 case 29:
269 name = "TestSkippedWallTime";
270 if(exec) {
271 logln("TestSkippedWallTime---"); logln("");
272 TestSkippedWallTime();
273 }
274 break;
275 case 30:
276 name = "TestCloneLocale";
277 if(exec) {
278 logln("TestCloneLocale---"); logln("");
279 TestCloneLocale();
280 }
281 break;
282 default: name = ""; break;
283 }
284 }
285
286 // ---------------------------------------------------------------------------------
287
fieldName(UCalendarDateFields f)288 UnicodeString CalendarTest::fieldName(UCalendarDateFields f) {
289 switch (f) {
290 #define FIELD_NAME_STR(x) case x: return (#x+5)
291 FIELD_NAME_STR( UCAL_ERA );
292 FIELD_NAME_STR( UCAL_YEAR );
293 FIELD_NAME_STR( UCAL_MONTH );
294 FIELD_NAME_STR( UCAL_WEEK_OF_YEAR );
295 FIELD_NAME_STR( UCAL_WEEK_OF_MONTH );
296 FIELD_NAME_STR( UCAL_DATE );
297 FIELD_NAME_STR( UCAL_DAY_OF_YEAR );
298 FIELD_NAME_STR( UCAL_DAY_OF_WEEK );
299 FIELD_NAME_STR( UCAL_DAY_OF_WEEK_IN_MONTH );
300 FIELD_NAME_STR( UCAL_AM_PM );
301 FIELD_NAME_STR( UCAL_HOUR );
302 FIELD_NAME_STR( UCAL_HOUR_OF_DAY );
303 FIELD_NAME_STR( UCAL_MINUTE );
304 FIELD_NAME_STR( UCAL_SECOND );
305 FIELD_NAME_STR( UCAL_MILLISECOND );
306 FIELD_NAME_STR( UCAL_ZONE_OFFSET );
307 FIELD_NAME_STR( UCAL_DST_OFFSET );
308 FIELD_NAME_STR( UCAL_YEAR_WOY );
309 FIELD_NAME_STR( UCAL_DOW_LOCAL );
310 FIELD_NAME_STR( UCAL_EXTENDED_YEAR );
311 FIELD_NAME_STR( UCAL_JULIAN_DAY );
312 FIELD_NAME_STR( UCAL_MILLISECONDS_IN_DAY );
313 #undef FIELD_NAME_STR
314 default:
315 return UnicodeString("") + ((int32_t)f);
316 }
317 }
318
319 /**
320 * Test various API methods for API completeness.
321 */
322 void
TestGenericAPI()323 CalendarTest::TestGenericAPI()
324 {
325 UErrorCode status = U_ZERO_ERROR;
326 UDate d;
327 UnicodeString str;
328 UBool eq = FALSE,b4 = FALSE,af = FALSE;
329
330 UDate when = date(90, UCAL_APRIL, 15);
331
332 UnicodeString tzid("TestZone");
333 int32_t tzoffset = 123400;
334
335 SimpleTimeZone *zone = new SimpleTimeZone(tzoffset, tzid);
336 Calendar *cal = Calendar::createInstance(zone->clone(), status);
337 if (failure(status, "Calendar::createInstance", TRUE)) return;
338
339 if (*zone != cal->getTimeZone()) errln("FAIL: Calendar::getTimeZone failed");
340
341 Calendar *cal2 = Calendar::createInstance(cal->getTimeZone(), status);
342 if (failure(status, "Calendar::createInstance")) return;
343 cal->setTime(when, status);
344 cal2->setTime(when, status);
345 if (failure(status, "Calendar::setTime")) return;
346
347 if (!(*cal == *cal2)) errln("FAIL: Calendar::operator== failed");
348 if ((*cal != *cal2)) errln("FAIL: Calendar::operator!= failed");
349 if (!cal->equals(*cal2, status) ||
350 cal->before(*cal2, status) ||
351 cal->after(*cal2, status) ||
352 U_FAILURE(status)) errln("FAIL: equals/before/after failed");
353
354 logln(UnicodeString("cal=") +cal->getTime(status) + UnicodeString(calToStr(*cal)));
355 logln(UnicodeString("cal2=") +cal2->getTime(status) + UnicodeString(calToStr(*cal2)));
356 logln("cal2->setTime(when+1000)");
357 cal2->setTime(when + 1000, status);
358 logln(UnicodeString("cal2=") +cal2->getTime(status) + UnicodeString(calToStr(*cal2)));
359
360 if (failure(status, "Calendar::setTime")) return;
361 if (cal->equals(*cal2, status) ||
362 cal2->before(*cal, status) ||
363 cal->after(*cal2, status) ||
364 U_FAILURE(status)) errln("FAIL: equals/before/after failed after setTime(+1000)");
365
366 logln("cal->roll(UCAL_SECOND)");
367 cal->roll(UCAL_SECOND, (UBool) TRUE, status);
368 logln(UnicodeString("cal=") +cal->getTime(status) + UnicodeString(calToStr(*cal)));
369 cal->roll(UCAL_SECOND, (int32_t)0, status);
370 logln(UnicodeString("cal=") +cal->getTime(status) + UnicodeString(calToStr(*cal)));
371 if (failure(status, "Calendar::roll")) return;
372
373 if (!(eq=cal->equals(*cal2, status)) ||
374 (b4=cal->before(*cal2, status)) ||
375 (af=cal->after(*cal2, status)) ||
376 U_FAILURE(status)) {
377 errln("FAIL: equals[%c]/before[%c]/after[%c] failed after roll 1 second [should be T/F/F]",
378 eq?'T':'F',
379 b4?'T':'F',
380 af?'T':'F');
381 logln(UnicodeString("cal=") +cal->getTime(status) + UnicodeString(calToStr(*cal)));
382 logln(UnicodeString("cal2=") +cal2->getTime(status) + UnicodeString(calToStr(*cal2)));
383 }
384
385 // Roll back to January
386 cal->roll(UCAL_MONTH, (int32_t)(1 + UCAL_DECEMBER - cal->get(UCAL_MONTH, status)), status);
387 if (failure(status, "Calendar::roll")) return;
388 if (cal->equals(*cal2, status) ||
389 cal2->before(*cal, status) ||
390 cal->after(*cal2, status) ||
391 U_FAILURE(status)) errln("FAIL: equals/before/after failed after rollback to January");
392
393 TimeZone *z = cal->orphanTimeZone();
394 if (z->getID(str) != tzid ||
395 z->getRawOffset() != tzoffset)
396 errln("FAIL: orphanTimeZone failed");
397
398 int32_t i;
399 for (i=0; i<2; ++i)
400 {
401 UBool lenient = ( i > 0 );
402 cal->setLenient(lenient);
403 if (lenient != cal->isLenient()) errln("FAIL: setLenient/isLenient failed");
404 // Later: Check for lenient behavior
405 }
406
407 for (i=UCAL_SUNDAY; i<=UCAL_SATURDAY; ++i)
408 {
409 cal->setFirstDayOfWeek((UCalendarDaysOfWeek)i);
410 if (cal->getFirstDayOfWeek() != i) errln("FAIL: set/getFirstDayOfWeek failed");
411 UErrorCode aStatus = U_ZERO_ERROR;
412 if (cal->getFirstDayOfWeek(aStatus) != i || U_FAILURE(aStatus)) errln("FAIL: getFirstDayOfWeek(status) failed");
413 }
414
415 for (i=1; i<=7; ++i)
416 {
417 cal->setMinimalDaysInFirstWeek((uint8_t)i);
418 if (cal->getMinimalDaysInFirstWeek() != i) errln("FAIL: set/getFirstDayOfWeek failed");
419 }
420
421 for (i=0; i<UCAL_FIELD_COUNT; ++i)
422 {
423 if (cal->getMinimum((UCalendarDateFields)i) > cal->getGreatestMinimum((UCalendarDateFields)i))
424 errln("FAIL: getMinimum larger than getGreatestMinimum for field " + i);
425 if (cal->getLeastMaximum((UCalendarDateFields)i) > cal->getMaximum((UCalendarDateFields)i))
426 errln("FAIL: getLeastMaximum larger than getMaximum for field " + i);
427 if (cal->getMinimum((UCalendarDateFields)i) >= cal->getMaximum((UCalendarDateFields)i))
428 errln("FAIL: getMinimum not less than getMaximum for field " + i);
429 }
430
431 cal->adoptTimeZone(TimeZone::createDefault());
432 cal->clear();
433 cal->set(1984, 5, 24);
434 if (cal->getTime(status) != date(84, 5, 24) || U_FAILURE(status))
435 errln("FAIL: Calendar::set(3 args) failed");
436
437 cal->clear();
438 cal->set(1985, 3, 2, 11, 49);
439 if (cal->getTime(status) != date(85, 3, 2, 11, 49) || U_FAILURE(status))
440 errln("FAIL: Calendar::set(5 args) failed");
441
442 cal->clear();
443 cal->set(1995, 9, 12, 1, 39, 55);
444 if (cal->getTime(status) != date(95, 9, 12, 1, 39, 55) || U_FAILURE(status))
445 errln("FAIL: Calendar::set(6 args) failed");
446
447 cal->getTime(status);
448 if (failure(status, "Calendar::getTime")) return;
449 for (i=0; i<UCAL_FIELD_COUNT; ++i)
450 {
451 switch(i) {
452 case UCAL_YEAR: case UCAL_MONTH: case UCAL_DATE:
453 case UCAL_HOUR_OF_DAY: case UCAL_MINUTE: case UCAL_SECOND:
454 case UCAL_EXTENDED_YEAR:
455 if (!cal->isSet((UCalendarDateFields)i)) errln("FAIL: Calendar::isSet F, should be T " + fieldName((UCalendarDateFields)i));
456 break;
457 default:
458 if (cal->isSet((UCalendarDateFields)i)) errln("FAIL: Calendar::isSet = T, should be F " + fieldName((UCalendarDateFields)i));
459 }
460 cal->clear((UCalendarDateFields)i);
461 if (cal->isSet((UCalendarDateFields)i)) errln("FAIL: Calendar::clear/isSet failed " + fieldName((UCalendarDateFields)i));
462 }
463
464 if(cal->getActualMinimum(Calendar::SECOND, status) != 0){
465 errln("Calendar is suppose to return 0 for getActualMinimum");
466 }
467
468 Calendar *cal3 = Calendar::createInstance(status);
469 cal3->roll(Calendar::SECOND, (int32_t)0, status);
470 if (failure(status, "Calendar::roll(EDateFields, int32_t, UErrorCode)")) return;
471
472 delete cal;
473 delete cal2;
474 delete cal3;
475
476 int32_t count;
477 const Locale* loc = Calendar::getAvailableLocales(count);
478 if (count < 1 || loc == 0)
479 {
480 dataerrln("FAIL: getAvailableLocales failed");
481 }
482 else
483 {
484 for (i=0; i<count; ++i)
485 {
486 cal = Calendar::createInstance(loc[i], status);
487 if (failure(status, "Calendar::createInstance")) return;
488 delete cal;
489 }
490 }
491
492 cal = Calendar::createInstance(TimeZone::createDefault(), Locale::getEnglish(), status);
493 if (failure(status, "Calendar::createInstance")) return;
494 delete cal;
495
496 cal = Calendar::createInstance(*zone, Locale::getEnglish(), status);
497 if (failure(status, "Calendar::createInstance")) return;
498 delete cal;
499
500 GregorianCalendar *gc = new GregorianCalendar(*zone, status);
501 if (failure(status, "new GregorianCalendar")) return;
502 delete gc;
503
504 gc = new GregorianCalendar(Locale::getEnglish(), status);
505 if (failure(status, "new GregorianCalendar")) return;
506 delete gc;
507
508 gc = new GregorianCalendar(Locale::getEnglish(), status);
509 delete gc;
510
511 gc = new GregorianCalendar(*zone, Locale::getEnglish(), status);
512 if (failure(status, "new GregorianCalendar")) return;
513 delete gc;
514
515 gc = new GregorianCalendar(zone, status);
516 if (failure(status, "new GregorianCalendar")) return;
517 delete gc;
518
519 gc = new GregorianCalendar(1998, 10, 14, 21, 43, status);
520 if (gc->getTime(status) != (d =date(98, 10, 14, 21, 43) )|| U_FAILURE(status))
521 errln("FAIL: new GregorianCalendar(ymdhm) failed with " + UnicodeString(u_errorName(status)) + ", cal=" + gc->getTime(status) + UnicodeString(calToStr(*gc)) + ", d=" + d);
522 else
523 logln(UnicodeString("GOOD: cal=") +gc->getTime(status) + UnicodeString(calToStr(*gc)) + ", d=" + d);
524 delete gc;
525
526 gc = new GregorianCalendar(1998, 10, 14, 21, 43, 55, status);
527 if (gc->getTime(status) != (d=date(98, 10, 14, 21, 43, 55)) || U_FAILURE(status))
528 errln("FAIL: new GregorianCalendar(ymdhms) failed with " + UnicodeString(u_errorName(status)));
529
530 GregorianCalendar gc2(Locale::getEnglish(), status);
531 if (failure(status, "new GregorianCalendar")) return;
532 gc2 = *gc;
533 if (gc2 != *gc || !(gc2 == *gc)) errln("FAIL: GregorianCalendar assignment/operator==/operator!= failed");
534 delete gc;
535 delete z;
536
537 /* Code coverage for Calendar class. */
538 cal = Calendar::createInstance(status);
539 if (failure(status, "Calendar::createInstance")) {
540 return;
541 }else {
542 ((Calendar *)cal)->roll(UCAL_HOUR, (int32_t)100, status);
543 ((Calendar *)cal)->clear(UCAL_HOUR);
544 #if !UCONFIG_NO_SERVICE
545 URegistryKey key = cal->registerFactory(NULL, status);
546 cal->unregister(key, status);
547 #endif
548 }
549 delete cal;
550
551 status = U_ZERO_ERROR;
552 cal = Calendar::createInstance(Locale("he_IL@calendar=hebrew"), status);
553 if (failure(status, "Calendar::createInstance")) {
554 return;
555 } else {
556 cal->roll(Calendar::MONTH, (int32_t)100, status);
557 }
558
559 LocalPointer<StringEnumeration> values(
560 Calendar::getKeywordValuesForLocale("calendar", Locale("he"), FALSE, status));
561 if (values.isNull() || U_FAILURE(status)) {
562 dataerrln("FAIL: Calendar::getKeywordValuesForLocale(he): %s", u_errorName(status));
563 } else {
564 UBool containsHebrew = FALSE;
565 const char *charValue;
566 int32_t valueLength;
567 while ((charValue = values->next(&valueLength, status)) != NULL) {
568 if (valueLength == 6 && strcmp(charValue, "hebrew") == 0) {
569 containsHebrew = TRUE;
570 }
571 }
572 if (!containsHebrew) {
573 errln("Calendar::getKeywordValuesForLocale(he)->next() does not contain \"hebrew\"");
574 }
575
576 values->reset(status);
577 containsHebrew = FALSE;
578 UnicodeString hebrew = UNICODE_STRING_SIMPLE("hebrew");
579 const UChar *ucharValue;
580 while ((ucharValue = values->unext(&valueLength, status)) != NULL) {
581 UnicodeString value(FALSE, ucharValue, valueLength);
582 if (value == hebrew) {
583 containsHebrew = TRUE;
584 }
585 }
586 if (!containsHebrew) {
587 errln("Calendar::getKeywordValuesForLocale(he)->unext() does not contain \"hebrew\"");
588 }
589
590 values->reset(status);
591 containsHebrew = FALSE;
592 const UnicodeString *stringValue;
593 while ((stringValue = values->snext(status)) != NULL) {
594 if (*stringValue == hebrew) {
595 containsHebrew = TRUE;
596 }
597 }
598 if (!containsHebrew) {
599 errln("Calendar::getKeywordValuesForLocale(he)->snext() does not contain \"hebrew\"");
600 }
601 }
602 delete cal;
603 }
604
605 // -------------------------------------
606
607 /**
608 * This test confirms the correct behavior of add when incrementing
609 * through subsequent days.
610 */
611 void
TestRog()612 CalendarTest::TestRog()
613 {
614 UErrorCode status = U_ZERO_ERROR;
615 GregorianCalendar* gc = new GregorianCalendar(status);
616 if (failure(status, "new GregorianCalendar", TRUE)) return;
617 int32_t year = 1997, month = UCAL_APRIL, date = 1;
618 gc->set(year, month, date);
619 gc->set(UCAL_HOUR_OF_DAY, 23);
620 gc->set(UCAL_MINUTE, 0);
621 gc->set(UCAL_SECOND, 0);
622 gc->set(UCAL_MILLISECOND, 0);
623 for (int32_t i = 0; i < 9; i++, gc->add(UCAL_DATE, 1, status)) {
624 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
625 if (gc->get(UCAL_YEAR, status) != year ||
626 gc->get(UCAL_MONTH, status) != month ||
627 gc->get(UCAL_DATE, status) != (date + i)) errln("FAIL: Date wrong");
628 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
629 }
630 delete gc;
631 }
632
633 // -------------------------------------
634
635 /**
636 * Test the handling of the day of the week, checking for correctness and
637 * for correct minimum and maximum values.
638 */
639 void
TestDOW943()640 CalendarTest::TestDOW943()
641 {
642 dowTest(FALSE);
643 dowTest(TRUE);
644 }
645
dowTest(UBool lenient)646 void CalendarTest::dowTest(UBool lenient)
647 {
648 UErrorCode status = U_ZERO_ERROR;
649 GregorianCalendar* cal = new GregorianCalendar(status);
650 if (failure(status, "new GregorianCalendar", TRUE)) return;
651 logln("cal - Aug 12, 1997\n");
652 cal->set(1997, UCAL_AUGUST, 12);
653 cal->getTime(status);
654 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; }
655 logln((lenient?UnicodeString("LENIENT0: "):UnicodeString("nonlenient0: ")) + UnicodeString(calToStr(*cal)));
656 cal->setLenient(lenient);
657 logln("cal - Dec 1, 1996\n");
658 cal->set(1996, UCAL_DECEMBER, 1);
659 logln((lenient?UnicodeString("LENIENT: "):UnicodeString("nonlenient: ")) + UnicodeString(calToStr(*cal)));
660 int32_t dow = cal->get(UCAL_DAY_OF_WEEK, status);
661 if (U_FAILURE(status)) { errln("Calendar::get failed [%s]", u_errorName(status)); return; }
662 int32_t min = cal->getMinimum(UCAL_DAY_OF_WEEK);
663 int32_t max = cal->getMaximum(UCAL_DAY_OF_WEEK);
664 if (dow < min ||
665 dow > max) errln(UnicodeString("FAIL: Day of week ") + (int32_t)dow + " out of range");
666 if (dow != UCAL_SUNDAY) errln("FAIL: Day of week should be SUNDAY[%d] not %d", UCAL_SUNDAY, dow);
667 if (min != UCAL_SUNDAY ||
668 max != UCAL_SATURDAY) errln("FAIL: Min/max bad");
669 delete cal;
670 }
671
672 // -------------------------------------
673
674 /**
675 * Confirm that cloned Calendar objects do not inadvertently share substructures.
676 */
677 void
TestClonesUnique908()678 CalendarTest::TestClonesUnique908()
679 {
680 UErrorCode status = U_ZERO_ERROR;
681 Calendar *c = Calendar::createInstance(status);
682 if (failure(status, "Calendar::createInstance", TRUE)) return;
683 Calendar *d = (Calendar*) c->clone();
684 c->set(UCAL_MILLISECOND, 123);
685 d->set(UCAL_MILLISECOND, 456);
686 if (c->get(UCAL_MILLISECOND, status) != 123 ||
687 d->get(UCAL_MILLISECOND, status) != 456) {
688 errln("FAIL: Clones share fields");
689 }
690 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
691 delete c;
692 delete d;
693 }
694
695 // -------------------------------------
696
697 /**
698 * Confirm that the Gregorian cutoff value works as advertised.
699 */
700 void
TestGregorianChange768()701 CalendarTest::TestGregorianChange768()
702 {
703 UBool b;
704 UErrorCode status = U_ZERO_ERROR;
705 UnicodeString str;
706 GregorianCalendar* c = new GregorianCalendar(status);
707 if (failure(status, "new GregorianCalendar", TRUE)) return;
708 logln(UnicodeString("With cutoff ") + dateToString(c->getGregorianChange(), str));
709 b = c->isLeapYear(1800);
710 logln(UnicodeString(" isLeapYear(1800) = ") + (b ? "true" : "false"));
711 logln(UnicodeString(" (should be FALSE)"));
712 if (b) errln("FAIL");
713 c->setGregorianChange(date(0, 0, 1), status);
714 if (U_FAILURE(status)) { errln("GregorianCalendar::setGregorianChange failed"); return; }
715 logln(UnicodeString("With cutoff ") + dateToString(c->getGregorianChange(), str));
716 b = c->isLeapYear(1800);
717 logln(UnicodeString(" isLeapYear(1800) = ") + (b ? "true" : "false"));
718 logln(UnicodeString(" (should be TRUE)"));
719 if (!b) errln("FAIL");
720 delete c;
721 }
722
723 // -------------------------------------
724
725 /**
726 * Confirm the functioning of the field disambiguation algorithm.
727 */
728 void
TestDisambiguation765()729 CalendarTest::TestDisambiguation765()
730 {
731 UErrorCode status = U_ZERO_ERROR;
732 Calendar *c = Calendar::createInstance("en_US", status);
733 if (failure(status, "Calendar::createInstance", TRUE)) return;
734 c->setLenient(FALSE);
735 c->clear();
736 c->set(UCAL_YEAR, 1997);
737 c->set(UCAL_MONTH, UCAL_JUNE);
738 c->set(UCAL_DATE, 3);
739 verify765("1997 third day of June = ", c, 1997, UCAL_JUNE, 3);
740 c->clear();
741 c->set(UCAL_YEAR, 1997);
742 c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY);
743 c->set(UCAL_MONTH, UCAL_JUNE);
744 c->set(UCAL_DAY_OF_WEEK_IN_MONTH, 1);
745 verify765("1997 first Tuesday in June = ", c, 1997, UCAL_JUNE, 3);
746 c->clear();
747 c->set(UCAL_YEAR, 1997);
748 c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY);
749 c->set(UCAL_MONTH, UCAL_JUNE);
750 c->set(UCAL_DAY_OF_WEEK_IN_MONTH, - 1);
751 verify765("1997 last Tuesday in June = ", c, 1997, UCAL_JUNE, 24);
752
753 status = U_ZERO_ERROR;
754 c->clear();
755 c->set(UCAL_YEAR, 1997);
756 c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY);
757 c->set(UCAL_MONTH, UCAL_JUNE);
758 c->set(UCAL_DAY_OF_WEEK_IN_MONTH, 0);
759 c->getTime(status);
760 verify765("1997 zero-th Tuesday in June = ", status);
761
762 c->clear();
763 c->set(UCAL_YEAR, 1997);
764 c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY);
765 c->set(UCAL_MONTH, UCAL_JUNE);
766 c->set(UCAL_WEEK_OF_MONTH, 1);
767 verify765("1997 Tuesday in week 1 of June = ", c, 1997, UCAL_JUNE, 3);
768 c->clear();
769 c->set(UCAL_YEAR, 1997);
770 c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY);
771 c->set(UCAL_MONTH, UCAL_JUNE);
772 c->set(UCAL_WEEK_OF_MONTH, 5);
773 verify765("1997 Tuesday in week 5 of June = ", c, 1997, UCAL_JULY, 1);
774
775 status = U_ZERO_ERROR;
776 c->clear();
777 c->set(UCAL_YEAR, 1997);
778 c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY);
779 c->set(UCAL_MONTH, UCAL_JUNE);
780 c->set(UCAL_WEEK_OF_MONTH, 0);
781 c->setMinimalDaysInFirstWeek(1);
782 c->getTime(status);
783 verify765("1997 Tuesday in week 0 of June = ", status);
784
785 /* Note: The following test used to expect YEAR 1997, WOY 1 to
786 * resolve to a date in Dec 1996; that is, to behave as if
787 * YEAR_WOY were 1997. With the addition of a new explicit
788 * YEAR_WOY field, YEAR_WOY must itself be set if that is what is
789 * desired. Using YEAR in combination with WOY is ambiguous, and
790 * results in the first WOY/DOW day of the year satisfying the
791 * given fields (there may be up to two such days). In this case,
792 * it propertly resolves to Tue Dec 30 1997, which has a WOY value
793 * of 1 (for YEAR_WOY 1998) and a DOW of Tuesday, and falls in the
794 * _calendar_ year 1997, as specified. - aliu */
795 c->clear();
796 c->set(UCAL_YEAR_WOY, 1997); // aliu
797 c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY);
798 c->set(UCAL_WEEK_OF_YEAR, 1);
799 verify765("1997 Tuesday in week 1 of yearWOY = ", c, 1996, UCAL_DECEMBER, 31);
800 c->clear(); // - add test for YEAR
801 c->setMinimalDaysInFirstWeek(1);
802 c->set(UCAL_YEAR, 1997);
803 c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY);
804 c->set(UCAL_WEEK_OF_YEAR, 1);
805 verify765("1997 Tuesday in week 1 of year = ", c, 1997, UCAL_DECEMBER, 30);
806 c->clear();
807 c->set(UCAL_YEAR, 1997);
808 c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY);
809 c->set(UCAL_WEEK_OF_YEAR, 10);
810 verify765("1997 Tuesday in week 10 of year = ", c, 1997, UCAL_MARCH, 4);
811 //try {
812
813 // {sfb} week 0 is no longer a valid week of year
814 /*c->clear();
815 c->set(Calendar::YEAR, 1997);
816 c->set(Calendar::DAY_OF_WEEK, Calendar::TUESDAY);
817 //c->set(Calendar::WEEK_OF_YEAR, 0);
818 c->set(Calendar::WEEK_OF_YEAR, 1);
819 verify765("1997 Tuesday in week 0 of year = ", c, 1996, Calendar::DECEMBER, 24);*/
820
821 //}
822 //catch(IllegalArgumentException ex) {
823 // errln("FAIL: Exception seen:");
824 // ex.printStackTrace(log);
825 //}
826 delete c;
827 }
828
829 // -------------------------------------
830
831 void
verify765(const UnicodeString & msg,Calendar * c,int32_t year,int32_t month,int32_t day)832 CalendarTest::verify765(const UnicodeString& msg, Calendar* c, int32_t year, int32_t month, int32_t day)
833 {
834 UnicodeString str;
835 UErrorCode status = U_ZERO_ERROR;
836 int32_t y = c->get(UCAL_YEAR, status);
837 int32_t m = c->get(UCAL_MONTH, status);
838 int32_t d = c->get(UCAL_DATE, status);
839 if ( y == year &&
840 m == month &&
841 d == day) {
842 if (U_FAILURE(status)) { errln("FAIL: Calendar::get failed"); return; }
843 logln("PASS: " + msg + dateToString(c->getTime(status), str));
844 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; }
845 }
846 else {
847 errln("FAIL: " + msg + dateToString(c->getTime(status), str) + "; expected " + (int32_t)year + "/" + (int32_t)(month + 1) + "/" + (int32_t)day +
848 "; got " + (int32_t)y + "/" + (int32_t)(m + 1) + "/" + (int32_t)d + " for Locale: " + c->getLocaleID(ULOC_ACTUAL_LOCALE,status));
849 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; }
850 }
851 }
852
853 // -------------------------------------
854
855 void
verify765(const UnicodeString & msg,UErrorCode status)856 CalendarTest::verify765(const UnicodeString& msg/*, IllegalArgumentException e*/, UErrorCode status)
857 {
858 if (status != U_ILLEGAL_ARGUMENT_ERROR) errln("FAIL: No IllegalArgumentException for " + msg);
859 else logln("PASS: " + msg + "IllegalArgument as expected");
860 }
861
862 // -------------------------------------
863
864 /**
865 * Confirm that the offset between local time and GMT behaves as expected.
866 */
867 void
TestGMTvsLocal4064654()868 CalendarTest::TestGMTvsLocal4064654()
869 {
870 test4064654(1997, 1, 1, 12, 0, 0);
871 test4064654(1997, 4, 16, 18, 30, 0);
872 }
873
874 // -------------------------------------
875
876 void
test4064654(int32_t yr,int32_t mo,int32_t dt,int32_t hr,int32_t mn,int32_t sc)877 CalendarTest::test4064654(int32_t yr, int32_t mo, int32_t dt, int32_t hr, int32_t mn, int32_t sc)
878 {
879 UDate date;
880 UErrorCode status = U_ZERO_ERROR;
881 UnicodeString str;
882 Calendar *gmtcal = Calendar::createInstance(status);
883 if (failure(status, "Calendar::createInstance", TRUE)) return;
884 gmtcal->adoptTimeZone(TimeZone::createTimeZone("Africa/Casablanca"));
885 gmtcal->set(yr, mo - 1, dt, hr, mn, sc);
886 gmtcal->set(UCAL_MILLISECOND, 0);
887 date = gmtcal->getTime(status);
888 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; }
889 logln("date = " + dateToString(date, str));
890 Calendar *cal = Calendar::createInstance(status);
891 if (U_FAILURE(status)) { errln("Calendar::createInstance failed"); return; }
892 cal->setTime(date, status);
893 if (U_FAILURE(status)) { errln("Calendar::setTime failed"); return; }
894 int32_t offset = cal->getTimeZone().getOffset((uint8_t)cal->get(UCAL_ERA, status),
895 cal->get(UCAL_YEAR, status),
896 cal->get(UCAL_MONTH, status),
897 cal->get(UCAL_DATE, status),
898 (uint8_t)cal->get(UCAL_DAY_OF_WEEK, status),
899 cal->get(UCAL_MILLISECOND, status), status);
900 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
901 logln("offset for " + dateToString(date, str) + "= " + (offset / 1000 / 60 / 60.0) + "hr");
902 int32_t utc = ((cal->get(UCAL_HOUR_OF_DAY, status) * 60 +
903 cal->get(UCAL_MINUTE, status)) * 60 +
904 cal->get(UCAL_SECOND, status)) * 1000 +
905 cal->get(UCAL_MILLISECOND, status) - offset;
906 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
907 int32_t expected = ((hr * 60 + mn) * 60 + sc) * 1000;
908 if (utc != expected) errln(UnicodeString("FAIL: Discrepancy of ") + (utc - expected) +
909 " millis = " + ((utc - expected) / 1000 / 60 / 60.0) + " hr");
910 delete gmtcal;
911 delete cal;
912 }
913
914 // -------------------------------------
915
916 /**
917 * The operations of adding and setting should not exhibit pathological
918 * dependence on the order of operations. This test checks for this.
919 */
920 void
TestAddSetOrder621()921 CalendarTest::TestAddSetOrder621()
922 {
923 UDate d = date(97, 4, 14, 13, 23, 45);
924 UErrorCode status = U_ZERO_ERROR;
925 Calendar *cal = Calendar::createInstance(status);
926 if (failure(status, "Calendar::createInstance", TRUE)) return;
927
928 cal->setTime(d, status);
929 if (U_FAILURE(status)) {
930 errln("Calendar::setTime failed");
931 delete cal;
932 return;
933 }
934 cal->add(UCAL_DATE, - 5, status);
935 if (U_FAILURE(status)) {
936 errln("Calendar::add failed");
937 delete cal;
938 return;
939 }
940 cal->set(UCAL_HOUR_OF_DAY, 0);
941 cal->set(UCAL_MINUTE, 0);
942 cal->set(UCAL_SECOND, 0);
943 UnicodeString s;
944 dateToString(cal->getTime(status), s);
945 if (U_FAILURE(status)) {
946 errln("Calendar::getTime failed");
947 delete cal;
948 return;
949 }
950 delete cal;
951
952 cal = Calendar::createInstance(status);
953 if (U_FAILURE(status)) {
954 errln("Calendar::createInstance failed");
955 delete cal;
956 return;
957 }
958 cal->setTime(d, status);
959 if (U_FAILURE(status)) {
960 errln("Calendar::setTime failed");
961 delete cal;
962 return;
963 }
964 cal->set(UCAL_HOUR_OF_DAY, 0);
965 cal->set(UCAL_MINUTE, 0);
966 cal->set(UCAL_SECOND, 0);
967 cal->add(UCAL_DATE, - 5, status);
968 if (U_FAILURE(status)) {
969 errln("Calendar::add failed");
970 delete cal;
971 return;
972 }
973 UnicodeString s2;
974 dateToString(cal->getTime(status), s2);
975 if (U_FAILURE(status)) {
976 errln("Calendar::getTime failed");
977 delete cal;
978 return;
979 }
980 if (s == s2)
981 logln("Pass: " + s + " == " + s2);
982 else
983 errln("FAIL: " + s + " != " + s2);
984 delete cal;
985 }
986
987 // -------------------------------------
988
989 /**
990 * Confirm that adding to various fields works.
991 */
992 void
TestAdd520()993 CalendarTest::TestAdd520()
994 {
995 int32_t y = 1997, m = UCAL_FEBRUARY, d = 1;
996 UErrorCode status = U_ZERO_ERROR;
997 GregorianCalendar *temp = new GregorianCalendar(y, m, d, status);
998 if (failure(status, "new GregorianCalendar", TRUE)) return;
999 check520(temp, y, m, d);
1000 temp->add(UCAL_YEAR, 1, status);
1001 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
1002 y++;
1003 check520(temp, y, m, d);
1004 temp->add(UCAL_MONTH, 1, status);
1005 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
1006 m++;
1007 check520(temp, y, m, d);
1008 temp->add(UCAL_DATE, 1, status);
1009 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
1010 d++;
1011 check520(temp, y, m, d);
1012 temp->add(UCAL_DATE, 2, status);
1013 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
1014 d += 2;
1015 check520(temp, y, m, d);
1016 temp->add(UCAL_DATE, 28, status);
1017 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
1018 d = 1;++m;
1019 check520(temp, y, m, d);
1020 delete temp;
1021 }
1022
1023 // -------------------------------------
1024
1025 /**
1026 * Execute adding and rolling in GregorianCalendar extensively,
1027 */
1028 void
TestAddRollExtensive()1029 CalendarTest::TestAddRollExtensive()
1030 {
1031 int32_t maxlimit = 40;
1032 int32_t y = 1997, m = UCAL_FEBRUARY, d = 1, hr = 1, min = 1, sec = 0, ms = 0;
1033 UErrorCode status = U_ZERO_ERROR;
1034 GregorianCalendar *temp = new GregorianCalendar(y, m, d, status);
1035 if (failure(status, "new GregorianCalendar", TRUE)) return;
1036
1037 temp->set(UCAL_HOUR, hr);
1038 temp->set(UCAL_MINUTE, min);
1039 temp->set(UCAL_SECOND, sec);
1040 temp->set(UCAL_MILLISECOND, ms);
1041 temp->setMinimalDaysInFirstWeek(1);
1042
1043 UCalendarDateFields e;
1044
1045 logln("Testing GregorianCalendar add...");
1046 e = UCAL_YEAR;
1047 while (e < UCAL_FIELD_COUNT) {
1048 int32_t i;
1049 int32_t limit = maxlimit;
1050 status = U_ZERO_ERROR;
1051 for (i = 0; i < limit; i++) {
1052 temp->add(e, 1, status);
1053 if (U_FAILURE(status)) { limit = i; status = U_ZERO_ERROR; }
1054 }
1055 for (i = 0; i < limit; i++) {
1056 temp->add(e, -1, status);
1057 if (U_FAILURE(status)) { errln("GregorianCalendar::add -1 failed"); return; }
1058 }
1059 check520(temp, y, m, d, hr, min, sec, ms, e);
1060
1061 e = (UCalendarDateFields) ((int32_t) e + 1);
1062 }
1063
1064 logln("Testing GregorianCalendar roll...");
1065 e = UCAL_YEAR;
1066 while (e < UCAL_FIELD_COUNT) {
1067 int32_t i;
1068 int32_t limit = maxlimit;
1069 status = U_ZERO_ERROR;
1070 for (i = 0; i < limit; i++) {
1071 logln(calToStr(*temp) + UnicodeString(" " ) + fieldName(e) + UnicodeString("++") );
1072 temp->roll(e, 1, status);
1073 if (U_FAILURE(status)) {
1074 logln("caltest.cpp:%d e=%d, i=%d - roll(+) err %s\n", __LINE__, (int) e, (int) i, u_errorName(status));
1075 logln(calToStr(*temp));
1076 limit = i; status = U_ZERO_ERROR;
1077 }
1078 }
1079 for (i = 0; i < limit; i++) {
1080 logln("caltest.cpp:%d e=%d, i=%d\n", __LINE__, (int) e, (int) i);
1081 logln(calToStr(*temp) + UnicodeString(" " ) + fieldName(e) + UnicodeString("--") );
1082 temp->roll(e, -1, status);
1083 if (U_FAILURE(status)) { errln(UnicodeString("GregorianCalendar::roll ") + CalendarTest::fieldName(e) + " count=" + UnicodeString('@'+i) + " by -1 failed with " + u_errorName(status) ); return; }
1084 }
1085 check520(temp, y, m, d, hr, min, sec, ms, e);
1086
1087 e = (UCalendarDateFields) ((int32_t) e + 1);
1088 }
1089
1090 delete temp;
1091 }
1092
1093 // -------------------------------------
1094 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)1095 CalendarTest::check520(Calendar* c,
1096 int32_t y, int32_t m, int32_t d,
1097 int32_t hr, int32_t min, int32_t sec,
1098 int32_t ms, UCalendarDateFields field)
1099
1100 {
1101 UErrorCode status = U_ZERO_ERROR;
1102 if (c->get(UCAL_YEAR, status) != y ||
1103 c->get(UCAL_MONTH, status) != m ||
1104 c->get(UCAL_DATE, status) != d ||
1105 c->get(UCAL_HOUR, status) != hr ||
1106 c->get(UCAL_MINUTE, status) != min ||
1107 c->get(UCAL_SECOND, status) != sec ||
1108 c->get(UCAL_MILLISECOND, status) != ms) {
1109 errln(UnicodeString("U_FAILURE for field ") + (int32_t)field +
1110 ": Expected y/m/d h:m:s:ms of " +
1111 y + "/" + (m + 1) + "/" + d + " " +
1112 hr + ":" + min + ":" + sec + ":" + ms +
1113 "; got " + c->get(UCAL_YEAR, status) +
1114 "/" + (c->get(UCAL_MONTH, status) + 1) +
1115 "/" + c->get(UCAL_DATE, status) +
1116 " " + c->get(UCAL_HOUR, status) + ":" +
1117 c->get(UCAL_MINUTE, status) + ":" +
1118 c->get(UCAL_SECOND, status) + ":" +
1119 c->get(UCAL_MILLISECOND, status)
1120 );
1121
1122 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
1123 }
1124 else
1125 logln(UnicodeString("Confirmed: ") + y + "/" +
1126 (m + 1) + "/" + d + " " +
1127 hr + ":" + min + ":" + sec + ":" + ms);
1128 }
1129
1130 // -------------------------------------
1131 void
check520(Calendar * c,int32_t y,int32_t m,int32_t d)1132 CalendarTest::check520(Calendar* c,
1133 int32_t y, int32_t m, int32_t d)
1134
1135 {
1136 UErrorCode status = U_ZERO_ERROR;
1137 if (c->get(UCAL_YEAR, status) != y ||
1138 c->get(UCAL_MONTH, status) != m ||
1139 c->get(UCAL_DATE, status) != d) {
1140 errln(UnicodeString("FAILURE: Expected y/m/d of ") +
1141 y + "/" + (m + 1) + "/" + d + " " +
1142 "; got " + c->get(UCAL_YEAR, status) +
1143 "/" + (c->get(UCAL_MONTH, status) + 1) +
1144 "/" + c->get(UCAL_DATE, status)
1145 );
1146
1147 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
1148 }
1149 else
1150 logln(UnicodeString("Confirmed: ") + y + "/" +
1151 (m + 1) + "/" + d);
1152 }
1153
1154 // -------------------------------------
1155
1156 /**
1157 * Test that setting of fields works. In particular, make sure that all instances
1158 * of GregorianCalendar don't share a static instance of the fields array.
1159 */
1160 void
TestFieldSet4781()1161 CalendarTest::TestFieldSet4781()
1162 {
1163 // try {
1164 UErrorCode status = U_ZERO_ERROR;
1165 GregorianCalendar *g = new GregorianCalendar(status);
1166 if (failure(status, "new GregorianCalendar", TRUE)) return;
1167 GregorianCalendar *g2 = new GregorianCalendar(status);
1168 if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; }
1169 g2->set(UCAL_HOUR, 12, status);
1170 g2->set(UCAL_MINUTE, 0, status);
1171 g2->set(UCAL_SECOND, 0, status);
1172 if (U_FAILURE(status)) { errln("Calendar::set failed"); return; }
1173 if (*g == *g2) logln("Same");
1174 else logln("Different");
1175 //}
1176 //catch(IllegalArgumentException e) {
1177 //errln("Unexpected exception seen: " + e);
1178 //}
1179 delete g;
1180 delete g2;
1181 }
1182
1183 // -------------------------------------
1184
1185 /* We don't support serialization on C++
1186 void
1187 CalendarTest::TestSerialize337()
1188 {
1189 Calendar cal = Calendar::getInstance();
1190 UBool ok = FALSE;
1191 try {
1192 FileOutputStream f = new FileOutputStream(FILENAME);
1193 ObjectOutput s = new ObjectOutputStream(f);
1194 s.writeObject(PREFIX);
1195 s.writeObject(cal);
1196 s.writeObject(POSTFIX);
1197 f.close();
1198 FileInputStream in = new FileInputStream(FILENAME);
1199 ObjectInputStream t = new ObjectInputStream(in);
1200 UnicodeString& pre = (UnicodeString&) t.readObject();
1201 Calendar c = (Calendar) t.readObject();
1202 UnicodeString& post = (UnicodeString&) t.readObject();
1203 in.close();
1204 ok = pre.equals(PREFIX) &&
1205 post.equals(POSTFIX) &&
1206 cal->equals(c);
1207 File fl = new File(FILENAME);
1208 fl.delete();
1209 }
1210 catch(IOException e) {
1211 errln("FAIL: Exception received:");
1212 e.printStackTrace(log);
1213 }
1214 catch(ClassNotFoundException e) {
1215 errln("FAIL: Exception received:");
1216 e.printStackTrace(log);
1217 }
1218 if (!ok) errln("Serialization of Calendar object failed.");
1219 }
1220
1221 UnicodeString& CalendarTest::PREFIX = "abc";
1222
1223 UnicodeString& CalendarTest::POSTFIX = "def";
1224
1225 UnicodeString& CalendarTest::FILENAME = "tmp337.bin";
1226 */
1227
1228 // -------------------------------------
1229
1230 /**
1231 * Verify that the seconds of a Calendar can be zeroed out through the
1232 * expected sequence of operations.
1233 */
1234 void
TestSecondsZero121()1235 CalendarTest::TestSecondsZero121()
1236 {
1237 UErrorCode status = U_ZERO_ERROR;
1238 Calendar *cal = new GregorianCalendar(status);
1239 if (failure(status, "new GregorianCalendar", TRUE)) return;
1240 cal->setTime(Calendar::getNow(), status);
1241 if (U_FAILURE(status)) { errln("Calendar::setTime failed"); return; }
1242 cal->set(UCAL_SECOND, 0);
1243 if (U_FAILURE(status)) { errln("Calendar::set failed"); return; }
1244 UDate d = cal->getTime(status);
1245 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; }
1246 UnicodeString s;
1247 dateToString(d, s);
1248 if (s.indexOf("DATE_FORMAT_FAILURE") >= 0) {
1249 dataerrln("Got: \"DATE_FORMAT_FAILURE\".");
1250 } else if (s.indexOf(":00 ") < 0) {
1251 errln("Expected to see :00 in " + s);
1252 }
1253 delete cal;
1254 }
1255
1256 // -------------------------------------
1257
1258 /**
1259 * Verify that a specific sequence of adding and setting works as expected;
1260 * it should not vary depending on when and whether the get method is
1261 * called.
1262 */
1263 void
TestAddSetGet0610()1264 CalendarTest::TestAddSetGet0610()
1265 {
1266 UnicodeString EXPECTED_0610("1993/0/5", "");
1267 UErrorCode status = U_ZERO_ERROR;
1268 {
1269 Calendar *calendar = new GregorianCalendar(status);
1270 if (failure(status, "new GregorianCalendar", TRUE)) return;
1271 calendar->set(1993, UCAL_JANUARY, 4);
1272 logln("1A) " + value(calendar));
1273 calendar->add(UCAL_DATE, 1, status);
1274 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
1275 UnicodeString v = value(calendar);
1276 logln("1B) " + v);
1277 logln("--) 1993/0/5");
1278 if (!(v == EXPECTED_0610)) errln("Expected " + EXPECTED_0610 + "; saw " + v);
1279 delete calendar;
1280 }
1281 {
1282 Calendar *calendar = new GregorianCalendar(1993, UCAL_JANUARY, 4, status);
1283 if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; }
1284 logln("2A) " + value(calendar));
1285 calendar->add(UCAL_DATE, 1, status);
1286 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
1287 UnicodeString v = value(calendar);
1288 logln("2B) " + v);
1289 logln("--) 1993/0/5");
1290 if (!(v == EXPECTED_0610)) errln("Expected " + EXPECTED_0610 + "; saw " + v);
1291 delete calendar;
1292 }
1293 {
1294 Calendar *calendar = new GregorianCalendar(1993, UCAL_JANUARY, 4, status);
1295 if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; }
1296 logln("3A) " + value(calendar));
1297 calendar->getTime(status);
1298 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; }
1299 calendar->add(UCAL_DATE, 1, status);
1300 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
1301 UnicodeString v = value(calendar);
1302 logln("3B) " + v);
1303 logln("--) 1993/0/5");
1304 if (!(v == EXPECTED_0610)) errln("Expected " + EXPECTED_0610 + "; saw " + v);
1305 delete calendar;
1306 }
1307 }
1308
1309 // -------------------------------------
1310
1311 UnicodeString
value(Calendar * calendar)1312 CalendarTest::value(Calendar* calendar)
1313 {
1314 UErrorCode status = U_ZERO_ERROR;
1315 return UnicodeString("") + (int32_t)calendar->get(UCAL_YEAR, status) +
1316 "/" + (int32_t)calendar->get(UCAL_MONTH, status) +
1317 "/" + (int32_t)calendar->get(UCAL_DATE, status) +
1318 (U_FAILURE(status) ? " FAIL: Calendar::get failed" : "");
1319 }
1320
1321
1322 // -------------------------------------
1323
1324 /**
1325 * Verify that various fields on a known date are set correctly.
1326 */
1327 void
TestFields060()1328 CalendarTest::TestFields060()
1329 {
1330 UErrorCode status = U_ZERO_ERROR;
1331 int32_t year = 1997;
1332 int32_t month = UCAL_OCTOBER;
1333 int32_t dDate = 22;
1334 GregorianCalendar *calendar = 0;
1335 calendar = new GregorianCalendar(year, month, dDate, status);
1336 if (failure(status, "new GregorianCalendar", TRUE)) return;
1337 for (int32_t i = 0; i < EXPECTED_FIELDS_length;) {
1338 UCalendarDateFields field = (UCalendarDateFields)EXPECTED_FIELDS[i++];
1339 int32_t expected = EXPECTED_FIELDS[i++];
1340 if (calendar->get(field, status) != expected) {
1341 errln(UnicodeString("Expected field ") + (int32_t)field + " to have value " + (int32_t)expected +
1342 "; received " + (int32_t)calendar->get(field, status) + " instead");
1343 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
1344 }
1345 }
1346 delete calendar;
1347 }
1348
1349 int32_t CalendarTest::EXPECTED_FIELDS[] = {
1350 UCAL_YEAR, 1997,
1351 UCAL_MONTH, UCAL_OCTOBER,
1352 UCAL_DATE, 22,
1353 UCAL_DAY_OF_WEEK, UCAL_WEDNESDAY,
1354 UCAL_DAY_OF_WEEK_IN_MONTH, 4,
1355 UCAL_DAY_OF_YEAR, 295
1356 };
1357
1358 const int32_t CalendarTest::EXPECTED_FIELDS_length = (int32_t)(sizeof(CalendarTest::EXPECTED_FIELDS) /
1359 sizeof(CalendarTest::EXPECTED_FIELDS[0]));
1360
1361 // -------------------------------------
1362
1363 /**
1364 * Verify that various fields on a known date are set correctly. In this
1365 * case, the start of the epoch (January 1 1970).
1366 */
1367 void
TestEpochStartFields()1368 CalendarTest::TestEpochStartFields()
1369 {
1370 UErrorCode status = U_ZERO_ERROR;
1371 TimeZone *z = TimeZone::createDefault();
1372 Calendar *c = Calendar::createInstance(status);
1373 if (failure(status, "Calendar::createInstance", TRUE)) return;
1374 UDate d = - z->getRawOffset();
1375 GregorianCalendar *gc = new GregorianCalendar(status);
1376 if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; }
1377 gc->setTimeZone(*z);
1378 gc->setTime(d, status);
1379 if (U_FAILURE(status)) { errln("Calendar::setTime failed"); return; }
1380 UBool idt = gc->inDaylightTime(status);
1381 if (U_FAILURE(status)) { errln("GregorianCalendar::inDaylightTime failed"); return; }
1382 if (idt) {
1383 UnicodeString str;
1384 logln("Warning: Skipping test because " + dateToString(d, str) + " is in DST.");
1385 }
1386 else {
1387 c->setTime(d, status);
1388 if (U_FAILURE(status)) { errln("Calendar::setTime failed"); return; }
1389 for (int32_t i = 0; i < UCAL_ZONE_OFFSET;++i) {
1390 if (c->get((UCalendarDateFields)i, status) != EPOCH_FIELDS[i])
1391 dataerrln(UnicodeString("Expected field ") + i + " to have value " + EPOCH_FIELDS[i] +
1392 "; saw " + c->get((UCalendarDateFields)i, status) + " instead");
1393 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
1394 }
1395 if (c->get(UCAL_ZONE_OFFSET, status) != z->getRawOffset())
1396 {
1397 errln(UnicodeString("Expected field ZONE_OFFSET to have value ") + z->getRawOffset() +
1398 "; saw " + c->get(UCAL_ZONE_OFFSET, status) + " instead");
1399 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
1400 }
1401 if (c->get(UCAL_DST_OFFSET, status) != 0)
1402 {
1403 errln(UnicodeString("Expected field DST_OFFSET to have value 0") +
1404 "; saw " + c->get(UCAL_DST_OFFSET, status) + " instead");
1405 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
1406 }
1407 }
1408 delete c;
1409 delete z;
1410 delete gc;
1411 }
1412
1413 int32_t CalendarTest::EPOCH_FIELDS[] = {
1414 1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, - 28800000, 0
1415 };
1416
1417 // -------------------------------------
1418
1419 /**
1420 * Test that the days of the week progress properly when add is called repeatedly
1421 * for increments of 24 days.
1422 */
1423 void
TestDOWProgression()1424 CalendarTest::TestDOWProgression()
1425 {
1426 UErrorCode status = U_ZERO_ERROR;
1427 Calendar *cal = new GregorianCalendar(1972, UCAL_OCTOBER, 26, status);
1428 if (failure(status, "new GregorianCalendar", TRUE)) return;
1429 marchByDelta(cal, 24);
1430 delete cal;
1431 }
1432
1433 // -------------------------------------
1434
1435 void
TestDOW_LOCALandYEAR_WOY()1436 CalendarTest::TestDOW_LOCALandYEAR_WOY()
1437 {
1438 /* Note: I've commented out the loop_addroll tests for YEAR and
1439 * YEAR_WOY below because these two fields should NOT behave
1440 * identically when adding. YEAR should keep the month/dom
1441 * invariant. YEAR_WOY should keep the woy/dow invariant. I've
1442 * added a new test that checks for this in place of the old call
1443 * to loop_addroll. - aliu */
1444 UErrorCode status = U_ZERO_ERROR;
1445 int32_t times = 20;
1446 Calendar *cal=Calendar::createInstance(Locale::getGermany(), status);
1447 if (failure(status, "Calendar::createInstance", TRUE)) return;
1448 SimpleDateFormat *sdf=new SimpleDateFormat(UnicodeString("YYYY'-W'ww-ee"), Locale::getGermany(), status);
1449 if (U_FAILURE(status)) { dataerrln("Couldn't create SimpleDateFormat - %s", u_errorName(status)); return; }
1450
1451 // ICU no longer use localized date-time pattern characters by default.
1452 // So we set pattern chars using 'J' instead of 'Y'.
1453 DateFormatSymbols *dfs = new DateFormatSymbols(Locale::getGermany(), status);
1454 dfs->setLocalPatternChars(UnicodeString("GyMdkHmsSEDFwWahKzJeugAZvcLQq"));
1455 sdf->adoptDateFormatSymbols(dfs);
1456 sdf->applyLocalizedPattern(UnicodeString("JJJJ'-W'ww-ee"), status);
1457 if (U_FAILURE(status)) { errln("Couldn't apply localized pattern"); return; }
1458
1459 cal->clear();
1460 cal->set(1997, UCAL_DECEMBER, 25);
1461 doYEAR_WOYLoop(cal, sdf, times, status);
1462 //loop_addroll(cal, /*sdf,*/ times, UCAL_YEAR_WOY, UCAL_YEAR, status);
1463 yearAddTest(*cal, status); // aliu
1464 loop_addroll(cal, /*sdf,*/ times, UCAL_DOW_LOCAL, UCAL_DAY_OF_WEEK, status);
1465 if (U_FAILURE(status)) { errln("Error in parse/calculate test for 1997"); return; }
1466
1467 cal->clear();
1468 cal->set(1998, UCAL_DECEMBER, 25);
1469 doYEAR_WOYLoop(cal, sdf, times, status);
1470 //loop_addroll(cal, /*sdf,*/ times, UCAL_YEAR_WOY, UCAL_YEAR, status);
1471 yearAddTest(*cal, status); // aliu
1472 loop_addroll(cal, /*sdf,*/ times, UCAL_DOW_LOCAL, UCAL_DAY_OF_WEEK, status);
1473 if (U_FAILURE(status)) { errln("Error in parse/calculate test for 1998"); return; }
1474
1475 cal->clear();
1476 cal->set(1582, UCAL_OCTOBER, 1);
1477 doYEAR_WOYLoop(cal, sdf, times, status);
1478 //loop_addroll(cal, /*sdf,*/ times, Calendar::YEAR_WOY, Calendar::YEAR, status);
1479 yearAddTest(*cal, status); // aliu
1480 loop_addroll(cal, /*sdf,*/ times, UCAL_DOW_LOCAL, UCAL_DAY_OF_WEEK, status);
1481 if (U_FAILURE(status)) { errln("Error in parse/calculate test for 1582"); return; }
1482 delete sdf;
1483 delete cal;
1484
1485 return;
1486 }
1487
1488 /**
1489 * Confirm that adding a YEAR and adding a YEAR_WOY work properly for
1490 * the given Calendar at its current setting.
1491 */
yearAddTest(Calendar & cal,UErrorCode & status)1492 void CalendarTest::yearAddTest(Calendar& cal, UErrorCode& status) {
1493 /**
1494 * When adding the YEAR, the month and day should remain constant.
1495 * When adding the YEAR_WOY, the WOY and DOW should remain constant. - aliu
1496 * Examples:
1497 * Wed Jan 14 1998 / 1998-W03-03 Add(YEAR_WOY, 1) -> Wed Jan 20 1999 / 1999-W03-03
1498 * Add(YEAR, 1) -> Thu Jan 14 1999 / 1999-W02-04
1499 * Thu Jan 14 1999 / 1999-W02-04 Add(YEAR_WOY, 1) -> Thu Jan 13 2000 / 2000-W02-04
1500 * Add(YEAR, 1) -> Fri Jan 14 2000 / 2000-W02-05
1501 * Sun Oct 31 1582 / 1582-W42-07 Add(YEAR_WOY, 1) -> Sun Oct 23 1583 / 1583-W42-07
1502 * Add(YEAR, 1) -> Mon Oct 31 1583 / 1583-W44-01
1503 */
1504 int32_t y = cal.get(UCAL_YEAR, status);
1505 int32_t mon = cal.get(UCAL_MONTH, status);
1506 int32_t day = cal.get(UCAL_DATE, status);
1507 int32_t ywy = cal.get(UCAL_YEAR_WOY, status);
1508 int32_t woy = cal.get(UCAL_WEEK_OF_YEAR, status);
1509 int32_t dow = cal.get(UCAL_DOW_LOCAL, status);
1510 UDate t = cal.getTime(status);
1511
1512 if(U_FAILURE(status)){
1513 errln(UnicodeString("Failed to create Calendar for locale. Error: ") + UnicodeString(u_errorName(status)));
1514 return;
1515 }
1516 UnicodeString str, str2;
1517 SimpleDateFormat fmt(UnicodeString("EEE MMM dd yyyy / YYYY'-W'ww-ee"), status);
1518 fmt.setCalendar(cal);
1519
1520 fmt.format(t, str.remove());
1521 str += ".add(YEAR, 1) =>";
1522 cal.add(UCAL_YEAR, 1, status);
1523 int32_t y2 = cal.get(UCAL_YEAR, status);
1524 int32_t mon2 = cal.get(UCAL_MONTH, status);
1525 int32_t day2 = cal.get(UCAL_DATE, status);
1526 fmt.format(cal.getTime(status), str);
1527 if (y2 != (y+1) || mon2 != mon || day2 != day) {
1528 str += (UnicodeString)", expected year " +
1529 (y+1) + ", month " + (mon+1) + ", day " + day;
1530 errln((UnicodeString)"FAIL: " + str);
1531 logln( UnicodeString(" -> ") + CalendarTest::calToStr(cal) );
1532 } else {
1533 logln(str);
1534 }
1535
1536 fmt.format(t, str.remove());
1537 str += ".add(YEAR_WOY, 1)=>";
1538 cal.setTime(t, status);
1539 logln( UnicodeString(" <- ") + CalendarTest::calToStr(cal) );
1540 cal.add(UCAL_YEAR_WOY, 1, status);
1541 int32_t ywy2 = cal.get(UCAL_YEAR_WOY, status);
1542 int32_t woy2 = cal.get(UCAL_WEEK_OF_YEAR, status);
1543 int32_t dow2 = cal.get(UCAL_DOW_LOCAL, status);
1544 fmt.format(cal.getTime(status), str);
1545 if (ywy2 != (ywy+1) || woy2 != woy || dow2 != dow) {
1546 str += (UnicodeString)", expected yearWOY " +
1547 (ywy+1) + ", woy " + woy + ", dowLocal " + dow;
1548 errln((UnicodeString)"FAIL: " + str);
1549 logln( UnicodeString(" -> ") + CalendarTest::calToStr(cal) );
1550 } else {
1551 logln(str);
1552 }
1553 }
1554
1555 // -------------------------------------
1556
loop_addroll(Calendar * cal,int times,UCalendarDateFields field,UCalendarDateFields field2,UErrorCode & errorCode)1557 void CalendarTest::loop_addroll(Calendar *cal, /*SimpleDateFormat *sdf,*/ int times, UCalendarDateFields field, UCalendarDateFields field2, UErrorCode& errorCode) {
1558 Calendar *calclone;
1559 SimpleDateFormat fmt(UnicodeString("EEE MMM dd yyyy / YYYY'-W'ww-ee"), errorCode);
1560 fmt.setCalendar(*cal);
1561 int i;
1562
1563 for(i = 0; i<times; i++) {
1564 calclone = cal->clone();
1565 UDate start = cal->getTime(errorCode);
1566 cal->add(field,1,errorCode);
1567 if (U_FAILURE(errorCode)) { errln("Error in add"); delete calclone; return; }
1568 calclone->add(field2,1,errorCode);
1569 if (U_FAILURE(errorCode)) { errln("Error in add"); delete calclone; return; }
1570 if(cal->getTime(errorCode) != calclone->getTime(errorCode)) {
1571 UnicodeString str("FAIL: Results of add differ. "), str2;
1572 str += fmt.format(start, str2) + " ";
1573 str += UnicodeString("Add(") + fieldName(field) + ", 1) -> " +
1574 fmt.format(cal->getTime(errorCode), str2.remove()) + "; ";
1575 str += UnicodeString("Add(") + fieldName(field2) + ", 1) -> " +
1576 fmt.format(calclone->getTime(errorCode), str2.remove());
1577 errln(str);
1578 delete calclone;
1579 return;
1580 }
1581 delete calclone;
1582 }
1583
1584 for(i = 0; i<times; i++) {
1585 calclone = cal->clone();
1586 cal->roll(field,(int32_t)1,errorCode);
1587 if (U_FAILURE(errorCode)) { errln("Error in roll"); delete calclone; return; }
1588 calclone->roll(field2,(int32_t)1,errorCode);
1589 if (U_FAILURE(errorCode)) { errln("Error in roll"); delete calclone; return; }
1590 if(cal->getTime(errorCode) != calclone->getTime(errorCode)) {
1591 delete calclone;
1592 errln("Results of roll differ!");
1593 return;
1594 }
1595 delete calclone;
1596 }
1597 }
1598
1599 // -------------------------------------
1600
1601 void
doYEAR_WOYLoop(Calendar * cal,SimpleDateFormat * sdf,int32_t times,UErrorCode & errorCode)1602 CalendarTest::doYEAR_WOYLoop(Calendar *cal, SimpleDateFormat *sdf,
1603 int32_t times, UErrorCode& errorCode) {
1604
1605 UnicodeString us;
1606 UDate tst, original;
1607 Calendar *tstres = new GregorianCalendar(Locale::getGermany(), errorCode);
1608 for(int i=0; i<times; ++i) {
1609 sdf->format(Formattable(cal->getTime(errorCode),Formattable::kIsDate), us, errorCode);
1610 //logln("expected: "+us);
1611 if (U_FAILURE(errorCode)) { errln("Format error"); return; }
1612 tst=sdf->parse(us,errorCode);
1613 if (U_FAILURE(errorCode)) { errln("Parse error"); return; }
1614 tstres->clear();
1615 tstres->setTime(tst, errorCode);
1616 //logln((UnicodeString)"Parsed week of year is "+tstres->get(UCAL_WEEK_OF_YEAR, errorCode));
1617 if (U_FAILURE(errorCode)) { errln("Set time error"); return; }
1618 original = cal->getTime(errorCode);
1619 us.remove();
1620 sdf->format(Formattable(tst,Formattable::kIsDate), us, errorCode);
1621 //logln("got: "+us);
1622 if (U_FAILURE(errorCode)) { errln("Get time error"); return; }
1623 if(original!=tst) {
1624 us.remove();
1625 sdf->format(Formattable(original, Formattable::kIsDate), us, errorCode);
1626 errln("FAIL: Parsed time doesn't match with regular");
1627 logln("expected "+us + " " + calToStr(*cal));
1628 us.remove();
1629 sdf->format(Formattable(tst, Formattable::kIsDate), us, errorCode);
1630 logln("got "+us + " " + calToStr(*tstres));
1631 }
1632 tstres->clear();
1633 tstres->set(UCAL_YEAR_WOY, cal->get(UCAL_YEAR_WOY, errorCode));
1634 tstres->set(UCAL_WEEK_OF_YEAR, cal->get(UCAL_WEEK_OF_YEAR, errorCode));
1635 tstres->set(UCAL_DOW_LOCAL, cal->get(UCAL_DOW_LOCAL, errorCode));
1636 if(cal->get(UCAL_YEAR, errorCode) != tstres->get(UCAL_YEAR, errorCode)) {
1637 errln("FAIL: Different Year!");
1638 logln((UnicodeString)"Expected "+cal->get(UCAL_YEAR, errorCode));
1639 logln((UnicodeString)"Got "+tstres->get(UCAL_YEAR, errorCode));
1640 return;
1641 }
1642 if(cal->get(UCAL_DAY_OF_YEAR, errorCode) != tstres->get(UCAL_DAY_OF_YEAR, errorCode)) {
1643 errln("FAIL: Different Day Of Year!");
1644 logln((UnicodeString)"Expected "+cal->get(UCAL_DAY_OF_YEAR, errorCode));
1645 logln((UnicodeString)"Got "+tstres->get(UCAL_DAY_OF_YEAR, errorCode));
1646 return;
1647 }
1648 //logln(calToStr(*cal));
1649 cal->add(UCAL_DATE, 1, errorCode);
1650 if (U_FAILURE(errorCode)) { errln("Add error"); return; }
1651 us.remove();
1652 }
1653 delete (tstres);
1654 }
1655 // -------------------------------------
1656
1657 void
marchByDelta(Calendar * cal,int32_t delta)1658 CalendarTest::marchByDelta(Calendar* cal, int32_t delta)
1659 {
1660 UErrorCode status = U_ZERO_ERROR;
1661 Calendar *cur = (Calendar*) cal->clone();
1662 int32_t initialDOW = cur->get(UCAL_DAY_OF_WEEK, status);
1663 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
1664 int32_t DOW, newDOW = initialDOW;
1665 do {
1666 UnicodeString str;
1667 DOW = newDOW;
1668 logln(UnicodeString("DOW = ") + DOW + " " + dateToString(cur->getTime(status), str));
1669 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; }
1670 cur->add(UCAL_DAY_OF_WEEK, delta, status);
1671 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
1672 newDOW = cur->get(UCAL_DAY_OF_WEEK, status);
1673 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
1674 int32_t expectedDOW = 1 + (DOW + delta - 1) % 7;
1675 if (newDOW != expectedDOW) {
1676 errln(UnicodeString("Day of week should be ") + expectedDOW + " instead of " + newDOW +
1677 " on " + dateToString(cur->getTime(status), str));
1678 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; }
1679 return;
1680 }
1681 }
1682 while (newDOW != initialDOW);
1683 delete cur;
1684 }
1685
1686 #define CHECK(status, msg) \
1687 if (U_FAILURE(status)) { \
1688 errcheckln(status, msg); \
1689 return; \
1690 }
1691
TestWOY(void)1692 void CalendarTest::TestWOY(void) {
1693 /*
1694 FDW = Mon, MDFW = 4:
1695 Sun Dec 26 1999, WOY 51
1696 Mon Dec 27 1999, WOY 52
1697 Tue Dec 28 1999, WOY 52
1698 Wed Dec 29 1999, WOY 52
1699 Thu Dec 30 1999, WOY 52
1700 Fri Dec 31 1999, WOY 52
1701 Sat Jan 01 2000, WOY 52 ***
1702 Sun Jan 02 2000, WOY 52 ***
1703 Mon Jan 03 2000, WOY 1
1704 Tue Jan 04 2000, WOY 1
1705 Wed Jan 05 2000, WOY 1
1706 Thu Jan 06 2000, WOY 1
1707 Fri Jan 07 2000, WOY 1
1708 Sat Jan 08 2000, WOY 1
1709 Sun Jan 09 2000, WOY 1
1710 Mon Jan 10 2000, WOY 2
1711
1712 FDW = Mon, MDFW = 2:
1713 Sun Dec 26 1999, WOY 52
1714 Mon Dec 27 1999, WOY 1 ***
1715 Tue Dec 28 1999, WOY 1 ***
1716 Wed Dec 29 1999, WOY 1 ***
1717 Thu Dec 30 1999, WOY 1 ***
1718 Fri Dec 31 1999, WOY 1 ***
1719 Sat Jan 01 2000, WOY 1
1720 Sun Jan 02 2000, WOY 1
1721 Mon Jan 03 2000, WOY 2
1722 Tue Jan 04 2000, WOY 2
1723 Wed Jan 05 2000, WOY 2
1724 Thu Jan 06 2000, WOY 2
1725 Fri Jan 07 2000, WOY 2
1726 Sat Jan 08 2000, WOY 2
1727 Sun Jan 09 2000, WOY 2
1728 Mon Jan 10 2000, WOY 3
1729 */
1730
1731 UnicodeString str;
1732 UErrorCode status = U_ZERO_ERROR;
1733 int32_t i;
1734
1735 GregorianCalendar cal(status);
1736 SimpleDateFormat fmt(UnicodeString("EEE MMM dd yyyy', WOY' w"), status);
1737 if (failure(status, "Cannot construct calendar/format", TRUE)) return;
1738
1739 UCalendarDaysOfWeek fdw = (UCalendarDaysOfWeek) 0;
1740
1741 //for (int8_t pass=2; pass<=2; ++pass) {
1742 for (int8_t pass=1; pass<=2; ++pass) {
1743 switch (pass) {
1744 case 1:
1745 fdw = UCAL_MONDAY;
1746 cal.setFirstDayOfWeek(fdw);
1747 cal.setMinimalDaysInFirstWeek(4);
1748 fmt.adoptCalendar(cal.clone());
1749 break;
1750 case 2:
1751 fdw = UCAL_MONDAY;
1752 cal.setFirstDayOfWeek(fdw);
1753 cal.setMinimalDaysInFirstWeek(2);
1754 fmt.adoptCalendar(cal.clone());
1755 break;
1756 }
1757
1758 //for (i=2; i<=6; ++i) {
1759 for (i=0; i<16; ++i) {
1760 UDate t, t2;
1761 int32_t t_y, t_woy, t_dow;
1762 cal.clear();
1763 cal.set(1999, UCAL_DECEMBER, 26 + i);
1764 fmt.format(t = cal.getTime(status), str.remove());
1765 CHECK(status, "Fail: getTime failed");
1766 logln(UnicodeString("* ") + str);
1767 int32_t dow = cal.get(UCAL_DAY_OF_WEEK, status);
1768 int32_t woy = cal.get(UCAL_WEEK_OF_YEAR, status);
1769 int32_t year = cal.get(UCAL_YEAR, status);
1770 int32_t mon = cal.get(UCAL_MONTH, status);
1771 logln(calToStr(cal));
1772 CHECK(status, "Fail: get failed");
1773 int32_t dowLocal = dow - fdw;
1774 if (dowLocal < 0) dowLocal += 7;
1775 dowLocal++;
1776 int32_t yearWoy = year;
1777 if (mon == UCAL_JANUARY) {
1778 if (woy >= 52) --yearWoy;
1779 } else {
1780 if (woy == 1) ++yearWoy;
1781 }
1782
1783 // Basic fields->time check y/woy/dow
1784 // Since Y/WOY is ambiguous, we do a check of the fields,
1785 // not of the specific time.
1786 cal.clear();
1787 cal.set(UCAL_YEAR, year);
1788 cal.set(UCAL_WEEK_OF_YEAR, woy);
1789 cal.set(UCAL_DAY_OF_WEEK, dow);
1790 t_y = cal.get(UCAL_YEAR, status);
1791 t_woy = cal.get(UCAL_WEEK_OF_YEAR, status);
1792 t_dow = cal.get(UCAL_DAY_OF_WEEK, status);
1793 CHECK(status, "Fail: get failed");
1794 if (t_y != year || t_woy != woy || t_dow != dow) {
1795 str = "Fail: y/woy/dow fields->time => ";
1796 fmt.format(cal.getTime(status), str);
1797 errln(str);
1798 logln(calToStr(cal));
1799 logln("[get!=set] Y%d!=%d || woy%d!=%d || dow%d!=%d\n",
1800 t_y, year, t_woy, woy, t_dow, dow);
1801 } else {
1802 logln("y/woy/dow fields->time OK");
1803 }
1804
1805 // Basic fields->time check y/woy/dow_local
1806 // Since Y/WOY is ambiguous, we do a check of the fields,
1807 // not of the specific time.
1808 cal.clear();
1809 cal.set(UCAL_YEAR, year);
1810 cal.set(UCAL_WEEK_OF_YEAR, woy);
1811 cal.set(UCAL_DOW_LOCAL, dowLocal);
1812 t_y = cal.get(UCAL_YEAR, status);
1813 t_woy = cal.get(UCAL_WEEK_OF_YEAR, status);
1814 t_dow = cal.get(UCAL_DOW_LOCAL, status);
1815 CHECK(status, "Fail: get failed");
1816 if (t_y != year || t_woy != woy || t_dow != dowLocal) {
1817 str = "Fail: y/woy/dow_local fields->time => ";
1818 fmt.format(cal.getTime(status), str);
1819 errln(str);
1820 }
1821
1822 // Basic fields->time check y_woy/woy/dow
1823 cal.clear();
1824 cal.set(UCAL_YEAR_WOY, yearWoy);
1825 cal.set(UCAL_WEEK_OF_YEAR, woy);
1826 cal.set(UCAL_DAY_OF_WEEK, dow);
1827 t2 = cal.getTime(status);
1828 CHECK(status, "Fail: getTime failed");
1829 if (t != t2) {
1830 str = "Fail: y_woy/woy/dow fields->time => ";
1831 fmt.format(t2, str);
1832 errln(str);
1833 logln(calToStr(cal));
1834 logln("%.f != %.f\n", t, t2);
1835 } else {
1836 logln("y_woy/woy/dow OK");
1837 }
1838
1839 // Basic fields->time check y_woy/woy/dow_local
1840 cal.clear();
1841 cal.set(UCAL_YEAR_WOY, yearWoy);
1842 cal.set(UCAL_WEEK_OF_YEAR, woy);
1843 cal.set(UCAL_DOW_LOCAL, dowLocal);
1844 t2 = cal.getTime(status);
1845 CHECK(status, "Fail: getTime failed");
1846 if (t != t2) {
1847 str = "Fail: y_woy/woy/dow_local fields->time => ";
1848 fmt.format(t2, str);
1849 errln(str);
1850 }
1851
1852 logln("Testing DOW_LOCAL.. dow%d\n", dow);
1853 // Make sure DOW_LOCAL disambiguates over DOW
1854 int32_t wrongDow = dow - 3;
1855 if (wrongDow < 1) wrongDow += 7;
1856 cal.setTime(t, status);
1857 cal.set(UCAL_DAY_OF_WEEK, wrongDow);
1858 cal.set(UCAL_DOW_LOCAL, dowLocal);
1859 t2 = cal.getTime(status);
1860 CHECK(status, "Fail: set/getTime failed");
1861 if (t != t2) {
1862 str = "Fail: DOW_LOCAL fields->time => ";
1863 fmt.format(t2, str);
1864 errln(str);
1865 logln(calToStr(cal));
1866 logln("%.f : DOW%d, DOW_LOCAL%d -> %.f\n",
1867 t, wrongDow, dowLocal, t2);
1868 }
1869
1870 // Make sure DOW disambiguates over DOW_LOCAL
1871 int32_t wrongDowLocal = dowLocal - 3;
1872 if (wrongDowLocal < 1) wrongDowLocal += 7;
1873 cal.setTime(t, status);
1874 cal.set(UCAL_DOW_LOCAL, wrongDowLocal);
1875 cal.set(UCAL_DAY_OF_WEEK, dow);
1876 t2 = cal.getTime(status);
1877 CHECK(status, "Fail: set/getTime failed");
1878 if (t != t2) {
1879 str = "Fail: DOW fields->time => ";
1880 fmt.format(t2, str);
1881 errln(str);
1882 }
1883
1884 // Make sure YEAR_WOY disambiguates over YEAR
1885 cal.setTime(t, status);
1886 cal.set(UCAL_YEAR, year - 2);
1887 cal.set(UCAL_YEAR_WOY, yearWoy);
1888 t2 = cal.getTime(status);
1889 CHECK(status, "Fail: set/getTime failed");
1890 if (t != t2) {
1891 str = "Fail: YEAR_WOY fields->time => ";
1892 fmt.format(t2, str);
1893 errln(str);
1894 }
1895
1896 // Make sure YEAR disambiguates over YEAR_WOY
1897 cal.setTime(t, status);
1898 cal.set(UCAL_YEAR_WOY, yearWoy - 2);
1899 cal.set(UCAL_YEAR, year);
1900 t2 = cal.getTime(status);
1901 CHECK(status, "Fail: set/getTime failed");
1902 if (t != t2) {
1903 str = "Fail: YEAR fields->time => ";
1904 fmt.format(t2, str);
1905 errln(str);
1906 }
1907 }
1908 }
1909
1910 /*
1911 FDW = Mon, MDFW = 4:
1912 Sun Dec 26 1999, WOY 51
1913 Mon Dec 27 1999, WOY 52
1914 Tue Dec 28 1999, WOY 52
1915 Wed Dec 29 1999, WOY 52
1916 Thu Dec 30 1999, WOY 52
1917 Fri Dec 31 1999, WOY 52
1918 Sat Jan 01 2000, WOY 52
1919 Sun Jan 02 2000, WOY 52
1920 */
1921
1922 // Roll the DOW_LOCAL within week 52
1923 for (i=27; i<=33; ++i) {
1924 int32_t amount;
1925 for (amount=-7; amount<=7; ++amount) {
1926 str = "roll(";
1927 cal.set(1999, UCAL_DECEMBER, i);
1928 UDate t, t2;
1929 fmt.format(cal.getTime(status), str);
1930 CHECK(status, "Fail: getTime failed");
1931 str += UnicodeString(", ") + amount + ") = ";
1932
1933 cal.roll(UCAL_DOW_LOCAL, amount, status);
1934 CHECK(status, "Fail: roll failed");
1935
1936 t = cal.getTime(status);
1937 int32_t newDom = i + amount;
1938 while (newDom < 27) newDom += 7;
1939 while (newDom > 33) newDom -= 7;
1940 cal.set(1999, UCAL_DECEMBER, newDom);
1941 t2 = cal.getTime(status);
1942 CHECK(status, "Fail: getTime failed");
1943 fmt.format(t, str);
1944
1945 if (t != t2) {
1946 str.append(", exp ");
1947 fmt.format(t2, str);
1948 errln(str);
1949 } else {
1950 logln(str);
1951 }
1952 }
1953 }
1954 }
1955
TestYWOY()1956 void CalendarTest::TestYWOY()
1957 {
1958 UnicodeString str;
1959 UErrorCode status = U_ZERO_ERROR;
1960
1961 GregorianCalendar cal(status);
1962 if (failure(status, "construct GregorianCalendar", TRUE)) return;
1963
1964 cal.setFirstDayOfWeek(UCAL_SUNDAY);
1965 cal.setMinimalDaysInFirstWeek(1);
1966
1967 logln("Setting: ywoy=2004, woy=1, dow=MONDAY");
1968 cal.clear();
1969 cal.set(UCAL_YEAR_WOY,2004);
1970 cal.set(UCAL_WEEK_OF_YEAR,1);
1971 cal.set(UCAL_DAY_OF_WEEK, UCAL_MONDAY);
1972
1973 logln(calToStr(cal));
1974 if(cal.get(UCAL_YEAR, status) != 2003) {
1975 errln("year not 2003");
1976 }
1977
1978 logln("+ setting DOW to THURSDAY");
1979 cal.clear();
1980 cal.set(UCAL_YEAR_WOY,2004);
1981 cal.set(UCAL_WEEK_OF_YEAR,1);
1982 cal.set(UCAL_DAY_OF_WEEK, UCAL_THURSDAY);
1983
1984 logln(calToStr(cal));
1985 if(cal.get(UCAL_YEAR, status) != 2004) {
1986 errln("year not 2004");
1987 }
1988
1989 logln("+ setting DOW_LOCAL to 1");
1990 cal.clear();
1991 cal.set(UCAL_YEAR_WOY,2004);
1992 cal.set(UCAL_WEEK_OF_YEAR,1);
1993 cal.set(UCAL_DAY_OF_WEEK, UCAL_THURSDAY);
1994 cal.set(UCAL_DOW_LOCAL, 1);
1995
1996 logln(calToStr(cal));
1997 if(cal.get(UCAL_YEAR, status) != 2003) {
1998 errln("year not 2003");
1999 }
2000
2001 cal.setFirstDayOfWeek(UCAL_MONDAY);
2002 cal.setMinimalDaysInFirstWeek(4);
2003 UDate t = 946713600000.;
2004 cal.setTime(t, status);
2005 cal.set(UCAL_DAY_OF_WEEK, 4);
2006 cal.set(UCAL_DOW_LOCAL, 6);
2007 if(cal.getTime(status) != t) {
2008 logln(calToStr(cal));
2009 errln("FAIL: DOW_LOCAL did not take precedence");
2010 }
2011
2012 }
2013
TestJD()2014 void CalendarTest::TestJD()
2015 {
2016 int32_t jd;
2017 static const int32_t kEpochStartAsJulianDay = 2440588;
2018 UErrorCode status = U_ZERO_ERROR;
2019 GregorianCalendar cal(status);
2020 if (failure(status, "construct GregorianCalendar", TRUE)) return;
2021 cal.setTimeZone(*TimeZone::getGMT());
2022 cal.clear();
2023 jd = cal.get(UCAL_JULIAN_DAY, status);
2024 if(jd != kEpochStartAsJulianDay) {
2025 errln("Wanted JD of %d at time=0, [epoch 1970] but got %d\n", kEpochStartAsJulianDay, jd);
2026 } else {
2027 logln("Wanted JD of %d at time=0, [epoch 1970], got %d\n", kEpochStartAsJulianDay, jd);
2028 }
2029
2030 cal.setTime(Calendar::getNow(), status);
2031 cal.clear();
2032 cal.set(UCAL_JULIAN_DAY, kEpochStartAsJulianDay);
2033 UDate epochTime = cal.getTime(status);
2034 if(epochTime != 0) {
2035 errln("Wanted time of 0 at jd=%d, got %.1lf\n", kEpochStartAsJulianDay, epochTime);
2036 } else {
2037 logln("Wanted time of 0 at jd=%d, got %.1lf\n", kEpochStartAsJulianDay, epochTime);
2038 }
2039
2040 }
2041
2042 // make sure the ctestfw utilities are in sync with the Calendar
TestDebug()2043 void CalendarTest::TestDebug()
2044 {
2045 for(int32_t t=0;t<=UDBG_ENUM_COUNT;t++) {
2046 int32_t count = udbg_enumCount((UDebugEnumType)t);
2047 if(count == -1) {
2048 logln("enumCount(%d) returned -1", count);
2049 continue;
2050 }
2051 for(int32_t i=0;i<=count;i++) {
2052 if(t<=UDBG_HIGHEST_CONTIGUOUS_ENUM && i<count) {
2053 if( i!=udbg_enumArrayValue((UDebugEnumType)t, i)) {
2054 errln("FAIL: udbg_enumArrayValue(%d,%d) returned %d, expected %d", t, i, udbg_enumArrayValue((UDebugEnumType)t,i), i);
2055 }
2056 } else {
2057 logln("Testing count+1:");
2058 }
2059 const char *name = udbg_enumName((UDebugEnumType)t,i);
2060 if(name==NULL) {
2061 if(i==count || t>UDBG_HIGHEST_CONTIGUOUS_ENUM ) {
2062 logln(" null name - expected.\n");
2063 } else {
2064 errln("FAIL: udbg_enumName(%d,%d) returned NULL", t, i);
2065 }
2066 name = "(null)";
2067 }
2068 logln("udbg_enumArrayValue(%d,%d) = %s, returned %d", t, i,
2069 name, udbg_enumArrayValue((UDebugEnumType)t,i));
2070 logln("udbg_enumString = " + udbg_enumString((UDebugEnumType)t,i));
2071 }
2072 if(udbg_enumExpectedCount((UDebugEnumType)t) != count && t<=UDBG_HIGHEST_CONTIGUOUS_ENUM) {
2073 errln("FAIL: udbg_enumExpectedCount(%d): %d, != UCAL_FIELD_COUNT=%d ", t, udbg_enumExpectedCount((UDebugEnumType)t), count);
2074 } else {
2075 logln("udbg_ucal_fieldCount: %d, UCAL_FIELD_COUNT=udbg_enumCount %d ", udbg_enumExpectedCount((UDebugEnumType)t), count);
2076 }
2077 }
2078 }
2079
2080
2081 #undef CHECK
2082
2083 // List of interesting locales
testLocaleID(int32_t i)2084 const char *CalendarTest::testLocaleID(int32_t i)
2085 {
2086 switch(i) {
2087 case 0: return "he_IL@calendar=hebrew";
2088 case 1: return "en_US@calendar=hebrew";
2089 case 2: return "fr_FR@calendar=hebrew";
2090 case 3: return "fi_FI@calendar=hebrew";
2091 case 4: return "nl_NL@calendar=hebrew";
2092 case 5: return "hu_HU@calendar=hebrew";
2093 case 6: return "nl_BE@currency=MTL;calendar=islamic";
2094 case 7: return "th_TH_TRADITIONAL@calendar=gregorian";
2095 case 8: return "ar_JO@calendar=islamic-civil";
2096 case 9: return "fi_FI@calendar=islamic";
2097 case 10: return "fr_CH@calendar=islamic-civil";
2098 case 11: return "he_IL@calendar=islamic-civil";
2099 case 12: return "hu_HU@calendar=buddhist";
2100 case 13: return "hu_HU@calendar=islamic";
2101 case 14: return "en_US@calendar=japanese";
2102 default: return NULL;
2103 }
2104 }
2105
testLocaleCount()2106 int32_t CalendarTest::testLocaleCount()
2107 {
2108 static int32_t gLocaleCount = -1;
2109 if(gLocaleCount < 0) {
2110 int32_t i;
2111 for(i=0;testLocaleID(i) != NULL;i++) {
2112 ;
2113 }
2114 gLocaleCount = i;
2115 }
2116 return gLocaleCount;
2117 }
2118
doMinDateOfCalendar(Calendar * adopt,UBool & isGregorian,UErrorCode & status)2119 static UDate doMinDateOfCalendar(Calendar* adopt, UBool &isGregorian, UErrorCode& status) {
2120 if(U_FAILURE(status)) return 0.0;
2121
2122 adopt->clear();
2123 adopt->set(UCAL_EXTENDED_YEAR, adopt->getActualMinimum(UCAL_EXTENDED_YEAR, status));
2124 UDate ret = adopt->getTime(status);
2125 isGregorian = dynamic_cast<GregorianCalendar*>(adopt) != NULL;
2126 delete adopt;
2127 return ret;
2128 }
2129
minDateOfCalendar(const Locale & locale,UBool & isGregorian,UErrorCode & status)2130 UDate CalendarTest::minDateOfCalendar(const Locale& locale, UBool &isGregorian, UErrorCode& status) {
2131 if(U_FAILURE(status)) return 0.0;
2132 return doMinDateOfCalendar(Calendar::createInstance(locale, status), isGregorian, status);
2133 }
2134
minDateOfCalendar(const Calendar & cal,UBool & isGregorian,UErrorCode & status)2135 UDate CalendarTest::minDateOfCalendar(const Calendar& cal, UBool &isGregorian, UErrorCode& status) {
2136 if(U_FAILURE(status)) return 0.0;
2137 return doMinDateOfCalendar(cal.clone(), isGregorian, status);
2138 }
2139
Test6703()2140 void CalendarTest::Test6703()
2141 {
2142 UErrorCode status = U_ZERO_ERROR;
2143 Calendar *cal;
2144
2145 Locale loc1("en@calendar=fubar");
2146 cal = Calendar::createInstance(loc1, status);
2147 if (failure(status, "Calendar::createInstance", TRUE)) return;
2148 delete cal;
2149
2150 status = U_ZERO_ERROR;
2151 Locale loc2("en");
2152 cal = Calendar::createInstance(loc2, status);
2153 if (failure(status, "Calendar::createInstance")) return;
2154 delete cal;
2155
2156 status = U_ZERO_ERROR;
2157 Locale loc3("en@calendar=roc");
2158 cal = Calendar::createInstance(loc3, status);
2159 if (failure(status, "Calendar::createInstance")) return;
2160 delete cal;
2161
2162 return;
2163 }
2164
Test3785()2165 void CalendarTest::Test3785()
2166 {
2167 UErrorCode status = U_ZERO_ERROR;
2168 UnicodeString uzone = UNICODE_STRING_SIMPLE("Europe/Paris");
2169 UnicodeString exp1 = UNICODE_STRING_SIMPLE("Mon 30 Jumada II 1433 AH, 01:47:03");
2170 UnicodeString exp2 = UNICODE_STRING_SIMPLE("Mon 1 Rajab 1433 AH, 01:47:04");
2171
2172 LocalUDateFormatPointer df(udat_open(UDAT_NONE, UDAT_NONE, "en@calendar=islamic", uzone.getTerminatedBuffer(),
2173 uzone.length(), NULL, 0, &status));
2174 if (df.isNull() || U_FAILURE(status)) return;
2175
2176 UChar upattern[64];
2177 u_uastrcpy(upattern, "EEE d MMMM y G, HH:mm:ss");
2178 udat_applyPattern(df.getAlias(), FALSE, upattern, u_strlen(upattern));
2179
2180 UChar ubuffer[1024];
2181 UDate ud0 = 1337557623000.0;
2182
2183 status = U_ZERO_ERROR;
2184 udat_format(df.getAlias(), ud0, ubuffer, 1024, NULL, &status);
2185 if (U_FAILURE(status)) {
2186 errln("Error formatting date 1\n");
2187 return;
2188 }
2189 //printf("formatted: '%s'\n", mkcstr(ubuffer));
2190
2191 UnicodeString act1(ubuffer);
2192 if ( act1 != exp1 ) {
2193 errln("Unexpected result from date 1 format\n");
2194 }
2195 ud0 += 1000.0; // add one second
2196
2197 status = U_ZERO_ERROR;
2198 udat_format(df.getAlias(), ud0, ubuffer, 1024, NULL, &status);
2199 if (U_FAILURE(status)) {
2200 errln("Error formatting date 2\n");
2201 return;
2202 }
2203 //printf("formatted: '%s'\n", mkcstr(ubuffer));
2204 UnicodeString act2(ubuffer);
2205 if ( act2 != exp2 ) {
2206 errln("Unexpected result from date 2 format\n");
2207 }
2208
2209 return;
2210 }
2211
Test1624()2212 void CalendarTest::Test1624() {
2213 UErrorCode status = U_ZERO_ERROR;
2214 Locale loc("he_IL@calendar=hebrew");
2215 HebrewCalendar hc(loc,status);
2216
2217 for (int32_t year = 5600; year < 5800; year++ ) {
2218
2219 for (int32_t month = HebrewCalendar::TISHRI; month <= HebrewCalendar::ELUL; month++) {
2220 // skip the adar 1 month if year is not a leap year
2221 if (HebrewCalendar::isLeapYear(year) == FALSE && month == HebrewCalendar::ADAR_1) {
2222 continue;
2223 }
2224 int32_t day = 15;
2225 hc.set(year,month,day);
2226 int32_t dayHC = hc.get(UCAL_DATE,status);
2227 int32_t monthHC = hc.get(UCAL_MONTH,status);
2228 int32_t yearHC = hc.get(UCAL_YEAR,status);
2229
2230 if (failure(status, "HebrewCalendar.get()", TRUE)) continue;
2231
2232 if (dayHC != day) {
2233 errln(" ==> day %d incorrect, should be: %d\n",dayHC,day);
2234 break;
2235 }
2236 if (monthHC != month) {
2237 errln(" ==> month %d incorrect, should be: %d\n",monthHC,month);
2238 break;
2239 }
2240 if (yearHC != year) {
2241 errln(" ==> day %d incorrect, should be: %d\n",yearHC,year);
2242 break;
2243 }
2244 }
2245 }
2246 return;
2247 }
2248
TestTimeStamp()2249 void CalendarTest::TestTimeStamp() {
2250 UErrorCode status = U_ZERO_ERROR;
2251 UDate start = 0.0, time;
2252 Calendar *cal;
2253
2254 // Create a new Gregorian Calendar.
2255 cal = Calendar::createInstance("en_US@calender=gregorian", status);
2256 if (U_FAILURE(status)) {
2257 dataerrln("Error creating Gregorian calendar.");
2258 return;
2259 }
2260
2261 for (int i = 0; i < 20000; i++) {
2262 // Set the Gregorian Calendar to a specific date for testing.
2263 cal->set(2009, UCAL_JULY, 3, 0, 49, 46);
2264
2265 time = cal->getTime(status);
2266 if (U_FAILURE(status)) {
2267 errln("Error calling getTime()");
2268 break;
2269 }
2270
2271 if (i == 0) {
2272 start = time;
2273 } else {
2274 if (start != time) {
2275 errln("start and time not equal.");
2276 break;
2277 }
2278 }
2279 }
2280
2281 delete cal;
2282 }
2283
TestISO8601()2284 void CalendarTest::TestISO8601() {
2285 const char* TEST_LOCALES[] = {
2286 "en_US@calendar=iso8601",
2287 "en_US@calendar=Iso8601",
2288 "th_TH@calendar=iso8601",
2289 "ar_EG@calendar=iso8601",
2290 NULL
2291 };
2292
2293 int32_t TEST_DATA[][3] = {
2294 {2008, 1, 2008},
2295 {2009, 1, 2009},
2296 {2010, 53, 2009},
2297 {2011, 52, 2010},
2298 {2012, 52, 2011},
2299 {2013, 1, 2013},
2300 {2014, 1, 2014},
2301 {0, 0, 0},
2302 };
2303
2304 for (int i = 0; TEST_LOCALES[i] != NULL; i++) {
2305 UErrorCode status = U_ZERO_ERROR;
2306 Calendar *cal = Calendar::createInstance(TEST_LOCALES[i], status);
2307 if (U_FAILURE(status)) {
2308 errln("Error: Failed to create a calendar for locale: %s", TEST_LOCALES[i]);
2309 continue;
2310 }
2311 if (uprv_strcmp(cal->getType(), "gregorian") != 0) {
2312 errln("Error: Gregorian calendar is not used for locale: %s", TEST_LOCALES[i]);
2313 continue;
2314 }
2315 for (int j = 0; TEST_DATA[j][0] != 0; j++) {
2316 cal->set(TEST_DATA[j][0], UCAL_JANUARY, 1);
2317 int32_t weekNum = cal->get(UCAL_WEEK_OF_YEAR, status);
2318 int32_t weekYear = cal->get(UCAL_YEAR_WOY, status);
2319 if (U_FAILURE(status)) {
2320 errln("Error: Failed to get week of year");
2321 break;
2322 }
2323 if (weekNum != TEST_DATA[j][1] || weekYear != TEST_DATA[j][2]) {
2324 errln("Error: Incorrect week of year on January 1st, %d for locale %s: Returned [weekNum=%d, weekYear=%d], Expected [weekNum=%d, weekYear=%d]",
2325 TEST_DATA[j][0], TEST_LOCALES[i], weekNum, weekYear, TEST_DATA[j][1], TEST_DATA[j][2]);
2326 }
2327 }
2328 delete cal;
2329 }
2330
2331 }
2332
2333 void
TestAmbiguousWallTimeAPIs(void)2334 CalendarTest::TestAmbiguousWallTimeAPIs(void) {
2335 UErrorCode status = U_ZERO_ERROR;
2336 Calendar* cal = Calendar::createInstance(status);
2337 if (U_FAILURE(status)) {
2338 errln("Fail: Error creating a calendar instance.");
2339 return;
2340 }
2341
2342 if (cal->getRepeatedWallTimeOption() != UCAL_WALLTIME_LAST) {
2343 errln("Fail: Default repeted time option is not UCAL_WALLTIME_LAST");
2344 }
2345 if (cal->getSkippedWallTimeOption() != UCAL_WALLTIME_LAST) {
2346 errln("Fail: Default skipped time option is not UCAL_WALLTIME_LAST");
2347 }
2348
2349 Calendar* cal2 = cal->clone();
2350
2351 if (*cal != *cal2) {
2352 errln("Fail: Cloned calendar != the original");
2353 }
2354 if (!cal->equals(*cal2, status)) {
2355 errln("Fail: The time of cloned calendar is not equal to the original");
2356 } else if (U_FAILURE(status)) {
2357 errln("Fail: Error equals");
2358 }
2359 status = U_ZERO_ERROR;
2360
2361 cal2->setRepeatedWallTimeOption(UCAL_WALLTIME_FIRST);
2362 cal2->setSkippedWallTimeOption(UCAL_WALLTIME_FIRST);
2363
2364 if (*cal == *cal2) {
2365 errln("Fail: Cloned and modified calendar == the original");
2366 }
2367 if (!cal->equals(*cal2, status)) {
2368 errln("Fail: The time of cloned calendar is not equal to the original after changing wall time options");
2369 } else if (U_FAILURE(status)) {
2370 errln("Fail: Error equals after changing wall time options");
2371 }
2372 status = U_ZERO_ERROR;
2373
2374 if (cal2->getRepeatedWallTimeOption() != UCAL_WALLTIME_FIRST) {
2375 errln("Fail: Repeted time option is not UCAL_WALLTIME_FIRST");
2376 }
2377 if (cal2->getSkippedWallTimeOption() != UCAL_WALLTIME_FIRST) {
2378 errln("Fail: Skipped time option is not UCAL_WALLTIME_FIRST");
2379 }
2380
2381 cal2->setRepeatedWallTimeOption(UCAL_WALLTIME_NEXT_VALID);
2382 if (cal2->getRepeatedWallTimeOption() != UCAL_WALLTIME_FIRST) {
2383 errln("Fail: Repeated wall time option was updated other than UCAL_WALLTIME_FIRST");
2384 }
2385
2386 delete cal;
2387 delete cal2;
2388 }
2389
2390 class CalFields {
2391 public:
2392 CalFields(int32_t year, int32_t month, int32_t day, int32_t hour, int32_t min, int32_t sec);
2393 CalFields(const Calendar& cal, UErrorCode& status);
2394 void setTo(Calendar& cal) const;
2395 char* toString(char* buf, int32_t len) const;
2396 UBool operator==(const CalFields& rhs) const;
2397 UBool operator!=(const CalFields& rhs) const;
2398
2399 private:
2400 int32_t year;
2401 int32_t month;
2402 int32_t day;
2403 int32_t hour;
2404 int32_t min;
2405 int32_t sec;
2406 };
2407
CalFields(int32_t year,int32_t month,int32_t day,int32_t hour,int32_t min,int32_t sec)2408 CalFields::CalFields(int32_t year, int32_t month, int32_t day, int32_t hour, int32_t min, int32_t sec)
2409 : year(year), month(month), day(day), hour(hour), min(min), sec(sec) {
2410 }
2411
CalFields(const Calendar & cal,UErrorCode & status)2412 CalFields::CalFields(const Calendar& cal, UErrorCode& status) {
2413 year = cal.get(UCAL_YEAR, status);
2414 month = cal.get(UCAL_MONTH, status) + 1;
2415 day = cal.get(UCAL_DAY_OF_MONTH, status);
2416 hour = cal.get(UCAL_HOUR_OF_DAY, status);
2417 min = cal.get(UCAL_MINUTE, status);
2418 sec = cal.get(UCAL_SECOND, status);
2419 }
2420
2421 void
setTo(Calendar & cal) const2422 CalFields::setTo(Calendar& cal) const {
2423 cal.clear();
2424 cal.set(year, month - 1, day, hour, min, sec);
2425 }
2426
2427 char*
toString(char * buf,int32_t len) const2428 CalFields::toString(char* buf, int32_t len) const {
2429 char local[32];
2430 sprintf(local, "%04d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, min, sec);
2431 uprv_strncpy(buf, local, len - 1);
2432 buf[len - 1] = 0;
2433 return buf;
2434 }
2435
2436 UBool
operator ==(const CalFields & rhs) const2437 CalFields::operator==(const CalFields& rhs) const {
2438 return year == rhs.year
2439 && month == rhs.month
2440 && day == rhs.day
2441 && hour == rhs.hour
2442 && min == rhs.min
2443 && sec == rhs.sec;
2444 }
2445
2446 UBool
operator !=(const CalFields & rhs) const2447 CalFields::operator!=(const CalFields& rhs) const {
2448 return !(*this == rhs);
2449 }
2450
2451 typedef struct {
2452 const char* tzid;
2453 const CalFields in;
2454 const CalFields expLastGMT;
2455 const CalFields expFirstGMT;
2456 } RepeatedWallTimeTestData;
2457
2458 static const RepeatedWallTimeTestData RPDATA[] =
2459 {
2460 // Time zone Input wall time WALLTIME_LAST in GMT WALLTIME_FIRST in GMT
2461 {"America/New_York", CalFields(2011,11,6,0,59,59), CalFields(2011,11,6,4,59,59), CalFields(2011,11,6,4,59,59)},
2462 {"America/New_York", CalFields(2011,11,6,1,0,0), CalFields(2011,11,6,6,0,0), CalFields(2011,11,6,5,0,0)},
2463 {"America/New_York", CalFields(2011,11,6,1,0,1), CalFields(2011,11,6,6,0,1), CalFields(2011,11,6,5,0,1)},
2464 {"America/New_York", CalFields(2011,11,6,1,30,0), CalFields(2011,11,6,6,30,0), CalFields(2011,11,6,5,30,0)},
2465 {"America/New_York", CalFields(2011,11,6,1,59,59), CalFields(2011,11,6,6,59,59), CalFields(2011,11,6,5,59,59)},
2466 {"America/New_York", CalFields(2011,11,6,2,0,0), CalFields(2011,11,6,7,0,0), CalFields(2011,11,6,7,0,0)},
2467 {"America/New_York", CalFields(2011,11,6,2,0,1), CalFields(2011,11,6,7,0,1), CalFields(2011,11,6,7,0,1)},
2468
2469 {"Australia/Lord_Howe", CalFields(2011,4,3,1,29,59), CalFields(2011,4,2,14,29,59), CalFields(2011,4,2,14,29,59)},
2470 {"Australia/Lord_Howe", CalFields(2011,4,3,1,30,0), CalFields(2011,4,2,15,0,0), CalFields(2011,4,2,14,30,0)},
2471 {"Australia/Lord_Howe", CalFields(2011,4,3,1,45,0), CalFields(2011,4,2,15,15,0), CalFields(2011,4,2,14,45,0)},
2472 {"Australia/Lord_Howe", CalFields(2011,4,3,1,59,59), CalFields(2011,4,2,15,29,59), CalFields(2011,4,2,14,59,59)},
2473 {"Australia/Lord_Howe", CalFields(2011,4,3,2,0,0), CalFields(2011,4,2,15,30,0), CalFields(2011,4,2,15,30,0)},
2474 {"Australia/Lord_Howe", CalFields(2011,4,3,2,0,1), CalFields(2011,4,2,15,30,1), CalFields(2011,4,2,15,30,1)},
2475
2476 {NULL, CalFields(0,0,0,0,0,0), CalFields(0,0,0,0,0,0), CalFields(0,0,0,0,0,0)}
2477 };
2478
TestRepeatedWallTime(void)2479 void CalendarTest::TestRepeatedWallTime(void) {
2480 UErrorCode status = U_ZERO_ERROR;
2481 GregorianCalendar calGMT((const TimeZone&)*TimeZone::getGMT(), status);
2482 GregorianCalendar calDefault(status);
2483 GregorianCalendar calLast(status);
2484 GregorianCalendar calFirst(status);
2485
2486 if (U_FAILURE(status)) {
2487 errln("Fail: Failed to create a calendar object.");
2488 return;
2489 }
2490
2491 calLast.setRepeatedWallTimeOption(UCAL_WALLTIME_LAST);
2492 calFirst.setRepeatedWallTimeOption(UCAL_WALLTIME_FIRST);
2493
2494 for (int32_t i = 0; RPDATA[i].tzid != NULL; i++) {
2495 char buf[32];
2496 TimeZone *tz = TimeZone::createTimeZone(RPDATA[i].tzid);
2497
2498 // UCAL_WALLTIME_LAST
2499 status = U_ZERO_ERROR;
2500 calLast.setTimeZone(*tz);
2501 RPDATA[i].in.setTo(calLast);
2502 calGMT.setTime(calLast.getTime(status), status);
2503 CalFields outLastGMT(calGMT, status);
2504 if (U_FAILURE(status)) {
2505 errln(UnicodeString("Fail: Failed to get/set time calLast/calGMT (UCAL_WALLTIME_LAST) - ")
2506 + RPDATA[i].in.toString(buf, sizeof(buf)) + "[" + RPDATA[i].tzid + "]");
2507 } else {
2508 if (outLastGMT != RPDATA[i].expLastGMT) {
2509 dataerrln(UnicodeString("Fail: UCAL_WALLTIME_LAST ") + RPDATA[i].in.toString(buf, sizeof(buf)) + "[" + RPDATA[i].tzid + "] is parsed as "
2510 + outLastGMT.toString(buf, sizeof(buf)) + "[GMT]. Expected: " + RPDATA[i].expLastGMT.toString(buf, sizeof(buf)) + "[GMT]");
2511 }
2512 }
2513
2514 // default
2515 status = U_ZERO_ERROR;
2516 calDefault.setTimeZone(*tz);
2517 RPDATA[i].in.setTo(calDefault);
2518 calGMT.setTime(calDefault.getTime(status), status);
2519 CalFields outDefGMT(calGMT, status);
2520 if (U_FAILURE(status)) {
2521 errln(UnicodeString("Fail: Failed to get/set time calLast/calGMT (default) - ")
2522 + RPDATA[i].in.toString(buf, sizeof(buf)) + "[" + RPDATA[i].tzid + "]");
2523 } else {
2524 if (outDefGMT != RPDATA[i].expLastGMT) {
2525 dataerrln(UnicodeString("Fail: (default) ") + RPDATA[i].in.toString(buf, sizeof(buf)) + "[" + RPDATA[i].tzid + "] is parsed as "
2526 + outDefGMT.toString(buf, sizeof(buf)) + "[GMT]. Expected: " + RPDATA[i].expLastGMT.toString(buf, sizeof(buf)) + "[GMT]");
2527 }
2528 }
2529
2530 // UCAL_WALLTIME_FIRST
2531 status = U_ZERO_ERROR;
2532 calFirst.setTimeZone(*tz);
2533 RPDATA[i].in.setTo(calFirst);
2534 calGMT.setTime(calFirst.getTime(status), status);
2535 CalFields outFirstGMT(calGMT, status);
2536 if (U_FAILURE(status)) {
2537 errln(UnicodeString("Fail: Failed to get/set time calLast/calGMT (UCAL_WALLTIME_FIRST) - ")
2538 + RPDATA[i].in.toString(buf, sizeof(buf)) + "[" + RPDATA[i].tzid + "]");
2539 } else {
2540 if (outFirstGMT != RPDATA[i].expFirstGMT) {
2541 dataerrln(UnicodeString("Fail: UCAL_WALLTIME_FIRST ") + RPDATA[i].in.toString(buf, sizeof(buf)) + "[" + RPDATA[i].tzid + "] is parsed as "
2542 + outFirstGMT.toString(buf, sizeof(buf)) + "[GMT]. Expected: " + RPDATA[i].expFirstGMT.toString(buf, sizeof(buf)) + "[GMT]");
2543 }
2544 }
2545 delete tz;
2546 }
2547 }
2548
2549 typedef struct {
2550 const char* tzid;
2551 const CalFields in;
2552 UBool isValid;
2553 const CalFields expLastGMT;
2554 const CalFields expFirstGMT;
2555 const CalFields expNextAvailGMT;
2556 } SkippedWallTimeTestData;
2557
2558 static SkippedWallTimeTestData SKDATA[] =
2559 {
2560 // Time zone Input wall time valid? WALLTIME_LAST in GMT WALLTIME_FIRST in GMT WALLTIME_NEXT_VALID in GMT
2561 {"America/New_York", CalFields(2011,3,13,1,59,59), TRUE, CalFields(2011,3,13,6,59,59), CalFields(2011,3,13,6,59,59), CalFields(2011,3,13,6,59,59)},
2562 {"America/New_York", CalFields(2011,3,13,2,0,0), FALSE, CalFields(2011,3,13,7,0,0), CalFields(2011,3,13,6,0,0), CalFields(2011,3,13,7,0,0)},
2563 {"America/New_York", CalFields(2011,3,13,2,1,0), FALSE, CalFields(2011,3,13,7,1,0), CalFields(2011,3,13,6,1,0), CalFields(2011,3,13,7,0,0)},
2564 {"America/New_York", CalFields(2011,3,13,2,30,0), FALSE, CalFields(2011,3,13,7,30,0), CalFields(2011,3,13,6,30,0), CalFields(2011,3,13,7,0,0)},
2565 {"America/New_York", CalFields(2011,3,13,2,59,59), FALSE, CalFields(2011,3,13,7,59,59), CalFields(2011,3,13,6,59,59), CalFields(2011,3,13,7,0,0)},
2566 {"America/New_York", CalFields(2011,3,13,3,0,0), TRUE, CalFields(2011,3,13,7,0,0), CalFields(2011,3,13,7,0,0), CalFields(2011,3,13,7,0,0)},
2567
2568 {"Pacific/Apia", CalFields(2011,12,29,23,59,59), TRUE, CalFields(2011,12,30,9,59,59), CalFields(2011,12,30,9,59,59), CalFields(2011,12,30,9,59,59)},
2569 {"Pacific/Apia", CalFields(2011,12,30,0,0,0), FALSE, CalFields(2011,12,30,10,0,0), CalFields(2011,12,29,10,0,0), CalFields(2011,12,30,10,0,0)},
2570 {"Pacific/Apia", CalFields(2011,12,30,12,0,0), FALSE, CalFields(2011,12,30,22,0,0), CalFields(2011,12,29,22,0,0), CalFields(2011,12,30,10,0,0)},
2571 {"Pacific/Apia", CalFields(2011,12,30,23,59,59), FALSE, CalFields(2011,12,31,9,59,59), CalFields(2011,12,30,9,59,59), CalFields(2011,12,30,10,0,0)},
2572 {"Pacific/Apia", CalFields(2011,12,31,0,0,0), TRUE, CalFields(2011,12,30,10,0,0), CalFields(2011,12,30,10,0,0), CalFields(2011,12,30,10,0,0)},
2573
2574 {NULL, CalFields(0,0,0,0,0,0), TRUE, CalFields(0,0,0,0,0,0), CalFields(0,0,0,0,0,0), CalFields(0,0,0,0,0,0)}
2575 };
2576
2577
TestSkippedWallTime(void)2578 void CalendarTest::TestSkippedWallTime(void) {
2579 UErrorCode status = U_ZERO_ERROR;
2580 GregorianCalendar calGMT((const TimeZone&)*TimeZone::getGMT(), status);
2581 GregorianCalendar calDefault(status);
2582 GregorianCalendar calLast(status);
2583 GregorianCalendar calFirst(status);
2584 GregorianCalendar calNextAvail(status);
2585
2586 if (U_FAILURE(status)) {
2587 errln("Fail: Failed to create a calendar object.");
2588 return;
2589 }
2590
2591 calLast.setSkippedWallTimeOption(UCAL_WALLTIME_LAST);
2592 calFirst.setSkippedWallTimeOption(UCAL_WALLTIME_FIRST);
2593 calNextAvail.setSkippedWallTimeOption(UCAL_WALLTIME_NEXT_VALID);
2594
2595 for (int32_t i = 0; SKDATA[i].tzid != NULL; i++) {
2596 UDate d;
2597 char buf[32];
2598 TimeZone *tz = TimeZone::createTimeZone(SKDATA[i].tzid);
2599
2600 for (int32_t j = 0; j < 2; j++) {
2601 UBool bLenient = (j == 0);
2602
2603 // UCAL_WALLTIME_LAST
2604 status = U_ZERO_ERROR;
2605 calLast.setLenient(bLenient);
2606 calLast.setTimeZone(*tz);
2607 SKDATA[i].in.setTo(calLast);
2608 d = calLast.getTime(status);
2609 if (bLenient || SKDATA[i].isValid) {
2610 calGMT.setTime(d, status);
2611 CalFields outLastGMT(calGMT, status);
2612 if (U_FAILURE(status)) {
2613 errln(UnicodeString("Fail: Failed to get/set time calLast/calGMT (UCAL_WALLTIME_LAST) - ")
2614 + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "]");
2615 } else {
2616 if (outLastGMT != SKDATA[i].expLastGMT) {
2617 dataerrln(UnicodeString("Fail: UCAL_WALLTIME_LAST ") + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "] is parsed as "
2618 + outLastGMT.toString(buf, sizeof(buf)) + "[GMT]. Expected: " + SKDATA[i].expLastGMT.toString(buf, sizeof(buf)) + "[GMT]");
2619 }
2620 }
2621 } else if (U_SUCCESS(status)) {
2622 // strict, invalid wall time - must report an error
2623 dataerrln(UnicodeString("Fail: An error expected (UCAL_WALLTIME_LAST)") +
2624 + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "]");
2625 }
2626
2627 // default
2628 status = U_ZERO_ERROR;
2629 calDefault.setLenient(bLenient);
2630 calDefault.setTimeZone(*tz);
2631 SKDATA[i].in.setTo(calDefault);
2632 d = calDefault.getTime(status);
2633 if (bLenient || SKDATA[i].isValid) {
2634 calGMT.setTime(d, status);
2635 CalFields outDefGMT(calGMT, status);
2636 if (U_FAILURE(status)) {
2637 errln(UnicodeString("Fail: Failed to get/set time calDefault/calGMT (default) - ")
2638 + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "]");
2639 } else {
2640 if (outDefGMT != SKDATA[i].expLastGMT) {
2641 dataerrln(UnicodeString("Fail: (default) ") + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "] is parsed as "
2642 + outDefGMT.toString(buf, sizeof(buf)) + "[GMT]. Expected: " + SKDATA[i].expLastGMT.toString(buf, sizeof(buf)) + "[GMT]");
2643 }
2644 }
2645 } else if (U_SUCCESS(status)) {
2646 // strict, invalid wall time - must report an error
2647 dataerrln(UnicodeString("Fail: An error expected (default)") +
2648 + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "]");
2649 }
2650
2651 // UCAL_WALLTIME_FIRST
2652 status = U_ZERO_ERROR;
2653 calFirst.setLenient(bLenient);
2654 calFirst.setTimeZone(*tz);
2655 SKDATA[i].in.setTo(calFirst);
2656 d = calFirst.getTime(status);
2657 if (bLenient || SKDATA[i].isValid) {
2658 calGMT.setTime(d, status);
2659 CalFields outFirstGMT(calGMT, status);
2660 if (U_FAILURE(status)) {
2661 errln(UnicodeString("Fail: Failed to get/set time calFirst/calGMT (UCAL_WALLTIME_FIRST) - ")
2662 + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "]");
2663 } else {
2664 if (outFirstGMT != SKDATA[i].expFirstGMT) {
2665 dataerrln(UnicodeString("Fail: UCAL_WALLTIME_FIRST ") + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "] is parsed as "
2666 + outFirstGMT.toString(buf, sizeof(buf)) + "[GMT]. Expected: " + SKDATA[i].expFirstGMT.toString(buf, sizeof(buf)) + "[GMT]");
2667 }
2668 }
2669 } else if (U_SUCCESS(status)) {
2670 // strict, invalid wall time - must report an error
2671 dataerrln(UnicodeString("Fail: An error expected (UCAL_WALLTIME_FIRST)") +
2672 + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "]");
2673 }
2674
2675 // UCAL_WALLTIME_NEXT_VALID
2676 status = U_ZERO_ERROR;
2677 calNextAvail.setLenient(bLenient);
2678 calNextAvail.setTimeZone(*tz);
2679 SKDATA[i].in.setTo(calNextAvail);
2680 d = calNextAvail.getTime(status);
2681 if (bLenient || SKDATA[i].isValid) {
2682 calGMT.setTime(d, status);
2683 CalFields outNextAvailGMT(calGMT, status);
2684 if (U_FAILURE(status)) {
2685 errln(UnicodeString("Fail: Failed to get/set time calNextAvail/calGMT (UCAL_WALLTIME_NEXT_VALID) - ")
2686 + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "]");
2687 } else {
2688 if (outNextAvailGMT != SKDATA[i].expNextAvailGMT) {
2689 dataerrln(UnicodeString("Fail: UCAL_WALLTIME_NEXT_VALID ") + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "] is parsed as "
2690 + outNextAvailGMT.toString(buf, sizeof(buf)) + "[GMT]. Expected: " + SKDATA[i].expNextAvailGMT.toString(buf, sizeof(buf)) + "[GMT]");
2691 }
2692 }
2693 } else if (U_SUCCESS(status)) {
2694 // strict, invalid wall time - must report an error
2695 dataerrln(UnicodeString("Fail: An error expected (UCAL_WALLTIME_NEXT_VALID)") +
2696 + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "]");
2697 }
2698 }
2699
2700 delete tz;
2701 }
2702 }
2703
TestCloneLocale(void)2704 void CalendarTest::TestCloneLocale(void) {
2705 UErrorCode status = U_ZERO_ERROR;
2706 LocalPointer<Calendar> cal(Calendar::createInstance(TimeZone::getGMT()->clone(),
2707 Locale::createFromName("en"), status));
2708 TEST_CHECK_STATUS;
2709 Locale l0 = cal->getLocale(ULOC_VALID_LOCALE, status);
2710 TEST_CHECK_STATUS;
2711 LocalPointer<Calendar> cal2(cal->clone());
2712 Locale l = cal2->getLocale(ULOC_VALID_LOCALE, status);
2713 if(l0!=l) {
2714 errln("Error: cloned locale %s != original locale %s, status %s\n", l0.getName(), l.getName(), u_errorName(status));
2715 }
2716 TEST_CHECK_STATUS;
2717 }
2718
2719 #endif /* #if !UCONFIG_NO_FORMATTING */
2720
2721 //eof
2722