1 /********************************************************************
3 * Copyright (c) 1997-2014, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ********************************************************************/
6 /********************************************************************************
10 * Modification History:
12 * Madhu Katragadda Creation
13 *********************************************************************************
16 /* C API TEST FOR DATE FORMAT */
18 #include "unicode/utypes.h"
20 #if !UCONFIG_NO_FORMATTING
22 #include "unicode/uloc.h"
23 #include "unicode/udat.h"
24 #include "unicode/udatpg.h"
25 #include "unicode/ucal.h"
26 #include "unicode/unum.h"
27 #include "unicode/ustring.h"
35 static void TestExtremeDates(void);
36 static void TestAllLocales(void);
37 static void TestRelativeCrash(void);
38 static void TestContext(void);
39 static void TestCalendarDateParse(void);
41 #define LEN(a) (sizeof(a)/sizeof(a[0]))
43 void addDateForTest(TestNode
** root
);
45 #define TESTCASE(x) addTest(root, &x, "tsformat/cdattst/" #x)
47 void addDateForTest(TestNode
** root
)
49 TESTCASE(TestDateFormat
);
50 TESTCASE(TestRelativeDateFormat
);
51 TESTCASE(TestSymbols
);
52 TESTCASE(TestDateFormatCalendar
);
53 TESTCASE(TestExtremeDates
);
54 TESTCASE(TestAllLocales
);
55 TESTCASE(TestRelativeCrash
);
56 TESTCASE(TestContext
);
57 TESTCASE(TestCalendarDateParse
);
59 /* Testing the DateFormat API */
60 static void TestDateFormat()
62 UDateFormat
*def
, *fr
, *it
, *de
, *def1
, *fr_pat
;
65 UErrorCode status
= U_ZERO_ERROR
;
68 const UNumberFormat
*numformat1
, *numformat2
;
74 int32_t resultlengthneeded
;
76 UDate d
= 837039928046.0;
77 double num
= -10456.37;
78 /*const char* str="yyyy.MM.dd G 'at' hh:mm:ss z";
79 const char t[]="2/3/76 2:50 AM";*/
80 /*Testing udat_open() to open a dateformat */
82 ctest_setTimeZone(NULL
, &status
);
84 log_verbose("\nTesting udat_open() with various parameters\n");
85 fr
= udat_open(UDAT_FULL
, UDAT_DEFAULT
, "fr_FR", NULL
,0, NULL
, 0,&status
);
88 log_data_err("FAIL: error in creating the dateformat using full time style with french locale -> %s (Are you missing data?)\n",
89 myErrorName(status
) );
92 /* this is supposed to open default date format, but later on it treats it like it is "en_US"
93 - very bad if you try to run the tests on machine where default locale is NOT "en_US" */
94 /* def = udat_open(UDAT_SHORT, UDAT_SHORT, NULL, NULL, 0, &status); */
95 def
= udat_open(UDAT_SHORT
, UDAT_SHORT
, "en_US", NULL
, 0,NULL
, 0, &status
);
98 log_err("FAIL: error in creating the dateformat using short date and time style\n %s\n",
99 myErrorName(status
) );
102 it
= udat_open(UDAT_DEFAULT
, UDAT_MEDIUM
, "it_IT", NULL
, 0, NULL
, 0,&status
);
103 if(U_FAILURE(status
))
105 log_err("FAIL: error in creating the dateformat using medium date style with italian locale\n %s\n",
106 myErrorName(status
) );
109 de
= udat_open(UDAT_LONG
, UDAT_LONG
, "de_DE", NULL
, 0, NULL
, 0,&status
);
110 if(U_FAILURE(status
))
112 log_err("FAIL: error in creating the dateformat using long time and date styles with german locale\n %s\n",
113 myErrorName(status
));
116 /*creating a default dateformat */
117 def1
= udat_open(UDAT_SHORT
, UDAT_SHORT
, NULL
, NULL
, 0,NULL
, 0, &status
);
118 if(U_FAILURE(status
))
120 log_err("FAIL: error in creating the dateformat using short date and time style\n %s\n",
121 myErrorName(status
) );
126 /*Testing udat_getAvailable() and udat_countAvailable()*/
127 log_verbose("\nTesting getAvailableLocales and countAvailable()\n");
128 numlocales
=udat_countAvailable();
129 /* use something sensible w/o hardcoding the count */
131 log_data_err("FAIL: error in countAvailable\n");
132 log_verbose("The number of locales for which date/time formatting patterns are available is %d\n", numlocales
);
134 for(i
=0;i
<numlocales
;i
++) {
135 UErrorCode subStatus
= U_ZERO_ERROR
;
136 log_verbose("Testing open of %s\n", udat_getAvailable(i
));
137 any
= udat_open(UDAT_SHORT
, UDAT_SHORT
, udat_getAvailable(i
), NULL
,0, NULL
, 0, &subStatus
);
138 if(U_FAILURE(subStatus
)) {
139 log_data_err("FAIL: date format %s (getAvailable(%d)) is not instantiable: %s\n", udat_getAvailable(i
), i
, u_errorName(subStatus
));
144 /*Testing udat_clone()*/
145 log_verbose("\nTesting the udat_clone() function of date format\n");
146 copy
=udat_clone(def
, &status
);
147 if(U_FAILURE(status
)){
148 log_err("Error in creating the clone using udat_clone: %s\n", myErrorName(status
) );
151 log_err("Error in udat_clone");*/ /*how should i check for equality???? */
153 /*Testing udat_format()*/
154 log_verbose("\nTesting the udat_format() function of date format\n");
155 u_uastrcpy(temp
, "7/10/96, 4:05 PM");
156 /*format using def */
158 resultlengthneeded
=udat_format(def
, d
, NULL
, resultlength
, NULL
, &status
);
159 if(status
==U_BUFFER_OVERFLOW_ERROR
)
162 resultlength
=resultlengthneeded
+1;
167 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
168 udat_format(def
, d
, result
, resultlength
, NULL
, &status
);
170 if(U_FAILURE(status
) || !result
)
172 log_err("FAIL: Error in formatting using udat_format(.....) %s\n", myErrorName(status
) );
176 log_verbose("PASS: formatting successful\n");
177 if(u_strcmp(result
, temp
)==0)
178 log_verbose("PASS: Date Format for US locale successful using udat_format()\n");
182 u_austrcpy(xbuf
, temp
);
183 u_austrcpy(gbuf
, result
);
184 log_err("FAIL: Date Format for US locale failed using udat_format() - expected %s got %s\n", xbuf
, gbuf
);
188 u_unescape("10 juil. 1996 16:05:28 heure avanc\\u00E9e du Pacifique", temp
, 50);
193 result
=myDateFormat(fr
, d
);
194 if(u_strcmp(result
, temp
)==0)
195 log_verbose("PASS: Date Format for french locale successful using udat_format()\n");
197 log_data_err("FAIL: Date Format for french locale failed using udat_format().\n" );
200 u_uastrcpy(temp
, "10/lug/1996 16:05:28");
207 fmtted
= myDateFormat(it
,d
);
208 u_austrcpy(g
, fmtted
);
210 if(u_strcmp(fmtted
, temp
)==0) {
211 log_verbose("PASS: Date Format for italian locale successful uisng udat_format() - wanted %s, got %s\n", x
, g
);
213 log_data_err("FAIL: Date Format for italian locale failed using udat_format() - wanted %s, got %s\n", x
, g
);
217 /*Testing parsing using udat_parse()*/
218 log_verbose("\nTesting parsing using udat_parse()\n");
219 u_uastrcpy(temp
,"2/3/76, 2:50 AM");
223 d1
=udat_parse(def
, temp
, u_strlen(temp
), &parsepos
, &status
);
224 if(U_FAILURE(status
))
226 log_err("FAIL: Error in parsing using udat_parse(.....) %s\n", myErrorName(status
) );
229 log_verbose("PASS: parsing succesful\n");
230 /*format it back and check for equality */
233 if(u_strcmp(myDateFormat(def
, d1
),temp
)!=0)
234 log_err("FAIL: error in parsing\n");
236 /*Testing parsing using udat_parse()*/
237 log_verbose("\nTesting parsing using udat_parse()\n");
238 u_uastrcpy(temp
,"2/Don't parse this part");
241 d1
=udat_parse(def
, temp
, u_strlen(temp
), NULL
, &status
);
242 if(status
!= U_PARSE_ERROR
)
244 log_err("FAIL: udat_parse(\"bad string\") passed when it should have failed\n");
247 log_verbose("PASS: parsing succesful\n");
251 /*Testing udat_openPattern() */
253 log_verbose("\nTesting the udat_openPattern with a specified pattern\n");
254 /*for french locale */
255 fr_pat
=udat_open(UDAT_PATTERN
, UDAT_PATTERN
,"fr_FR",NULL
,0,temp
, u_strlen(temp
), &status
);
256 if(U_FAILURE(status
))
258 log_err("FAIL: Error in creating a date format using udat_openPattern \n %s\n",
259 myErrorName(status
) );
262 log_verbose("PASS: creating dateformat using udat_openPattern() succesful\n");
265 /*Testing applyPattern and toPattern */
266 log_verbose("\nTesting applyPattern and toPattern()\n");
267 udat_applyPattern(def1
, FALSE
, temp
, u_strlen(temp
));
268 log_verbose("Extracting the pattern\n");
271 resultlengthneeded
=udat_toPattern(def1
, FALSE
, NULL
, resultlength
, &status
);
272 if(status
==U_BUFFER_OVERFLOW_ERROR
)
275 resultlength
=resultlengthneeded
+ 1;
276 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
277 udat_toPattern(def1
, FALSE
, result
, resultlength
, &status
);
279 if(U_FAILURE(status
))
281 log_err("FAIL: error in extracting the pattern from UNumberFormat\n %s\n",
282 myErrorName(status
) );
284 if(u_strcmp(result
, temp
)!=0)
285 log_err("FAIL: Error in extracting the pattern\n");
287 log_verbose("PASS: applyPattern and toPattern work fine\n");
295 /*Testing getter and setter functions*/
296 /*isLenient and setLenient()*/
297 log_verbose("\nTesting the isLenient and setLenient properties\n");
298 udat_setLenient(fr
, udat_isLenient(it
));
299 if(udat_isLenient(fr
) != udat_isLenient(it
))
300 log_err("ERROR: setLenient() failed\n");
302 log_verbose("PASS: setLenient() successful\n");
305 /*Test get2DigitYearStart set2DigitYearStart */
306 log_verbose("\nTesting the get and set 2DigitYearStart properties\n");
307 d1
= udat_get2DigitYearStart(fr_pat
,&status
);
308 if(U_FAILURE(status
)) {
309 log_err("ERROR: udat_get2DigitYearStart failed %s\n", myErrorName(status
) );
311 status
= U_ZERO_ERROR
;
312 udat_set2DigitYearStart(def1
,d1
, &status
);
313 if(U_FAILURE(status
)) {
314 log_err("ERROR: udat_set2DigitYearStart failed %s\n", myErrorName(status
) );
316 if(udat_get2DigitYearStart(fr_pat
, &status
) != udat_get2DigitYearStart(def1
, &status
))
317 log_err("FAIL: error in set2DigitYearStart\n");
319 log_verbose("PASS: set2DigitYearStart successful\n");
320 /*try setting it to another value */
321 udat_set2DigitYearStart(de
, 2000.0, &status
);
322 if(U_FAILURE(status
)){
323 log_verbose("ERROR: udat_set2DigitYearStart failed %s\n", myErrorName(status
) );
325 if(udat_get2DigitYearStart(de
, &status
) != 2000)
326 log_err("FAIL: error in set2DigitYearStart\n");
328 log_verbose("PASS: set2DigitYearStart successful\n");
332 /*Test getNumberFormat() and setNumberFormat() */
333 log_verbose("\nTesting the get and set NumberFormat properties of date format\n");
334 numformat1
=udat_getNumberFormat(fr_pat
);
335 udat_setNumberFormat(def1
, numformat1
);
336 numformat2
=udat_getNumberFormat(def1
);
337 if(u_strcmp(myNumformat(numformat1
, num
), myNumformat(numformat2
, num
)) !=0)
338 log_err("FAIL: error in setNumberFormat or getNumberFormat()\n");
340 log_verbose("PASS:setNumberFormat and getNumberFormat succesful\n");
342 /*try setting the number format to another format */
343 numformat1
=udat_getNumberFormat(def
);
344 udat_setNumberFormat(def1
, numformat1
);
345 numformat2
=udat_getNumberFormat(def1
);
346 if(u_strcmp(myNumformat(numformat1
, num
), myNumformat(numformat2
, num
)) !=0)
347 log_err("FAIL: error in setNumberFormat or getNumberFormat()\n");
349 log_verbose("PASS: setNumberFormat and getNumberFormat succesful\n");
353 /*Test getCalendar and setCalendar*/
354 log_verbose("\nTesting the udat_getCalendar() and udat_setCalendar() properties\n");
355 cal
=udat_getCalendar(fr_pat
);
358 udat_setCalendar(def1
, cal
);
359 if(!ucal_equivalentTo(udat_getCalendar(fr_pat
), udat_getCalendar(def1
)))
360 log_err("FAIL: Error in setting and getting the calendar\n");
362 log_verbose("PASS: getting and setting calendar successful\n");
368 /*Closing the UDateForamt */
377 ctest_resetTimeZone();
381 Test combined relative date formatting (relative date + non-relative time).
382 This is a bit tricky since we can't have static test data for comparison, the
383 relative date formatting is relative to the time the tests are run. We generate
384 the data for comparison dynamically. However, the tests could fail if they are
385 run right at midnight Pacific time and the call to ucal_getNow() is before midnight
386 while the calls to udat_format are after midnight or span midnight.
388 static const UDate dayInterval
= 24.0*60.0*60.0*1000.0;
389 static const UChar trdfZone
[] = { 0x0055, 0x0053, 0x002F, 0x0050, 0x0061, 0x0063, 0x0069, 0x0066, 0x0069, 0x0063, 0 }; /* US/Pacific */
390 static const char trdfLocale
[] = "en_US";
391 static const UChar minutesPatn
[] = { 0x006D, 0x006D, 0 }; /* "mm" */
392 static const UChar monthLongPatn
[] = { 0x004D, 0x004D, 0x004D, 0x004D, 0 }; /* "MMMM" */
393 static const UChar monthMediumPatn
[] = { 0x004D, 0x004D, 0x004D, 0 }; /* "MMM" */
394 static const UChar monthShortPatn
[] = { 0x004D, 0 }; /* "M" */
395 static const UDateFormatStyle dateStylesList
[] = { UDAT_FULL
, UDAT_LONG
, UDAT_MEDIUM
, UDAT_SHORT
, UDAT_NONE
};
396 static const UChar
*monthPatnsList
[] = { monthLongPatn
, monthLongPatn
, monthMediumPatn
, monthShortPatn
, NULL
};
397 static const UChar newTimePatn
[] = { 0x0048, 0x0048, 0x002C, 0x006D, 0x006D, 0 }; /* "HH,mm" */
398 static const UChar minutesStr
[] = { 0x0034, 0x0039, 0 }; /* "49", minutes string to search for in output */
399 enum { kDateOrTimeOutMax
= 96, kDateAndTimeOutMax
= 192 };
401 static const UDate minutesTolerance
= 2 * 60.0 * 1000.0;
402 static const UDate daysTolerance
= 2 * 24.0 * 60.0 * 60.0 * 1000.0;
404 static void TestRelativeDateFormat()
407 const UDateFormatStyle
* stylePtr
;
408 const UChar
** monthPtnPtr
;
409 UErrorCode status
= U_ZERO_ERROR
;
410 UCalendar
* ucal
= ucal_open(trdfZone
, -1, trdfLocale
, UCAL_GREGORIAN
, &status
);
411 if ( U_SUCCESS(status
) ) {
412 int32_t year
, month
, day
;
413 ucal_setMillis(ucal
, ucal_getNow(), &status
);
414 year
= ucal_get(ucal
, UCAL_YEAR
, &status
);
415 month
= ucal_get(ucal
, UCAL_MONTH
, &status
);
416 day
= ucal_get(ucal
, UCAL_DATE
, &status
);
417 ucal_setDateTime(ucal
, year
, month
, day
, 18, 49, 0, &status
); /* set to today at 18:49:00 */
418 today
= ucal_getMillis(ucal
, &status
);
421 if ( U_FAILURE(status
) || today
== 0.0 ) {
422 log_data_err("Generate UDate for a specified time today fails, error %s - (Are you missing data?)\n", myErrorName(status
) );
425 for (stylePtr
= dateStylesList
, monthPtnPtr
= monthPatnsList
; *stylePtr
!= UDAT_NONE
; ++stylePtr
, ++monthPtnPtr
) {
426 UDateFormat
* fmtRelDateTime
;
427 UDateFormat
* fmtRelDate
;
428 UDateFormat
* fmtTime
;
429 int32_t dayOffset
, limit
;
431 UChar strDateTime
[kDateAndTimeOutMax
];
432 UChar strDate
[kDateOrTimeOutMax
];
433 UChar strTime
[kDateOrTimeOutMax
];
437 fmtRelDateTime
= udat_open(UDAT_SHORT
, *stylePtr
| UDAT_RELATIVE
, trdfLocale
, trdfZone
, -1, NULL
, 0, &status
);
438 if ( U_FAILURE(status
) ) {
439 log_data_err("udat_open timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s (Are you missing data?)\n", *stylePtr
, myErrorName(status
) );
442 fmtRelDate
= udat_open(UDAT_NONE
, *stylePtr
| UDAT_RELATIVE
, trdfLocale
, trdfZone
, -1, NULL
, 0, &status
);
443 if ( U_FAILURE(status
) ) {
444 log_err("udat_open timeStyle NONE dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr
, myErrorName(status
) );
445 udat_close(fmtRelDateTime
);
448 fmtTime
= udat_open(UDAT_SHORT
, UDAT_NONE
, trdfLocale
, trdfZone
, -1, NULL
, 0, &status
);
449 if ( U_FAILURE(status
) ) {
450 log_err("udat_open timeStyle SHORT dateStyle NONE fails, error %s\n", myErrorName(status
) );
451 udat_close(fmtRelDateTime
);
452 udat_close(fmtRelDate
);
456 dtpatLen
= udat_toPatternRelativeDate(fmtRelDateTime
, strDate
, kDateAndTimeOutMax
, &status
);
457 if ( U_FAILURE(status
) ) {
458 log_err("udat_toPatternRelativeDate timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr
, myErrorName(status
) );
459 status
= U_ZERO_ERROR
;
460 } else if ( u_strstr(strDate
, *monthPtnPtr
) == NULL
|| dtpatLen
!= u_strlen(strDate
) ) {
461 log_err("udat_toPatternRelativeDate timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) date pattern incorrect\n", *stylePtr
);
463 dtpatLen
= udat_toPatternRelativeTime(fmtRelDateTime
, strTime
, kDateAndTimeOutMax
, &status
);
464 if ( U_FAILURE(status
) ) {
465 log_err("udat_toPatternRelativeTime timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr
, myErrorName(status
) );
466 status
= U_ZERO_ERROR
;
467 } else if ( u_strstr(strTime
, minutesPatn
) == NULL
|| dtpatLen
!= u_strlen(strTime
) ) {
468 log_err("udat_toPatternRelativeTime timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) time pattern incorrect\n", *stylePtr
);
470 dtpatLen
= udat_toPattern(fmtRelDateTime
, FALSE
, strDateTime
, kDateAndTimeOutMax
, &status
);
471 if ( U_FAILURE(status
) ) {
472 log_err("udat_toPattern timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr
, myErrorName(status
) );
473 status
= U_ZERO_ERROR
;
474 } else if ( u_strstr(strDateTime
, strDate
) == NULL
|| u_strstr(strDateTime
, strTime
) == NULL
|| dtpatLen
!= u_strlen(strDateTime
) ) {
475 log_err("udat_toPattern timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) dateTime pattern incorrect\n", *stylePtr
);
477 udat_applyPatternRelative(fmtRelDateTime
, strDate
, u_strlen(strDate
), newTimePatn
, u_strlen(newTimePatn
), &status
);
478 if ( U_FAILURE(status
) ) {
479 log_err("udat_applyPatternRelative timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr
, myErrorName(status
) );
480 status
= U_ZERO_ERROR
;
482 udat_toPattern(fmtRelDateTime
, FALSE
, strDateTime
, kDateAndTimeOutMax
, &status
);
483 if ( U_FAILURE(status
) ) {
484 log_err("udat_toPattern timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr
, myErrorName(status
) );
485 status
= U_ZERO_ERROR
;
486 } else if ( u_strstr(strDateTime
, newTimePatn
) == NULL
) {
487 log_err("udat_applyPatternRelative timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) didn't update time pattern\n", *stylePtr
);
490 udat_applyPatternRelative(fmtRelDateTime
, strDate
, u_strlen(strDate
), strTime
, u_strlen(strTime
), &status
); /* restore original */
492 fp
.field
= UDAT_MINUTE_FIELD
;
493 for (dayOffset
= -2, limit
= 2; dayOffset
<= limit
; ++dayOffset
) {
494 UDate dateToUse
= today
+ (float)dayOffset
*dayInterval
;
496 udat_format(fmtRelDateTime
, dateToUse
, strDateTime
, kDateAndTimeOutMax
, &fp
, &status
);
497 if ( U_FAILURE(status
) ) {
498 log_err("udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr
, myErrorName(status
) );
499 status
= U_ZERO_ERROR
;
501 int32_t parsePos
= 0;
502 UDate dateResult
= udat_parse(fmtRelDateTime
, strDateTime
, -1, &parsePos
, &status
);
503 UDate dateDiff
= (dateResult
>= dateToUse
)? dateResult
- dateToUse
: dateToUse
- dateResult
;
504 if ( U_FAILURE(status
) || dateDiff
> minutesTolerance
) {
505 log_err("udat_parse timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s, expect approx %.1f, got %.1f, parsePos %d\n",
506 *stylePtr
, myErrorName(status
), dateToUse
, dateResult
, parsePos
);
507 status
= U_ZERO_ERROR
;
510 udat_format(fmtRelDate
, dateToUse
, strDate
, kDateOrTimeOutMax
, NULL
, &status
);
511 if ( U_FAILURE(status
) ) {
512 log_err("udat_format timeStyle NONE dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr
, myErrorName(status
) );
513 status
= U_ZERO_ERROR
;
514 } else if ( u_strstr(strDateTime
, strDate
) == NULL
) {
515 log_err("relative date string not found in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", *stylePtr
);
518 dateResult
= udat_parse(fmtRelDate
, strDate
, -1, &parsePos
, &status
);
519 dateDiff
= (dateResult
>= dateToUse
)? dateResult
- dateToUse
: dateToUse
- dateResult
;
520 if ( U_FAILURE(status
) || dateDiff
> daysTolerance
) {
521 log_err("udat_parse timeStyle NONE dateStyle (%d | UDAT_RELATIVE) fails, error %s, expect approx %.1f, got %.1f, parsePos %d\n",
522 *stylePtr
, myErrorName(status
), dateToUse
, dateResult
, parsePos
);
523 status
= U_ZERO_ERROR
;
527 udat_format(fmtTime
, dateToUse
, strTime
, kDateOrTimeOutMax
, NULL
, &status
);
528 if ( U_FAILURE(status
) ) {
529 log_err("udat_format timeStyle SHORT dateStyle NONE fails, error %s\n", myErrorName(status
) );
530 status
= U_ZERO_ERROR
;
531 } else if ( u_strstr(strDateTime
, strTime
) == NULL
) {
532 log_err("time string not found in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", *stylePtr
);
535 strPtr
= u_strstr(strDateTime
, minutesStr
);
536 if ( strPtr
!= NULL
) {
537 int32_t beginIndex
= strPtr
- strDateTime
;
538 if ( fp
.beginIndex
!= beginIndex
) {
539 log_err("UFieldPosition beginIndex %d, expected %d, in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", fp
.beginIndex
, beginIndex
, *stylePtr
);
542 log_err("minutes string not found in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", *stylePtr
);
547 udat_close(fmtRelDateTime
);
548 udat_close(fmtRelDate
);
553 /*Testing udat_getSymbols() and udat_setSymbols() and udat_countSymbols()*/
554 static void TestSymbols()
556 UDateFormat
*def
, *fr
;
557 UErrorCode status
= U_ZERO_ERROR
;
559 UChar
*result
= NULL
;
560 int32_t resultlength
;
561 int32_t resultlengthout
;
565 /*creating a dateformat with french locale */
566 log_verbose("\ncreating a date format with french locale\n");
567 fr
= udat_open(UDAT_FULL
, UDAT_DEFAULT
, "fr_FR", NULL
, 0, NULL
, 0, &status
);
568 if(U_FAILURE(status
))
570 log_data_err("error in creating the dateformat using full time style with french locale -> %s (Are you missing data?)\n",
571 myErrorName(status
) );
574 /*creating a default dateformat */
575 log_verbose("\ncreating a date format with default locale\n");
576 /* this is supposed to open default date format, but later on it treats it like it is "en_US"
577 - very bad if you try to run the tests on machine where default locale is NOT "en_US" */
578 /* def = udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,NULL, NULL, 0, &status); */
579 def
= udat_open(UDAT_DEFAULT
,UDAT_DEFAULT
,"en_US", NULL
, 0, NULL
, 0, &status
);
580 if(U_FAILURE(status
))
582 log_err("error in creating the dateformat using short date and time style\n %s\n",
583 myErrorName(status
) );
588 /*Testing countSymbols, getSymbols and setSymbols*/
589 log_verbose("\nTesting countSymbols\n");
590 /*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 */
591 if(udat_countSymbols(def
, UDAT_ERAS
)!=2 || udat_countSymbols(def
, UDAT_MONTHS
)!=12 ||
592 udat_countSymbols(def
, UDAT_SHORT_MONTHS
)!=12 || udat_countSymbols(def
, UDAT_WEEKDAYS
)!=8 ||
593 udat_countSymbols(def
, UDAT_SHORT_WEEKDAYS
)!=8 || udat_countSymbols(def
, UDAT_AM_PMS
)!=2 ||
594 udat_countSymbols(def
, UDAT_QUARTERS
) != 4 || udat_countSymbols(def
, UDAT_SHORT_QUARTERS
) != 4 ||
595 udat_countSymbols(def
, UDAT_LOCALIZED_CHARS
)!=1 || udat_countSymbols(def
, UDAT_SHORTER_WEEKDAYS
)!=8)
597 log_err("FAIL: error in udat_countSymbols\n");
600 log_verbose("PASS: udat_countSymbols() successful\n");
602 /*testing getSymbols*/
603 log_verbose("\nTesting getSymbols\n");
604 pattern
=(UChar
*)malloc(sizeof(UChar
) * 10);
605 u_uastrcpy(pattern
, "jeudi");
607 resultlengthout
=udat_getSymbols(fr
, UDAT_WEEKDAYS
, 5 , NULL
, resultlength
, &status
);
608 if(status
==U_BUFFER_OVERFLOW_ERROR
)
611 resultlength
=resultlengthout
+1;
616 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
617 udat_getSymbols(fr
, UDAT_WEEKDAYS
, 5, result
, resultlength
, &status
);
620 if(U_FAILURE(status
))
622 log_err("FAIL: Error in udat_getSymbols().... %s\n", myErrorName(status
) );
625 log_verbose("PASS: getSymbols succesful\n");
627 if(u_strcmp(result
, pattern
)==0)
628 log_verbose("PASS: getSymbols retrieved the right value\n");
630 log_data_err("FAIL: getSymbols retrieved the wrong value\n");
632 /*run series of tests to test getsymbols regressively*/
633 log_verbose("\nTesting getSymbols() regressively\n");
634 VerifygetSymbols(fr
, UDAT_WEEKDAYS
, 1, "dimanche");
635 VerifygetSymbols(def
, UDAT_WEEKDAYS
, 1, "Sunday");
636 VerifygetSymbols(fr
, UDAT_SHORT_WEEKDAYS
, 7, "sam.");
637 VerifygetSymbols(fr
, UDAT_SHORTER_WEEKDAYS
, 7, "sa");
638 VerifygetSymbols(def
, UDAT_SHORT_WEEKDAYS
, 7, "Sat");
639 VerifygetSymbols(def
, UDAT_MONTHS
, 11, "December");
640 VerifygetSymbols(def
, UDAT_MONTHS
, 0, "January");
641 VerifygetSymbols(fr
, UDAT_ERAS
, 0, "av. J.-C.");
642 VerifygetSymbols(def
, UDAT_AM_PMS
, 0, "AM");
643 VerifygetSymbols(def
, UDAT_AM_PMS
, 1, "PM");
644 VerifygetSymbols(fr
, UDAT_SHORT_MONTHS
, 0, "janv.");
645 VerifygetSymbols(def
, UDAT_SHORT_MONTHS
, 11, "Dec");
646 VerifygetSymbols(fr
, UDAT_QUARTERS
, 0, "1er trimestre");
647 VerifygetSymbols(def
, UDAT_QUARTERS
, 3, "4th quarter");
648 VerifygetSymbols(fr
, UDAT_SHORT_QUARTERS
, 1, "T2");
649 VerifygetSymbols(def
, UDAT_SHORT_QUARTERS
, 2, "Q3");
650 VerifygetSymbols(def
,UDAT_LOCALIZED_CHARS
, 0, "GyMdkHmsSEDFwWahKzYeugAZvcLQqVUOXxr");
659 log_verbose("\nTesting setSymbols\n");
660 /*applying the pattern so that setSymbolss works */
662 resultlengthout
=udat_toPattern(fr
, FALSE
, NULL
, resultlength
, &status
);
663 if(status
==U_BUFFER_OVERFLOW_ERROR
)
666 resultlength
=resultlengthout
+ 1;
667 pattern
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
668 udat_toPattern(fr
, FALSE
, pattern
, resultlength
, &status
);
670 if(U_FAILURE(status
))
672 log_err("FAIL: error in extracting the pattern from UNumberFormat\n %s\n",
673 myErrorName(status
) );
676 udat_applyPattern(def
, FALSE
, pattern
, u_strlen(pattern
));
678 resultlengthout
=udat_toPattern(def
, FALSE
, NULL
, resultlength
,&status
);
679 if(status
==U_BUFFER_OVERFLOW_ERROR
)
682 resultlength
=resultlengthout
+ 1;
687 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
688 udat_toPattern(fr
, FALSE
,result
, resultlength
, &status
);
690 if(U_FAILURE(status
))
692 log_err("FAIL: error in extracting the pattern from UNumberFormat\n %s\n",
693 myErrorName(status
) );
695 if(u_strcmp(result
, pattern
)==0)
696 log_verbose("Pattern applied properly\n");
698 log_err("pattern could not be applied properly\n");
701 /*testing set symbols */
703 resultlengthout
=udat_getSymbols(fr
, UDAT_MONTHS
, 11 , NULL
, resultlength
, &status
);
704 if(status
==U_BUFFER_OVERFLOW_ERROR
){
706 resultlength
=resultlengthout
+1;
711 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
712 udat_getSymbols(fr
, UDAT_MONTHS
, 11, result
, resultlength
, &status
);
715 if(U_FAILURE(status
))
716 log_err("FAIL: error in getSymbols() %s\n", myErrorName(status
) );
717 resultlength
=resultlengthout
+1;
719 udat_setSymbols(def
, UDAT_MONTHS
, 11, result
, resultlength
, &status
);
720 if(U_FAILURE(status
))
722 log_err("FAIL: Error in udat_setSymbols() : %s\n", myErrorName(status
) );
725 log_verbose("PASS: SetSymbols successful\n");
728 resultlengthout
=udat_getSymbols(def
, UDAT_MONTHS
, 11, NULL
, resultlength
, &status
);
729 if(status
==U_BUFFER_OVERFLOW_ERROR
){
731 resultlength
=resultlengthout
+1;
732 value
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
733 udat_getSymbols(def
, UDAT_MONTHS
, 11, value
, resultlength
, &status
);
735 if(U_FAILURE(status
))
736 log_err("FAIL: error in retrieving the value using getSymbols i.e roundtrip\n");
738 if(u_strcmp(result
, value
)!=0)
739 log_data_err("FAIL: Error in settting and getting symbols\n");
741 log_verbose("PASS: setSymbols successful\n");
744 /*run series of tests to test setSymbols regressively*/
745 log_verbose("\nTesting setSymbols regressively\n");
746 VerifysetSymbols(def
, UDAT_ERAS
, 0, "BeforeChrist");
747 VerifysetSymbols(def
, UDAT_ERA_NAMES
, 1, "AnnoDomini");
748 VerifysetSymbols(def
, UDAT_WEEKDAYS
, 1, "Sundayweek");
749 VerifysetSymbols(def
, UDAT_SHORT_WEEKDAYS
, 7, "Satweek");
750 VerifysetSymbols(def
, UDAT_NARROW_WEEKDAYS
, 4, "M");
751 VerifysetSymbols(def
, UDAT_STANDALONE_WEEKDAYS
, 1, "Sonntagweek");
752 VerifysetSymbols(def
, UDAT_STANDALONE_SHORT_WEEKDAYS
, 7, "Sams");
753 VerifysetSymbols(def
, UDAT_STANDALONE_NARROW_WEEKDAYS
, 4, "V");
754 VerifysetSymbols(fr
, UDAT_MONTHS
, 11, "december");
755 VerifysetSymbols(fr
, UDAT_SHORT_MONTHS
, 0, "Jan");
756 VerifysetSymbols(fr
, UDAT_NARROW_MONTHS
, 1, "R");
757 VerifysetSymbols(fr
, UDAT_STANDALONE_MONTHS
, 11, "dezember");
758 VerifysetSymbols(fr
, UDAT_STANDALONE_SHORT_MONTHS
, 7, "Aug");
759 VerifysetSymbols(fr
, UDAT_STANDALONE_NARROW_MONTHS
, 2, "M");
760 VerifysetSymbols(fr
, UDAT_QUARTERS
, 0, "1. Quart");
761 VerifysetSymbols(fr
, UDAT_SHORT_QUARTERS
, 1, "QQ2");
762 VerifysetSymbols(fr
, UDAT_STANDALONE_QUARTERS
, 2, "3rd Quar.");
763 VerifysetSymbols(fr
, UDAT_STANDALONE_SHORT_QUARTERS
, 3, "4QQ");
766 /*run series of tests to test get and setSymbols regressively*/
767 log_verbose("\nTesting get and set symbols regressively\n");
768 VerifygetsetSymbols(fr
, def
, UDAT_WEEKDAYS
, 1);
769 VerifygetsetSymbols(fr
, def
, UDAT_WEEKDAYS
, 7);
770 VerifygetsetSymbols(fr
, def
, UDAT_SHORT_WEEKDAYS
, 1);
771 VerifygetsetSymbols(fr
, def
, UDAT_SHORT_WEEKDAYS
, 7);
772 VerifygetsetSymbols(fr
, def
, UDAT_MONTHS
, 0);
773 VerifygetsetSymbols(fr
, def
, UDAT_SHORT_MONTHS
, 0);
774 VerifygetsetSymbols(fr
, def
, UDAT_ERAS
,1);
775 VerifygetsetSymbols(fr
, def
, UDAT_LOCALIZED_CHARS
, 0);
776 VerifygetsetSymbols(fr
, def
, UDAT_AM_PMS
, 1);
792 * Test DateFormat(Calendar) API
794 static void TestDateFormatCalendar() {
795 UDateFormat
*date
=0, *time
=0, *full
=0;
801 UErrorCode ec
= U_ZERO_ERROR
;
803 ctest_setTimeZone(NULL
, &ec
);
805 /* Create a formatter for date fields. */
806 date
= udat_open(UDAT_NONE
, UDAT_SHORT
, "en_US", NULL
, 0, NULL
, 0, &ec
);
808 log_data_err("FAIL: udat_open(NONE, SHORT, en_US) failed with %s (Are you missing data?)\n",
813 /* Create a formatter for time fields. */
814 time
= udat_open(UDAT_SHORT
, UDAT_NONE
, "en_US", NULL
, 0, NULL
, 0, &ec
);
816 log_err("FAIL: udat_open(SHORT, NONE, en_US) failed with %s\n",
821 /* Create a full format for output */
822 full
= udat_open(UDAT_FULL
, UDAT_FULL
, "en_US", NULL
, 0, NULL
, 0, &ec
);
824 log_err("FAIL: udat_open(FULL, FULL, en_US) failed with %s\n",
829 /* Create a calendar */
830 cal
= ucal_open(NULL
, 0, "en_US", UCAL_GREGORIAN
, &ec
);
832 log_err("FAIL: ucal_open(en_US) failed with %s\n",
839 u_uastrcpy(buf
, "4/5/2001");
841 udat_parseCalendar(date
, cal
, buf
, -1, &pos
, &ec
);
843 log_err("FAIL: udat_parseCalendar(4/5/2001) failed at %d with %s\n",
844 pos
, u_errorName(ec
));
849 u_uastrcpy(buf
, "5:45 PM");
851 udat_parseCalendar(time
, cal
, buf
, -1, &pos
, &ec
);
853 log_err("FAIL: udat_parseCalendar(17:45) failed at %d with %s\n",
854 pos
, u_errorName(ec
));
859 when
= ucal_getMillis(cal
, &ec
);
861 log_err("FAIL: ucal_getMillis() failed with %s\n", u_errorName(ec
));
864 udat_format(full
, when
, buf
, sizeof(buf
), NULL
, &ec
);
866 log_err("FAIL: udat_format() failed with %s\n", u_errorName(ec
));
869 u_austrcpy(cbuf
, buf
);
870 /* Thursday, April 5, 2001 5:45:00 PM PDT 986517900000 */
871 if (when
== 986517900000.0) {
872 log_verbose("Ok: Parsed result: %s\n", cbuf
);
874 log_err("FAIL: Parsed result: %s, exp 4/5/2001 5:45 PM\n", cbuf
);
883 ctest_resetTimeZone();
889 * Test parsing two digit year against "YY" vs. "YYYY" patterns
891 static void TestCalendarDateParse() {
894 UErrorCode ec
= U_ZERO_ERROR
;
895 UDateFormat
* simpleDateFormat
= 0;
896 int32_t parsePos
= 0;
897 int32_t twoDigitCenturyStart
= 75;
898 int32_t currentTwoDigitYear
= 0;
899 int32_t startCentury
= 0;
900 UCalendar
* tempCal
= 0;
901 UCalendar
* calendar
= 0;
903 U_STRING_DECL(pattern
, "yyyy", 4);
904 U_STRING_DECL(pattern2
, "yy", 2);
905 U_STRING_DECL(text
, "75", 2);
907 U_STRING_INIT(pattern
, "yyyy", 4);
908 U_STRING_INIT(pattern2
, "yy", 2);
909 U_STRING_INIT(text
, "75", 2);
911 simpleDateFormat
= udat_open(UDAT_FULL
, UDAT_FULL
, "en-GB", 0, 0, 0, 0, &ec
);
913 log_data_err("udat_open(UDAT_FULL, UDAT_FULL, \"en-GB\", 0, 0, 0, 0, &ec) failed: %s - (Are you missing data?)\n", u_errorName(ec
));
916 udat_applyPattern(simpleDateFormat
, 0, pattern
, u_strlen(pattern
));
917 udat_setLenient(simpleDateFormat
, 0);
919 currentTwoDigitYear
= getCurrentYear() % 100;
920 startCentury
= getCurrentYear() - currentTwoDigitYear
;
921 if (twoDigitCenturyStart
> currentTwoDigitYear
) {
924 tempCal
= ucal_open(NULL
, -1, NULL
, UCAL_GREGORIAN
, &ec
);
925 ucal_setMillis(tempCal
, 0, &ec
);
926 ucal_setDateTime(tempCal
, startCentury
+ twoDigitCenturyStart
, UCAL_JANUARY
, 1, 0, 0, 0, &ec
);
927 udat_set2DigitYearStart(simpleDateFormat
, ucal_getMillis(tempCal
, &ec
), &ec
);
929 calendar
= ucal_open(NULL
, -1, NULL
, UCAL_GREGORIAN
, &ec
);
930 ucal_setMillis(calendar
, 0, &ec
);
931 ucal_setDateTime(calendar
, twoDigitCenturyStart
, UCAL_JANUARY
, 1, 0, 0, 0, &ec
);
933 udat_parseCalendar(simpleDateFormat
, calendar
, text
, u_strlen(text
), &parsePos
, &ec
);
936 result
= ucal_get(calendar
, UCAL_YEAR
, &ec
);
938 log_err("FAIL: ucal_get(UCAL_YEAR) failed with %s\n", u_errorName(ec
));
943 log_err("FAIL: parsed incorrect year: %d\n", result
);
948 udat_applyPattern(simpleDateFormat
, 0, pattern2
, u_strlen(pattern2
));
949 udat_parseCalendar(simpleDateFormat
, calendar
, text
, u_strlen(text
), &parsePos
, &ec
);
952 result
= ucal_get(calendar
, UCAL_YEAR
, &ec
);
954 log_err("FAIL: ucal_get(UCAL_YEAR) failed with %s\n", u_errorName(ec
));
958 if (result
!= 1975) {
959 log_err("FAIL: parsed incorrect year: %d\n", result
);
964 udat_close(simpleDateFormat
);
966 udat_close(calendar
);
970 /*INTERNAL FUNCTIONS USED*/
971 static int getCurrentYear() {
972 static int currentYear
= 0;
973 if (currentYear
== 0) {
974 UErrorCode status
= U_ZERO_ERROR
;
975 UCalendar
*cal
= ucal_open(NULL
, -1, NULL
, UCAL_GREGORIAN
, &status
);
976 if (!U_FAILURE(status
)) {
977 /* Get the current year from the default UCalendar */
978 currentYear
= ucal_get(cal
, UCAL_YEAR
, &status
);
986 /* N.B.: use idx instead of index to avoid 'shadow' warnings in strict mode. */
987 static void VerifygetSymbols(UDateFormat
* datfor
, UDateFormatSymbolType type
, int32_t idx
, const char* expected
)
990 UErrorCode status
= U_ZERO_ERROR
;
992 int32_t resultlength
, resultlengthout
;
995 pattern
=(UChar
*)malloc(sizeof(UChar
) * (strlen(expected
)+1));
996 u_uastrcpy(pattern
, expected
);
998 resultlengthout
=udat_getSymbols(datfor
, type
, idx
, NULL
, resultlength
, &status
);
999 if(status
==U_BUFFER_OVERFLOW_ERROR
)
1001 status
=U_ZERO_ERROR
;
1002 resultlength
=resultlengthout
+1;
1003 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
1004 udat_getSymbols(datfor
, type
, idx
, result
, resultlength
, &status
);
1007 if(U_FAILURE(status
))
1009 log_err("FAIL: Error in udat_getSymbols()... %s\n", myErrorName(status
) );
1012 if(u_strcmp(result
, pattern
)==0)
1013 log_verbose("PASS: getSymbols retrieved the right value\n");
1015 log_data_err("FAIL: getSymbols retrieved the wrong value\n Expected %s Got %s\n", austrdup(pattern
),
1022 static void VerifysetSymbols(UDateFormat
* datfor
, UDateFormatSymbolType type
, int32_t idx
, const char* expected
)
1026 int32_t resultlength
, resultlengthout
;
1027 UErrorCode status
= U_ZERO_ERROR
;
1029 value
=(UChar
*)malloc(sizeof(UChar
) * (strlen(expected
) + 1));
1030 u_uastrcpy(value
, expected
);
1031 udat_setSymbols(datfor
, type
, idx
, value
, u_strlen(value
), &status
);
1032 if(U_FAILURE(status
))
1034 log_err("FAIL: Error in udat_setSymbols() %s\n", myErrorName(status
) );
1039 resultlengthout
=udat_getSymbols(datfor
, type
, idx
, NULL
, resultlength
, &status
);
1040 if(status
==U_BUFFER_OVERFLOW_ERROR
){
1041 status
=U_ZERO_ERROR
;
1042 resultlength
=resultlengthout
+1;
1043 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
1044 udat_getSymbols(datfor
, type
, idx
, result
, resultlength
, &status
);
1046 if(U_FAILURE(status
)){
1047 log_err("FAIL: error in retrieving the value using getSymbols after setting it previously\n %s\n",
1048 myErrorName(status
) );
1052 if(u_strcmp(result
, value
)!=0){
1053 log_err("FAIL:Error in setting and then getting symbols\n Expected %s Got %s\n", austrdup(value
),
1057 log_verbose("PASS: setSymbols successful\n");
1064 static void VerifygetsetSymbols(UDateFormat
* from
, UDateFormat
* to
, UDateFormatSymbolType type
, int32_t idx
)
1068 int32_t resultlength
, resultlengthout
;
1069 UErrorCode status
= U_ZERO_ERROR
;
1072 resultlengthout
=udat_getSymbols(from
, type
, idx
, NULL
, resultlength
, &status
);
1073 if(status
==U_BUFFER_OVERFLOW_ERROR
){
1074 status
=U_ZERO_ERROR
;
1075 resultlength
=resultlengthout
+1;
1076 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
1077 udat_getSymbols(from
, type
, idx
, result
, resultlength
, &status
);
1079 if(U_FAILURE(status
)){
1080 log_err("FAIL: error in getSymbols() %s\n", myErrorName(status
) );
1084 resultlength
=resultlengthout
+1;
1085 udat_setSymbols(to
, type
, idx
, result
, resultlength
, &status
);
1086 if(U_FAILURE(status
))
1088 log_err("FAIL: Error in udat_setSymbols() : %s\n", myErrorName(status
) );
1093 resultlengthout
=udat_getSymbols(to
, type
, idx
, NULL
, resultlength
, &status
);
1094 if(status
==U_BUFFER_OVERFLOW_ERROR
){
1095 status
=U_ZERO_ERROR
;
1096 resultlength
=resultlengthout
+1;
1097 value
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
1098 udat_getSymbols(to
, type
, idx
, value
, resultlength
, &status
);
1100 if(U_FAILURE(status
)){
1101 log_err("FAIL: error in retrieving the value using getSymbols i.e roundtrip\n %s\n",
1102 myErrorName(status
) );
1106 if(u_strcmp(result
, value
)!=0){
1107 log_data_err("FAIL:Error in setting and then getting symbols\n Expected %s Got %s\n", austrdup(result
),
1111 log_verbose("PASS: setSymbols successful\n");
1118 static UChar
* myNumformat(const UNumberFormat
* numfor
, double d
)
1120 UChar
*result2
=NULL
;
1121 int32_t resultlength
, resultlengthneeded
;
1122 UErrorCode status
= U_ZERO_ERROR
;
1125 resultlengthneeded
=unum_formatDouble(numfor
, d
, NULL
, resultlength
, NULL
, &status
);
1126 if(status
==U_BUFFER_OVERFLOW_ERROR
)
1128 status
=U_ZERO_ERROR
;
1129 resultlength
=resultlengthneeded
+1;
1130 /*result2=(UChar*)malloc(sizeof(UChar) * resultlength);*/ /* this leaks */
1131 result2
=(UChar
*)ctst_malloc(sizeof(UChar
) * resultlength
); /*this won't*/
1132 unum_formatDouble(numfor
, d
, result2
, resultlength
, NULL
, &status
);
1134 if(U_FAILURE(status
))
1136 log_err("FAIL: Error in formatting using unum_format(.....) %s\n", myErrorName(status
) );
1144 * The search depth for TestExtremeDates. The total number of
1145 * dates that will be tested is (2^EXTREME_DATES_DEPTH) - 1.
1147 #define EXTREME_DATES_DEPTH 8
1150 * Support for TestExtremeDates (below).
1152 * Test a single date to see whether udat_format handles it properly.
1154 static UBool
_aux1ExtremeDates(UDateFormat
* fmt
, UDate date
,
1155 UChar
* buf
, int32_t buflen
, char* cbuf
,
1157 int32_t len
= udat_format(fmt
, date
, buf
, buflen
, 0, ec
);
1158 if (!assertSuccess("udat_format", ec
)) return FALSE
;
1159 u_austrncpy(cbuf
, buf
, buflen
);
1161 log_err("FAIL: udat_format(%g) => \"%s\"\n", date
, cbuf
);
1163 log_verbose("udat_format(%g) => \"%s\"\n", date
, cbuf
);
1169 * Support for TestExtremeDates (below).
1171 * Recursively test between 'small' and 'large', up to the depth
1172 * limit specified by EXTREME_DATES_DEPTH.
1174 static UBool
_aux2ExtremeDates(UDateFormat
* fmt
, UDate small
, UDate large
,
1175 UChar
* buf
, int32_t buflen
, char* cbuf
,
1178 /* Logarithmic midpoint; see below */
1179 UDate mid
= (UDate
) exp((log(small
) + log(large
)) / 2);
1180 if (count
== EXTREME_DATES_DEPTH
) {
1184 _aux1ExtremeDates(fmt
, mid
, buf
, buflen
, cbuf
, ec
) &&
1185 _aux2ExtremeDates(fmt
, small
, mid
, buf
, buflen
, cbuf
, count
+1, ec
) &&
1186 _aux2ExtremeDates(fmt
, mid
, large
, buf
, buflen
, cbuf
, count
+1, ec
);
1190 * http://www.jtcsv.com/cgibin/icu-bugs?findid=3659
1192 * For certain large dates, udat_format crashes on MacOS. This test
1193 * attempts to reproduce this problem by doing a recursive logarithmic*
1194 * binary search of a predefined interval (from 'small' to 'large').
1196 * The limit of the search is given by EXTREME_DATES_DEPTH, above.
1198 * *The search has to be logarithmic, not linear. A linear search of the
1199 * range 0..10^30, for example, will find 0.5*10^30, then 0.25*10^30 and
1200 * 0.75*10^30, etc. A logarithmic search will find 10^15, then 10^7.5
1203 static void TestExtremeDates() {
1208 const double small
= 1000; /* 1 sec */
1209 const double large
= 1e+30; /* well beyond usable UDate range */
1211 /* There is no need to test larger values from 1e+30 to 1e+300;
1212 the failures occur around 1e+27, and never above 1e+30. */
1215 fmt
= udat_open(UDAT_LONG
, UDAT_LONG
, "en_US",
1217 if (U_FAILURE(ec
)) {
1218 log_data_err("FAIL: udat_open (%s) (Are you missing data?)\n", u_errorName(ec
));
1222 _aux2ExtremeDates(fmt
, small
, large
, buf
, LEN(buf
), cbuf
, 0, &ec
);
1227 static void TestAllLocales(void) {
1228 int32_t idx
, dateIdx
, timeIdx
, localeCount
;
1229 static const UDateFormatStyle style
[] = {
1230 UDAT_FULL
, UDAT_LONG
, UDAT_MEDIUM
, UDAT_SHORT
1232 localeCount
= uloc_countAvailable();
1233 for (idx
= 0; idx
< localeCount
; idx
++) {
1234 for (dateIdx
= 0; dateIdx
< (int32_t)(sizeof(style
)/sizeof(style
[0])); dateIdx
++) {
1235 for (timeIdx
= 0; timeIdx
< (int32_t)(sizeof(style
)/sizeof(style
[0])); timeIdx
++) {
1236 UErrorCode status
= U_ZERO_ERROR
;
1237 udat_close(udat_open(style
[dateIdx
], style
[timeIdx
],
1238 uloc_getAvailable(idx
), NULL
, 0, NULL
, 0, &status
));
1239 if (U_FAILURE(status
)) {
1240 log_err("FAIL: udat_open(%s) failed with (%s) dateIdx=%d, timeIdx=%d\n",
1241 uloc_getAvailable(idx
), u_errorName(status
), dateIdx
, timeIdx
);
1248 static void TestRelativeCrash(void) {
1249 static const UChar tzName
[] = { 0x0055, 0x0053, 0x002F, 0x0050, 0x0061, 0x0063, 0x0069, 0x0066, 0x0069, 0x0063, 0 };
1250 static const UDate aDate
= -631152000000.0;
1252 UErrorCode status
= U_ZERO_ERROR
;
1253 UErrorCode expectStatus
= U_ILLEGAL_ARGUMENT_ERROR
;
1256 icudf
= udat_open(UDAT_NONE
, UDAT_SHORT_RELATIVE
, "en", tzName
, -1, NULL
, 0, &status
);
1257 if ( U_SUCCESS(status
) ) {
1258 const char *what
= "???";
1260 UErrorCode subStatus
= U_ZERO_ERROR
;
1261 what
= "udat_set2DigitYearStart";
1262 log_verbose("Trying %s on a relative date..\n", what
);
1263 udat_set2DigitYearStart(icudf
, aDate
, &subStatus
);
1264 if(subStatus
== expectStatus
) {
1265 log_verbose("Success: did not crash on %s, but got %s.\n", what
, u_errorName(subStatus
));
1267 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what
, u_errorName(subStatus
), u_errorName(expectStatus
));
1271 /* clone works polymorphically. try it anyways */
1272 UErrorCode subStatus
= U_ZERO_ERROR
;
1275 log_verbose("Trying %s on a relative date..\n", what
);
1276 oth
= udat_clone(icudf
, &subStatus
);
1277 if(subStatus
== U_ZERO_ERROR
) {
1278 log_verbose("Success: did not crash on %s, but got %s.\n", what
, u_errorName(subStatus
));
1279 udat_close(oth
); /* ? */
1281 log_err("FAIL: didn't crash on %s, but got %s instead of %s. \n", what
, u_errorName(subStatus
), u_errorName(expectStatus
));
1285 UErrorCode subStatus
= U_ZERO_ERROR
;
1286 what
= "udat_get2DigitYearStart";
1287 log_verbose("Trying %s on a relative date..\n", what
);
1288 udat_get2DigitYearStart(icudf
, &subStatus
);
1289 if(subStatus
== expectStatus
) {
1290 log_verbose("Success: did not crash on %s, but got %s.\n", what
, u_errorName(subStatus
));
1292 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what
, u_errorName(subStatus
), u_errorName(expectStatus
));
1296 /* Now udat_toPattern works for relative date formatters, unless localized is TRUE */
1297 UErrorCode subStatus
= U_ZERO_ERROR
;
1298 what
= "udat_toPattern";
1299 log_verbose("Trying %s on a relative date..\n", what
);
1300 udat_toPattern(icudf
, TRUE
,NULL
,0, &subStatus
);
1301 if(subStatus
== expectStatus
) {
1302 log_verbose("Success: did not crash on %s, but got %s.\n", what
, u_errorName(subStatus
));
1304 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what
, u_errorName(subStatus
), u_errorName(expectStatus
));
1308 UErrorCode subStatus
= U_ZERO_ERROR
;
1309 what
= "udat_applyPattern";
1310 log_verbose("Trying %s on a relative date..\n", what
);
1311 udat_applyPattern(icudf
, FALSE
,tzName
,-1);
1312 subStatus
= U_ILLEGAL_ARGUMENT_ERROR
; /* what it should be, if this took an errorcode. */
1313 if(subStatus
== expectStatus
) {
1314 log_verbose("Success: did not crash on %s, but got %s.\n", what
, u_errorName(subStatus
));
1316 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what
, u_errorName(subStatus
), u_errorName(expectStatus
));
1321 UErrorCode subStatus
= U_ZERO_ERROR
;
1322 what
= "udat_getSymbols";
1323 log_verbose("Trying %s on a relative date..\n", what
);
1324 udat_getSymbols(icudf
, UDAT_ERAS
,0,erabuf
,sizeof(erabuf
)/sizeof(erabuf
[0]), &subStatus
);
1325 if(subStatus
== U_ZERO_ERROR
) {
1326 log_verbose("Success: %s returned %s.\n", what
, u_errorName(subStatus
));
1328 log_err("FAIL: didn't crash on %s, but got %s instead of U_ZERO_ERROR.\n", what
, u_errorName(subStatus
));
1332 UErrorCode subStatus
= U_ZERO_ERROR
;
1333 UChar symbolValue
= 0x0041;
1334 what
= "udat_setSymbols";
1335 log_verbose("Trying %s on a relative date..\n", what
);
1336 udat_setSymbols(icudf
, UDAT_ERAS
,0,&symbolValue
,1, &subStatus
); /* bogus values */
1337 if(subStatus
== expectStatus
) {
1338 log_verbose("Success: did not crash on %s, but got %s.\n", what
, u_errorName(subStatus
));
1340 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what
, u_errorName(subStatus
), u_errorName(expectStatus
));
1344 UErrorCode subStatus
= U_ZERO_ERROR
;
1345 what
= "udat_countSymbols";
1346 log_verbose("Trying %s on a relative date..\n", what
);
1347 udat_countSymbols(icudf
, UDAT_ERAS
);
1348 subStatus
= U_ILLEGAL_ARGUMENT_ERROR
; /* should have an errorcode. */
1349 if(subStatus
== expectStatus
) {
1350 log_verbose("Success: did not crash on %s, but got %s.\n", what
, u_errorName(subStatus
));
1352 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what
, u_errorName(subStatus
), u_errorName(expectStatus
));
1358 log_data_err("FAIL: err calling udat_open() ->%s (Are you missing data?)\n", u_errorName(status
));
1362 static const UChar skeleton_yMMMM
[] = { 0x79,0x4D,0x4D,0x4D,0x4D,0 }; /* "yMMMM"; fr maps to "MMMM y", cs maps to "LLLL y" */
1363 static const UChar july2008_frDefault
[] = { 0x6A,0x75,0x69,0x6C,0x6C,0x65,0x74,0x20,0x32,0x30,0x30,0x38,0 }; /* "juillet 2008" */
1364 static const UChar july2008_frTitle
[] = { 0x4A,0x75,0x69,0x6C,0x6C,0x65,0x74,0x20,0x32,0x30,0x30,0x38,0 }; /* "Juillet 2008" sentence-begin, standalone */
1365 static const UChar july2008_csDefault
[] = { 0x10D,0x65,0x72,0x76,0x65,0x6E,0x65,0x63,0x20,0x32,0x30,0x30,0x38,0 }; /* "c(hacek)ervenec 2008" */
1366 static const UChar july2008_csTitle
[] = { 0x10C,0x65,0x72,0x76,0x65,0x6E,0x65,0x63,0x20,0x32,0x30,0x30,0x38,0 }; /* "C(hacek)ervenec 2008" sentence-begin, uiListOrMenu */
1369 const char * locale
;
1370 const UChar
* skeleton
;
1371 UDisplayContext capitalizationContext
;
1372 const UChar
* expectedFormat
;
1375 static const TestContextItem textContextItems
[] = {
1376 { "fr", skeleton_yMMMM
, UDISPCTX_CAPITALIZATION_NONE
, july2008_frDefault
},
1377 #if !UCONFIG_NO_BREAK_ITERATION
1378 { "fr", skeleton_yMMMM
, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE
, july2008_frDefault
},
1379 { "fr", skeleton_yMMMM
, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE
, july2008_frTitle
},
1380 { "fr", skeleton_yMMMM
, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU
, july2008_frDefault
},
1381 { "fr", skeleton_yMMMM
, UDISPCTX_CAPITALIZATION_FOR_STANDALONE
, july2008_frTitle
},
1383 { "cs", skeleton_yMMMM
, UDISPCTX_CAPITALIZATION_NONE
, july2008_csDefault
},
1384 #if !UCONFIG_NO_BREAK_ITERATION
1385 { "cs", skeleton_yMMMM
, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE
, july2008_csDefault
},
1386 { "cs", skeleton_yMMMM
, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE
, july2008_csTitle
},
1387 { "cs", skeleton_yMMMM
, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU
, july2008_csTitle
},
1388 { "cs", skeleton_yMMMM
, UDISPCTX_CAPITALIZATION_FOR_STANDALONE
, july2008_csDefault
},
1390 { NULL
, NULL
, (UDisplayContext
)0, NULL
}
1393 static const UChar today_enDefault
[] = { 0x74,0x6F,0x64,0x61,0x79,0 }; /* "today" */
1394 static const UChar today_enTitle
[] = { 0x54,0x6F,0x64,0x61,0x79,0 }; /* "Today" sentence-begin, uiListOrMenu, standalone */
1395 static const UChar yesterday_enDefault
[] = { 0x79,0x65,0x73,0x74,0x65,0x72,0x64,0x61,0x79,0 }; /* "yesterday" */
1396 static const UChar yesterday_enTitle
[] = { 0x59,0x65,0x73,0x74,0x65,0x72,0x64,0x61,0x79,0 }; /* "Yesterday" sentence-begin, uiListOrMenu, standalone */
1397 static const UChar today_nbDefault
[] = { 0x69,0x20,0x64,0x61,0x67,0 }; /* "i dag" */
1398 static const UChar today_nbTitle
[] = { 0x49,0x20,0x64,0x61,0x67,0 }; /* "I dag" sentence-begin, standalone */
1399 static const UChar yesterday_nbDefault
[] = { 0x69,0x20,0x67,0xE5,0x72,0 };
1400 static const UChar yesterday_nbTitle
[] = { 0x49,0x20,0x67,0xE5,0x72,0 };
1403 const char * locale
;
1404 UDisplayContext capitalizationContext
;
1405 const UChar
* expectedFormatToday
;
1406 const UChar
* expectedFormatYesterday
;
1407 } TestRelativeContextItem
;
1409 static const TestRelativeContextItem textContextRelativeItems
[] = {
1410 { "en", UDISPCTX_CAPITALIZATION_NONE
, today_enDefault
, yesterday_enDefault
},
1411 #if !UCONFIG_NO_BREAK_ITERATION
1412 { "en", UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE
, today_enDefault
, yesterday_enDefault
},
1413 { "en", UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE
, today_enTitle
, yesterday_enTitle
},
1414 { "en", UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU
, today_enTitle
, yesterday_enTitle
},
1415 { "en", UDISPCTX_CAPITALIZATION_FOR_STANDALONE
, today_enTitle
, yesterday_enTitle
},
1417 { "nb", UDISPCTX_CAPITALIZATION_NONE
, today_nbDefault
, yesterday_nbDefault
},
1418 #if !UCONFIG_NO_BREAK_ITERATION
1419 { "nb", UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE
, today_nbDefault
, yesterday_nbDefault
},
1420 { "nb", UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE
, today_nbTitle
, yesterday_nbTitle
},
1421 { "nb", UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU
, today_nbDefault
, yesterday_nbDefault
},
1422 { "nb", UDISPCTX_CAPITALIZATION_FOR_STANDALONE
, today_nbTitle
, yesterday_nbTitle
},
1424 { NULL
, (UDisplayContext
)0, NULL
, NULL
}
1427 static const UChar zoneGMT
[] = { 0x47,0x4D,0x54,0 }; /* "GMT" */
1428 static const UDate july022008
= 1215000000000.0;
1429 enum { kUbufMax
= 64, kBbufMax
= 3*kUbufMax
};
1431 static void TestContext(void) {
1432 const TestContextItem
* textContextItemPtr
;
1433 const TestRelativeContextItem
* textRelContextItemPtr
;
1434 for (textContextItemPtr
= textContextItems
; textContextItemPtr
->locale
!= NULL
; ++textContextItemPtr
) {
1435 UErrorCode status
= U_ZERO_ERROR
;
1436 UDateTimePatternGenerator
* udtpg
= udatpg_open(textContextItemPtr
->locale
, &status
);
1437 if ( U_SUCCESS(status
) ) {
1438 UChar ubuf
[kUbufMax
];
1439 int32_t len
= udatpg_getBestPattern(udtpg
, textContextItemPtr
->skeleton
, -1, ubuf
, kUbufMax
, &status
);
1440 if ( U_SUCCESS(status
) ) {
1441 UDateFormat
* udfmt
= udat_open(UDAT_PATTERN
, UDAT_PATTERN
, textContextItemPtr
->locale
, zoneGMT
, -1, ubuf
, len
, &status
);
1442 if ( U_SUCCESS(status
) ) {
1443 udat_setContext(udfmt
, textContextItemPtr
->capitalizationContext
, &status
);
1444 if ( U_SUCCESS(status
) ) {
1445 UDisplayContext getContext
;
1446 len
= udat_format(udfmt
, july022008
, ubuf
, kUbufMax
, NULL
, &status
);
1447 if ( U_FAILURE(status
) ) {
1448 log_err("FAIL: udat_format for locale %s, capitalizationContext %d, status %s\n",
1449 textContextItemPtr
->locale
, (int)textContextItemPtr
->capitalizationContext
, u_errorName(status
) );
1450 status
= U_ZERO_ERROR
;
1451 } else if (u_strncmp(ubuf
, textContextItemPtr
->expectedFormat
, kUbufMax
) != 0) {
1452 char bbuf1
[kBbufMax
];
1453 char bbuf2
[kBbufMax
];
1454 log_err("FAIL: udat_format for locale %s, capitalizationContext %d, expected %s, got %s\n",
1455 textContextItemPtr
->locale
, (int)textContextItemPtr
->capitalizationContext
,
1456 u_austrncpy(bbuf1
,textContextItemPtr
->expectedFormat
,kUbufMax
), u_austrncpy(bbuf2
,ubuf
,kUbufMax
) );
1458 getContext
= udat_getContext(udfmt
, UDISPCTX_TYPE_CAPITALIZATION
, &status
);
1459 if ( U_FAILURE(status
) ) {
1460 log_err("FAIL: udat_getContext for locale %s, capitalizationContext %d, status %s\n",
1461 textContextItemPtr
->locale
, (int)textContextItemPtr
->capitalizationContext
, u_errorName(status
) );
1462 } else if (getContext
!= textContextItemPtr
->capitalizationContext
) {
1463 log_err("FAIL: udat_getContext for locale %s, capitalizationContext %d, got context %d\n",
1464 textContextItemPtr
->locale
, (int)textContextItemPtr
->capitalizationContext
, (int)getContext
);
1467 log_err("FAIL: udat_setContext for locale %s, capitalizationContext %d, status %s\n",
1468 textContextItemPtr
->locale
, (int)textContextItemPtr
->capitalizationContext
, u_errorName(status
) );
1472 log_data_err("FAIL: udat_open for locale %s, status %s\n", textContextItemPtr
->locale
, u_errorName(status
) );
1475 log_err("FAIL: udatpg_getBestPattern for locale %s, status %s\n", textContextItemPtr
->locale
, u_errorName(status
) );
1477 udatpg_close(udtpg
);
1479 log_data_err("FAIL: udatpg_open for locale %s, status %s\n", textContextItemPtr
->locale
, u_errorName(status
) );
1482 for (textRelContextItemPtr
= textContextRelativeItems
; textRelContextItemPtr
->locale
!= NULL
; ++textRelContextItemPtr
) {
1483 UErrorCode status
= U_ZERO_ERROR
;
1484 UCalendar
* ucal
= ucal_open(zoneGMT
, -1, "root", UCAL_GREGORIAN
, &status
);
1485 if ( U_SUCCESS(status
) ) {
1486 UDateFormat
* udfmt
= udat_open(UDAT_NONE
, UDAT_LONG_RELATIVE
, textRelContextItemPtr
->locale
, zoneGMT
, -1, NULL
, 0, &status
);
1487 if ( U_SUCCESS(status
) ) {
1488 udat_setContext(udfmt
, textRelContextItemPtr
->capitalizationContext
, &status
);
1489 if ( U_SUCCESS(status
) ) {
1490 UDate yesterday
, today
= ucal_getNow();
1491 UChar ubuf
[kUbufMax
];
1492 char bbuf1
[kBbufMax
];
1493 char bbuf2
[kBbufMax
];
1494 int32_t len
= udat_format(udfmt
, today
, ubuf
, kUbufMax
, NULL
, &status
);
1496 if ( U_FAILURE(status
) ) {
1497 log_err("FAIL: udat_format today for locale %s, capitalizationContext %d, status %s\n",
1498 textRelContextItemPtr
->locale
, (int)textRelContextItemPtr
->capitalizationContext
, u_errorName(status
) );
1499 } else if (u_strncmp(ubuf
, textRelContextItemPtr
->expectedFormatToday
, kUbufMax
) != 0) {
1500 log_err("FAIL: udat_format today for locale %s, capitalizationContext %d, expected %s, got %s\n",
1501 textRelContextItemPtr
->locale
, (int)textRelContextItemPtr
->capitalizationContext
,
1502 u_austrncpy(bbuf1
,textRelContextItemPtr
->expectedFormatToday
,kUbufMax
), u_austrncpy(bbuf2
,ubuf
,kUbufMax
) );
1504 status
= U_ZERO_ERROR
;
1505 ucal_setMillis(ucal
, today
, &status
);
1506 ucal_add(ucal
, UCAL_DATE
, -1, &status
);
1507 yesterday
= ucal_getMillis(ucal
, &status
);
1508 if ( U_SUCCESS(status
) ) {
1509 len
= udat_format(udfmt
, yesterday
, ubuf
, kUbufMax
, NULL
, &status
);
1510 if ( U_FAILURE(status
) ) {
1511 log_err("FAIL: udat_format yesterday for locale %s, capitalizationContext %d, status %s\n",
1512 textRelContextItemPtr
->locale
, (int)textRelContextItemPtr
->capitalizationContext
, u_errorName(status
) );
1513 } else if (u_strncmp(ubuf
, textRelContextItemPtr
->expectedFormatYesterday
, kUbufMax
) != 0) {
1514 log_err("FAIL: udat_format yesterday for locale %s, capitalizationContext %d, expected %s, got %s\n",
1515 textRelContextItemPtr
->locale
, (int)textRelContextItemPtr
->capitalizationContext
,
1516 u_austrncpy(bbuf1
,textRelContextItemPtr
->expectedFormatYesterday
,kUbufMax
), u_austrncpy(bbuf2
,ubuf
,kUbufMax
) );
1520 log_err("FAIL: udat_setContext relative for locale %s, capitalizationContext %d, status %s\n",
1521 textRelContextItemPtr
->locale
, (int)textRelContextItemPtr
->capitalizationContext
, u_errorName(status
) );
1525 log_data_err("FAIL: udat_open relative for locale %s, status %s\n", textRelContextItemPtr
->locale
, u_errorName(status
) );
1529 log_data_err("FAIL: ucal_open for locale root, status %s\n", u_errorName(status
) );
1534 #endif /* #if !UCONFIG_NO_FORMATTING */