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