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