Home | History | Annotate | Download | only in cintltst
      1 //  2016 and later: Unicode, Inc. and others.
      2 // License & terms of use: http://www.unicode.org/copyright.html
      3 /********************************************************************
      4  * COPYRIGHT:
      5  * Copyright (c) 1997-2014, International Business Machines Corporation and
      6  * others. All Rights Reserved.
      7  ********************************************************************/
      8 /********************************************************************************
      9 *
     10 * File CDTDPTST.C
     11 *
     12 * Modification History:
     13 *        Name                     Description
     14 *     Madhu Katragadda               Creation
     15 *********************************************************************************
     16 */
     17 /* INDEPTH TEST FOR DATE FORMAT */
     18 
     19 #include "unicode/utypes.h"
     20 
     21 #if !UCONFIG_NO_FORMATTING
     22 
     23 #include "unicode/uloc.h"
     24 #include "unicode/udat.h"
     25 #include "unicode/ucal.h"
     26 #include "unicode/unum.h"
     27 #include "unicode/ustring.h"
     28 #include "cintltst.h"
     29 #include "cdtdptst.h"
     30 #include "cformtst.h"
     31 
     32 #include "cmemory.h"
     33 
     34 void addDtFrDepTest(TestNode** root);
     35 
     36 void addDtFrDepTest(TestNode** root)
     37 {
     38     addTest(root, &TestTwoDigitYearDSTParse, "tsformat/cdtdptst/TestTwoDigitYearDSTParse");
     39     addTest(root, &TestPartialParse994, "tsformat/cdtdptst/TestPartialParse994");
     40     addTest(root, &TestRunTogetherPattern985, "tsformat/cdtdptst/TestRunTogetherPattern985");
     41     addTest(root, &TestCzechMonths459, "tsformat/cdtdptst/TestCzechMonths459");
     42     addTest(root, &TestQuotePattern161, "tsformat/cdtdptst/TestQuotePattern161");
     43     addTest(root, &TestBooleanAttributes, "tsformat/cdtdptst/TestBooleanAttributes");
     44 
     45 
     46 }
     47 
     48 /**
     49  * Test the parsing of 2-digit years.
     50  */
     51 void TestTwoDigitYearDSTParse()
     52 {
     53     UDateFormat *fullFmt, *fmt;
     54     UErrorCode status = U_ZERO_ERROR;
     55     UChar *pattern;
     56     UDate d;
     57     UChar *s;
     58     int32_t pos;
     59 
     60     ctest_setTimeZone(NULL, &status);
     61 
     62     pattern=(UChar*)malloc(sizeof(UChar) * (strlen("EEE MMM dd HH:mm:ss.SSS zzz yyyy G")+1 ));
     63     u_uastrcpy(pattern, "EEE MMM dd HH:mm:ss.SSS zzz yyyy G");
     64     fullFmt= udat_open(UDAT_PATTERN, UDAT_PATTERN,"en_US",NULL,0,pattern, u_strlen(pattern),&status);
     65     if(U_FAILURE(status))    {
     66         log_data_err("FAIL: Error in creating a date format using udat_openPattern %s - (Are you missing data?)\n",
     67             myErrorName(status) );
     68     }
     69     else {
     70         log_verbose("PASS: creating dateformat using udat_openPattern() succesful\n");
     71 
     72         u_uastrcpy(pattern, "dd-MMM-yy h:mm:ss 'o''clock' a z");
     73         fmt= udat_open(UDAT_PATTERN,UDAT_PATTERN,"en_US", NULL, 0,pattern, u_strlen(pattern), &status);
     74 
     75 
     76         s=(UChar*)malloc(sizeof(UChar) * (strlen("03-Apr-04 2:20:47 o'clock AM PST")+1) );
     77         u_uastrcpy(s, "03-Apr-04 2:20:47 o'clock AM PST");
     78         pos=0;
     79         d = udat_parse(fmt, s, u_strlen(s), &pos, &status);
     80         if (U_FAILURE(status)) {
     81             log_err("FAIL: Could not parse \"%s\"\n", austrdup(s));
     82         } else {
     83             UCalendar *cal = ucal_open(NULL, 0, uloc_getDefault(), UCAL_TRADITIONAL, &status);
     84             if (U_FAILURE(status)) {
     85                 log_err_status(status, "FAIL: Could not open calendar: %s\n", u_errorName(status));
     86             } else {
     87                 int32_t h;
     88                 ucal_setMillis(cal, d, &status);
     89                 h = ucal_get(cal, UCAL_HOUR_OF_DAY, &status);
     90                 if (U_FAILURE(status)) {
     91                     log_err("FAIL: Some calendar operations failed");
     92                 } else if (h != 2) {
     93                     log_err("FAIL: Parse of \"%s\" returned HOUR_OF_DAY %d\n",
     94                             austrdup(s), h);
     95                 }
     96                 ucal_close(cal);
     97             }
     98         }
     99 
    100         udat_close(fullFmt);
    101         udat_close(fmt);
    102         free(s);
    103     }
    104     free(pattern);
    105 
    106     ctest_resetTimeZone();
    107 }
    108 
    109 
    110 /**
    111  * Verify that strings which contain incomplete specifications are parsed
    112  * correctly.  In some instances, this means not being parsed at all, and
    113  * returning an appropriate error.
    114  */
    115 void TestPartialParse994()
    116 {
    117     int32_t pos;
    118     UDateFormat *f;
    119     UErrorCode status = U_ZERO_ERROR;
    120     UChar *s;
    121     UChar *fmtChars;
    122     UDate d, null;
    123     null=0;
    124 
    125     /* this is supposed to open default date format, but later on it treats it like it is "en_US"
    126        - very bad if you try to run the tests on machine where default locale is NOT "en_US" */
    127     /* f = udat_open(UDAT_DEFAULT, UDAT_SHORT, NULL, NULL, 0, &status); */
    128     f = udat_open(UDAT_DEFAULT, UDAT_SHORT, "en_US", NULL, 0,  NULL, 0,&status);
    129     if(U_FAILURE(status)){
    130         log_data_err("FAIL: ErrorCode received during test: %s (Are you missing data?)\n", myErrorName(status));
    131         return;
    132     }
    133     s=(UChar*)malloc(sizeof(UChar) * (strlen("01/01/1997 10:11:42 AM")+1) );
    134     u_uastrcpy(s, "01/01/1997 10:11:42 AM");
    135     pos=0;
    136     d = udat_parse(f, s, u_strlen(s), &pos, &status);
    137     if(U_FAILURE(status)) {
    138       log_data_err("FAIL: could not parse - exitting");
    139       return;
    140     }
    141     fmtChars = myDateFormat(f, d);
    142     if(fmtChars) {
    143       log_verbose("%s\n", fmtChars);
    144     } else {
    145       log_data_err("FAIL: could not format \n");
    146       return;
    147     }
    148     tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/01 10:11:42", d);
    149     tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/01 10:", null);
    150     tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/01 10", null);
    151     tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/01 ", null);
    152     tryPat994(f, "yy/MM/dd HH:mm:ss", "97/01/01", null);
    153     udat_close(f);
    154     free(s);
    155 }
    156 
    157 
    158 
    159 void tryPat994(UDateFormat* format, const char* pattern, const char* s, UDate expected)
    160 {
    161     UChar *f;
    162     UChar *str, *pat;
    163     UDate date;
    164     UDate null=0;
    165     int32_t pos;
    166     UErrorCode status = U_ZERO_ERROR;
    167     str=(UChar*)malloc(sizeof(UChar) * (strlen(s) + 1) );
    168     u_uastrcpy(str, s);
    169     pat=(UChar*)malloc(sizeof(UChar) * (strlen(pattern) + 1) );
    170     u_uastrcpy(pat, pattern);
    171     log_verbose("Pattern : %s ;  String : %s\n", austrdup(pat), austrdup(str));
    172     udat_applyPattern(format, FALSE, pat, u_strlen(pat));
    173     pos=0;
    174     date = udat_parse(format, str, u_strlen(str), &pos, &status);
    175     if(U_FAILURE(status) || date == null) {
    176         log_verbose("ParseException: : %s\n", myErrorName(status) );
    177          if (expected != null)
    178              log_err("FAIL: Expected: %s\n", austrdup(myDateFormat(format, expected)) );
    179         }
    180     else {
    181         f=myDateFormat(format, date);
    182         log_verbose(" parse( %s ) -> %s\n", austrdup(str), austrdup(f));
    183         if (expected == null || date != expected)
    184             log_err("FAIL: Expected null for \"%s\"\n", s);
    185         if (u_strcmp(f, str) !=0)
    186             log_err("FAIL: Expected : %s\n", austrdup(str) );
    187     }
    188 
    189     free(str);
    190     free(pat);
    191 }
    192 
    193 
    194 /**
    195  * Verify the behavior of patterns in which digits for different fields run together
    196  * without intervening separators.
    197  */
    198 void TestRunTogetherPattern985()
    199 {
    200     int32_t pos;
    201     UChar *pattern=NULL, *now=NULL, *then=NULL;
    202     UDateFormat *format;
    203     UDate date1, date2;
    204     UErrorCode status = U_ZERO_ERROR;
    205     pattern=(UChar*)malloc(sizeof(UChar) * (strlen("yyyyMMddHHmmssSSS")+1) );
    206     u_uastrcpy(pattern, "yyyyMMddHHmmssSSS");
    207     format = udat_open(UDAT_PATTERN, UDAT_PATTERN, NULL, NULL, 0,pattern, u_strlen(pattern), &status);
    208     if(U_FAILURE(status)){
    209         log_data_err("FAIL: Error in date format construction with pattern: %s - (Are you missing data?)\n", myErrorName(status));
    210         return;
    211     }
    212     date1 = ucal_getNow();
    213     now=myDateFormat(format, date1);
    214     log_verbose("%s\n", austrdup(now) );
    215     pos = 0;
    216     date2 = udat_parse(format, now, u_strlen(now), &pos, &status);
    217     if (date2 == 0) log_verbose("Parse stopped at : %d\n", pos);
    218     else then=myDateFormat(format, date2);
    219     log_verbose("%s\n", austrdup(then) );
    220     if (!(date2 == date1)) log_err("FAIL\n");
    221 
    222     udat_close(format);
    223     free(pattern);
    224 
    225 }
    226 
    227 /**
    228  * Verify the handling of Czech June and July, which have the unique attribute that
    229  * one is a proper prefix substring of the other.
    230  */
    231 void TestCzechMonths459()
    232 {
    233     int32_t lneed, pos;
    234     UChar *pattern=NULL, *tzID=NULL;
    235     UChar *juneStr, *julyStr;
    236     UDateFormat *fmt;
    237     UCalendar *cal;
    238     UDate june, july, d;
    239     UErrorCode status = U_ZERO_ERROR;
    240     UChar *date;
    241 
    242     ctest_setTimeZone(NULL, &status);
    243     fmt = udat_open(UDAT_FULL, UDAT_FULL, "cs", NULL, 0, NULL, 0, &status);
    244     if(U_FAILURE(status)){
    245         log_data_err("Error in constructing the date format -> %s (Are you missing data?)\n", u_errorName(status));
    246         ctest_resetTimeZone();
    247         return;
    248     }
    249     lneed=0;
    250     lneed=udat_toPattern(fmt, TRUE, NULL, lneed, &status);
    251     if(status==U_BUFFER_OVERFLOW_ERROR){
    252         status=U_ZERO_ERROR;
    253         pattern=(UChar*)malloc(sizeof(UChar) * (lneed+1) );
    254         udat_toPattern(fmt, TRUE, pattern, lneed+1, &status);
    255     }
    256     if(U_FAILURE(status)){ log_err("Error in extracting the pattern\n"); }
    257     tzID=(UChar*)malloc(sizeof(UChar) * 4);
    258     u_uastrcpy(tzID, "GMT");
    259     cal=ucal_open(tzID, u_strlen(tzID), "cs", UCAL_GREGORIAN, &status);
    260     if(U_FAILURE(status)){ log_err("error in ucal_open caldef : %s\n", myErrorName(status));    }
    261 
    262     ucal_setDate(cal, 1997, UCAL_JUNE, 15, &status);
    263     june=ucal_getMillis(cal, &status);
    264     ucal_setDate(cal, 1997, UCAL_JULY, 15, &status);
    265     july=ucal_getMillis(cal, &status);
    266 
    267     juneStr = myDateFormat(fmt, june);
    268     julyStr = myDateFormat(fmt, july);
    269     pos=0;
    270     if(juneStr == NULL) {
    271       log_data_err("Can't load juneStr. Quitting.\n");
    272       return;
    273     }
    274     d = udat_parse(fmt, juneStr, u_strlen(juneStr), &pos, &status);
    275     date = myDateFormat(fmt, d);
    276 
    277     if(U_SUCCESS(status)){
    278         UChar* out1 = myDateFormat(fmt, june);
    279         UChar* out2 = myDateFormat(fmt, d);
    280         if(u_strcmp(out1, out2) !=0)
    281             log_err("Error in handling the czech month june\n");
    282         else
    283             log_verbose("Pass: Date = %s (czech month June)\n", aescstrdup(date, -1));
    284     }else{
    285         log_err("udat_parse failed. Error. %s\n",u_errorName(status));
    286     }
    287     pos=0;
    288     d = udat_parse(fmt, julyStr, u_strlen(julyStr), &pos, &status);
    289     date = myDateFormat(fmt, d);
    290     if(u_strcmp(myDateFormat(fmt, july), myDateFormat(fmt, d) ) !=0)
    291         log_err("Error in handling the czech month july\n");
    292     else
    293         log_verbose("Pass: Date = %s (czech month July)\n", aescstrdup(date, -1));
    294 
    295     ctest_resetTimeZone();
    296     udat_close(fmt);
    297     ucal_close(cal);
    298     free(pattern);
    299     free(tzID);
    300 }
    301 
    302 /**
    303  * Test the handling of single quotes in patterns.
    304  */
    305 void TestQuotePattern161()
    306 {
    307     UDateFormat *format;
    308     UCalendar *cal;
    309     UDate currentTime_1;
    310     UChar *pattern, *tzID, *exp;
    311     UChar *dateString;
    312     UErrorCode status = U_ZERO_ERROR;
    313     const char* expStr = "04/13/1999 at 10:42:28 AM ";
    314 
    315     ctest_setTimeZone(NULL, &status);
    316 
    317     pattern=(UChar*)malloc(sizeof(UChar) * (strlen("MM/dd/yyyy 'at' hh:mm:ss a zzz")+1) );
    318     u_uastrcpy(pattern, "MM/dd/yyyy 'at' hh:mm:ss a zzz");
    319 
    320     /* this is supposed to open default date format, but later on it treats it like it is "en_US"
    321        - very bad if you try to run the tests on machine where default locale is NOT "en_US" */
    322     /* format= udat_openPattern(pattern, u_strlen(pattern), NULL, &status); */
    323     format= udat_open(UDAT_PATTERN, UDAT_PATTERN,"en_US", NULL, 0,pattern, u_strlen(pattern), &status);
    324     if(U_FAILURE(status)){
    325         log_data_err("error in udat_open: %s - (Are you missing data?)\n", myErrorName(status));
    326         return;
    327     }
    328     tzID=(UChar*)malloc(sizeof(UChar) * 4);
    329     u_uastrcpy(tzID, "PST");
    330     /* this is supposed to open default date format, but later on it treats it like it is "en_US"
    331        - very bad if you try to run the tests on machine where default locale is NOT "en_US" */
    332     /* cal=ucal_open(tzID, u_strlen(tzID), NULL, UCAL_TRADITIONAL, &status); */
    333     cal=ucal_open(tzID, u_strlen(tzID), "en_US", UCAL_TRADITIONAL, &status);
    334     if(U_FAILURE(status)){ log_err("error in ucal_open cal : %s\n", myErrorName(status));    }
    335 
    336     ucal_setDateTime(cal, 1999, UCAL_APRIL, 13, 10, 42, 28, &status);
    337     currentTime_1 = ucal_getMillis(cal, &status);
    338 
    339     dateString = myDateFormat(format, currentTime_1);
    340     exp=(UChar*)malloc(sizeof(UChar) * (strlen(expStr) + 1) );
    341     u_uastrcpy(exp, expStr);
    342 
    343     log_verbose("%s\n", austrdup(dateString) );
    344     if(u_strncmp(dateString, exp, (int32_t)strlen(expStr)) !=0)
    345         log_err("Error in formatting a pattern with single quotes\n");
    346 
    347     udat_close(format);
    348     ucal_close(cal);
    349     free(exp);
    350     free(tzID);
    351     free(pattern);
    352 
    353     ctest_resetTimeZone();
    354 }
    355 
    356 /*
    357  * Testing udat_getBooleanAttribute and  unum_setBooleanAttribute() to make sure basic C wrapper functionality is present
    358  */
    359 void TestBooleanAttributes(void)
    360 {
    361     UDateFormat *en;
    362     UErrorCode status=U_ZERO_ERROR;
    363     UBool initialState = TRUE;
    364     UBool switchedState = FALSE;
    365 
    366     log_verbose("\ncreating a date format with english locale\n");
    367     en = udat_open(UDAT_FULL, UDAT_DEFAULT, "en_US", NULL, 0, NULL, 0, &status);
    368     if(U_FAILURE(status)) {
    369         log_data_err("error in creating the dateformat -> %s (Are you missing data?)\n",
    370             myErrorName(status) );
    371         return;
    372     }
    373 
    374 
    375     initialState = udat_getBooleanAttribute(en, UDAT_PARSE_ALLOW_NUMERIC, &status);
    376     if(initialState != TRUE) switchedState = TRUE;  // if it wasn't the default of TRUE, then flip what we expect
    377 
    378     udat_setBooleanAttribute(en, UDAT_PARSE_ALLOW_NUMERIC, switchedState, &status);
    379     if(switchedState != udat_getBooleanAttribute(en, UDAT_PARSE_ALLOW_NUMERIC, &status)) {
    380         log_err("unable to switch states!");
    381         return;
    382     }
    383 
    384     udat_close(en);
    385 }
    386 
    387 #endif /* #if !UCONFIG_NO_FORMATTING */
    388