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