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