• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
addDtFrDepTest(TestNode ** root)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  */
TestTwoDigitYearDSTParse()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  */
TestPartialParse994()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 
tryPat994(UDateFormat * format,const char * pattern,const char * s,UDate expected)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  */
TestRunTogetherPattern985()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  */
TestCzechMonths459()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  */
TestQuotePattern161()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  */
TestBooleanAttributes(void)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