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