Home | History | Annotate | Download | only in cintltst
      1 /********************************************************************
      2  * Copyright (c) 1997-2012, International Business Machines
      3  * Corporation and others. All Rights Reserved.
      4  ********************************************************************
      5  *
      6  * File CCALTST.C
      7  *
      8  * Modification History:
      9  *        Name                     Description
     10  *     Madhu Katragadda               Creation
     11  ********************************************************************
     12  */
     13 
     14 /* C API AND FUNCTIONALITY TEST FOR CALENDAR (ucol.h)*/
     15 
     16 #include "unicode/utypes.h"
     17 
     18 #if !UCONFIG_NO_FORMATTING
     19 
     20 #include <stdlib.h>
     21 #include <string.h>
     22 
     23 #include "unicode/uloc.h"
     24 #include "unicode/ucal.h"
     25 #include "unicode/udat.h"
     26 #include "unicode/ustring.h"
     27 #include "cintltst.h"
     28 #include "ccaltst.h"
     29 #include "cformtst.h"
     30 #include "cstring.h"
     31 #include "ulist.h"
     32 
     33 void TestGregorianChange(void);
     34 void TestFieldDifference(void);
     35 void TestAddRollEra0AndEraBounds(void);
     36 void TestGetTZTransition(void);
     37 
     38 void addCalTest(TestNode** root);
     39 
     40 void addCalTest(TestNode** root)
     41 {
     42 
     43     addTest(root, &TestCalendar, "tsformat/ccaltst/TestCalendar");
     44     addTest(root, &TestGetSetDateAPI, "tsformat/ccaltst/TestGetSetDateAPI");
     45     addTest(root, &TestFieldGetSet, "tsformat/ccaltst/TestFieldGetSet");
     46     addTest(root, &TestAddRollExtensive, "tsformat/ccaltst/TestAddRollExtensive");
     47     addTest(root, &TestGetLimits, "tsformat/ccaltst/TestGetLimits");
     48     addTest(root, &TestDOWProgression, "tsformat/ccaltst/TestDOWProgression");
     49     addTest(root, &TestGMTvsLocal, "tsformat/ccaltst/TestGMTvsLocal");
     50     addTest(root, &TestGregorianChange, "tsformat/ccaltst/TestGregorianChange");
     51     addTest(root, &TestGetKeywordValuesForLocale, "tsformat/ccaltst/TestGetKeywordValuesForLocale");
     52     addTest(root, &TestWeekend, "tsformat/ccaltst/TestWeekend");
     53     addTest(root, &TestFieldDifference, "tsformat/ccaltst/TestFieldDifference");
     54     addTest(root, &TestAmbiguousWallTime, "tsformat/ccaltst/TestAmbiguousWallTime");
     55     addTest(root, &TestAddRollEra0AndEraBounds, "tsformat/ccaltst/TestAddRollEra0AndEraBounds");
     56     addTest(root, &TestGetTZTransition, "tsformat/ccaltst/TestGetTZTransition");
     57 }
     58 
     59 /* "GMT" */
     60 static const UChar fgGMTID [] = { 0x0047, 0x004d, 0x0054, 0x0000 };
     61 
     62 /* "PST" */
     63 static const UChar PST[] = {0x50, 0x53, 0x54, 0x00}; /* "PST" */
     64 
     65 static const UChar EUROPE_PARIS[] = {0x45, 0x75, 0x72, 0x6F, 0x70, 0x65, 0x2F, 0x50, 0x61, 0x72, 0x69, 0x73, 0x00}; /* "Europe/Paris" */
     66 
     67 static const UChar AMERICA_LOS_ANGELES[] = {0x41, 0x6D, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2F,
     68     0x4C, 0x6F, 0x73, 0x5F, 0x41, 0x6E, 0x67, 0x65, 0x6C, 0x65, 0x73, 0x00}; /* America/Los_Angeles */
     69 
     70 typedef struct {
     71     const char *    locale;
     72     UCalendarType   calType;
     73     const char *    expectedResult;
     74 } UCalGetTypeTest;
     75 
     76 static const UCalGetTypeTest ucalGetTypeTests[] = {
     77     { "en_US",                   UCAL_GREGORIAN, "gregorian" },
     78     { "ja_JP@calendar=japanese", UCAL_DEFAULT,   "japanese"  },
     79     { "th_TH",                   UCAL_GREGORIAN, "gregorian" },
     80     { "th_TH",                   UCAL_DEFAULT,   "buddhist"  },
     81     { "th-TH-u-ca-gregory",      UCAL_DEFAULT,   "gregorian" },
     82     { "ja_JP@calendar=japanese", UCAL_GREGORIAN, "gregorian" },
     83     { "",                        UCAL_GREGORIAN, "gregorian" },
     84     { NULL,                      UCAL_GREGORIAN, "gregorian" },
     85     { NULL, 0, NULL } /* terminator */
     86 };
     87 
     88 static void TestCalendar()
     89 {
     90     UCalendar *caldef = 0, *caldef2 = 0, *calfr = 0, *calit = 0, *calfrclone = 0;
     91     UEnumeration* uenum = NULL;
     92     int32_t count, count2, i,j;
     93     UChar tzID[4];
     94     UChar *tzdname = 0;
     95     UErrorCode status = U_ZERO_ERROR;
     96     UDate now;
     97     UDateFormat *datdef = 0;
     98     UChar *result = 0;
     99     int32_t resultlength, resultlengthneeded;
    100     char tempMsgBuf[256];
    101     UChar zone1[32], zone2[32];
    102     const char *tzver = 0;
    103     UChar canonicalID[64];
    104     UBool isSystemID = FALSE;
    105     const UCalGetTypeTest * ucalGetTypeTestPtr;
    106 
    107 #ifdef U_USE_UCAL_OBSOLETE_2_8
    108     /*Testing countAvailableTimeZones*/
    109     int32_t offset=0;
    110     log_verbose("\nTesting ucal_countAvailableTZIDs\n");
    111     count=ucal_countAvailableTZIDs(offset);
    112     log_verbose("The number of timezone id's present with offset 0 are %d:\n", count);
    113     if(count < 5) /* Don't hard code an exact == test here! */
    114         log_err("FAIL: error in the ucal_countAvailableTZIDs - got %d expected at least 5 total\n", count);
    115 
    116     /*Testing getAvailableTZIDs*/
    117     log_verbose("\nTesting ucal_getAvailableTZIDs");
    118     for(i=0;i<count;i++){
    119         ucal_getAvailableTZIDs(offset, i, &status);
    120         if(U_FAILURE(status)){
    121             log_err("FAIL: ucal_getAvailableTZIDs returned %s\n", u_errorName(status));
    122         }
    123         log_verbose("%s\n", u_austrcpy(tempMsgBuf, ucal_getAvailableTZIDs(offset, i, &status)));
    124     }
    125     /*get Illegal TZID where index >= count*/
    126     ucal_getAvailableTZIDs(offset, i, &status);
    127     if(status != U_INDEX_OUTOFBOUNDS_ERROR){
    128         log_err("FAIL:for TZID index >= count Expected INDEX_OUTOFBOUNDS_ERROR Got %s\n", u_errorName(status));
    129     }
    130     status=U_ZERO_ERROR;
    131 #endif
    132 
    133     /*Test ucal_openTimeZones, ucal_openCountryTimeZones and ucal_openTimeZoneIDEnumeration */
    134     for (j=0; j<6; ++j) {
    135         const char *api = "?";
    136         const int32_t offsetMinus5 = -5*60*60*1000;
    137         switch (j) {
    138         case 0:
    139             api = "ucal_openTimeZones()";
    140             uenum = ucal_openTimeZones(&status);
    141             break;
    142         case 1:
    143             api = "ucal_openCountryTimeZones(US)";
    144             uenum = ucal_openCountryTimeZones("US", &status);
    145             break;
    146         case 2:
    147             api = "ucal_openTimeZoneIDEnumerarion(UCAL_ZONE_TYPE_CANONICAL, NULL, NULL)";
    148             uenum = ucal_openTimeZoneIDEnumeration(UCAL_ZONE_TYPE_CANONICAL, NULL, NULL, &status);
    149             break;
    150         case 3:
    151             api = "ucal_openTimeZoneIDEnumerarion(UCAL_ZONE_TYPE_CANONICAL_LOCATION, CA, NULL)";
    152             uenum = ucal_openTimeZoneIDEnumeration(UCAL_ZONE_TYPE_CANONICAL_LOCATION, "CA", NULL, &status);
    153             break;
    154         case 4:
    155             api = "ucal_openTimeZoneIDEnumerarion(UCAL_ZONE_TYPE_ANY, NULL, -5 hour)";
    156             uenum = ucal_openTimeZoneIDEnumeration(UCAL_ZONE_TYPE_ANY, NULL, &offsetMinus5, &status);
    157             break;
    158         case 5:
    159             api = "ucal_openTimeZoneIDEnumerarion(UCAL_ZONE_TYPE_ANY, US, -5 hour)";
    160             uenum = ucal_openTimeZoneIDEnumeration(UCAL_ZONE_TYPE_ANY, "US", &offsetMinus5, &status);
    161             break;
    162         }
    163         if (U_FAILURE(status)) {
    164             log_err_status(status, "FAIL: %s failed with %s\n", api,
    165                     u_errorName(status));
    166         } else {
    167             const char* id;
    168             int32_t len;
    169             count = uenum_count(uenum, &status);
    170             log_verbose("%s returned %d timezone id's:\n", api, count);
    171             if (count < 5) { /* Don't hard code an exact == test here! */
    172                 log_data_err("FAIL: in %s, got %d, expected at least 5 -> %s (Are you missing data?)\n", api, count, u_errorName(status));
    173             }
    174             uenum_reset(uenum, &status);
    175             if (U_FAILURE(status)){
    176                 log_err("FAIL: uenum_reset for %s returned %s\n",
    177                         api, u_errorName(status));
    178             }
    179             for (i=0; i<count; i++) {
    180                 id = uenum_next(uenum, &len, &status);
    181                 if (U_FAILURE(status)){
    182                     log_err("FAIL: uenum_next for %s returned %s\n",
    183                             api, u_errorName(status));
    184                 } else {
    185                     log_verbose("%s\n", id);
    186                 }
    187             }
    188             /* Next one should be NULL */
    189             id = uenum_next(uenum, &len, &status);
    190             if (id != NULL) {
    191                 log_err("FAIL: uenum_next for %s returned %s, expected NULL\n",
    192                         api, id);
    193             }
    194         }
    195         uenum_close(uenum);
    196     }
    197 
    198     /*Test ucal_getDSTSavings*/
    199     status = U_ZERO_ERROR;
    200     i = ucal_getDSTSavings(fgGMTID, &status);
    201     if (U_FAILURE(status)) {
    202         log_err("FAIL: ucal_getDSTSavings(GMT) => %s\n",
    203                 u_errorName(status));
    204     } else if (i != 0) {
    205         log_data_err("FAIL: ucal_getDSTSavings(GMT) => %d, expect 0 (Are you missing data?)\n", i);
    206     }
    207     i = ucal_getDSTSavings(PST, &status);
    208     if (U_FAILURE(status)) {
    209         log_err("FAIL: ucal_getDSTSavings(PST) => %s\n",
    210                 u_errorName(status));
    211     } else if (i != 1*60*60*1000) {
    212         log_err("FAIL: ucal_getDSTSavings(PST) => %d, expect %d\n", i, 1*60*60*1000);
    213     }
    214 
    215     /*Test ucal_set/getDefaultTimeZone*/
    216     status = U_ZERO_ERROR;
    217     i = ucal_getDefaultTimeZone(zone1, sizeof(zone1)/sizeof(zone1[0]), &status);
    218     if (U_FAILURE(status)) {
    219         log_err("FAIL: ucal_getDefaultTimeZone() => %s\n",
    220                 u_errorName(status));
    221     } else {
    222         ucal_setDefaultTimeZone(EUROPE_PARIS, &status);
    223         if (U_FAILURE(status)) {
    224             log_err("FAIL: ucal_setDefaultTimeZone(Europe/Paris) => %s\n",
    225                     u_errorName(status));
    226         } else {
    227             i = ucal_getDefaultTimeZone(zone2, sizeof(zone2)/sizeof(zone2[0]), &status);
    228             if (U_FAILURE(status)) {
    229                 log_err("FAIL: ucal_getDefaultTimeZone() => %s\n",
    230                         u_errorName(status));
    231             } else {
    232                 if (u_strcmp(zone2, EUROPE_PARIS) != 0) {
    233                     log_data_err("FAIL: ucal_getDefaultTimeZone() did not return Europe/Paris (Are you missing data?)\n");
    234                 }
    235             }
    236         }
    237         status = U_ZERO_ERROR;
    238         ucal_setDefaultTimeZone(zone1, &status);
    239     }
    240 
    241     /*Test ucal_getTZDataVersion*/
    242     status = U_ZERO_ERROR;
    243     tzver = ucal_getTZDataVersion(&status);
    244     if (U_FAILURE(status)) {
    245         log_err_status(status, "FAIL: ucal_getTZDataVersion() => %s\n", u_errorName(status));
    246     } else if (uprv_strlen(tzver) != 5 /*4 digits + 1 letter*/) {
    247         log_err("FAIL: Bad version string was returned by ucal_getTZDataVersion\n");
    248     } else {
    249         log_verbose("PASS: ucal_getTZDataVersion returned %s\n", tzver);
    250     }
    251 
    252     /*Testing ucal_getCanonicalTimeZoneID*/
    253     status = U_ZERO_ERROR;
    254     resultlength = ucal_getCanonicalTimeZoneID(PST, -1,
    255         canonicalID, sizeof(canonicalID)/sizeof(UChar), &isSystemID, &status);
    256     if (U_FAILURE(status)) {
    257         log_err("FAIL: error in ucal_getCanonicalTimeZoneID : %s\n", u_errorName(status));
    258     } else {
    259         if (u_strcmp(AMERICA_LOS_ANGELES, canonicalID) != 0) {
    260             log_data_err("FAIL: ucal_getCanonicalTimeZoneID(%s) returned %s : expected - %s (Are you missing data?)\n",
    261                 PST, canonicalID, AMERICA_LOS_ANGELES);
    262         }
    263         if (!isSystemID) {
    264             log_data_err("FAIL: ucal_getCanonicalTimeZoneID(%s) set %d to isSystemID (Are you missing data?)\n",
    265                 PST, isSystemID);
    266         }
    267     }
    268 
    269     /*Testing the  ucal_open() function*/
    270     status = U_ZERO_ERROR;
    271     log_verbose("\nTesting the ucal_open()\n");
    272     u_uastrcpy(tzID, "PST");
    273     caldef=ucal_open(tzID, u_strlen(tzID), "en_US", UCAL_TRADITIONAL, &status);
    274     if(U_FAILURE(status)){
    275         log_data_err("FAIL: error in ucal_open caldef : %s\n - (Are you missing data?)", u_errorName(status));
    276     }
    277 
    278     caldef2=ucal_open(tzID, u_strlen(tzID), "en_US", UCAL_TRADITIONAL, &status);
    279     if(U_FAILURE(status)){
    280         log_data_err("FAIL: error in ucal_open caldef : %s - (Are you missing data?)\n", u_errorName(status));
    281     }
    282     u_strcpy(tzID, fgGMTID);
    283     calfr=ucal_open(tzID, u_strlen(tzID), "fr_FR", UCAL_TRADITIONAL, &status);
    284     if(U_FAILURE(status)){
    285         log_data_err("FAIL: error in ucal_open calfr : %s - (Are you missing data?)\n", u_errorName(status));
    286     }
    287     calit=ucal_open(tzID, u_strlen(tzID), "it_IT", UCAL_TRADITIONAL, &status);
    288     if(U_FAILURE(status))    {
    289         log_data_err("FAIL: error in ucal_open calit : %s - (Are you missing data?)\n", u_errorName(status));
    290     }
    291 
    292     /*Testing the  clone() function*/
    293     calfrclone = ucal_clone(calfr, &status);
    294     if(U_FAILURE(status)){
    295         log_data_err("FAIL: error in ucal_clone calfr : %s - (Are you missing data?)\n", u_errorName(status));
    296     }
    297 
    298     /*Testing udat_getAvailable() and udat_countAvailable()*/
    299     log_verbose("\nTesting getAvailableLocales and countAvailable()\n");
    300     count=ucal_countAvailable();
    301     /* use something sensible w/o hardcoding the count */
    302     if(count > 0) {
    303         log_verbose("PASS: ucal_countAvailable() works fine\n");
    304         log_verbose("The no: of locales for which calendars are avilable are %d\n", count);
    305     } else {
    306         log_data_err("FAIL: Error in countAvailable()\n");
    307     }
    308 
    309     for(i=0;i<count;i++) {
    310        log_verbose("%s\n", ucal_getAvailable(i));
    311     }
    312 
    313 
    314     /*Testing the equality between calendar's*/
    315     log_verbose("\nTesting ucal_equivalentTo()\n");
    316     if(caldef && caldef2 && calfr && calit) {
    317       if(ucal_equivalentTo(caldef, caldef2) == FALSE || ucal_equivalentTo(caldef, calfr)== TRUE ||
    318         ucal_equivalentTo(caldef, calit)== TRUE || ucal_equivalentTo(calfr, calfrclone) == FALSE) {
    319           log_data_err("FAIL: Error. equivalentTo test failed (Are you missing data?)\n");
    320       } else {
    321           log_verbose("PASS: equivalentTo test passed\n");
    322       }
    323     }
    324 
    325 
    326     /*Testing the current time and date using ucal_getnow()*/
    327     log_verbose("\nTesting the ucal_getNow function to check if it is fetching tbe current time\n");
    328     now=ucal_getNow();
    329     /* open the date format and format the date to check the output */
    330     datdef=udat_open(UDAT_FULL,UDAT_FULL ,NULL, NULL, 0,NULL,0,&status);
    331     if(U_FAILURE(status)){
    332         log_data_err("FAIL: error in creating the dateformat : %s (Are you missing data?)\n", u_errorName(status));
    333         return;
    334     }
    335     log_verbose("PASS: The current date and time fetched is %s\n", u_austrcpy(tempMsgBuf, myDateFormat(datdef, now)) );
    336 
    337 
    338     /*Testing the TimeZoneDisplayName */
    339     log_verbose("\nTesting the fetching of time zone display name\n");
    340     /*for the US locale */
    341     resultlength=0;
    342     resultlengthneeded=ucal_getTimeZoneDisplayName(caldef, UCAL_DST, "en_US", NULL, resultlength, &status);
    343 
    344     if(status==U_BUFFER_OVERFLOW_ERROR)
    345     {
    346         status=U_ZERO_ERROR;
    347         resultlength=resultlengthneeded+1;
    348         result=(UChar*)malloc(sizeof(UChar) * resultlength);
    349         ucal_getTimeZoneDisplayName(caldef, UCAL_DST, "en_US", result, resultlength, &status);
    350     }
    351     if(U_FAILURE(status))    {
    352         log_err("FAIL: Error in getting the timezone display name : %s\n", u_errorName(status));
    353     }
    354     else{
    355         log_verbose("PASS: getting the time zone display name successful : %s, %d needed \n",
    356             u_errorName(status), resultlengthneeded);
    357     }
    358 
    359 
    360 #define expectPDT "Pacific Daylight Time"
    361 
    362     tzdname=(UChar*)malloc(sizeof(UChar) * (sizeof(expectPDT)+1));
    363     u_uastrcpy(tzdname, expectPDT);
    364     if(u_strcmp(tzdname, result)==0){
    365         log_verbose("PASS: got the correct time zone display name %s\n", u_austrcpy(tempMsgBuf, result) );
    366     }
    367     else{
    368         log_err("FAIL: got the wrong time zone(DST) display name %s, wanted %s\n", austrdup(result) , expectPDT);
    369     }
    370 
    371     ucal_getTimeZoneDisplayName(caldef, UCAL_SHORT_DST, "en_US", result, resultlength, &status);
    372     u_uastrcpy(tzdname, "PDT");
    373     if(u_strcmp(tzdname, result) != 0){
    374         log_err("FAIL: got the wrong time zone(SHORT_DST) display name %s, wanted %s\n", austrdup(result), austrdup(tzdname));
    375     }
    376 
    377     ucal_getTimeZoneDisplayName(caldef, UCAL_STANDARD, "en_US", result, resultlength, &status);
    378     u_uastrcpy(tzdname, "Pacific Standard Time");
    379     if(u_strcmp(tzdname, result) != 0){
    380         log_err("FAIL: got the wrong time zone(STANDARD) display name %s, wanted %s\n", austrdup(result), austrdup(tzdname));
    381     }
    382 
    383     ucal_getTimeZoneDisplayName(caldef, UCAL_SHORT_STANDARD, "en_US", result, resultlength, &status);
    384     u_uastrcpy(tzdname, "PST");
    385     if(u_strcmp(tzdname, result) != 0){
    386         log_err("FAIL: got the wrong time zone(SHORT_STANDARD) display name %s, wanted %s\n", austrdup(result), austrdup(tzdname));
    387     }
    388 
    389 
    390     /*testing the setAttributes and getAttributes of a UCalendar*/
    391     log_verbose("\nTesting the getAttributes and set Attributes\n");
    392     count=ucal_getAttribute(calit, UCAL_LENIENT);
    393     count2=ucal_getAttribute(calfr, UCAL_LENIENT);
    394     ucal_setAttribute(calit, UCAL_LENIENT, 0);
    395     ucal_setAttribute(caldef, UCAL_LENIENT, count2);
    396     if( ucal_getAttribute(calit, UCAL_LENIENT) !=0 ||
    397         ucal_getAttribute(calfr, UCAL_LENIENT)!=ucal_getAttribute(caldef, UCAL_LENIENT) )
    398         log_err("FAIL: there is an error in getAttributes or setAttributes\n");
    399     else
    400         log_verbose("PASS: attribute set and got successfully\n");
    401         /*set it back to orginal value */
    402     log_verbose("Setting it back to normal\n");
    403     ucal_setAttribute(calit, UCAL_LENIENT, count);
    404     if(ucal_getAttribute(calit, UCAL_LENIENT)!=count)
    405         log_err("FAIL: Error in setting the attribute back to normal\n");
    406 
    407     /*setting the first day of the week to other values  */
    408     count=ucal_getAttribute(calit, UCAL_FIRST_DAY_OF_WEEK);
    409     for (i=1; i<=7; ++i) {
    410         ucal_setAttribute(calit, UCAL_FIRST_DAY_OF_WEEK,i);
    411         if (ucal_getAttribute(calit, UCAL_FIRST_DAY_OF_WEEK) != i)
    412             log_err("FAIL: set/getFirstDayOfWeek failed\n");
    413     }
    414     /*get bogus Attribute*/
    415     count=ucal_getAttribute(calit, (UCalendarAttribute)99); /* BOGUS_ATTRIBUTE */
    416     if(count != -1){
    417         log_err("FAIL: get/bogus attribute should return -1\n");
    418     }
    419 
    420     /*set it back to normal */
    421     ucal_setAttribute(calit, UCAL_FIRST_DAY_OF_WEEK,count);
    422     /*setting minimal days of the week to other values */
    423     count=ucal_getAttribute(calit, UCAL_MINIMAL_DAYS_IN_FIRST_WEEK);
    424     for (i=1; i<=7; ++i) {
    425         ucal_setAttribute(calit, UCAL_MINIMAL_DAYS_IN_FIRST_WEEK,i);
    426         if (ucal_getAttribute(calit, UCAL_MINIMAL_DAYS_IN_FIRST_WEEK) != i)
    427             log_err("FAIL: set/getMinimalDaysInFirstWeek failed\n");
    428     }
    429     /*set it back to normal */
    430     ucal_setAttribute(calit, UCAL_MINIMAL_DAYS_IN_FIRST_WEEK,count);
    431 
    432 
    433     /*testing if the UCalendar's timezone is currently in day light saving's time*/
    434     log_verbose("\nTesting if the UCalendar is currently in daylight saving's time\n");
    435     ucal_setDateTime(caldef, 1999, UCAL_MARCH, 3, 10, 45, 20, &status);
    436     ucal_inDaylightTime(caldef, &status );
    437     if(U_FAILURE(status))    {
    438         log_err("Error in ucal_inDaylightTime: %s\n", u_errorName(status));
    439     }
    440     if(!ucal_inDaylightTime(caldef, &status))
    441         log_verbose("PASS: It is not in daylight saving's time\n");
    442     else
    443         log_err("FAIL: It is not in daylight saving's time\n");
    444 
    445     /*closing the UCalendar*/
    446     ucal_close(caldef);
    447     ucal_close(caldef2);
    448     ucal_close(calfr);
    449     ucal_close(calit);
    450     ucal_close(calfrclone);
    451 
    452     /*testing ucal_getType, and ucal_open with UCAL_GREGORIAN*/
    453     for (ucalGetTypeTestPtr = ucalGetTypeTests; ucalGetTypeTestPtr->expectedResult != NULL; ++ucalGetTypeTestPtr) {
    454         const char * localeToDisplay = (ucalGetTypeTestPtr->locale != NULL)? ucalGetTypeTestPtr->locale: "<NULL>";
    455         status = U_ZERO_ERROR;
    456         caldef = ucal_open(NULL, 0, ucalGetTypeTestPtr->locale, ucalGetTypeTestPtr->calType, &status);
    457         if ( U_SUCCESS(status) ) {
    458             const char * calType = ucal_getType(caldef, &status);
    459             if ( U_SUCCESS(status) && calType != NULL ) {
    460                 if ( uprv_strcmp( calType, ucalGetTypeTestPtr->expectedResult ) != 0 ) {
    461                     log_err("FAIL: ucal_open %s type %d does not return %s calendar\n", localeToDisplay,
    462                                                 ucalGetTypeTestPtr->calType, ucalGetTypeTestPtr->expectedResult);
    463                 }
    464             } else {
    465                 log_err("FAIL: ucal_open %s type %d, then ucal_getType fails\n", localeToDisplay, ucalGetTypeTestPtr->calType);
    466             }
    467             ucal_close(caldef);
    468         } else {
    469             log_err("FAIL: ucal_open %s type %d fails\n", localeToDisplay, ucalGetTypeTestPtr->calType);
    470         }
    471     }
    472 
    473     /*closing the UDateFormat used */
    474     udat_close(datdef);
    475     free(result);
    476     free(tzdname);
    477 }
    478 
    479 /*------------------------------------------------------*/
    480 /*Testing the getMillis, setMillis, setDate and setDateTime functions extensively*/
    481 
    482 static void TestGetSetDateAPI()
    483 {
    484     UCalendar *caldef = 0, *caldef2 = 0, *caldef3 = 0;
    485     UChar tzID[4];
    486     UDate d1;
    487     int32_t hour;
    488     int32_t zoneOffset;
    489     UDateFormat *datdef = 0;
    490     UErrorCode status=U_ZERO_ERROR;
    491     UDate d2= 837039928046.0;
    492     UChar temp[30];
    493 	double testMillis;
    494 	int32_t dateBit;
    495 
    496     log_verbose("\nOpening the calendars()\n");
    497     u_strcpy(tzID, fgGMTID);
    498     /*open the calendars used */
    499     caldef=ucal_open(tzID, u_strlen(tzID), "en_US", UCAL_TRADITIONAL, &status);
    500     caldef2=ucal_open(tzID, u_strlen(tzID), "en_US", UCAL_TRADITIONAL, &status);
    501     caldef3=ucal_open(tzID, u_strlen(tzID), "en_US", UCAL_TRADITIONAL, &status);
    502     /*open the dateformat */
    503     /* this is supposed to open default date format, but later on it treats it like it is "en_US"
    504        - very bad if you try to run the tests on machine where default locale is NOT "en_US" */
    505     /*datdef=udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,NULL,fgGMTID,-1, &status);*/
    506     datdef=udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,"en_US",fgGMTID,-1,NULL,0, &status);
    507     if(U_FAILURE(status))
    508     {
    509         log_data_err("error in creating the dateformat : %s (Are you missing data?)\n", u_errorName(status));
    510         return;
    511     }
    512 
    513 
    514     /*Testing getMillis and setMillis */
    515     log_verbose("\nTesting the date and time fetched in millis for a calendar using getMillis\n");
    516     d1=ucal_getMillis(caldef, &status);
    517     if(U_FAILURE(status)){
    518         log_err("Error in getMillis : %s\n", u_errorName(status));
    519     }
    520 
    521     /*testing setMillis */
    522     log_verbose("\nTesting the set date and time function using setMillis\n");
    523     ucal_setMillis(caldef, d2, &status);
    524     if(U_FAILURE(status)){
    525         log_err("Error in setMillis : %s\n", u_errorName(status));
    526     }
    527 
    528     /*testing if the calendar date is set properly or not  */
    529     d1=ucal_getMillis(caldef, &status);
    530     if(u_strcmp(myDateFormat(datdef, d1), myDateFormat(datdef, d2))!=0)
    531         log_err("error in setMillis or getMillis\n");
    532     /*-------------------*/
    533 
    534     /*testing large negative millis*/
    535 	/*test a previously failed millis and beyond the lower bounds - ICU trac #9403 */
    536 	// -184303902611600000.0         - just beyond lower bounds (#9403 sets U_ILLEGAL_ARGUMENT_ERROR in strict mode)
    537 	// -46447814188001000.0	         - fixed by #9403
    538 
    539     log_verbose("\nTesting very large valid millis & invalid setMillis values (in both strict & lienent modes) detected\n");
    540 
    541 	testMillis = -46447814188001000.0;	// point where floorDivide in handleComputeFields failed as per #9403
    542 	log_verbose("using value[%lf]\n", testMillis);
    543     ucal_setAttribute(caldef3, UCAL_LENIENT, 0);
    544     ucal_setMillis(caldef3, testMillis, &status);
    545    	if(U_FAILURE(status)){
    546    		log_err("Fail: setMillis incorrectly detected invalid value : for millis : %e : returned  : %s\n", testMillis, u_errorName(status));
    547 		status = U_ZERO_ERROR;
    548 	}
    549 
    550     log_verbose("\nTesting invalid setMillis values detected\n");
    551 	testMillis = -184303902611600000.0;
    552 	log_verbose("using value[%lf]\n", testMillis);
    553     ucal_setAttribute(caldef3, UCAL_LENIENT, 1);
    554    	ucal_setMillis(caldef3, testMillis, &status);
    555    	if(U_FAILURE(status)){
    556    		log_err("Fail: setMillis incorrectly detected invalid value : for millis : %e : returned  : %s\n", testMillis, u_errorName(status));
    557 		status = U_ZERO_ERROR;
    558    	} else {
    559         dateBit = ucal_get(caldef2, UCAL_MILLISECOND, &status);
    560         if(testMillis == dateBit)
    561         {
    562 		    log_err("Fail: error in setMillis, allowed invalid value %e : returns millisecond : %d", testMillis, dateBit);
    563         } else {
    564             log_verbose("Pass: setMillis correctly pinned min, returned : %d", dateBit);
    565         }
    566 	}
    567 
    568     log_verbose("\nTesting invalid setMillis values detected\n");
    569 	testMillis = -184303902611600000.0;
    570 	log_verbose("using value[%lf]\n", testMillis);
    571     ucal_setAttribute(caldef3, UCAL_LENIENT, 0);
    572    	ucal_setMillis(caldef3, testMillis, &status);
    573    	if(U_FAILURE(status)){
    574    		log_verbose("Pass: Illegal argument error as expected : for millis : %e : returned  : %s\n", testMillis, u_errorName(status));
    575 		status = U_ZERO_ERROR;
    576    	} else {
    577 		dateBit = ucal_get(caldef3, UCAL_DAY_OF_MONTH, &status);
    578 		log_err("Fail: error in setMillis, allowed invalid value %e : returns DayOfMonth : %d", testMillis, dateBit);
    579 	}
    580 	/*-------------------*/
    581 
    582 
    583     ctest_setTimeZone(NULL, &status);
    584 
    585     /*testing ucal_setTimeZone() function*/
    586     log_verbose("\nTesting if the function ucal_setTimeZone() works fine\n");
    587     ucal_setMillis(caldef2, d2, &status);
    588     if(U_FAILURE(status)){
    589         log_err("Error in getMillis : %s\n", u_errorName(status));;
    590     }
    591     hour=ucal_get(caldef2, UCAL_HOUR_OF_DAY, &status);
    592 
    593     u_uastrcpy(tzID, "PST");
    594     ucal_setTimeZone(caldef2,tzID, 3, &status);
    595     if(U_FAILURE(status)){
    596         log_err("Error in setting the time zone using ucal_setTimeZone(): %s\n", u_errorName(status));
    597     }
    598     else
    599         log_verbose("ucal_setTimeZone worked fine\n");
    600     if(hour == ucal_get(caldef2, UCAL_HOUR_OF_DAY, &status))
    601         log_err("FAIL: Error setting the time zone doesn't change the represented time\n");
    602     else if((hour-8 + 1) != ucal_get(caldef2, UCAL_HOUR_OF_DAY, &status)) /*because it is not in daylight savings time */
    603         log_err("FAIL: Error setTimeZone doesn't change the represented time correctly with 8 hour offset\n");
    604     else
    605         log_verbose("PASS: setTimeZone works fine\n");
    606 
    607     /*testing setTimeZone roundtrip */
    608     log_verbose("\nTesting setTimeZone() roundtrip\n");
    609     u_strcpy(tzID, fgGMTID);
    610     ucal_setTimeZone(caldef2, tzID, 3, &status);
    611     if(U_FAILURE(status)){
    612         log_err("Error in setting the time zone using ucal_setTimeZone(): %s\n", u_errorName(status));
    613     }
    614     if(d2==ucal_getMillis(caldef2, &status))
    615         log_verbose("PASS: setTimeZone roundtrip test passed\n");
    616     else
    617         log_err("FAIL: setTimeZone roundtrip test failed\n");
    618 
    619     zoneOffset = ucal_get(caldef2, UCAL_ZONE_OFFSET, &status);
    620     if(U_FAILURE(status)){
    621         log_err("Error in getting the time zone using ucal_get() after using ucal_setTimeZone(): %s\n", u_errorName(status));
    622     }
    623     else if (zoneOffset != 0) {
    624         log_err("Error in getting the time zone using ucal_get() after using ucal_setTimeZone() offset=%d\n", zoneOffset);
    625     }
    626 
    627     ucal_setTimeZone(caldef2, NULL, -1, &status);
    628     if(U_FAILURE(status)){
    629         log_err("Error in setting the time zone using ucal_setTimeZone(): %s\n", u_errorName(status));
    630     }
    631     if(ucal_getMillis(caldef2, &status))
    632         log_verbose("PASS: setTimeZone roundtrip test passed\n");
    633     else
    634         log_err("FAIL: setTimeZone roundtrip test failed\n");
    635 
    636     zoneOffset = ucal_get(caldef2, UCAL_ZONE_OFFSET, &status);
    637     if(U_FAILURE(status)){
    638         log_err("Error in getting the time zone using ucal_get() after using ucal_setTimeZone(): %s\n", u_errorName(status));
    639     }
    640     else if (zoneOffset != -28800000) {
    641         log_err("Error in getting the time zone using ucal_get() after using ucal_setTimeZone() offset=%d\n", zoneOffset);
    642     }
    643 
    644     ctest_resetTimeZone();
    645 
    646 /*----------------------------*     */
    647 
    648 
    649 
    650     /*Testing  if setDate works fine  */
    651     log_verbose("\nTesting the ucal_setDate() function \n");
    652     u_uastrcpy(temp, "Dec 17, 1971, 11:05:28 PM");
    653     ucal_setDate(caldef,1971, UCAL_DECEMBER, 17, &status);
    654     if(U_FAILURE(status)){
    655         log_err("error in setting the calendar date : %s\n", u_errorName(status));
    656     }
    657     /*checking if the calendar date is set properly or not  */
    658     d1=ucal_getMillis(caldef, &status);
    659     if(u_strcmp(myDateFormat(datdef, d1), temp)==0)
    660         log_verbose("PASS:setDate works fine\n");
    661     else
    662         log_err("FAIL:Error in setDate()\n");
    663 
    664 
    665     /* Testing setDate Extensively with various input values */
    666     log_verbose("\nTesting ucal_setDate() extensively\n");
    667     ucal_setDate(caldef, 1999, UCAL_JANUARY, 10, &status);
    668     verify1("1999  10th day of January  is :", caldef, datdef, 1999, UCAL_JANUARY, 10);
    669     ucal_setDate(caldef, 1999, UCAL_DECEMBER, 3, &status);
    670     verify1("1999 3rd day of December  is :", caldef, datdef, 1999, UCAL_DECEMBER, 3);
    671     ucal_setDate(caldef, 2000, UCAL_MAY, 3, &status);
    672     verify1("2000 3rd day of May is :", caldef, datdef, 2000, UCAL_MAY, 3);
    673     ucal_setDate(caldef, 1999, UCAL_AUGUST, 32, &status);
    674     verify1("1999 32th day of August is :", caldef, datdef, 1999, UCAL_SEPTEMBER, 1);
    675     ucal_setDate(caldef, 1999, UCAL_MARCH, 0, &status);
    676     verify1("1999 0th day of March is :", caldef, datdef, 1999, UCAL_FEBRUARY, 28);
    677     ucal_setDate(caldef, 0, UCAL_MARCH, 12, &status);
    678 
    679     /*--------------------*/
    680 
    681     /*Testing if setDateTime works fine */
    682     log_verbose("\nTesting the ucal_setDateTime() function \n");
    683     u_uastrcpy(temp, "May 3, 1972, 4:30:42 PM");
    684     ucal_setDateTime(caldef,1972, UCAL_MAY, 3, 16, 30, 42, &status);
    685     if(U_FAILURE(status)){
    686         log_err("error in setting the calendar date : %s\n", u_errorName(status));
    687     }
    688     /*checking  if the calendar date is set properly or not  */
    689     d1=ucal_getMillis(caldef, &status);
    690     if(u_strcmp(myDateFormat(datdef, d1), temp)==0)
    691         log_verbose("PASS: setDateTime works fine\n");
    692     else
    693         log_err("FAIL: Error in setDateTime\n");
    694 
    695 
    696 
    697     /*Testing setDateTime extensively with various input values*/
    698     log_verbose("\nTesting ucal_setDateTime() function extensively\n");
    699     ucal_setDateTime(caldef, 1999, UCAL_OCTOBER, 10, 6, 45, 30, &status);
    700     verify2("1999  10th day of October  at 6:45:30 is :", caldef, datdef, 1999, UCAL_OCTOBER, 10, 6, 45, 30, 0 );
    701     ucal_setDateTime(caldef, 1999, UCAL_MARCH, 3, 15, 10, 55, &status);
    702     verify2("1999 3rd day of March   at 15:10:55 is :", caldef, datdef, 1999, UCAL_MARCH, 3, 3, 10, 55, 1);
    703     ucal_setDateTime(caldef, 1999, UCAL_MAY, 3, 25, 30, 45, &status);
    704     verify2("1999 3rd day of May at 25:30:45 is :", caldef, datdef, 1999, UCAL_MAY, 4, 1, 30, 45, 0);
    705     ucal_setDateTime(caldef, 1999, UCAL_AUGUST, 32, 22, 65, 40, &status);
    706     verify2("1999 32th day of August at 22:65:40 is :", caldef, datdef, 1999, UCAL_SEPTEMBER, 1, 11, 5, 40,1);
    707     ucal_setDateTime(caldef, 1999, UCAL_MARCH, 12, 0, 0, 0,&status);
    708     verify2("1999 12th day of March at 0:0:0 is :", caldef, datdef, 1999, UCAL_MARCH, 12, 0, 0, 0, 0);
    709     ucal_setDateTime(caldef, 1999, UCAL_MARCH, 12, -10, -10,0, &status);
    710     verify2("1999 12th day of March is at -10:-10:0 :", caldef, datdef, 1999, UCAL_MARCH, 11, 1, 50, 0, 1);
    711 
    712 
    713 
    714     /*close caldef and datdef*/
    715     ucal_close(caldef);
    716     ucal_close(caldef2);
    717     ucal_close(caldef3);
    718     udat_close(datdef);
    719 }
    720 
    721 /*----------------------------------------------------------- */
    722 /**
    723  * Confirm the functioning of the calendar field related functions.
    724  */
    725 static void TestFieldGetSet()
    726 {
    727     UCalendar *cal = 0;
    728     UChar tzID[4];
    729     UDateFormat *datdef = 0;
    730     UDate d1;
    731     UErrorCode status=U_ZERO_ERROR;
    732     log_verbose("\nFetching pointer to UCalendar using the ucal_open()\n");
    733     u_strcpy(tzID, fgGMTID);
    734     /*open the calendar used */
    735     cal=ucal_open(tzID, u_strlen(tzID), "en_US", UCAL_TRADITIONAL, &status);
    736     if (U_FAILURE(status)) {
    737         log_data_err("ucal_open failed: %s - (Are you missing data?)\n", u_errorName(status));
    738         return;
    739     }
    740     datdef=udat_open(UDAT_SHORT,UDAT_SHORT ,NULL,fgGMTID,-1,NULL, 0, &status);
    741     if(U_FAILURE(status))
    742     {
    743         log_data_err("error in creating the dateformat : %s (Are you missing data?)\n", u_errorName(status));
    744     }
    745 
    746     /*Testing ucal_get()*/
    747     log_verbose("\nTesting the ucal_get() function of Calendar\n");
    748     ucal_setDateTime(cal, 1999, UCAL_MARCH, 12, 5, 25, 30, &status);
    749     if(U_FAILURE(status)){
    750         log_data_err("error in the setDateTime() : %s (Are you missing data?)\n", u_errorName(status));
    751     }
    752     if(ucal_get(cal, UCAL_YEAR, &status)!=1999 || ucal_get(cal, UCAL_MONTH, &status)!=2 ||
    753         ucal_get(cal, UCAL_DATE, &status)!=12 || ucal_get(cal, UCAL_HOUR, &status)!=5)
    754         log_data_err("error in ucal_get() -> %s (Are you missing data?)\n", u_errorName(status));
    755     else if(ucal_get(cal, UCAL_DAY_OF_WEEK_IN_MONTH, &status)!=2 || ucal_get(cal, UCAL_DAY_OF_WEEK, &status)!=6
    756         || ucal_get(cal, UCAL_WEEK_OF_MONTH, &status)!=2 || ucal_get(cal, UCAL_WEEK_OF_YEAR, &status)!= 11)
    757         log_err("FAIL: error in ucal_get()\n");
    758     else
    759         log_verbose("PASS: ucal_get() works fine\n");
    760 
    761     /*Testing the ucal_set() , ucal_clear() functions of calendar*/
    762     log_verbose("\nTesting the set, and clear  field functions of calendar\n");
    763     ucal_setAttribute(cal, UCAL_LENIENT, 0);
    764     ucal_clear(cal);
    765     ucal_set(cal, UCAL_YEAR, 1997);
    766     ucal_set(cal, UCAL_MONTH, UCAL_JUNE);
    767     ucal_set(cal, UCAL_DATE, 3);
    768     verify1("1997 third day of June = ", cal, datdef, 1997, UCAL_JUNE, 3);
    769     ucal_clear(cal);
    770     ucal_set(cal, UCAL_YEAR, 1997);
    771     ucal_set(cal, UCAL_DAY_OF_WEEK, UCAL_TUESDAY);
    772     ucal_set(cal, UCAL_MONTH, UCAL_JUNE);
    773     ucal_set(cal, UCAL_DAY_OF_WEEK_IN_MONTH, 1);
    774     verify1("1997 first Tuesday in June = ", cal, datdef, 1997, UCAL_JUNE, 3);
    775     ucal_clear(cal);
    776     ucal_set(cal, UCAL_YEAR, 1997);
    777     ucal_set(cal, UCAL_DAY_OF_WEEK, UCAL_TUESDAY);
    778     ucal_set(cal, UCAL_MONTH, UCAL_JUNE);
    779     ucal_set(cal, UCAL_DAY_OF_WEEK_IN_MONTH, - 1);
    780     verify1("1997 last Tuesday in June = ", cal, datdef,1997,   UCAL_JUNE, 24);
    781     /*give undesirable input    */
    782     status = U_ZERO_ERROR;
    783     ucal_clear(cal);
    784     ucal_set(cal, UCAL_YEAR, 1997);
    785     ucal_set(cal, UCAL_DAY_OF_WEEK, UCAL_TUESDAY);
    786     ucal_set(cal, UCAL_MONTH, UCAL_JUNE);
    787     ucal_set(cal, UCAL_DAY_OF_WEEK_IN_MONTH, 0);
    788     d1 = ucal_getMillis(cal, &status);
    789     if (status != U_ILLEGAL_ARGUMENT_ERROR) {
    790         log_err("FAIL: U_ILLEGAL_ARGUMENT_ERROR was not returned for : 1997 zero-th Tuesday in June\n");
    791     } else {
    792         log_verbose("PASS: U_ILLEGAL_ARGUMENT_ERROR as expected\n");
    793     }
    794     status = U_ZERO_ERROR;
    795     ucal_clear(cal);
    796     ucal_set(cal, UCAL_YEAR, 1997);
    797     ucal_set(cal, UCAL_DAY_OF_WEEK, UCAL_TUESDAY);
    798     ucal_set(cal, UCAL_MONTH, UCAL_JUNE);
    799     ucal_set(cal, UCAL_WEEK_OF_MONTH, 1);
    800     verify1("1997 Tuesday in week 1 of June = ", cal,datdef, 1997, UCAL_JUNE, 3);
    801     ucal_clear(cal);
    802     ucal_set(cal, UCAL_YEAR, 1997);
    803     ucal_set(cal, UCAL_DAY_OF_WEEK, UCAL_TUESDAY);
    804     ucal_set(cal, UCAL_MONTH, UCAL_JUNE);
    805     ucal_set(cal, UCAL_WEEK_OF_MONTH, 5);
    806     verify1("1997 Tuesday in week 5 of June = ", cal,datdef, 1997, UCAL_JULY, 1);
    807     status = U_ZERO_ERROR;
    808     ucal_clear(cal);
    809     ucal_set(cal, UCAL_YEAR, 1997);
    810     ucal_set(cal, UCAL_DAY_OF_WEEK, UCAL_TUESDAY);
    811     ucal_set(cal, UCAL_MONTH, UCAL_JUNE);
    812     ucal_set(cal, UCAL_WEEK_OF_MONTH, 0);
    813     ucal_setAttribute(cal, UCAL_MINIMAL_DAYS_IN_FIRST_WEEK,1);
    814     d1 = ucal_getMillis(cal,&status);
    815     if (status != U_ILLEGAL_ARGUMENT_ERROR){
    816         log_err("FAIL: U_ILLEGAL_ARGUMENT_ERROR was not returned for : 1997 Tuesday zero-th week in June\n");
    817     } else {
    818         log_verbose("PASS: U_ILLEGAL_ARGUMENT_ERROR as expected\n");
    819     }
    820     status = U_ZERO_ERROR;
    821     ucal_clear(cal);
    822     ucal_set(cal, UCAL_YEAR_WOY, 1997);
    823     ucal_set(cal, UCAL_DAY_OF_WEEK, UCAL_TUESDAY);
    824     ucal_set(cal, UCAL_WEEK_OF_YEAR, 1);
    825     verify1("1997 Tuesday in week 1 of year = ", cal, datdef,1996, UCAL_DECEMBER, 31);
    826     ucal_clear(cal);
    827     ucal_set(cal, UCAL_YEAR, 1997);
    828     ucal_set(cal, UCAL_DAY_OF_WEEK, UCAL_TUESDAY);
    829     ucal_set(cal, UCAL_WEEK_OF_YEAR, 10);
    830     verify1("1997 Tuesday in week 10 of year = ", cal,datdef, 1997, UCAL_MARCH, 4);
    831     ucal_clear(cal);
    832     ucal_set(cal, UCAL_YEAR, 1999);
    833     ucal_set(cal, UCAL_DAY_OF_YEAR, 1);
    834     verify1("1999 1st day of the year =", cal, datdef, 1999, UCAL_JANUARY, 1);
    835     ucal_set(cal, UCAL_MONTH, -3);
    836     d1 = ucal_getMillis(cal,&status);
    837     if (status != U_ILLEGAL_ARGUMENT_ERROR){
    838         log_err("FAIL: U_ILLEGAL_ARGUMENT_ERROR was not returned for : 1999 -3th month\n");
    839     } else {
    840         log_verbose("PASS: U_ILLEGAL_ARGUMENT_ERROR as expected\n");
    841     }
    842 
    843     ucal_setAttribute(cal, UCAL_LENIENT, 1);
    844 
    845     ucal_set(cal, UCAL_MONTH, -3);
    846     verify1("1999 -3th month should be", cal, datdef, 1998, UCAL_OCTOBER, 1);
    847 
    848 
    849     /*testing isSet and clearField()*/
    850     if(!ucal_isSet(cal, UCAL_WEEK_OF_YEAR))
    851         log_err("FAIL: error in isSet\n");
    852     else
    853         log_verbose("PASS: isSet working fine\n");
    854     ucal_clearField(cal, UCAL_WEEK_OF_YEAR);
    855     if(ucal_isSet(cal, UCAL_WEEK_OF_YEAR))
    856         log_err("FAIL: there is an error in clearField or isSet\n");
    857     else
    858         log_verbose("PASS :clearField working fine\n");
    859 
    860     /*-------------------------------*/
    861 
    862     ucal_close(cal);
    863     udat_close(datdef);
    864 }
    865 
    866 typedef struct {
    867     const char * zone;
    868     int32_t      year;
    869     int32_t      month;
    870     int32_t      day;
    871     int32_t      hour;
    872 } TransitionItem;
    873 
    874 static const TransitionItem transitionItems[] = {
    875     { "America/Caracas", 2007, UCAL_DECEMBER,  8, 10 }, /* day before change in UCAL_ZONE_OFFSET */
    876     { "US/Pacific",      2011,    UCAL_MARCH, 12, 10 }, /* day before change in UCAL_DST_OFFSET */
    877     { NULL,                 0,             0,  0,  0 }
    878 };
    879 
    880 /* ------------------------------------- */
    881 /**
    882  * Execute adding and rolling in Calendar extensively,
    883  */
    884 static void TestAddRollExtensive()
    885 {
    886     const TransitionItem * itemPtr;
    887     UCalendar *cal = 0;
    888     int32_t i,limit;
    889     UChar tzID[32];
    890     UCalendarDateFields e;
    891     int32_t y,m,d,hr,min,sec,ms;
    892     int32_t maxlimit = 40;
    893     UErrorCode status = U_ZERO_ERROR;
    894     y = 1997; m = UCAL_FEBRUARY; d = 1; hr = 1; min = 1; sec = 0; ms = 0;
    895 
    896     log_verbose("Testing add and roll extensively\n");
    897 
    898     u_uastrcpy(tzID, "PST");
    899     /*open the calendar used */
    900     cal=ucal_open(tzID, u_strlen(tzID), "en_US", UCAL_GREGORIAN, &status);;
    901     if (U_FAILURE(status)) {
    902         log_data_err("ucal_open() failed : %s - (Are you missing data?)\n", u_errorName(status));
    903         return;
    904     }
    905 
    906     ucal_set(cal, UCAL_YEAR, y);
    907     ucal_set(cal, UCAL_MONTH, m);
    908     ucal_set(cal, UCAL_DATE, d);
    909     ucal_setAttribute(cal, UCAL_MINIMAL_DAYS_IN_FIRST_WEEK,1);
    910 
    911     /* Confirm that adding to various fields works.*/
    912     log_verbose("\nTesting to confirm that adding to various fields works with ucal_add()\n");
    913     checkDate(cal, y, m, d);
    914     ucal_add(cal,UCAL_YEAR, 1, &status);
    915     if (U_FAILURE(status)) { log_err("ucal_add failed: %s\n", u_errorName(status)); return; }
    916     y++;
    917     checkDate(cal, y, m, d);
    918     ucal_add(cal,UCAL_MONTH, 12, &status);
    919     if (U_FAILURE(status)) { log_err("ucal_add failed: %s\n", u_errorName(status) ); return; }
    920     y+=1;
    921     checkDate(cal, y, m, d);
    922     ucal_add(cal,UCAL_DATE, 1, &status);
    923     if (U_FAILURE(status)) { log_err("ucal_add failed: %s\n", u_errorName(status) ); return; }
    924     d++;
    925     checkDate(cal, y, m, d);
    926     ucal_add(cal,UCAL_DATE, 2, &status);
    927     if (U_FAILURE(status)) { log_err("ucal_add failed: %s\n", u_errorName(status) ); return; }
    928     d += 2;
    929     checkDate(cal, y, m, d);
    930     ucal_add(cal,UCAL_DATE, 28, &status);
    931     if (U_FAILURE(status)) { log_err("ucal_add failed: %s\n", u_errorName(status) ); return; }
    932     ++m;
    933     checkDate(cal, y, m, d);
    934     ucal_add(cal, (UCalendarDateFields)-1, 10, &status);
    935     if(status==U_ILLEGAL_ARGUMENT_ERROR)
    936         log_verbose("Pass: Illegal argument error as expected\n");
    937     else{
    938         log_err("Fail: No, illegal argument error as expected. Got....: %s\n", u_errorName(status));
    939     }
    940     status=U_ZERO_ERROR;
    941 
    942 
    943     /*confirm that applying roll to various fields works fine*/
    944     log_verbose("\nTesting to confirm that ucal_roll() works\n");
    945     ucal_roll(cal, UCAL_DATE, -1, &status);
    946     if (U_FAILURE(status)) { log_err("ucal_roll failed: %s\n", u_errorName(status) ); return; }
    947     d -=1;
    948     checkDate(cal, y, m, d);
    949     ucal_roll(cal, UCAL_MONTH, -2, &status);
    950     if (U_FAILURE(status)) { log_err("ucal_roll failed: %s\n", u_errorName(status) ); return; }
    951     m -=2;
    952     checkDate(cal, y, m, d);
    953     ucal_roll(cal, UCAL_DATE, 1, &status);
    954     if (U_FAILURE(status)) { log_err("ucal_roll failed: %s\n", u_errorName(status) ); return; }
    955     d +=1;
    956     checkDate(cal, y, m, d);
    957     ucal_roll(cal, UCAL_MONTH, -12, &status);
    958     if (U_FAILURE(status)) { log_err("ucal_roll failed: %s\n", u_errorName(status) ); return; }
    959     checkDate(cal, y, m, d);
    960     ucal_roll(cal, UCAL_YEAR, -1, &status);
    961     if (U_FAILURE(status)) { log_err("ucal_roll failed: %s\n", u_errorName(status) ); return; }
    962     y -=1;
    963     checkDate(cal, y, m, d);
    964     ucal_roll(cal, UCAL_DATE, 29, &status);
    965     if (U_FAILURE(status)) { log_err("ucal_roll failed: %s\n", u_errorName(status) ); return; }
    966     d = 2;
    967     checkDate(cal, y, m, d);
    968     ucal_roll(cal, (UCalendarDateFields)-1, 10, &status);
    969     if(status==U_ILLEGAL_ARGUMENT_ERROR)
    970         log_verbose("Pass: illegal arguement error as expected\n");
    971     else{
    972         log_err("Fail: no illegal argument error got..: %s\n", u_errorName(status));
    973         return;
    974     }
    975     status=U_ZERO_ERROR;
    976     ucal_clear(cal);
    977     ucal_setDateTime(cal, 1999, UCAL_FEBRUARY, 28, 10, 30, 45,  &status);
    978     if(U_FAILURE(status)){
    979         log_err("error is setting the datetime: %s\n", u_errorName(status));
    980     }
    981     ucal_add(cal, UCAL_MONTH, 1, &status);
    982     checkDate(cal, 1999, UCAL_MARCH, 28);
    983     ucal_add(cal, UCAL_MILLISECOND, 1000, &status);
    984     checkDateTime(cal, 1999, UCAL_MARCH, 28, 10, 30, 46, 0, UCAL_MILLISECOND);
    985 
    986     ucal_close(cal);
    987 /*--------------- */
    988     status=U_ZERO_ERROR;
    989     /* Testing add and roll extensively */
    990     log_verbose("\nTesting the ucal_add() and ucal_roll() functions extensively\n");
    991     y = 1997; m = UCAL_FEBRUARY; d = 1; hr = 1; min = 1; sec = 0; ms = 0;
    992     cal=ucal_open(tzID, u_strlen(tzID), "en_US", UCAL_TRADITIONAL, &status);
    993     if (U_FAILURE(status)) {
    994         log_err("ucal_open failed: %s\n", u_errorName(status));
    995         return;
    996     }
    997     ucal_set(cal, UCAL_YEAR, y);
    998     ucal_set(cal, UCAL_MONTH, m);
    999     ucal_set(cal, UCAL_DATE, d);
   1000     ucal_set(cal, UCAL_HOUR, hr);
   1001     ucal_set(cal, UCAL_MINUTE, min);
   1002     ucal_set(cal, UCAL_SECOND,sec);
   1003     ucal_set(cal, UCAL_MILLISECOND, ms);
   1004     ucal_setAttribute(cal, UCAL_MINIMAL_DAYS_IN_FIRST_WEEK,1);
   1005     status=U_ZERO_ERROR;
   1006 
   1007     log_verbose("\nTesting UCalendar add...\n");
   1008     for(e = UCAL_YEAR;e < UCAL_FIELD_COUNT; e=(UCalendarDateFields)((int32_t)e + 1)) {
   1009         limit = maxlimit;
   1010         status = U_ZERO_ERROR;
   1011         for (i = 0; i < limit; i++) {
   1012             ucal_add(cal, e, 1, &status);
   1013             if (U_FAILURE(status)) { limit = i; status = U_ZERO_ERROR; }
   1014         }
   1015         for (i = 0; i < limit; i++) {
   1016             ucal_add(cal, e, -1, &status);
   1017             if (U_FAILURE(status)) {
   1018                 log_err("ucal_add -1 failed: %s\n", u_errorName(status));
   1019                 return;
   1020             }
   1021         }
   1022         checkDateTime(cal, y, m, d, hr, min, sec, ms, e);
   1023     }
   1024     log_verbose("\nTesting calendar ucal_roll()...\n");
   1025     for(e = UCAL_YEAR;e < UCAL_FIELD_COUNT; e=(UCalendarDateFields)((int32_t)e + 1)) {
   1026         limit = maxlimit;
   1027         status = U_ZERO_ERROR;
   1028         for (i = 0; i < limit; i++) {
   1029             ucal_roll(cal, e, 1, &status);
   1030             if (U_FAILURE(status)) {
   1031                 limit = i;
   1032                 status = U_ZERO_ERROR;
   1033             }
   1034         }
   1035         for (i = 0; i < limit; i++) {
   1036             ucal_roll(cal, e, -1, &status);
   1037             if (U_FAILURE(status)) {
   1038                 log_err("ucal_roll -1 failed: %s\n", u_errorName(status));
   1039                 return;
   1040             }
   1041         }
   1042         checkDateTime(cal, y, m, d, hr, min, sec, ms, e);
   1043     }
   1044 
   1045     ucal_close(cal);
   1046 /*--------------- */
   1047     log_verbose("\nTesting ucal_add() across ZONE_OFFSET and DST_OFFSE transitions.\n");
   1048     for (itemPtr = transitionItems; itemPtr->zone != NULL; itemPtr++) {
   1049         status=U_ZERO_ERROR;
   1050         u_uastrcpy(tzID, itemPtr->zone);
   1051         cal=ucal_open(tzID, u_strlen(tzID), "en_US", UCAL_GREGORIAN, &status);
   1052         if (U_FAILURE(status)) {
   1053             log_err("ucal_open failed for zone %s: %s\n", itemPtr->zone, u_errorName(status));
   1054             continue;
   1055         }
   1056         ucal_setDateTime(cal, itemPtr->year, itemPtr->month, itemPtr->day, itemPtr->hour, 0, 0, &status);
   1057         ucal_add(cal, UCAL_DATE, 1, &status);
   1058         hr = ucal_get(cal, UCAL_HOUR_OF_DAY, &status);
   1059         if ( U_FAILURE(status) ) {
   1060             log_err("ucal_add failed adding day across transition for zone %s: %s\n", itemPtr->zone, u_errorName(status));
   1061         } else if ( hr != itemPtr->hour ) {
   1062             log_err("ucal_add produced wrong hour %d when adding day across transition for zone %s\n", hr, itemPtr->zone);
   1063         } else {
   1064             ucal_add(cal, UCAL_DATE, -1, &status);
   1065             hr = ucal_get(cal, UCAL_HOUR_OF_DAY, &status);
   1066             if ( U_FAILURE(status) ) {
   1067                 log_err("ucal_add failed subtracting day across transition for zone %s: %s\n", itemPtr->zone, u_errorName(status));
   1068             } else if ( hr != itemPtr->hour ) {
   1069                 log_err("ucal_add produced wrong hour %d when subtracting day across transition for zone %s\n", hr, itemPtr->zone);
   1070             }
   1071         }
   1072         ucal_close(cal);
   1073     }
   1074 }
   1075 
   1076 /*------------------------------------------------------ */
   1077 /*Testing the Limits for various Fields of Calendar*/
   1078 static void TestGetLimits()
   1079 {
   1080     UCalendar *cal = 0;
   1081     int32_t min, max, gr_min, le_max, ac_min, ac_max, val;
   1082     UChar tzID[4];
   1083     UErrorCode status = U_ZERO_ERROR;
   1084 
   1085 
   1086     u_uastrcpy(tzID, "PST");
   1087     /*open the calendar used */
   1088     cal=ucal_open(tzID, u_strlen(tzID), "en_US", UCAL_GREGORIAN, &status);;
   1089     if (U_FAILURE(status)) {
   1090         log_data_err("ucal_open() for gregorian calendar failed in TestGetLimits: %s - (Are you missing data?)\n", u_errorName(status));
   1091         return;
   1092     }
   1093 
   1094     log_verbose("\nTesting the getLimits function for various fields\n");
   1095 
   1096 
   1097 
   1098     ucal_setDate(cal, 1999, UCAL_MARCH, 5, &status); /* Set the date to be March 5, 1999 */
   1099     val = ucal_get(cal, UCAL_DAY_OF_WEEK, &status);
   1100     min = ucal_getLimit(cal, UCAL_DAY_OF_WEEK, UCAL_MINIMUM, &status);
   1101     max = ucal_getLimit(cal, UCAL_DAY_OF_WEEK, UCAL_MAXIMUM, &status);
   1102     if ( (min != UCAL_SUNDAY || max != UCAL_SATURDAY ) && (min > val && val > max)  && (val != UCAL_FRIDAY)){
   1103            log_err("FAIL: Min/max bad\n");
   1104            log_err("FAIL: Day of week %d out of range\n", val);
   1105            log_err("FAIL: FAIL: Day of week should be SUNDAY Got %d\n", val);
   1106     }
   1107     else
   1108         log_verbose("getLimits successful\n");
   1109 
   1110     val = ucal_get(cal, UCAL_DAY_OF_WEEK_IN_MONTH, &status);
   1111     min = ucal_getLimit(cal, UCAL_DAY_OF_WEEK_IN_MONTH, UCAL_MINIMUM, &status);
   1112     max = ucal_getLimit(cal, UCAL_DAY_OF_WEEK_IN_MONTH, UCAL_MAXIMUM, &status);
   1113     if ( (min != 0 || max != 5 ) && (min > val && val > max)  && (val != 1)){
   1114            log_err("FAIL: Min/max bad\n");
   1115            log_err("FAIL: Day of week in month %d out of range\n", val);
   1116            log_err("FAIL: FAIL: Day of week in month should be SUNDAY Got %d\n", val);
   1117 
   1118     }
   1119     else
   1120         log_verbose("getLimits successful\n");
   1121 
   1122     min=ucal_getLimit(cal, UCAL_MONTH, UCAL_MINIMUM, &status);
   1123     max=ucal_getLimit(cal, UCAL_MONTH, UCAL_MAXIMUM, &status);
   1124     gr_min=ucal_getLimit(cal, UCAL_MONTH, UCAL_GREATEST_MINIMUM, &status);
   1125     le_max=ucal_getLimit(cal, UCAL_MONTH, UCAL_LEAST_MAXIMUM, &status);
   1126     ac_min=ucal_getLimit(cal, UCAL_MONTH, UCAL_ACTUAL_MINIMUM, &status);
   1127     ac_max=ucal_getLimit(cal, UCAL_MONTH, UCAL_ACTUAL_MAXIMUM, &status);
   1128     if(U_FAILURE(status)){
   1129         log_err("Error in getLimits: %s\n", u_errorName(status));
   1130     }
   1131     if(min!=0 || max!=11 || gr_min!=0 || le_max!=11 || ac_min!=0 || ac_max!=11)
   1132         log_err("There is and error in getLimits in fetching the values\n");
   1133     else
   1134         log_verbose("getLimits successful\n");
   1135 
   1136     ucal_setDateTime(cal, 1999, UCAL_MARCH, 5, 4, 10, 35, &status);
   1137     val=ucal_get(cal, UCAL_HOUR_OF_DAY, &status);
   1138     min=ucal_getLimit(cal, UCAL_HOUR_OF_DAY, UCAL_MINIMUM, &status);
   1139     max=ucal_getLimit(cal, UCAL_HOUR_OF_DAY, UCAL_MAXIMUM, &status);
   1140     gr_min=ucal_getLimit(cal, UCAL_MINUTE, UCAL_GREATEST_MINIMUM, &status);
   1141     le_max=ucal_getLimit(cal, UCAL_MINUTE, UCAL_LEAST_MAXIMUM, &status);
   1142     ac_min=ucal_getLimit(cal, UCAL_MINUTE, UCAL_ACTUAL_MINIMUM, &status);
   1143     ac_max=ucal_getLimit(cal, UCAL_SECOND, UCAL_ACTUAL_MAXIMUM, &status);
   1144     if( (min!=0 || max!= 11 || gr_min!=0 || le_max!=60 || ac_min!=0 || ac_max!=60) &&
   1145         (min>val && val>max) && val!=4){
   1146 
   1147         log_err("FAIL: Min/max bad\n");
   1148         log_err("FAIL: Hour of Day %d out of range\n", val);
   1149         log_err("FAIL: HOUR_OF_DAY should be 4 Got %d\n", val);
   1150     }
   1151     else
   1152         log_verbose("getLimits successful\n");
   1153 
   1154 
   1155     /*get BOGUS_LIMIT type*/
   1156     val=ucal_getLimit(cal, UCAL_SECOND, (UCalendarLimitType)99, &status);
   1157     if(val != -1){
   1158         log_err("FAIL: ucal_getLimit() with BOGUS type should return -1\n");
   1159     }
   1160     status=U_ZERO_ERROR;
   1161 
   1162 
   1163     ucal_close(cal);
   1164 }
   1165 
   1166 
   1167 
   1168 /* ------------------------------------- */
   1169 
   1170 /**
   1171  * Test that the days of the week progress properly when add is called repeatedly
   1172  * for increments of 24 days.
   1173  */
   1174 static void TestDOWProgression()
   1175 {
   1176     int32_t initialDOW, DOW, newDOW, expectedDOW;
   1177     UCalendar *cal = 0;
   1178     UDateFormat *datfor = 0;
   1179     UDate date1;
   1180     int32_t delta=24;
   1181     UErrorCode status = U_ZERO_ERROR;
   1182     UChar tzID[4];
   1183     char tempMsgBuf[256];
   1184     u_strcpy(tzID, fgGMTID);
   1185     /*open the calendar used */
   1186     cal=ucal_open(tzID, u_strlen(tzID), "en_US", UCAL_TRADITIONAL, &status);;
   1187     if (U_FAILURE(status)) {
   1188         log_data_err("ucal_open failed: %s - (Are you missing data?)\n", u_errorName(status));
   1189         return;
   1190     }
   1191 
   1192     datfor=udat_open(UDAT_MEDIUM,UDAT_MEDIUM ,NULL, fgGMTID,-1,NULL, 0, &status);
   1193     if(U_FAILURE(status)){
   1194         log_data_err("error in creating the dateformat : %s (Are you missing data?)\n", u_errorName(status));
   1195     }
   1196 
   1197 
   1198     ucal_setDate(cal, 1999, UCAL_JANUARY, 1, &status);
   1199 
   1200     log_verbose("\nTesting the DOW progression\n");
   1201 
   1202     initialDOW = ucal_get(cal, UCAL_DAY_OF_WEEK, &status);
   1203     if (U_FAILURE(status)) { log_data_err("ucal_get() failed: %s (Are you missing data?)\n", u_errorName(status) ); return; }
   1204     newDOW = initialDOW;
   1205     do {
   1206         DOW = newDOW;
   1207         log_verbose("DOW = %d...\n", DOW);
   1208         date1=ucal_getMillis(cal, &status);
   1209         if(U_FAILURE(status)){ log_err("ucal_getMiilis() failed: %s\n", u_errorName(status)); return;}
   1210         log_verbose("%s\n", u_austrcpy(tempMsgBuf, myDateFormat(datfor, date1)));
   1211 
   1212         ucal_add(cal,UCAL_DAY_OF_WEEK, delta, &status);
   1213         if (U_FAILURE(status)) { log_err("ucal_add() failed: %s\n", u_errorName(status)); return; }
   1214 
   1215         newDOW = ucal_get(cal, UCAL_DAY_OF_WEEK, &status);
   1216         if (U_FAILURE(status)) { log_err("ucal_get() failed: %s\n", u_errorName(status)); return; }
   1217         expectedDOW = 1 + (DOW + delta - 1) % 7;
   1218         date1=ucal_getMillis(cal, &status);
   1219         if(U_FAILURE(status)){ log_err("ucal_getMiilis() failed: %s\n", u_errorName(status)); return;}
   1220         if (newDOW != expectedDOW) {
   1221             log_err("Day of week should be %d instead of %d on %s", expectedDOW, newDOW,
   1222                 u_austrcpy(tempMsgBuf, myDateFormat(datfor, date1)) );
   1223             return;
   1224         }
   1225     }
   1226     while (newDOW != initialDOW);
   1227 
   1228     ucal_close(cal);
   1229     udat_close(datfor);
   1230 }
   1231 
   1232 /* ------------------------------------- */
   1233 
   1234 /**
   1235  * Confirm that the offset between local time and GMT behaves as expected.
   1236  */
   1237 static void TestGMTvsLocal()
   1238 {
   1239     log_verbose("\nTesting the offset between the GMT and local time\n");
   1240     testZones(1999, 1, 1, 12, 0, 0);
   1241     testZones(1999, 4, 16, 18, 30, 0);
   1242     testZones(1998, 12, 17, 19, 0, 0);
   1243 }
   1244 
   1245 /* ------------------------------------- */
   1246 
   1247 static void testZones(int32_t yr, int32_t mo, int32_t dt, int32_t hr, int32_t mn, int32_t sc)
   1248 {
   1249     int32_t offset,utc, expected;
   1250     UCalendar *gmtcal = 0, *cal = 0;
   1251     UDate date1;
   1252     double temp;
   1253     UDateFormat *datfor = 0;
   1254     UErrorCode status = U_ZERO_ERROR;
   1255     UChar tzID[4];
   1256     char tempMsgBuf[256];
   1257 
   1258     u_strcpy(tzID, fgGMTID);
   1259     gmtcal=ucal_open(tzID, 3, "en_US", UCAL_TRADITIONAL, &status);;
   1260     if (U_FAILURE(status)) {
   1261         log_data_err("ucal_open failed: %s - (Are you missing data?)\n", u_errorName(status));
   1262         return;
   1263     }
   1264     u_uastrcpy(tzID, "PST");
   1265     cal = ucal_open(tzID, 3, "en_US", UCAL_TRADITIONAL, &status);
   1266     if (U_FAILURE(status)) {
   1267         log_err("ucal_open failed: %s\n", u_errorName(status));
   1268         return;
   1269     }
   1270 
   1271     datfor=udat_open(UDAT_MEDIUM,UDAT_MEDIUM ,NULL, fgGMTID,-1,NULL, 0, &status);
   1272     if(U_FAILURE(status)){
   1273         log_data_err("error in creating the dateformat : %s (Are you missing data?)\n", u_errorName(status));
   1274     }
   1275 
   1276     ucal_setDateTime(gmtcal, yr, mo - 1, dt, hr, mn, sc, &status);
   1277     if (U_FAILURE(status)) {
   1278         log_data_err("ucal_setDateTime failed: %s (Are you missing data?)\n", u_errorName(status));
   1279         return;
   1280     }
   1281     ucal_set(gmtcal, UCAL_MILLISECOND, 0);
   1282     date1 = ucal_getMillis(gmtcal, &status);
   1283     if (U_FAILURE(status)) {
   1284         log_err("ucal_getMillis failed: %s\n", u_errorName(status));
   1285         return;
   1286     }
   1287     log_verbose("date = %s\n", u_austrcpy(tempMsgBuf, myDateFormat(datfor, date1)) );
   1288 
   1289 
   1290     ucal_setMillis(cal, date1, &status);
   1291     if (U_FAILURE(status)) {
   1292         log_err("ucal_setMillis() failed: %s\n", u_errorName(status));
   1293         return;
   1294     }
   1295 
   1296     offset = ucal_get(cal, UCAL_ZONE_OFFSET, &status);
   1297     offset += ucal_get(cal, UCAL_DST_OFFSET, &status);
   1298 
   1299     if (U_FAILURE(status)) {
   1300         log_err("ucal_get() failed: %s\n", u_errorName(status));
   1301         return;
   1302     }
   1303     temp=(double)((double)offset / 1000.0 / 60.0 / 60.0);
   1304     /*printf("offset for %s %f hr\n", austrdup(myDateFormat(datfor, date1)), temp);*/
   1305 
   1306     utc = ((ucal_get(cal, UCAL_HOUR_OF_DAY, &status) * 60 +
   1307                     ucal_get(cal, UCAL_MINUTE, &status)) * 60 +
   1308                    ucal_get(cal, UCAL_SECOND, &status)) * 1000 +
   1309                     ucal_get(cal, UCAL_MILLISECOND, &status) - offset;
   1310     if (U_FAILURE(status)) {
   1311         log_err("ucal_get() failed: %s\n", u_errorName(status));
   1312         return;
   1313     }
   1314 
   1315     expected = ((hr * 60 + mn) * 60 + sc) * 1000;
   1316     if (utc != expected) {
   1317         temp=(double)(utc - expected)/ 1000 / 60 / 60.0;
   1318         log_err("FAIL: Discrepancy of %d  millis = %fhr\n", utc-expected, temp );
   1319     }
   1320     else
   1321         log_verbose("PASS: the offset between local and GMT is correct\n");
   1322     ucal_close(gmtcal);
   1323     ucal_close(cal);
   1324     udat_close(datfor);
   1325 }
   1326 
   1327 /* ------------------------------------- */
   1328 
   1329 
   1330 
   1331 
   1332 /* INTERNAL FUNCTIONS USED */
   1333 /*------------------------------------------------------------------------------------------- */
   1334 
   1335 /* ------------------------------------- */
   1336 static void checkDateTime(UCalendar* c,
   1337                         int32_t y, int32_t m, int32_t d,
   1338                         int32_t hr, int32_t min, int32_t sec,
   1339                         int32_t ms, UCalendarDateFields field)
   1340 
   1341 {
   1342     UErrorCode status = U_ZERO_ERROR;
   1343     if (ucal_get(c, UCAL_YEAR, &status) != y ||
   1344         ucal_get(c, UCAL_MONTH, &status) != m ||
   1345         ucal_get(c, UCAL_DATE, &status) != d ||
   1346         ucal_get(c, UCAL_HOUR, &status) != hr ||
   1347         ucal_get(c, UCAL_MINUTE, &status) != min ||
   1348         ucal_get(c, UCAL_SECOND, &status) != sec ||
   1349         ucal_get(c, UCAL_MILLISECOND, &status) != ms) {
   1350         log_err("U_FAILURE for field  %d, Expected y/m/d h:m:s:ms of %d/%d/%d %d:%d:%d:%d  got %d/%d/%d %d:%d:%d:%d\n",
   1351             (int32_t)field, y, m + 1, d, hr, min, sec, ms,
   1352                     ucal_get(c, UCAL_YEAR, &status),
   1353                     ucal_get(c, UCAL_MONTH, &status) + 1,
   1354                     ucal_get(c, UCAL_DATE, &status),
   1355                     ucal_get(c, UCAL_HOUR, &status),
   1356                     ucal_get(c, UCAL_MINUTE, &status) + 1,
   1357                     ucal_get(c, UCAL_SECOND, &status),
   1358                     ucal_get(c, UCAL_MILLISECOND, &status) );
   1359 
   1360                     if (U_FAILURE(status)){
   1361                     log_err("ucal_get failed: %s\n", u_errorName(status));
   1362                     return;
   1363                     }
   1364 
   1365      }
   1366     else
   1367         log_verbose("Confirmed: %d/%d/%d %d:%d:%d:%d\n", y, m + 1, d, hr, min, sec, ms);
   1368 
   1369 }
   1370 
   1371 /* ------------------------------------- */
   1372 static void checkDate(UCalendar* c, int32_t y, int32_t m, int32_t d)
   1373 {
   1374     UErrorCode status = U_ZERO_ERROR;
   1375     if (ucal_get(c,UCAL_YEAR, &status) != y ||
   1376         ucal_get(c, UCAL_MONTH, &status) != m ||
   1377         ucal_get(c, UCAL_DATE, &status) != d) {
   1378 
   1379         log_err("FAILURE: Expected y/m/d of %d/%d/%d  got %d/%d/%d\n", y, m + 1, d,
   1380                     ucal_get(c, UCAL_YEAR, &status),
   1381                     ucal_get(c, UCAL_MONTH, &status) + 1,
   1382                     ucal_get(c, UCAL_DATE, &status) );
   1383 
   1384         if (U_FAILURE(status)) {
   1385             log_err("ucal_get failed: %s\n", u_errorName(status));
   1386             return;
   1387         }
   1388     }
   1389     else
   1390         log_verbose("Confirmed: %d/%d/%d\n", y, m + 1, d);
   1391 
   1392 
   1393 }
   1394 
   1395 /* ------------------------------------- */
   1396 
   1397 /* ------------------------------------- */
   1398 
   1399 static void verify1(const char* msg, UCalendar* c, UDateFormat* dat, int32_t year, int32_t month, int32_t day)
   1400 {
   1401     UDate d1;
   1402     UErrorCode status = U_ZERO_ERROR;
   1403     if (ucal_get(c, UCAL_YEAR, &status) == year &&
   1404         ucal_get(c, UCAL_MONTH, &status) == month &&
   1405         ucal_get(c, UCAL_DATE, &status) == day) {
   1406         if (U_FAILURE(status)) {
   1407             log_err("FAIL: Calendar::get failed: %s\n", u_errorName(status));
   1408             return;
   1409         }
   1410         log_verbose("PASS: %s\n", msg);
   1411         d1=ucal_getMillis(c, &status);
   1412         if (U_FAILURE(status)) {
   1413             log_err("ucal_getMillis failed: %s\n", u_errorName(status));
   1414             return;
   1415         }
   1416     /*log_verbose(austrdup(myDateFormat(dat, d1)) );*/
   1417     }
   1418     else {
   1419         log_err("FAIL: %s\n", msg);
   1420         d1=ucal_getMillis(c, &status);
   1421         if (U_FAILURE(status)) {
   1422             log_err("ucal_getMillis failed: %s\n", u_errorName(status) );
   1423             return;
   1424         }
   1425         log_err("Got %s  Expected %d/%d/%d \n", austrdup(myDateFormat(dat, d1)), year, month + 1, day );
   1426         return;
   1427     }
   1428 
   1429 
   1430 }
   1431 
   1432 /* ------------------------------------ */
   1433 static void verify2(const char* msg, UCalendar* c, UDateFormat* dat, int32_t year, int32_t month, int32_t day,
   1434                                                                      int32_t hour, int32_t min, int32_t sec, int32_t am_pm)
   1435 {
   1436     UDate d1;
   1437     UErrorCode status = U_ZERO_ERROR;
   1438     char tempMsgBuf[256];
   1439 
   1440     if (ucal_get(c, UCAL_YEAR, &status) == year &&
   1441         ucal_get(c, UCAL_MONTH, &status) == month &&
   1442         ucal_get(c, UCAL_DATE, &status) == day &&
   1443         ucal_get(c, UCAL_HOUR, &status) == hour &&
   1444         ucal_get(c, UCAL_MINUTE, &status) == min &&
   1445         ucal_get(c, UCAL_SECOND, &status) == sec &&
   1446         ucal_get(c, UCAL_AM_PM, &status) == am_pm ){
   1447         if (U_FAILURE(status)) {
   1448             log_err("FAIL: Calendar::get failed: %s\n", u_errorName(status));
   1449             return;
   1450         }
   1451         log_verbose("PASS: %s\n", msg);
   1452         d1=ucal_getMillis(c, &status);
   1453         if (U_FAILURE(status)) {
   1454             log_err("ucal_getMillis failed: %s\n", u_errorName(status));
   1455             return;
   1456         }
   1457         log_verbose("%s\n" , u_austrcpy(tempMsgBuf, myDateFormat(dat, d1)) );
   1458     }
   1459     else {
   1460         log_err("FAIL: %s\n", msg);
   1461         d1=ucal_getMillis(c, &status);
   1462         if (U_FAILURE(status)) {
   1463             log_err("ucal_getMillis failed: %s\n", u_errorName(status));
   1464             return;
   1465         }
   1466         log_err("Got %s Expected %d/%d/%d/ %d:%d:%d  %s\n", austrdup(myDateFormat(dat, d1)),
   1467             year, month + 1, day, hour, min, sec, (am_pm==0) ? "AM": "PM");
   1468 
   1469         return;
   1470     }
   1471 
   1472 
   1473 }
   1474 
   1475 void TestGregorianChange() {
   1476     static const UChar utc[] = { 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0 }; /* "Etc/GMT" */
   1477     const int32_t dayMillis = 86400 * INT64_C(1000);    /* 1 day = 86400 seconds */
   1478     UCalendar *cal;
   1479     UDate date;
   1480     UErrorCode errorCode = U_ZERO_ERROR;
   1481 
   1482     /* Test ucal_setGregorianChange() on a Gregorian calendar. */
   1483     errorCode = U_ZERO_ERROR;
   1484     cal = ucal_open(utc, -1, "", UCAL_GREGORIAN, &errorCode);
   1485     if(U_FAILURE(errorCode)) {
   1486         log_data_err("ucal_open(UTC) failed: %s - (Are you missing data?)\n", u_errorName(errorCode));
   1487         return;
   1488     }
   1489     ucal_setGregorianChange(cal, -365 * (dayMillis * (UDate)1), &errorCode);
   1490     if(U_FAILURE(errorCode)) {
   1491         log_err("ucal_setGregorianChange(1969) failed: %s\n", u_errorName(errorCode));
   1492     } else {
   1493         date = ucal_getGregorianChange(cal, &errorCode);
   1494         if(U_FAILURE(errorCode) || date != -365 * (dayMillis * (UDate)1)) {
   1495             log_err("ucal_getGregorianChange() failed: %s, date = %f\n", u_errorName(errorCode), date);
   1496         }
   1497     }
   1498     ucal_close(cal);
   1499 
   1500     /* Test ucal_setGregorianChange() on a non-Gregorian calendar where it should fail. */
   1501     errorCode = U_ZERO_ERROR;
   1502     cal = ucal_open(utc, -1, "th@calendar=buddhist", UCAL_TRADITIONAL, &errorCode);
   1503     if(U_FAILURE(errorCode)) {
   1504         log_err("ucal_open(UTC, non-Gregorian) failed: %s\n", u_errorName(errorCode));
   1505         return;
   1506     }
   1507     ucal_setGregorianChange(cal, -730 * (dayMillis * (UDate)1), &errorCode);
   1508     if(errorCode != U_UNSUPPORTED_ERROR) {
   1509         log_err("ucal_setGregorianChange(non-Gregorian calendar) did not yield U_UNSUPPORTED_ERROR but %s\n",
   1510                 u_errorName(errorCode));
   1511     }
   1512     errorCode = U_ZERO_ERROR;
   1513     date = ucal_getGregorianChange(cal, &errorCode);
   1514     if(errorCode != U_UNSUPPORTED_ERROR) {
   1515         log_err("ucal_getGregorianChange(non-Gregorian calendar) did not yield U_UNSUPPORTED_ERROR but %s\n",
   1516                 u_errorName(errorCode));
   1517     }
   1518     ucal_close(cal);
   1519 }
   1520 
   1521 static void TestGetKeywordValuesForLocale() {
   1522 #define PREFERRED_SIZE 15
   1523 #define MAX_NUMBER_OF_KEYWORDS 4
   1524     const char *PREFERRED[PREFERRED_SIZE][MAX_NUMBER_OF_KEYWORDS+1] = {
   1525             { "root",        "gregorian", NULL, NULL, NULL },
   1526             { "und",         "gregorian", NULL, NULL, NULL },
   1527             { "en_US",       "gregorian", NULL, NULL, NULL },
   1528             { "en_029",      "gregorian", NULL, NULL, NULL },
   1529             { "th_TH",       "buddhist", "gregorian", NULL, NULL },
   1530             { "und_TH",      "buddhist", "gregorian", NULL, NULL },
   1531             { "en_TH",       "buddhist", "gregorian", NULL, NULL },
   1532             { "he_IL",       "gregorian", "hebrew", "islamic", "islamic-civil" },
   1533             { "ar_EG",       "gregorian", "coptic", "islamic", "islamic-civil" },
   1534             { "ja",          "gregorian", "japanese", NULL, NULL },
   1535             { "ps_Guru_IN",  "gregorian", "indian", NULL, NULL },
   1536             { "th@calendar=gregorian", "buddhist", "gregorian", NULL, NULL },
   1537             { "en@calendar=islamic",   "gregorian", NULL, NULL, NULL },
   1538             { "zh_TW",       "gregorian", "roc", "chinese", NULL },
   1539             { "ar_IR",       "gregorian", "persian", "islamic", "islamic-civil" },
   1540     };
   1541     const int32_t EXPECTED_SIZE[PREFERRED_SIZE] = { 1, 1, 1, 1, 2, 2, 2, 4, 4, 2, 2, 2, 1, 3, 4 };
   1542     UErrorCode status = U_ZERO_ERROR;
   1543     int32_t i, size, j;
   1544     UEnumeration *all, *pref;
   1545     const char *loc = NULL;
   1546     UBool matchPref, matchAll;
   1547     const char *value;
   1548     int32_t valueLength;
   1549     UList *ALLList = NULL;
   1550 
   1551     UEnumeration *ALL = ucal_getKeywordValuesForLocale("calendar", uloc_getDefault(), FALSE, &status);
   1552     if (U_SUCCESS(status)) {
   1553         for (i = 0; i < PREFERRED_SIZE; i++) {
   1554             pref = NULL;
   1555             all = NULL;
   1556             loc = PREFERRED[i][0];
   1557             pref = ucal_getKeywordValuesForLocale("calendar", loc, TRUE, &status);
   1558             matchPref = FALSE;
   1559             matchAll = FALSE;
   1560 
   1561             value = NULL;
   1562             valueLength = 0;
   1563 
   1564             if (U_SUCCESS(status) && uenum_count(pref, &status) == EXPECTED_SIZE[i]) {
   1565                 matchPref = TRUE;
   1566                 for (j = 0; j < EXPECTED_SIZE[i]; j++) {
   1567                     if ((value = uenum_next(pref, &valueLength, &status)) != NULL && U_SUCCESS(status)) {
   1568                         if (uprv_strcmp(value, PREFERRED[i][j+1]) != 0) {
   1569                             matchPref = FALSE;
   1570                             break;
   1571                         }
   1572                     } else {
   1573                         matchPref = FALSE;
   1574                         log_err("ERROR getting keyword value for locale \"%s\"\n", loc);
   1575                         break;
   1576                     }
   1577                 }
   1578             }
   1579 
   1580             if (!matchPref) {
   1581                 log_err("FAIL: Preferred values for locale \"%s\" does not match expected.\n", loc);
   1582                 break;
   1583             }
   1584             uenum_close(pref);
   1585 
   1586             all = ucal_getKeywordValuesForLocale("calendar", loc, FALSE, &status);
   1587 
   1588             size = uenum_count(all, &status);
   1589 
   1590             if (U_SUCCESS(status) && size == uenum_count(ALL, &status)) {
   1591                 matchAll = TRUE;
   1592                 ALLList = ulist_getListFromEnum(ALL);
   1593                 for (j = 0; j < size; j++) {
   1594                     if ((value = uenum_next(all, &valueLength, &status)) != NULL && U_SUCCESS(status)) {
   1595                         if (!ulist_containsString(ALLList, value, uprv_strlen(value))) {
   1596                             log_err("Locale %s have %s not in ALL\n", loc, value);
   1597                             matchAll = FALSE;
   1598                             break;
   1599                         }
   1600                     } else {
   1601                         matchAll = FALSE;
   1602                         log_err("ERROR getting \"all\" keyword value for locale \"%s\"\n", loc);
   1603                         break;
   1604                     }
   1605                 }
   1606             }
   1607             if (!matchAll) {
   1608                 log_err("FAIL: All values for locale \"%s\" does not match expected.\n", loc);
   1609             }
   1610 
   1611             uenum_close(all);
   1612         }
   1613     } else {
   1614         log_err_status(status, "Failed to get ALL keyword values for default locale %s: %s.\n", uloc_getDefault(), u_errorName(status));
   1615     }
   1616     uenum_close(ALL);
   1617 }
   1618 
   1619 /*
   1620  * Weekend tests, ported from
   1621  * icu4j/trunk/main/tests/core/src/com/ibm/icu/dev/test/calendar/IBMCalendarTest.java
   1622  * and extended a bit. Notes below from IBMCalendarTest.java ...
   1623  * This test tests for specific locale data. This is probably okay
   1624  * as far as US data is concerned, but if the Arabic/Yemen data
   1625  * changes, this test will have to be updated.
   1626  */
   1627 
   1628 typedef struct {
   1629     int32_t year;
   1630     int32_t month;
   1631     int32_t day;
   1632     int32_t hour;
   1633     int32_t millisecOffset;
   1634     UBool   isWeekend;
   1635 } TestWeekendDates;
   1636 typedef struct {
   1637     const char * locale;
   1638     const        TestWeekendDates * dates;
   1639     int32_t      numDates;
   1640 } TestWeekendDatesList;
   1641 
   1642 static const TestWeekendDates weekendDates_en_US[] = {
   1643     { 2000, UCAL_MARCH, 17, 23,  0, 0 }, /* Fri 23:00        */
   1644     { 2000, UCAL_MARCH, 18,  0, -1, 0 }, /* Fri 23:59:59.999 */
   1645     { 2000, UCAL_MARCH, 18,  0,  0, 1 }, /* Sat 00:00        */
   1646     { 2000, UCAL_MARCH, 18, 15,  0, 1 }, /* Sat 15:00        */
   1647     { 2000, UCAL_MARCH, 19, 23,  0, 1 }, /* Sun 23:00        */
   1648     { 2000, UCAL_MARCH, 20,  0, -1, 1 }, /* Sun 23:59:59.999 */
   1649     { 2000, UCAL_MARCH, 20,  0,  0, 0 }, /* Mon 00:00        */
   1650     { 2000, UCAL_MARCH, 20,  8,  0, 0 }, /* Mon 08:00        */
   1651 };
   1652 static const TestWeekendDates weekendDates_ar_YE[] = {
   1653     { 2000, UCAL_MARCH, 15, 23,  0, 0 }, /* Wed 23:00        */
   1654     { 2000, UCAL_MARCH, 16,  0, -1, 0 }, /* Wed 23:59:59.999 */
   1655     { 2000, UCAL_MARCH, 16,  0,  0, 1 }, /* Thu 00:00        */
   1656     { 2000, UCAL_MARCH, 16, 15,  0, 1 }, /* Thu 15:00        */
   1657     { 2000, UCAL_MARCH, 17, 23,  0, 1 }, /* Fri 23:00        */
   1658     { 2000, UCAL_MARCH, 18,  0, -1, 1 }, /* Fri 23:59:59.999 */
   1659     { 2000, UCAL_MARCH, 18,  0,  0, 0 }, /* Sat 00:00        */
   1660     { 2000, UCAL_MARCH, 18,  8,  0, 0 }, /* Sat 08:00        */
   1661 };
   1662 static const TestWeekendDatesList testDates[] = {
   1663     { "en_US", weekendDates_en_US, sizeof(weekendDates_en_US)/sizeof(weekendDates_en_US[0]) },
   1664     { "ar_YE", weekendDates_ar_YE, sizeof(weekendDates_ar_YE)/sizeof(weekendDates_ar_YE[0]) },
   1665 };
   1666 
   1667 typedef struct {
   1668     UCalendarDaysOfWeek  dayOfWeek;
   1669     UCalendarWeekdayType dayType;
   1670     int32_t              transition; /* transition time if dayType is UCAL_WEEKEND_ONSET or UCAL_WEEKEND_CEASE; else must be 0 */
   1671 } TestDaysOfWeek;
   1672 typedef struct {
   1673     const char *           locale;
   1674     const TestDaysOfWeek * days;
   1675     int32_t                numDays;
   1676 } TestDaysOfWeekList;
   1677 
   1678 static const TestDaysOfWeek daysOfWeek_en_US[] = {
   1679     { UCAL_MONDAY,   UCAL_WEEKDAY,       0        },
   1680     { UCAL_FRIDAY,   UCAL_WEEKDAY,       0        },
   1681     { UCAL_SATURDAY, UCAL_WEEKEND,       0        },
   1682     { UCAL_SUNDAY,   UCAL_WEEKEND_CEASE, 86400000 },
   1683 };
   1684 static const TestDaysOfWeek daysOfWeek_ar_YE[] = { /* Thursday:Friday */
   1685     { UCAL_WEDNESDAY,UCAL_WEEKDAY,       0        },
   1686     { UCAL_SATURDAY, UCAL_WEEKDAY,       0        },
   1687     { UCAL_THURSDAY, UCAL_WEEKEND,       0        },
   1688     { UCAL_FRIDAY,   UCAL_WEEKEND_CEASE, 86400000 },
   1689 };
   1690 static const TestDaysOfWeekList testDays[] = {
   1691     { "en_US", daysOfWeek_en_US, sizeof(daysOfWeek_en_US)/sizeof(daysOfWeek_en_US[0]) },
   1692     { "ar_YE", daysOfWeek_ar_YE, sizeof(daysOfWeek_ar_YE)/sizeof(daysOfWeek_ar_YE[0]) },
   1693 };
   1694 
   1695 static const UChar logDateFormat[] = { 0x0045,0x0045,0x0045,0x0020,0x004D,0x004D,0x004D,0x0020,0x0064,0x0064,0x0020,0x0079,
   1696                                        0x0079,0x0079,0x0079,0x0020,0x0047,0x0020,0x0048,0x0048,0x003A,0x006D,0x006D,0x003A,
   1697                                        0x0073,0x0073,0x002E,0x0053,0x0053,0x0053,0 }; /* "EEE MMM dd yyyy G HH:mm:ss.SSS" */
   1698 enum { kFormattedDateMax = 2*sizeof(logDateFormat)/sizeof(logDateFormat[0]) };
   1699 
   1700 static void TestWeekend() {
   1701     const TestWeekendDatesList * testDatesPtr = testDates;
   1702     const TestDaysOfWeekList *   testDaysPtr = testDays;
   1703     int32_t count, subCount;
   1704 
   1705     UErrorCode fmtStatus = U_ZERO_ERROR;
   1706     UDateFormat * fmt = udat_open(UDAT_NONE, UDAT_NONE, "en", NULL, 0, NULL, 0, &fmtStatus);
   1707     if (U_SUCCESS(fmtStatus)) {
   1708         udat_applyPattern(fmt, FALSE, logDateFormat, -1);
   1709     } else {
   1710         log_data_err("Unable to create UDateFormat - %s\n", u_errorName(fmtStatus));
   1711         return;
   1712     }
   1713     for (count = sizeof(testDates)/sizeof(testDates[0]); count-- > 0; ++testDatesPtr) {
   1714         UErrorCode status = U_ZERO_ERROR;
   1715         UCalendar * cal = ucal_open(NULL, 0, testDatesPtr->locale, UCAL_GREGORIAN, &status);
   1716         log_verbose("locale: %s\n", testDatesPtr->locale);
   1717         if (U_SUCCESS(status)) {
   1718             const TestWeekendDates * weekendDatesPtr = testDatesPtr->dates;
   1719             for (subCount = testDatesPtr->numDates; subCount--; ++weekendDatesPtr) {
   1720                 UDate dateToTest;
   1721                 UBool isWeekend;
   1722                 char  fmtDateBytes[kFormattedDateMax] = "<could not format test date>"; /* initialize for failure */
   1723 
   1724                 ucal_clear(cal);
   1725                 ucal_setDateTime(cal, weekendDatesPtr->year, weekendDatesPtr->month, weekendDatesPtr->day,
   1726                                  weekendDatesPtr->hour, 0, 0, &status);
   1727                 dateToTest = ucal_getMillis(cal, &status) + weekendDatesPtr->millisecOffset;
   1728                 isWeekend = ucal_isWeekend(cal, dateToTest, &status);
   1729                 if (U_SUCCESS(fmtStatus)) {
   1730                     UChar fmtDate[kFormattedDateMax];
   1731                     (void)udat_format(fmt, dateToTest, fmtDate, kFormattedDateMax, NULL, &fmtStatus);
   1732                     if (U_SUCCESS(fmtStatus)) {
   1733                         u_austrncpy(fmtDateBytes, fmtDate, kFormattedDateMax);
   1734                         fmtDateBytes[kFormattedDateMax-1] = 0;
   1735                     } else {
   1736                         fmtStatus = U_ZERO_ERROR;
   1737                     }
   1738                 }
   1739                 if ( U_FAILURE(status) ) {
   1740                     log_err("FAIL: locale %s date %s isWeekend() status %s\n", testDatesPtr->locale, fmtDateBytes, u_errorName(status) );
   1741                     status = U_ZERO_ERROR;
   1742                 } else if ( (isWeekend!=0) != (weekendDatesPtr->isWeekend!=0) ) {
   1743                     log_err("FAIL: locale %s date %s isWeekend %d, expected the opposite\n", testDatesPtr->locale, fmtDateBytes, isWeekend );
   1744                 } else {
   1745                     log_verbose("OK:   locale %s date %s isWeekend %d\n", testDatesPtr->locale, fmtDateBytes, isWeekend );
   1746                 }
   1747             }
   1748             ucal_close(cal);
   1749         } else {
   1750             log_data_err("FAIL: ucal_open for locale %s failed: %s - (Are you missing data?)\n", testDatesPtr->locale, u_errorName(status) );
   1751         }
   1752     }
   1753     if (U_SUCCESS(fmtStatus)) {
   1754         udat_close(fmt);
   1755     }
   1756 
   1757     for (count = sizeof(testDays)/sizeof(testDays[0]); count-- > 0; ++testDaysPtr) {
   1758         UErrorCode status = U_ZERO_ERROR;
   1759         UCalendar * cal = ucal_open(NULL, 0, testDaysPtr->locale, UCAL_GREGORIAN, &status);
   1760         log_verbose("locale: %s\n", testDaysPtr->locale);
   1761         if (U_SUCCESS(status)) {
   1762             const TestDaysOfWeek * daysOfWeekPtr = testDaysPtr->days;
   1763             for (subCount = testDaysPtr->numDays; subCount--; ++daysOfWeekPtr) {
   1764                 int32_t transition = 0;
   1765                 UCalendarWeekdayType dayType = ucal_getDayOfWeekType(cal, daysOfWeekPtr->dayOfWeek, &status);
   1766                 if ( dayType == UCAL_WEEKEND_ONSET || dayType == UCAL_WEEKEND_CEASE ) {
   1767                     transition = ucal_getWeekendTransition(cal, daysOfWeekPtr->dayOfWeek, &status);
   1768                 }
   1769                 if ( U_FAILURE(status) ) {
   1770                     log_err("FAIL: locale %s DOW %d getDayOfWeekType() status %s\n", testDaysPtr->locale, daysOfWeekPtr->dayOfWeek, u_errorName(status) );
   1771                     status = U_ZERO_ERROR;
   1772                 } else if ( dayType != daysOfWeekPtr->dayType || transition != daysOfWeekPtr->transition ) {
   1773                     log_err("FAIL: locale %s DOW %d type %d, expected %d\n", testDaysPtr->locale, daysOfWeekPtr->dayOfWeek, dayType, daysOfWeekPtr->dayType );
   1774                 } else {
   1775                     log_verbose("OK:   locale %s DOW %d type %d\n", testDaysPtr->locale, daysOfWeekPtr->dayOfWeek, dayType );
   1776                 }
   1777             }
   1778             ucal_close(cal);
   1779         } else {
   1780             log_data_err("FAIL: ucal_open for locale %s failed: %s - (Are you missing data?)\n", testDaysPtr->locale, u_errorName(status) );
   1781         }
   1782     }
   1783 }
   1784 
   1785 /**
   1786  * TestFieldDifference
   1787  */
   1788 
   1789 typedef struct {
   1790     const UChar * timezone;
   1791     const char *  locale;
   1792     UDate         start;
   1793     UDate         target;
   1794     UBool         progressive; /* TRUE to compute progressive difference for each field, FALSE to reset calendar after each call */
   1795     int32_t       yDiff;
   1796     int32_t       MDiff;
   1797     int32_t       dDiff;
   1798     int32_t       HDiff;
   1799     int32_t       mDiff;
   1800     int32_t       sDiff; /* 0x7FFFFFFF indicates overflow error expected */
   1801 } TFDItem;
   1802 
   1803 static const UChar tzUSPacific[] = { 0x55,0x53,0x2F,0x50,0x61,0x63,0x69,0x66,0x69,0x63,0 }; /* "US/Pacific" */
   1804 static const UChar tzGMT[] = { 0x47,0x4D,0x54,0 }; /* "GMT" */
   1805 
   1806 static const TFDItem tfdItems[] = {
   1807     /* timezone    locale          start              target           progres  yDf  MDf    dDf     HDf       mDf         sDf */
   1808     /* For these we compute the progressive difference for each field - not resetting the calendar after each call */
   1809     { tzUSPacific, "en_US",        1267459800000.0,   1277772600000.0,  TRUE,     0,   3,    27,      9,       40,          0 }, /* 2010-Mar-01 08:10 -> 2010-Jun-28 17:50 */
   1810     { tzUSPacific, "en_US",        1267459800000.0,   1299089280000.0,  TRUE,     1,   0,     1,      1,       58,          0 }, /* 2010-Mar-01 08:10 -> 2011-Mar-02 10:08 */
   1811     /* For these we compute the total difference for each field - resetting the calendar after each call */
   1812     { tzGMT,       "en_US",        0.0,               1073692800000.0,  FALSE,   34, 408, 12427, 298248, 17894880, 1073692800 }, /* 1970-Jan-01 00:00 -> 2004-Jan-10 00:00 */
   1813     { tzGMT,       "en_US",        0.0,               1073779200000.0,  FALSE,   34, 408, 12428, 298272, 17896320, 1073779200 }, /* 1970-Jan-01 00:00 -> 2004-Jan-11 00:00 */
   1814     { tzGMT,       "en_US",        0.0,               2147472000000.0,  FALSE,   68, 816, 24855, 596520, 35791200, 2147472000 }, /* 1970-Jan-01 00:00 -> 2038-Jan-19 00:00 */
   1815     { tzGMT,       "en_US",        0.0,               2147558400000.0,  FALSE,   68, 816, 24856, 596544, 35792640, 0x7FFFFFFF }, /* 1970-Jan-01 00:00 -> 2038-Jan-20 00:00, seconds diff overflow */
   1816     { tzGMT,       "en_US",        0.0,              -1073692800000.0,  FALSE,  -34,-408,-12427,-298248,-17894880,-1073692800 }, /* 1970-Jan-01 00:00 -> 1935-Dec-24 00:00 */
   1817     { tzGMT,       "en_US",        0.0,              -1073779200000.0,  FALSE,  -34,-408,-12428,-298272,-17896320,-1073779200 }, /* 1970-Jan-01 00:00 -> 1935-Dec-23 00:00 */
   1818     /* check fwd/backward on either side of era boundary and across era boundary */
   1819     { tzGMT,       "en_US",       -61978089600000.0,-61820409600000.0,  FALSE,    4,  59,  1825,  43800,  2628000,  157680000 }, /* CE   5-Dec-31 00:00 -> CE  10-Dec-30 00:00 */
   1820     { tzGMT,       "en_US",       -61820409600000.0,-61978089600000.0,  FALSE,   -4, -59, -1825, -43800, -2628000, -157680000 }, /* CE  10-Dec-30 00:00 -> CE   5-Dec-31 00:00 */
   1821     { tzGMT,       "en_US",       -62451129600000.0,-62293449600000.0,  FALSE,    4,  59,  1825,  43800,  2628000,  157680000 }, /* BCE 10-Jan-04 00:00 -> BCE  5-Jan-03 00:00 */
   1822     { tzGMT,       "en_US",       -62293449600000.0,-62451129600000.0,  FALSE,   -4, -59, -1825, -43800, -2628000, -157680000 }, /* BCE  5-Jan-03 00:00 -> BCE 10-Jan-04 00:00 */
   1823     { tzGMT,       "en_US",       -62293449600000.0,-61978089600000.0,  FALSE,    9, 119,  3650,  87600,  5256000,  315360000 }, /* BCE  5-Jan-03 00:00 -> CE   5-Dec-31 00:00 */
   1824     { tzGMT,       "en_US",       -61978089600000.0,-62293449600000.0,  FALSE,   -9,-119, -3650, -87600, -5256000, -315360000 }, /* CE   5-Dec-31 00:00 -> BCE  5-Jan-03 00:00 */
   1825     { tzGMT, "en@calendar=roc",    -1672704000000.0, -1515024000000.0,  FALSE,    4,  59,  1825,  43800,  2628000,  157680000 }, /* MG   5-Dec-30 00:00 -> MG  10-Dec-29 00:00 */
   1826     { tzGMT, "en@calendar=roc",    -1515024000000.0, -1672704000000.0,  FALSE,   -4, -59, -1825, -43800, -2628000, -157680000 }, /* MG  10-Dec-29 00:00 -> MG   5-Dec-30 00:00 */
   1827     { tzGMT, "en@calendar=roc",    -2145744000000.0, -1988064000000.0,  FALSE,    4,  59,  1825,  43800,  2628000,  157680000 }, /* BMG 10-Jan-03 00:00 -> BMG  5-Jan-02 00:00 */
   1828     { tzGMT, "en@calendar=roc",    -1988064000000.0, -2145744000000.0,  FALSE,   -4, -59, -1825, -43800, -2628000, -157680000 }, /* BMG  5-Jan-02 00:00 -> BMG 10-Jan-03 00:00 */
   1829     { tzGMT, "en@calendar=roc",    -1988064000000.0, -1672704000000.0,  FALSE,    9, 119,  3650,  87600,  5256000,  315360000 }, /* BMG  5-Jan-02 00:00 -> MG   5-Dec-30 00:00 */
   1830     { tzGMT, "en@calendar=roc",    -1672704000000.0, -1988064000000.0,  FALSE,   -9,-119, -3650, -87600, -5256000, -315360000 }, /* MG   5-Dec-30 00:00 -> BMG  5-Jan-02 00:00 */
   1831     { tzGMT, "en@calendar=coptic",-53026531200000.0,-52868851200000.0,  FALSE,    4,  64,  1825,  43800,  2628000,  157680000 }, /* Er1  5-Nas-05 00:00 -> Er1 10-Nas-04 00:00 */
   1832     { tzGMT, "en@calendar=coptic",-52868851200000.0,-53026531200000.0,  FALSE,   -4, -64, -1825, -43800, -2628000, -157680000 }, /* Er1 10-Nas-04 00:00 -> Er1  5-Nas-05 00:00 */
   1833     { tzGMT, "en@calendar=coptic",-53499571200000.0,-53341891200000.0,  FALSE,    4,  64,  1825,  43800,  2628000,  157680000 }, /* Er0 10-Tou-04 00:00 -> Er0  5-Tou-02 00:00 */
   1834     { tzGMT, "en@calendar=coptic",-53341891200000.0,-53499571200000.0,  FALSE,   -4, -64, -1825, -43800, -2628000, -157680000 }, /* Er0  5-Tou-02 00:00 -> Er0 10-Tou-04 00:00 */
   1835     { tzGMT, "en@calendar=coptic",-53341891200000.0,-53026531200000.0,  FALSE,    9, 129,  3650,  87600,  5256000,  315360000 }, /* Er0  5-Tou-02 00:00 -> Er1  5-Nas-05 00:00 */
   1836     { tzGMT, "en@calendar=coptic",-53026531200000.0,-53341891200000.0,  FALSE,   -9,-129, -3650, -87600, -5256000, -315360000 }, /* Er1  5-Nas-05 00:00 -> Er0  5-Tou-02 00:00 */
   1837     { NULL,        NULL,           0.0,               0.0,              FALSE,    0,   0,     0,      0,        0,          0 }  /* terminator */
   1838 };
   1839 
   1840 void TestFieldDifference() {
   1841     const TFDItem * tfdItemPtr;
   1842     for (tfdItemPtr = tfdItems; tfdItemPtr->timezone != NULL; tfdItemPtr++) {
   1843         UErrorCode status = U_ZERO_ERROR;
   1844         UCalendar* ucal = ucal_open(tfdItemPtr->timezone, -1, tfdItemPtr->locale, UCAL_DEFAULT, &status);
   1845         if (U_FAILURE(status)) {
   1846             log_err("FAIL: for locale \"%s\", ucal_open had status %s\n", tfdItemPtr->locale, u_errorName(status) );
   1847         } else {
   1848             int32_t yDf, MDf, dDf, HDf, mDf, sDf;
   1849             if (tfdItemPtr->progressive) {
   1850                 ucal_setMillis(ucal, tfdItemPtr->start, &status);
   1851                 yDf = ucal_getFieldDifference(ucal, tfdItemPtr->target, UCAL_YEAR, &status);
   1852                 MDf = ucal_getFieldDifference(ucal, tfdItemPtr->target, UCAL_MONTH, &status);
   1853                 dDf = ucal_getFieldDifference(ucal, tfdItemPtr->target, UCAL_DATE, &status);
   1854                 HDf = ucal_getFieldDifference(ucal, tfdItemPtr->target, UCAL_HOUR, &status);
   1855                 mDf = ucal_getFieldDifference(ucal, tfdItemPtr->target, UCAL_MINUTE, &status);
   1856                 sDf = ucal_getFieldDifference(ucal, tfdItemPtr->target, UCAL_SECOND, &status);
   1857                 if (U_FAILURE(status)) {
   1858                     log_err("FAIL: for locale \"%s\", start %.1f, target %.1f, ucal_setMillis or ucal_getFieldDifference had status %s\n",
   1859                             tfdItemPtr->locale, tfdItemPtr->start, tfdItemPtr->target, u_errorName(status) );
   1860                 } else if ( yDf !=  tfdItemPtr->yDiff ||
   1861                             MDf !=  tfdItemPtr->MDiff ||
   1862                             dDf !=  tfdItemPtr->dDiff ||
   1863                             HDf !=  tfdItemPtr->HDiff ||
   1864                             mDf !=  tfdItemPtr->mDiff ||
   1865                             sDf !=  tfdItemPtr->sDiff ) {
   1866                     log_data_err("FAIL: for locale \"%s\", start %.1f, target %.1f, expected y-M-d-H-m-s progressive diffs %d-%d-%d-%d-%d-%d, got %d-%d-%d-%d-%d-%d\n",
   1867                             tfdItemPtr->locale, tfdItemPtr->start, tfdItemPtr->target,
   1868                             tfdItemPtr->yDiff, tfdItemPtr->MDiff, tfdItemPtr->dDiff, tfdItemPtr->HDiff, tfdItemPtr->mDiff, tfdItemPtr->sDiff,
   1869                             yDf, MDf, dDf, HDf, mDf, sDf);
   1870                 }
   1871             } else {
   1872                 ucal_setMillis(ucal, tfdItemPtr->start, &status);
   1873                 yDf = ucal_getFieldDifference(ucal, tfdItemPtr->target, UCAL_YEAR, &status);
   1874                 ucal_setMillis(ucal, tfdItemPtr->start, &status);
   1875                 MDf = ucal_getFieldDifference(ucal, tfdItemPtr->target, UCAL_MONTH, &status);
   1876                 ucal_setMillis(ucal, tfdItemPtr->start, &status);
   1877                 dDf = ucal_getFieldDifference(ucal, tfdItemPtr->target, UCAL_DATE, &status);
   1878                 ucal_setMillis(ucal, tfdItemPtr->start, &status);
   1879                 HDf = ucal_getFieldDifference(ucal, tfdItemPtr->target, UCAL_HOUR, &status);
   1880                 ucal_setMillis(ucal, tfdItemPtr->start, &status);
   1881                 mDf = ucal_getFieldDifference(ucal, tfdItemPtr->target, UCAL_MINUTE, &status);
   1882                 if (U_FAILURE(status)) {
   1883                     log_err("FAIL: for locale \"%s\", start %.1f, target %.1f, ucal_setMillis or ucal_getFieldDifference (y-M-d-H-m) had status %s\n",
   1884                             tfdItemPtr->locale, tfdItemPtr->start, tfdItemPtr->target, u_errorName(status) );
   1885                 } else if ( yDf !=  tfdItemPtr->yDiff ||
   1886                             MDf !=  tfdItemPtr->MDiff ||
   1887                             dDf !=  tfdItemPtr->dDiff ||
   1888                             HDf !=  tfdItemPtr->HDiff ||
   1889                             mDf !=  tfdItemPtr->mDiff ) {
   1890                     log_data_err("FAIL: for locale \"%s\", start %.1f, target %.1f, expected y-M-d-H-m total diffs %d-%d-%d-%d-%d, got %d-%d-%d-%d-%d\n",
   1891                             tfdItemPtr->locale, tfdItemPtr->start, tfdItemPtr->target,
   1892                             tfdItemPtr->yDiff, tfdItemPtr->MDiff, tfdItemPtr->dDiff, tfdItemPtr->HDiff, tfdItemPtr->mDiff,
   1893                             yDf, MDf, dDf, HDf, mDf);
   1894                 }
   1895                 ucal_setMillis(ucal, tfdItemPtr->start, &status);
   1896                 sDf = ucal_getFieldDifference(ucal, tfdItemPtr->target, UCAL_SECOND, &status);
   1897                 if (tfdItemPtr->sDiff != 0x7FFFFFFF) {
   1898                     if (U_FAILURE(status)) {
   1899                         log_err("FAIL: for locale \"%s\", start %.1f, target %.1f, ucal_setMillis or ucal_getFieldDifference (seconds) had status %s\n",
   1900                                 tfdItemPtr->locale, tfdItemPtr->start, tfdItemPtr->target, u_errorName(status) );
   1901                     } else if (sDf !=  tfdItemPtr->sDiff) {
   1902                         log_data_err("FAIL: for locale \"%s\", start %.1f, target %.1f, expected seconds progressive diff %d, got %d\n",
   1903                                 tfdItemPtr->locale, tfdItemPtr->start, tfdItemPtr->target, tfdItemPtr->sDiff, sDf);
   1904                     }
   1905                 } else if (!U_FAILURE(status)) {
   1906                     log_err("FAIL: for locale \"%s\", start %.1f, target %.1f, for ucal_getFieldDifference (seconds) expected overflow error, got none\n",
   1907                             tfdItemPtr->locale, tfdItemPtr->start, tfdItemPtr->target );
   1908                 }
   1909             }
   1910             ucal_close(ucal);
   1911         }
   1912     }
   1913 }
   1914 
   1915 void TestAmbiguousWallTime() {
   1916     UErrorCode status = U_ZERO_ERROR;
   1917     UChar tzID[32];
   1918     UCalendar* ucal;
   1919     UDate t, expected;
   1920 
   1921     u_uastrcpy(tzID, "America/New_York");
   1922     ucal = ucal_open(tzID, -1, NULL, UCAL_DEFAULT, &status);
   1923     if (U_FAILURE(status)) {
   1924         log_err("FAIL: Failed to create a calendar");
   1925         return;
   1926     }
   1927 
   1928     if (ucal_getAttribute(ucal, UCAL_REPEATED_WALL_TIME) != UCAL_WALLTIME_LAST) {
   1929         log_err("FAIL: Default UCAL_REPEATED_WALL_TIME value is not UCAL_WALLTIME_LAST");
   1930     }
   1931 
   1932     if (ucal_getAttribute(ucal, UCAL_SKIPPED_WALL_TIME) != UCAL_WALLTIME_LAST) {
   1933         log_err("FAIL: Default UCAL_SKIPPED_WALL_TIME value is not UCAL_WALLTIME_LAST");
   1934     }
   1935 
   1936     /* UCAL_WALLTIME_FIRST on US fall transition */
   1937     ucal_setAttribute(ucal, UCAL_REPEATED_WALL_TIME, UCAL_WALLTIME_FIRST);
   1938     ucal_clear(ucal);
   1939     ucal_setDateTime(ucal, 2011, 11-1, 6, 1, 30, 0, &status);
   1940     t = ucal_getMillis(ucal, &status);
   1941     expected = 1320557400000.0; /* 2011-11-06T05:30:00Z */
   1942     if (U_FAILURE(status)) {
   1943         log_err("FAIL: Calculating time 2011-11-06 01:30:00 with UCAL_WALLTIME_FIRST - %s\n", u_errorName(status));
   1944         status = U_ZERO_ERROR;
   1945     } else if (t != expected) {
   1946         log_data_err("FAIL: 2011-11-06 01:30:00 with UCAL_WALLTIME_FIRST - got: %f, expected: %f\n", t, expected);
   1947     }
   1948 
   1949     /* UCAL_WALLTIME_LAST on US fall transition */
   1950     ucal_setAttribute(ucal, UCAL_REPEATED_WALL_TIME, UCAL_WALLTIME_LAST);
   1951     ucal_clear(ucal);
   1952     ucal_setDateTime(ucal, 2011, 11-1, 6, 1, 30, 0, &status);
   1953     t = ucal_getMillis(ucal, &status);
   1954     expected = 1320561000000.0; /* 2011-11-06T06:30:00Z */
   1955     if (U_FAILURE(status)) {
   1956         log_err("FAIL: Calculating time 2011-11-06 01:30:00 with UCAL_WALLTIME_LAST - %s\n", u_errorName(status));
   1957         status = U_ZERO_ERROR;
   1958     } else if (t != expected) {
   1959         log_data_err("FAIL: 2011-11-06 01:30:00 with UCAL_WALLTIME_LAST - got: %f, expected: %f\n", t, expected);
   1960     }
   1961 
   1962     /* UCAL_WALLTIME_FIRST on US spring transition */
   1963     ucal_setAttribute(ucal, UCAL_SKIPPED_WALL_TIME, UCAL_WALLTIME_FIRST);
   1964     ucal_clear(ucal);
   1965     ucal_setDateTime(ucal, 2011, 3-1, 13, 2, 30, 0, &status);
   1966     t = ucal_getMillis(ucal, &status);
   1967     expected = 1299997800000.0; /* 2011-03-13T06:30:00Z */
   1968     if (U_FAILURE(status)) {
   1969         log_err("FAIL: Calculating time 2011-03-13 02:30:00 with UCAL_WALLTIME_FIRST - %s\n", u_errorName(status));
   1970         status = U_ZERO_ERROR;
   1971     } else if (t != expected) {
   1972         log_data_err("FAIL: 2011-03-13 02:30:00 with UCAL_WALLTIME_FIRST - got: %f, expected: %f\n", t, expected);
   1973     }
   1974 
   1975     /* UCAL_WALLTIME_LAST on US spring transition */
   1976     ucal_setAttribute(ucal, UCAL_SKIPPED_WALL_TIME, UCAL_WALLTIME_LAST);
   1977     ucal_clear(ucal);
   1978     ucal_setDateTime(ucal, 2011, 3-1, 13, 2, 30, 0, &status);
   1979     t = ucal_getMillis(ucal, &status);
   1980     expected = 1300001400000.0; /* 2011-03-13T07:30:00Z */
   1981     if (U_FAILURE(status)) {
   1982         log_err("FAIL: Calculating time 2011-03-13 02:30:00 with UCAL_WALLTIME_LAST - %s\n", u_errorName(status));
   1983         status = U_ZERO_ERROR;
   1984     } else if (t != expected) {
   1985         log_data_err("FAIL: 2011-03-13 02:30:00 with UCAL_WALLTIME_LAST - got: %f, expected: %f\n", t, expected);
   1986     }
   1987 
   1988     /* UCAL_WALLTIME_NEXT_VALID on US spring transition */
   1989     ucal_setAttribute(ucal, UCAL_SKIPPED_WALL_TIME, UCAL_WALLTIME_NEXT_VALID);
   1990     ucal_clear(ucal);
   1991     ucal_setDateTime(ucal, 2011, 3-1, 13, 2, 30, 0, &status);
   1992     t = ucal_getMillis(ucal, &status);
   1993     expected = 1299999600000.0; /* 2011-03-13T07:00:00Z */
   1994     if (U_FAILURE(status)) {
   1995         log_err("FAIL: Calculating time 2011-03-13 02:30:00 with UCAL_WALLTIME_NEXT_VALID - %s\n", u_errorName(status));
   1996         status = U_ZERO_ERROR;
   1997     } else if (t != expected) {
   1998         log_data_err("FAIL: 2011-03-13 02:30:00 with UCAL_WALLTIME_NEXT_VALID - got: %f, expected: %f\n", t, expected);
   1999     }
   2000 
   2001     /* non-lenient on US spring transition */
   2002     ucal_setAttribute(ucal, UCAL_LENIENT, 0);
   2003     ucal_clear(ucal);
   2004     ucal_setDateTime(ucal, 2011, 3-1, 13, 2, 30, 0, &status);
   2005     t = ucal_getMillis(ucal, &status);
   2006     if (U_SUCCESS(status)) {
   2007         /* must return error */
   2008         log_data_err("FAIL: Non-lenient did not fail with 2011-03-13 02:30:00\n");
   2009         status = U_ZERO_ERROR;
   2010     }
   2011 
   2012     ucal_close(ucal);
   2013 }
   2014 
   2015 /**
   2016  * TestAddRollEra0AndEraBounds, for #9226
   2017  */
   2018 
   2019  typedef struct {
   2020      const char * locale;
   2021      UBool era0YearsGoBackwards; /* until we have API to get this, per #9393 */
   2022  } EraTestItem;
   2023 
   2024 static const EraTestItem eraTestItems[] = {
   2025     /* calendars with non-modern era 0 that goes backwards, max era == 1 */
   2026     { "en@calendar=gregorian", TRUE },
   2027     { "en@calendar=roc", TRUE },
   2028     { "en@calendar=coptic", TRUE },
   2029     /* calendars with non-modern era 0 that goes forwards, max era > 1 */
   2030     { "en@calendar=japanese", FALSE },
   2031     { "en@calendar=chinese", FALSE },
   2032     /* calendars with non-modern era 0 that goes forwards, max era == 1 */
   2033     { "en@calendar=ethiopic", FALSE },
   2034     /* calendars with only one era  = 0, forwards */
   2035     { "en@calendar=buddhist", FALSE },
   2036     { "en@calendar=hebrew", FALSE },
   2037     { "en@calendar=islamic", FALSE },
   2038     { "en@calendar=indian", FALSE },
   2039     { "en@calendar=persian", FALSE },
   2040     { "en@calendar=ethiopic-amete-alem", FALSE },
   2041     { NULL, FALSE }
   2042 };
   2043 
   2044 static const UChar zoneGMT[] = { 0x47,0x4D,0x54,0 };
   2045 
   2046 void TestAddRollEra0AndEraBounds() {
   2047     const EraTestItem * eraTestItemPtr;
   2048     for (eraTestItemPtr = eraTestItems; eraTestItemPtr->locale != NULL; eraTestItemPtr++) {
   2049         UErrorCode status = U_ZERO_ERROR;
   2050         UCalendar *ucalTest = ucal_open(zoneGMT, -1, eraTestItemPtr->locale, UCAL_DEFAULT, &status);
   2051         if ( U_SUCCESS(status) ) {
   2052             int32_t yrBefore, yrAfter, yrMax, eraAfter, eraMax, eraNow;
   2053 
   2054             status = U_ZERO_ERROR;
   2055             ucal_clear(ucalTest);
   2056             ucal_set(ucalTest, UCAL_YEAR, 2);
   2057             ucal_set(ucalTest, UCAL_ERA, 0);
   2058             yrBefore = ucal_get(ucalTest, UCAL_YEAR, &status);
   2059             ucal_add(ucalTest, UCAL_YEAR, 1, &status);
   2060             yrAfter = ucal_get(ucalTest, UCAL_YEAR, &status);
   2061             if (U_FAILURE(status)) {
   2062                 log_err("FAIL: set era 0 year 2 then add 1 year and get year for %s, error %s\n",
   2063                         eraTestItemPtr->locale, u_errorName(status));
   2064             } else if ( (eraTestItemPtr->era0YearsGoBackwards && yrAfter>yrBefore) ||
   2065                         (!eraTestItemPtr->era0YearsGoBackwards && yrAfter<yrBefore) ) {
   2066                 log_err("FAIL: era 0 add 1 year does not move forward in time for %s\n", eraTestItemPtr->locale);
   2067             }
   2068 
   2069             status = U_ZERO_ERROR;
   2070             ucal_clear(ucalTest);
   2071             ucal_set(ucalTest, UCAL_YEAR, 2);
   2072             ucal_set(ucalTest, UCAL_ERA, 0);
   2073             yrBefore = ucal_get(ucalTest, UCAL_YEAR, &status);
   2074             ucal_roll(ucalTest, UCAL_YEAR, 1, &status);
   2075             yrAfter = ucal_get(ucalTest, UCAL_YEAR, &status);
   2076             if (U_FAILURE(status)) {
   2077                 log_err("FAIL: set era 0 year 2 then roll 1 year and get year for %s, error %s\n",
   2078                         eraTestItemPtr->locale, u_errorName(status));
   2079             } else if ( (eraTestItemPtr->era0YearsGoBackwards && yrAfter>yrBefore) ||
   2080                         (!eraTestItemPtr->era0YearsGoBackwards && yrAfter<yrBefore) ) {
   2081                 log_err("FAIL: era 0 roll 1 year does not move forward in time for %s\n", eraTestItemPtr->locale);
   2082             }
   2083 
   2084             status = U_ZERO_ERROR;
   2085             ucal_clear(ucalTest);
   2086             ucal_set(ucalTest, UCAL_YEAR, 1);
   2087             ucal_set(ucalTest, UCAL_ERA, 0);
   2088             if (eraTestItemPtr->era0YearsGoBackwards) {
   2089                 ucal_roll(ucalTest, UCAL_YEAR, 1, &status); /* roll forward in time to era 0 boundary */
   2090                 yrAfter = ucal_get(ucalTest, UCAL_YEAR, &status);
   2091                 eraAfter = ucal_get(ucalTest, UCAL_ERA, &status);
   2092                 if (U_FAILURE(status)) {
   2093                     log_err("FAIL: set era 0 year 1 then roll 1 year and get year,era for %s, error %s\n",
   2094                             eraTestItemPtr->locale, u_errorName(status));
   2095                 /* all calendars with era0YearsGoBackwards have "unbounded" era0 year values, so we should pin at yr 1 */
   2096                 } else if (eraAfter != 0 || yrAfter != 1) {
   2097                     log_err("FAIL: era 0 roll 1 year from year 1 does not stay within era or pin to year 1 for %s (get era %d year %d)\n",
   2098                             eraTestItemPtr->locale, eraAfter, yrAfter);
   2099                 }
   2100             } else {
   2101                 /* roll backward in time to where era 0 years go negative, except for the Chinese
   2102                    calendar, which uses negative eras instead of having years outside the range 1-60 */
   2103                 const char * calType = ucal_getType(ucalTest, &status);
   2104                 ucal_roll(ucalTest, UCAL_YEAR, -2, &status);
   2105                 yrAfter = ucal_get(ucalTest, UCAL_YEAR, &status);
   2106                 eraAfter = ucal_get(ucalTest, UCAL_ERA, &status);
   2107                 if (U_FAILURE(status)) {
   2108                     log_err("FAIL: set era 0 year 1 then roll -2 years and get year,era for %s, error %s\n",
   2109                             eraTestItemPtr->locale, u_errorName(status));
   2110                 } else if ( uprv_strcmp(calType,"chinese")!=0 && (eraAfter != 0 || yrAfter != -1) ) {
   2111                     log_err("FAIL: era 0 roll -2 years from year 1 does not stay within era or produce year -1 for %s (get era %d year %d)\n",
   2112                             eraTestItemPtr->locale, eraAfter, yrAfter);
   2113                 }
   2114             }
   2115 
   2116             status = U_ZERO_ERROR;
   2117             ucal_clear(ucalTest);
   2118             {
   2119                 int32_t eraMin = ucal_getLimit(ucalTest, UCAL_ERA, UCAL_MINIMUM, &status);
   2120                 const char * calType = ucal_getType(ucalTest, &status);
   2121                 if (eraMin != 0 && uprv_strcmp(calType, "chinese") != 0) {
   2122                     log_err("FAIL: ucal_getLimit returns minimum era %d (should be 0) for calType %s, error %s\n", eraMin, calType, u_errorName(status));
   2123                 }
   2124             }
   2125 
   2126             status = U_ZERO_ERROR;
   2127             ucal_clear(ucalTest);
   2128             ucal_set(ucalTest, UCAL_YEAR, 1);
   2129             ucal_set(ucalTest, UCAL_ERA, 0);
   2130             eraMax = ucal_getLimit(ucalTest, UCAL_ERA, UCAL_MAXIMUM, &status);
   2131             if ( U_SUCCESS(status) && eraMax > 0 ) {
   2132                 /* try similar tests for era 1 (if calendar has it), in which years always go forward */
   2133                 status = U_ZERO_ERROR;
   2134                 ucal_clear(ucalTest);
   2135                 ucal_set(ucalTest, UCAL_YEAR, 2);
   2136                 ucal_set(ucalTest, UCAL_ERA, 1);
   2137                 yrBefore = ucal_get(ucalTest, UCAL_YEAR, &status);
   2138                 ucal_add(ucalTest, UCAL_YEAR, 1, &status);
   2139                 yrAfter = ucal_get(ucalTest, UCAL_YEAR, &status);
   2140                 if (U_FAILURE(status)) {
   2141                     log_err("FAIL: set era 1 year 2 then add 1 year and get year for %s, error %s\n",
   2142                             eraTestItemPtr->locale, u_errorName(status));
   2143                 } else if ( yrAfter<yrBefore ) {
   2144                     log_err("FAIL: era 1 add 1 year does not move forward in time for %s\n", eraTestItemPtr->locale);
   2145                 }
   2146 
   2147                 status = U_ZERO_ERROR;
   2148                 ucal_clear(ucalTest);
   2149                 ucal_set(ucalTest, UCAL_YEAR, 2);
   2150                 ucal_set(ucalTest, UCAL_ERA, 1);
   2151                 yrBefore = ucal_get(ucalTest, UCAL_YEAR, &status);
   2152                 ucal_roll(ucalTest, UCAL_YEAR, 1, &status);
   2153                 yrAfter = ucal_get(ucalTest, UCAL_YEAR, &status);
   2154                 if (U_FAILURE(status)) {
   2155                     log_err("FAIL: set era 1 year 2 then roll 1 year and get year for %s, error %s\n",
   2156                             eraTestItemPtr->locale, u_errorName(status));
   2157                 } else if ( yrAfter<yrBefore ) {
   2158                     log_err("FAIL: era 1 roll 1 year does not move forward in time for %s\n", eraTestItemPtr->locale);
   2159                 }
   2160 
   2161                 status = U_ZERO_ERROR;
   2162                 ucal_clear(ucalTest);
   2163                 ucal_set(ucalTest, UCAL_YEAR, 1);
   2164                 ucal_set(ucalTest, UCAL_ERA, 1);
   2165                 yrMax = ucal_getLimit(ucalTest, UCAL_YEAR, UCAL_ACTUAL_MAXIMUM, &status); /* max year value for era 1 */
   2166                 ucal_roll(ucalTest, UCAL_YEAR, -1, &status); /* roll down which should pin or wrap to end */
   2167                 yrAfter = ucal_get(ucalTest, UCAL_YEAR, &status);
   2168                 eraAfter = ucal_get(ucalTest, UCAL_ERA, &status);
   2169                 if (U_FAILURE(status)) {
   2170                     log_err("FAIL: set era 1 year 1 then roll -1 year and get year,era for %s, error %s\n",
   2171                             eraTestItemPtr->locale, u_errorName(status));
   2172                 /* if yrMax is reasonable we should wrap to that, else we should pin at yr 1 */
   2173                 } else if (yrMax >= 32768) {
   2174                     if (eraAfter != 1 || yrAfter != 1) {
   2175                         log_err("FAIL: era 1 roll -1 year from year 1 does not stay within era or pin to year 1 for %s (get era %d year %d)\n",
   2176                                 eraTestItemPtr->locale, eraAfter, yrAfter);
   2177                     }
   2178                 } else if (eraAfter != 1 || yrAfter != yrMax) {
   2179                     log_err("FAIL: era 1 roll -1 year from year 1 does not stay within era or wrap to year %d for %s (get era %d year %d)\n",
   2180                             yrMax, eraTestItemPtr->locale, eraAfter, yrAfter);
   2181                 } else {
   2182                     /* now roll up which should wrap to beginning */
   2183                     ucal_roll(ucalTest, UCAL_YEAR, 1, &status); /* now roll up which should wrap to beginning */
   2184                     yrAfter = ucal_get(ucalTest, UCAL_YEAR, &status);
   2185                     eraAfter = ucal_get(ucalTest, UCAL_ERA, &status);
   2186                     if (U_FAILURE(status)) {
   2187                         log_err("FAIL: era 1 roll 1 year from end and get year,era for %s, error %s\n",
   2188                                 eraTestItemPtr->locale, u_errorName(status));
   2189                     } else if (eraAfter != 1 || yrAfter != 1) {
   2190                         log_err("FAIL: era 1 roll 1 year from year %d does not stay within era or wrap to year 1 for %s (get era %d year %d)\n",
   2191                                 yrMax, eraTestItemPtr->locale, eraAfter, yrAfter);
   2192                     }
   2193                 }
   2194 
   2195                 /* if current era  > 1, try the same roll tests for current era */
   2196                 ucal_setMillis(ucalTest, ucal_getNow(), &status);
   2197                 eraNow = ucal_get(ucalTest, UCAL_ERA, &status);
   2198                 if ( U_SUCCESS(status) && eraNow > 1 ) {
   2199                     status = U_ZERO_ERROR;
   2200                     ucal_clear(ucalTest);
   2201                     ucal_set(ucalTest, UCAL_YEAR, 1);
   2202                     ucal_set(ucalTest, UCAL_ERA, eraNow);
   2203                     yrMax = ucal_getLimit(ucalTest, UCAL_YEAR, UCAL_ACTUAL_MAXIMUM, &status); /* max year value for this era */
   2204                     ucal_roll(ucalTest, UCAL_YEAR, -1, &status);
   2205                     yrAfter = ucal_get(ucalTest, UCAL_YEAR, &status);
   2206                     eraAfter = ucal_get(ucalTest, UCAL_ERA, &status);
   2207                     if (U_FAILURE(status)) {
   2208                         log_err("FAIL: set era %d year 1 then roll -1 year and get year,era for %s, error %s\n",
   2209                                 eraNow, eraTestItemPtr->locale, u_errorName(status));
   2210                     /* if yrMax is reasonable we should wrap to that, else we should pin at yr 1 */
   2211                     } else if (yrMax >= 32768) {
   2212                         if (eraAfter != eraNow || yrAfter != 1) {
   2213                             log_err("FAIL: era %d roll -1 year from year 1 does not stay within era or pin to year 1 for %s (get era %d year %d)\n",
   2214                                     eraNow, eraTestItemPtr->locale, eraAfter, yrAfter);
   2215                         }
   2216                     } else if (eraAfter != eraNow || yrAfter != yrMax) {
   2217                         log_err("FAIL: era %d roll -1 year from year 1 does not stay within era or wrap to year %d for %s (get era %d year %d)\n",
   2218                                 eraNow, yrMax, eraTestItemPtr->locale, eraAfter, yrAfter);
   2219                     } else {
   2220                         /* now roll up which should wrap to beginning */
   2221                         ucal_roll(ucalTest, UCAL_YEAR, 1, &status); /* now roll up which should wrap to beginning */
   2222                         yrAfter = ucal_get(ucalTest, UCAL_YEAR, &status);
   2223                         eraAfter = ucal_get(ucalTest, UCAL_ERA, &status);
   2224                         if (U_FAILURE(status)) {
   2225                             log_err("FAIL: era %d roll 1 year from end and get year,era for %s, error %s\n",
   2226                                     eraNow, eraTestItemPtr->locale, u_errorName(status));
   2227                         } else if (eraAfter != eraNow || yrAfter != 1) {
   2228                             log_err("FAIL: era %d roll 1 year from year %d does not stay within era or wrap to year 1 for %s (get era %d year %d)\n",
   2229                                     eraNow, yrMax, eraTestItemPtr->locale, eraAfter, yrAfter);
   2230                         }
   2231                     }
   2232                 }
   2233             }
   2234 
   2235             ucal_close(ucalTest);
   2236         } else {
   2237             log_data_err("FAIL: ucal_open fails for zone GMT, locale %s, UCAL_DEFAULT\n", eraTestItemPtr->locale);
   2238         }
   2239     }
   2240 }
   2241 
   2242 /**
   2243  * TestGetTZTransition, for #9606
   2244  */
   2245 
   2246 typedef struct {
   2247     const char *descrip;    /* test description */
   2248     const UChar * zoneName; /* pointer to zero-terminated zone name */
   2249     int32_t year;           /* starting point for test is gregorian calendar noon on day specified by y,M,d here */
   2250     int32_t month;
   2251     int32_t day;
   2252     UBool hasPrev;          /* does it have a previous transition from starting point? If so we test inclusive from that */
   2253     UBool hasNext;          /* does it have a next transition from starting point? If so we test inclusive from that */
   2254 } TZTransitionItem;
   2255 
   2256 /* have zoneGMT above */
   2257 static const UChar zoneUSPacific[] = { 0x55,0x53,0x2F,0x50,0x61,0x63,0x69,0x66,0x69,0x63,0 }; /* "US/Pacific" */
   2258 static const UChar zoneCairo[]     = { 0x41,0x66,0x72,0x69,0x63,0x61,0x2F,0x43,0x61,0x69,0x72,0x6F,0 }; /* "Africa/Cairo", DST cancelled since 2011 */
   2259 static const UChar zoneIceland[]   = { 0x41,0x74,0x6C,0x61,0x6E,0x74,0x69,0x63,0x2F,0x52,0x65,0x79,0x6B,0x6A,0x61,0x76,0x69,0x6B,0 }; /* "Atlantic/Reykjavik", always on DST (since when?) */
   2260 
   2261 static const TZTransitionItem tzTransitionItems[] = {
   2262     { "USPacific mid 2012", zoneUSPacific, 2012, UCAL_JULY, 1, TRUE , TRUE  },
   2263     { "USPacific mid  100", zoneUSPacific,  100, UCAL_JULY, 1, FALSE, TRUE  }, /* no transitions before 100 CE... */
   2264     { "Cairo     mid 2012", zoneCairo,     2012, UCAL_JULY, 1, TRUE , FALSE }, /* DST cancelled since 2011 */
   2265     { "Iceland   mid 2012", zoneIceland,   2012, UCAL_JULY, 1, TRUE , FALSE }, /* always on DST */
   2266     { NULL,                 NULL,             0,         0, 0, FALSE, FALSE } /* terminator */
   2267 };
   2268 
   2269 void TestGetTZTransition() {
   2270     UErrorCode status = U_ZERO_ERROR;
   2271     UCalendar * ucal = ucal_open(zoneGMT, -1, "en", UCAL_GREGORIAN, &status);
   2272     if ( U_SUCCESS(status) ) {
   2273         const TZTransitionItem * itemPtr;
   2274         for (itemPtr = tzTransitionItems; itemPtr->descrip != NULL; itemPtr++) {
   2275             UDate curMillis;
   2276             ucal_setTimeZone(ucal, itemPtr->zoneName, -1, &status);
   2277             ucal_setDateTime(ucal, itemPtr->year, itemPtr->month, itemPtr->day, 12, 0, 0, &status);
   2278             curMillis = ucal_getMillis(ucal, &status);
   2279             if ( U_SUCCESS(status) ) {
   2280                 UDate transition1, transition2;
   2281                 UBool result;
   2282 
   2283                 result = ucal_getTimeZoneTransitionDate(ucal, UCAL_TZ_TRANSITION_PREVIOUS, &transition1, &status);
   2284                 if (U_FAILURE(status) || result != itemPtr->hasPrev) {
   2285                     log_data_err("FAIL: %s ucal_getTimeZoneTransitionDate prev status %s, expected result %d but got %d\n",
   2286                             itemPtr->descrip, u_errorName(status), itemPtr->hasPrev, result);
   2287                 } else if (result) {
   2288                     ucal_setMillis(ucal, transition1, &status);
   2289                     result = ucal_getTimeZoneTransitionDate(ucal, UCAL_TZ_TRANSITION_PREVIOUS_INCLUSIVE, &transition2, &status);
   2290                     if (U_FAILURE(status) || !result || transition2 != transition1) {
   2291                         log_err("FAIL: %s ucal_getTimeZoneTransitionDate prev_inc status %s, result %d, expected date %.1f but got %.1f\n",
   2292                                 itemPtr->descrip, u_errorName(status), result, transition1, transition2);
   2293                     }
   2294                 }
   2295                 status = U_ZERO_ERROR;
   2296 
   2297                 result = ucal_getTimeZoneTransitionDate(ucal, UCAL_TZ_TRANSITION_NEXT, &transition1, &status);
   2298                 if (U_FAILURE(status) || result != itemPtr->hasNext) {
   2299                     log_data_err("FAIL: %s ucal_getTimeZoneTransitionDate next status %s, expected result %d but got %d\n",
   2300                             itemPtr->descrip, u_errorName(status), itemPtr->hasNext, result);
   2301                 } else if (result) {
   2302                     ucal_setMillis(ucal, transition1, &status);
   2303                     result = ucal_getTimeZoneTransitionDate(ucal, UCAL_TZ_TRANSITION_NEXT_INCLUSIVE, &transition2, &status);
   2304                     if (U_FAILURE(status) || !result || transition2 != transition1) {
   2305                         log_err("FAIL: %s ucal_getTimeZoneTransitionDate next_inc status %s, result %d, expected date %.1f but got %.1f\n",
   2306                                 itemPtr->descrip, u_errorName(status), result, transition1, transition2);
   2307                     }
   2308                 }
   2309                 status = U_ZERO_ERROR;
   2310             } else {
   2311                 log_data_err("FAIL setup: can't setup calendar for %s, status %s\n",
   2312                             itemPtr->descrip, u_errorName(status));
   2313                 status = U_ZERO_ERROR;
   2314             }
   2315         }
   2316         ucal_close(ucal);
   2317     } else {
   2318         log_data_err("FAIL setup: ucal_open status %s\n", u_errorName(status));
   2319     }
   2320 }
   2321 
   2322 #endif /* #if !UCONFIG_NO_FORMATTING */
   2323