Home | History | Annotate | Download | only in intltest
      1 /************************************************************************
      2  * COPYRIGHT:
      3  * Copyright (c) 1997-2013, International Business Machines Corporation
      4  * and others. All Rights Reserved.
      5  ************************************************************************/
      6 #include "unicode/utypes.h"
      7 
      8 #if !UCONFIG_NO_FORMATTING
      9 
     10 #include "caltest.h"
     11 #include "unicode/dtfmtsym.h"
     12 #include "unicode/gregocal.h"
     13 #include "unicode/localpointer.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 #include "unicode/localpointer.h"
     22 #include "islamcal.h"
     23 
     24 #define mkcstr(U) u_austrcpy(calloc(8, u_strlen(U) + 1), U)
     25 
     26 #define TEST_CHECK_STATUS { \
     27     if (U_FAILURE(status)) { \
     28         if (status == U_MISSING_RESOURCE_ERROR) { \
     29             dataerrln("%s:%d: Test failure.  status=%s", __FILE__, __LINE__, u_errorName(status)); \
     30         } else { \
     31             errln("%s:%d: Test failure.  status=%s", __FILE__, __LINE__, u_errorName(status)); \
     32         } return;}}
     33 
     34 #define TEST_ASSERT(expr) {if ((expr)==FALSE) {errln("%s:%d: Test failure \n", __FILE__, __LINE__);};}
     35 
     36 // *****************************************************************************
     37 // class CalendarTest
     38 // *****************************************************************************
     39 
     40 UnicodeString CalendarTest::calToStr(const Calendar & cal)
     41 {
     42   UnicodeString out;
     43   UErrorCode status = U_ZERO_ERROR;
     44   int i;
     45   UDate d;
     46   for(i = 0;i<UCAL_FIELD_COUNT;i++) {
     47     out += (UnicodeString("") + fieldName((UCalendarDateFields)i) + "=" +  cal.get((UCalendarDateFields)i, status) + UnicodeString(" "));
     48   }
     49   out += "[" + UnicodeString(cal.getType()) + "]";
     50 
     51   if(cal.inDaylightTime(status)) {
     52     out += UnicodeString(" (in DST), zone=");
     53   }
     54   else {
     55     out += UnicodeString(", zone=");
     56   }
     57 
     58   UnicodeString str2;
     59   out += cal.getTimeZone().getDisplayName(str2);
     60   d = cal.getTime(status);
     61   out += UnicodeString(" :","") + d;
     62 
     63   return out;
     64 }
     65 
     66 void CalendarTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
     67 {
     68     if (exec) logln("TestSuite TestCalendar");
     69     switch (index) {
     70         case 0:
     71             name = "TestDOW943";
     72             if (exec) {
     73                 logln("TestDOW943---"); logln("");
     74                 TestDOW943();
     75             }
     76             break;
     77         case 1:
     78             name = "TestClonesUnique908";
     79             if (exec) {
     80                 logln("TestClonesUnique908---"); logln("");
     81                 TestClonesUnique908();
     82             }
     83             break;
     84         case 2:
     85             name = "TestGregorianChange768";
     86             if (exec) {
     87                 logln("TestGregorianChange768---"); logln("");
     88                 TestGregorianChange768();
     89             }
     90             break;
     91         case 3:
     92             name = "TestDisambiguation765";
     93             if (exec) {
     94                 logln("TestDisambiguation765---"); logln("");
     95                 TestDisambiguation765();
     96             }
     97             break;
     98         case 4:
     99             name = "TestGMTvsLocal4064654";
    100             if (exec) {
    101                 logln("TestGMTvsLocal4064654---"); logln("");
    102                 TestGMTvsLocal4064654();
    103             }
    104             break;
    105         case 5:
    106             name = "TestAddSetOrder621";
    107             if (exec) {
    108                 logln("TestAddSetOrder621---"); logln("");
    109                 TestAddSetOrder621();
    110             }
    111             break;
    112         case 6:
    113             name = "TestAdd520";
    114             if (exec) {
    115                 logln("TestAdd520---"); logln("");
    116                 TestAdd520();
    117             }
    118             break;
    119         case 7:
    120             name = "TestFieldSet4781";
    121             if (exec) {
    122                 logln("TestFieldSet4781---"); logln("");
    123                 TestFieldSet4781();
    124             }
    125             break;
    126         case 8:
    127             name = "TestSerialize337";
    128             if (exec) {
    129                 logln("TestSerialize337---"); logln("");
    130             //  TestSerialize337();
    131             }
    132             break;
    133         case 9:
    134             name = "TestSecondsZero121";
    135             if (exec) {
    136                 logln("TestSecondsZero121---"); logln("");
    137                 TestSecondsZero121();
    138             }
    139             break;
    140         case 10:
    141             name = "TestAddSetGet0610";
    142             if (exec) {
    143                 logln("TestAddSetGet0610---"); logln("");
    144                 TestAddSetGet0610();
    145             }
    146             break;
    147         case 11:
    148             name = "TestFields060";
    149             if (exec) {
    150                 logln("TestFields060---"); logln("");
    151                 TestFields060();
    152             }
    153             break;
    154         case 12:
    155             name = "TestEpochStartFields";
    156             if (exec) {
    157                 logln("TestEpochStartFields---"); logln("");
    158                 TestEpochStartFields();
    159             }
    160             break;
    161         case 13:
    162             name = "TestDOWProgression";
    163             if (exec) {
    164                 logln("TestDOWProgression---"); logln("");
    165                 TestDOWProgression();
    166             }
    167             break;
    168         case 14:
    169             name = "TestGenericAPI";
    170             if (exec) {
    171                 logln("TestGenericAPI---"); logln("");
    172                 TestGenericAPI();
    173             }
    174             break;
    175         case 15:
    176             name = "TestAddRollExtensive";
    177             if (exec) {
    178                 logln("TestAddRollExtensive---"); logln("");
    179                 TestAddRollExtensive();
    180             }
    181             break;
    182         case 16:
    183             name = "TestDOW_LOCALandYEAR_WOY";
    184             if (exec) {
    185                 logln("TestDOW_LOCALandYEAR_WOY---"); logln("");
    186                 TestDOW_LOCALandYEAR_WOY();
    187             }
    188             break;
    189         case 17:
    190             name = "TestWOY";
    191             if (exec) {
    192                 logln("TestWOY---"); logln("");
    193                 TestWOY();
    194             }
    195             break;
    196         case 18:
    197             name = "TestRog";
    198             if (exec) {
    199                 logln("TestRog---"); logln("");
    200                 TestRog();
    201             }
    202             break;
    203         case 19:
    204            name = "TestYWOY";
    205             if (exec) {
    206                 logln("TestYWOY---"); logln("");
    207                 TestYWOY();
    208             }
    209             break;
    210         case 20:
    211           name = "TestJD";
    212           if(exec) {
    213             logln("TestJD---"); logln("");
    214             TestJD();
    215           }
    216           break;
    217         case 21:
    218           name = "TestDebug";
    219           if(exec) {
    220             logln("TestDebug---"); logln("");
    221             TestDebug();
    222           }
    223           break;
    224         case 22:
    225           name = "Test6703";
    226           if(exec) {
    227             logln("Test6703---"); logln("");
    228             Test6703();
    229           }
    230           break;
    231         case 23:
    232           name = "Test3785";
    233           if(exec) {
    234             logln("Test3785---"); logln("");
    235             Test3785();
    236           }
    237           break;
    238         case 24:
    239           name = "Test1624";
    240           if(exec) {
    241             logln("Test1624---"); logln("");
    242             Test1624();
    243           }
    244           break;
    245         case 25:
    246           name = "TestTimeStamp";
    247           if(exec) {
    248             logln("TestTimeStamp---"); logln("");
    249             TestTimeStamp();
    250           }
    251           break;
    252         case 26:
    253           name = "TestISO8601";
    254           if(exec) {
    255             logln("TestISO8601---"); logln("");
    256             TestISO8601();
    257           }
    258           break;
    259         case 27:
    260           name = "TestAmbiguousWallTimeAPIs";
    261           if(exec) {
    262             logln("TestAmbiguousWallTimeAPIs---"); logln("");
    263             TestAmbiguousWallTimeAPIs();
    264           }
    265           break;
    266         case 28:
    267           name = "TestRepeatedWallTime";
    268           if(exec) {
    269             logln("TestRepeatedWallTime---"); logln("");
    270             TestRepeatedWallTime();
    271           }
    272           break;
    273         case 29:
    274           name = "TestSkippedWallTime";
    275           if(exec) {
    276             logln("TestSkippedWallTime---"); logln("");
    277             TestSkippedWallTime();
    278           }
    279           break;
    280         case 30:
    281           name = "TestCloneLocale";
    282           if(exec) {
    283             logln("TestCloneLocale---"); logln("");
    284             TestCloneLocale();
    285           }
    286           break;
    287         case 31:
    288           name = "TestIslamicUmAlQura";
    289           if(exec) {
    290             logln("TestIslamicUmAlQura---"); logln("");
    291             TestIslamicUmAlQura();
    292           }
    293           break;
    294         case 32:
    295           name = "TestIslamicTabularDates";
    296           if(exec) {
    297             logln("TestIslamicTabularDates---"); logln("");
    298             TestIslamicTabularDates();
    299           }
    300           break;
    301         default: name = ""; break;
    302     }
    303 }
    304 
    305 // ---------------------------------------------------------------------------------
    306 
    307 UnicodeString CalendarTest::fieldName(UCalendarDateFields f) {
    308     switch (f) {
    309 #define FIELD_NAME_STR(x) case x: return (#x+5)
    310       FIELD_NAME_STR( UCAL_ERA );
    311       FIELD_NAME_STR( UCAL_YEAR );
    312       FIELD_NAME_STR( UCAL_MONTH );
    313       FIELD_NAME_STR( UCAL_WEEK_OF_YEAR );
    314       FIELD_NAME_STR( UCAL_WEEK_OF_MONTH );
    315       FIELD_NAME_STR( UCAL_DATE );
    316       FIELD_NAME_STR( UCAL_DAY_OF_YEAR );
    317       FIELD_NAME_STR( UCAL_DAY_OF_WEEK );
    318       FIELD_NAME_STR( UCAL_DAY_OF_WEEK_IN_MONTH );
    319       FIELD_NAME_STR( UCAL_AM_PM );
    320       FIELD_NAME_STR( UCAL_HOUR );
    321       FIELD_NAME_STR( UCAL_HOUR_OF_DAY );
    322       FIELD_NAME_STR( UCAL_MINUTE );
    323       FIELD_NAME_STR( UCAL_SECOND );
    324       FIELD_NAME_STR( UCAL_MILLISECOND );
    325       FIELD_NAME_STR( UCAL_ZONE_OFFSET );
    326       FIELD_NAME_STR( UCAL_DST_OFFSET );
    327       FIELD_NAME_STR( UCAL_YEAR_WOY );
    328       FIELD_NAME_STR( UCAL_DOW_LOCAL );
    329       FIELD_NAME_STR( UCAL_EXTENDED_YEAR );
    330       FIELD_NAME_STR( UCAL_JULIAN_DAY );
    331       FIELD_NAME_STR( UCAL_MILLISECONDS_IN_DAY );
    332 #undef FIELD_NAME_STR
    333     default:
    334         return UnicodeString("") + ((int32_t)f);
    335     }
    336 }
    337 
    338 /**
    339  * Test various API methods for API completeness.
    340  */
    341 void
    342 CalendarTest::TestGenericAPI()
    343 {
    344     UErrorCode status = U_ZERO_ERROR;
    345     UDate d;
    346     UnicodeString str;
    347     UBool eq = FALSE,b4 = FALSE,af = FALSE;
    348 
    349     UDate when = date(90, UCAL_APRIL, 15);
    350 
    351     UnicodeString tzid("TestZone");
    352     int32_t tzoffset = 123400;
    353 
    354     SimpleTimeZone *zone = new SimpleTimeZone(tzoffset, tzid);
    355     Calendar *cal = Calendar::createInstance(zone->clone(), status);
    356     if (failure(status, "Calendar::createInstance", TRUE)) return;
    357 
    358     if (*zone != cal->getTimeZone()) errln("FAIL: Calendar::getTimeZone failed");
    359 
    360     Calendar *cal2 = Calendar::createInstance(cal->getTimeZone(), status);
    361     if (failure(status, "Calendar::createInstance")) return;
    362     cal->setTime(when, status);
    363     cal2->setTime(when, status);
    364     if (failure(status, "Calendar::setTime")) return;
    365 
    366     if (!(*cal == *cal2)) errln("FAIL: Calendar::operator== failed");
    367     if ((*cal != *cal2))  errln("FAIL: Calendar::operator!= failed");
    368     if (!cal->equals(*cal2, status) ||
    369         cal->before(*cal2, status) ||
    370         cal->after(*cal2, status) ||
    371         U_FAILURE(status)) errln("FAIL: equals/before/after failed");
    372 
    373     logln(UnicodeString("cal=")  +cal->getTime(status)  + UnicodeString(calToStr(*cal)));
    374     logln(UnicodeString("cal2=")  +cal2->getTime(status)  + UnicodeString(calToStr(*cal2)));
    375     logln("cal2->setTime(when+1000)");
    376     cal2->setTime(when + 1000, status);
    377     logln(UnicodeString("cal2=")  +cal2->getTime(status)  + UnicodeString(calToStr(*cal2)));
    378 
    379     if (failure(status, "Calendar::setTime")) return;
    380     if (cal->equals(*cal2, status) ||
    381         cal2->before(*cal, status) ||
    382         cal->after(*cal2, status) ||
    383         U_FAILURE(status)) errln("FAIL: equals/before/after failed after setTime(+1000)");
    384 
    385     logln("cal->roll(UCAL_SECOND)");
    386     cal->roll(UCAL_SECOND, (UBool) TRUE, status);
    387     logln(UnicodeString("cal=")  +cal->getTime(status)  + UnicodeString(calToStr(*cal)));
    388     cal->roll(UCAL_SECOND, (int32_t)0, status);
    389     logln(UnicodeString("cal=")  +cal->getTime(status)  + UnicodeString(calToStr(*cal)));
    390     if (failure(status, "Calendar::roll")) return;
    391 
    392     if (!(eq=cal->equals(*cal2, status)) ||
    393         (b4=cal->before(*cal2, status)) ||
    394         (af=cal->after(*cal2, status)) ||
    395         U_FAILURE(status)) {
    396       errln("FAIL: equals[%c]/before[%c]/after[%c] failed after roll 1 second [should be T/F/F]",
    397             eq?'T':'F',
    398             b4?'T':'F',
    399             af?'T':'F');
    400       logln(UnicodeString("cal=")  +cal->getTime(status)  + UnicodeString(calToStr(*cal)));
    401       logln(UnicodeString("cal2=")  +cal2->getTime(status)  + UnicodeString(calToStr(*cal2)));
    402     }
    403 
    404     // Roll back to January
    405     cal->roll(UCAL_MONTH, (int32_t)(1 + UCAL_DECEMBER - cal->get(UCAL_MONTH, status)), status);
    406     if (failure(status, "Calendar::roll")) return;
    407     if (cal->equals(*cal2, status) ||
    408         cal2->before(*cal, status) ||
    409         cal->after(*cal2, status) ||
    410         U_FAILURE(status)) errln("FAIL: equals/before/after failed after rollback to January");
    411 
    412     TimeZone *z = cal->orphanTimeZone();
    413     if (z->getID(str) != tzid ||
    414         z->getRawOffset() != tzoffset)
    415         errln("FAIL: orphanTimeZone failed");
    416 
    417     int32_t i;
    418     for (i=0; i<2; ++i)
    419     {
    420         UBool lenient = ( i > 0 );
    421         cal->setLenient(lenient);
    422         if (lenient != cal->isLenient()) errln("FAIL: setLenient/isLenient failed");
    423         // Later: Check for lenient behavior
    424     }
    425 
    426     for (i=UCAL_SUNDAY; i<=UCAL_SATURDAY; ++i)
    427     {
    428         cal->setFirstDayOfWeek((UCalendarDaysOfWeek)i);
    429         if (cal->getFirstDayOfWeek() != i) errln("FAIL: set/getFirstDayOfWeek failed");
    430         UErrorCode aStatus = U_ZERO_ERROR;
    431         if (cal->getFirstDayOfWeek(aStatus) != i || U_FAILURE(aStatus)) errln("FAIL: getFirstDayOfWeek(status) failed");
    432     }
    433 
    434     for (i=1; i<=7; ++i)
    435     {
    436         cal->setMinimalDaysInFirstWeek((uint8_t)i);
    437         if (cal->getMinimalDaysInFirstWeek() != i) errln("FAIL: set/getFirstDayOfWeek failed");
    438     }
    439 
    440     for (i=0; i<UCAL_FIELD_COUNT; ++i)
    441     {
    442         if (cal->getMinimum((UCalendarDateFields)i) > cal->getGreatestMinimum((UCalendarDateFields)i))
    443             errln(UnicodeString("FAIL: getMinimum larger than getGreatestMinimum for field ") + i);
    444         if (cal->getLeastMaximum((UCalendarDateFields)i) > cal->getMaximum((UCalendarDateFields)i))
    445             errln(UnicodeString("FAIL: getLeastMaximum larger than getMaximum for field ") + i);
    446         if (cal->getMinimum((UCalendarDateFields)i) >= cal->getMaximum((UCalendarDateFields)i))
    447             errln(UnicodeString("FAIL: getMinimum not less than getMaximum for field ") + i);
    448     }
    449 
    450     cal->adoptTimeZone(TimeZone::createDefault());
    451     cal->clear();
    452     cal->set(1984, 5, 24);
    453     if (cal->getTime(status) != date(84, 5, 24) || U_FAILURE(status))
    454         errln("FAIL: Calendar::set(3 args) failed");
    455 
    456     cal->clear();
    457     cal->set(1985, 3, 2, 11, 49);
    458     if (cal->getTime(status) != date(85, 3, 2, 11, 49) || U_FAILURE(status))
    459         errln("FAIL: Calendar::set(5 args) failed");
    460 
    461     cal->clear();
    462     cal->set(1995, 9, 12, 1, 39, 55);
    463     if (cal->getTime(status) != date(95, 9, 12, 1, 39, 55) || U_FAILURE(status))
    464         errln("FAIL: Calendar::set(6 args) failed");
    465 
    466     cal->getTime(status);
    467     if (failure(status, "Calendar::getTime")) return;
    468     for (i=0; i<UCAL_FIELD_COUNT; ++i)
    469     {
    470         switch(i) {
    471             case UCAL_YEAR: case UCAL_MONTH: case UCAL_DATE:
    472             case UCAL_HOUR_OF_DAY: case UCAL_MINUTE: case UCAL_SECOND:
    473             case UCAL_EXTENDED_YEAR:
    474               if (!cal->isSet((UCalendarDateFields)i)) errln("FAIL: Calendar::isSet F, should be T " + fieldName((UCalendarDateFields)i));
    475                 break;
    476             default:
    477               if (cal->isSet((UCalendarDateFields)i)) errln("FAIL: Calendar::isSet = T, should be F  " + fieldName((UCalendarDateFields)i));
    478         }
    479         cal->clear((UCalendarDateFields)i);
    480         if (cal->isSet((UCalendarDateFields)i)) errln("FAIL: Calendar::clear/isSet failed " + fieldName((UCalendarDateFields)i));
    481     }
    482 
    483     if(cal->getActualMinimum(Calendar::SECOND, status) != 0){
    484         errln("Calendar is suppose to return 0 for getActualMinimum");
    485     }
    486 
    487     Calendar *cal3 = Calendar::createInstance(status);
    488     cal3->roll(Calendar::SECOND, (int32_t)0, status);
    489     if (failure(status, "Calendar::roll(EDateFields, int32_t, UErrorCode)")) return;
    490 
    491     delete cal;
    492     delete cal2;
    493     delete cal3;
    494 
    495     int32_t count;
    496     const Locale* loc = Calendar::getAvailableLocales(count);
    497     if (count < 1 || loc == 0)
    498     {
    499         dataerrln("FAIL: getAvailableLocales failed");
    500     }
    501     else
    502     {
    503         for (i=0; i<count; ++i)
    504         {
    505             cal = Calendar::createInstance(loc[i], status);
    506             if (failure(status, "Calendar::createInstance")) return;
    507             delete cal;
    508         }
    509     }
    510 
    511     cal = Calendar::createInstance(TimeZone::createDefault(), Locale::getEnglish(), status);
    512     if (failure(status, "Calendar::createInstance")) return;
    513     delete cal;
    514 
    515     cal = Calendar::createInstance(*zone, Locale::getEnglish(), status);
    516     if (failure(status, "Calendar::createInstance")) return;
    517     delete cal;
    518 
    519     GregorianCalendar *gc = new GregorianCalendar(*zone, status);
    520     if (failure(status, "new GregorianCalendar")) return;
    521     delete gc;
    522 
    523     gc = new GregorianCalendar(Locale::getEnglish(), status);
    524     if (failure(status, "new GregorianCalendar")) return;
    525     delete gc;
    526 
    527     gc = new GregorianCalendar(Locale::getEnglish(), status);
    528     delete gc;
    529 
    530     gc = new GregorianCalendar(*zone, Locale::getEnglish(), status);
    531     if (failure(status, "new GregorianCalendar")) return;
    532     delete gc;
    533 
    534     gc = new GregorianCalendar(zone, status);
    535     if (failure(status, "new GregorianCalendar")) return;
    536     delete gc;
    537 
    538     gc = new GregorianCalendar(1998, 10, 14, 21, 43, status);
    539     if (gc->getTime(status) != (d =date(98, 10, 14, 21, 43) )|| U_FAILURE(status))
    540       errln("FAIL: new GregorianCalendar(ymdhm) failed with " + UnicodeString(u_errorName(status)) + ",  cal="  + gc->getTime(status)  + UnicodeString(calToStr(*gc)) + ", d=" + d);
    541     else
    542       logln(UnicodeString("GOOD: cal=")  +gc->getTime(status)  + UnicodeString(calToStr(*gc)) + ", d=" + d);
    543     delete gc;
    544 
    545     gc = new GregorianCalendar(1998, 10, 14, 21, 43, 55, status);
    546     if (gc->getTime(status) != (d=date(98, 10, 14, 21, 43, 55)) || U_FAILURE(status))
    547       errln("FAIL: new GregorianCalendar(ymdhms) failed with " + UnicodeString(u_errorName(status)));
    548 
    549     GregorianCalendar gc2(Locale::getEnglish(), status);
    550     if (failure(status, "new GregorianCalendar")) return;
    551     gc2 = *gc;
    552     if (gc2 != *gc || !(gc2 == *gc)) errln("FAIL: GregorianCalendar assignment/operator==/operator!= failed");
    553     delete gc;
    554     delete z;
    555 
    556     /* Code coverage for Calendar class. */
    557     cal = Calendar::createInstance(status);
    558     if (failure(status, "Calendar::createInstance")) {
    559         return;
    560     }else {
    561         ((Calendar *)cal)->roll(UCAL_HOUR, (int32_t)100, status);
    562         ((Calendar *)cal)->clear(UCAL_HOUR);
    563 #if !UCONFIG_NO_SERVICE
    564         URegistryKey key = cal->registerFactory(NULL, status);
    565         cal->unregister(key, status);
    566 #endif
    567     }
    568     delete cal;
    569 
    570     status = U_ZERO_ERROR;
    571     cal = Calendar::createInstance(Locale("he_IL@calendar=hebrew"), status);
    572     if (failure(status, "Calendar::createInstance")) {
    573         return;
    574     } else {
    575         cal->roll(Calendar::MONTH, (int32_t)100, status);
    576     }
    577 
    578     LocalPointer<StringEnumeration> values(
    579         Calendar::getKeywordValuesForLocale("calendar", Locale("he"), FALSE, status));
    580     if (values.isNull() || U_FAILURE(status)) {
    581         dataerrln("FAIL: Calendar::getKeywordValuesForLocale(he): %s", u_errorName(status));
    582     } else {
    583         UBool containsHebrew = FALSE;
    584         const char *charValue;
    585         int32_t valueLength;
    586         while ((charValue = values->next(&valueLength, status)) != NULL) {
    587             if (valueLength == 6 && strcmp(charValue, "hebrew") == 0) {
    588                 containsHebrew = TRUE;
    589             }
    590         }
    591         if (!containsHebrew) {
    592             errln("Calendar::getKeywordValuesForLocale(he)->next() does not contain \"hebrew\"");
    593         }
    594 
    595         values->reset(status);
    596         containsHebrew = FALSE;
    597         UnicodeString hebrew = UNICODE_STRING_SIMPLE("hebrew");
    598         const UChar *ucharValue;
    599         while ((ucharValue = values->unext(&valueLength, status)) != NULL) {
    600             UnicodeString value(FALSE, ucharValue, valueLength);
    601             if (value == hebrew) {
    602                 containsHebrew = TRUE;
    603             }
    604         }
    605         if (!containsHebrew) {
    606             errln("Calendar::getKeywordValuesForLocale(he)->unext() does not contain \"hebrew\"");
    607         }
    608 
    609         values->reset(status);
    610         containsHebrew = FALSE;
    611         const UnicodeString *stringValue;
    612         while ((stringValue = values->snext(status)) != NULL) {
    613             if (*stringValue == hebrew) {
    614                 containsHebrew = TRUE;
    615             }
    616         }
    617         if (!containsHebrew) {
    618             errln("Calendar::getKeywordValuesForLocale(he)->snext() does not contain \"hebrew\"");
    619         }
    620     }
    621     delete cal;
    622 }
    623 
    624 // -------------------------------------
    625 
    626 /**
    627  * This test confirms the correct behavior of add when incrementing
    628  * through subsequent days.
    629  */
    630 void
    631 CalendarTest::TestRog()
    632 {
    633     UErrorCode status = U_ZERO_ERROR;
    634     GregorianCalendar* gc = new GregorianCalendar(status);
    635     if (failure(status, "new GregorianCalendar", TRUE)) return;
    636     int32_t year = 1997, month = UCAL_APRIL, date = 1;
    637     gc->set(year, month, date);
    638     gc->set(UCAL_HOUR_OF_DAY, 23);
    639     gc->set(UCAL_MINUTE, 0);
    640     gc->set(UCAL_SECOND, 0);
    641     gc->set(UCAL_MILLISECOND, 0);
    642     for (int32_t i = 0; i < 9; i++, gc->add(UCAL_DATE, 1, status)) {
    643         if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
    644         if (gc->get(UCAL_YEAR, status) != year ||
    645             gc->get(UCAL_MONTH, status) != month ||
    646             gc->get(UCAL_DATE, status) != (date + i)) errln("FAIL: Date wrong");
    647         if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
    648     }
    649     delete gc;
    650 }
    651 
    652 // -------------------------------------
    653 
    654 /**
    655  * Test the handling of the day of the week, checking for correctness and
    656  * for correct minimum and maximum values.
    657  */
    658 void
    659 CalendarTest::TestDOW943()
    660 {
    661     dowTest(FALSE);
    662     dowTest(TRUE);
    663 }
    664 
    665 void CalendarTest::dowTest(UBool lenient)
    666 {
    667     UErrorCode status = U_ZERO_ERROR;
    668     GregorianCalendar* cal = new GregorianCalendar(status);
    669     if (failure(status, "new GregorianCalendar", TRUE)) return;
    670     logln("cal - Aug 12, 1997\n");
    671     cal->set(1997, UCAL_AUGUST, 12);
    672     cal->getTime(status);
    673     if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; }
    674     logln((lenient?UnicodeString("LENIENT0: "):UnicodeString("nonlenient0: ")) + UnicodeString(calToStr(*cal)));
    675     cal->setLenient(lenient);
    676     logln("cal - Dec 1, 1996\n");
    677     cal->set(1996, UCAL_DECEMBER, 1);
    678     logln((lenient?UnicodeString("LENIENT: "):UnicodeString("nonlenient: ")) + UnicodeString(calToStr(*cal)));
    679     int32_t dow = cal->get(UCAL_DAY_OF_WEEK, status);
    680     if (U_FAILURE(status)) { errln("Calendar::get failed [%s]", u_errorName(status)); return; }
    681     int32_t min = cal->getMinimum(UCAL_DAY_OF_WEEK);
    682     int32_t max = cal->getMaximum(UCAL_DAY_OF_WEEK);
    683     if (dow < min ||
    684         dow > max) errln(UnicodeString("FAIL: Day of week ") + (int32_t)dow + " out of range");
    685     if (dow != UCAL_SUNDAY) errln("FAIL: Day of week should be SUNDAY[%d] not %d", UCAL_SUNDAY, dow);
    686     if (min != UCAL_SUNDAY ||
    687         max != UCAL_SATURDAY) errln("FAIL: Min/max bad");
    688     delete cal;
    689 }
    690 
    691 // -------------------------------------
    692 
    693 /**
    694  * Confirm that cloned Calendar objects do not inadvertently share substructures.
    695  */
    696 void
    697 CalendarTest::TestClonesUnique908()
    698 {
    699     UErrorCode status = U_ZERO_ERROR;
    700     Calendar *c = Calendar::createInstance(status);
    701     if (failure(status, "Calendar::createInstance", TRUE)) return;
    702     Calendar *d = (Calendar*) c->clone();
    703     c->set(UCAL_MILLISECOND, 123);
    704     d->set(UCAL_MILLISECOND, 456);
    705     if (c->get(UCAL_MILLISECOND, status) != 123 ||
    706         d->get(UCAL_MILLISECOND, status) != 456) {
    707         errln("FAIL: Clones share fields");
    708     }
    709     if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
    710     delete c;
    711     delete d;
    712 }
    713 
    714 // -------------------------------------
    715 
    716 /**
    717  * Confirm that the Gregorian cutoff value works as advertised.
    718  */
    719 void
    720 CalendarTest::TestGregorianChange768()
    721 {
    722     UBool b;
    723     UErrorCode status = U_ZERO_ERROR;
    724     UnicodeString str;
    725     GregorianCalendar* c = new GregorianCalendar(status);
    726     if (failure(status, "new GregorianCalendar", TRUE)) return;
    727     logln(UnicodeString("With cutoff ") + dateToString(c->getGregorianChange(), str));
    728     b = c->isLeapYear(1800);
    729     logln(UnicodeString(" isLeapYear(1800) = ") + (b ? "true" : "false"));
    730     logln(UnicodeString(" (should be FALSE)"));
    731     if (b) errln("FAIL");
    732     c->setGregorianChange(date(0, 0, 1), status);
    733     if (U_FAILURE(status)) { errln("GregorianCalendar::setGregorianChange failed"); return; }
    734     logln(UnicodeString("With cutoff ") + dateToString(c->getGregorianChange(), str));
    735     b = c->isLeapYear(1800);
    736     logln(UnicodeString(" isLeapYear(1800) = ") + (b ? "true" : "false"));
    737     logln(UnicodeString(" (should be TRUE)"));
    738     if (!b) errln("FAIL");
    739     delete c;
    740 }
    741 
    742 // -------------------------------------
    743 
    744 /**
    745  * Confirm the functioning of the field disambiguation algorithm.
    746  */
    747 void
    748 CalendarTest::TestDisambiguation765()
    749 {
    750     UErrorCode status = U_ZERO_ERROR;
    751     Calendar *c = Calendar::createInstance("en_US", status);
    752     if (failure(status, "Calendar::createInstance", TRUE)) return;
    753     c->setLenient(FALSE);
    754     c->clear();
    755     c->set(UCAL_YEAR, 1997);
    756     c->set(UCAL_MONTH, UCAL_JUNE);
    757     c->set(UCAL_DATE, 3);
    758     verify765("1997 third day of June = ", c, 1997, UCAL_JUNE, 3);
    759     c->clear();
    760     c->set(UCAL_YEAR, 1997);
    761     c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY);
    762     c->set(UCAL_MONTH, UCAL_JUNE);
    763     c->set(UCAL_DAY_OF_WEEK_IN_MONTH, 1);
    764     verify765("1997 first Tuesday in June = ", c, 1997, UCAL_JUNE, 3);
    765     c->clear();
    766     c->set(UCAL_YEAR, 1997);
    767     c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY);
    768     c->set(UCAL_MONTH, UCAL_JUNE);
    769     c->set(UCAL_DAY_OF_WEEK_IN_MONTH, - 1);
    770     verify765("1997 last Tuesday in June = ", c, 1997, UCAL_JUNE, 24);
    771 
    772     status = U_ZERO_ERROR;
    773     c->clear();
    774     c->set(UCAL_YEAR, 1997);
    775     c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY);
    776     c->set(UCAL_MONTH, UCAL_JUNE);
    777     c->set(UCAL_DAY_OF_WEEK_IN_MONTH, 0);
    778     c->getTime(status);
    779     verify765("1997 zero-th Tuesday in June = ", status);
    780 
    781     c->clear();
    782     c->set(UCAL_YEAR, 1997);
    783     c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY);
    784     c->set(UCAL_MONTH, UCAL_JUNE);
    785     c->set(UCAL_WEEK_OF_MONTH, 1);
    786     verify765("1997 Tuesday in week 1 of June = ", c, 1997, UCAL_JUNE, 3);
    787     c->clear();
    788     c->set(UCAL_YEAR, 1997);
    789     c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY);
    790     c->set(UCAL_MONTH, UCAL_JUNE);
    791     c->set(UCAL_WEEK_OF_MONTH, 5);
    792     verify765("1997 Tuesday in week 5 of June = ", c, 1997, UCAL_JULY, 1);
    793 
    794     status = U_ZERO_ERROR;
    795     c->clear();
    796     c->set(UCAL_YEAR, 1997);
    797     c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY);
    798     c->set(UCAL_MONTH, UCAL_JUNE);
    799     c->set(UCAL_WEEK_OF_MONTH, 0);
    800     c->setMinimalDaysInFirstWeek(1);
    801     c->getTime(status);
    802     verify765("1997 Tuesday in week 0 of June = ", status);
    803 
    804     /* Note: The following test used to expect YEAR 1997, WOY 1 to
    805      * resolve to a date in Dec 1996; that is, to behave as if
    806      * YEAR_WOY were 1997.  With the addition of a new explicit
    807      * YEAR_WOY field, YEAR_WOY must itself be set if that is what is
    808      * desired.  Using YEAR in combination with WOY is ambiguous, and
    809      * results in the first WOY/DOW day of the year satisfying the
    810      * given fields (there may be up to two such days). In this case,
    811      * it propertly resolves to Tue Dec 30 1997, which has a WOY value
    812      * of 1 (for YEAR_WOY 1998) and a DOW of Tuesday, and falls in the
    813      * _calendar_ year 1997, as specified. - aliu */
    814     c->clear();
    815     c->set(UCAL_YEAR_WOY, 1997); // aliu
    816     c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY);
    817     c->set(UCAL_WEEK_OF_YEAR, 1);
    818     verify765("1997 Tuesday in week 1 of yearWOY = ", c, 1996, UCAL_DECEMBER, 31);
    819     c->clear(); // - add test for YEAR
    820     c->setMinimalDaysInFirstWeek(1);
    821     c->set(UCAL_YEAR, 1997);
    822     c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY);
    823     c->set(UCAL_WEEK_OF_YEAR, 1);
    824     verify765("1997 Tuesday in week 1 of year = ", c, 1997, UCAL_DECEMBER, 30);
    825     c->clear();
    826     c->set(UCAL_YEAR, 1997);
    827     c->set(UCAL_DAY_OF_WEEK, UCAL_TUESDAY);
    828     c->set(UCAL_WEEK_OF_YEAR, 10);
    829     verify765("1997 Tuesday in week 10 of year = ", c, 1997, UCAL_MARCH, 4);
    830     //try {
    831 
    832     // {sfb} week 0 is no longer a valid week of year
    833     /*c->clear();
    834     c->set(Calendar::YEAR, 1997);
    835     c->set(Calendar::DAY_OF_WEEK, Calendar::TUESDAY);
    836     //c->set(Calendar::WEEK_OF_YEAR, 0);
    837     c->set(Calendar::WEEK_OF_YEAR, 1);
    838     verify765("1997 Tuesday in week 0 of year = ", c, 1996, Calendar::DECEMBER, 24);*/
    839 
    840     //}
    841     //catch(IllegalArgumentException ex) {
    842     //    errln("FAIL: Exception seen:");
    843     //    ex.printStackTrace(log);
    844     //}
    845     delete c;
    846 }
    847 
    848 // -------------------------------------
    849 
    850 void
    851 CalendarTest::verify765(const UnicodeString& msg, Calendar* c, int32_t year, int32_t month, int32_t day)
    852 {
    853     UnicodeString str;
    854     UErrorCode status = U_ZERO_ERROR;
    855     int32_t y = c->get(UCAL_YEAR, status);
    856     int32_t m = c->get(UCAL_MONTH, status);
    857     int32_t d = c->get(UCAL_DATE, status);
    858     if ( y == year &&
    859          m == month &&
    860          d == day) {
    861         if (U_FAILURE(status)) { errln("FAIL: Calendar::get failed"); return; }
    862         logln("PASS: " + msg + dateToString(c->getTime(status), str));
    863         if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; }
    864     }
    865     else {
    866         errln("FAIL: " + msg + dateToString(c->getTime(status), str) + "; expected " + (int32_t)year + "/" + (int32_t)(month + 1) + "/" + (int32_t)day +
    867             "; got " + (int32_t)y + "/" + (int32_t)(m + 1) + "/" + (int32_t)d + " for Locale: " + c->getLocaleID(ULOC_ACTUAL_LOCALE,status));
    868         if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; }
    869     }
    870 }
    871 
    872 // -------------------------------------
    873 
    874 void
    875 CalendarTest::verify765(const UnicodeString& msg/*, IllegalArgumentException e*/, UErrorCode status)
    876 {
    877     if (status != U_ILLEGAL_ARGUMENT_ERROR) errln("FAIL: No IllegalArgumentException for " + msg);
    878     else logln("PASS: " + msg + "IllegalArgument as expected");
    879 }
    880 
    881 // -------------------------------------
    882 
    883 /**
    884  * Confirm that the offset between local time and GMT behaves as expected.
    885  */
    886 void
    887 CalendarTest::TestGMTvsLocal4064654()
    888 {
    889     test4064654(1997, 1, 1, 12, 0, 0);
    890     test4064654(1997, 4, 16, 18, 30, 0);
    891 }
    892 
    893 // -------------------------------------
    894 
    895 void
    896 CalendarTest::test4064654(int32_t yr, int32_t mo, int32_t dt, int32_t hr, int32_t mn, int32_t sc)
    897 {
    898     UDate date;
    899     UErrorCode status = U_ZERO_ERROR;
    900     UnicodeString str;
    901     Calendar *gmtcal = Calendar::createInstance(status);
    902     if (failure(status, "Calendar::createInstance", TRUE)) return;
    903     gmtcal->adoptTimeZone(TimeZone::createTimeZone("Africa/Casablanca"));
    904     gmtcal->set(yr, mo - 1, dt, hr, mn, sc);
    905     gmtcal->set(UCAL_MILLISECOND, 0);
    906     date = gmtcal->getTime(status);
    907     if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; }
    908     logln("date = " + dateToString(date, str));
    909     Calendar *cal = Calendar::createInstance(status);
    910     if (U_FAILURE(status)) { errln("Calendar::createInstance failed"); return; }
    911     cal->setTime(date, status);
    912     if (U_FAILURE(status)) { errln("Calendar::setTime failed"); return; }
    913     int32_t offset = cal->getTimeZone().getOffset((uint8_t)cal->get(UCAL_ERA, status),
    914                                                   cal->get(UCAL_YEAR, status),
    915                                                   cal->get(UCAL_MONTH, status),
    916                                                   cal->get(UCAL_DATE, status),
    917                                                   (uint8_t)cal->get(UCAL_DAY_OF_WEEK, status),
    918                                                   cal->get(UCAL_MILLISECOND, status), status);
    919     if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
    920     logln("offset for " + dateToString(date, str) + "= " + (offset / 1000 / 60 / 60.0) + "hr");
    921     int32_t utc = ((cal->get(UCAL_HOUR_OF_DAY, status) * 60 +
    922                     cal->get(UCAL_MINUTE, status)) * 60 +
    923                    cal->get(UCAL_SECOND, status)) * 1000 +
    924         cal->get(UCAL_MILLISECOND, status) - offset;
    925     if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
    926     int32_t expected = ((hr * 60 + mn) * 60 + sc) * 1000;
    927     if (utc != expected) errln(UnicodeString("FAIL: Discrepancy of ") + (utc - expected) +
    928                                " millis = " + ((utc - expected) / 1000 / 60 / 60.0) + " hr");
    929     delete gmtcal;
    930     delete cal;
    931 }
    932 
    933 // -------------------------------------
    934 
    935 /**
    936  * The operations of adding and setting should not exhibit pathological
    937  * dependence on the order of operations.  This test checks for this.
    938  */
    939 void
    940 CalendarTest::TestAddSetOrder621()
    941 {
    942     UDate d = date(97, 4, 14, 13, 23, 45);
    943     UErrorCode status = U_ZERO_ERROR;
    944     Calendar *cal = Calendar::createInstance(status);
    945     if (failure(status, "Calendar::createInstance", TRUE)) return;
    946 
    947     cal->setTime(d, status);
    948     if (U_FAILURE(status)) {
    949         errln("Calendar::setTime failed");
    950         delete cal;
    951         return;
    952     }
    953     cal->add(UCAL_DATE, - 5, status);
    954     if (U_FAILURE(status)) {
    955         errln("Calendar::add failed");
    956         delete cal;
    957         return;
    958     }
    959     cal->set(UCAL_HOUR_OF_DAY, 0);
    960     cal->set(UCAL_MINUTE, 0);
    961     cal->set(UCAL_SECOND, 0);
    962     UnicodeString s;
    963     dateToString(cal->getTime(status), s);
    964     if (U_FAILURE(status)) {
    965         errln("Calendar::getTime failed");
    966         delete cal;
    967         return;
    968     }
    969     delete cal;
    970 
    971     cal = Calendar::createInstance(status);
    972     if (U_FAILURE(status)) {
    973         errln("Calendar::createInstance failed");
    974         delete cal;
    975         return;
    976     }
    977     cal->setTime(d, status);
    978     if (U_FAILURE(status)) {
    979         errln("Calendar::setTime failed");
    980         delete cal;
    981         return;
    982     }
    983     cal->set(UCAL_HOUR_OF_DAY, 0);
    984     cal->set(UCAL_MINUTE, 0);
    985     cal->set(UCAL_SECOND, 0);
    986     cal->add(UCAL_DATE, - 5, status);
    987     if (U_FAILURE(status)) {
    988         errln("Calendar::add failed");
    989         delete cal;
    990         return;
    991     }
    992     UnicodeString s2;
    993     dateToString(cal->getTime(status), s2);
    994     if (U_FAILURE(status)) {
    995         errln("Calendar::getTime failed");
    996         delete cal;
    997         return;
    998     }
    999     if (s == s2)
   1000         logln("Pass: " + s + " == " + s2);
   1001     else
   1002         errln("FAIL: " + s + " != " + s2);
   1003     delete cal;
   1004 }
   1005 
   1006 // -------------------------------------
   1007 
   1008 /**
   1009  * Confirm that adding to various fields works.
   1010  */
   1011 void
   1012 CalendarTest::TestAdd520()
   1013 {
   1014     int32_t y = 1997, m = UCAL_FEBRUARY, d = 1;
   1015     UErrorCode status = U_ZERO_ERROR;
   1016     GregorianCalendar *temp = new GregorianCalendar(y, m, d, status);
   1017     if (failure(status, "new GregorianCalendar", TRUE)) return;
   1018     check520(temp, y, m, d);
   1019     temp->add(UCAL_YEAR, 1, status);
   1020     if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
   1021     y++;
   1022     check520(temp, y, m, d);
   1023     temp->add(UCAL_MONTH, 1, status);
   1024     if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
   1025     m++;
   1026     check520(temp, y, m, d);
   1027     temp->add(UCAL_DATE, 1, status);
   1028     if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
   1029     d++;
   1030     check520(temp, y, m, d);
   1031     temp->add(UCAL_DATE, 2, status);
   1032     if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
   1033     d += 2;
   1034     check520(temp, y, m, d);
   1035     temp->add(UCAL_DATE, 28, status);
   1036     if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
   1037     d = 1;++m;
   1038     check520(temp, y, m, d);
   1039     delete temp;
   1040 }
   1041 
   1042 // -------------------------------------
   1043 
   1044 /**
   1045  * Execute adding and rolling in GregorianCalendar extensively,
   1046  */
   1047 void
   1048 CalendarTest::TestAddRollExtensive()
   1049 {
   1050     int32_t maxlimit = 40;
   1051     int32_t y = 1997, m = UCAL_FEBRUARY, d = 1, hr = 1, min = 1, sec = 0, ms = 0;
   1052     UErrorCode status = U_ZERO_ERROR;
   1053     GregorianCalendar *temp = new GregorianCalendar(y, m, d, status);
   1054     if (failure(status, "new GregorianCalendar", TRUE)) return;
   1055 
   1056     temp->set(UCAL_HOUR, hr);
   1057     temp->set(UCAL_MINUTE, min);
   1058     temp->set(UCAL_SECOND, sec);
   1059     temp->set(UCAL_MILLISECOND, ms);
   1060     temp->setMinimalDaysInFirstWeek(1);
   1061 
   1062     UCalendarDateFields e;
   1063 
   1064     logln("Testing GregorianCalendar add...");
   1065     e = UCAL_YEAR;
   1066     while (e < UCAL_FIELD_COUNT) {
   1067         int32_t i;
   1068         int32_t limit = maxlimit;
   1069         status = U_ZERO_ERROR;
   1070         for (i = 0; i < limit; i++) {
   1071             temp->add(e, 1, status);
   1072             if (U_FAILURE(status)) { limit = i; status = U_ZERO_ERROR; }
   1073         }
   1074         for (i = 0; i < limit; i++) {
   1075             temp->add(e, -1, status);
   1076             if (U_FAILURE(status)) { errln("GregorianCalendar::add -1 failed"); return; }
   1077         }
   1078         check520(temp, y, m, d, hr, min, sec, ms, e);
   1079 
   1080         e = (UCalendarDateFields) ((int32_t) e + 1);
   1081     }
   1082 
   1083     logln("Testing GregorianCalendar roll...");
   1084     e = UCAL_YEAR;
   1085     while (e < UCAL_FIELD_COUNT) {
   1086         int32_t i;
   1087         int32_t limit = maxlimit;
   1088         status = U_ZERO_ERROR;
   1089         for (i = 0; i < limit; i++) {
   1090             logln(calToStr(*temp) + UnicodeString("  " ) + fieldName(e) + UnicodeString("++") );
   1091             temp->roll(e, 1, status);
   1092             if (U_FAILURE(status)) {
   1093               logln("caltest.cpp:%d e=%d, i=%d - roll(+) err %s\n",  __LINE__, (int) e, (int) i, u_errorName(status));
   1094               logln(calToStr(*temp));
   1095               limit = i; status = U_ZERO_ERROR;
   1096             }
   1097         }
   1098         for (i = 0; i < limit; i++) {
   1099             logln("caltest.cpp:%d e=%d, i=%d\n",  __LINE__, (int) e, (int) i);
   1100             logln(calToStr(*temp) + UnicodeString("  " ) + fieldName(e) + UnicodeString("--") );
   1101             temp->roll(e, -1, status);
   1102             if (U_FAILURE(status)) { errln(UnicodeString("GregorianCalendar::roll ") + CalendarTest::fieldName(e) + " count=" + UnicodeString('@'+i) + " by -1 failed with " + u_errorName(status) ); return; }
   1103         }
   1104         check520(temp, y, m, d, hr, min, sec, ms, e);
   1105 
   1106         e = (UCalendarDateFields) ((int32_t) e + 1);
   1107     }
   1108 
   1109     delete temp;
   1110 }
   1111 
   1112 // -------------------------------------
   1113 void
   1114 CalendarTest::check520(Calendar* c,
   1115                         int32_t y, int32_t m, int32_t d,
   1116                         int32_t hr, int32_t min, int32_t sec,
   1117                         int32_t ms, UCalendarDateFields field)
   1118 
   1119 {
   1120     UErrorCode status = U_ZERO_ERROR;
   1121     if (c->get(UCAL_YEAR, status) != y ||
   1122         c->get(UCAL_MONTH, status) != m ||
   1123         c->get(UCAL_DATE, status) != d ||
   1124         c->get(UCAL_HOUR, status) != hr ||
   1125         c->get(UCAL_MINUTE, status) != min ||
   1126         c->get(UCAL_SECOND, status) != sec ||
   1127         c->get(UCAL_MILLISECOND, status) != ms) {
   1128         errln(UnicodeString("U_FAILURE for field ") + (int32_t)field +
   1129                 ": Expected y/m/d h:m:s:ms of " +
   1130                 y + "/" + (m + 1) + "/" + d + " " +
   1131               hr + ":" + min + ":" + sec + ":" + ms +
   1132               "; got " + c->get(UCAL_YEAR, status) +
   1133               "/" + (c->get(UCAL_MONTH, status) + 1) +
   1134               "/" + c->get(UCAL_DATE, status) +
   1135               " " + c->get(UCAL_HOUR, status) + ":" +
   1136               c->get(UCAL_MINUTE, status) + ":" +
   1137               c->get(UCAL_SECOND, status) + ":" +
   1138               c->get(UCAL_MILLISECOND, status)
   1139               );
   1140 
   1141         if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
   1142     }
   1143     else
   1144         logln(UnicodeString("Confirmed: ") + y + "/" +
   1145                 (m + 1) + "/" + d + " " +
   1146                 hr + ":" + min + ":" + sec + ":" + ms);
   1147 }
   1148 
   1149 // -------------------------------------
   1150 void
   1151 CalendarTest::check520(Calendar* c,
   1152                         int32_t y, int32_t m, int32_t d)
   1153 
   1154 {
   1155     UErrorCode status = U_ZERO_ERROR;
   1156     if (c->get(UCAL_YEAR, status) != y ||
   1157         c->get(UCAL_MONTH, status) != m ||
   1158         c->get(UCAL_DATE, status) != d) {
   1159         errln(UnicodeString("FAILURE: Expected y/m/d of ") +
   1160               y + "/" + (m + 1) + "/" + d + " " +
   1161               "; got " + c->get(UCAL_YEAR, status) +
   1162               "/" + (c->get(UCAL_MONTH, status) + 1) +
   1163               "/" + c->get(UCAL_DATE, status)
   1164               );
   1165 
   1166         if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
   1167     }
   1168     else
   1169         logln(UnicodeString("Confirmed: ") + y + "/" +
   1170                 (m + 1) + "/" + d);
   1171 }
   1172 
   1173 // -------------------------------------
   1174 
   1175 /**
   1176  * Test that setting of fields works.  In particular, make sure that all instances
   1177  * of GregorianCalendar don't share a static instance of the fields array.
   1178  */
   1179 void
   1180 CalendarTest::TestFieldSet4781()
   1181 {
   1182     // try {
   1183         UErrorCode status = U_ZERO_ERROR;
   1184         GregorianCalendar *g = new GregorianCalendar(status);
   1185         if (failure(status, "new GregorianCalendar", TRUE)) return;
   1186         GregorianCalendar *g2 = new GregorianCalendar(status);
   1187         if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; }
   1188         g2->set(UCAL_HOUR, 12, status);
   1189         g2->set(UCAL_MINUTE, 0, status);
   1190         g2->set(UCAL_SECOND, 0, status);
   1191         if (U_FAILURE(status)) { errln("Calendar::set failed"); return; }
   1192         if (*g == *g2) logln("Same");
   1193         else logln("Different");
   1194     //}
   1195         //catch(IllegalArgumentException e) {
   1196         //errln("Unexpected exception seen: " + e);
   1197     //}
   1198         delete g;
   1199         delete g2;
   1200 }
   1201 
   1202 // -------------------------------------
   1203 
   1204 /* We don't support serialization on C++
   1205 void
   1206 CalendarTest::TestSerialize337()
   1207 {
   1208     Calendar cal = Calendar::getInstance();
   1209     UBool ok = FALSE;
   1210     try {
   1211         FileOutputStream f = new FileOutputStream(FILENAME);
   1212         ObjectOutput s = new ObjectOutputStream(f);
   1213         s.writeObject(PREFIX);
   1214         s.writeObject(cal);
   1215         s.writeObject(POSTFIX);
   1216         f.close();
   1217         FileInputStream in = new FileInputStream(FILENAME);
   1218         ObjectInputStream t = new ObjectInputStream(in);
   1219         UnicodeString& pre = (UnicodeString&) t.readObject();
   1220         Calendar c = (Calendar) t.readObject();
   1221         UnicodeString& post = (UnicodeString&) t.readObject();
   1222         in.close();
   1223         ok = pre.equals(PREFIX) &&
   1224             post.equals(POSTFIX) &&
   1225             cal->equals(c);
   1226         File fl = new File(FILENAME);
   1227         fl.delete();
   1228     }
   1229     catch(IOException e) {
   1230         errln("FAIL: Exception received:");
   1231         e.printStackTrace(log);
   1232     }
   1233     catch(ClassNotFoundException e) {
   1234         errln("FAIL: Exception received:");
   1235         e.printStackTrace(log);
   1236     }
   1237     if (!ok) errln("Serialization of Calendar object failed.");
   1238 }
   1239 
   1240 UnicodeString& CalendarTest::PREFIX = "abc";
   1241 
   1242 UnicodeString& CalendarTest::POSTFIX = "def";
   1243 
   1244 UnicodeString& CalendarTest::FILENAME = "tmp337.bin";
   1245  */
   1246 
   1247 // -------------------------------------
   1248 
   1249 /**
   1250  * Verify that the seconds of a Calendar can be zeroed out through the
   1251  * expected sequence of operations.
   1252  */
   1253 void
   1254 CalendarTest::TestSecondsZero121()
   1255 {
   1256     UErrorCode status = U_ZERO_ERROR;
   1257     Calendar *cal = new GregorianCalendar(status);
   1258     if (failure(status, "new GregorianCalendar", TRUE)) return;
   1259     cal->setTime(Calendar::getNow(), status);
   1260     if (U_FAILURE(status)) { errln("Calendar::setTime failed"); return; }
   1261     cal->set(UCAL_SECOND, 0);
   1262     if (U_FAILURE(status)) { errln("Calendar::set failed"); return; }
   1263     UDate d = cal->getTime(status);
   1264     if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; }
   1265     UnicodeString s;
   1266     dateToString(d, s);
   1267     if (s.indexOf("DATE_FORMAT_FAILURE") >= 0) {
   1268         dataerrln("Got: \"DATE_FORMAT_FAILURE\".");
   1269     } else if (s.indexOf(":00 ") < 0) {
   1270         errln("Expected to see :00 in " + s);
   1271     }
   1272     delete cal;
   1273 }
   1274 
   1275 // -------------------------------------
   1276 
   1277 /**
   1278  * Verify that a specific sequence of adding and setting works as expected;
   1279  * it should not vary depending on when and whether the get method is
   1280  * called.
   1281  */
   1282 void
   1283 CalendarTest::TestAddSetGet0610()
   1284 {
   1285     UnicodeString EXPECTED_0610("1993/0/5", "");
   1286     UErrorCode status = U_ZERO_ERROR;
   1287     {
   1288         Calendar *calendar = new GregorianCalendar(status);
   1289         if (failure(status, "new GregorianCalendar", TRUE)) return;
   1290         calendar->set(1993, UCAL_JANUARY, 4);
   1291         logln("1A) " + value(calendar));
   1292         calendar->add(UCAL_DATE, 1, status);
   1293         if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
   1294         UnicodeString v = value(calendar);
   1295         logln("1B) " + v);
   1296         logln("--) 1993/0/5");
   1297         if (!(v == EXPECTED_0610)) errln("Expected " + EXPECTED_0610 + "; saw " + v);
   1298         delete calendar;
   1299     }
   1300     {
   1301         Calendar *calendar = new GregorianCalendar(1993, UCAL_JANUARY, 4, status);
   1302         if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; }
   1303         logln("2A) " + value(calendar));
   1304         calendar->add(UCAL_DATE, 1, status);
   1305         if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
   1306         UnicodeString v = value(calendar);
   1307         logln("2B) " + v);
   1308         logln("--) 1993/0/5");
   1309         if (!(v == EXPECTED_0610)) errln("Expected " + EXPECTED_0610 + "; saw " + v);
   1310         delete calendar;
   1311     }
   1312     {
   1313         Calendar *calendar = new GregorianCalendar(1993, UCAL_JANUARY, 4, status);
   1314         if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; }
   1315         logln("3A) " + value(calendar));
   1316         calendar->getTime(status);
   1317         if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; }
   1318         calendar->add(UCAL_DATE, 1, status);
   1319         if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
   1320         UnicodeString v = value(calendar);
   1321         logln("3B) " + v);
   1322         logln("--) 1993/0/5");
   1323         if (!(v == EXPECTED_0610)) errln("Expected " + EXPECTED_0610 + "; saw " + v);
   1324         delete calendar;
   1325     }
   1326 }
   1327 
   1328 // -------------------------------------
   1329 
   1330 UnicodeString
   1331 CalendarTest::value(Calendar* calendar)
   1332 {
   1333     UErrorCode status = U_ZERO_ERROR;
   1334     return UnicodeString("") + (int32_t)calendar->get(UCAL_YEAR, status) +
   1335         "/" + (int32_t)calendar->get(UCAL_MONTH, status) +
   1336         "/" + (int32_t)calendar->get(UCAL_DATE, status) +
   1337         (U_FAILURE(status) ? " FAIL: Calendar::get failed" : "");
   1338 }
   1339 
   1340 
   1341 // -------------------------------------
   1342 
   1343 /**
   1344  * Verify that various fields on a known date are set correctly.
   1345  */
   1346 void
   1347 CalendarTest::TestFields060()
   1348 {
   1349     UErrorCode status = U_ZERO_ERROR;
   1350     int32_t year = 1997;
   1351     int32_t month = UCAL_OCTOBER;
   1352     int32_t dDate = 22;
   1353     GregorianCalendar *calendar = 0;
   1354     calendar = new GregorianCalendar(year, month, dDate, status);
   1355     if (failure(status, "new GregorianCalendar", TRUE)) return;
   1356     for (int32_t i = 0; i < EXPECTED_FIELDS_length;) {
   1357         UCalendarDateFields field = (UCalendarDateFields)EXPECTED_FIELDS[i++];
   1358         int32_t expected = EXPECTED_FIELDS[i++];
   1359         if (calendar->get(field, status) != expected) {
   1360             errln(UnicodeString("Expected field ") + (int32_t)field + " to have value " + (int32_t)expected +
   1361                   "; received " + (int32_t)calendar->get(field, status) + " instead");
   1362             if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
   1363         }
   1364     }
   1365     delete calendar;
   1366 }
   1367 
   1368 int32_t CalendarTest::EXPECTED_FIELDS[] = {
   1369     UCAL_YEAR, 1997,
   1370     UCAL_MONTH, UCAL_OCTOBER,
   1371     UCAL_DATE, 22,
   1372     UCAL_DAY_OF_WEEK, UCAL_WEDNESDAY,
   1373     UCAL_DAY_OF_WEEK_IN_MONTH, 4,
   1374     UCAL_DAY_OF_YEAR, 295
   1375 };
   1376 
   1377 const int32_t CalendarTest::EXPECTED_FIELDS_length = (int32_t)(sizeof(CalendarTest::EXPECTED_FIELDS) /
   1378     sizeof(CalendarTest::EXPECTED_FIELDS[0]));
   1379 
   1380 // -------------------------------------
   1381 
   1382 /**
   1383  * Verify that various fields on a known date are set correctly.  In this
   1384  * case, the start of the epoch (January 1 1970).
   1385  */
   1386 void
   1387 CalendarTest::TestEpochStartFields()
   1388 {
   1389     UErrorCode status = U_ZERO_ERROR;
   1390     TimeZone *z = TimeZone::createDefault();
   1391     Calendar *c = Calendar::createInstance(status);
   1392     if (failure(status, "Calendar::createInstance", TRUE)) return;
   1393     UDate d = - z->getRawOffset();
   1394     GregorianCalendar *gc = new GregorianCalendar(status);
   1395     if (U_FAILURE(status)) { errln("Couldn't create GregorianCalendar"); return; }
   1396     gc->setTimeZone(*z);
   1397     gc->setTime(d, status);
   1398     if (U_FAILURE(status)) { errln("Calendar::setTime failed"); return; }
   1399     UBool idt = gc->inDaylightTime(status);
   1400     if (U_FAILURE(status)) { errln("GregorianCalendar::inDaylightTime failed"); return; }
   1401     if (idt) {
   1402         UnicodeString str;
   1403         logln("Warning: Skipping test because " + dateToString(d, str) + " is in DST.");
   1404     }
   1405     else {
   1406         c->setTime(d, status);
   1407         if (U_FAILURE(status)) { errln("Calendar::setTime failed"); return; }
   1408         for (int32_t i = 0; i < UCAL_ZONE_OFFSET;++i) {
   1409             if (c->get((UCalendarDateFields)i, status) != EPOCH_FIELDS[i])
   1410                 dataerrln(UnicodeString("Expected field ") + i + " to have value " + EPOCH_FIELDS[i] +
   1411                       "; saw " + c->get((UCalendarDateFields)i, status) + " instead");
   1412             if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
   1413         }
   1414         if (c->get(UCAL_ZONE_OFFSET, status) != z->getRawOffset())
   1415         {
   1416             errln(UnicodeString("Expected field ZONE_OFFSET to have value ") + z->getRawOffset() +
   1417                   "; saw " + c->get(UCAL_ZONE_OFFSET, status) + " instead");
   1418             if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
   1419         }
   1420         if (c->get(UCAL_DST_OFFSET, status) != 0)
   1421         {
   1422             errln(UnicodeString("Expected field DST_OFFSET to have value 0") +
   1423                   "; saw " + c->get(UCAL_DST_OFFSET, status) + " instead");
   1424             if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
   1425         }
   1426     }
   1427     delete c;
   1428     delete z;
   1429     delete gc;
   1430 }
   1431 
   1432 int32_t CalendarTest::EPOCH_FIELDS[] = {
   1433     1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, - 28800000, 0
   1434 };
   1435 
   1436 // -------------------------------------
   1437 
   1438 /**
   1439  * Test that the days of the week progress properly when add is called repeatedly
   1440  * for increments of 24 days.
   1441  */
   1442 void
   1443 CalendarTest::TestDOWProgression()
   1444 {
   1445     UErrorCode status = U_ZERO_ERROR;
   1446     Calendar *cal = new GregorianCalendar(1972, UCAL_OCTOBER, 26, status);
   1447     if (failure(status, "new GregorianCalendar", TRUE)) return;
   1448     marchByDelta(cal, 24);
   1449     delete cal;
   1450 }
   1451 
   1452 // -------------------------------------
   1453 
   1454 void
   1455 CalendarTest::TestDOW_LOCALandYEAR_WOY()
   1456 {
   1457     /* Note: I've commented out the loop_addroll tests for YEAR and
   1458      * YEAR_WOY below because these two fields should NOT behave
   1459      * identically when adding.  YEAR should keep the month/dom
   1460      * invariant.  YEAR_WOY should keep the woy/dow invariant.  I've
   1461      * added a new test that checks for this in place of the old call
   1462      * to loop_addroll. - aliu */
   1463     UErrorCode status = U_ZERO_ERROR;
   1464     int32_t times = 20;
   1465     Calendar *cal=Calendar::createInstance(Locale::getGermany(), status);
   1466     if (failure(status, "Calendar::createInstance", TRUE)) return;
   1467     SimpleDateFormat *sdf=new SimpleDateFormat(UnicodeString("YYYY'-W'ww-ee"), Locale::getGermany(), status);
   1468     if (U_FAILURE(status)) { dataerrln("Couldn't create SimpleDateFormat - %s", u_errorName(status)); return; }
   1469 
   1470     // ICU no longer use localized date-time pattern characters by default.
   1471     // So we set pattern chars using 'J' instead of 'Y'.
   1472     DateFormatSymbols *dfs = new DateFormatSymbols(Locale::getGermany(), status);
   1473     dfs->setLocalPatternChars(UnicodeString("GyMdkHmsSEDFwWahKzJeugAZvcLQq"));
   1474     sdf->adoptDateFormatSymbols(dfs);
   1475     sdf->applyLocalizedPattern(UnicodeString("JJJJ'-W'ww-ee"), status);
   1476     if (U_FAILURE(status)) { errln("Couldn't apply localized pattern"); return; }
   1477 
   1478     cal->clear();
   1479     cal->set(1997, UCAL_DECEMBER, 25);
   1480     doYEAR_WOYLoop(cal, sdf, times, status);
   1481     //loop_addroll(cal, /*sdf,*/ times, UCAL_YEAR_WOY, UCAL_YEAR,  status);
   1482     yearAddTest(*cal, status); // aliu
   1483     loop_addroll(cal, /*sdf,*/ times, UCAL_DOW_LOCAL, UCAL_DAY_OF_WEEK, status);
   1484     if (U_FAILURE(status)) { errln("Error in parse/calculate test for 1997"); return; }
   1485 
   1486     cal->clear();
   1487     cal->set(1998, UCAL_DECEMBER, 25);
   1488     doYEAR_WOYLoop(cal, sdf, times, status);
   1489     //loop_addroll(cal, /*sdf,*/ times, UCAL_YEAR_WOY, UCAL_YEAR,  status);
   1490     yearAddTest(*cal, status); // aliu
   1491     loop_addroll(cal, /*sdf,*/ times, UCAL_DOW_LOCAL, UCAL_DAY_OF_WEEK, status);
   1492     if (U_FAILURE(status)) { errln("Error in parse/calculate test for 1998"); return; }
   1493 
   1494     cal->clear();
   1495     cal->set(1582, UCAL_OCTOBER, 1);
   1496     doYEAR_WOYLoop(cal, sdf, times, status);
   1497     //loop_addroll(cal, /*sdf,*/ times, Calendar::YEAR_WOY, Calendar::YEAR,  status);
   1498     yearAddTest(*cal, status); // aliu
   1499     loop_addroll(cal, /*sdf,*/ times, UCAL_DOW_LOCAL, UCAL_DAY_OF_WEEK, status);
   1500     if (U_FAILURE(status)) { errln("Error in parse/calculate test for 1582"); return; }
   1501     delete sdf;
   1502     delete cal;
   1503 
   1504     return;
   1505 }
   1506 
   1507 /**
   1508  * Confirm that adding a YEAR and adding a YEAR_WOY work properly for
   1509  * the given Calendar at its current setting.
   1510  */
   1511 void CalendarTest::yearAddTest(Calendar& cal, UErrorCode& status) {
   1512     /**
   1513      * When adding the YEAR, the month and day should remain constant.
   1514      * When adding the YEAR_WOY, the WOY and DOW should remain constant. - aliu
   1515      * Examples:
   1516      *  Wed Jan 14 1998 / 1998-W03-03 Add(YEAR_WOY, 1) -> Wed Jan 20 1999 / 1999-W03-03
   1517      *                                Add(YEAR, 1)     -> Thu Jan 14 1999 / 1999-W02-04
   1518      *  Thu Jan 14 1999 / 1999-W02-04 Add(YEAR_WOY, 1) -> Thu Jan 13 2000 / 2000-W02-04
   1519      *                                Add(YEAR, 1)     -> Fri Jan 14 2000 / 2000-W02-05
   1520      *  Sun Oct 31 1582 / 1582-W42-07 Add(YEAR_WOY, 1) -> Sun Oct 23 1583 / 1583-W42-07
   1521      *                                Add(YEAR, 1)     -> Mon Oct 31 1583 / 1583-W44-01
   1522      */
   1523     int32_t y   = cal.get(UCAL_YEAR, status);
   1524     int32_t mon = cal.get(UCAL_MONTH, status);
   1525     int32_t day = cal.get(UCAL_DATE, status);
   1526     int32_t ywy = cal.get(UCAL_YEAR_WOY, status);
   1527     int32_t woy = cal.get(UCAL_WEEK_OF_YEAR, status);
   1528     int32_t dow = cal.get(UCAL_DOW_LOCAL, status);
   1529     UDate t = cal.getTime(status);
   1530 
   1531     if(U_FAILURE(status)){
   1532         errln(UnicodeString("Failed to create Calendar for locale. Error: ") + UnicodeString(u_errorName(status)));
   1533         return;
   1534     }
   1535     UnicodeString str, str2;
   1536     SimpleDateFormat fmt(UnicodeString("EEE MMM dd yyyy / YYYY'-W'ww-ee"), status);
   1537     fmt.setCalendar(cal);
   1538 
   1539     fmt.format(t, str.remove());
   1540     str += ".add(YEAR, 1)    =>";
   1541     cal.add(UCAL_YEAR, 1, status);
   1542     int32_t y2   = cal.get(UCAL_YEAR, status);
   1543     int32_t mon2 = cal.get(UCAL_MONTH, status);
   1544     int32_t day2 = cal.get(UCAL_DATE, status);
   1545     fmt.format(cal.getTime(status), str);
   1546     if (y2 != (y+1) || mon2 != mon || day2 != day) {
   1547         str += (UnicodeString)", expected year " +
   1548             (y+1) + ", month " + (mon+1) + ", day " + day;
   1549         errln((UnicodeString)"FAIL: " + str);
   1550         logln( UnicodeString(" -> ") + CalendarTest::calToStr(cal) );
   1551     } else {
   1552         logln(str);
   1553     }
   1554 
   1555     fmt.format(t, str.remove());
   1556     str += ".add(YEAR_WOY, 1)=>";
   1557     cal.setTime(t, status);
   1558     logln( UnicodeString(" <- ") + CalendarTest::calToStr(cal) );
   1559     cal.add(UCAL_YEAR_WOY, 1, status);
   1560     int32_t ywy2 = cal.get(UCAL_YEAR_WOY, status);
   1561     int32_t woy2 = cal.get(UCAL_WEEK_OF_YEAR, status);
   1562     int32_t dow2 = cal.get(UCAL_DOW_LOCAL, status);
   1563     fmt.format(cal.getTime(status), str);
   1564     if (ywy2 != (ywy+1) || woy2 != woy || dow2 != dow) {
   1565         str += (UnicodeString)", expected yearWOY " +
   1566             (ywy+1) + ", woy " + woy + ", dowLocal " + dow;
   1567         errln((UnicodeString)"FAIL: " + str);
   1568         logln( UnicodeString(" -> ") + CalendarTest::calToStr(cal) );
   1569     } else {
   1570         logln(str);
   1571     }
   1572 }
   1573 
   1574 // -------------------------------------
   1575 
   1576 void CalendarTest::loop_addroll(Calendar *cal, /*SimpleDateFormat *sdf,*/ int times, UCalendarDateFields field, UCalendarDateFields field2, UErrorCode& errorCode) {
   1577     Calendar *calclone;
   1578     SimpleDateFormat fmt(UnicodeString("EEE MMM dd yyyy / YYYY'-W'ww-ee"), errorCode);
   1579     fmt.setCalendar(*cal);
   1580     int i;
   1581 
   1582     for(i = 0; i<times; i++) {
   1583         calclone = cal->clone();
   1584         UDate start = cal->getTime(errorCode);
   1585         cal->add(field,1,errorCode);
   1586         if (U_FAILURE(errorCode)) { errln("Error in add"); delete calclone; return; }
   1587         calclone->add(field2,1,errorCode);
   1588         if (U_FAILURE(errorCode)) { errln("Error in add"); delete calclone; return; }
   1589         if(cal->getTime(errorCode) != calclone->getTime(errorCode)) {
   1590             UnicodeString str("FAIL: Results of add differ. "), str2;
   1591             str += fmt.format(start, str2) + " ";
   1592             str += UnicodeString("Add(") + fieldName(field) + ", 1) -> " +
   1593                 fmt.format(cal->getTime(errorCode), str2.remove()) + "; ";
   1594             str += UnicodeString("Add(") + fieldName(field2) + ", 1) -> " +
   1595                 fmt.format(calclone->getTime(errorCode), str2.remove());
   1596             errln(str);
   1597             delete calclone;
   1598             return;
   1599         }
   1600         delete calclone;
   1601     }
   1602 
   1603     for(i = 0; i<times; i++) {
   1604         calclone = cal->clone();
   1605         cal->roll(field,(int32_t)1,errorCode);
   1606         if (U_FAILURE(errorCode)) { errln("Error in roll"); delete calclone; return; }
   1607         calclone->roll(field2,(int32_t)1,errorCode);
   1608         if (U_FAILURE(errorCode)) { errln("Error in roll"); delete calclone; return; }
   1609         if(cal->getTime(errorCode) != calclone->getTime(errorCode)) {
   1610             delete calclone;
   1611             errln("Results of roll differ!");
   1612             return;
   1613         }
   1614         delete calclone;
   1615     }
   1616 }
   1617 
   1618 // -------------------------------------
   1619 
   1620 void
   1621 CalendarTest::doYEAR_WOYLoop(Calendar *cal, SimpleDateFormat *sdf,
   1622                                     int32_t times, UErrorCode& errorCode) {
   1623 
   1624     UnicodeString us;
   1625     UDate tst, original;
   1626     Calendar *tstres = new GregorianCalendar(Locale::getGermany(), errorCode);
   1627     for(int i=0; i<times; ++i) {
   1628         sdf->format(Formattable(cal->getTime(errorCode),Formattable::kIsDate), us, errorCode);
   1629         //logln("expected: "+us);
   1630         if (U_FAILURE(errorCode)) { errln("Format error"); return; }
   1631         tst=sdf->parse(us,errorCode);
   1632         if (U_FAILURE(errorCode)) { errln("Parse error"); return; }
   1633         tstres->clear();
   1634         tstres->setTime(tst, errorCode);
   1635         //logln((UnicodeString)"Parsed week of year is "+tstres->get(UCAL_WEEK_OF_YEAR, errorCode));
   1636         if (U_FAILURE(errorCode)) { errln("Set time error"); return; }
   1637         original = cal->getTime(errorCode);
   1638         us.remove();
   1639         sdf->format(Formattable(tst,Formattable::kIsDate), us, errorCode);
   1640         //logln("got: "+us);
   1641         if (U_FAILURE(errorCode)) { errln("Get time error"); return; }
   1642         if(original!=tst) {
   1643             us.remove();
   1644             sdf->format(Formattable(original, Formattable::kIsDate), us, errorCode);
   1645             errln("FAIL: Parsed time doesn't match with regular");
   1646             logln("expected "+us + " " + calToStr(*cal));
   1647             us.remove();
   1648             sdf->format(Formattable(tst, Formattable::kIsDate), us, errorCode);
   1649             logln("got "+us + " " + calToStr(*tstres));
   1650         }
   1651         tstres->clear();
   1652         tstres->set(UCAL_YEAR_WOY, cal->get(UCAL_YEAR_WOY, errorCode));
   1653         tstres->set(UCAL_WEEK_OF_YEAR, cal->get(UCAL_WEEK_OF_YEAR, errorCode));
   1654         tstres->set(UCAL_DOW_LOCAL, cal->get(UCAL_DOW_LOCAL, errorCode));
   1655         if(cal->get(UCAL_YEAR, errorCode) != tstres->get(UCAL_YEAR, errorCode)) {
   1656             errln("FAIL: Different Year!");
   1657             logln((UnicodeString)"Expected "+cal->get(UCAL_YEAR, errorCode));
   1658             logln((UnicodeString)"Got "+tstres->get(UCAL_YEAR, errorCode));
   1659             return;
   1660         }
   1661         if(cal->get(UCAL_DAY_OF_YEAR, errorCode) != tstres->get(UCAL_DAY_OF_YEAR, errorCode)) {
   1662             errln("FAIL: Different Day Of Year!");
   1663             logln((UnicodeString)"Expected "+cal->get(UCAL_DAY_OF_YEAR, errorCode));
   1664             logln((UnicodeString)"Got "+tstres->get(UCAL_DAY_OF_YEAR, errorCode));
   1665             return;
   1666         }
   1667         //logln(calToStr(*cal));
   1668         cal->add(UCAL_DATE, 1, errorCode);
   1669         if (U_FAILURE(errorCode)) { errln("Add error"); return; }
   1670         us.remove();
   1671     }
   1672     delete (tstres);
   1673 }
   1674 // -------------------------------------
   1675 
   1676 void
   1677 CalendarTest::marchByDelta(Calendar* cal, int32_t delta)
   1678 {
   1679     UErrorCode status = U_ZERO_ERROR;
   1680     Calendar *cur = (Calendar*) cal->clone();
   1681     int32_t initialDOW = cur->get(UCAL_DAY_OF_WEEK, status);
   1682     if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
   1683     int32_t DOW, newDOW = initialDOW;
   1684     do {
   1685         UnicodeString str;
   1686         DOW = newDOW;
   1687         logln(UnicodeString("DOW = ") + DOW + "  " + dateToString(cur->getTime(status), str));
   1688         if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; }
   1689         cur->add(UCAL_DAY_OF_WEEK, delta, status);
   1690         if (U_FAILURE(status)) { errln("Calendar::add failed"); return; }
   1691         newDOW = cur->get(UCAL_DAY_OF_WEEK, status);
   1692         if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
   1693         int32_t expectedDOW = 1 + (DOW + delta - 1) % 7;
   1694         if (newDOW != expectedDOW) {
   1695             errln(UnicodeString("Day of week should be ") + expectedDOW + " instead of " + newDOW +
   1696                   " on " + dateToString(cur->getTime(status), str));
   1697             if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; }
   1698             return;
   1699         }
   1700     }
   1701     while (newDOW != initialDOW);
   1702     delete cur;
   1703 }
   1704 
   1705 #define CHECK(status, msg) \
   1706     if (U_FAILURE(status)) { \
   1707         errcheckln(status, msg); \
   1708         return; \
   1709     }
   1710 
   1711 void CalendarTest::TestWOY(void) {
   1712     /*
   1713       FDW = Mon, MDFW = 4:
   1714          Sun Dec 26 1999, WOY 51
   1715          Mon Dec 27 1999, WOY 52
   1716          Tue Dec 28 1999, WOY 52
   1717          Wed Dec 29 1999, WOY 52
   1718          Thu Dec 30 1999, WOY 52
   1719          Fri Dec 31 1999, WOY 52
   1720          Sat Jan 01 2000, WOY 52 ***
   1721          Sun Jan 02 2000, WOY 52 ***
   1722          Mon Jan 03 2000, WOY 1
   1723          Tue Jan 04 2000, WOY 1
   1724          Wed Jan 05 2000, WOY 1
   1725          Thu Jan 06 2000, WOY 1
   1726          Fri Jan 07 2000, WOY 1
   1727          Sat Jan 08 2000, WOY 1
   1728          Sun Jan 09 2000, WOY 1
   1729          Mon Jan 10 2000, WOY 2
   1730 
   1731       FDW = Mon, MDFW = 2:
   1732          Sun Dec 26 1999, WOY 52
   1733          Mon Dec 27 1999, WOY 1  ***
   1734          Tue Dec 28 1999, WOY 1  ***
   1735          Wed Dec 29 1999, WOY 1  ***
   1736          Thu Dec 30 1999, WOY 1  ***
   1737          Fri Dec 31 1999, WOY 1  ***
   1738          Sat Jan 01 2000, WOY 1
   1739          Sun Jan 02 2000, WOY 1
   1740          Mon Jan 03 2000, WOY 2
   1741          Tue Jan 04 2000, WOY 2
   1742          Wed Jan 05 2000, WOY 2
   1743          Thu Jan 06 2000, WOY 2
   1744          Fri Jan 07 2000, WOY 2
   1745          Sat Jan 08 2000, WOY 2
   1746          Sun Jan 09 2000, WOY 2
   1747          Mon Jan 10 2000, WOY 3
   1748     */
   1749 
   1750     UnicodeString str;
   1751     UErrorCode status = U_ZERO_ERROR;
   1752     int32_t i;
   1753 
   1754     GregorianCalendar cal(status);
   1755     SimpleDateFormat fmt(UnicodeString("EEE MMM dd yyyy', WOY' w"), status);
   1756     if (failure(status, "Cannot construct calendar/format", TRUE)) return;
   1757 
   1758     UCalendarDaysOfWeek fdw = (UCalendarDaysOfWeek) 0;
   1759 
   1760     //for (int8_t pass=2; pass<=2; ++pass) {
   1761     for (int8_t pass=1; pass<=2; ++pass) {
   1762         switch (pass) {
   1763         case 1:
   1764             fdw = UCAL_MONDAY;
   1765             cal.setFirstDayOfWeek(fdw);
   1766             cal.setMinimalDaysInFirstWeek(4);
   1767             fmt.adoptCalendar(cal.clone());
   1768             break;
   1769         case 2:
   1770             fdw = UCAL_MONDAY;
   1771             cal.setFirstDayOfWeek(fdw);
   1772             cal.setMinimalDaysInFirstWeek(2);
   1773             fmt.adoptCalendar(cal.clone());
   1774             break;
   1775         }
   1776 
   1777         //for (i=2; i<=6; ++i) {
   1778         for (i=0; i<16; ++i) {
   1779         UDate t, t2;
   1780         int32_t t_y, t_woy, t_dow;
   1781         cal.clear();
   1782         cal.set(1999, UCAL_DECEMBER, 26 + i);
   1783         fmt.format(t = cal.getTime(status), str.remove());
   1784         CHECK(status, "Fail: getTime failed");
   1785         logln(UnicodeString("* ") + str);
   1786         int32_t dow = cal.get(UCAL_DAY_OF_WEEK, status);
   1787         int32_t woy = cal.get(UCAL_WEEK_OF_YEAR, status);
   1788         int32_t year = cal.get(UCAL_YEAR, status);
   1789         int32_t mon = cal.get(UCAL_MONTH, status);
   1790         logln(calToStr(cal));
   1791         CHECK(status, "Fail: get failed");
   1792         int32_t dowLocal = dow - fdw;
   1793         if (dowLocal < 0) dowLocal += 7;
   1794         dowLocal++;
   1795         int32_t yearWoy = year;
   1796         if (mon == UCAL_JANUARY) {
   1797             if (woy >= 52) --yearWoy;
   1798         } else {
   1799             if (woy == 1) ++yearWoy;
   1800         }
   1801 
   1802         // Basic fields->time check y/woy/dow
   1803         // Since Y/WOY is ambiguous, we do a check of the fields,
   1804         // not of the specific time.
   1805         cal.clear();
   1806         cal.set(UCAL_YEAR, year);
   1807         cal.set(UCAL_WEEK_OF_YEAR, woy);
   1808         cal.set(UCAL_DAY_OF_WEEK, dow);
   1809         t_y = cal.get(UCAL_YEAR, status);
   1810         t_woy = cal.get(UCAL_WEEK_OF_YEAR, status);
   1811         t_dow = cal.get(UCAL_DAY_OF_WEEK, status);
   1812         CHECK(status, "Fail: get failed");
   1813         if (t_y != year || t_woy != woy || t_dow != dow) {
   1814             str = "Fail: y/woy/dow fields->time => ";
   1815             fmt.format(cal.getTime(status), str);
   1816             errln(str);
   1817             logln(calToStr(cal));
   1818             logln("[get!=set] Y%d!=%d || woy%d!=%d || dow%d!=%d\n",
   1819                   t_y, year, t_woy, woy, t_dow, dow);
   1820         } else {
   1821           logln("y/woy/dow fields->time OK");
   1822         }
   1823 
   1824         // Basic fields->time check y/woy/dow_local
   1825         // Since Y/WOY is ambiguous, we do a check of the fields,
   1826         // not of the specific time.
   1827         cal.clear();
   1828         cal.set(UCAL_YEAR, year);
   1829         cal.set(UCAL_WEEK_OF_YEAR, woy);
   1830         cal.set(UCAL_DOW_LOCAL, dowLocal);
   1831         t_y = cal.get(UCAL_YEAR, status);
   1832         t_woy = cal.get(UCAL_WEEK_OF_YEAR, status);
   1833         t_dow = cal.get(UCAL_DOW_LOCAL, status);
   1834         CHECK(status, "Fail: get failed");
   1835         if (t_y != year || t_woy != woy || t_dow != dowLocal) {
   1836             str = "Fail: y/woy/dow_local fields->time => ";
   1837             fmt.format(cal.getTime(status), str);
   1838             errln(str);
   1839         }
   1840 
   1841         // Basic fields->time check y_woy/woy/dow
   1842         cal.clear();
   1843         cal.set(UCAL_YEAR_WOY, yearWoy);
   1844         cal.set(UCAL_WEEK_OF_YEAR, woy);
   1845         cal.set(UCAL_DAY_OF_WEEK, dow);
   1846         t2 = cal.getTime(status);
   1847         CHECK(status, "Fail: getTime failed");
   1848         if (t != t2) {
   1849             str = "Fail: y_woy/woy/dow fields->time => ";
   1850             fmt.format(t2, str);
   1851             errln(str);
   1852             logln(calToStr(cal));
   1853             logln("%.f != %.f\n", t, t2);
   1854         } else {
   1855           logln("y_woy/woy/dow OK");
   1856         }
   1857 
   1858         // Basic fields->time check y_woy/woy/dow_local
   1859         cal.clear();
   1860         cal.set(UCAL_YEAR_WOY, yearWoy);
   1861         cal.set(UCAL_WEEK_OF_YEAR, woy);
   1862         cal.set(UCAL_DOW_LOCAL, dowLocal);
   1863         t2 = cal.getTime(status);
   1864         CHECK(status, "Fail: getTime failed");
   1865         if (t != t2) {
   1866             str = "Fail: y_woy/woy/dow_local fields->time => ";
   1867             fmt.format(t2, str);
   1868             errln(str);
   1869         }
   1870 
   1871         logln("Testing DOW_LOCAL.. dow%d\n", dow);
   1872         // Make sure DOW_LOCAL disambiguates over DOW
   1873         int32_t wrongDow = dow - 3;
   1874         if (wrongDow < 1) wrongDow += 7;
   1875         cal.setTime(t, status);
   1876         cal.set(UCAL_DAY_OF_WEEK, wrongDow);
   1877         cal.set(UCAL_DOW_LOCAL, dowLocal);
   1878         t2 = cal.getTime(status);
   1879         CHECK(status, "Fail: set/getTime failed");
   1880         if (t != t2) {
   1881             str = "Fail: DOW_LOCAL fields->time => ";
   1882             fmt.format(t2, str);
   1883             errln(str);
   1884             logln(calToStr(cal));
   1885             logln("%.f :   DOW%d, DOW_LOCAL%d -> %.f\n",
   1886                   t, wrongDow, dowLocal, t2);
   1887         }
   1888 
   1889         // Make sure DOW disambiguates over DOW_LOCAL
   1890         int32_t wrongDowLocal = dowLocal - 3;
   1891         if (wrongDowLocal < 1) wrongDowLocal += 7;
   1892         cal.setTime(t, status);
   1893         cal.set(UCAL_DOW_LOCAL, wrongDowLocal);
   1894         cal.set(UCAL_DAY_OF_WEEK, dow);
   1895         t2 = cal.getTime(status);
   1896         CHECK(status, "Fail: set/getTime failed");
   1897         if (t != t2) {
   1898             str = "Fail: DOW       fields->time => ";
   1899             fmt.format(t2, str);
   1900             errln(str);
   1901         }
   1902 
   1903         // Make sure YEAR_WOY disambiguates over YEAR
   1904         cal.setTime(t, status);
   1905         cal.set(UCAL_YEAR, year - 2);
   1906         cal.set(UCAL_YEAR_WOY, yearWoy);
   1907         t2 = cal.getTime(status);
   1908         CHECK(status, "Fail: set/getTime failed");
   1909         if (t != t2) {
   1910             str = "Fail: YEAR_WOY  fields->time => ";
   1911             fmt.format(t2, str);
   1912             errln(str);
   1913         }
   1914 
   1915         // Make sure YEAR disambiguates over YEAR_WOY
   1916         cal.setTime(t, status);
   1917         cal.set(UCAL_YEAR_WOY, yearWoy - 2);
   1918         cal.set(UCAL_YEAR, year);
   1919         t2 = cal.getTime(status);
   1920         CHECK(status, "Fail: set/getTime failed");
   1921         if (t != t2) {
   1922             str = "Fail: YEAR      fields->time => ";
   1923             fmt.format(t2, str);
   1924             errln(str);
   1925         }
   1926     }
   1927     }
   1928 
   1929     /*
   1930       FDW = Mon, MDFW = 4:
   1931          Sun Dec 26 1999, WOY 51
   1932          Mon Dec 27 1999, WOY 52
   1933          Tue Dec 28 1999, WOY 52
   1934          Wed Dec 29 1999, WOY 52
   1935          Thu Dec 30 1999, WOY 52
   1936          Fri Dec 31 1999, WOY 52
   1937          Sat Jan 01 2000, WOY 52
   1938          Sun Jan 02 2000, WOY 52
   1939     */
   1940 
   1941     // Roll the DOW_LOCAL within week 52
   1942     for (i=27; i<=33; ++i) {
   1943         int32_t amount;
   1944         for (amount=-7; amount<=7; ++amount) {
   1945             str = "roll(";
   1946             cal.set(1999, UCAL_DECEMBER, i);
   1947             UDate t, t2;
   1948             fmt.format(cal.getTime(status), str);
   1949             CHECK(status, "Fail: getTime failed");
   1950             str += UnicodeString(", ") + amount + ") = ";
   1951 
   1952             cal.roll(UCAL_DOW_LOCAL, amount, status);
   1953             CHECK(status, "Fail: roll failed");
   1954 
   1955             t = cal.getTime(status);
   1956             int32_t newDom = i + amount;
   1957             while (newDom < 27) newDom += 7;
   1958             while (newDom > 33) newDom -= 7;
   1959             cal.set(1999, UCAL_DECEMBER, newDom);
   1960             t2 = cal.getTime(status);
   1961             CHECK(status, "Fail: getTime failed");
   1962             fmt.format(t, str);
   1963 
   1964             if (t != t2) {
   1965                 str.append(", exp ");
   1966                 fmt.format(t2, str);
   1967                 errln(str);
   1968             } else {
   1969                 logln(str);
   1970             }
   1971         }
   1972     }
   1973 }
   1974 
   1975 void CalendarTest::TestYWOY()
   1976 {
   1977    UnicodeString str;
   1978    UErrorCode status = U_ZERO_ERROR;
   1979 
   1980    GregorianCalendar cal(status);
   1981    if (failure(status, "construct GregorianCalendar", TRUE)) return;
   1982 
   1983    cal.setFirstDayOfWeek(UCAL_SUNDAY);
   1984    cal.setMinimalDaysInFirstWeek(1);
   1985 
   1986    logln("Setting:  ywoy=2004, woy=1, dow=MONDAY");
   1987    cal.clear();
   1988    cal.set(UCAL_YEAR_WOY,2004);
   1989    cal.set(UCAL_WEEK_OF_YEAR,1);
   1990    cal.set(UCAL_DAY_OF_WEEK, UCAL_MONDAY);
   1991 
   1992    logln(calToStr(cal));
   1993    if(cal.get(UCAL_YEAR, status) != 2003) {
   1994      errln("year not 2003");
   1995    }
   1996 
   1997    logln("+ setting DOW to THURSDAY");
   1998    cal.clear();
   1999    cal.set(UCAL_YEAR_WOY,2004);
   2000    cal.set(UCAL_WEEK_OF_YEAR,1);
   2001    cal.set(UCAL_DAY_OF_WEEK, UCAL_THURSDAY);
   2002 
   2003    logln(calToStr(cal));
   2004    if(cal.get(UCAL_YEAR, status) != 2004) {
   2005      errln("year not 2004");
   2006    }
   2007 
   2008    logln("+ setting DOW_LOCAL to 1");
   2009    cal.clear();
   2010    cal.set(UCAL_YEAR_WOY,2004);
   2011    cal.set(UCAL_WEEK_OF_YEAR,1);
   2012    cal.set(UCAL_DAY_OF_WEEK, UCAL_THURSDAY);
   2013    cal.set(UCAL_DOW_LOCAL, 1);
   2014 
   2015    logln(calToStr(cal));
   2016    if(cal.get(UCAL_YEAR, status) != 2003) {
   2017      errln("year not 2003");
   2018    }
   2019 
   2020    cal.setFirstDayOfWeek(UCAL_MONDAY);
   2021    cal.setMinimalDaysInFirstWeek(4);
   2022    UDate t = 946713600000.;
   2023    cal.setTime(t, status);
   2024    cal.set(UCAL_DAY_OF_WEEK, 4);
   2025    cal.set(UCAL_DOW_LOCAL, 6);
   2026    if(cal.getTime(status) != t) {
   2027      logln(calToStr(cal));
   2028      errln("FAIL:  DOW_LOCAL did not take precedence");
   2029    }
   2030 
   2031 }
   2032 
   2033 void CalendarTest::TestJD()
   2034 {
   2035   int32_t jd;
   2036   static const int32_t kEpochStartAsJulianDay = 2440588;
   2037   UErrorCode status = U_ZERO_ERROR;
   2038   GregorianCalendar cal(status);
   2039   if (failure(status, "construct GregorianCalendar", TRUE)) return;
   2040   cal.setTimeZone(*TimeZone::getGMT());
   2041   cal.clear();
   2042   jd = cal.get(UCAL_JULIAN_DAY, status);
   2043   if(jd != kEpochStartAsJulianDay) {
   2044     errln("Wanted JD of %d at time=0, [epoch 1970] but got %d\n", kEpochStartAsJulianDay, jd);
   2045   } else {
   2046     logln("Wanted JD of %d at time=0, [epoch 1970], got %d\n", kEpochStartAsJulianDay, jd);
   2047   }
   2048 
   2049   cal.setTime(Calendar::getNow(), status);
   2050   cal.clear();
   2051   cal.set(UCAL_JULIAN_DAY, kEpochStartAsJulianDay);
   2052   UDate epochTime = cal.getTime(status);
   2053   if(epochTime != 0) {
   2054     errln("Wanted time of 0 at jd=%d, got %.1lf\n", kEpochStartAsJulianDay, epochTime);
   2055   } else {
   2056     logln("Wanted time of 0 at jd=%d, got %.1lf\n", kEpochStartAsJulianDay, epochTime);
   2057   }
   2058 
   2059 }
   2060 
   2061 // make sure the ctestfw utilities are in sync with the Calendar
   2062 void CalendarTest::TestDebug()
   2063 {
   2064     for(int32_t  t=0;t<=UDBG_ENUM_COUNT;t++) {
   2065         int32_t count = udbg_enumCount((UDebugEnumType)t);
   2066         if(count == -1) {
   2067             logln("enumCount(%d) returned -1", count);
   2068             continue;
   2069         }
   2070         for(int32_t i=0;i<=count;i++) {
   2071             if(t<=UDBG_HIGHEST_CONTIGUOUS_ENUM && i<count) {
   2072                 if( i!=udbg_enumArrayValue((UDebugEnumType)t, i)) {
   2073                     errln("FAIL: udbg_enumArrayValue(%d,%d) returned %d, expected %d", t, i, udbg_enumArrayValue((UDebugEnumType)t,i), i);
   2074                 }
   2075             } else {
   2076                 logln("Testing count+1:");
   2077             }
   2078                   const char *name = udbg_enumName((UDebugEnumType)t,i);
   2079                   if(name==NULL) {
   2080                           if(i==count || t>UDBG_HIGHEST_CONTIGUOUS_ENUM  ) {
   2081                                 logln(" null name - expected.\n");
   2082                           } else {
   2083                                 errln("FAIL: udbg_enumName(%d,%d) returned NULL", t, i);
   2084                           }
   2085                           name = "(null)";
   2086                   }
   2087           logln("udbg_enumArrayValue(%d,%d) = %s, returned %d", t, i,
   2088                       name, udbg_enumArrayValue((UDebugEnumType)t,i));
   2089             logln("udbg_enumString = " + udbg_enumString((UDebugEnumType)t,i));
   2090         }
   2091         if(udbg_enumExpectedCount((UDebugEnumType)t) != count && t<=UDBG_HIGHEST_CONTIGUOUS_ENUM) {
   2092             errln("FAIL: udbg_enumExpectedCount(%d): %d, != UCAL_FIELD_COUNT=%d ", t, udbg_enumExpectedCount((UDebugEnumType)t), count);
   2093         } else {
   2094             logln("udbg_ucal_fieldCount: %d, UCAL_FIELD_COUNT=udbg_enumCount %d ", udbg_enumExpectedCount((UDebugEnumType)t), count);
   2095         }
   2096     }
   2097 }
   2098 
   2099 
   2100 #undef CHECK
   2101 
   2102 // List of interesting locales
   2103 const char *CalendarTest::testLocaleID(int32_t i)
   2104 {
   2105   switch(i) {
   2106   case 0: return "he_IL@calendar=hebrew";
   2107   case 1: return "en_US@calendar=hebrew";
   2108   case 2: return "fr_FR@calendar=hebrew";
   2109   case 3: return "fi_FI@calendar=hebrew";
   2110   case 4: return "nl_NL@calendar=hebrew";
   2111   case 5: return "hu_HU@calendar=hebrew";
   2112   case 6: return "nl_BE@currency=MTL;calendar=islamic";
   2113   case 7: return "th_TH_TRADITIONAL@calendar=gregorian";
   2114   case 8: return "ar_JO@calendar=islamic-civil";
   2115   case 9: return "fi_FI@calendar=islamic";
   2116   case 10: return "fr_CH@calendar=islamic-civil";
   2117   case 11: return "he_IL@calendar=islamic-civil";
   2118   case 12: return "hu_HU@calendar=buddhist";
   2119   case 13: return "hu_HU@calendar=islamic";
   2120   case 14: return "en_US@calendar=japanese";
   2121   default: return NULL;
   2122   }
   2123 }
   2124 
   2125 int32_t CalendarTest::testLocaleCount()
   2126 {
   2127   static int32_t gLocaleCount = -1;
   2128   if(gLocaleCount < 0) {
   2129     int32_t i;
   2130     for(i=0;testLocaleID(i) != NULL;i++) {
   2131       ;
   2132     }
   2133     gLocaleCount = i;
   2134   }
   2135   return gLocaleCount;
   2136 }
   2137 
   2138 static UDate doMinDateOfCalendar(Calendar* adopt, UBool &isGregorian, UErrorCode& status) {
   2139   if(U_FAILURE(status)) return 0.0;
   2140 
   2141   adopt->clear();
   2142   adopt->set(UCAL_EXTENDED_YEAR, adopt->getActualMinimum(UCAL_EXTENDED_YEAR, status));
   2143   UDate ret = adopt->getTime(status);
   2144   isGregorian = dynamic_cast<GregorianCalendar*>(adopt) != NULL;
   2145   delete adopt;
   2146   return ret;
   2147 }
   2148 
   2149 UDate CalendarTest::minDateOfCalendar(const Locale& locale, UBool &isGregorian, UErrorCode& status) {
   2150   if(U_FAILURE(status)) return 0.0;
   2151   return doMinDateOfCalendar(Calendar::createInstance(locale, status), isGregorian, status);
   2152 }
   2153 
   2154 UDate CalendarTest::minDateOfCalendar(const Calendar& cal, UBool &isGregorian, UErrorCode& status) {
   2155   if(U_FAILURE(status)) return 0.0;
   2156   return doMinDateOfCalendar(cal.clone(), isGregorian, status);
   2157 }
   2158 
   2159 void CalendarTest::Test6703()
   2160 {
   2161     UErrorCode status = U_ZERO_ERROR;
   2162     Calendar *cal;
   2163 
   2164     Locale loc1("en@calendar=fubar");
   2165     cal = Calendar::createInstance(loc1, status);
   2166     if (failure(status, "Calendar::createInstance", TRUE)) return;
   2167     delete cal;
   2168 
   2169     status = U_ZERO_ERROR;
   2170     Locale loc2("en");
   2171     cal = Calendar::createInstance(loc2, status);
   2172     if (failure(status, "Calendar::createInstance")) return;
   2173     delete cal;
   2174 
   2175     status = U_ZERO_ERROR;
   2176     Locale loc3("en@calendar=roc");
   2177     cal = Calendar::createInstance(loc3, status);
   2178     if (failure(status, "Calendar::createInstance")) return;
   2179     delete cal;
   2180 
   2181     return;
   2182 }
   2183 
   2184 void CalendarTest::Test3785()
   2185 {
   2186     UErrorCode status = U_ZERO_ERROR;
   2187     UnicodeString uzone = UNICODE_STRING_SIMPLE("Europe/Paris");
   2188     UnicodeString exp1 = UNICODE_STRING_SIMPLE("Mon 30 Jumada II 1433 AH, 01:47:03");
   2189     UnicodeString exp2 = UNICODE_STRING_SIMPLE("Mon 1 Rajab 1433 AH, 01:47:04");
   2190 
   2191     LocalUDateFormatPointer df(udat_open(UDAT_NONE, UDAT_NONE, "en@calendar=islamic", uzone.getTerminatedBuffer(),
   2192                                          uzone.length(), NULL, 0, &status));
   2193     if (df.isNull() || U_FAILURE(status)) return;
   2194 
   2195     UChar upattern[64];
   2196     u_uastrcpy(upattern, "EEE d MMMM y G, HH:mm:ss");
   2197     udat_applyPattern(df.getAlias(), FALSE, upattern, u_strlen(upattern));
   2198 
   2199     UChar ubuffer[1024];
   2200     UDate ud0 = 1337557623000.0;
   2201 
   2202     status = U_ZERO_ERROR;
   2203     udat_format(df.getAlias(), ud0, ubuffer, 1024, NULL, &status);
   2204     if (U_FAILURE(status)) {
   2205         errln("Error formatting date 1\n");
   2206         return;
   2207     }
   2208     //printf("formatted: '%s'\n", mkcstr(ubuffer));
   2209 
   2210     UnicodeString act1(ubuffer);
   2211     if ( act1 != exp1 ) {
   2212         errln("Unexpected result from date 1 format\n");
   2213     }
   2214     ud0 += 1000.0; // add one second
   2215 
   2216     status = U_ZERO_ERROR;
   2217     udat_format(df.getAlias(), ud0, ubuffer, 1024, NULL, &status);
   2218     if (U_FAILURE(status)) {
   2219         errln("Error formatting date 2\n");
   2220         return;
   2221     }
   2222     //printf("formatted: '%s'\n", mkcstr(ubuffer));
   2223     UnicodeString act2(ubuffer);
   2224     if ( act2 != exp2 ) {
   2225         errln("Unexpected result from date 2 format\n");
   2226     }
   2227 
   2228     return;
   2229 }
   2230 
   2231 void CalendarTest::Test1624() {
   2232     UErrorCode status = U_ZERO_ERROR;
   2233     Locale loc("he_IL@calendar=hebrew");
   2234     HebrewCalendar hc(loc,status);
   2235 
   2236     for (int32_t year = 5600; year < 5800; year++ ) {
   2237 
   2238         for (int32_t month = HebrewCalendar::TISHRI; month <= HebrewCalendar::ELUL; month++) {
   2239             // skip the adar 1 month if year is not a leap year
   2240             if (HebrewCalendar::isLeapYear(year) == FALSE && month == HebrewCalendar::ADAR_1) {
   2241                 continue;
   2242             }
   2243             int32_t day = 15;
   2244             hc.set(year,month,day);
   2245             int32_t dayHC = hc.get(UCAL_DATE,status);
   2246             int32_t monthHC = hc.get(UCAL_MONTH,status);
   2247             int32_t yearHC = hc.get(UCAL_YEAR,status);
   2248 
   2249             if (failure(status, "HebrewCalendar.get()", TRUE)) continue;
   2250 
   2251             if (dayHC != day) {
   2252                 errln(" ==> day %d incorrect, should be: %d\n",dayHC,day);
   2253                 break;
   2254             }
   2255             if (monthHC != month) {
   2256                 errln(" ==> month %d incorrect, should be: %d\n",monthHC,month);
   2257                 break;
   2258             }
   2259             if (yearHC != year) {
   2260                 errln(" ==> day %d incorrect, should be: %d\n",yearHC,year);
   2261                 break;
   2262             }
   2263         }
   2264     }
   2265     return;
   2266 }
   2267 
   2268 void CalendarTest::TestTimeStamp() {
   2269     UErrorCode status = U_ZERO_ERROR;
   2270     UDate start = 0.0, time;
   2271     Calendar *cal;
   2272 
   2273     // Create a new Gregorian Calendar.
   2274     cal = Calendar::createInstance("en_US@calender=gregorian", status);
   2275     if (U_FAILURE(status)) {
   2276         dataerrln("Error creating Gregorian calendar.");
   2277         return;
   2278     }
   2279 
   2280     for (int i = 0; i < 20000; i++) {
   2281         // Set the Gregorian Calendar to a specific date for testing.
   2282         cal->set(2009, UCAL_JULY, 3, 0, 49, 46);
   2283 
   2284         time = cal->getTime(status);
   2285         if (U_FAILURE(status)) {
   2286             errln("Error calling getTime()");
   2287             break;
   2288         }
   2289 
   2290         if (i == 0) {
   2291             start = time;
   2292         } else {
   2293             if (start != time) {
   2294                 errln("start and time not equal.");
   2295                 break;
   2296             }
   2297         }
   2298     }
   2299 
   2300     delete cal;
   2301 }
   2302 
   2303 void CalendarTest::TestISO8601() {
   2304     const char* TEST_LOCALES[] = {
   2305         "en_US@calendar=iso8601",
   2306         "en_US@calendar=Iso8601",
   2307         "th_TH@calendar=iso8601",
   2308         "ar_EG@calendar=iso8601",
   2309         NULL
   2310     };
   2311 
   2312     int32_t TEST_DATA[][3] = {
   2313         {2008, 1, 2008},
   2314         {2009, 1, 2009},
   2315         {2010, 53, 2009},
   2316         {2011, 52, 2010},
   2317         {2012, 52, 2011},
   2318         {2013, 1, 2013},
   2319         {2014, 1, 2014},
   2320         {0, 0, 0},
   2321     };
   2322 
   2323     for (int i = 0; TEST_LOCALES[i] != NULL; i++) {
   2324         UErrorCode status = U_ZERO_ERROR;
   2325         Calendar *cal = Calendar::createInstance(TEST_LOCALES[i], status);
   2326         if (U_FAILURE(status)) {
   2327             errln("Error: Failed to create a calendar for locale: %s", TEST_LOCALES[i]);
   2328             continue;
   2329         }
   2330         if (uprv_strcmp(cal->getType(), "gregorian") != 0) {
   2331             errln("Error: Gregorian calendar is not used for locale: %s", TEST_LOCALES[i]);
   2332             continue;
   2333         }
   2334         for (int j = 0; TEST_DATA[j][0] != 0; j++) {
   2335             cal->set(TEST_DATA[j][0], UCAL_JANUARY, 1);
   2336             int32_t weekNum = cal->get(UCAL_WEEK_OF_YEAR, status);
   2337             int32_t weekYear = cal->get(UCAL_YEAR_WOY, status);
   2338             if (U_FAILURE(status)) {
   2339                 errln("Error: Failed to get week of year");
   2340                 break;
   2341             }
   2342             if (weekNum != TEST_DATA[j][1] || weekYear != TEST_DATA[j][2]) {
   2343                 errln("Error: Incorrect week of year on January 1st, %d for locale %s: Returned [weekNum=%d, weekYear=%d], Expected [weekNum=%d, weekYear=%d]",
   2344                     TEST_DATA[j][0], TEST_LOCALES[i], weekNum, weekYear, TEST_DATA[j][1], TEST_DATA[j][2]);
   2345             }
   2346         }
   2347         delete cal;
   2348     }
   2349 
   2350 }
   2351 
   2352 void
   2353 CalendarTest::TestAmbiguousWallTimeAPIs(void) {
   2354     UErrorCode status = U_ZERO_ERROR;
   2355     Calendar* cal = Calendar::createInstance(status);
   2356     if (U_FAILURE(status)) {
   2357         errln("Fail: Error creating a calendar instance.");
   2358         return;
   2359     }
   2360 
   2361     if (cal->getRepeatedWallTimeOption() != UCAL_WALLTIME_LAST) {
   2362         errln("Fail: Default repeted time option is not UCAL_WALLTIME_LAST");
   2363     }
   2364     if (cal->getSkippedWallTimeOption() != UCAL_WALLTIME_LAST) {
   2365         errln("Fail: Default skipped time option is not UCAL_WALLTIME_LAST");
   2366     }
   2367 
   2368     Calendar* cal2 = cal->clone();
   2369 
   2370     if (*cal != *cal2) {
   2371         errln("Fail: Cloned calendar != the original");
   2372     }
   2373     if (!cal->equals(*cal2, status)) {
   2374         errln("Fail: The time of cloned calendar is not equal to the original");
   2375     } else if (U_FAILURE(status)) {
   2376         errln("Fail: Error equals");
   2377     }
   2378     status = U_ZERO_ERROR;
   2379 
   2380     cal2->setRepeatedWallTimeOption(UCAL_WALLTIME_FIRST);
   2381     cal2->setSkippedWallTimeOption(UCAL_WALLTIME_FIRST);
   2382 
   2383     if (*cal == *cal2) {
   2384         errln("Fail: Cloned and modified calendar == the original");
   2385     }
   2386     if (!cal->equals(*cal2, status)) {
   2387         errln("Fail: The time of cloned calendar is not equal to the original after changing wall time options");
   2388     } else if (U_FAILURE(status)) {
   2389         errln("Fail: Error equals after changing wall time options");
   2390     }
   2391     status = U_ZERO_ERROR;
   2392 
   2393     if (cal2->getRepeatedWallTimeOption() != UCAL_WALLTIME_FIRST) {
   2394         errln("Fail: Repeted time option is not UCAL_WALLTIME_FIRST");
   2395     }
   2396     if (cal2->getSkippedWallTimeOption() != UCAL_WALLTIME_FIRST) {
   2397         errln("Fail: Skipped time option is not UCAL_WALLTIME_FIRST");
   2398     }
   2399 
   2400     cal2->setRepeatedWallTimeOption(UCAL_WALLTIME_NEXT_VALID);
   2401     if (cal2->getRepeatedWallTimeOption() != UCAL_WALLTIME_FIRST) {
   2402         errln("Fail: Repeated wall time option was updated other than UCAL_WALLTIME_FIRST");
   2403     }
   2404 
   2405     delete cal;
   2406     delete cal2;
   2407 }
   2408 
   2409 class CalFields {
   2410 public:
   2411     CalFields(int32_t year, int32_t month, int32_t day, int32_t hour, int32_t min, int32_t sec);
   2412     CalFields(const Calendar& cal, UErrorCode& status);
   2413     void setTo(Calendar& cal) const;
   2414     char* toString(char* buf, int32_t len) const;
   2415     UBool operator==(const CalFields& rhs) const;
   2416     UBool operator!=(const CalFields& rhs) const;
   2417 
   2418 private:
   2419     int32_t year;
   2420     int32_t month;
   2421     int32_t day;
   2422     int32_t hour;
   2423     int32_t min;
   2424     int32_t sec;
   2425 };
   2426 
   2427 CalFields::CalFields(int32_t year, int32_t month, int32_t day, int32_t hour, int32_t min, int32_t sec)
   2428     : year(year), month(month), day(day), hour(hour), min(min), sec(sec) {
   2429 }
   2430 
   2431 CalFields::CalFields(const Calendar& cal, UErrorCode& status) {
   2432     year = cal.get(UCAL_YEAR, status);
   2433     month = cal.get(UCAL_MONTH, status) + 1;
   2434     day = cal.get(UCAL_DAY_OF_MONTH, status);
   2435     hour = cal.get(UCAL_HOUR_OF_DAY, status);
   2436     min = cal.get(UCAL_MINUTE, status);
   2437     sec = cal.get(UCAL_SECOND, status);
   2438 }
   2439 
   2440 void
   2441 CalFields::setTo(Calendar& cal) const {
   2442     cal.clear();
   2443     cal.set(year, month - 1, day, hour, min, sec);
   2444 }
   2445 
   2446 char*
   2447 CalFields::toString(char* buf, int32_t len) const {
   2448     char local[32];
   2449     sprintf(local, "%04d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, min, sec);
   2450     uprv_strncpy(buf, local, len - 1);
   2451     buf[len - 1] = 0;
   2452     return buf;
   2453 }
   2454 
   2455 UBool
   2456 CalFields::operator==(const CalFields& rhs) const {
   2457     return year == rhs.year
   2458         && month == rhs.month
   2459         && day == rhs.day
   2460         && hour == rhs.hour
   2461         && min == rhs.min
   2462         && sec == rhs.sec;
   2463 }
   2464 
   2465 UBool
   2466 CalFields::operator!=(const CalFields& rhs) const {
   2467     return !(*this == rhs);
   2468 }
   2469 
   2470 typedef struct {
   2471     const char*     tzid;
   2472     const CalFields in;
   2473     const CalFields expLastGMT;
   2474     const CalFields expFirstGMT;
   2475 } RepeatedWallTimeTestData;
   2476 
   2477 static const RepeatedWallTimeTestData RPDATA[] =
   2478 {
   2479     // Time zone            Input wall time                 WALLTIME_LAST in GMT            WALLTIME_FIRST in GMT
   2480     {"America/New_York",    CalFields(2011,11,6,0,59,59),   CalFields(2011,11,6,4,59,59),   CalFields(2011,11,6,4,59,59)},
   2481     {"America/New_York",    CalFields(2011,11,6,1,0,0),     CalFields(2011,11,6,6,0,0),     CalFields(2011,11,6,5,0,0)},
   2482     {"America/New_York",    CalFields(2011,11,6,1,0,1),     CalFields(2011,11,6,6,0,1),     CalFields(2011,11,6,5,0,1)},
   2483     {"America/New_York",    CalFields(2011,11,6,1,30,0),    CalFields(2011,11,6,6,30,0),    CalFields(2011,11,6,5,30,0)},
   2484     {"America/New_York",    CalFields(2011,11,6,1,59,59),   CalFields(2011,11,6,6,59,59),   CalFields(2011,11,6,5,59,59)},
   2485     {"America/New_York",    CalFields(2011,11,6,2,0,0),     CalFields(2011,11,6,7,0,0),     CalFields(2011,11,6,7,0,0)},
   2486     {"America/New_York",    CalFields(2011,11,6,2,0,1),     CalFields(2011,11,6,7,0,1),     CalFields(2011,11,6,7,0,1)},
   2487 
   2488     {"Australia/Lord_Howe", CalFields(2011,4,3,1,29,59),    CalFields(2011,4,2,14,29,59),   CalFields(2011,4,2,14,29,59)},
   2489     {"Australia/Lord_Howe", CalFields(2011,4,3,1,30,0),     CalFields(2011,4,2,15,0,0),     CalFields(2011,4,2,14,30,0)},
   2490     {"Australia/Lord_Howe", CalFields(2011,4,3,1,45,0),     CalFields(2011,4,2,15,15,0),    CalFields(2011,4,2,14,45,0)},
   2491     {"Australia/Lord_Howe", CalFields(2011,4,3,1,59,59),    CalFields(2011,4,2,15,29,59),   CalFields(2011,4,2,14,59,59)},
   2492     {"Australia/Lord_Howe", CalFields(2011,4,3,2,0,0),      CalFields(2011,4,2,15,30,0),    CalFields(2011,4,2,15,30,0)},
   2493     {"Australia/Lord_Howe", CalFields(2011,4,3,2,0,1),      CalFields(2011,4,2,15,30,1),    CalFields(2011,4,2,15,30,1)},
   2494 
   2495     {NULL,                  CalFields(0,0,0,0,0,0),         CalFields(0,0,0,0,0,0),          CalFields(0,0,0,0,0,0)}
   2496 };
   2497 
   2498 void CalendarTest::TestRepeatedWallTime(void) {
   2499     UErrorCode status = U_ZERO_ERROR;
   2500     GregorianCalendar calGMT((const TimeZone&)*TimeZone::getGMT(), status);
   2501     GregorianCalendar calDefault(status);
   2502     GregorianCalendar calLast(status);
   2503     GregorianCalendar calFirst(status);
   2504 
   2505     if (U_FAILURE(status)) {
   2506         errln("Fail: Failed to create a calendar object.");
   2507         return;
   2508     }
   2509 
   2510     calLast.setRepeatedWallTimeOption(UCAL_WALLTIME_LAST);
   2511     calFirst.setRepeatedWallTimeOption(UCAL_WALLTIME_FIRST);
   2512 
   2513     for (int32_t i = 0; RPDATA[i].tzid != NULL; i++) {
   2514         char buf[32];
   2515         TimeZone *tz = TimeZone::createTimeZone(RPDATA[i].tzid);
   2516 
   2517         // UCAL_WALLTIME_LAST
   2518         status = U_ZERO_ERROR;
   2519         calLast.setTimeZone(*tz);
   2520         RPDATA[i].in.setTo(calLast);
   2521         calGMT.setTime(calLast.getTime(status), status);
   2522         CalFields outLastGMT(calGMT, status);
   2523         if (U_FAILURE(status)) {
   2524             errln(UnicodeString("Fail: Failed to get/set time calLast/calGMT (UCAL_WALLTIME_LAST) - ")
   2525                 + RPDATA[i].in.toString(buf, sizeof(buf)) + "[" + RPDATA[i].tzid + "]");
   2526         } else {
   2527             if (outLastGMT != RPDATA[i].expLastGMT) {
   2528                 dataerrln(UnicodeString("Fail: UCAL_WALLTIME_LAST ") + RPDATA[i].in.toString(buf, sizeof(buf)) + "[" + RPDATA[i].tzid + "] is parsed as "
   2529                     + outLastGMT.toString(buf, sizeof(buf)) + "[GMT]. Expected: " + RPDATA[i].expLastGMT.toString(buf, sizeof(buf)) + "[GMT]");
   2530             }
   2531         }
   2532 
   2533         // default
   2534         status = U_ZERO_ERROR;
   2535         calDefault.setTimeZone(*tz);
   2536         RPDATA[i].in.setTo(calDefault);
   2537         calGMT.setTime(calDefault.getTime(status), status);
   2538         CalFields outDefGMT(calGMT, status);
   2539         if (U_FAILURE(status)) {
   2540             errln(UnicodeString("Fail: Failed to get/set time calLast/calGMT (default) - ")
   2541                 + RPDATA[i].in.toString(buf, sizeof(buf)) + "[" + RPDATA[i].tzid + "]");
   2542         } else {
   2543             if (outDefGMT != RPDATA[i].expLastGMT) {
   2544                 dataerrln(UnicodeString("Fail: (default) ") + RPDATA[i].in.toString(buf, sizeof(buf)) + "[" + RPDATA[i].tzid + "] is parsed as "
   2545                     + outDefGMT.toString(buf, sizeof(buf)) + "[GMT]. Expected: " + RPDATA[i].expLastGMT.toString(buf, sizeof(buf)) + "[GMT]");
   2546             }
   2547         }
   2548 
   2549         // UCAL_WALLTIME_FIRST
   2550         status = U_ZERO_ERROR;
   2551         calFirst.setTimeZone(*tz);
   2552         RPDATA[i].in.setTo(calFirst);
   2553         calGMT.setTime(calFirst.getTime(status), status);
   2554         CalFields outFirstGMT(calGMT, status);
   2555         if (U_FAILURE(status)) {
   2556             errln(UnicodeString("Fail: Failed to get/set time calLast/calGMT (UCAL_WALLTIME_FIRST) - ")
   2557                 + RPDATA[i].in.toString(buf, sizeof(buf)) + "[" + RPDATA[i].tzid + "]");
   2558         } else {
   2559             if (outFirstGMT != RPDATA[i].expFirstGMT) {
   2560                 dataerrln(UnicodeString("Fail: UCAL_WALLTIME_FIRST ") + RPDATA[i].in.toString(buf, sizeof(buf)) + "[" + RPDATA[i].tzid + "] is parsed as "
   2561                     + outFirstGMT.toString(buf, sizeof(buf)) + "[GMT]. Expected: " + RPDATA[i].expFirstGMT.toString(buf, sizeof(buf)) + "[GMT]");
   2562             }
   2563         }
   2564         delete tz;
   2565     }
   2566 }
   2567 
   2568 typedef struct {
   2569     const char*     tzid;
   2570     const CalFields in;
   2571     UBool           isValid;
   2572     const CalFields expLastGMT;
   2573     const CalFields expFirstGMT;
   2574     const CalFields expNextAvailGMT;
   2575 } SkippedWallTimeTestData;
   2576 
   2577 static SkippedWallTimeTestData SKDATA[] =
   2578 {
   2579      // Time zone           Input wall time                 valid?  WALLTIME_LAST in GMT            WALLTIME_FIRST in GMT           WALLTIME_NEXT_VALID in GMT
   2580     {"America/New_York",    CalFields(2011,3,13,1,59,59),   TRUE,   CalFields(2011,3,13,6,59,59),   CalFields(2011,3,13,6,59,59),   CalFields(2011,3,13,6,59,59)},
   2581     {"America/New_York",    CalFields(2011,3,13,2,0,0),     FALSE,  CalFields(2011,3,13,7,0,0),     CalFields(2011,3,13,6,0,0),     CalFields(2011,3,13,7,0,0)},
   2582     {"America/New_York",    CalFields(2011,3,13,2,1,0),     FALSE,  CalFields(2011,3,13,7,1,0),     CalFields(2011,3,13,6,1,0),     CalFields(2011,3,13,7,0,0)},
   2583     {"America/New_York",    CalFields(2011,3,13,2,30,0),    FALSE,  CalFields(2011,3,13,7,30,0),    CalFields(2011,3,13,6,30,0),    CalFields(2011,3,13,7,0,0)},
   2584     {"America/New_York",    CalFields(2011,3,13,2,59,59),   FALSE,  CalFields(2011,3,13,7,59,59),   CalFields(2011,3,13,6,59,59),   CalFields(2011,3,13,7,0,0)},
   2585     {"America/New_York",    CalFields(2011,3,13,3,0,0),     TRUE,   CalFields(2011,3,13,7,0,0),     CalFields(2011,3,13,7,0,0),     CalFields(2011,3,13,7,0,0)},
   2586 
   2587     {"Pacific/Apia",        CalFields(2011,12,29,23,59,59), TRUE,   CalFields(2011,12,30,9,59,59),  CalFields(2011,12,30,9,59,59),  CalFields(2011,12,30,9,59,59)},
   2588     {"Pacific/Apia",        CalFields(2011,12,30,0,0,0),    FALSE,  CalFields(2011,12,30,10,0,0),   CalFields(2011,12,29,10,0,0),   CalFields(2011,12,30,10,0,0)},
   2589     {"Pacific/Apia",        CalFields(2011,12,30,12,0,0),   FALSE,  CalFields(2011,12,30,22,0,0),   CalFields(2011,12,29,22,0,0),   CalFields(2011,12,30,10,0,0)},
   2590     {"Pacific/Apia",        CalFields(2011,12,30,23,59,59), FALSE,  CalFields(2011,12,31,9,59,59),  CalFields(2011,12,30,9,59,59),  CalFields(2011,12,30,10,0,0)},
   2591     {"Pacific/Apia",        CalFields(2011,12,31,0,0,0),    TRUE,   CalFields(2011,12,30,10,0,0),   CalFields(2011,12,30,10,0,0),   CalFields(2011,12,30,10,0,0)},
   2592 
   2593     {NULL,                  CalFields(0,0,0,0,0,0),         TRUE,   CalFields(0,0,0,0,0,0),         CalFields(0,0,0,0,0,0),         CalFields(0,0,0,0,0,0)}
   2594 };
   2595 
   2596 
   2597 void CalendarTest::TestSkippedWallTime(void) {
   2598     UErrorCode status = U_ZERO_ERROR;
   2599     GregorianCalendar calGMT((const TimeZone&)*TimeZone::getGMT(), status);
   2600     GregorianCalendar calDefault(status);
   2601     GregorianCalendar calLast(status);
   2602     GregorianCalendar calFirst(status);
   2603     GregorianCalendar calNextAvail(status);
   2604 
   2605     if (U_FAILURE(status)) {
   2606         errln("Fail: Failed to create a calendar object.");
   2607         return;
   2608     }
   2609 
   2610     calLast.setSkippedWallTimeOption(UCAL_WALLTIME_LAST);
   2611     calFirst.setSkippedWallTimeOption(UCAL_WALLTIME_FIRST);
   2612     calNextAvail.setSkippedWallTimeOption(UCAL_WALLTIME_NEXT_VALID);
   2613 
   2614     for (int32_t i = 0; SKDATA[i].tzid != NULL; i++) {
   2615         UDate d;
   2616         char buf[32];
   2617         TimeZone *tz = TimeZone::createTimeZone(SKDATA[i].tzid);
   2618 
   2619         for (int32_t j = 0; j < 2; j++) {
   2620             UBool bLenient = (j == 0);
   2621 
   2622             // UCAL_WALLTIME_LAST
   2623             status = U_ZERO_ERROR;
   2624             calLast.setLenient(bLenient);
   2625             calLast.setTimeZone(*tz);
   2626             SKDATA[i].in.setTo(calLast);
   2627             d = calLast.getTime(status);
   2628             if (bLenient || SKDATA[i].isValid) {
   2629                 calGMT.setTime(d, status);
   2630                 CalFields outLastGMT(calGMT, status);
   2631                 if (U_FAILURE(status)) {
   2632                     errln(UnicodeString("Fail: Failed to get/set time calLast/calGMT (UCAL_WALLTIME_LAST) - ")
   2633                         + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "]");
   2634                 } else {
   2635                     if (outLastGMT != SKDATA[i].expLastGMT) {
   2636                         dataerrln(UnicodeString("Fail: UCAL_WALLTIME_LAST ") + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "] is parsed as "
   2637                             + outLastGMT.toString(buf, sizeof(buf)) + "[GMT]. Expected: " + SKDATA[i].expLastGMT.toString(buf, sizeof(buf)) + "[GMT]");
   2638                     }
   2639                 }
   2640             } else if (U_SUCCESS(status)) {
   2641                 // strict, invalid wall time - must report an error
   2642                 dataerrln(UnicodeString("Fail: An error expected (UCAL_WALLTIME_LAST)") +
   2643                     + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "]");
   2644             }
   2645 
   2646             // default
   2647             status = U_ZERO_ERROR;
   2648             calDefault.setLenient(bLenient);
   2649             calDefault.setTimeZone(*tz);
   2650             SKDATA[i].in.setTo(calDefault);
   2651             d = calDefault.getTime(status);
   2652             if (bLenient || SKDATA[i].isValid) {
   2653                 calGMT.setTime(d, status);
   2654                 CalFields outDefGMT(calGMT, status);
   2655                 if (U_FAILURE(status)) {
   2656                     errln(UnicodeString("Fail: Failed to get/set time calDefault/calGMT (default) - ")
   2657                         + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "]");
   2658                 } else {
   2659                     if (outDefGMT != SKDATA[i].expLastGMT) {
   2660                         dataerrln(UnicodeString("Fail: (default) ") + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "] is parsed as "
   2661                             + outDefGMT.toString(buf, sizeof(buf)) + "[GMT]. Expected: " + SKDATA[i].expLastGMT.toString(buf, sizeof(buf)) + "[GMT]");
   2662                     }
   2663                 }
   2664             } else if (U_SUCCESS(status)) {
   2665                 // strict, invalid wall time - must report an error
   2666                 dataerrln(UnicodeString("Fail: An error expected (default)") +
   2667                     + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "]");
   2668             }
   2669 
   2670             // UCAL_WALLTIME_FIRST
   2671             status = U_ZERO_ERROR;
   2672             calFirst.setLenient(bLenient);
   2673             calFirst.setTimeZone(*tz);
   2674             SKDATA[i].in.setTo(calFirst);
   2675             d = calFirst.getTime(status);
   2676             if (bLenient || SKDATA[i].isValid) {
   2677                 calGMT.setTime(d, status);
   2678                 CalFields outFirstGMT(calGMT, status);
   2679                 if (U_FAILURE(status)) {
   2680                     errln(UnicodeString("Fail: Failed to get/set time calFirst/calGMT (UCAL_WALLTIME_FIRST) - ")
   2681                         + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "]");
   2682                 } else {
   2683                     if (outFirstGMT != SKDATA[i].expFirstGMT) {
   2684                         dataerrln(UnicodeString("Fail: UCAL_WALLTIME_FIRST ") + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "] is parsed as "
   2685                             + outFirstGMT.toString(buf, sizeof(buf)) + "[GMT]. Expected: " + SKDATA[i].expFirstGMT.toString(buf, sizeof(buf)) + "[GMT]");
   2686                     }
   2687                 }
   2688             } else if (U_SUCCESS(status)) {
   2689                 // strict, invalid wall time - must report an error
   2690                 dataerrln(UnicodeString("Fail: An error expected (UCAL_WALLTIME_FIRST)") +
   2691                     + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "]");
   2692             }
   2693 
   2694             // UCAL_WALLTIME_NEXT_VALID
   2695             status = U_ZERO_ERROR;
   2696             calNextAvail.setLenient(bLenient);
   2697             calNextAvail.setTimeZone(*tz);
   2698             SKDATA[i].in.setTo(calNextAvail);
   2699             d = calNextAvail.getTime(status);
   2700             if (bLenient || SKDATA[i].isValid) {
   2701                 calGMT.setTime(d, status);
   2702                 CalFields outNextAvailGMT(calGMT, status);
   2703                 if (U_FAILURE(status)) {
   2704                     errln(UnicodeString("Fail: Failed to get/set time calNextAvail/calGMT (UCAL_WALLTIME_NEXT_VALID) - ")
   2705                         + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "]");
   2706                 } else {
   2707                     if (outNextAvailGMT != SKDATA[i].expNextAvailGMT) {
   2708                         dataerrln(UnicodeString("Fail: UCAL_WALLTIME_NEXT_VALID ") + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "] is parsed as "
   2709                             + outNextAvailGMT.toString(buf, sizeof(buf)) + "[GMT]. Expected: " + SKDATA[i].expNextAvailGMT.toString(buf, sizeof(buf)) + "[GMT]");
   2710                     }
   2711                 }
   2712             } else if (U_SUCCESS(status)) {
   2713                 // strict, invalid wall time - must report an error
   2714                 dataerrln(UnicodeString("Fail: An error expected (UCAL_WALLTIME_NEXT_VALID)") +
   2715                     + SKDATA[i].in.toString(buf, sizeof(buf)) + "[" + SKDATA[i].tzid + "]");
   2716             }
   2717         }
   2718 
   2719         delete tz;
   2720     }
   2721 }
   2722 
   2723 void CalendarTest::TestCloneLocale(void) {
   2724   UErrorCode status = U_ZERO_ERROR;
   2725   LocalPointer<Calendar>  cal(Calendar::createInstance(TimeZone::getGMT()->clone(),
   2726                                                        Locale::createFromName("en"), status));
   2727   TEST_CHECK_STATUS;
   2728   Locale l0 = cal->getLocale(ULOC_VALID_LOCALE, status);
   2729   TEST_CHECK_STATUS;
   2730   LocalPointer<Calendar> cal2(cal->clone());
   2731   Locale l = cal2->getLocale(ULOC_VALID_LOCALE, status);
   2732   if(l0!=l) {
   2733     errln("Error: cloned locale %s != original locale %s, status %s\n", l0.getName(), l.getName(), u_errorName(status));
   2734   }
   2735   TEST_CHECK_STATUS;
   2736 }
   2737 
   2738 void CalendarTest::setAndTestCalendar(Calendar* cal, int32_t initMonth, int32_t initDay, int32_t initYear, UErrorCode& status) {
   2739         cal->clear();
   2740         cal->setLenient(FALSE);
   2741         cal->set(initYear, initMonth, initDay);
   2742         int32_t day = cal->get(UCAL_DAY_OF_MONTH, status);
   2743         int32_t month = cal->get(UCAL_MONTH, status);
   2744         int32_t year = cal->get(UCAL_YEAR, status);
   2745         if(U_FAILURE(status))
   2746             return;
   2747 
   2748         if(initDay != day || initMonth != month || initYear != year)
   2749         {
   2750             errln(" year init values:\tmonth %i\tday %i\tyear %i", initMonth, initDay, initYear);
   2751             errln("values post set():\tmonth %i\tday %i\tyear %i",month, day, year);
   2752         }
   2753 }
   2754 
   2755 void CalendarTest::setAndTestWholeYear(Calendar* cal, int32_t startYear, UErrorCode& status) {
   2756         for(int32_t startMonth = 0; startMonth < 12; startMonth++) {
   2757             for(int32_t startDay = 1; startDay < 31; startDay++ ) {
   2758                     setAndTestCalendar(cal, startMonth, startDay, startYear, status);
   2759                     if(U_FAILURE(status) && startDay == 30) {
   2760                         status = U_ZERO_ERROR;
   2761                         continue;
   2762                     }
   2763                     TEST_CHECK_STATUS;
   2764             }
   2765         }
   2766 }
   2767 
   2768 
   2769 void CalendarTest::TestIslamicUmAlQura() {
   2770 
   2771     UErrorCode status = U_ZERO_ERROR;
   2772     Locale islamicLoc("ar_SA@calendar=islamic-umalqura");
   2773     Calendar* tstCal = Calendar::createInstance(islamicLoc, status);
   2774 
   2775     IslamicCalendar* iCal = (IslamicCalendar*)tstCal;
   2776     if(strcmp(iCal->getType(), "islamic-umalqura") != 0) {
   2777         errln("wrong type of calendar created - %s", iCal->getType());
   2778     }
   2779 
   2780 
   2781     int32_t firstYear = 1318;
   2782     int32_t lastYear = 1368;    // just enough to be pretty sure
   2783     //int32_t lastYear = 1480;    // the whole shootin' match
   2784 
   2785     tstCal->clear();
   2786     tstCal->setLenient(FALSE);
   2787 
   2788     int32_t day=0, month=0, year=0, initDay = 27, initMonth = IslamicCalendar::RAJAB, initYear = 1434;
   2789 
   2790     for( int32_t startYear = firstYear; startYear <= lastYear; startYear++) {
   2791         setAndTestWholeYear(tstCal, startYear, status);
   2792         status = U_ZERO_ERROR;
   2793     }
   2794 
   2795     initMonth = IslamicCalendar::RABI_2;
   2796     initDay = 5;
   2797     int32_t loopCnt = 25;
   2798     tstCal->clear();
   2799     setAndTestCalendar( tstCal, initMonth, initDay, initYear, status);
   2800     TEST_CHECK_STATUS;
   2801 
   2802     for(int x=1; x<=loopCnt; x++) {
   2803         day = tstCal->get(UCAL_DAY_OF_MONTH,status);
   2804         month = tstCal->get(UCAL_MONTH,status);
   2805         year = tstCal->get(UCAL_YEAR,status);
   2806         TEST_CHECK_STATUS;
   2807         tstCal->roll(UCAL_DAY_OF_MONTH, (UBool)TRUE, status);
   2808         TEST_CHECK_STATUS;
   2809     }
   2810 
   2811     if(day != (initDay + loopCnt - 1) || month != IslamicCalendar::RABI_2 || year != 1434)
   2812       errln("invalid values for RABI_2 date after roll of %d", loopCnt);
   2813 
   2814     status = U_ZERO_ERROR;
   2815     tstCal->clear();
   2816     initMonth = 2;
   2817     initDay = 30;
   2818     setAndTestCalendar( tstCal, initMonth, initDay, initYear, status);
   2819     if(U_SUCCESS(status)) {
   2820         errln("error NOT detected status %i",status);
   2821         errln("      init values:\tmonth %i\tday %i\tyear %i", initMonth, initDay, initYear);
   2822         int32_t day = tstCal->get(UCAL_DAY_OF_MONTH, status);
   2823         int32_t month = tstCal->get(UCAL_MONTH, status);
   2824         int32_t year = tstCal->get(UCAL_YEAR, status);
   2825         errln("values post set():\tmonth %i\tday %i\tyear %i",month, day, year);
   2826     }
   2827 
   2828     status = U_ZERO_ERROR;
   2829     tstCal->clear();
   2830     initMonth = 3;
   2831     initDay = 30;
   2832     setAndTestCalendar( tstCal, initMonth, initDay, initYear, status);
   2833     TEST_CHECK_STATUS;
   2834 
   2835     SimpleDateFormat* formatter = new SimpleDateFormat("yyyy-MM-dd", Locale::getUS(), status);
   2836     UDate date = formatter->parse("1975-05-06", status);
   2837     Calendar* is_cal = Calendar::createInstance(islamicLoc, status);
   2838     is_cal->setTime(date, status);
   2839     int32_t is_day = is_cal->get(UCAL_DAY_OF_MONTH,status);
   2840     int32_t is_month = is_cal->get(UCAL_MONTH,status);
   2841     int32_t is_year = is_cal->get(UCAL_YEAR,status);
   2842     TEST_CHECK_STATUS;
   2843     if(is_day != 29 || is_month != IslamicCalendar::RABI_2 || is_year != 1395)
   2844         errln("unexpected conversion date month %i not %i or day %i not 20 or year %i not 1395", is_month, IslamicCalendar::RABI_2, is_day, is_year);
   2845 
   2846     UDate date2 = is_cal->getTime(status);
   2847     TEST_CHECK_STATUS;
   2848     if(date2 != date) {
   2849         errln("before(%f) and after(%f) dates don't match up!",date, date2);
   2850     }
   2851 
   2852     delete is_cal;
   2853     delete formatter;
   2854     delete tstCal;
   2855 }
   2856 
   2857 void CalendarTest::TestIslamicTabularDates() {
   2858     UErrorCode status = U_ZERO_ERROR;
   2859     Locale islamicLoc("ar_SA@calendar=islamic-civil");
   2860     Locale tblaLoc("ar_SA@calendar=islamic-tbla");
   2861     SimpleDateFormat* formatter = new SimpleDateFormat("yyyy-MM-dd", Locale::getUS(), status);
   2862     UDate date = formatter->parse("1975-05-06", status);
   2863 
   2864     Calendar* tstCal = Calendar::createInstance(islamicLoc, status);
   2865     tstCal->setTime(date, status);
   2866     int32_t is_day = tstCal->get(UCAL_DAY_OF_MONTH,status);
   2867     int32_t is_month = tstCal->get(UCAL_MONTH,status);
   2868     int32_t is_year = tstCal->get(UCAL_YEAR,status);
   2869     TEST_CHECK_STATUS;
   2870     delete tstCal;
   2871 
   2872     tstCal = Calendar::createInstance(tblaLoc, status);
   2873     tstCal->setTime(date, status);
   2874     int32_t tbla_day = tstCal->get(UCAL_DAY_OF_MONTH,status);
   2875     int32_t tbla_month = tstCal->get(UCAL_MONTH,status);
   2876     int32_t tbla_year = tstCal->get(UCAL_YEAR,status);
   2877     TEST_CHECK_STATUS;
   2878 
   2879     if(tbla_month != is_month || tbla_year != is_year)
   2880         errln("unexpected difference between islamic and tbla month %d : %d and/or year %d : %d",tbla_month,is_month,tbla_year,is_year);
   2881 
   2882     if(tbla_day - is_day != 1)
   2883         errln("unexpected day difference between islamic and tbla: %d : %d ",tbla_day,is_day);
   2884     delete tstCal;
   2885     delete formatter;
   2886 }
   2887 
   2888 
   2889 #endif /* #if !UCONFIG_NO_FORMATTING */
   2890 
   2891 //eof
   2892