]> git.saurik.com Git - apple/icu.git/blame - icuSources/test/intltest/caltest.cpp
ICU-8.11.tar.gz
[apple/icu.git] / icuSources / test / intltest / caltest.cpp
CommitLineData
374ca955 1/************************************************************************
b75a7d8f 2 * COPYRIGHT:
73c04bcf 3 * Copyright (c) 1997-2006, International Business Machines Corporation
374ca955
A
4 * and others. All Rights Reserved.
5 ************************************************************************/
b75a7d8f
A
6
7#include "unicode/utypes.h"
8
9#if !UCONFIG_NO_FORMATTING
10
11#include "caltest.h"
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;
73c04bcf 570 Calendar *c = Calendar::createInstance("en_US", status);
b75a7d8f
A
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;
73c04bcf
A
679 int32_t y = c->get(UCAL_YEAR, status);
680 int32_t m = c->get(UCAL_MONTH, status);
681 int32_t d = c->get(UCAL_DATE, status);
682 if ( y == year &&
683 m == month &&
684 d == day) {
b75a7d8f
A
685 if (U_FAILURE(status)) { errln("FAIL: Calendar::get failed"); return; }
686 logln("PASS: " + msg + dateToString(c->getTime(status), str));
687 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; }
688 }
689 else {
73c04bcf
A
690 errln("FAIL: " + msg + dateToString(c->getTime(status), str) + "; expected " + (int32_t)year + "/" + (int32_t)(month + 1) + "/" + (int32_t)day +
691 "; got " + (int32_t)y + "/" + (int32_t)(m + 1) + "/" + (int32_t)d + " for Locale: " + c->getLocaleID(ULOC_ACTUAL_LOCALE,status));
b75a7d8f
A
692 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; }
693 }
694}
695
696// -------------------------------------
697
698void
699CalendarTest::verify765(const UnicodeString& msg/*, IllegalArgumentException e*/, UErrorCode status)
700{
701 if (status != U_ILLEGAL_ARGUMENT_ERROR) errln("FAIL: No IllegalArgumentException for " + msg);
702 else logln("PASS: " + msg + "IllegalArgument as expected");
703}
704
705// -------------------------------------
706
707/**
708 * Confirm that the offset between local time and GMT behaves as expected.
709 */
710void
711CalendarTest::TestGMTvsLocal4064654()
712{
713 test4064654(1997, 1, 1, 12, 0, 0);
714 test4064654(1997, 4, 16, 18, 30, 0);
715}
716
717// -------------------------------------
718
719void
720CalendarTest::test4064654(int32_t yr, int32_t mo, int32_t dt, int32_t hr, int32_t mn, int32_t sc)
721{
722 UDate date;
723 UErrorCode status = U_ZERO_ERROR;
724 UnicodeString str;
725 Calendar *gmtcal = Calendar::createInstance(status);
726 if (U_FAILURE(status)) { errln("Calendar::createInstance failed"); return; }
727 gmtcal->adoptTimeZone(TimeZone::createTimeZone("Africa/Casablanca"));
728 gmtcal->set(yr, mo - 1, dt, hr, mn, sc);
729 gmtcal->set(UCAL_MILLISECOND, 0);
730 date = gmtcal->getTime(status);
731 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; }
732 logln("date = " + dateToString(date, str));
733 Calendar *cal = Calendar::createInstance(status);
734 if (U_FAILURE(status)) { errln("Calendar::createInstance failed"); return; }
735 cal->setTime(date, status);
736 if (U_FAILURE(status)) { errln("Calendar::setTime failed"); return; }
737 int32_t offset = cal->getTimeZone().getOffset((uint8_t)cal->get(UCAL_ERA, status),
738 cal->get(UCAL_YEAR, status),
739 cal->get(UCAL_MONTH, status),
740 cal->get(UCAL_DATE, status),
741 (uint8_t)cal->get(UCAL_DAY_OF_WEEK, status),
742 cal->get(UCAL_MILLISECOND, status), status);
743 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
744 logln("offset for " + dateToString(date, str) + "= " + (offset / 1000 / 60 / 60.0) + "hr");
745 int32_t utc = ((cal->get(UCAL_HOUR_OF_DAY, status) * 60 +
746 cal->get(UCAL_MINUTE, status)) * 60 +
747 cal->get(UCAL_SECOND, status)) * 1000 +
748 cal->get(UCAL_MILLISECOND, status) - offset;
749 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
750 int32_t expected = ((hr * 60 + mn) * 60 + sc) * 1000;
751 if (utc != expected) errln(UnicodeString("FAIL: Discrepancy of ") + (utc - expected) +
752 " millis = " + ((utc - expected) / 1000 / 60 / 60.0) + " hr");
753 delete gmtcal;
754 delete cal;
755}
756
757// -------------------------------------
758
759/**
760 * The operations of adding and setting should not exhibit pathological
761 * dependence on the order of operations. This test checks for this.
762 */
763void
764CalendarTest::TestAddSetOrder621()
765{
766 UDate d = date(97, 4, 14, 13, 23, 45);
767 UErrorCode status = U_ZERO_ERROR;
768 Calendar *cal = Calendar::createInstance(status);
769 if (U_FAILURE(status)) {
770 errln("Calendar::createInstance failed");
771 delete cal;
772 return;
773 }
774 cal->setTime(d, status);
775 if (U_FAILURE(status)) {
776 errln("Calendar::setTime failed");
777 delete cal;
778 return;
779 }
780 cal->add(UCAL_DATE, - 5, status);
781 if (U_FAILURE(status)) {
782 errln("Calendar::add failed");
783 delete cal;
784 return;
785 }
786 cal->set(UCAL_HOUR_OF_DAY, 0);
787 cal->set(UCAL_MINUTE, 0);
788 cal->set(UCAL_SECOND, 0);
789 UnicodeString s;
790 dateToString(cal->getTime(status), s);
791 if (U_FAILURE(status)) {
792 errln("Calendar::getTime failed");
793 delete cal;
794 return;
795 }
796 delete cal;
797
798 cal = Calendar::createInstance(status);
799 if (U_FAILURE(status)) {
800 errln("Calendar::createInstance failed");
801 delete cal;
802 return;
803 }
804 cal->setTime(d, status);
805 if (U_FAILURE(status)) {
806 errln("Calendar::setTime failed");
807 delete cal;
808 return;
809 }
810 cal->set(UCAL_HOUR_OF_DAY, 0);
811 cal->set(UCAL_MINUTE, 0);
812 cal->set(UCAL_SECOND, 0);
813 cal->add(UCAL_DATE, - 5, status);
814 if (U_FAILURE(status)) {
815 errln("Calendar::add failed");
816 delete cal;
817 return;
818 }
819 UnicodeString s2;
820 dateToString(cal->getTime(status), s2);
821 if (U_FAILURE(status)) {
822 errln("Calendar::getTime failed");
823 delete cal;
824 return;
825 }
826 if (s == s2)
827 logln("Pass: " + s + " == " + s2);
828 else
829 errln("FAIL: " + s + " != " + s2);
830 delete cal;
831}
832
833// -------------------------------------
834
835/**
836 * Confirm that adding to various fields works.
837 */
838void
839CalendarTest::TestAdd520()
840{
841 int32_t y = 1997, m = UCAL_FEBRUARY, d = 1;
842 UErrorCode status = U_ZERO_ERROR;
843 GregorianCalendar *temp = new GregorianCalendar(y, m, d, status);
844 if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; }
845 check520(temp, y, m, d);
846 temp->add(UCAL_YEAR, 1, status);
847 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
848 y++;
849 check520(temp, y, m, d);
850 temp->add(UCAL_MONTH, 1, status);
851 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
852 m++;
853 check520(temp, y, m, d);
854 temp->add(UCAL_DATE, 1, status);
855 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
856 d++;
857 check520(temp, y, m, d);
858 temp->add(UCAL_DATE, 2, status);
859 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
860 d += 2;
861 check520(temp, y, m, d);
862 temp->add(UCAL_DATE, 28, status);
863 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
864 d = 1;++m;
865 check520(temp, y, m, d);
866 delete temp;
867}
868
869// -------------------------------------
870
871/**
872 * Execute adding and rolling in GregorianCalendar extensively,
873 */
874void
875CalendarTest::TestAddRollExtensive()
876{
877 int32_t maxlimit = 40;
878 int32_t y = 1997, m = UCAL_FEBRUARY, d = 1, hr = 1, min = 1, sec = 0, ms = 0;
879 UErrorCode status = U_ZERO_ERROR;
880 GregorianCalendar *temp = new GregorianCalendar(y, m, d, status);
881 if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; }
882
883 temp->set(UCAL_HOUR, hr);
884 temp->set(UCAL_MINUTE, min);
885 temp->set(UCAL_SECOND, sec);
886 temp->set(UCAL_MILLISECOND, ms);
887
888 UCalendarDateFields e;
889
890 logln("Testing GregorianCalendar add...");
891 e = UCAL_YEAR;
892 while (e < UCAL_FIELD_COUNT) {
893 int32_t i;
894 int32_t limit = maxlimit;
895 status = U_ZERO_ERROR;
896 for (i = 0; i < limit; i++) {
897 temp->add(e, 1, status);
898 if (U_FAILURE(status)) { limit = i; status = U_ZERO_ERROR; }
899 }
900 for (i = 0; i < limit; i++) {
901 temp->add(e, -1, status);
902 if (U_FAILURE(status)) { errln("GregorianCalendar::add -1 failed"); return; }
903 }
904 check520(temp, y, m, d, hr, min, sec, ms, e);
905
906 e = (UCalendarDateFields) ((int32_t) e + 1);
907 }
908
909 logln("Testing GregorianCalendar roll...");
910 e = UCAL_YEAR;
911 while (e < UCAL_FIELD_COUNT) {
912 int32_t i;
913 int32_t limit = maxlimit;
914 status = U_ZERO_ERROR;
915 for (i = 0; i < limit; i++) {
374ca955 916 logln(calToStr(*temp) + UnicodeString(" " ) + fieldName(e) + UnicodeString("++") );
b75a7d8f 917 temp->roll(e, 1, status);
374ca955
A
918 if (U_FAILURE(status)) {
919 logln("caltest.cpp:%d e=%d, i=%d - roll(+) err %s\n", __LINE__, (int) e, (int) i, u_errorName(status));
920 logln(calToStr(*temp));
921 limit = i; status = U_ZERO_ERROR;
922 }
b75a7d8f
A
923 }
924 for (i = 0; i < limit; i++) {
374ca955
A
925 logln("caltest.cpp:%d e=%d, i=%d\n", __LINE__, (int) e, (int) i);
926 logln(calToStr(*temp) + UnicodeString(" " ) + fieldName(e) + UnicodeString("--") );
b75a7d8f 927 temp->roll(e, -1, status);
374ca955 928 if (U_FAILURE(status)) { errln(UnicodeString("GregorianCalendar::roll ") + CalendarTest::fieldName(e) + " count=" + UnicodeString('@'+i) + " by -1 failed with " + u_errorName(status) ); return; }
b75a7d8f
A
929 }
930 check520(temp, y, m, d, hr, min, sec, ms, e);
931
932 e = (UCalendarDateFields) ((int32_t) e + 1);
933 }
934
935 delete temp;
936}
937
938// -------------------------------------
939void
940CalendarTest::check520(Calendar* c,
941 int32_t y, int32_t m, int32_t d,
942 int32_t hr, int32_t min, int32_t sec,
943 int32_t ms, UCalendarDateFields field)
944
945{
946 UErrorCode status = U_ZERO_ERROR;
947 if (c->get(UCAL_YEAR, status) != y ||
948 c->get(UCAL_MONTH, status) != m ||
949 c->get(UCAL_DATE, status) != d ||
950 c->get(UCAL_HOUR, status) != hr ||
951 c->get(UCAL_MINUTE, status) != min ||
952 c->get(UCAL_SECOND, status) != sec ||
953 c->get(UCAL_MILLISECOND, status) != ms) {
954 errln(UnicodeString("U_FAILURE for field ") + (int32_t)field +
955 ": Expected y/m/d h:m:s:ms of " +
956 y + "/" + (m + 1) + "/" + d + " " +
957 hr + ":" + min + ":" + sec + ":" + ms +
958 "; got " + c->get(UCAL_YEAR, status) +
959 "/" + (c->get(UCAL_MONTH, status) + 1) +
960 "/" + c->get(UCAL_DATE, status) +
961 " " + c->get(UCAL_HOUR, status) + ":" +
962 c->get(UCAL_MINUTE, status) + ":" +
963 c->get(UCAL_SECOND, status) + ":" +
964 c->get(UCAL_MILLISECOND, status)
965 );
966
967 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
968 }
969 else
970 logln(UnicodeString("Confirmed: ") + y + "/" +
971 (m + 1) + "/" + d + " " +
972 hr + ":" + min + ":" + sec + ":" + ms);
973}
974
975// -------------------------------------
976void
977CalendarTest::check520(Calendar* c,
978 int32_t y, int32_t m, int32_t d)
979
980{
981 UErrorCode status = U_ZERO_ERROR;
982 if (c->get(UCAL_YEAR, status) != y ||
983 c->get(UCAL_MONTH, status) != m ||
984 c->get(UCAL_DATE, status) != d) {
985 errln(UnicodeString("FAILURE: Expected y/m/d of ") +
986 y + "/" + (m + 1) + "/" + d + " " +
987 "; got " + c->get(UCAL_YEAR, status) +
988 "/" + (c->get(UCAL_MONTH, status) + 1) +
989 "/" + c->get(UCAL_DATE, status)
990 );
991
992 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
993 }
994 else
995 logln(UnicodeString("Confirmed: ") + y + "/" +
996 (m + 1) + "/" + d);
997}
998
999// -------------------------------------
1000
1001/**
1002 * Test that setting of fields works. In particular, make sure that all instances
1003 * of GregorianCalendar don't share a static instance of the fields array.
1004 */
1005void
1006CalendarTest::TestFieldSet4781()
1007{
1008 // try {
1009 UErrorCode status = U_ZERO_ERROR;
1010 GregorianCalendar *g = new GregorianCalendar(status);
1011 if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; }
1012 GregorianCalendar *g2 = new GregorianCalendar(status);
1013 if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; }
1014 g2->set(UCAL_HOUR, 12, status);
1015 g2->set(UCAL_MINUTE, 0, status);
1016 g2->set(UCAL_SECOND, 0, status);
1017 if (U_FAILURE(status)) { errln("Calendar::set failed"); return; }
1018 if (*g == *g2) logln("Same");
1019 else logln("Different");
1020 //}
1021 //catch(IllegalArgumentException e) {
1022 //errln("Unexpected exception seen: " + e);
1023 //}
1024 delete g;
1025 delete g2;
1026}
1027
1028// -------------------------------------
1029
1030/* We don't support serialization on C++
1031void
1032CalendarTest::TestSerialize337()
1033{
1034 Calendar cal = Calendar::getInstance();
1035 UBool ok = FALSE;
1036 try {
1037 FileOutputStream f = new FileOutputStream(FILENAME);
1038 ObjectOutput s = new ObjectOutputStream(f);
1039 s.writeObject(PREFIX);
1040 s.writeObject(cal);
1041 s.writeObject(POSTFIX);
1042 f.close();
1043 FileInputStream in = new FileInputStream(FILENAME);
1044 ObjectInputStream t = new ObjectInputStream(in);
1045 UnicodeString& pre = (UnicodeString&) t.readObject();
1046 Calendar c = (Calendar) t.readObject();
1047 UnicodeString& post = (UnicodeString&) t.readObject();
1048 in.close();
1049 ok = pre.equals(PREFIX) &&
1050 post.equals(POSTFIX) &&
1051 cal->equals(c);
1052 File fl = new File(FILENAME);
1053 fl.delete();
1054 }
1055 catch(IOException e) {
1056 errln("FAIL: Exception received:");
1057 e.printStackTrace(log);
1058 }
1059 catch(ClassNotFoundException e) {
1060 errln("FAIL: Exception received:");
1061 e.printStackTrace(log);
1062 }
1063 if (!ok) errln("Serialization of Calendar object failed.");
1064}
1065
1066UnicodeString& CalendarTest::PREFIX = "abc";
1067
1068UnicodeString& CalendarTest::POSTFIX = "def";
1069
1070UnicodeString& CalendarTest::FILENAME = "tmp337.bin";
1071 */
1072
1073// -------------------------------------
1074
1075/**
1076 * Verify that the seconds of a Calendar can be zeroed out through the
1077 * expected sequence of operations.
1078 */
1079void
1080CalendarTest::TestSecondsZero121()
1081{
1082 UErrorCode status = U_ZERO_ERROR;
1083 Calendar *cal = new GregorianCalendar(status);
1084 if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; }
1085 cal->setTime(Calendar::getNow(), status);
1086 if (U_FAILURE(status)) { errln("Calendar::setTime failed"); return; }
1087 cal->set(UCAL_SECOND, 0);
1088 if (U_FAILURE(status)) { errln("Calendar::set failed"); return; }
1089 UDate d = cal->getTime(status);
1090 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; }
1091 UnicodeString s;
1092 dateToString(d, s);
1093 if (s.indexOf(":00 ") < 0) errln("Expected to see :00 in " + s);
1094 delete cal;
1095}
1096
1097// -------------------------------------
1098
1099/**
1100 * Verify that a specific sequence of adding and setting works as expected;
1101 * it should not vary depending on when and whether the get method is
1102 * called.
1103 */
1104void
1105CalendarTest::TestAddSetGet0610()
1106{
1107 UnicodeString EXPECTED_0610("1993/0/5", "");
1108 UErrorCode status = U_ZERO_ERROR;
1109 {
1110 Calendar *calendar = new GregorianCalendar(status);
1111 if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; }
1112 calendar->set(1993, UCAL_JANUARY, 4);
1113 logln("1A) " + value(calendar));
1114 calendar->add(UCAL_DATE, 1, status);
1115 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
1116 UnicodeString v = value(calendar);
1117 logln("1B) " + v);
1118 logln("--) 1993/0/5");
1119 if (!(v == EXPECTED_0610)) errln("Expected " + EXPECTED_0610 + "; saw " + v);
1120 delete calendar;
1121 }
1122 {
1123 Calendar *calendar = new GregorianCalendar(1993, UCAL_JANUARY, 4, status);
1124 if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; }
1125 logln("2A) " + value(calendar));
1126 calendar->add(UCAL_DATE, 1, status);
1127 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
1128 UnicodeString v = value(calendar);
1129 logln("2B) " + v);
1130 logln("--) 1993/0/5");
1131 if (!(v == EXPECTED_0610)) errln("Expected " + EXPECTED_0610 + "; saw " + v);
1132 delete calendar;
1133 }
1134 {
1135 Calendar *calendar = new GregorianCalendar(1993, UCAL_JANUARY, 4, status);
1136 if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; }
1137 logln("3A) " + value(calendar));
1138 calendar->getTime(status);
1139 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; }
1140 calendar->add(UCAL_DATE, 1, status);
1141 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
1142 UnicodeString v = value(calendar);
1143 logln("3B) " + v);
1144 logln("--) 1993/0/5");
1145 if (!(v == EXPECTED_0610)) errln("Expected " + EXPECTED_0610 + "; saw " + v);
1146 delete calendar;
1147 }
1148}
1149
1150// -------------------------------------
1151
1152UnicodeString
1153CalendarTest::value(Calendar* calendar)
1154{
1155 UErrorCode status = U_ZERO_ERROR;
1156 return UnicodeString("") + (int32_t)calendar->get(UCAL_YEAR, status) +
1157 "/" + (int32_t)calendar->get(UCAL_MONTH, status) +
1158 "/" + (int32_t)calendar->get(UCAL_DATE, status) +
1159 (U_FAILURE(status) ? " FAIL: Calendar::get failed" : "");
1160}
1161
1162
1163// -------------------------------------
1164
1165/**
1166 * Verify that various fields on a known date are set correctly.
1167 */
1168void
1169CalendarTest::TestFields060()
1170{
1171 UErrorCode status = U_ZERO_ERROR;
1172 int32_t year = 1997;
1173 int32_t month = UCAL_OCTOBER;
1174 int32_t dDate = 22;
1175 GregorianCalendar *calendar = 0;
1176 calendar = new GregorianCalendar(year, month, dDate, status);
1177 if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; }
1178 for (int32_t i = 0; i < EXPECTED_FIELDS_length;) {
1179 UCalendarDateFields field = (UCalendarDateFields)EXPECTED_FIELDS[i++];
1180 int32_t expected = EXPECTED_FIELDS[i++];
1181 if (calendar->get(field, status) != expected) {
1182 errln(UnicodeString("Expected field ") + (int32_t)field + " to have value " + (int32_t)expected +
1183 "; received " + (int32_t)calendar->get(field, status) + " instead");
1184 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
1185 }
1186 }
1187 delete calendar;
1188}
1189
1190int32_t CalendarTest::EXPECTED_FIELDS[] = {
1191 UCAL_YEAR, 1997,
1192 UCAL_MONTH, UCAL_OCTOBER,
1193 UCAL_DATE, 22,
1194 UCAL_DAY_OF_WEEK, UCAL_WEDNESDAY,
1195 UCAL_DAY_OF_WEEK_IN_MONTH, 4,
1196 UCAL_DAY_OF_YEAR, 295
1197};
1198
1199const int32_t CalendarTest::EXPECTED_FIELDS_length = (int32_t)(sizeof(CalendarTest::EXPECTED_FIELDS) /
1200 sizeof(CalendarTest::EXPECTED_FIELDS[0]));
1201
1202// -------------------------------------
1203
1204/**
1205 * Verify that various fields on a known date are set correctly. In this
1206 * case, the start of the epoch (January 1 1970).
1207 */
1208void
1209CalendarTest::TestEpochStartFields()
1210{
1211 UErrorCode status = U_ZERO_ERROR;
1212 TimeZone *z = TimeZone::createDefault();
1213 Calendar *c = Calendar::createInstance(status);
1214 if (U_FAILURE(status)) { errln("Calendar::createInstance failed"); return; }
1215 UDate d = - z->getRawOffset();
1216 GregorianCalendar *gc = new GregorianCalendar(status);
1217 if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; }
1218 gc->setTimeZone(*z);
1219 gc->setTime(d, status);
1220 if (U_FAILURE(status)) { errln("Calendar::setTime failed"); return; }
1221 UBool idt = gc->inDaylightTime(status);
1222 if (U_FAILURE(status)) { errln("GregorianCalendar::inDaylightTime failed"); return; }
1223 if (idt) {
1224 UnicodeString str;
1225 logln("Warning: Skipping test because " + dateToString(d, str) + " is in DST.");
1226 }
1227 else {
1228 c->setTime(d, status);
1229 if (U_FAILURE(status)) { errln("Calendar::setTime failed"); return; }
1230 for (int32_t i = 0; i < UCAL_ZONE_OFFSET;++i) {
1231 if (c->get((UCalendarDateFields)i, status) != EPOCH_FIELDS[i])
1232 errln(UnicodeString("Expected field ") + i + " to have value " + EPOCH_FIELDS[i] +
1233 "; saw " + c->get((UCalendarDateFields)i, status) + " instead");
1234 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
1235 }
1236 if (c->get(UCAL_ZONE_OFFSET, status) != z->getRawOffset())
1237 {
1238 errln(UnicodeString("Expected field ZONE_OFFSET to have value ") + z->getRawOffset() +
1239 "; saw " + c->get(UCAL_ZONE_OFFSET, status) + " instead");
1240 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
1241 }
1242 if (c->get(UCAL_DST_OFFSET, status) != 0)
1243 {
1244 errln(UnicodeString("Expected field DST_OFFSET to have value 0") +
1245 "; saw " + c->get(UCAL_DST_OFFSET, status) + " instead");
1246 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
1247 }
1248 }
1249 delete c;
1250 delete z;
1251 delete gc;
1252}
1253
1254int32_t CalendarTest::EPOCH_FIELDS[] = {
1255 1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, - 28800000, 0
1256};
1257
1258// -------------------------------------
1259
1260/**
1261 * Test that the days of the week progress properly when add is called repeatedly
1262 * for increments of 24 days.
1263 */
1264void
1265CalendarTest::TestDOWProgression()
1266{
1267 UErrorCode status = U_ZERO_ERROR;
1268 Calendar *cal = new GregorianCalendar(1972, UCAL_OCTOBER, 26, status);
1269 if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; }
1270 marchByDelta(cal, 24);
1271 delete cal;
1272}
1273
1274// -------------------------------------
1275
1276void
1277CalendarTest::TestDOW_LOCALandYEAR_WOY()
1278{
1279 /* Note: I've commented out the loop_addroll tests for YEAR and
1280 * YEAR_WOY below because these two fields should NOT behave
1281 * identically when adding. YEAR should keep the month/dom
1282 * invariant. YEAR_WOY should keep the woy/dow invariant. I've
1283 * added a new test that checks for this in place of the old call
1284 * to loop_addroll. - aliu */
1285 UErrorCode status = U_ZERO_ERROR;
1286 int32_t times = 20;
1287 Calendar *cal=Calendar::createInstance(Locale::getGermany(), status);
1288 if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; }
1289 SimpleDateFormat *sdf=new SimpleDateFormat(UnicodeString("YYYY'-W'ww-ee"), Locale::getGermany(), status);
1290 if (U_FAILURE(status)) { errln("Couldn't create SimpleDateFormat"); return; }
1291 sdf->applyLocalizedPattern(UnicodeString("JJJJ'-W'ww-ee"), status);
1292 if (U_FAILURE(status)) { errln("Couldn't apply localized pattern"); return; }
1293 cal->clear();
1294 cal->set(1997, UCAL_DECEMBER, 25);
1295 doYEAR_WOYLoop(cal, sdf, times, status);
1296 //loop_addroll(cal, /*sdf,*/ times, UCAL_YEAR_WOY, UCAL_YEAR, status);
1297 yearAddTest(*cal, status); // aliu
1298 loop_addroll(cal, /*sdf,*/ times, UCAL_DOW_LOCAL, UCAL_DAY_OF_WEEK, status);
1299 if (U_FAILURE(status)) { errln("Error in parse/calculate test for 1997"); return; }
374ca955 1300
b75a7d8f
A
1301 cal->clear();
1302 cal->set(1998, UCAL_DECEMBER, 25);
1303 doYEAR_WOYLoop(cal, sdf, times, status);
1304 //loop_addroll(cal, /*sdf,*/ times, UCAL_YEAR_WOY, UCAL_YEAR, status);
1305 yearAddTest(*cal, status); // aliu
1306 loop_addroll(cal, /*sdf,*/ times, UCAL_DOW_LOCAL, UCAL_DAY_OF_WEEK, status);
1307 if (U_FAILURE(status)) { errln("Error in parse/calculate test for 1998"); return; }
374ca955 1308
b75a7d8f
A
1309 cal->clear();
1310 cal->set(1582, UCAL_OCTOBER, 1);
1311 doYEAR_WOYLoop(cal, sdf, times, status);
1312 //loop_addroll(cal, /*sdf,*/ times, Calendar::YEAR_WOY, Calendar::YEAR, status);
1313 yearAddTest(*cal, status); // aliu
1314 loop_addroll(cal, /*sdf,*/ times, UCAL_DOW_LOCAL, UCAL_DAY_OF_WEEK, status);
1315 if (U_FAILURE(status)) { errln("Error in parse/calculate test for 1582"); return; }
b75a7d8f
A
1316 delete sdf;
1317 delete cal;
1318
1319 return;
1320}
1321
1322/**
1323 * Confirm that adding a YEAR and adding a YEAR_WOY work properly for
1324 * the given Calendar at its current setting.
1325 */
1326void CalendarTest::yearAddTest(Calendar& cal, UErrorCode& status) {
1327 /**
1328 * When adding the YEAR, the month and day should remain constant.
1329 * When adding the YEAR_WOY, the WOY and DOW should remain constant. - aliu
1330 * Examples:
1331 * Wed Jan 14 1998 / 1998-W03-03 Add(YEAR_WOY, 1) -> Wed Jan 20 1999 / 1999-W03-03
1332 * Add(YEAR, 1) -> Thu Jan 14 1999 / 1999-W02-04
1333 * Thu Jan 14 1999 / 1999-W02-04 Add(YEAR_WOY, 1) -> Thu Jan 13 2000 / 2000-W02-04
1334 * Add(YEAR, 1) -> Fri Jan 14 2000 / 2000-W02-05
1335 * Sun Oct 31 1582 / 1582-W42-07 Add(YEAR_WOY, 1) -> Sun Oct 23 1583 / 1583-W42-07
1336 * Add(YEAR, 1) -> Mon Oct 31 1583 / 1583-W44-01
1337 */
1338 int32_t y = cal.get(UCAL_YEAR, status);
1339 int32_t mon = cal.get(UCAL_MONTH, status);
1340 int32_t day = cal.get(UCAL_DATE, status);
1341 int32_t ywy = cal.get(UCAL_YEAR_WOY, status);
1342 int32_t woy = cal.get(UCAL_WEEK_OF_YEAR, status);
1343 int32_t dow = cal.get(UCAL_DOW_LOCAL, status);
1344 UDate t = cal.getTime(status);
73c04bcf
A
1345
1346 if(U_FAILURE(status)){
1347 errln(UnicodeString("Failed to create Calendar for locale. Error: ") + UnicodeString(u_errorName(status)));
1348 return;
1349 }
b75a7d8f
A
1350 UnicodeString str, str2;
1351 SimpleDateFormat fmt(UnicodeString("EEE MMM dd yyyy / YYYY'-W'ww-ee"), status);
1352 fmt.setCalendar(cal);
1353
1354 fmt.format(t, str.remove());
1355 str += ".add(YEAR, 1) =>";
1356 cal.add(UCAL_YEAR, 1, status);
1357 int32_t y2 = cal.get(UCAL_YEAR, status);
1358 int32_t mon2 = cal.get(UCAL_MONTH, status);
1359 int32_t day2 = cal.get(UCAL_DATE, status);
1360 fmt.format(cal.getTime(status), str);
1361 if (y2 != (y+1) || mon2 != mon || day2 != day) {
1362 str += (UnicodeString)", expected year " +
1363 (y+1) + ", month " + (mon+1) + ", day " + day;
1364 errln((UnicodeString)"FAIL: " + str);
374ca955 1365 logln( UnicodeString(" -> ") + CalendarTest::calToStr(cal) );
b75a7d8f
A
1366 } else {
1367 logln(str);
1368 }
1369
1370 fmt.format(t, str.remove());
1371 str += ".add(YEAR_WOY, 1)=>";
1372 cal.setTime(t, status);
374ca955 1373 logln( UnicodeString(" <- ") + CalendarTest::calToStr(cal) );
b75a7d8f
A
1374 cal.add(UCAL_YEAR_WOY, 1, status);
1375 int32_t ywy2 = cal.get(UCAL_YEAR_WOY, status);
1376 int32_t woy2 = cal.get(UCAL_WEEK_OF_YEAR, status);
1377 int32_t dow2 = cal.get(UCAL_DOW_LOCAL, status);
1378 fmt.format(cal.getTime(status), str);
1379 if (ywy2 != (ywy+1) || woy2 != woy || dow2 != dow) {
1380 str += (UnicodeString)", expected yearWOY " +
1381 (ywy+1) + ", woy " + woy + ", dowLocal " + dow;
1382 errln((UnicodeString)"FAIL: " + str);
374ca955 1383 logln( UnicodeString(" -> ") + CalendarTest::calToStr(cal) );
b75a7d8f
A
1384 } else {
1385 logln(str);
1386 }
1387}
1388
1389// -------------------------------------
1390
1391void CalendarTest::loop_addroll(Calendar *cal, /*SimpleDateFormat *sdf,*/ int times, UCalendarDateFields field, UCalendarDateFields field2, UErrorCode& errorCode) {
1392 Calendar *calclone;
1393 SimpleDateFormat fmt(UnicodeString("EEE MMM dd yyyy / YYYY'-W'ww-ee"), errorCode);
1394 fmt.setCalendar(*cal);
1395 int i;
1396
1397 for(i = 0; i<times; i++) {
1398 calclone = cal->clone();
1399 UDate start = cal->getTime(errorCode);
1400 cal->add(field,1,errorCode);
1401 if (U_FAILURE(errorCode)) { errln("Error in add"); delete calclone; return; }
1402 calclone->add(field2,1,errorCode);
1403 if (U_FAILURE(errorCode)) { errln("Error in add"); delete calclone; return; }
1404 if(cal->getTime(errorCode) != calclone->getTime(errorCode)) {
1405 UnicodeString str("FAIL: Results of add differ. "), str2;
1406 str += fmt.format(start, str2) + " ";
1407 str += UnicodeString("Add(") + fieldName(field) + ", 1) -> " +
1408 fmt.format(cal->getTime(errorCode), str2.remove()) + "; ";
1409 str += UnicodeString("Add(") + fieldName(field2) + ", 1) -> " +
1410 fmt.format(calclone->getTime(errorCode), str2.remove());
1411 errln(str);
1412 delete calclone;
1413 return;
1414 }
1415 delete calclone;
1416 }
1417
1418 for(i = 0; i<times; i++) {
1419 calclone = cal->clone();
1420 cal->roll(field,(int32_t)1,errorCode);
1421 if (U_FAILURE(errorCode)) { errln("Error in roll"); delete calclone; return; }
1422 calclone->roll(field2,(int32_t)1,errorCode);
1423 if (U_FAILURE(errorCode)) { errln("Error in roll"); delete calclone; return; }
1424 if(cal->getTime(errorCode) != calclone->getTime(errorCode)) {
1425 delete calclone;
1426 errln("Results of roll differ!");
1427 return;
1428 }
1429 delete calclone;
1430 }
1431}
1432
1433// -------------------------------------
1434
1435void
1436CalendarTest::doYEAR_WOYLoop(Calendar *cal, SimpleDateFormat *sdf,
1437 int32_t times, UErrorCode& errorCode) {
1438
1439 UnicodeString us;
1440 UDate tst, original;
1441 Calendar *tstres = new GregorianCalendar(Locale::getGermany(), errorCode);
1442 for(int i=0; i<times; ++i) {
1443 sdf->format(Formattable(cal->getTime(errorCode),Formattable::kIsDate), us, errorCode);
1444 //logln("expected: "+us);
1445 if (U_FAILURE(errorCode)) { errln("Format error"); return; }
1446 tst=sdf->parse(us,errorCode);
1447 if (U_FAILURE(errorCode)) { errln("Parse error"); return; }
1448 tstres->clear();
1449 tstres->setTime(tst, errorCode);
1450 //logln((UnicodeString)"Parsed week of year is "+tstres->get(UCAL_WEEK_OF_YEAR, errorCode));
1451 if (U_FAILURE(errorCode)) { errln("Set time error"); return; }
1452 original = cal->getTime(errorCode);
1453 us.remove();
1454 sdf->format(Formattable(tst,Formattable::kIsDate), us, errorCode);
1455 //logln("got: "+us);
1456 if (U_FAILURE(errorCode)) { errln("Get time error"); return; }
1457 if(original!=tst) {
1458 us.remove();
1459 sdf->format(Formattable(original, Formattable::kIsDate), us, errorCode);
374ca955
A
1460 errln("FAIL: Parsed time doesn't match with regular");
1461 logln("expected "+us + " " + calToStr(*cal));
b75a7d8f
A
1462 us.remove();
1463 sdf->format(Formattable(tst, Formattable::kIsDate), us, errorCode);
374ca955 1464 logln("got "+us + " " + calToStr(*tstres));
b75a7d8f
A
1465 }
1466 tstres->clear();
1467 tstres->set(UCAL_YEAR_WOY, cal->get(UCAL_YEAR_WOY, errorCode));
1468 tstres->set(UCAL_WEEK_OF_YEAR, cal->get(UCAL_WEEK_OF_YEAR, errorCode));
1469 tstres->set(UCAL_DOW_LOCAL, cal->get(UCAL_DOW_LOCAL, errorCode));
1470 if(cal->get(UCAL_YEAR, errorCode) != tstres->get(UCAL_YEAR, errorCode)) {
374ca955 1471 errln("FAIL: Different Year!");
b75a7d8f
A
1472 logln((UnicodeString)"Expected "+cal->get(UCAL_YEAR, errorCode));
1473 logln((UnicodeString)"Got "+tstres->get(UCAL_YEAR, errorCode));
1474 return;
1475 }
1476 if(cal->get(UCAL_DAY_OF_YEAR, errorCode) != tstres->get(UCAL_DAY_OF_YEAR, errorCode)) {
374ca955 1477 errln("FAIL: Different Day Of Year!");
b75a7d8f
A
1478 logln((UnicodeString)"Expected "+cal->get(UCAL_DAY_OF_YEAR, errorCode));
1479 logln((UnicodeString)"Got "+tstres->get(UCAL_DAY_OF_YEAR, errorCode));
1480 return;
1481 }
374ca955 1482 //logln(calToStr(*cal));
b75a7d8f
A
1483 cal->add(UCAL_DATE, 1, errorCode);
1484 if (U_FAILURE(errorCode)) { errln("Add error"); return; }
1485 us.remove();
1486 }
1487 delete (tstres);
1488}
1489// -------------------------------------
1490
1491void
1492CalendarTest::marchByDelta(Calendar* cal, int32_t delta)
1493{
1494 UErrorCode status = U_ZERO_ERROR;
1495 Calendar *cur = (Calendar*) cal->clone();
1496 int32_t initialDOW = cur->get(UCAL_DAY_OF_WEEK, status);
1497 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
1498 int32_t DOW, newDOW = initialDOW;
1499 do {
1500 UnicodeString str;
1501 DOW = newDOW;
1502 logln(UnicodeString("DOW = ") + DOW + " " + dateToString(cur->getTime(status), str));
1503 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; }
1504 cur->add(UCAL_DAY_OF_WEEK, delta, status);
1505 if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
1506 newDOW = cur->get(UCAL_DAY_OF_WEEK, status);
1507 if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
1508 int32_t expectedDOW = 1 + (DOW + delta - 1) % 7;
1509 if (newDOW != expectedDOW) {
1510 errln(UnicodeString("Day of week should be ") + expectedDOW + " instead of " + newDOW +
1511 " on " + dateToString(cur->getTime(status), str));
1512 if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; }
1513 return;
1514 }
1515 }
1516 while (newDOW != initialDOW);
1517 delete cur;
1518}
1519
1520#define CHECK(status, msg) \
1521 if (U_FAILURE(status)) { \
1522 errln(msg); \
1523 return; \
1524 }
1525
1526void CalendarTest::TestWOY(void) {
1527 /*
1528 FDW = Mon, MDFW = 4:
1529 Sun Dec 26 1999, WOY 51
1530 Mon Dec 27 1999, WOY 52
1531 Tue Dec 28 1999, WOY 52
1532 Wed Dec 29 1999, WOY 52
1533 Thu Dec 30 1999, WOY 52
1534 Fri Dec 31 1999, WOY 52
1535 Sat Jan 01 2000, WOY 52 ***
1536 Sun Jan 02 2000, WOY 52 ***
1537 Mon Jan 03 2000, WOY 1
1538 Tue Jan 04 2000, WOY 1
1539 Wed Jan 05 2000, WOY 1
1540 Thu Jan 06 2000, WOY 1
1541 Fri Jan 07 2000, WOY 1
1542 Sat Jan 08 2000, WOY 1
1543 Sun Jan 09 2000, WOY 1
1544 Mon Jan 10 2000, WOY 2
1545
1546 FDW = Mon, MDFW = 2:
1547 Sun Dec 26 1999, WOY 52
1548 Mon Dec 27 1999, WOY 1 ***
1549 Tue Dec 28 1999, WOY 1 ***
1550 Wed Dec 29 1999, WOY 1 ***
1551 Thu Dec 30 1999, WOY 1 ***
1552 Fri Dec 31 1999, WOY 1 ***
1553 Sat Jan 01 2000, WOY 1
1554 Sun Jan 02 2000, WOY 1
1555 Mon Jan 03 2000, WOY 2
1556 Tue Jan 04 2000, WOY 2
1557 Wed Jan 05 2000, WOY 2
1558 Thu Jan 06 2000, WOY 2
1559 Fri Jan 07 2000, WOY 2
1560 Sat Jan 08 2000, WOY 2
1561 Sun Jan 09 2000, WOY 2
1562 Mon Jan 10 2000, WOY 3
1563 */
374ca955 1564
b75a7d8f
A
1565 UnicodeString str;
1566 UErrorCode status = U_ZERO_ERROR;
1567 int32_t i;
1568
1569 GregorianCalendar cal(status);
1570 SimpleDateFormat fmt(UnicodeString("EEE MMM dd yyyy', WOY' w"), status);
1571 CHECK(status, "Fail: Cannot construct calendar/format");
1572
1573 UCalendarDaysOfWeek fdw = (UCalendarDaysOfWeek) 0;
1574
374ca955 1575 //for (int8_t pass=2; pass<=2; ++pass) {
b75a7d8f
A
1576 for (int8_t pass=1; pass<=2; ++pass) {
1577 switch (pass) {
1578 case 1:
1579 fdw = UCAL_MONDAY;
1580 cal.setFirstDayOfWeek(fdw);
1581 cal.setMinimalDaysInFirstWeek(4);
374ca955 1582 fmt.adoptCalendar(cal.clone());
b75a7d8f
A
1583 break;
1584 case 2:
1585 fdw = UCAL_MONDAY;
1586 cal.setFirstDayOfWeek(fdw);
1587 cal.setMinimalDaysInFirstWeek(2);
374ca955 1588 fmt.adoptCalendar(cal.clone());
b75a7d8f
A
1589 break;
1590 }
1591
374ca955
A
1592 //for (i=2; i<=6; ++i) {
1593 for (i=0; i<16; ++i) {
b75a7d8f
A
1594 UDate t, t2;
1595 int32_t t_y, t_woy, t_dow;
1596 cal.clear();
1597 cal.set(1999, UCAL_DECEMBER, 26 + i);
1598 fmt.format(t = cal.getTime(status), str.remove());
1599 CHECK(status, "Fail: getTime failed");
374ca955 1600 logln(UnicodeString("* ") + str);
b75a7d8f
A
1601 int32_t dow = cal.get(UCAL_DAY_OF_WEEK, status);
1602 int32_t woy = cal.get(UCAL_WEEK_OF_YEAR, status);
1603 int32_t year = cal.get(UCAL_YEAR, status);
1604 int32_t mon = cal.get(UCAL_MONTH, status);
374ca955 1605 logln(calToStr(cal));
b75a7d8f
A
1606 CHECK(status, "Fail: get failed");
1607 int32_t dowLocal = dow - fdw;
1608 if (dowLocal < 0) dowLocal += 7;
1609 dowLocal++;
1610 int32_t yearWoy = year;
1611 if (mon == UCAL_JANUARY) {
1612 if (woy >= 52) --yearWoy;
1613 } else {
1614 if (woy == 1) ++yearWoy;
1615 }
1616
1617 // Basic fields->time check y/woy/dow
1618 // Since Y/WOY is ambiguous, we do a check of the fields,
1619 // not of the specific time.
1620 cal.clear();
1621 cal.set(UCAL_YEAR, year);
1622 cal.set(UCAL_WEEK_OF_YEAR, woy);
1623 cal.set(UCAL_DAY_OF_WEEK, dow);
1624 t_y = cal.get(UCAL_YEAR, status);
1625 t_woy = cal.get(UCAL_WEEK_OF_YEAR, status);
1626 t_dow = cal.get(UCAL_DAY_OF_WEEK, status);
1627 CHECK(status, "Fail: get failed");
1628 if (t_y != year || t_woy != woy || t_dow != dow) {
1629 str = "Fail: y/woy/dow fields->time => ";
1630 fmt.format(cal.getTime(status), str);
1631 errln(str);
374ca955
A
1632 logln(calToStr(cal));
1633 logln("[get!=set] Y%d!=%d || woy%d!=%d || dow%d!=%d\n",
1634 t_y, year, t_woy, woy, t_dow, dow);
1635 } else {
1636 logln("y/woy/dow fields->time OK");
b75a7d8f
A
1637 }
1638
1639 // Basic fields->time check y/woy/dow_local
1640 // Since Y/WOY is ambiguous, we do a check of the fields,
1641 // not of the specific time.
1642 cal.clear();
1643 cal.set(UCAL_YEAR, year);
1644 cal.set(UCAL_WEEK_OF_YEAR, woy);
1645 cal.set(UCAL_DOW_LOCAL, dowLocal);
1646 t_y = cal.get(UCAL_YEAR, status);
1647 t_woy = cal.get(UCAL_WEEK_OF_YEAR, status);
1648 t_dow = cal.get(UCAL_DOW_LOCAL, status);
1649 CHECK(status, "Fail: get failed");
1650 if (t_y != year || t_woy != woy || t_dow != dowLocal) {
1651 str = "Fail: y/woy/dow_local fields->time => ";
1652 fmt.format(cal.getTime(status), str);
1653 errln(str);
1654 }
1655
1656 // Basic fields->time check y_woy/woy/dow
1657 cal.clear();
1658 cal.set(UCAL_YEAR_WOY, yearWoy);
1659 cal.set(UCAL_WEEK_OF_YEAR, woy);
1660 cal.set(UCAL_DAY_OF_WEEK, dow);
1661 t2 = cal.getTime(status);
1662 CHECK(status, "Fail: getTime failed");
1663 if (t != t2) {
1664 str = "Fail: y_woy/woy/dow fields->time => ";
1665 fmt.format(t2, str);
1666 errln(str);
374ca955
A
1667 logln(calToStr(cal));
1668 logln("%.f != %.f\n", t, t2);
1669 } else {
1670 logln("y_woy/woy/dow OK");
b75a7d8f
A
1671 }
1672
1673 // Basic fields->time check y_woy/woy/dow_local
1674 cal.clear();
1675 cal.set(UCAL_YEAR_WOY, yearWoy);
1676 cal.set(UCAL_WEEK_OF_YEAR, woy);
1677 cal.set(UCAL_DOW_LOCAL, dowLocal);
1678 t2 = cal.getTime(status);
1679 CHECK(status, "Fail: getTime failed");
1680 if (t != t2) {
1681 str = "Fail: y_woy/woy/dow_local fields->time => ";
1682 fmt.format(t2, str);
1683 errln(str);
1684 }
1685
374ca955 1686 logln("Testing DOW_LOCAL.. dow%d\n", dow);
b75a7d8f
A
1687 // Make sure DOW_LOCAL disambiguates over DOW
1688 int32_t wrongDow = dow - 3;
1689 if (wrongDow < 1) wrongDow += 7;
1690 cal.setTime(t, status);
1691 cal.set(UCAL_DAY_OF_WEEK, wrongDow);
1692 cal.set(UCAL_DOW_LOCAL, dowLocal);
1693 t2 = cal.getTime(status);
1694 CHECK(status, "Fail: set/getTime failed");
1695 if (t != t2) {
1696 str = "Fail: DOW_LOCAL fields->time => ";
1697 fmt.format(t2, str);
1698 errln(str);
374ca955
A
1699 logln(calToStr(cal));
1700 logln("%.f : DOW%d, DOW_LOCAL%d -> %.f\n",
1701 t, wrongDow, dowLocal, t2);
b75a7d8f
A
1702 }
1703
1704 // Make sure DOW disambiguates over DOW_LOCAL
1705 int32_t wrongDowLocal = dowLocal - 3;
1706 if (wrongDowLocal < 1) wrongDowLocal += 7;
1707 cal.setTime(t, status);
1708 cal.set(UCAL_DOW_LOCAL, wrongDowLocal);
1709 cal.set(UCAL_DAY_OF_WEEK, dow);
1710 t2 = cal.getTime(status);
1711 CHECK(status, "Fail: set/getTime failed");
1712 if (t != t2) {
1713 str = "Fail: DOW fields->time => ";
1714 fmt.format(t2, str);
1715 errln(str);
1716 }
1717
1718 // Make sure YEAR_WOY disambiguates over YEAR
1719 cal.setTime(t, status);
1720 cal.set(UCAL_YEAR, year - 2);
1721 cal.set(UCAL_YEAR_WOY, yearWoy);
1722 t2 = cal.getTime(status);
1723 CHECK(status, "Fail: set/getTime failed");
1724 if (t != t2) {
1725 str = "Fail: YEAR_WOY fields->time => ";
1726 fmt.format(t2, str);
1727 errln(str);
1728 }
1729
1730 // Make sure YEAR disambiguates over YEAR_WOY
1731 cal.setTime(t, status);
1732 cal.set(UCAL_YEAR_WOY, yearWoy - 2);
1733 cal.set(UCAL_YEAR, year);
1734 t2 = cal.getTime(status);
1735 CHECK(status, "Fail: set/getTime failed");
1736 if (t != t2) {
1737 str = "Fail: YEAR fields->time => ";
1738 fmt.format(t2, str);
1739 errln(str);
1740 }
1741 }
1742 }
1743
1744 /*
1745 FDW = Mon, MDFW = 4:
1746 Sun Dec 26 1999, WOY 51
1747 Mon Dec 27 1999, WOY 52
1748 Tue Dec 28 1999, WOY 52
1749 Wed Dec 29 1999, WOY 52
1750 Thu Dec 30 1999, WOY 52
1751 Fri Dec 31 1999, WOY 52
1752 Sat Jan 01 2000, WOY 52
1753 Sun Jan 02 2000, WOY 52
1754 */
1755
1756 // Roll the DOW_LOCAL within week 52
1757 for (i=27; i<=33; ++i) {
1758 int32_t amount;
1759 for (amount=-7; amount<=7; ++amount) {
1760 str = "roll(";
1761 cal.set(1999, UCAL_DECEMBER, i);
1762 UDate t, t2;
1763 fmt.format(cal.getTime(status), str);
1764 CHECK(status, "Fail: getTime failed");
1765 str += UnicodeString(", ") + amount + ") = ";
1766
1767 cal.roll(UCAL_DOW_LOCAL, amount, status);
1768 CHECK(status, "Fail: roll failed");
1769
1770 t = cal.getTime(status);
1771 int32_t newDom = i + amount;
1772 while (newDom < 27) newDom += 7;
1773 while (newDom > 33) newDom -= 7;
1774 cal.set(1999, UCAL_DECEMBER, newDom);
1775 t2 = cal.getTime(status);
1776 CHECK(status, "Fail: getTime failed");
1777 fmt.format(t, str);
1778
1779 if (t != t2) {
1780 str.append(", exp ");
1781 fmt.format(t2, str);
1782 errln(str);
1783 } else {
1784 logln(str);
1785 }
1786 }
1787 }
1788}
1789
374ca955
A
1790void CalendarTest::TestYWOY()
1791{
1792 UnicodeString str;
1793 UErrorCode status = U_ZERO_ERROR;
1794
1795 GregorianCalendar cal(status);
1796 CHECK(status, "Fail: Cannot construct calendar/format");
1797
1798 cal.setFirstDayOfWeek(UCAL_SUNDAY);
1799 cal.setMinimalDaysInFirstWeek(1);
1800
1801 logln("Setting: ywoy=2004, woy=1, dow=MONDAY");
1802 cal.clear();
1803 cal.set(UCAL_YEAR_WOY,2004);
1804 cal.set(UCAL_WEEK_OF_YEAR,1);
1805 cal.set(UCAL_DAY_OF_WEEK, UCAL_MONDAY);
1806
1807 logln(calToStr(cal));
1808 if(cal.get(UCAL_YEAR, status) != 2003) {
1809 errln("year not 2003");
1810 }
1811
1812 logln("+ setting DOW to THURSDAY");
1813 cal.clear();
1814 cal.set(UCAL_YEAR_WOY,2004);
1815 cal.set(UCAL_WEEK_OF_YEAR,1);
1816 cal.set(UCAL_DAY_OF_WEEK, UCAL_THURSDAY);
1817
1818 logln(calToStr(cal));
1819 if(cal.get(UCAL_YEAR, status) != 2004) {
1820 errln("year not 2004");
1821 }
1822
1823 logln("+ setting DOW_LOCAL to 1");
1824 cal.clear();
1825 cal.set(UCAL_YEAR_WOY,2004);
1826 cal.set(UCAL_WEEK_OF_YEAR,1);
1827 cal.set(UCAL_DAY_OF_WEEK, UCAL_THURSDAY);
1828 cal.set(UCAL_DOW_LOCAL, 1);
1829
1830 logln(calToStr(cal));
1831 if(cal.get(UCAL_YEAR, status) != 2003) {
1832 errln("year not 2003");
1833 }
1834
1835 cal.setFirstDayOfWeek(UCAL_MONDAY);
1836 cal.setMinimalDaysInFirstWeek(4);
1837 UDate t = 946713600000.;
1838 cal.setTime(t, status);
1839 cal.set(UCAL_DAY_OF_WEEK, 4);
1840 cal.set(UCAL_DOW_LOCAL, 6);
1841 if(cal.getTime(status) != t) {
1842 logln(calToStr(cal));
1843 errln("FAIL: DOW_LOCAL did not take precedence");
1844 }
1845
1846}
1847
1848void CalendarTest::TestJD()
1849{
1850 int32_t jd;
1851 static const int32_t kEpochStartAsJulianDay = 2440588;
1852 UErrorCode status = U_ZERO_ERROR;
1853 GregorianCalendar cal(status);
1854 cal.setTimeZone(*TimeZone::getGMT());
1855 cal.clear();
1856 jd = cal.get(UCAL_JULIAN_DAY, status);
1857 if(jd != kEpochStartAsJulianDay) {
1858 errln("Wanted JD of %d at time=0, [epoch 1970] but got %d\n", kEpochStartAsJulianDay, jd);
1859 } else {
1860 logln("Wanted JD of %d at time=0, [epoch 1970], got %d\n", kEpochStartAsJulianDay, jd);
1861 }
1862
1863 cal.setTime(Calendar::getNow(), status);
1864 cal.clear();
1865 cal.set(UCAL_JULIAN_DAY, kEpochStartAsJulianDay);
1866 UDate epochTime = cal.getTime(status);
1867 if(epochTime != 0) {
1868 errln("Wanted time of 0 at jd=%d, got %.1lf\n", kEpochStartAsJulianDay, epochTime);
1869 } else {
1870 logln("Wanted time of 0 at jd=%d, got %.1lf\n", kEpochStartAsJulianDay, epochTime);
1871 }
1872
1873}
1874
b75a7d8f
A
1875#undef CHECK
1876
374ca955
A
1877// List of interesting locales
1878const char *CalendarTest::testLocaleID(int32_t i)
1879{
1880 switch(i) {
1881 case 0: return "he_IL@calendar=hebrew";
1882 case 1: return "en_US@calendar=hebrew";
1883 case 2: return "fr_FR@calendar=hebrew";
1884 case 3: return "fi_FI@calendar=hebrew";
1885 case 4: return "nl_NL@calendar=hebrew";
1886 case 5: return "hu_HU@calendar=hebrew";
1887 case 6: return "nl_BE@currency=MTL;calendar=islamic";
1888 case 7: return "th_TH_TRADITIONAL@calendar=gregorian";
1889 case 8: return "ar_JO@calendar=islamic-civil";
1890 case 9: return "fi_FI@calendar=islamic";
1891 case 10: return "fr_CH@calendar=islamic-civil";
1892 case 11: return "he_IL@calendar=islamic-civil";
1893 case 12: return "hu_HU@calendar=buddhist";
1894 case 13: return "hu_HU@calendar=islamic";
1895 case 14: return "en_US@calendar=japanese";
1896 default: return NULL;
1897 }
1898}
1899
1900int32_t CalendarTest::testLocaleCount()
1901{
1902 static int32_t gLocaleCount = -1;
1903 if(gLocaleCount < 0) {
1904 int32_t i;
1905 for(i=0;testLocaleID(i) != NULL;i++) {
1906 ;
1907 }
1908 gLocaleCount = i;
1909 }
1910 return gLocaleCount;
1911}
1912
1913static UDate doMinDateOfCalendar(Calendar* adopt, UBool &isGregorian, UErrorCode& status) {
1914 if(U_FAILURE(status)) return 0.0;
1915
1916 adopt->clear();
1917 adopt->set(UCAL_EXTENDED_YEAR, adopt->getActualMinimum(UCAL_EXTENDED_YEAR, status));
1918 UDate ret = adopt->getTime(status);
1919 isGregorian = (adopt->getDynamicClassID() == GregorianCalendar::getStaticClassID());
1920 delete adopt;
1921 return ret;
1922}
1923
1924UDate CalendarTest::minDateOfCalendar(const Locale& locale, UBool &isGregorian, UErrorCode& status) {
1925 if(U_FAILURE(status)) return 0.0;
1926 return doMinDateOfCalendar(Calendar::createInstance(locale, status), isGregorian, status);
1927}
1928
1929UDate CalendarTest::minDateOfCalendar(const Calendar& cal, UBool &isGregorian, UErrorCode& status) {
1930 if(U_FAILURE(status)) return 0.0;
1931 return doMinDateOfCalendar(cal.clone(), isGregorian, status);
1932}
1933
1934
1935
b75a7d8f
A
1936#endif /* #if !UCONFIG_NO_FORMATTING */
1937
1938//eof