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