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