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