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