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