Home | History | Annotate | Download | only in cintltst
      1 /********************************************************************
      2  * COPYRIGHT:
      3  * Copyright (c) 1997-2012, International Business Machines Corporation and
      4  * others. All Rights Reserved.
      5  ********************************************************************/
      6 /********************************************************************************
      7 *
      8 * File CDATTST.C
      9 *
     10 * Modification History:
     11 *        Name                     Description
     12 *     Madhu Katragadda               Creation
     13 *********************************************************************************
     14 */
     15 
     16 /* C API TEST FOR DATE FORMAT */
     17 
     18 #include "unicode/utypes.h"
     19 
     20 #if !UCONFIG_NO_FORMATTING
     21 
     22 #include "unicode/uloc.h"
     23 #include "unicode/udat.h"
     24 #include "unicode/udatpg.h"
     25 #include "unicode/ucal.h"
     26 #include "unicode/unum.h"
     27 #include "unicode/ustring.h"
     28 #include "cintltst.h"
     29 #include "cdattst.h"
     30 #include "cformtst.h"
     31 #include "cmemory.h"
     32 
     33 #include <math.h>
     34 
     35 static void TestExtremeDates(void);
     36 static void TestAllLocales(void);
     37 static void TestRelativeCrash(void);
     38 static void TestContext(void);
     39 
     40 #define LEN(a) (sizeof(a)/sizeof(a[0]))
     41 
     42 void addDateForTest(TestNode** root);
     43 
     44 #define TESTCASE(x) addTest(root, &x, "tsformat/cdattst/" #x)
     45 
     46 void addDateForTest(TestNode** root)
     47 {
     48     TESTCASE(TestDateFormat);
     49     TESTCASE(TestRelativeDateFormat);
     50     TESTCASE(TestSymbols);
     51     TESTCASE(TestDateFormatCalendar);
     52     TESTCASE(TestExtremeDates);
     53     TESTCASE(TestAllLocales);
     54     TESTCASE(TestRelativeCrash);
     55     TESTCASE(TestContext);
     56 }
     57 /* Testing the DateFormat API */
     58 static void TestDateFormat()
     59 {
     60     UDateFormat *def, *fr, *it, *de, *def1, *fr_pat;
     61     UDateFormat *any;
     62     UDateFormat *copy;
     63     UErrorCode status = U_ZERO_ERROR;
     64     UChar* result = NULL;
     65     const UCalendar *cal;
     66     const UNumberFormat *numformat1, *numformat2;
     67     UChar temp[50];
     68     int32_t numlocales;
     69     UDate d1;
     70     int i;
     71     int32_t resultlength;
     72     int32_t resultlengthneeded;
     73     int32_t parsepos;
     74     UDate d = 837039928046.0;
     75     double num = -10456.37;
     76     /*const char* str="yyyy.MM.dd G 'at' hh:mm:ss z";
     77     const char t[]="2/3/76 2:50 AM";*/
     78     /*Testing udat_open() to open a dateformat */
     79 
     80     ctest_setTimeZone(NULL, &status);
     81 
     82     log_verbose("\nTesting udat_open() with various parameters\n");
     83     fr = udat_open(UDAT_FULL, UDAT_DEFAULT, "fr_FR", NULL,0, NULL, 0,&status);
     84     if(U_FAILURE(status))
     85     {
     86         log_data_err("FAIL: error in creating the dateformat using full time style with french locale -> %s (Are you missing data?)\n",
     87             myErrorName(status) );
     88         return;
     89     }
     90     /* this is supposed to open default date format, but later on it treats it like it is "en_US"
     91        - very bad if you try to run the tests on machine where default locale is NOT "en_US" */
     92     /* def = udat_open(UDAT_SHORT, UDAT_SHORT, NULL, NULL, 0, &status); */
     93     def = udat_open(UDAT_SHORT, UDAT_SHORT, "en_US", NULL, 0,NULL, 0, &status);
     94     if(U_FAILURE(status))
     95     {
     96         log_err("FAIL: error in creating the dateformat using short date and time style\n %s\n",
     97             myErrorName(status) );
     98         return;
     99     }
    100     it = udat_open(UDAT_DEFAULT, UDAT_MEDIUM, "it_IT", NULL, 0, NULL, 0,&status);
    101     if(U_FAILURE(status))
    102     {
    103         log_err("FAIL: error in creating the dateformat using medium date style with italian locale\n %s\n",
    104             myErrorName(status) );
    105         return;
    106     }
    107     de = udat_open(UDAT_LONG, UDAT_LONG, "de_DE", NULL, 0, NULL, 0,&status);
    108     if(U_FAILURE(status))
    109     {
    110         log_err("FAIL: error in creating the dateformat using long time and date styles with german locale\n %s\n",
    111             myErrorName(status));
    112         return;
    113     }
    114     /*creating a default dateformat */
    115     def1 = udat_open(UDAT_SHORT, UDAT_SHORT, NULL, NULL, 0,NULL, 0, &status);
    116     if(U_FAILURE(status))
    117     {
    118         log_err("FAIL: error in creating the dateformat using short date and time style\n %s\n",
    119             myErrorName(status) );
    120         return;
    121     }
    122 
    123 
    124     /*Testing udat_getAvailable() and udat_countAvailable()*/
    125     log_verbose("\nTesting getAvailableLocales and countAvailable()\n");
    126     numlocales=udat_countAvailable();
    127     /* use something sensible w/o hardcoding the count */
    128     if(numlocales < 0)
    129         log_data_err("FAIL: error in countAvailable\n");
    130     log_verbose("The number of locales for which date/time formatting patterns are available is %d\n", numlocales);
    131 
    132     for(i=0;i<numlocales;i++) {
    133       UErrorCode subStatus = U_ZERO_ERROR;
    134       log_verbose("Testing open of %s\n", udat_getAvailable(i));
    135       any = udat_open(UDAT_SHORT, UDAT_SHORT, udat_getAvailable(i), NULL ,0, NULL, 0, &subStatus);
    136       if(U_FAILURE(subStatus)) {
    137         log_data_err("FAIL: date format %s (getAvailable(%d)) is not instantiable: %s\n", udat_getAvailable(i), i, u_errorName(subStatus));
    138       }
    139       udat_close(any);
    140     }
    141 
    142     /*Testing udat_clone()*/
    143     log_verbose("\nTesting the udat_clone() function of date format\n");
    144     copy=udat_clone(def, &status);
    145     if(U_FAILURE(status)){
    146         log_err("Error in creating the clone using udat_clone: %s\n", myErrorName(status) );
    147     }
    148     /*if(def != copy)
    149         log_err("Error in udat_clone");*/ /*how should i check for equality???? */
    150 
    151     /*Testing udat_format()*/
    152     log_verbose("\nTesting the udat_format() function of date format\n");
    153     u_uastrcpy(temp, "7/10/96, 4:05 PM");
    154     /*format using def */
    155     resultlength=0;
    156     resultlengthneeded=udat_format(def, d, NULL, resultlength, NULL, &status);
    157     if(status==U_BUFFER_OVERFLOW_ERROR)
    158     {
    159         status=U_ZERO_ERROR;
    160         resultlength=resultlengthneeded+1;
    161         if(result != NULL) {
    162             free(result);
    163             result = NULL;
    164         }
    165         result=(UChar*)malloc(sizeof(UChar) * resultlength);
    166         udat_format(def, d, result, resultlength, NULL, &status);
    167     }
    168     if(U_FAILURE(status) || !result)
    169     {
    170         log_err("FAIL: Error in formatting using udat_format(.....) %s\n", myErrorName(status) );
    171         return;
    172     }
    173     else
    174         log_verbose("PASS: formatting successful\n");
    175     if(u_strcmp(result, temp)==0)
    176         log_verbose("PASS: Date Format for US locale successful using udat_format()\n");
    177     else {
    178         char xbuf[2048];
    179         char gbuf[2048];
    180         u_austrcpy(xbuf, temp);
    181         u_austrcpy(gbuf, result);
    182         log_err("FAIL: Date Format for US locale failed using udat_format() - expected %s got %s\n", xbuf, gbuf);
    183     }
    184     /*format using fr */
    185 
    186     u_unescape("10 juil. 1996 16:05:28 heure avanc\\u00E9e du Pacifique", temp, 50);
    187     if(result != NULL) {
    188         free(result);
    189         result = NULL;
    190     }
    191     result=myDateFormat(fr, d);
    192     if(u_strcmp(result, temp)==0)
    193         log_verbose("PASS: Date Format for french locale successful using udat_format()\n");
    194     else
    195         log_data_err("FAIL: Date Format for french locale failed using udat_format().\n" );
    196 
    197     /*format using it */
    198     u_uastrcpy(temp, "10/lug/1996 16:05:28");
    199 
    200     {
    201         UChar *fmtted;
    202         char g[100];
    203         char x[100];
    204 
    205         fmtted = myDateFormat(it,d);
    206         u_austrcpy(g, fmtted);
    207         u_austrcpy(x, temp);
    208         if(u_strcmp(fmtted, temp)==0) {
    209             log_verbose("PASS: Date Format for italian locale successful uisng udat_format() - wanted %s, got %s\n", x, g);
    210         } else {
    211             log_data_err("FAIL: Date Format for italian locale failed using udat_format() - wanted %s, got %s\n", x, g);
    212         }
    213     }
    214 
    215     /*Testing parsing using udat_parse()*/
    216     log_verbose("\nTesting parsing using udat_parse()\n");
    217     u_uastrcpy(temp,"2/3/76, 2:50 AM");
    218     parsepos=0;
    219     status=U_ZERO_ERROR;
    220 
    221     d1=udat_parse(def, temp, u_strlen(temp), &parsepos, &status);
    222     if(U_FAILURE(status))
    223     {
    224         log_err("FAIL: Error in parsing using udat_parse(.....) %s\n", myErrorName(status) );
    225     }
    226     else
    227         log_verbose("PASS: parsing succesful\n");
    228     /*format it back and check for equality */
    229 
    230 
    231     if(u_strcmp(myDateFormat(def, d1),temp)!=0)
    232         log_err("FAIL: error in parsing\n");
    233 
    234     /*Testing parsing using udat_parse()*/
    235     log_verbose("\nTesting parsing using udat_parse()\n");
    236     u_uastrcpy(temp,"2/Don't parse this part");
    237     status=U_ZERO_ERROR;
    238 
    239     d1=udat_parse(def, temp, u_strlen(temp), NULL, &status);
    240     if(status != U_PARSE_ERROR)
    241     {
    242         log_err("FAIL: udat_parse(\"bad string\") passed when it should have failed\n");
    243     }
    244     else
    245         log_verbose("PASS: parsing succesful\n");
    246 
    247 
    248 
    249     /*Testing udat_openPattern()  */
    250     status=U_ZERO_ERROR;
    251     log_verbose("\nTesting the udat_openPattern with a specified pattern\n");
    252     /*for french locale */
    253     fr_pat=udat_open(UDAT_PATTERN, UDAT_PATTERN,"fr_FR",NULL,0,temp, u_strlen(temp), &status);
    254     if(U_FAILURE(status))
    255     {
    256         log_err("FAIL: Error in creating a date format using udat_openPattern \n %s\n",
    257             myErrorName(status) );
    258     }
    259     else
    260         log_verbose("PASS: creating dateformat using udat_openPattern() succesful\n");
    261 
    262 
    263         /*Testing applyPattern and toPattern */
    264     log_verbose("\nTesting applyPattern and toPattern()\n");
    265     udat_applyPattern(def1, FALSE, temp, u_strlen(temp));
    266     log_verbose("Extracting the pattern\n");
    267 
    268     resultlength=0;
    269     resultlengthneeded=udat_toPattern(def1, FALSE, NULL, resultlength, &status);
    270     if(status==U_BUFFER_OVERFLOW_ERROR)
    271     {
    272         status=U_ZERO_ERROR;
    273         resultlength=resultlengthneeded + 1;
    274         result=(UChar*)malloc(sizeof(UChar) * resultlength);
    275         udat_toPattern(def1, FALSE, result, resultlength, &status);
    276     }
    277     if(U_FAILURE(status))
    278     {
    279         log_err("FAIL: error in extracting the pattern from UNumberFormat\n %s\n",
    280             myErrorName(status) );
    281     }
    282     if(u_strcmp(result, temp)!=0)
    283         log_err("FAIL: Error in extracting the pattern\n");
    284     else
    285         log_verbose("PASS: applyPattern and toPattern work fine\n");
    286 
    287     if(result != NULL) {
    288         free(result);
    289         result = NULL;
    290     }
    291 
    292 
    293     /*Testing getter and setter functions*/
    294     /*isLenient and setLenient()*/
    295     log_verbose("\nTesting the isLenient and setLenient properties\n");
    296     udat_setLenient(fr, udat_isLenient(it));
    297     if(udat_isLenient(fr) != udat_isLenient(it))
    298         log_err("ERROR: setLenient() failed\n");
    299     else
    300         log_verbose("PASS: setLenient() successful\n");
    301 
    302 
    303     /*Test get2DigitYearStart set2DigitYearStart */
    304     log_verbose("\nTesting the get and set 2DigitYearStart properties\n");
    305     d1= udat_get2DigitYearStart(fr_pat,&status);
    306     if(U_FAILURE(status)) {
    307             log_err("ERROR: udat_get2DigitYearStart failed %s\n", myErrorName(status) );
    308     }
    309     status = U_ZERO_ERROR;
    310     udat_set2DigitYearStart(def1 ,d1, &status);
    311     if(U_FAILURE(status)) {
    312         log_err("ERROR: udat_set2DigitYearStart failed %s\n", myErrorName(status) );
    313     }
    314     if(udat_get2DigitYearStart(fr_pat, &status) != udat_get2DigitYearStart(def1, &status))
    315         log_err("FAIL: error in set2DigitYearStart\n");
    316     else
    317         log_verbose("PASS: set2DigitYearStart successful\n");
    318     /*try setting it to another value */
    319     udat_set2DigitYearStart(de, 2000.0, &status);
    320     if(U_FAILURE(status)){
    321         log_verbose("ERROR: udat_set2DigitYearStart failed %s\n", myErrorName(status) );
    322     }
    323     if(udat_get2DigitYearStart(de, &status) != 2000)
    324         log_err("FAIL: error in set2DigitYearStart\n");
    325     else
    326         log_verbose("PASS: set2DigitYearStart successful\n");
    327 
    328 
    329 
    330     /*Test getNumberFormat() and setNumberFormat() */
    331     log_verbose("\nTesting the get and set NumberFormat properties of date format\n");
    332     numformat1=udat_getNumberFormat(fr_pat);
    333     udat_setNumberFormat(def1, numformat1);
    334     numformat2=udat_getNumberFormat(def1);
    335     if(u_strcmp(myNumformat(numformat1, num), myNumformat(numformat2, num)) !=0)
    336         log_err("FAIL: error in setNumberFormat or getNumberFormat()\n");
    337     else
    338         log_verbose("PASS:setNumberFormat and getNumberFormat succesful\n");
    339 
    340     /*try setting the number format to another format */
    341     numformat1=udat_getNumberFormat(def);
    342     udat_setNumberFormat(def1, numformat1);
    343     numformat2=udat_getNumberFormat(def1);
    344     if(u_strcmp(myNumformat(numformat1, num), myNumformat(numformat2, num)) !=0)
    345         log_err("FAIL: error in setNumberFormat or getNumberFormat()\n");
    346     else
    347         log_verbose("PASS: setNumberFormat and getNumberFormat succesful\n");
    348 
    349 
    350 
    351     /*Test getCalendar and setCalendar*/
    352     log_verbose("\nTesting the udat_getCalendar() and udat_setCalendar() properties\n");
    353     cal=udat_getCalendar(fr_pat);
    354 
    355 
    356     udat_setCalendar(def1, cal);
    357     if(!ucal_equivalentTo(udat_getCalendar(fr_pat), udat_getCalendar(def1)))
    358         log_err("FAIL: Error in setting and getting the calendar\n");
    359     else
    360         log_verbose("PASS: getting and setting calendar successful\n");
    361 
    362     if(result!=NULL) {
    363         free(result);
    364     }
    365 
    366     /*Closing the UDateForamt */
    367     udat_close(def);
    368     udat_close(fr);
    369     udat_close(it);
    370     udat_close(de);
    371     udat_close(def1);
    372     udat_close(fr_pat);
    373     udat_close(copy);
    374 
    375     ctest_resetTimeZone();
    376 }
    377 
    378 /*
    379 Test combined relative date formatting (relative date + non-relative time).
    380 This is a bit tricky since we can't have static test data for comparison, the
    381 relative date formatting is relative to the time the tests are run. We generate
    382 the data for comparison dynamically. However, the tests could fail if they are
    383 run right at midnight Pacific time and the call to ucal_getNow() is before midnight
    384 while the calls to udat_format are after midnight or span midnight.
    385 */
    386 static const UDate dayInterval = 24.0*60.0*60.0*1000.0;
    387 static const UChar trdfZone[] = { 0x0055, 0x0053, 0x002F, 0x0050, 0x0061, 0x0063, 0x0069, 0x0066, 0x0069, 0x0063, 0 }; /* US/Pacific */
    388 static const char trdfLocale[] = "en_US";
    389 static const UChar minutesPatn[] = { 0x006D, 0x006D, 0 }; /* "mm" */
    390 static const UChar monthLongPatn[] = { 0x004D, 0x004D, 0x004D, 0x004D, 0 }; /* "MMMM" */
    391 static const UChar monthMediumPatn[] = { 0x004D, 0x004D, 0x004D, 0 }; /* "MMM" */
    392 static const UChar monthShortPatn[] = { 0x004D, 0 }; /* "M" */
    393 static const UDateFormatStyle dateStylesList[] = { UDAT_FULL, UDAT_LONG, UDAT_MEDIUM, UDAT_SHORT, UDAT_NONE };
    394 static const UChar *monthPatnsList[] = { monthLongPatn, monthLongPatn, monthMediumPatn, monthShortPatn, NULL };
    395 static const UChar newTimePatn[] = { 0x0048, 0x0048, 0x002C, 0x006D, 0x006D, 0 }; /* "HH,mm" */
    396 static const UChar minutesStr[] = { 0x0034, 0x0039, 0 }; /* "49", minutes string to search for in output */
    397 enum { kDateOrTimeOutMax = 96, kDateAndTimeOutMax = 192 };
    398 
    399 static const UDate minutesTolerance = 2 * 60.0 * 1000.0;
    400 static const UDate daysTolerance = 2 * 24.0 * 60.0 * 60.0 * 1000.0;
    401 
    402 static void TestRelativeDateFormat()
    403 {
    404     UDate today = 0.0;
    405     const UDateFormatStyle * stylePtr;
    406     const UChar ** monthPtnPtr;
    407     UErrorCode status = U_ZERO_ERROR;
    408     UCalendar * ucal = ucal_open(trdfZone, -1, trdfLocale, UCAL_GREGORIAN, &status);
    409     if ( U_SUCCESS(status) ) {
    410         int32_t    year, month, day;
    411         ucal_setMillis(ucal, ucal_getNow(), &status);
    412         year = ucal_get(ucal, UCAL_YEAR, &status);
    413         month = ucal_get(ucal, UCAL_MONTH, &status);
    414         day = ucal_get(ucal, UCAL_DATE, &status);
    415         ucal_setDateTime(ucal, year, month, day, 18, 49, 0, &status); /* set to today at 18:49:00 */
    416         today = ucal_getMillis(ucal, &status);
    417         ucal_close(ucal);
    418     }
    419     if ( U_FAILURE(status) || today == 0.0 ) {
    420         log_data_err("Generate UDate for a specified time today fails, error %s - (Are you missing data?)\n", myErrorName(status) );
    421         return;
    422     }
    423     for (stylePtr = dateStylesList, monthPtnPtr = monthPatnsList; *stylePtr != UDAT_NONE; ++stylePtr, ++monthPtnPtr) {
    424         UDateFormat* fmtRelDateTime;
    425         UDateFormat* fmtRelDate;
    426         UDateFormat* fmtTime;
    427         int32_t dayOffset, limit;
    428         UFieldPosition fp;
    429         UChar   strDateTime[kDateAndTimeOutMax];
    430         UChar   strDate[kDateOrTimeOutMax];
    431         UChar   strTime[kDateOrTimeOutMax];
    432         UChar * strPtr;
    433         int32_t dtpatLen;
    434 
    435         fmtRelDateTime = udat_open(UDAT_SHORT, *stylePtr | UDAT_RELATIVE, trdfLocale, trdfZone, -1, NULL, 0, &status);
    436         if ( U_FAILURE(status) ) {
    437             log_data_err("udat_open timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s (Are you missing data?)\n", *stylePtr, myErrorName(status) );
    438             continue;
    439         }
    440         fmtRelDate = udat_open(UDAT_NONE, *stylePtr | UDAT_RELATIVE, trdfLocale, trdfZone, -1, NULL, 0, &status);
    441         if ( U_FAILURE(status) ) {
    442             log_err("udat_open timeStyle NONE dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
    443             udat_close(fmtRelDateTime);
    444             continue;
    445         }
    446         fmtTime = udat_open(UDAT_SHORT, UDAT_NONE, trdfLocale, trdfZone, -1, NULL, 0, &status);
    447         if ( U_FAILURE(status) ) {
    448             log_err("udat_open timeStyle SHORT dateStyle NONE fails, error %s\n", myErrorName(status) );
    449             udat_close(fmtRelDateTime);
    450             udat_close(fmtRelDate);
    451             continue;
    452         }
    453 
    454         dtpatLen = udat_toPatternRelativeDate(fmtRelDateTime, strDate, kDateAndTimeOutMax, &status);
    455         if ( U_FAILURE(status) ) {
    456             log_err("udat_toPatternRelativeDate timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
    457             status = U_ZERO_ERROR;
    458         } else if ( u_strstr(strDate, *monthPtnPtr) == NULL || dtpatLen != u_strlen(strDate) ) {
    459             log_err("udat_toPatternRelativeDate timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) date pattern incorrect\n", *stylePtr );
    460         }
    461         dtpatLen = udat_toPatternRelativeTime(fmtRelDateTime, strTime, kDateAndTimeOutMax, &status);
    462         if ( U_FAILURE(status) ) {
    463             log_err("udat_toPatternRelativeTime timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
    464             status = U_ZERO_ERROR;
    465         } else if ( u_strstr(strTime, minutesPatn) == NULL || dtpatLen != u_strlen(strTime) ) {
    466             log_err("udat_toPatternRelativeTime timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) time pattern incorrect\n", *stylePtr );
    467         }
    468         dtpatLen = udat_toPattern(fmtRelDateTime, FALSE, strDateTime, kDateAndTimeOutMax, &status);
    469         if ( U_FAILURE(status) ) {
    470             log_err("udat_toPattern timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
    471             status = U_ZERO_ERROR;
    472         } else if ( u_strstr(strDateTime, strDate) == NULL || u_strstr(strDateTime, strTime) == NULL || dtpatLen != u_strlen(strDateTime) ) {
    473             log_err("udat_toPattern timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) dateTime pattern incorrect\n", *stylePtr );
    474         }
    475         udat_applyPatternRelative(fmtRelDateTime, strDate, u_strlen(strDate), newTimePatn, u_strlen(newTimePatn), &status);
    476         if ( U_FAILURE(status) ) {
    477             log_err("udat_applyPatternRelative timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
    478             status = U_ZERO_ERROR;
    479         } else {
    480             udat_toPattern(fmtRelDateTime, FALSE, strDateTime, kDateAndTimeOutMax, &status);
    481             if ( U_FAILURE(status) ) {
    482                 log_err("udat_toPattern timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
    483                 status = U_ZERO_ERROR;
    484             } else if ( u_strstr(strDateTime, newTimePatn) == NULL ) {
    485                 log_err("udat_applyPatternRelative timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) didn't update time pattern\n", *stylePtr );
    486             }
    487         }
    488         udat_applyPatternRelative(fmtRelDateTime, strDate, u_strlen(strDate), strTime, u_strlen(strTime), &status); /* restore original */
    489 
    490         fp.field = UDAT_MINUTE_FIELD;
    491         for (dayOffset = -2, limit = 2; dayOffset <= limit; ++dayOffset) {
    492             UDate   dateToUse = today + (float)dayOffset*dayInterval;
    493 
    494             udat_format(fmtRelDateTime, dateToUse, strDateTime, kDateAndTimeOutMax, &fp, &status);
    495             if ( U_FAILURE(status) ) {
    496                 log_err("udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
    497                 status = U_ZERO_ERROR;
    498             } else {
    499                 int32_t parsePos = 0;
    500                 UDate dateResult = udat_parse(fmtRelDateTime, strDateTime, -1, &parsePos, &status);
    501                 UDate dateDiff =  (dateResult >= dateToUse)? dateResult - dateToUse: dateToUse - dateResult;
    502                 if ( U_FAILURE(status) || dateDiff > minutesTolerance ) {
    503                     log_err("udat_parse timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s, expect approx %.1f, got %.1f, parsePos %d\n",
    504                             *stylePtr, myErrorName(status), dateToUse, dateResult, parsePos );
    505                     status = U_ZERO_ERROR;
    506                 }
    507 
    508                 udat_format(fmtRelDate, dateToUse, strDate, kDateOrTimeOutMax, NULL, &status);
    509                 if ( U_FAILURE(status) ) {
    510                     log_err("udat_format timeStyle NONE dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
    511                     status = U_ZERO_ERROR;
    512                 } else if ( u_strstr(strDateTime, strDate) == NULL ) {
    513                     log_err("relative date string not found in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", *stylePtr );
    514                 } else {
    515                     parsePos = 0;
    516                     dateResult = udat_parse(fmtRelDate, strDate, -1, &parsePos, &status);
    517                     dateDiff =  (dateResult >= dateToUse)? dateResult - dateToUse: dateToUse - dateResult;
    518                     if ( U_FAILURE(status) || dateDiff > daysTolerance ) {
    519                         log_err("udat_parse timeStyle NONE dateStyle (%d | UDAT_RELATIVE) fails, error %s, expect approx %.1f, got %.1f, parsePos %d\n",
    520                                 *stylePtr, myErrorName(status), dateToUse, dateResult, parsePos );
    521                         status = U_ZERO_ERROR;
    522                     }
    523                 }
    524 
    525                 udat_format(fmtTime, dateToUse, strTime, kDateOrTimeOutMax, NULL, &status);
    526                 if ( U_FAILURE(status) ) {
    527                     log_err("udat_format timeStyle SHORT dateStyle NONE fails, error %s\n", myErrorName(status) );
    528                     status = U_ZERO_ERROR;
    529                 } else if ( u_strstr(strDateTime, strTime) == NULL ) {
    530                     log_err("time string not found in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", *stylePtr );
    531                 }
    532 
    533                 strPtr = u_strstr(strDateTime, minutesStr);
    534                 if ( strPtr != NULL ) {
    535                     int32_t beginIndex = strPtr - strDateTime;
    536                     if ( fp.beginIndex != beginIndex ) {
    537                         log_err("UFieldPosition beginIndex %d, expected %d, in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", fp.beginIndex, beginIndex, *stylePtr );
    538                     }
    539                 } else {
    540                     log_err("minutes string not found in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", *stylePtr );
    541                 }
    542             }
    543         }
    544 
    545         udat_close(fmtRelDateTime);
    546         udat_close(fmtRelDate);
    547         udat_close(fmtTime);
    548      }
    549 }
    550 
    551 /*Testing udat_getSymbols() and udat_setSymbols() and udat_countSymbols()*/
    552 static void TestSymbols()
    553 {
    554     UDateFormat *def, *fr;
    555     UErrorCode status = U_ZERO_ERROR;
    556     UChar *value=NULL;
    557     UChar *result = NULL;
    558     int32_t resultlength;
    559     int32_t resultlengthout;
    560     UChar *pattern;
    561 
    562 
    563     /*creating a dateformat with french locale */
    564     log_verbose("\ncreating a date format with french locale\n");
    565     fr = udat_open(UDAT_FULL, UDAT_DEFAULT, "fr_FR", NULL, 0, NULL, 0, &status);
    566     if(U_FAILURE(status))
    567     {
    568         log_data_err("error in creating the dateformat using full time style with french locale -> %s (Are you missing data?)\n",
    569             myErrorName(status) );
    570         return;
    571     }
    572     /*creating a default dateformat */
    573     log_verbose("\ncreating a date format with default locale\n");
    574     /* this is supposed to open default date format, but later on it treats it like it is "en_US"
    575        - very bad if you try to run the tests on machine where default locale is NOT "en_US" */
    576     /* def = udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,NULL, NULL, 0, &status); */
    577     def = udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,"en_US", NULL, 0, NULL, 0, &status);
    578     if(U_FAILURE(status))
    579     {
    580         log_err("error in creating the dateformat using short date and time style\n %s\n",
    581             myErrorName(status) );
    582         return;
    583     }
    584 
    585 
    586     /*Testing countSymbols, getSymbols and setSymbols*/
    587     log_verbose("\nTesting countSymbols\n");
    588     /*since the month names has the last string empty and week names are 1 based 1.e first string in the weeknames array is empty */
    589     if(udat_countSymbols(def, UDAT_ERAS)!=2 || udat_countSymbols(def, UDAT_MONTHS)!=12 ||
    590         udat_countSymbols(def, UDAT_SHORT_MONTHS)!=12 || udat_countSymbols(def, UDAT_WEEKDAYS)!=8 ||
    591         udat_countSymbols(def, UDAT_SHORT_WEEKDAYS)!=8 || udat_countSymbols(def, UDAT_AM_PMS)!=2 ||
    592         udat_countSymbols(def, UDAT_QUARTERS) != 4 || udat_countSymbols(def, UDAT_SHORT_QUARTERS) != 4 ||
    593         udat_countSymbols(def, UDAT_LOCALIZED_CHARS)!=1)
    594     {
    595         log_err("FAIL: error in udat_countSymbols\n");
    596     }
    597     else
    598         log_verbose("PASS: udat_countSymbols() successful\n");
    599 
    600     /*testing getSymbols*/
    601     log_verbose("\nTesting getSymbols\n");
    602     pattern=(UChar*)malloc(sizeof(UChar) * 10);
    603     u_uastrcpy(pattern, "jeudi");
    604     resultlength=0;
    605     resultlengthout=udat_getSymbols(fr, UDAT_WEEKDAYS, 5 , NULL, resultlength, &status);
    606     if(status==U_BUFFER_OVERFLOW_ERROR)
    607     {
    608         status=U_ZERO_ERROR;
    609         resultlength=resultlengthout+1;
    610         if(result != NULL) {
    611             free(result);
    612             result = NULL;
    613         }
    614         result=(UChar*)malloc(sizeof(UChar) * resultlength);
    615         udat_getSymbols(fr, UDAT_WEEKDAYS, 5, result, resultlength, &status);
    616 
    617     }
    618     if(U_FAILURE(status))
    619     {
    620         log_err("FAIL: Error in udat_getSymbols().... %s\n", myErrorName(status) );
    621     }
    622     else
    623         log_verbose("PASS: getSymbols succesful\n");
    624 
    625     if(u_strcmp(result, pattern)==0)
    626         log_verbose("PASS: getSymbols retrieved the right value\n");
    627     else
    628         log_data_err("FAIL: getSymbols retrieved the wrong value\n");
    629 
    630     /*run series of tests to test getsymbols regressively*/
    631     log_verbose("\nTesting getSymbols() regressively\n");
    632     VerifygetSymbols(fr, UDAT_WEEKDAYS, 1, "dimanche");
    633     VerifygetSymbols(def, UDAT_WEEKDAYS, 1, "Sunday");
    634     VerifygetSymbols(fr, UDAT_SHORT_WEEKDAYS, 7, "sam.");
    635     VerifygetSymbols(def, UDAT_SHORT_WEEKDAYS, 7, "Sat");
    636     VerifygetSymbols(def, UDAT_MONTHS, 11, "December");
    637     VerifygetSymbols(def, UDAT_MONTHS, 0, "January");
    638     VerifygetSymbols(fr, UDAT_ERAS, 0, "av. J.-C.");
    639     VerifygetSymbols(def, UDAT_AM_PMS, 0, "AM");
    640     VerifygetSymbols(def, UDAT_AM_PMS, 1, "PM");
    641     VerifygetSymbols(fr, UDAT_SHORT_MONTHS, 0, "janv.");
    642     VerifygetSymbols(def, UDAT_SHORT_MONTHS, 11, "Dec");
    643     VerifygetSymbols(fr, UDAT_QUARTERS, 0, "1er trimestre");
    644     VerifygetSymbols(def, UDAT_QUARTERS, 3, "4th quarter");
    645     VerifygetSymbols(fr, UDAT_SHORT_QUARTERS, 1, "T2");
    646     VerifygetSymbols(def, UDAT_SHORT_QUARTERS, 2, "Q3");
    647     VerifygetSymbols(def,UDAT_LOCALIZED_CHARS, 0, "GyMdkHmsSEDFwWahKzYeugAZvcLQqVU");
    648 
    649 
    650     if(result != NULL) {
    651         free(result);
    652         result = NULL;
    653     }
    654 free(pattern);
    655 
    656     log_verbose("\nTesting setSymbols\n");
    657     /*applying the pattern so that setSymbolss works */
    658     resultlength=0;
    659     resultlengthout=udat_toPattern(fr, FALSE, NULL, resultlength, &status);
    660     if(status==U_BUFFER_OVERFLOW_ERROR)
    661     {
    662         status=U_ZERO_ERROR;
    663         resultlength=resultlengthout + 1;
    664         pattern=(UChar*)malloc(sizeof(UChar) * resultlength);
    665         udat_toPattern(fr, FALSE, pattern, resultlength, &status);
    666     }
    667     if(U_FAILURE(status))
    668     {
    669         log_err("FAIL: error in extracting the pattern from UNumberFormat\n %s\n",
    670             myErrorName(status) );
    671     }
    672 
    673     udat_applyPattern(def, FALSE, pattern, u_strlen(pattern));
    674     resultlength=0;
    675     resultlengthout=udat_toPattern(def, FALSE, NULL, resultlength,&status);
    676     if(status==U_BUFFER_OVERFLOW_ERROR)
    677     {
    678         status=U_ZERO_ERROR;
    679         resultlength=resultlengthout + 1;
    680         if(result != NULL) {
    681             free(result);
    682             result = NULL;
    683         }
    684         result=(UChar*)malloc(sizeof(UChar) * resultlength);
    685         udat_toPattern(fr, FALSE,result, resultlength, &status);
    686     }
    687     if(U_FAILURE(status))
    688     {
    689         log_err("FAIL: error in extracting the pattern from UNumberFormat\n %s\n",
    690             myErrorName(status) );
    691     }
    692     if(u_strcmp(result, pattern)==0)
    693         log_verbose("Pattern applied properly\n");
    694     else
    695         log_err("pattern could not be applied properly\n");
    696 
    697 free(pattern);
    698     /*testing set symbols */
    699     resultlength=0;
    700     resultlengthout=udat_getSymbols(fr, UDAT_MONTHS, 11 , NULL, resultlength, &status);
    701     if(status==U_BUFFER_OVERFLOW_ERROR){
    702         status=U_ZERO_ERROR;
    703         resultlength=resultlengthout+1;
    704         if(result != NULL) {
    705             free(result);
    706             result = NULL;
    707         }
    708         result=(UChar*)malloc(sizeof(UChar) * resultlength);
    709         udat_getSymbols(fr, UDAT_MONTHS, 11, result, resultlength, &status);
    710 
    711     }
    712     if(U_FAILURE(status))
    713         log_err("FAIL: error in getSymbols() %s\n", myErrorName(status) );
    714     resultlength=resultlengthout+1;
    715 
    716     udat_setSymbols(def, UDAT_MONTHS, 11, result, resultlength, &status);
    717     if(U_FAILURE(status))
    718         {
    719             log_err("FAIL: Error in udat_setSymbols() : %s\n", myErrorName(status) );
    720         }
    721     else
    722         log_verbose("PASS: SetSymbols successful\n");
    723 
    724     resultlength=0;
    725     resultlengthout=udat_getSymbols(def, UDAT_MONTHS, 11, NULL, resultlength, &status);
    726     if(status==U_BUFFER_OVERFLOW_ERROR){
    727         status=U_ZERO_ERROR;
    728         resultlength=resultlengthout+1;
    729         value=(UChar*)malloc(sizeof(UChar) * resultlength);
    730         udat_getSymbols(def, UDAT_MONTHS, 11, value, resultlength, &status);
    731     }
    732     if(U_FAILURE(status))
    733         log_err("FAIL: error in retrieving the value using getSymbols i.e roundtrip\n");
    734 
    735     if(u_strcmp(result, value)!=0)
    736         log_data_err("FAIL: Error in settting and getting symbols\n");
    737     else
    738         log_verbose("PASS: setSymbols successful\n");
    739 
    740 
    741     /*run series of tests to test setSymbols regressively*/
    742     log_verbose("\nTesting setSymbols regressively\n");
    743     VerifysetSymbols(def, UDAT_ERAS, 0, "BeforeChrist");
    744     VerifysetSymbols(def, UDAT_ERA_NAMES, 1, "AnnoDomini");
    745     VerifysetSymbols(def, UDAT_WEEKDAYS, 1, "Sundayweek");
    746     VerifysetSymbols(def, UDAT_SHORT_WEEKDAYS, 7, "Satweek");
    747     VerifysetSymbols(def, UDAT_NARROW_WEEKDAYS, 4, "M");
    748     VerifysetSymbols(def, UDAT_STANDALONE_WEEKDAYS, 1, "Sonntagweek");
    749     VerifysetSymbols(def, UDAT_STANDALONE_SHORT_WEEKDAYS, 7, "Sams");
    750     VerifysetSymbols(def, UDAT_STANDALONE_NARROW_WEEKDAYS, 4, "V");
    751     VerifysetSymbols(fr, UDAT_MONTHS, 11, "december");
    752     VerifysetSymbols(fr, UDAT_SHORT_MONTHS, 0, "Jan");
    753     VerifysetSymbols(fr, UDAT_NARROW_MONTHS, 1, "R");
    754     VerifysetSymbols(fr, UDAT_STANDALONE_MONTHS, 11, "dezember");
    755     VerifysetSymbols(fr, UDAT_STANDALONE_SHORT_MONTHS, 7, "Aug");
    756     VerifysetSymbols(fr, UDAT_STANDALONE_NARROW_MONTHS, 2, "M");
    757     VerifysetSymbols(fr, UDAT_QUARTERS, 0, "1. Quart");
    758     VerifysetSymbols(fr, UDAT_SHORT_QUARTERS, 1, "QQ2");
    759     VerifysetSymbols(fr, UDAT_STANDALONE_QUARTERS, 2, "3rd Quar.");
    760     VerifysetSymbols(fr, UDAT_STANDALONE_SHORT_QUARTERS, 3, "4QQ");
    761 
    762 
    763     /*run series of tests to test get and setSymbols regressively*/
    764     log_verbose("\nTesting get and set symbols regressively\n");
    765     VerifygetsetSymbols(fr, def, UDAT_WEEKDAYS, 1);
    766     VerifygetsetSymbols(fr, def, UDAT_WEEKDAYS, 7);
    767     VerifygetsetSymbols(fr, def, UDAT_SHORT_WEEKDAYS, 1);
    768     VerifygetsetSymbols(fr, def, UDAT_SHORT_WEEKDAYS, 7);
    769     VerifygetsetSymbols(fr, def, UDAT_MONTHS, 0);
    770     VerifygetsetSymbols(fr, def, UDAT_SHORT_MONTHS, 0);
    771     VerifygetsetSymbols(fr, def, UDAT_ERAS,1);
    772     VerifygetsetSymbols(fr, def, UDAT_LOCALIZED_CHARS, 0);
    773     VerifygetsetSymbols(fr, def, UDAT_AM_PMS, 1);
    774 
    775 
    776     /*closing*/
    777 
    778     udat_close(fr);
    779     udat_close(def);
    780     if(result != NULL) {
    781         free(result);
    782         result = NULL;
    783     }
    784     free(value);
    785 
    786 }
    787 
    788 /**
    789  * Test DateFormat(Calendar) API
    790  */
    791 static void TestDateFormatCalendar() {
    792     UDateFormat *date=0, *time=0, *full=0;
    793     UCalendar *cal=0;
    794     UChar buf[256];
    795     char cbuf[256];
    796     int32_t pos;
    797     UDate when;
    798     UErrorCode ec = U_ZERO_ERROR;
    799 
    800     ctest_setTimeZone(NULL, &ec);
    801 
    802     /* Create a formatter for date fields. */
    803     date = udat_open(UDAT_NONE, UDAT_SHORT, "en_US", NULL, 0, NULL, 0, &ec);
    804     if (U_FAILURE(ec)) {
    805         log_data_err("FAIL: udat_open(NONE, SHORT, en_US) failed with %s (Are you missing data?)\n",
    806                 u_errorName(ec));
    807         goto FAIL;
    808     }
    809 
    810     /* Create a formatter for time fields. */
    811     time = udat_open(UDAT_SHORT, UDAT_NONE, "en_US", NULL, 0, NULL, 0, &ec);
    812     if (U_FAILURE(ec)) {
    813         log_err("FAIL: udat_open(SHORT, NONE, en_US) failed with %s\n",
    814                 u_errorName(ec));
    815         goto FAIL;
    816     }
    817 
    818     /* Create a full format for output */
    819     full = udat_open(UDAT_FULL, UDAT_FULL, "en_US", NULL, 0, NULL, 0, &ec);
    820     if (U_FAILURE(ec)) {
    821         log_err("FAIL: udat_open(FULL, FULL, en_US) failed with %s\n",
    822                 u_errorName(ec));
    823         goto FAIL;
    824     }
    825 
    826     /* Create a calendar */
    827     cal = ucal_open(NULL, 0, "en_US", UCAL_GREGORIAN, &ec);
    828     if (U_FAILURE(ec)) {
    829         log_err("FAIL: ucal_open(en_US) failed with %s\n",
    830                 u_errorName(ec));
    831         goto FAIL;
    832     }
    833 
    834     /* Parse the date */
    835     ucal_clear(cal);
    836     u_uastrcpy(buf, "4/5/2001");
    837     pos = 0;
    838     udat_parseCalendar(date, cal, buf, -1, &pos, &ec);
    839     if (U_FAILURE(ec)) {
    840         log_err("FAIL: udat_parseCalendar(4/5/2001) failed at %d with %s\n",
    841                 pos, u_errorName(ec));
    842         goto FAIL;
    843     }
    844 
    845     /* Parse the time */
    846     u_uastrcpy(buf, "5:45 PM");
    847     pos = 0;
    848     udat_parseCalendar(time, cal, buf, -1, &pos, &ec);
    849     if (U_FAILURE(ec)) {
    850         log_err("FAIL: udat_parseCalendar(17:45) failed at %d with %s\n",
    851                 pos, u_errorName(ec));
    852         goto FAIL;
    853     }
    854 
    855     /* Check result */
    856     when = ucal_getMillis(cal, &ec);
    857     if (U_FAILURE(ec)) {
    858         log_err("FAIL: ucal_getMillis() failed with %s\n", u_errorName(ec));
    859         goto FAIL;
    860     }
    861     udat_format(full, when, buf, sizeof(buf), NULL, &ec);
    862     if (U_FAILURE(ec)) {
    863         log_err("FAIL: udat_format() failed with %s\n", u_errorName(ec));
    864         goto FAIL;
    865     }
    866     u_austrcpy(cbuf, buf);
    867     /* Thursday, April 5, 2001 5:45:00 PM PDT 986517900000 */
    868     if (when == 986517900000.0) {
    869         log_verbose("Ok: Parsed result: %s\n", cbuf);
    870     } else {
    871         log_err("FAIL: Parsed result: %s, exp 4/5/2001 5:45 PM\n", cbuf);
    872     }
    873 
    874  FAIL:
    875     udat_close(date);
    876     udat_close(time);
    877     udat_close(full);
    878     ucal_close(cal);
    879 
    880     ctest_resetTimeZone();
    881 }
    882 
    883 /*INTERNAL FUNCTIONS USED*/
    884 /* N.B.:  use idx instead of index to avoid 'shadow' warnings in strict mode. */
    885 static void VerifygetSymbols(UDateFormat* datfor, UDateFormatSymbolType type, int32_t idx, const char* expected)
    886 {
    887     UChar *pattern=NULL;
    888     UErrorCode status = U_ZERO_ERROR;
    889     UChar *result=NULL;
    890     int32_t resultlength, resultlengthout;
    891 
    892 
    893     pattern=(UChar*)malloc(sizeof(UChar) * (strlen(expected)+1));
    894     u_uastrcpy(pattern, expected);
    895     resultlength=0;
    896     resultlengthout=udat_getSymbols(datfor, type, idx , NULL, resultlength, &status);
    897     if(status==U_BUFFER_OVERFLOW_ERROR)
    898     {
    899         status=U_ZERO_ERROR;
    900         resultlength=resultlengthout+1;
    901         result=(UChar*)malloc(sizeof(UChar) * resultlength);
    902         udat_getSymbols(datfor, type, idx, result, resultlength, &status);
    903 
    904     }
    905     if(U_FAILURE(status))
    906     {
    907         log_err("FAIL: Error in udat_getSymbols()... %s\n", myErrorName(status) );
    908         return;
    909     }
    910     if(u_strcmp(result, pattern)==0)
    911         log_verbose("PASS: getSymbols retrieved the right value\n");
    912     else{
    913         log_data_err("FAIL: getSymbols retrieved the wrong value\n Expected %s Got %s\n", austrdup(pattern),
    914             austrdup(result) );
    915     }
    916     free(result);
    917     free(pattern);
    918 }
    919 
    920 static void VerifysetSymbols(UDateFormat* datfor, UDateFormatSymbolType type, int32_t idx, const char* expected)
    921 {
    922     UChar *result=NULL;
    923     UChar *value=NULL;
    924     int32_t resultlength, resultlengthout;
    925     UErrorCode status = U_ZERO_ERROR;
    926 
    927     value=(UChar*)malloc(sizeof(UChar) * (strlen(expected) + 1));
    928     u_uastrcpy(value, expected);
    929     udat_setSymbols(datfor, type, idx, value, u_strlen(value), &status);
    930     if(U_FAILURE(status))
    931         {
    932             log_err("FAIL: Error in udat_setSymbols()  %s\n", myErrorName(status) );
    933             return;
    934         }
    935 
    936     resultlength=0;
    937     resultlengthout=udat_getSymbols(datfor, type, idx, NULL, resultlength, &status);
    938     if(status==U_BUFFER_OVERFLOW_ERROR){
    939         status=U_ZERO_ERROR;
    940         resultlength=resultlengthout+1;
    941         result=(UChar*)malloc(sizeof(UChar) * resultlength);
    942         udat_getSymbols(datfor, type, idx, result, resultlength, &status);
    943     }
    944     if(U_FAILURE(status)){
    945         log_err("FAIL: error in retrieving the value using getSymbols after setting it previously\n %s\n",
    946             myErrorName(status) );
    947         return;
    948     }
    949 
    950     if(u_strcmp(result, value)!=0){
    951         log_err("FAIL:Error in setting and then getting symbols\n Expected %s Got %s\n", austrdup(value),
    952             austrdup(result) );
    953     }
    954     else
    955         log_verbose("PASS: setSymbols successful\n");
    956 
    957     free(value);
    958     free(result);
    959 }
    960 
    961 
    962 static void VerifygetsetSymbols(UDateFormat* from, UDateFormat* to, UDateFormatSymbolType type, int32_t idx)
    963 {
    964     UChar *result=NULL;
    965     UChar *value=NULL;
    966     int32_t resultlength, resultlengthout;
    967     UErrorCode status = U_ZERO_ERROR;
    968 
    969     resultlength=0;
    970     resultlengthout=udat_getSymbols(from, type, idx , NULL, resultlength, &status);
    971     if(status==U_BUFFER_OVERFLOW_ERROR){
    972         status=U_ZERO_ERROR;
    973         resultlength=resultlengthout+1;
    974         result=(UChar*)malloc(sizeof(UChar) * resultlength);
    975         udat_getSymbols(from, type, idx, result, resultlength, &status);
    976     }
    977     if(U_FAILURE(status)){
    978         log_err("FAIL: error in getSymbols() %s\n", myErrorName(status) );
    979         return;
    980     }
    981 
    982     resultlength=resultlengthout+1;
    983     udat_setSymbols(to, type, idx, result, resultlength, &status);
    984     if(U_FAILURE(status))
    985         {
    986             log_err("FAIL: Error in udat_setSymbols() : %s\n", myErrorName(status) );
    987             return;
    988         }
    989 
    990     resultlength=0;
    991     resultlengthout=udat_getSymbols(to, type, idx, NULL, resultlength, &status);
    992     if(status==U_BUFFER_OVERFLOW_ERROR){
    993         status=U_ZERO_ERROR;
    994         resultlength=resultlengthout+1;
    995         value=(UChar*)malloc(sizeof(UChar) * resultlength);
    996         udat_getSymbols(to, type, idx, value, resultlength, &status);
    997     }
    998     if(U_FAILURE(status)){
    999         log_err("FAIL: error in retrieving the value using getSymbols i.e roundtrip\n %s\n",
   1000             myErrorName(status) );
   1001         return;
   1002     }
   1003 
   1004     if(u_strcmp(result, value)!=0){
   1005         log_data_err("FAIL:Error in setting and then getting symbols\n Expected %s Got %s\n", austrdup(result),
   1006             austrdup(value) );
   1007     }
   1008     else
   1009         log_verbose("PASS: setSymbols successful\n");
   1010 
   1011     free(value);
   1012     free(result);
   1013 }
   1014 
   1015 
   1016 static UChar* myNumformat(const UNumberFormat* numfor, double d)
   1017 {
   1018     UChar *result2=NULL;
   1019     int32_t resultlength, resultlengthneeded;
   1020     UErrorCode status = U_ZERO_ERROR;
   1021 
   1022     resultlength=0;
   1023     resultlengthneeded=unum_formatDouble(numfor, d, NULL, resultlength, NULL, &status);
   1024     if(status==U_BUFFER_OVERFLOW_ERROR)
   1025     {
   1026         status=U_ZERO_ERROR;
   1027         resultlength=resultlengthneeded+1;
   1028         /*result2=(UChar*)malloc(sizeof(UChar) * resultlength);*/ /* this leaks */
   1029         result2=(UChar*)ctst_malloc(sizeof(UChar) * resultlength); /*this won't*/
   1030         unum_formatDouble(numfor, d, result2, resultlength, NULL, &status);
   1031     }
   1032     if(U_FAILURE(status))
   1033     {
   1034         log_err("FAIL: Error in formatting using unum_format(.....) %s\n", myErrorName(status) );
   1035         return 0;
   1036     }
   1037 
   1038     return result2;
   1039 }
   1040 
   1041 /**
   1042  * The search depth for TestExtremeDates.  The total number of
   1043  * dates that will be tested is (2^EXTREME_DATES_DEPTH) - 1.
   1044  */
   1045 #define EXTREME_DATES_DEPTH 8
   1046 
   1047 /**
   1048  * Support for TestExtremeDates (below).
   1049  *
   1050  * Test a single date to see whether udat_format handles it properly.
   1051  */
   1052 static UBool _aux1ExtremeDates(UDateFormat* fmt, UDate date,
   1053                                UChar* buf, int32_t buflen, char* cbuf,
   1054                                UErrorCode* ec) {
   1055     int32_t len = udat_format(fmt, date, buf, buflen, 0, ec);
   1056     if (!assertSuccess("udat_format", ec)) return FALSE;
   1057     u_austrncpy(cbuf, buf, buflen);
   1058     if (len < 4) {
   1059         log_err("FAIL: udat_format(%g) => \"%s\"\n", date, cbuf);
   1060     } else {
   1061         log_verbose("udat_format(%g) => \"%s\"\n", date, cbuf);
   1062     }
   1063     return TRUE;
   1064 }
   1065 
   1066 /**
   1067  * Support for TestExtremeDates (below).
   1068  *
   1069  * Recursively test between 'small' and 'large', up to the depth
   1070  * limit specified by EXTREME_DATES_DEPTH.
   1071  */
   1072 static UBool _aux2ExtremeDates(UDateFormat* fmt, UDate small, UDate large,
   1073                                UChar* buf, int32_t buflen, char* cbuf,
   1074                                int32_t count,
   1075                                UErrorCode* ec) {
   1076     /* Logarithmic midpoint; see below */
   1077     UDate mid = (UDate) exp((log(small) + log(large)) / 2);
   1078     if (count == EXTREME_DATES_DEPTH) {
   1079         return TRUE;
   1080     }
   1081     return
   1082         _aux1ExtremeDates(fmt, mid, buf, buflen, cbuf, ec) &&
   1083         _aux2ExtremeDates(fmt, small, mid, buf, buflen, cbuf, count+1, ec) &&
   1084         _aux2ExtremeDates(fmt, mid, large, buf, buflen, cbuf, count+1, ec);
   1085 }
   1086 
   1087 /**
   1088  * http://www.jtcsv.com/cgibin/icu-bugs?findid=3659
   1089  *
   1090  * For certain large dates, udat_format crashes on MacOS.  This test
   1091  * attempts to reproduce this problem by doing a recursive logarithmic*
   1092  * binary search of a predefined interval (from 'small' to 'large').
   1093  *
   1094  * The limit of the search is given by EXTREME_DATES_DEPTH, above.
   1095  *
   1096  * *The search has to be logarithmic, not linear.  A linear search of the
   1097  *  range 0..10^30, for example, will find 0.5*10^30, then 0.25*10^30 and
   1098  *  0.75*10^30, etc.  A logarithmic search will find 10^15, then 10^7.5
   1099  *  and 10^22.5, etc.
   1100  */
   1101 static void TestExtremeDates() {
   1102     UDateFormat *fmt;
   1103     UErrorCode ec;
   1104     UChar buf[256];
   1105     char cbuf[256];
   1106     const double small = 1000; /* 1 sec */
   1107     const double large = 1e+30; /* well beyond usable UDate range */
   1108 
   1109     /* There is no need to test larger values from 1e+30 to 1e+300;
   1110        the failures occur around 1e+27, and never above 1e+30. */
   1111 
   1112     ec = U_ZERO_ERROR;
   1113     fmt = udat_open(UDAT_LONG, UDAT_LONG, "en_US",
   1114                     0, 0, 0, 0, &ec);
   1115     if (U_FAILURE(ec)) {
   1116         log_data_err("FAIL: udat_open (%s) (Are you missing data?)\n", u_errorName(ec));
   1117         return;
   1118     }
   1119 
   1120     _aux2ExtremeDates(fmt, small, large, buf, LEN(buf), cbuf, 0, &ec);
   1121 
   1122     udat_close(fmt);
   1123 }
   1124 
   1125 static void TestAllLocales(void) {
   1126     int32_t idx, dateIdx, timeIdx, localeCount;
   1127     static const UDateFormatStyle style[] = {
   1128         UDAT_FULL, UDAT_LONG, UDAT_MEDIUM, UDAT_SHORT
   1129     };
   1130     localeCount = uloc_countAvailable();
   1131     for (idx = 0; idx < localeCount; idx++) {
   1132         for (dateIdx = 0; dateIdx < (int32_t)(sizeof(style)/sizeof(style[0])); dateIdx++) {
   1133             for (timeIdx = 0; timeIdx < (int32_t)(sizeof(style)/sizeof(style[0])); timeIdx++) {
   1134                 UErrorCode status = U_ZERO_ERROR;
   1135                 udat_close(udat_open(style[dateIdx], style[timeIdx],
   1136                     uloc_getAvailable(idx), NULL, 0, NULL, 0, &status));
   1137                 if (U_FAILURE(status)) {
   1138                     log_err("FAIL: udat_open(%s) failed with (%s) dateIdx=%d, timeIdx=%d\n",
   1139                         uloc_getAvailable(idx), u_errorName(status), dateIdx, timeIdx);
   1140                 }
   1141             }
   1142         }
   1143     }
   1144 }
   1145 
   1146 static void TestRelativeCrash(void) {
   1147        static const UChar tzName[] = { 0x0055, 0x0053, 0x002F, 0x0050, 0x0061, 0x0063, 0x0069, 0x0066, 0x0069, 0x0063, 0 };
   1148        static const UDate aDate = -631152000000.0;
   1149 
   1150     UErrorCode status = U_ZERO_ERROR;
   1151     UErrorCode expectStatus = U_ILLEGAL_ARGUMENT_ERROR;
   1152     UDateFormat icudf;
   1153 
   1154     icudf = udat_open(UDAT_NONE, UDAT_SHORT_RELATIVE, "en", tzName, -1, NULL, 0, &status);
   1155     if ( U_SUCCESS(status) ) {
   1156         const char *what = "???";
   1157         {
   1158             UErrorCode subStatus = U_ZERO_ERROR;
   1159             what = "udat_set2DigitYearStart";
   1160             log_verbose("Trying %s on a relative date..\n", what);
   1161             udat_set2DigitYearStart(icudf, aDate, &subStatus);
   1162             if(subStatus == expectStatus) {
   1163                 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
   1164             } else {
   1165                 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
   1166             }
   1167         }
   1168         {
   1169             /* clone works polymorphically. try it anyways */
   1170             UErrorCode subStatus = U_ZERO_ERROR;
   1171             UDateFormat *oth;
   1172             what = "clone";
   1173             log_verbose("Trying %s on a relative date..\n", what);
   1174             oth = udat_clone(icudf, &subStatus);
   1175             if(subStatus == U_ZERO_ERROR) {
   1176                 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
   1177                 udat_close(oth); /* ? */
   1178             } else {
   1179                 log_err("FAIL: didn't crash on %s, but got  %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
   1180             }
   1181         }
   1182         {
   1183             UErrorCode subStatus = U_ZERO_ERROR;
   1184             what = "udat_get2DigitYearStart";
   1185             log_verbose("Trying %s on a relative date..\n", what);
   1186             udat_get2DigitYearStart(icudf, &subStatus);
   1187             if(subStatus == expectStatus) {
   1188                 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
   1189             } else {
   1190                 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
   1191             }
   1192         }
   1193         {
   1194             /* Now udat_toPattern works for relative date formatters, unless localized is TRUE */
   1195             UErrorCode subStatus = U_ZERO_ERROR;
   1196             what = "udat_toPattern";
   1197             log_verbose("Trying %s on a relative date..\n", what);
   1198             udat_toPattern(icudf, TRUE,NULL,0, &subStatus);
   1199             if(subStatus == expectStatus) {
   1200                 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
   1201             } else {
   1202                 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
   1203             }
   1204         }
   1205         {
   1206             UErrorCode subStatus = U_ZERO_ERROR;
   1207             what = "udat_applyPattern";
   1208             log_verbose("Trying %s on a relative date..\n", what);
   1209             udat_applyPattern(icudf, FALSE,tzName,-1);
   1210             subStatus = U_ILLEGAL_ARGUMENT_ERROR; /* what it should be, if this took an errorcode. */
   1211             if(subStatus == expectStatus) {
   1212                 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
   1213             } else {
   1214                 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
   1215             }
   1216         }
   1217         {
   1218             UChar erabuf[32];
   1219             UErrorCode subStatus = U_ZERO_ERROR;
   1220             what = "udat_getSymbols";
   1221             log_verbose("Trying %s on a relative date..\n", what);
   1222             udat_getSymbols(icudf, UDAT_ERAS,0,erabuf,sizeof(erabuf)/sizeof(erabuf[0]), &subStatus);
   1223             if(subStatus == U_ZERO_ERROR) {
   1224                 log_verbose("Success: %s returned %s.\n", what, u_errorName(subStatus));
   1225             } else {
   1226                 log_err("FAIL: didn't crash on %s, but got %s instead of U_ZERO_ERROR.\n", what, u_errorName(subStatus));
   1227             }
   1228         }
   1229         {
   1230             UErrorCode subStatus = U_ZERO_ERROR;
   1231             UChar symbolValue = 0x0041;
   1232             what = "udat_setSymbols";
   1233             log_verbose("Trying %s on a relative date..\n", what);
   1234             udat_setSymbols(icudf, UDAT_ERAS,0,&symbolValue,1, &subStatus);  /* bogus values */
   1235             if(subStatus == expectStatus) {
   1236                 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
   1237             } else {
   1238                 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
   1239             }
   1240         }
   1241         {
   1242             UErrorCode subStatus = U_ZERO_ERROR;
   1243             what = "udat_countSymbols";
   1244             log_verbose("Trying %s on a relative date..\n", what);
   1245             udat_countSymbols(icudf, UDAT_ERAS);
   1246             subStatus = U_ILLEGAL_ARGUMENT_ERROR; /* should have an errorcode. */
   1247             if(subStatus == expectStatus) {
   1248                 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
   1249             } else {
   1250                 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
   1251             }
   1252         }
   1253 
   1254         udat_close(icudf);
   1255     } else {
   1256          log_data_err("FAIL: err calling udat_open() ->%s (Are you missing data?)\n", u_errorName(status));
   1257     }
   1258 }
   1259 
   1260 static const UChar skeleton_yMMMM[] = { 0x79,0x4D,0x4D,0x4D,0x4D,0 }; /* "yMMMM"; fr maps to "MMMM y", cs maps to "LLLL y" */
   1261 static const UChar july2008_frDefault[] = { 0x6A,0x75,0x69,0x6C,0x6C,0x65,0x74,0x20,0x32,0x30,0x30,0x38,0 }; /* "juillet 2008" */
   1262 static const UChar july2008_frTitle[] = { 0x4A,0x75,0x69,0x6C,0x6C,0x65,0x74,0x20,0x32,0x30,0x30,0x38,0 };  /* "Juillet 2008" sentence-begin, standalone */
   1263 static const UChar july2008_csDefault[] = { 0x10D,0x65,0x72,0x76,0x65,0x6E,0x65,0x63,0x20,0x32,0x30,0x30,0x38,0 }; /* "c(hacek)ervenec 2008" */
   1264 static const UChar july2008_csTitle[] = { 0x10C,0x65,0x72,0x76,0x65,0x6E,0x65,0x63,0x20,0x32,0x30,0x30,0x38,0 }; /* "C(hacek)ervenec 2008" sentence-begin, uiListOrMenu */
   1265 
   1266 typedef struct {
   1267     const char * locale;
   1268     const UChar * skeleton;
   1269     UDisplayContext capitalizationContext;
   1270     const UChar * expectedFormat;
   1271 } TestContextItem;
   1272 
   1273 static const TestContextItem textContextItems[] = {
   1274     { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_NONE,                   july2008_frDefault },
   1275 #if !UCONFIG_NO_BREAK_ITERATION
   1276     { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, july2008_frDefault },
   1277     { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, july2008_frTitle },
   1278     { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU,    july2008_frDefault },
   1279     { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_STANDALONE,         july2008_frTitle },
   1280 #endif
   1281     { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_NONE,                   july2008_csDefault },
   1282 #if !UCONFIG_NO_BREAK_ITERATION
   1283     { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, july2008_csDefault },
   1284     { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, july2008_csTitle },
   1285     { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU,    july2008_csTitle },
   1286     { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_STANDALONE,         july2008_csDefault },
   1287 #endif
   1288     { NULL, NULL, (UDisplayContext)0, NULL }
   1289 };
   1290 
   1291 static const UDate july022008 = 1215000001979.0;
   1292 enum { kUbufMax = 64, kBbufMax = 3*kUbufMax };
   1293 
   1294 static void TestContext(void) {
   1295     const TestContextItem* textContextItemPtr = textContextItems;
   1296     for (; textContextItemPtr->locale != NULL; ++textContextItemPtr) {
   1297         UErrorCode status = U_ZERO_ERROR;
   1298         UDateFormat* udfmt = udat_open(UDAT_NONE, UDAT_MEDIUM, textContextItemPtr->locale, NULL, 0, NULL, 0, &status);
   1299         if ( U_FAILURE(status) ) {
   1300             log_data_err("FAIL: udat_open for locale %s, status %s\n", textContextItemPtr->locale, u_errorName(status) );
   1301         } else {
   1302             UDateTimePatternGenerator* udtpg = udatpg_open(textContextItemPtr->locale, &status);
   1303             if ( U_FAILURE(status) ) {
   1304                 log_err("FAIL: udatpg_open for locale %s, status %s\n", textContextItemPtr->locale, u_errorName(status) );
   1305             } else {
   1306                 UChar ubuf[kUbufMax];
   1307                 int32_t len = udatpg_getBestPattern(udtpg, textContextItemPtr->skeleton, -1, ubuf, kUbufMax, &status);
   1308                 if ( U_FAILURE(status) ) {
   1309                     log_err("FAIL: udatpg_getBestPattern for locale %s, status %s\n", textContextItemPtr->locale, u_errorName(status) );
   1310                 } else {
   1311                     udat_applyPattern(udfmt, FALSE, ubuf, len);
   1312                     udat_setContext(udfmt, textContextItemPtr->capitalizationContext, &status);
   1313                     if ( U_FAILURE(status) ) {
   1314                         log_err("FAIL: udat_setContext for locale %s, capitalizationContext %d, status %s\n",
   1315                                 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, u_errorName(status) );
   1316                     } else {
   1317                         UDisplayContext getContext;
   1318                         len = udat_format(udfmt, july022008, ubuf, kUbufMax, NULL, &status);
   1319                         if ( U_FAILURE(status) ) {
   1320                             log_err("FAIL: udat_format for locale %s, capitalizationContext %d, status %s\n",
   1321                                     textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, u_errorName(status) );
   1322                             status = U_ZERO_ERROR;
   1323                         } else if (u_strncmp(ubuf, textContextItemPtr->expectedFormat, kUbufMax) != 0) {
   1324                             char bbuf1[kBbufMax];
   1325                             char bbuf2[kBbufMax];
   1326                             log_err("FAIL: udat_format for locale %s, capitalizationContext %d, expected %s, got %s\n",
   1327                                     textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext,
   1328                                     u_austrncpy(bbuf1,textContextItemPtr->expectedFormat,kUbufMax), u_austrncpy(bbuf2,ubuf,kUbufMax) );
   1329                         }
   1330                         getContext = udat_getContext(udfmt, UDISPCTX_TYPE_CAPITALIZATION, &status);
   1331                         if ( U_FAILURE(status) ) {
   1332                             log_err("FAIL: udat_getContext for locale %s, capitalizationContext %d, status %s\n",
   1333                                     textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, u_errorName(status) );
   1334                         } else if (getContext != textContextItemPtr->capitalizationContext) {
   1335                             log_err("FAIL: udat_getContext for locale %s, capitalizationContext %d, got context %d\n",
   1336                                     textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, (int)getContext );
   1337                         }
   1338                     }
   1339                 }
   1340                 udatpg_close(udtpg);
   1341             }
   1342             udat_close(udfmt);
   1343         }
   1344     }
   1345 }
   1346 
   1347 #endif /* #if !UCONFIG_NO_FORMATTING */
   1348