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