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