1 /********************************************************************
3 * Copyright (c) 1997-2015, 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"
28 #include "unicode/ufieldpositer.h"
33 #include "unicode/uatimeunitformat.h" /* Apple-specific */
37 static void TestExtremeDates(void);
38 static void TestAllLocales(void);
39 static void TestRelativeCrash(void);
40 static void TestContext(void);
41 static void TestCalendarDateParse(void);
42 static void TestParseErrorReturnValue(void);
43 static void TestFormatForFields(void);
44 static void TestApplyPatnOverridesTimeSep(void);
45 static void TestTimeUnitFormat(void); /* Apple-specific */
46 static void TestRemapPatternWithOpts(void); /* Apple-specific */
48 #define LEN(a) (sizeof(a)/sizeof(a[0]))
50 void addDateForTest(TestNode
** root
);
52 #define TESTCASE(x) addTest(root, &x, "tsformat/cdattst/" #x)
54 void addDateForTest(TestNode
** root
)
56 TESTCASE(TestDateFormat
);
57 TESTCASE(TestRelativeDateFormat
);
58 TESTCASE(TestSymbols
);
59 TESTCASE(TestDateFormatCalendar
);
60 TESTCASE(TestExtremeDates
);
61 TESTCASE(TestAllLocales
);
62 TESTCASE(TestRelativeCrash
);
63 TESTCASE(TestContext
);
64 TESTCASE(TestCalendarDateParse
);
65 TESTCASE(TestOverrideNumberFormat
);
66 TESTCASE(TestParseErrorReturnValue
);
67 TESTCASE(TestFormatForFields
);
68 TESTCASE(TestApplyPatnOverridesTimeSep
);
69 TESTCASE(TestTimeUnitFormat
); /* Apple-specific */
70 TESTCASE(TestRemapPatternWithOpts
); /* Apple-specific */
72 /* Testing the DateFormat API */
73 static void TestDateFormat()
75 UDateFormat
*def
, *fr
, *it
, *de
, *def1
, *fr_pat
;
78 UErrorCode status
= U_ZERO_ERROR
;
81 const UNumberFormat
*numformat1
, *numformat2
;
82 UNumberFormat
*adoptNF
;
88 int32_t resultlengthneeded
;
90 UDate d
= 837039928046.0;
91 double num
= -10456.37;
92 /*const char* str="yyyy.MM.dd G 'at' hh:mm:ss z";
93 const char t[]="2/3/76 2:50 AM";*/
94 /*Testing udat_open() to open a dateformat */
96 ctest_setTimeZone(NULL
, &status
);
98 log_verbose("\nTesting udat_open() with various parameters\n");
99 fr
= udat_open(UDAT_FULL
, UDAT_DEFAULT
, "fr_FR", NULL
,0, NULL
, 0,&status
);
100 if(U_FAILURE(status
))
102 log_data_err("FAIL: error in creating the dateformat using full time style with french locale -> %s (Are you missing data?)\n",
103 myErrorName(status
) );
106 /* this is supposed to open default date format, but later on it treats it like it is "en_US"
107 - very bad if you try to run the tests on machine where default locale is NOT "en_US" */
108 /* def = udat_open(UDAT_SHORT, UDAT_SHORT, NULL, NULL, 0, &status); */
109 def
= udat_open(UDAT_SHORT
, UDAT_SHORT
, "en_US", NULL
, 0,NULL
, 0, &status
);
110 if(U_FAILURE(status
))
112 log_err("FAIL: error in creating the dateformat using short date and time style\n %s\n",
113 myErrorName(status
) );
116 it
= udat_open(UDAT_DEFAULT
, UDAT_MEDIUM
, "it_IT", NULL
, 0, NULL
, 0,&status
);
117 if(U_FAILURE(status
))
119 log_err("FAIL: error in creating the dateformat using medium date style with italian locale\n %s\n",
120 myErrorName(status
) );
123 de
= udat_open(UDAT_LONG
, UDAT_LONG
, "de_DE", NULL
, 0, NULL
, 0,&status
);
124 if(U_FAILURE(status
))
126 log_err("FAIL: error in creating the dateformat using long time and date styles with german locale\n %s\n",
127 myErrorName(status
));
130 /*creating a default dateformat */
131 def1
= udat_open(UDAT_SHORT
, UDAT_SHORT
, NULL
, NULL
, 0,NULL
, 0, &status
);
132 if(U_FAILURE(status
))
134 log_err("FAIL: error in creating the dateformat using short date and time style\n %s\n",
135 myErrorName(status
) );
140 /*Testing udat_getAvailable() and udat_countAvailable()*/
141 log_verbose("\nTesting getAvailableLocales and countAvailable()\n");
142 numlocales
=udat_countAvailable();
143 /* use something sensible w/o hardcoding the count */
145 log_data_err("FAIL: error in countAvailable\n");
146 log_verbose("The number of locales for which date/time formatting patterns are available is %d\n", numlocales
);
148 for(i
=0;i
<numlocales
;i
++) {
149 UErrorCode subStatus
= U_ZERO_ERROR
;
150 log_verbose("Testing open of %s\n", udat_getAvailable(i
));
151 any
= udat_open(UDAT_SHORT
, UDAT_SHORT
, udat_getAvailable(i
), NULL
,0, NULL
, 0, &subStatus
);
152 if(U_FAILURE(subStatus
)) {
153 log_data_err("FAIL: date format %s (getAvailable(%d)) is not instantiable: %s\n", udat_getAvailable(i
), i
, u_errorName(subStatus
));
158 /*Testing udat_clone()*/
159 log_verbose("\nTesting the udat_clone() function of date format\n");
160 copy
=udat_clone(def
, &status
);
161 if(U_FAILURE(status
)){
162 log_err("Error in creating the clone using udat_clone: %s\n", myErrorName(status
) );
165 log_err("Error in udat_clone");*/ /*how should i check for equality???? */
167 /*Testing udat_format()*/
168 log_verbose("\nTesting the udat_format() function of date format\n");
169 u_uastrcpy(temp
, "7/10/96, 4:05 PM");
170 /*format using def */
172 resultlengthneeded
=udat_format(def
, d
, NULL
, resultlength
, NULL
, &status
);
173 if(status
==U_BUFFER_OVERFLOW_ERROR
)
176 resultlength
=resultlengthneeded
+1;
181 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
182 udat_format(def
, d
, result
, resultlength
, NULL
, &status
);
184 if(U_FAILURE(status
) || !result
)
186 log_err("FAIL: Error in formatting using udat_format(.....) %s\n", myErrorName(status
) );
190 log_verbose("PASS: formatting successful\n");
191 if(u_strcmp(result
, temp
)==0)
192 log_verbose("PASS: Date Format for US locale successful using udat_format()\n");
196 u_austrcpy(xbuf
, temp
);
197 u_austrcpy(gbuf
, result
);
198 log_err("FAIL: Date Format for US locale failed using udat_format() - expected %s got %s\n", xbuf
, gbuf
);
202 u_unescape("10 juil. 1996 16:05:28 heure d\\u2019\\u00E9t\\u00E9 du Pacifique", temp
, 50);
207 result
=myDateFormat(fr
, d
);
208 if(u_strcmp(result
, temp
)==0)
209 log_verbose("PASS: Date Format for french locale successful using udat_format()\n");
211 log_data_err("FAIL: Date Format for french locale failed using udat_format().\n" );
214 u_uastrcpy(temp
, "10 lug 1996, 16:05:28");
221 fmtted
= myDateFormat(it
,d
);
222 u_austrcpy(g
, fmtted
);
224 if(u_strcmp(fmtted
, temp
)==0) {
225 log_verbose("PASS: Date Format for italian locale successful uisng udat_format() - wanted %s, got %s\n", x
, g
);
227 log_data_err("FAIL: Date Format for italian locale failed using udat_format() - wanted %s, got %s\n", x
, g
);
231 /*Testing parsing using udat_parse()*/
232 log_verbose("\nTesting parsing using udat_parse()\n");
233 u_uastrcpy(temp
,"2/3/76, 2:50 AM");
237 d1
=udat_parse(def
, temp
, u_strlen(temp
), &parsepos
, &status
);
238 if(U_FAILURE(status
))
240 log_err("FAIL: Error in parsing using udat_parse(.....) %s\n", myErrorName(status
) );
243 log_verbose("PASS: parsing succesful\n");
244 /*format it back and check for equality */
247 if(u_strcmp(myDateFormat(def
, d1
),temp
)!=0)
248 log_err("FAIL: error in parsing\n");
250 /*Testing parsing using udat_parse()*/
251 log_verbose("\nTesting parsing using udat_parse()\n");
252 u_uastrcpy(temp
,"2/Don't parse this part");
255 d1
=udat_parse(def
, temp
, u_strlen(temp
), NULL
, &status
);
256 if(status
!= U_PARSE_ERROR
)
258 log_err("FAIL: udat_parse(\"bad string\") passed when it should have failed\n");
261 log_verbose("PASS: parsing succesful\n");
265 /*Testing udat_openPattern() */
267 log_verbose("\nTesting the udat_openPattern with a specified pattern\n");
268 /*for french locale */
269 fr_pat
=udat_open(UDAT_PATTERN
, UDAT_PATTERN
,"fr_FR",NULL
,0,temp
, u_strlen(temp
), &status
);
270 if(U_FAILURE(status
))
272 log_err("FAIL: Error in creating a date format using udat_openPattern \n %s\n",
273 myErrorName(status
) );
276 log_verbose("PASS: creating dateformat using udat_openPattern() succesful\n");
279 /*Testing applyPattern and toPattern */
280 log_verbose("\nTesting applyPattern and toPattern()\n");
281 udat_applyPattern(def1
, FALSE
, temp
, u_strlen(temp
));
282 log_verbose("Extracting the pattern\n");
285 resultlengthneeded
=udat_toPattern(def1
, FALSE
, NULL
, resultlength
, &status
);
286 if(status
==U_BUFFER_OVERFLOW_ERROR
)
289 resultlength
=resultlengthneeded
+ 1;
290 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
291 udat_toPattern(def1
, FALSE
, result
, resultlength
, &status
);
293 if(U_FAILURE(status
))
295 log_err("FAIL: error in extracting the pattern from UNumberFormat\n %s\n",
296 myErrorName(status
) );
298 if(u_strcmp(result
, temp
)!=0)
299 log_err("FAIL: Error in extracting the pattern\n");
301 log_verbose("PASS: applyPattern and toPattern work fine\n");
309 /*Testing getter and setter functions*/
310 /*isLenient and setLenient()*/
311 log_verbose("\nTesting the isLenient and setLenient properties\n");
312 udat_setLenient(fr
, udat_isLenient(it
));
313 if(udat_isLenient(fr
) != udat_isLenient(it
))
314 log_err("ERROR: setLenient() failed\n");
316 log_verbose("PASS: setLenient() successful\n");
319 /*Test get2DigitYearStart set2DigitYearStart */
320 log_verbose("\nTesting the get and set 2DigitYearStart properties\n");
321 d1
= udat_get2DigitYearStart(fr_pat
,&status
);
322 if(U_FAILURE(status
)) {
323 log_err("ERROR: udat_get2DigitYearStart failed %s\n", myErrorName(status
) );
325 status
= U_ZERO_ERROR
;
326 udat_set2DigitYearStart(def1
,d1
, &status
);
327 if(U_FAILURE(status
)) {
328 log_err("ERROR: udat_set2DigitYearStart failed %s\n", myErrorName(status
) );
330 if(udat_get2DigitYearStart(fr_pat
, &status
) != udat_get2DigitYearStart(def1
, &status
))
331 log_err("FAIL: error in set2DigitYearStart\n");
333 log_verbose("PASS: set2DigitYearStart successful\n");
334 /*try setting it to another value */
335 udat_set2DigitYearStart(de
, 2000.0, &status
);
336 if(U_FAILURE(status
)){
337 log_verbose("ERROR: udat_set2DigitYearStart failed %s\n", myErrorName(status
) );
339 if(udat_get2DigitYearStart(de
, &status
) != 2000)
340 log_err("FAIL: error in set2DigitYearStart\n");
342 log_verbose("PASS: set2DigitYearStart successful\n");
346 /*Test getNumberFormat() and setNumberFormat() */
347 log_verbose("\nTesting the get and set NumberFormat properties of date format\n");
348 numformat1
=udat_getNumberFormat(fr_pat
);
349 udat_setNumberFormat(def1
, numformat1
);
350 numformat2
=udat_getNumberFormat(def1
);
351 if(u_strcmp(myNumformat(numformat1
, num
), myNumformat(numformat2
, num
)) !=0)
352 log_err("FAIL: error in setNumberFormat or getNumberFormat()\n");
354 log_verbose("PASS:setNumberFormat and getNumberFormat succesful\n");
356 /*Test getNumberFormat() and adoptNumberFormat() */
357 log_verbose("\nTesting the get and adopt NumberFormat properties of date format\n");
358 adoptNF
= unum_open(UNUM_DEFAULT
, NULL
, 0, NULL
, NULL
, &status
);
359 udat_adoptNumberFormat(def1
, adoptNF
);
360 numformat2
=udat_getNumberFormat(def1
);
361 if(u_strcmp(myNumformat(adoptNF
, num
), myNumformat(numformat2
, num
)) !=0)
362 log_err("FAIL: error in adoptNumberFormat or getNumberFormat()\n");
364 log_verbose("PASS:adoptNumberFormat and getNumberFormat succesful\n");
366 /*try setting the number format to another format */
367 numformat1
=udat_getNumberFormat(def
);
368 udat_setNumberFormat(def1
, numformat1
);
369 numformat2
=udat_getNumberFormat(def1
);
370 if(u_strcmp(myNumformat(numformat1
, num
), myNumformat(numformat2
, num
)) !=0)
371 log_err("FAIL: error in setNumberFormat or getNumberFormat()\n");
373 log_verbose("PASS: setNumberFormat and getNumberFormat succesful\n");
377 /*Test getCalendar and setCalendar*/
378 log_verbose("\nTesting the udat_getCalendar() and udat_setCalendar() properties\n");
379 cal
=udat_getCalendar(fr_pat
);
382 udat_setCalendar(def1
, cal
);
383 if(!ucal_equivalentTo(udat_getCalendar(fr_pat
), udat_getCalendar(def1
)))
384 log_err("FAIL: Error in setting and getting the calendar\n");
386 log_verbose("PASS: getting and setting calendar successful\n");
392 /*Closing the UDateForamt */
401 ctest_resetTimeZone();
405 Test combined relative date formatting (relative date + non-relative time).
406 This is a bit tricky since we can't have static test data for comparison, the
407 relative date formatting is relative to the time the tests are run. We generate
408 the data for comparison dynamically. However, the tests could fail if they are
409 run right at midnight Pacific time and the call to ucal_getNow() is before midnight
410 while the calls to udat_format are after midnight or span midnight.
412 static const UDate dayInterval
= 24.0*60.0*60.0*1000.0;
413 static const UChar trdfZone
[] = { 0x0055, 0x0053, 0x002F, 0x0050, 0x0061, 0x0063, 0x0069, 0x0066, 0x0069, 0x0063, 0 }; /* US/Pacific */
414 static const char trdfLocale
[] = "en_US";
415 static const UChar minutesPatn
[] = { 0x006D, 0x006D, 0 }; /* "mm" */
416 static const UChar monthLongPatn
[] = { 0x004D, 0x004D, 0x004D, 0x004D, 0 }; /* "MMMM" */
417 static const UChar monthMediumPatn
[] = { 0x004D, 0x004D, 0x004D, 0 }; /* "MMM" */
418 static const UChar monthShortPatn
[] = { 0x004D, 0 }; /* "M" */
419 static const UDateFormatStyle dateStylesList
[] = { UDAT_FULL
, UDAT_LONG
, UDAT_MEDIUM
, UDAT_SHORT
, UDAT_NONE
};
420 static const UChar
*monthPatnsList
[] = { monthLongPatn
, monthLongPatn
, monthMediumPatn
, monthShortPatn
, NULL
};
421 static const UChar newTimePatn
[] = { 0x0048, 0x0048, 0x002C, 0x006D, 0x006D, 0 }; /* "HH,mm" */
422 static const UChar minutesStr
[] = { 0x0034, 0x0039, 0 }; /* "49", minutes string to search for in output */
423 enum { kDateOrTimeOutMax
= 96, kDateAndTimeOutMax
= 192 };
425 static const UDate minutesTolerance
= 2 * 60.0 * 1000.0;
426 static const UDate daysTolerance
= 2 * 24.0 * 60.0 * 60.0 * 1000.0;
428 static void TestRelativeDateFormat()
431 const UDateFormatStyle
* stylePtr
;
432 const UChar
** monthPtnPtr
;
433 UErrorCode status
= U_ZERO_ERROR
;
434 UCalendar
* ucal
= ucal_open(trdfZone
, -1, trdfLocale
, UCAL_GREGORIAN
, &status
);
435 if ( U_SUCCESS(status
) ) {
436 int32_t year
, month
, day
;
437 ucal_setMillis(ucal
, ucal_getNow(), &status
);
438 year
= ucal_get(ucal
, UCAL_YEAR
, &status
);
439 month
= ucal_get(ucal
, UCAL_MONTH
, &status
);
440 day
= ucal_get(ucal
, UCAL_DATE
, &status
);
441 ucal_setDateTime(ucal
, year
, month
, day
, 18, 49, 0, &status
); /* set to today at 18:49:00 */
442 today
= ucal_getMillis(ucal
, &status
);
445 if ( U_FAILURE(status
) || today
== 0.0 ) {
446 log_data_err("Generate UDate for a specified time today fails, error %s - (Are you missing data?)\n", myErrorName(status
) );
449 for (stylePtr
= dateStylesList
, monthPtnPtr
= monthPatnsList
; *stylePtr
!= UDAT_NONE
; ++stylePtr
, ++monthPtnPtr
) {
450 UDateFormat
* fmtRelDateTime
;
451 UDateFormat
* fmtRelDate
;
452 UDateFormat
* fmtTime
;
453 int32_t dayOffset
, limit
;
455 UChar strDateTime
[kDateAndTimeOutMax
];
456 UChar strDate
[kDateOrTimeOutMax
];
457 UChar strTime
[kDateOrTimeOutMax
];
461 fmtRelDateTime
= udat_open(UDAT_SHORT
, *stylePtr
| UDAT_RELATIVE
, trdfLocale
, trdfZone
, -1, NULL
, 0, &status
);
462 if ( U_FAILURE(status
) ) {
463 log_data_err("udat_open timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s (Are you missing data?)\n", *stylePtr
, myErrorName(status
) );
466 fmtRelDate
= udat_open(UDAT_NONE
, *stylePtr
| UDAT_RELATIVE
, trdfLocale
, trdfZone
, -1, NULL
, 0, &status
);
467 if ( U_FAILURE(status
) ) {
468 log_err("udat_open timeStyle NONE dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr
, myErrorName(status
) );
469 udat_close(fmtRelDateTime
);
472 fmtTime
= udat_open(UDAT_SHORT
, UDAT_NONE
, trdfLocale
, trdfZone
, -1, NULL
, 0, &status
);
473 if ( U_FAILURE(status
) ) {
474 log_err("udat_open timeStyle SHORT dateStyle NONE fails, error %s\n", myErrorName(status
) );
475 udat_close(fmtRelDateTime
);
476 udat_close(fmtRelDate
);
480 dtpatLen
= udat_toPatternRelativeDate(fmtRelDateTime
, strDate
, kDateAndTimeOutMax
, &status
);
481 if ( U_FAILURE(status
) ) {
482 log_err("udat_toPatternRelativeDate timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr
, myErrorName(status
) );
483 status
= U_ZERO_ERROR
;
484 } else if ( u_strstr(strDate
, *monthPtnPtr
) == NULL
|| dtpatLen
!= u_strlen(strDate
) ) {
485 log_err("udat_toPatternRelativeDate timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) date pattern incorrect\n", *stylePtr
);
487 dtpatLen
= udat_toPatternRelativeTime(fmtRelDateTime
, strTime
, kDateAndTimeOutMax
, &status
);
488 if ( U_FAILURE(status
) ) {
489 log_err("udat_toPatternRelativeTime timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr
, myErrorName(status
) );
490 status
= U_ZERO_ERROR
;
491 } else if ( u_strstr(strTime
, minutesPatn
) == NULL
|| dtpatLen
!= u_strlen(strTime
) ) {
492 log_err("udat_toPatternRelativeTime timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) time pattern incorrect\n", *stylePtr
);
494 dtpatLen
= udat_toPattern(fmtRelDateTime
, FALSE
, strDateTime
, kDateAndTimeOutMax
, &status
);
495 if ( U_FAILURE(status
) ) {
496 log_err("udat_toPattern timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr
, myErrorName(status
) );
497 status
= U_ZERO_ERROR
;
498 } else if ( u_strstr(strDateTime
, strDate
) == NULL
|| u_strstr(strDateTime
, strTime
) == NULL
|| dtpatLen
!= u_strlen(strDateTime
) ) {
499 log_err("udat_toPattern timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) dateTime pattern incorrect\n", *stylePtr
);
501 udat_applyPatternRelative(fmtRelDateTime
, strDate
, u_strlen(strDate
), newTimePatn
, u_strlen(newTimePatn
), &status
);
502 if ( U_FAILURE(status
) ) {
503 log_err("udat_applyPatternRelative timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr
, myErrorName(status
) );
504 status
= U_ZERO_ERROR
;
506 udat_toPattern(fmtRelDateTime
, FALSE
, strDateTime
, kDateAndTimeOutMax
, &status
);
507 if ( U_FAILURE(status
) ) {
508 log_err("udat_toPattern timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr
, myErrorName(status
) );
509 status
= U_ZERO_ERROR
;
510 } else if ( u_strstr(strDateTime
, newTimePatn
) == NULL
) {
511 log_err("udat_applyPatternRelative timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) didn't update time pattern\n", *stylePtr
);
514 udat_applyPatternRelative(fmtRelDateTime
, strDate
, u_strlen(strDate
), strTime
, u_strlen(strTime
), &status
); /* restore original */
516 fp
.field
= UDAT_MINUTE_FIELD
;
517 for (dayOffset
= -2, limit
= 2; dayOffset
<= limit
; ++dayOffset
) {
518 UDate dateToUse
= today
+ (float)dayOffset
*dayInterval
;
520 udat_format(fmtRelDateTime
, dateToUse
, strDateTime
, kDateAndTimeOutMax
, &fp
, &status
);
521 if ( U_FAILURE(status
) ) {
522 log_err("udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr
, myErrorName(status
) );
523 status
= U_ZERO_ERROR
;
525 int32_t parsePos
= 0;
526 UDate dateResult
= udat_parse(fmtRelDateTime
, strDateTime
, -1, &parsePos
, &status
);
527 UDate dateDiff
= (dateResult
>= dateToUse
)? dateResult
- dateToUse
: dateToUse
- dateResult
;
528 if ( U_FAILURE(status
) || dateDiff
> minutesTolerance
) {
529 log_err("udat_parse timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s, expect approx %.1f, got %.1f, parsePos %d\n",
530 *stylePtr
, myErrorName(status
), dateToUse
, dateResult
, parsePos
);
531 status
= U_ZERO_ERROR
;
534 udat_format(fmtRelDate
, dateToUse
, strDate
, kDateOrTimeOutMax
, NULL
, &status
);
535 if ( U_FAILURE(status
) ) {
536 log_err("udat_format timeStyle NONE dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr
, myErrorName(status
) );
537 status
= U_ZERO_ERROR
;
538 } else if ( u_strstr(strDateTime
, strDate
) == NULL
) {
539 log_err("relative date string not found in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", *stylePtr
);
542 dateResult
= udat_parse(fmtRelDate
, strDate
, -1, &parsePos
, &status
);
543 dateDiff
= (dateResult
>= dateToUse
)? dateResult
- dateToUse
: dateToUse
- dateResult
;
544 if ( U_FAILURE(status
) || dateDiff
> daysTolerance
) {
545 log_err("udat_parse timeStyle NONE dateStyle (%d | UDAT_RELATIVE) fails, error %s, expect approx %.1f, got %.1f, parsePos %d\n",
546 *stylePtr
, myErrorName(status
), dateToUse
, dateResult
, parsePos
);
547 status
= U_ZERO_ERROR
;
551 udat_format(fmtTime
, dateToUse
, strTime
, kDateOrTimeOutMax
, NULL
, &status
);
552 if ( U_FAILURE(status
) ) {
553 log_err("udat_format timeStyle SHORT dateStyle NONE fails, error %s\n", myErrorName(status
) );
554 status
= U_ZERO_ERROR
;
555 } else if ( u_strstr(strDateTime
, strTime
) == NULL
) {
556 log_err("time string not found in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", *stylePtr
);
559 strPtr
= u_strstr(strDateTime
, minutesStr
);
560 if ( strPtr
!= NULL
) {
561 int32_t beginIndex
= strPtr
- strDateTime
;
562 if ( fp
.beginIndex
!= beginIndex
) {
563 log_err("UFieldPosition beginIndex %d, expected %d, in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", fp
.beginIndex
, beginIndex
, *stylePtr
);
566 log_err("minutes string not found in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", *stylePtr
);
571 udat_close(fmtRelDateTime
);
572 udat_close(fmtRelDate
);
577 /*Testing udat_getSymbols() and udat_setSymbols() and udat_countSymbols()*/
578 static void TestSymbols()
580 UDateFormat
*def
, *fr
, *zhChiCal
;
581 UErrorCode status
= U_ZERO_ERROR
;
583 UChar
*result
= NULL
;
584 int32_t resultlength
;
585 int32_t resultlengthout
;
589 /*creating a dateformat with french locale */
590 log_verbose("\ncreating a date format with french locale\n");
591 fr
= udat_open(UDAT_FULL
, UDAT_DEFAULT
, "fr_FR", NULL
, 0, NULL
, 0, &status
);
592 if(U_FAILURE(status
))
594 log_data_err("error in creating the dateformat using full time style with french locale -> %s (Are you missing data?)\n",
595 myErrorName(status
) );
598 /*creating a default dateformat */
599 log_verbose("\ncreating a date format with default locale\n");
600 /* this is supposed to open default date format, but later on it treats it like it is "en_US"
601 - very bad if you try to run the tests on machine where default locale is NOT "en_US" */
602 /* def = udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,NULL, NULL, 0, &status); */
603 def
= udat_open(UDAT_DEFAULT
,UDAT_DEFAULT
,"en_US", NULL
, 0, NULL
, 0, &status
);
604 if(U_FAILURE(status
))
606 log_err("error in creating the dateformat using short date and time style\n %s\n",
607 myErrorName(status
) );
610 /*creating a dateformat with zh locale */
611 log_verbose("\ncreating a date format with zh locale for chinese calendar\n");
612 zhChiCal
= udat_open(UDAT_NONE
, UDAT_FULL
, "zh@calendar=chinese", NULL
, 0, NULL
, 0, &status
);
613 if(U_FAILURE(status
))
615 log_data_err("error in creating the dateformat using full date, no time, locale zh@calendar=chinese -> %s (Are you missing data?)\n",
616 myErrorName(status
) );
621 /*Testing countSymbols, getSymbols and setSymbols*/
622 log_verbose("\nTesting countSymbols\n");
623 /*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 */
624 if(udat_countSymbols(def
, UDAT_ERAS
)!=2 || udat_countSymbols(def
, UDAT_MONTHS
)!=12 ||
625 udat_countSymbols(def
, UDAT_SHORT_MONTHS
)!=12 || udat_countSymbols(def
, UDAT_WEEKDAYS
)!=8 ||
626 udat_countSymbols(def
, UDAT_SHORT_WEEKDAYS
)!=8 || udat_countSymbols(def
, UDAT_AM_PMS
)!=2 ||
627 udat_countSymbols(def
, UDAT_QUARTERS
) != 4 || udat_countSymbols(def
, UDAT_SHORT_QUARTERS
) != 4 ||
628 udat_countSymbols(def
, UDAT_LOCALIZED_CHARS
)!=1 || udat_countSymbols(def
, UDAT_SHORTER_WEEKDAYS
)!=8 ||
629 udat_countSymbols(zhChiCal
, UDAT_CYCLIC_YEARS_NARROW
)!=60 || udat_countSymbols(zhChiCal
, UDAT_ZODIAC_NAMES_NARROW
)!=12)
631 log_err("FAIL: error in udat_countSymbols\n");
634 log_verbose("PASS: udat_countSymbols() successful\n");
636 /*testing getSymbols*/
637 log_verbose("\nTesting getSymbols\n");
638 pattern
=(UChar
*)malloc(sizeof(UChar
) * 10);
639 u_uastrcpy(pattern
, "jeudi");
641 resultlengthout
=udat_getSymbols(fr
, UDAT_WEEKDAYS
, 5 , NULL
, resultlength
, &status
);
642 if(status
==U_BUFFER_OVERFLOW_ERROR
)
645 resultlength
=resultlengthout
+1;
650 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
651 udat_getSymbols(fr
, UDAT_WEEKDAYS
, 5, result
, resultlength
, &status
);
654 if(U_FAILURE(status
))
656 log_err("FAIL: Error in udat_getSymbols().... %s\n", myErrorName(status
) );
659 log_verbose("PASS: getSymbols succesful\n");
661 if(u_strcmp(result
, pattern
)==0)
662 log_verbose("PASS: getSymbols retrieved the right value\n");
664 log_data_err("FAIL: getSymbols retrieved the wrong value\n");
666 /*run series of tests to test getsymbols regressively*/
667 log_verbose("\nTesting getSymbols() regressively\n");
668 VerifygetSymbols(fr
, UDAT_WEEKDAYS
, 1, "dimanche");
669 VerifygetSymbols(def
, UDAT_WEEKDAYS
, 1, "Sunday");
670 VerifygetSymbols(fr
, UDAT_SHORT_WEEKDAYS
, 7, "sam.");
671 VerifygetSymbols(fr
, UDAT_SHORTER_WEEKDAYS
, 7, "sa");
672 VerifygetSymbols(def
, UDAT_SHORT_WEEKDAYS
, 7, "Sat");
673 VerifygetSymbols(def
, UDAT_MONTHS
, 11, "December");
674 VerifygetSymbols(def
, UDAT_MONTHS
, 0, "January");
675 VerifygetSymbols(fr
, UDAT_ERAS
, 0, "av. J.-C.");
676 VerifygetSymbols(def
, UDAT_AM_PMS
, 0, "AM");
677 VerifygetSymbols(def
, UDAT_AM_PMS
, 1, "PM");
678 VerifygetSymbols(fr
, UDAT_SHORT_MONTHS
, 0, "janv.");
679 VerifygetSymbols(def
, UDAT_SHORT_MONTHS
, 11, "Dec");
680 VerifygetSymbols(fr
, UDAT_QUARTERS
, 0, "1er trimestre");
681 VerifygetSymbols(def
, UDAT_QUARTERS
, 3, "4th quarter");
682 VerifygetSymbols(fr
, UDAT_SHORT_QUARTERS
, 1, "T2");
683 VerifygetSymbols(def
, UDAT_SHORT_QUARTERS
, 2, "Q3");
684 VerifygetSymbols(zhChiCal
, UDAT_CYCLIC_YEARS_ABBREVIATED
, 0, "\\u7532\\u5B50");
685 VerifygetSymbols(zhChiCal
, UDAT_CYCLIC_YEARS_NARROW
, 59, "\\u7678\\u4EA5");
686 VerifygetSymbols(zhChiCal
, UDAT_ZODIAC_NAMES_ABBREVIATED
, 0, "\\u9F20");
687 VerifygetSymbols(zhChiCal
, UDAT_ZODIAC_NAMES_WIDE
, 11, "\\u732A");
688 VerifygetSymbols(def
,UDAT_LOCALIZED_CHARS
, 0, "GyMdkHmsSEDFwWahKzYeugAZvcLQqVUOXxr:");
697 log_verbose("\nTesting setSymbols\n");
698 /*applying the pattern so that setSymbolss works */
700 resultlengthout
=udat_toPattern(fr
, FALSE
, NULL
, resultlength
, &status
);
701 if(status
==U_BUFFER_OVERFLOW_ERROR
)
704 resultlength
=resultlengthout
+ 1;
705 pattern
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
706 udat_toPattern(fr
, FALSE
, pattern
, resultlength
, &status
);
708 if(U_FAILURE(status
))
710 log_err("FAIL: error in extracting the pattern from UNumberFormat\n %s\n",
711 myErrorName(status
) );
714 udat_applyPattern(def
, FALSE
, pattern
, u_strlen(pattern
));
716 resultlengthout
=udat_toPattern(def
, FALSE
, NULL
, resultlength
,&status
);
717 if(status
==U_BUFFER_OVERFLOW_ERROR
)
720 resultlength
=resultlengthout
+ 1;
725 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
726 udat_toPattern(fr
, FALSE
,result
, resultlength
, &status
);
728 if(U_FAILURE(status
))
730 log_err("FAIL: error in extracting the pattern from UNumberFormat\n %s\n",
731 myErrorName(status
) );
733 if(u_strcmp(result
, pattern
)==0)
734 log_verbose("Pattern applied properly\n");
736 log_err("pattern could not be applied properly\n");
739 /*testing set symbols */
741 resultlengthout
=udat_getSymbols(fr
, UDAT_MONTHS
, 11 , NULL
, resultlength
, &status
);
742 if(status
==U_BUFFER_OVERFLOW_ERROR
){
744 resultlength
=resultlengthout
+1;
749 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
750 udat_getSymbols(fr
, UDAT_MONTHS
, 11, result
, resultlength
, &status
);
753 if(U_FAILURE(status
))
754 log_err("FAIL: error in getSymbols() %s\n", myErrorName(status
) );
755 resultlength
=resultlengthout
+1;
757 udat_setSymbols(def
, UDAT_MONTHS
, 11, result
, resultlength
, &status
);
758 if(U_FAILURE(status
))
760 log_err("FAIL: Error in udat_setSymbols() : %s\n", myErrorName(status
) );
763 log_verbose("PASS: SetSymbols successful\n");
766 resultlengthout
=udat_getSymbols(def
, UDAT_MONTHS
, 11, NULL
, resultlength
, &status
);
767 if(status
==U_BUFFER_OVERFLOW_ERROR
){
769 resultlength
=resultlengthout
+1;
770 value
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
771 udat_getSymbols(def
, UDAT_MONTHS
, 11, value
, resultlength
, &status
);
773 if(U_FAILURE(status
))
774 log_err("FAIL: error in retrieving the value using getSymbols i.e roundtrip\n");
776 if(u_strcmp(result
, value
)!=0)
777 log_data_err("FAIL: Error in settting and getting symbols\n");
779 log_verbose("PASS: setSymbols successful\n");
782 /*run series of tests to test setSymbols regressively*/
783 log_verbose("\nTesting setSymbols regressively\n");
784 VerifysetSymbols(def
, UDAT_ERAS
, 0, "BeforeChrist");
785 VerifysetSymbols(def
, UDAT_ERA_NAMES
, 1, "AnnoDomini");
786 VerifysetSymbols(def
, UDAT_WEEKDAYS
, 1, "Sundayweek");
787 VerifysetSymbols(def
, UDAT_SHORT_WEEKDAYS
, 7, "Satweek");
788 VerifysetSymbols(def
, UDAT_NARROW_WEEKDAYS
, 4, "M");
789 VerifysetSymbols(def
, UDAT_STANDALONE_WEEKDAYS
, 1, "Sonntagweek");
790 VerifysetSymbols(def
, UDAT_STANDALONE_SHORT_WEEKDAYS
, 7, "Sams");
791 VerifysetSymbols(def
, UDAT_STANDALONE_NARROW_WEEKDAYS
, 4, "V");
792 VerifysetSymbols(fr
, UDAT_MONTHS
, 11, "december");
793 VerifysetSymbols(fr
, UDAT_SHORT_MONTHS
, 0, "Jan");
794 VerifysetSymbols(fr
, UDAT_NARROW_MONTHS
, 1, "R");
795 VerifysetSymbols(fr
, UDAT_STANDALONE_MONTHS
, 11, "dezember");
796 VerifysetSymbols(fr
, UDAT_STANDALONE_SHORT_MONTHS
, 7, "Aug");
797 VerifysetSymbols(fr
, UDAT_STANDALONE_NARROW_MONTHS
, 2, "M");
798 VerifysetSymbols(fr
, UDAT_QUARTERS
, 0, "1. Quart");
799 VerifysetSymbols(fr
, UDAT_SHORT_QUARTERS
, 1, "QQ2");
800 VerifysetSymbols(fr
, UDAT_STANDALONE_QUARTERS
, 2, "3rd Quar.");
801 VerifysetSymbols(fr
, UDAT_STANDALONE_SHORT_QUARTERS
, 3, "4QQ");
802 VerifysetSymbols(zhChiCal
, UDAT_CYCLIC_YEARS_ABBREVIATED
, 1, "yi-chou");
803 VerifysetSymbols(zhChiCal
, UDAT_ZODIAC_NAMES_ABBREVIATED
, 1, "Ox");
806 /*run series of tests to test get and setSymbols regressively*/
807 log_verbose("\nTesting get and set symbols regressively\n");
808 VerifygetsetSymbols(fr
, def
, UDAT_WEEKDAYS
, 1);
809 VerifygetsetSymbols(fr
, def
, UDAT_WEEKDAYS
, 7);
810 VerifygetsetSymbols(fr
, def
, UDAT_SHORT_WEEKDAYS
, 1);
811 VerifygetsetSymbols(fr
, def
, UDAT_SHORT_WEEKDAYS
, 7);
812 VerifygetsetSymbols(fr
, def
, UDAT_MONTHS
, 0);
813 VerifygetsetSymbols(fr
, def
, UDAT_SHORT_MONTHS
, 0);
814 VerifygetsetSymbols(fr
, def
, UDAT_ERAS
,1);
815 VerifygetsetSymbols(fr
, def
, UDAT_LOCALIZED_CHARS
, 0);
816 VerifygetsetSymbols(fr
, def
, UDAT_AM_PMS
, 1);
823 udat_close(zhChiCal
);
833 * Test DateFormat(Calendar) API
835 static void TestDateFormatCalendar() {
836 UDateFormat
*date
=0, *time
=0, *full
=0;
842 UErrorCode ec
= U_ZERO_ERROR
;
845 const char *expected
;
848 ctest_setTimeZone(NULL
, &ec
);
850 /* Create a formatter for date fields. */
851 date
= udat_open(UDAT_NONE
, UDAT_SHORT
, "en_US", NULL
, 0, NULL
, 0, &ec
);
853 log_data_err("FAIL: udat_open(NONE, SHORT, en_US) failed with %s (Are you missing data?)\n",
858 /* Create a formatter for time fields. */
859 time
= udat_open(UDAT_SHORT
, UDAT_NONE
, "en_US", NULL
, 0, NULL
, 0, &ec
);
861 log_err("FAIL: udat_open(SHORT, NONE, en_US) failed with %s\n",
866 /* Create a full format for output */
867 full
= udat_open(UDAT_FULL
, UDAT_FULL
, "en_US", NULL
, 0, NULL
, 0, &ec
);
869 log_err("FAIL: udat_open(FULL, FULL, en_US) failed with %s\n",
874 /* Create a calendar */
875 cal
= ucal_open(NULL
, 0, "en_US", UCAL_GREGORIAN
, &ec
);
877 log_err("FAIL: ucal_open(en_US) failed with %s\n",
884 u_uastrcpy(buf
, "4/5/2001");
886 udat_parseCalendar(date
, cal
, buf
, -1, &pos
, &ec
);
888 log_err("FAIL: udat_parseCalendar(4/5/2001) failed at %d with %s\n",
889 pos
, u_errorName(ec
));
893 /* Check if formatCalendar matches the original date */
894 len1
= udat_formatCalendar(date
, cal
, buf1
, UPRV_LENGTHOF(buf1
), NULL
, &ec
);
896 log_err("FAIL: udat_formatCalendar(4/5/2001) failed with %s\n",
901 u_uastrcpy(uExpected
, expected
);
902 if (u_strlen(uExpected
) != len1
|| u_strncmp(uExpected
, buf1
, len1
) != 0) {
903 log_err("FAIL: udat_formatCalendar(4/5/2001), expected: %s", expected
);
907 u_uastrcpy(buf
, "5:45 PM");
909 udat_parseCalendar(time
, cal
, buf
, -1, &pos
, &ec
);
911 log_err("FAIL: udat_parseCalendar(17:45) failed at %d with %s\n",
912 pos
, u_errorName(ec
));
916 /* Check if formatCalendar matches the original time */
917 len1
= udat_formatCalendar(time
, cal
, buf1
, UPRV_LENGTHOF(buf1
), NULL
, &ec
);
919 log_err("FAIL: udat_formatCalendar(17:45) failed with %s\n",
923 expected
= "5:45 PM";
924 u_uastrcpy(uExpected
, expected
);
925 if (u_strlen(uExpected
) != len1
|| u_strncmp(uExpected
, buf1
, len1
) != 0) {
926 log_err("FAIL: udat_formatCalendar(17:45), expected: %s", expected
);
930 when
= ucal_getMillis(cal
, &ec
);
932 log_err("FAIL: ucal_getMillis() failed with %s\n", u_errorName(ec
));
935 udat_format(full
, when
, buf
, sizeof(buf
), NULL
, &ec
);
937 log_err("FAIL: udat_format() failed with %s\n", u_errorName(ec
));
940 u_austrcpy(cbuf
, buf
);
941 /* Thursday, April 5, 2001 5:45:00 PM PDT 986517900000 */
942 if (when
== 986517900000.0) {
943 log_verbose("Ok: Parsed result: %s\n", cbuf
);
945 log_err("FAIL: Parsed result: %s, exp 4/5/2001 5:45 PM\n", cbuf
);
954 ctest_resetTimeZone();
960 * Test parsing two digit year against "YY" vs. "YYYY" patterns
962 static void TestCalendarDateParse() {
965 UErrorCode ec
= U_ZERO_ERROR
;
966 UDateFormat
* simpleDateFormat
= 0;
967 int32_t parsePos
= 0;
968 int32_t twoDigitCenturyStart
= 75;
969 int32_t currentTwoDigitYear
= 0;
970 int32_t startCentury
= 0;
971 UCalendar
* tempCal
= 0;
972 UCalendar
* calendar
= 0;
974 U_STRING_DECL(pattern
, "yyyy", 4);
975 U_STRING_DECL(pattern2
, "yy", 2);
976 U_STRING_DECL(text
, "75", 2);
978 U_STRING_INIT(pattern
, "yyyy", 4);
979 U_STRING_INIT(pattern2
, "yy", 2);
980 U_STRING_INIT(text
, "75", 2);
982 simpleDateFormat
= udat_open(UDAT_FULL
, UDAT_FULL
, "en-GB", 0, 0, 0, 0, &ec
);
984 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
));
987 udat_applyPattern(simpleDateFormat
, 0, pattern
, u_strlen(pattern
));
988 udat_setLenient(simpleDateFormat
, 0);
990 currentTwoDigitYear
= getCurrentYear() % 100;
991 startCentury
= getCurrentYear() - currentTwoDigitYear
;
992 if (twoDigitCenturyStart
> currentTwoDigitYear
) {
995 tempCal
= ucal_open(NULL
, -1, NULL
, UCAL_GREGORIAN
, &ec
);
996 ucal_setMillis(tempCal
, 0, &ec
);
997 ucal_setDateTime(tempCal
, startCentury
+ twoDigitCenturyStart
, UCAL_JANUARY
, 1, 0, 0, 0, &ec
);
998 udat_set2DigitYearStart(simpleDateFormat
, ucal_getMillis(tempCal
, &ec
), &ec
);
1000 calendar
= ucal_open(NULL
, -1, NULL
, UCAL_GREGORIAN
, &ec
);
1001 ucal_setMillis(calendar
, 0, &ec
);
1002 ucal_setDateTime(calendar
, twoDigitCenturyStart
, UCAL_JANUARY
, 1, 0, 0, 0, &ec
);
1004 udat_parseCalendar(simpleDateFormat
, calendar
, text
, u_strlen(text
), &parsePos
, &ec
);
1007 result
= ucal_get(calendar
, UCAL_YEAR
, &ec
);
1008 if (U_FAILURE(ec
)) {
1009 log_err("FAIL: ucal_get(UCAL_YEAR) failed with %s\n", u_errorName(ec
));
1014 log_err("FAIL: parsed incorrect year: %d\n", result
);
1019 udat_applyPattern(simpleDateFormat
, 0, pattern2
, u_strlen(pattern2
));
1020 udat_parseCalendar(simpleDateFormat
, calendar
, text
, u_strlen(text
), &parsePos
, &ec
);
1023 result
= ucal_get(calendar
, UCAL_YEAR
, &ec
);
1024 if (U_FAILURE(ec
)) {
1025 log_err("FAIL: ucal_get(UCAL_YEAR) failed with %s\n", u_errorName(ec
));
1029 if (result
!= 1975) {
1030 log_err("FAIL: parsed incorrect year: %d\n", result
);
1035 udat_close(simpleDateFormat
);
1036 udat_close(tempCal
);
1037 udat_close(calendar
);
1041 /*INTERNAL FUNCTIONS USED*/
1042 static int getCurrentYear() {
1043 static int currentYear
= 0;
1044 if (currentYear
== 0) {
1045 UErrorCode status
= U_ZERO_ERROR
;
1046 UCalendar
*cal
= ucal_open(NULL
, -1, NULL
, UCAL_GREGORIAN
, &status
);
1047 if (!U_FAILURE(status
)) {
1048 /* Get the current year from the default UCalendar */
1049 currentYear
= ucal_get(cal
, UCAL_YEAR
, &status
);
1057 /* N.B.: use idx instead of index to avoid 'shadow' warnings in strict mode. */
1058 static void VerifygetSymbols(UDateFormat
* datfor
, UDateFormatSymbolType type
, int32_t idx
, const char* expected
)
1060 UChar
*pattern
=NULL
;
1061 UErrorCode status
= U_ZERO_ERROR
;
1063 int32_t resultlength
, resultlengthout
;
1064 int32_t patternSize
= strlen(expected
) + 1;
1066 pattern
=(UChar
*)malloc(sizeof(UChar
) * patternSize
);
1067 u_unescape(expected
, pattern
, patternSize
);
1069 resultlengthout
=udat_getSymbols(datfor
, type
, idx
, NULL
, resultlength
, &status
);
1070 if(status
==U_BUFFER_OVERFLOW_ERROR
)
1072 status
=U_ZERO_ERROR
;
1073 resultlength
=resultlengthout
+1;
1074 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
1075 udat_getSymbols(datfor
, type
, idx
, result
, resultlength
, &status
);
1078 if(U_FAILURE(status
))
1080 log_err("FAIL: Error in udat_getSymbols()... %s\n", myErrorName(status
) );
1083 if(u_strcmp(result
, pattern
)==0)
1084 log_verbose("PASS: getSymbols retrieved the right value\n");
1086 log_data_err("FAIL: getSymbols retrieved the wrong value\n Expected %s Got %s\n", expected
,
1087 aescstrdup(result
,-1) );
1093 static void VerifysetSymbols(UDateFormat
* datfor
, UDateFormatSymbolType type
, int32_t idx
, const char* expected
)
1097 int32_t resultlength
, resultlengthout
;
1098 UErrorCode status
= U_ZERO_ERROR
;
1099 int32_t valueLen
, valueSize
= strlen(expected
) + 1;
1101 value
=(UChar
*)malloc(sizeof(UChar
) * valueSize
);
1102 valueLen
= u_unescape(expected
, value
, valueSize
);
1103 udat_setSymbols(datfor
, type
, idx
, value
, valueLen
, &status
);
1104 if(U_FAILURE(status
))
1106 log_err("FAIL: Error in udat_setSymbols() %s\n", myErrorName(status
) );
1111 resultlengthout
=udat_getSymbols(datfor
, type
, idx
, NULL
, resultlength
, &status
);
1112 if(status
==U_BUFFER_OVERFLOW_ERROR
){
1113 status
=U_ZERO_ERROR
;
1114 resultlength
=resultlengthout
+1;
1115 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
1116 udat_getSymbols(datfor
, type
, idx
, result
, resultlength
, &status
);
1118 if(U_FAILURE(status
)){
1119 log_err("FAIL: error in retrieving the value using getSymbols after setting it previously\n %s\n",
1120 myErrorName(status
) );
1124 if(u_strcmp(result
, value
)!=0){
1125 log_err("FAIL:Error in setting and then getting symbols\n Expected %s Got %s\n", expected
,
1126 aescstrdup(result
,-1) );
1129 log_verbose("PASS: setSymbols successful\n");
1136 static void VerifygetsetSymbols(UDateFormat
* from
, UDateFormat
* to
, UDateFormatSymbolType type
, int32_t idx
)
1140 int32_t resultlength
, resultlengthout
;
1141 UErrorCode status
= U_ZERO_ERROR
;
1144 resultlengthout
=udat_getSymbols(from
, type
, idx
, NULL
, resultlength
, &status
);
1145 if(status
==U_BUFFER_OVERFLOW_ERROR
){
1146 status
=U_ZERO_ERROR
;
1147 resultlength
=resultlengthout
+1;
1148 result
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
1149 udat_getSymbols(from
, type
, idx
, result
, resultlength
, &status
);
1151 if(U_FAILURE(status
)){
1152 log_err("FAIL: error in getSymbols() %s\n", myErrorName(status
) );
1156 resultlength
=resultlengthout
+1;
1157 udat_setSymbols(to
, type
, idx
, result
, resultlength
, &status
);
1158 if(U_FAILURE(status
))
1160 log_err("FAIL: Error in udat_setSymbols() : %s\n", myErrorName(status
) );
1165 resultlengthout
=udat_getSymbols(to
, type
, idx
, NULL
, resultlength
, &status
);
1166 if(status
==U_BUFFER_OVERFLOW_ERROR
){
1167 status
=U_ZERO_ERROR
;
1168 resultlength
=resultlengthout
+1;
1169 value
=(UChar
*)malloc(sizeof(UChar
) * resultlength
);
1170 udat_getSymbols(to
, type
, idx
, value
, resultlength
, &status
);
1172 if(U_FAILURE(status
)){
1173 log_err("FAIL: error in retrieving the value using getSymbols i.e roundtrip\n %s\n",
1174 myErrorName(status
) );
1178 if(u_strcmp(result
, value
)!=0){
1179 log_data_err("FAIL:Error in setting and then getting symbols\n Expected %s Got %s\n", austrdup(result
),
1183 log_verbose("PASS: setSymbols successful\n");
1190 static UChar
* myNumformat(const UNumberFormat
* numfor
, double d
)
1192 UChar
*result2
=NULL
;
1193 int32_t resultlength
, resultlengthneeded
;
1194 UErrorCode status
= U_ZERO_ERROR
;
1197 resultlengthneeded
=unum_formatDouble(numfor
, d
, NULL
, resultlength
, NULL
, &status
);
1198 if(status
==U_BUFFER_OVERFLOW_ERROR
)
1200 status
=U_ZERO_ERROR
;
1201 resultlength
=resultlengthneeded
+1;
1202 /*result2=(UChar*)malloc(sizeof(UChar) * resultlength);*/ /* this leaks */
1203 result2
=(UChar
*)ctst_malloc(sizeof(UChar
) * resultlength
); /*this won't*/
1204 unum_formatDouble(numfor
, d
, result2
, resultlength
, NULL
, &status
);
1206 if(U_FAILURE(status
))
1208 log_err("FAIL: Error in formatting using unum_format(.....) %s\n", myErrorName(status
) );
1216 * The search depth for TestExtremeDates. The total number of
1217 * dates that will be tested is (2^EXTREME_DATES_DEPTH) - 1.
1219 #define EXTREME_DATES_DEPTH 8
1222 * Support for TestExtremeDates (below).
1224 * Test a single date to see whether udat_format handles it properly.
1226 static UBool
_aux1ExtremeDates(UDateFormat
* fmt
, UDate date
,
1227 UChar
* buf
, int32_t buflen
, char* cbuf
,
1229 int32_t len
= udat_format(fmt
, date
, buf
, buflen
, 0, ec
);
1230 if (!assertSuccess("udat_format", ec
)) return FALSE
;
1231 u_austrncpy(cbuf
, buf
, buflen
);
1233 log_err("FAIL: udat_format(%g) => \"%s\"\n", date
, cbuf
);
1235 log_verbose("udat_format(%g) => \"%s\"\n", date
, cbuf
);
1241 * Support for TestExtremeDates (below).
1243 * Recursively test between 'small' and 'large', up to the depth
1244 * limit specified by EXTREME_DATES_DEPTH.
1246 static UBool
_aux2ExtremeDates(UDateFormat
* fmt
, UDate small
, UDate large
,
1247 UChar
* buf
, int32_t buflen
, char* cbuf
,
1250 /* Logarithmic midpoint; see below */
1251 UDate mid
= (UDate
) exp((log(small
) + log(large
)) / 2);
1252 if (count
== EXTREME_DATES_DEPTH
) {
1256 _aux1ExtremeDates(fmt
, mid
, buf
, buflen
, cbuf
, ec
) &&
1257 _aux2ExtremeDates(fmt
, small
, mid
, buf
, buflen
, cbuf
, count
+1, ec
) &&
1258 _aux2ExtremeDates(fmt
, mid
, large
, buf
, buflen
, cbuf
, count
+1, ec
);
1262 * http://www.jtcsv.com/cgibin/icu-bugs?findid=3659
1264 * For certain large dates, udat_format crashes on MacOS. This test
1265 * attempts to reproduce this problem by doing a recursive logarithmic*
1266 * binary search of a predefined interval (from 'small' to 'large').
1268 * The limit of the search is given by EXTREME_DATES_DEPTH, above.
1270 * *The search has to be logarithmic, not linear. A linear search of the
1271 * range 0..10^30, for example, will find 0.5*10^30, then 0.25*10^30 and
1272 * 0.75*10^30, etc. A logarithmic search will find 10^15, then 10^7.5
1275 static void TestExtremeDates() {
1280 const double small
= 1000; /* 1 sec */
1281 const double large
= 1e+30; /* well beyond usable UDate range */
1283 /* There is no need to test larger values from 1e+30 to 1e+300;
1284 the failures occur around 1e+27, and never above 1e+30. */
1287 fmt
= udat_open(UDAT_LONG
, UDAT_LONG
, "en_US",
1289 if (U_FAILURE(ec
)) {
1290 log_data_err("FAIL: udat_open (%s) (Are you missing data?)\n", u_errorName(ec
));
1294 _aux2ExtremeDates(fmt
, small
, large
, buf
, LEN(buf
), cbuf
, 0, &ec
);
1299 static void TestAllLocales(void) {
1300 int32_t idx
, dateIdx
, timeIdx
, localeCount
;
1301 static const UDateFormatStyle style
[] = {
1302 UDAT_FULL
, UDAT_LONG
, UDAT_MEDIUM
, UDAT_SHORT
1304 localeCount
= uloc_countAvailable();
1305 for (idx
= 0; idx
< localeCount
; idx
++) {
1306 for (dateIdx
= 0; dateIdx
< (int32_t)(sizeof(style
)/sizeof(style
[0])); dateIdx
++) {
1307 for (timeIdx
= 0; timeIdx
< (int32_t)(sizeof(style
)/sizeof(style
[0])); timeIdx
++) {
1308 UErrorCode status
= U_ZERO_ERROR
;
1309 udat_close(udat_open(style
[dateIdx
], style
[timeIdx
],
1310 uloc_getAvailable(idx
), NULL
, 0, NULL
, 0, &status
));
1311 if (U_FAILURE(status
)) {
1312 log_err("FAIL: udat_open(%s) failed with (%s) dateIdx=%d, timeIdx=%d\n",
1313 uloc_getAvailable(idx
), u_errorName(status
), dateIdx
, timeIdx
);
1320 static void TestRelativeCrash(void) {
1321 static const UChar tzName
[] = { 0x0055, 0x0053, 0x002F, 0x0050, 0x0061, 0x0063, 0x0069, 0x0066, 0x0069, 0x0063, 0 };
1322 static const UDate aDate
= -631152000000.0;
1324 UErrorCode status
= U_ZERO_ERROR
;
1325 UErrorCode expectStatus
= U_ILLEGAL_ARGUMENT_ERROR
;
1328 icudf
= udat_open(UDAT_NONE
, UDAT_SHORT_RELATIVE
, "en", tzName
, -1, NULL
, 0, &status
);
1329 if ( U_SUCCESS(status
) ) {
1330 const char *what
= "???";
1332 UErrorCode subStatus
= U_ZERO_ERROR
;
1333 what
= "udat_set2DigitYearStart";
1334 log_verbose("Trying %s on a relative date..\n", what
);
1335 udat_set2DigitYearStart(icudf
, aDate
, &subStatus
);
1336 if(subStatus
== expectStatus
) {
1337 log_verbose("Success: did not crash on %s, but got %s.\n", what
, u_errorName(subStatus
));
1339 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what
, u_errorName(subStatus
), u_errorName(expectStatus
));
1343 /* clone works polymorphically. try it anyways */
1344 UErrorCode subStatus
= U_ZERO_ERROR
;
1347 log_verbose("Trying %s on a relative date..\n", what
);
1348 oth
= udat_clone(icudf
, &subStatus
);
1349 if(subStatus
== U_ZERO_ERROR
) {
1350 log_verbose("Success: did not crash on %s, but got %s.\n", what
, u_errorName(subStatus
));
1351 udat_close(oth
); /* ? */
1353 log_err("FAIL: didn't crash on %s, but got %s instead of %s. \n", what
, u_errorName(subStatus
), u_errorName(expectStatus
));
1357 UErrorCode subStatus
= U_ZERO_ERROR
;
1358 what
= "udat_get2DigitYearStart";
1359 log_verbose("Trying %s on a relative date..\n", what
);
1360 udat_get2DigitYearStart(icudf
, &subStatus
);
1361 if(subStatus
== expectStatus
) {
1362 log_verbose("Success: did not crash on %s, but got %s.\n", what
, u_errorName(subStatus
));
1364 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what
, u_errorName(subStatus
), u_errorName(expectStatus
));
1368 /* Now udat_toPattern works for relative date formatters, unless localized is TRUE */
1369 UErrorCode subStatus
= U_ZERO_ERROR
;
1370 what
= "udat_toPattern";
1371 log_verbose("Trying %s on a relative date..\n", what
);
1372 udat_toPattern(icudf
, TRUE
,NULL
,0, &subStatus
);
1373 if(subStatus
== expectStatus
) {
1374 log_verbose("Success: did not crash on %s, but got %s.\n", what
, u_errorName(subStatus
));
1376 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what
, u_errorName(subStatus
), u_errorName(expectStatus
));
1380 UErrorCode subStatus
= U_ZERO_ERROR
;
1381 what
= "udat_applyPattern";
1382 log_verbose("Trying %s on a relative date..\n", what
);
1383 udat_applyPattern(icudf
, FALSE
,tzName
,-1);
1384 subStatus
= U_ILLEGAL_ARGUMENT_ERROR
; /* what it should be, if this took an errorcode. */
1385 if(subStatus
== expectStatus
) {
1386 log_verbose("Success: did not crash on %s, but got %s.\n", what
, u_errorName(subStatus
));
1388 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what
, u_errorName(subStatus
), u_errorName(expectStatus
));
1393 UErrorCode subStatus
= U_ZERO_ERROR
;
1394 what
= "udat_getSymbols";
1395 log_verbose("Trying %s on a relative date..\n", what
);
1396 udat_getSymbols(icudf
, UDAT_ERAS
,0,erabuf
,sizeof(erabuf
)/sizeof(erabuf
[0]), &subStatus
);
1397 if(subStatus
== U_ZERO_ERROR
) {
1398 log_verbose("Success: %s returned %s.\n", what
, u_errorName(subStatus
));
1400 log_err("FAIL: didn't crash on %s, but got %s instead of U_ZERO_ERROR.\n", what
, u_errorName(subStatus
));
1404 UErrorCode subStatus
= U_ZERO_ERROR
;
1405 UChar symbolValue
= 0x0041;
1406 what
= "udat_setSymbols";
1407 log_verbose("Trying %s on a relative date..\n", what
);
1408 udat_setSymbols(icudf
, UDAT_ERAS
,0,&symbolValue
,1, &subStatus
); /* bogus values */
1409 if(subStatus
== expectStatus
) {
1410 log_verbose("Success: did not crash on %s, but got %s.\n", what
, u_errorName(subStatus
));
1412 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what
, u_errorName(subStatus
), u_errorName(expectStatus
));
1416 UErrorCode subStatus
= U_ZERO_ERROR
;
1417 what
= "udat_countSymbols";
1418 log_verbose("Trying %s on a relative date..\n", what
);
1419 udat_countSymbols(icudf
, UDAT_ERAS
);
1420 subStatus
= U_ILLEGAL_ARGUMENT_ERROR
; /* should have an errorcode. */
1421 if(subStatus
== expectStatus
) {
1422 log_verbose("Success: did not crash on %s, but got %s.\n", what
, u_errorName(subStatus
));
1424 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what
, u_errorName(subStatus
), u_errorName(expectStatus
));
1430 log_data_err("FAIL: err calling udat_open() ->%s (Are you missing data?)\n", u_errorName(status
));
1434 static const UChar skeleton_yMMMM
[] = { 0x79,0x4D,0x4D,0x4D,0x4D,0 }; /* "yMMMM"; fr maps to "MMMM y", cs maps to "LLLL y" */
1435 static const UChar july2008_frDefault
[] = { 0x6A,0x75,0x69,0x6C,0x6C,0x65,0x74,0x20,0x32,0x30,0x30,0x38,0 }; /* "juillet 2008" */
1436 static const UChar july2008_frTitle
[] = { 0x4A,0x75,0x69,0x6C,0x6C,0x65,0x74,0x20,0x32,0x30,0x30,0x38,0 }; /* "Juillet 2008" sentence-begin, standalone */
1437 static const UChar july2008_csDefault
[] = { 0x10D,0x65,0x72,0x76,0x65,0x6E,0x65,0x63,0x20,0x32,0x30,0x30,0x38,0 }; /* "c(hacek)ervenec 2008" */
1438 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 */
1441 const char * locale
;
1442 const UChar
* skeleton
;
1443 UDisplayContext capitalizationContext
;
1444 const UChar
* expectedFormat
;
1447 static const TestContextItem textContextItems
[] = {
1448 { "fr", skeleton_yMMMM
, UDISPCTX_CAPITALIZATION_NONE
, july2008_frDefault
},
1449 #if !UCONFIG_NO_BREAK_ITERATION
1450 { "fr", skeleton_yMMMM
, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE
, july2008_frDefault
},
1451 { "fr", skeleton_yMMMM
, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE
, july2008_frTitle
},
1452 { "fr", skeleton_yMMMM
, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU
, july2008_frDefault
},
1453 { "fr", skeleton_yMMMM
, UDISPCTX_CAPITALIZATION_FOR_STANDALONE
, july2008_frTitle
},
1455 { "cs", skeleton_yMMMM
, UDISPCTX_CAPITALIZATION_NONE
, july2008_csDefault
},
1456 #if !UCONFIG_NO_BREAK_ITERATION
1457 { "cs", skeleton_yMMMM
, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE
, july2008_csDefault
},
1458 { "cs", skeleton_yMMMM
, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE
, july2008_csTitle
},
1459 { "cs", skeleton_yMMMM
, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU
, july2008_csTitle
},
1460 { "cs", skeleton_yMMMM
, UDISPCTX_CAPITALIZATION_FOR_STANDALONE
, july2008_csDefault
},
1462 { NULL
, NULL
, (UDisplayContext
)0, NULL
}
1465 static const UChar today_enDefault
[] = { 0x74,0x6F,0x64,0x61,0x79,0 }; /* "today" */
1466 static const UChar today_enTitle
[] = { 0x54,0x6F,0x64,0x61,0x79,0 }; /* "Today" sentence-begin, uiListOrMenu, standalone */
1467 static const UChar yesterday_enDefault
[] = { 0x79,0x65,0x73,0x74,0x65,0x72,0x64,0x61,0x79,0 }; /* "yesterday" */
1468 static const UChar yesterday_enTitle
[] = { 0x59,0x65,0x73,0x74,0x65,0x72,0x64,0x61,0x79,0 }; /* "Yesterday" sentence-begin, uiListOrMenu, standalone */
1469 static const UChar today_nbDefault
[] = { 0x69,0x20,0x64,0x61,0x67,0 }; /* "i dag" */
1470 static const UChar today_nbTitle
[] = { 0x49,0x20,0x64,0x61,0x67,0 }; /* "I dag" sentence-begin, standalone */
1471 static const UChar yesterday_nbDefault
[] = { 0x69,0x20,0x67,0xE5,0x72,0 };
1472 static const UChar yesterday_nbTitle
[] = { 0x49,0x20,0x67,0xE5,0x72,0 };
1475 const char * locale
;
1476 UDisplayContext capitalizationContext
;
1477 const UChar
* expectedFormatToday
;
1478 const UChar
* expectedFormatYesterday
;
1479 } TestRelativeContextItem
;
1481 static const TestRelativeContextItem textContextRelativeItems
[] = {
1482 { "en", UDISPCTX_CAPITALIZATION_NONE
, today_enDefault
, yesterday_enDefault
},
1483 #if !UCONFIG_NO_BREAK_ITERATION
1484 { "en", UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE
, today_enDefault
, yesterday_enDefault
},
1485 { "en", UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE
, today_enTitle
, yesterday_enTitle
},
1486 { "en", UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU
, today_enTitle
, yesterday_enTitle
},
1487 { "en", UDISPCTX_CAPITALIZATION_FOR_STANDALONE
, today_enTitle
, yesterday_enTitle
},
1489 { "nb", UDISPCTX_CAPITALIZATION_NONE
, today_nbDefault
, yesterday_nbDefault
},
1490 #if !UCONFIG_NO_BREAK_ITERATION
1491 { "nb", UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE
, today_nbDefault
, yesterday_nbDefault
},
1492 { "nb", UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE
, today_nbTitle
, yesterday_nbTitle
},
1493 { "nb", UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU
, today_nbDefault
, yesterday_nbDefault
},
1494 { "nb", UDISPCTX_CAPITALIZATION_FOR_STANDALONE
, today_nbTitle
, yesterday_nbTitle
},
1496 { NULL
, (UDisplayContext
)0, NULL
, NULL
}
1499 static const UChar zoneGMT
[] = { 0x47,0x4D,0x54,0 }; /* "GMT" */
1500 static const UDate july022008
= 1215000000000.0;
1501 enum { kUbufMax
= 64, kBbufMax
= 3*kUbufMax
};
1503 static void TestContext(void) {
1504 const TestContextItem
* textContextItemPtr
;
1505 const TestRelativeContextItem
* textRelContextItemPtr
;
1506 for (textContextItemPtr
= textContextItems
; textContextItemPtr
->locale
!= NULL
; ++textContextItemPtr
) {
1507 UErrorCode status
= U_ZERO_ERROR
;
1508 UDateTimePatternGenerator
* udtpg
= udatpg_open(textContextItemPtr
->locale
, &status
);
1509 if ( U_SUCCESS(status
) ) {
1510 UChar ubuf
[kUbufMax
];
1511 int32_t len
= udatpg_getBestPattern(udtpg
, textContextItemPtr
->skeleton
, -1, ubuf
, kUbufMax
, &status
);
1512 if ( U_SUCCESS(status
) ) {
1513 UDateFormat
* udfmt
= udat_open(UDAT_PATTERN
, UDAT_PATTERN
, textContextItemPtr
->locale
, zoneGMT
, -1, ubuf
, len
, &status
);
1514 if ( U_SUCCESS(status
) ) {
1515 udat_setContext(udfmt
, textContextItemPtr
->capitalizationContext
, &status
);
1516 if ( U_SUCCESS(status
) ) {
1517 UDisplayContext getContext
;
1518 len
= udat_format(udfmt
, july022008
, ubuf
, kUbufMax
, NULL
, &status
);
1519 if ( U_FAILURE(status
) ) {
1520 log_err("FAIL: udat_format for locale %s, capitalizationContext %d, status %s\n",
1521 textContextItemPtr
->locale
, (int)textContextItemPtr
->capitalizationContext
, u_errorName(status
) );
1522 status
= U_ZERO_ERROR
;
1523 } else if (u_strncmp(ubuf
, textContextItemPtr
->expectedFormat
, kUbufMax
) != 0) {
1524 char bbuf1
[kBbufMax
];
1525 char bbuf2
[kBbufMax
];
1526 log_err("FAIL: udat_format for locale %s, capitalizationContext %d, expected %s, got %s\n",
1527 textContextItemPtr
->locale
, (int)textContextItemPtr
->capitalizationContext
,
1528 u_austrncpy(bbuf1
,textContextItemPtr
->expectedFormat
,kUbufMax
), u_austrncpy(bbuf2
,ubuf
,kUbufMax
) );
1530 getContext
= udat_getContext(udfmt
, UDISPCTX_TYPE_CAPITALIZATION
, &status
);
1531 if ( U_FAILURE(status
) ) {
1532 log_err("FAIL: udat_getContext for locale %s, capitalizationContext %d, status %s\n",
1533 textContextItemPtr
->locale
, (int)textContextItemPtr
->capitalizationContext
, u_errorName(status
) );
1534 } else if (getContext
!= textContextItemPtr
->capitalizationContext
) {
1535 log_err("FAIL: udat_getContext for locale %s, capitalizationContext %d, got context %d\n",
1536 textContextItemPtr
->locale
, (int)textContextItemPtr
->capitalizationContext
, (int)getContext
);
1539 log_err("FAIL: udat_setContext for locale %s, capitalizationContext %d, status %s\n",
1540 textContextItemPtr
->locale
, (int)textContextItemPtr
->capitalizationContext
, u_errorName(status
) );
1544 log_data_err("FAIL: udat_open for locale %s, status %s\n", textContextItemPtr
->locale
, u_errorName(status
) );
1547 log_err("FAIL: udatpg_getBestPattern for locale %s, status %s\n", textContextItemPtr
->locale
, u_errorName(status
) );
1549 udatpg_close(udtpg
);
1551 log_data_err("FAIL: udatpg_open for locale %s, status %s\n", textContextItemPtr
->locale
, u_errorName(status
) );
1554 for (textRelContextItemPtr
= textContextRelativeItems
; textRelContextItemPtr
->locale
!= NULL
; ++textRelContextItemPtr
) {
1555 UErrorCode status
= U_ZERO_ERROR
;
1556 UCalendar
* ucal
= ucal_open(zoneGMT
, -1, "root", UCAL_GREGORIAN
, &status
);
1557 if ( U_SUCCESS(status
) ) {
1558 UDateFormat
* udfmt
= udat_open(UDAT_NONE
, UDAT_LONG_RELATIVE
, textRelContextItemPtr
->locale
, zoneGMT
, -1, NULL
, 0, &status
);
1559 if ( U_SUCCESS(status
) ) {
1560 udat_setContext(udfmt
, textRelContextItemPtr
->capitalizationContext
, &status
);
1561 if ( U_SUCCESS(status
) ) {
1562 UDate yesterday
, today
= ucal_getNow();
1563 UChar ubuf
[kUbufMax
];
1564 char bbuf1
[kBbufMax
];
1565 char bbuf2
[kBbufMax
];
1566 int32_t len
= udat_format(udfmt
, today
, ubuf
, kUbufMax
, NULL
, &status
);
1568 if ( U_FAILURE(status
) ) {
1569 log_err("FAIL: udat_format today for locale %s, capitalizationContext %d, status %s\n",
1570 textRelContextItemPtr
->locale
, (int)textRelContextItemPtr
->capitalizationContext
, u_errorName(status
) );
1571 } else if (u_strncmp(ubuf
, textRelContextItemPtr
->expectedFormatToday
, kUbufMax
) != 0) {
1572 log_err("FAIL: udat_format today for locale %s, capitalizationContext %d, expected %s, got %s\n",
1573 textRelContextItemPtr
->locale
, (int)textRelContextItemPtr
->capitalizationContext
,
1574 u_austrncpy(bbuf1
,textRelContextItemPtr
->expectedFormatToday
,kUbufMax
), u_austrncpy(bbuf2
,ubuf
,kUbufMax
) );
1576 status
= U_ZERO_ERROR
;
1577 ucal_setMillis(ucal
, today
, &status
);
1578 ucal_add(ucal
, UCAL_DATE
, -1, &status
);
1579 yesterday
= ucal_getMillis(ucal
, &status
);
1580 if ( U_SUCCESS(status
) ) {
1581 len
= udat_format(udfmt
, yesterday
, ubuf
, kUbufMax
, NULL
, &status
);
1582 if ( U_FAILURE(status
) ) {
1583 log_err("FAIL: udat_format yesterday for locale %s, capitalizationContext %d, status %s\n",
1584 textRelContextItemPtr
->locale
, (int)textRelContextItemPtr
->capitalizationContext
, u_errorName(status
) );
1585 } else if (u_strncmp(ubuf
, textRelContextItemPtr
->expectedFormatYesterday
, kUbufMax
) != 0) {
1586 log_err("FAIL: udat_format yesterday for locale %s, capitalizationContext %d, expected %s, got %s\n",
1587 textRelContextItemPtr
->locale
, (int)textRelContextItemPtr
->capitalizationContext
,
1588 u_austrncpy(bbuf1
,textRelContextItemPtr
->expectedFormatYesterday
,kUbufMax
), u_austrncpy(bbuf2
,ubuf
,kUbufMax
) );
1592 log_err("FAIL: udat_setContext relative for locale %s, capitalizationContext %d, status %s\n",
1593 textRelContextItemPtr
->locale
, (int)textRelContextItemPtr
->capitalizationContext
, u_errorName(status
) );
1597 log_data_err("FAIL: udat_open relative for locale %s, status %s\n", textRelContextItemPtr
->locale
, u_errorName(status
) );
1601 log_data_err("FAIL: ucal_open for locale root, status %s\n", u_errorName(status
) );
1607 // overrideNumberFormat[i][0] is to tell which field to set,
1608 // overrideNumberFormat[i][1] is the expected result
1609 static const char * overrideNumberFormat
[][2] = {
1610 {"", "\\u521D\\u4E03 \\u521D\\u4E8C"},
1611 {"d", "07 \\u521D\\u4E8C"},
1612 {"do", "07 \\u521D\\u4E8C"},
1613 {"Md", "\\u521D\\u4E03 \\u521D\\u4E8C"},
1614 {"MdMMd", "\\u521D\\u4E03 \\u521D\\u4E8C"},
1615 {"mixed", "\\u521D\\u4E03 \\u521D\\u4E8C"}
1618 static void TestOverrideNumberFormat(void) {
1619 UErrorCode status
= U_ZERO_ERROR
;
1623 char bbuf1
[kBbufMax
];
1624 char bbuf2
[kBbufMax
];
1625 const char* localeString
= "zh@numbers=hanidays";
1627 const UNumberFormat
* getter_result
;
1630 u_uastrcpy(fields
, "d");
1631 u_uastrcpy(pattern
,"MM d");
1633 fmt
=udat_open(UDAT_PATTERN
, UDAT_PATTERN
, "en_US", zoneGMT
, -1, pattern
, u_strlen(pattern
), &status
);
1634 if (!assertSuccess("udat_open()", &status
)) {
1638 // loop 5 times to check getter/setter
1639 for (i
= 0; i
< 5; i
++){
1640 UNumberFormat
* overrideFmt
;
1641 overrideFmt
= unum_open(UNUM_DEFAULT
, NULL
, 0, localeString
, NULL
, &status
);
1642 assertSuccess("unum_open()", &status
);
1643 udat_adoptNumberFormatForFields(fmt
, fields
, overrideFmt
, &status
);
1644 overrideFmt
= NULL
; // no longer valid
1645 assertSuccess("udat_setNumberFormatForField()", &status
);
1647 getter_result
= udat_getNumberFormatForField(fmt
, 'd');
1648 if(getter_result
== NULL
) {
1649 log_err("FAIL: udat_getNumberFormatForField did not return a valid pointer\n");
1653 UNumberFormat
* overrideFmt
;
1654 overrideFmt
= unum_open(UNUM_DEFAULT
, NULL
, 0, localeString
, NULL
, &status
);
1655 assertSuccess("unum_open()", &status
);
1656 udat_setNumberFormat(fmt
, overrideFmt
); // test the same override NF will not crash
1657 unum_close(overrideFmt
);
1661 for (i
=0; i
<UPRV_LENGTHOF(overrideNumberFormat
); i
++){
1662 UChar ubuf
[kUbufMax
];
1664 UNumberFormat
* overrideFmt2
;
1666 fmt2
=udat_open(UDAT_PATTERN
, UDAT_PATTERN
,"en_US", zoneGMT
, -1, pattern
, u_strlen(pattern
), &status
);
1667 assertSuccess("udat_open() with en_US", &status
);
1669 overrideFmt2
= unum_open(UNUM_DEFAULT
, NULL
, 0, localeString
, NULL
, &status
);
1670 assertSuccess("unum_open() in loop", &status
);
1672 u_uastrcpy(fields
, overrideNumberFormat
[i
][0]);
1673 u_unescape(overrideNumberFormat
[i
][1], expected
, UPRV_LENGTHOF(expected
));
1675 if ( strcmp(overrideNumberFormat
[i
][0], "") == 0 ) { // use the one w/o field
1676 udat_adoptNumberFormat(fmt2
, overrideFmt2
);
1677 } else if ( strcmp(overrideNumberFormat
[i
][0], "mixed") == 0 ) { // set 1 field at first but then full override, both(M & d) should be override
1678 const char* singleLocale
= "en@numbers=hebr";
1679 UNumberFormat
* singleOverrideFmt
;
1680 u_uastrcpy(fields
, "d");
1682 singleOverrideFmt
= unum_open(UNUM_DEFAULT
, NULL
, 0, singleLocale
, NULL
, &status
);
1683 assertSuccess("unum_open() in mixed", &status
);
1685 udat_adoptNumberFormatForFields(fmt2
, fields
, singleOverrideFmt
, &status
);
1686 assertSuccess("udat_setNumberFormatForField() in mixed", &status
);
1688 udat_adoptNumberFormat(fmt2
, overrideFmt2
);
1689 } else if ( strcmp(overrideNumberFormat
[i
][0], "do") == 0 ) { // o is an invalid field
1690 udat_adoptNumberFormatForFields(fmt2
, fields
, overrideFmt2
, &status
);
1691 if(status
== U_INVALID_FORMAT_ERROR
) {
1693 status
= U_ZERO_ERROR
;
1697 udat_adoptNumberFormatForFields(fmt2
, fields
, overrideFmt2
, &status
);
1698 assertSuccess("udat_setNumberFormatForField() in loop", &status
);
1701 udat_format(fmt2
, july022008
, ubuf
, kUbufMax
, NULL
, &status
);
1702 assertSuccess("udat_format() july022008", &status
);
1704 if (u_strncmp(ubuf
, expected
, kUbufMax
) != 0)
1705 log_err("fail: udat_format for locale, expected %s, got %s\n",
1706 u_austrncpy(bbuf1
,expected
,kUbufMax
), u_austrncpy(bbuf2
,ubuf
,kUbufMax
) );
1714 * udat_parse and udat_parseCalendar should have the same error code when given the same invalid input.
1716 static void TestParseErrorReturnValue(void) {
1717 UErrorCode status
= U_ZERO_ERROR
;
1718 UErrorCode expectStatus
= U_PARSE_ERROR
;
1722 df
= udat_open(UDAT_DEFAULT
, UDAT_DEFAULT
, NULL
, NULL
, -1, NULL
, -1, &status
);
1723 if (!assertSuccessCheck("udat_open()", &status
, TRUE
)) {
1727 cal
= ucal_open(NULL
, 0, "en_US", UCAL_GREGORIAN
, &status
);
1728 if (!assertSuccess("ucal_open()", &status
)) {
1732 udat_parse(df
, NULL
, -1, NULL
, &status
);
1733 if (status
!= expectStatus
) {
1734 log_err("%s should have been returned by udat_parse when given an invalid input, instead got - %s\n", u_errorName(expectStatus
), u_errorName(status
));
1737 status
= U_ZERO_ERROR
;
1738 udat_parseCalendar(df
, cal
, NULL
, -1, NULL
, &status
);
1739 if (status
!= expectStatus
) {
1740 log_err("%s should have been returned by udat_parseCalendar when given an invalid input, instead got - %s\n", u_errorName(expectStatus
), u_errorName(status
));
1749 * Test new udat_formatForFields, udat_formatCalendarForFields (and UFieldPositionIterator)
1751 static const char localeForFields
[] = "en_US";
1752 /* zoneGMT[]defined above */
1753 static const UDate date2015Feb25
= 1424841000000.0; /* Wednesday, February 25, 2015 at 5:10:00 AM GMT */
1760 static const FieldsData expectedFields
[] = {
1761 { UDAT_DAY_OF_WEEK_FIELD
/* 9*/, 0, 9 },
1762 { UDAT_MONTH_FIELD
/* 2*/, 11, 19 },
1763 { UDAT_DATE_FIELD
/* 3*/, 20, 22 },
1764 { UDAT_YEAR_FIELD
/* 1*/, 24, 28 },
1765 { UDAT_HOUR1_FIELD
/*15*/, 32, 33 },
1766 { UDAT_TIME_SEPARATOR_FIELD
/*35*/, 33, 34 }, // add this with ICU 55 roll-in
1767 { UDAT_MINUTE_FIELD
/* 6*/, 34, 36 },
1768 { UDAT_TIME_SEPARATOR_FIELD
/*35*/, 36, 37 }, // add this with ICU 55 roll-in
1769 { UDAT_SECOND_FIELD
/* 7*/, 37, 39 },
1770 { UDAT_AM_PM_FIELD
/*14*/, 40, 42 },
1771 { UDAT_TIMEZONE_FIELD
/*17*/, 43, 46 },
1775 enum {kUBufFieldsLen
= 128, kBBufFieldsLen
= 256 };
1777 static void TestFormatForFields(void) {
1778 UErrorCode status
= U_ZERO_ERROR
;
1779 UFieldPositionIterator
* fpositer
= ufieldpositer_open(&status
);
1780 if ( U_FAILURE(status
) ) {
1781 log_err("ufieldpositer_open fails, status %s\n", u_errorName(status
));
1783 UDateFormat
* udfmt
= udat_open(UDAT_LONG
, UDAT_FULL
, localeForFields
, zoneGMT
, -1, NULL
, 0, &status
);
1784 UCalendar
* ucal
= ucal_open(zoneGMT
, -1, localeForFields
, UCAL_DEFAULT
, &status
);
1785 if ( U_FAILURE(status
) ) {
1786 log_data_err("udat_open or ucal_open fails for locale %s, status %s (Are you missing data?)\n", localeForFields
, u_errorName(status
));
1788 int32_t ulen
, field
, beginPos
, endPos
;
1789 UChar ubuf
[kUBufFieldsLen
];
1790 const FieldsData
* fptr
;
1792 status
= U_ZERO_ERROR
;
1793 ulen
= udat_formatForFields(udfmt
, date2015Feb25
, ubuf
, kUBufFieldsLen
, fpositer
, &status
);
1794 if ( U_FAILURE(status
) ) {
1795 log_err("udat_formatForFields fails, status %s\n", u_errorName(status
));
1797 for (fptr
= expectedFields
; ; fptr
++) {
1798 field
= ufieldpositer_next(fpositer
, &beginPos
, &endPos
);
1799 if (field
!= fptr
->field
|| (field
>= 0 && (beginPos
!= fptr
->beginPos
|| endPos
!= fptr
->endPos
))) {
1800 if (fptr
->field
>= 0) {
1801 log_err("udat_formatForFields as \"%s\"; expect field %d range %d-%d, get field %d range %d-%d\n",
1802 aescstrdup(ubuf
, ulen
), fptr
->field
, fptr
->beginPos
, fptr
->endPos
, field
, beginPos
, endPos
);
1804 log_err("udat_formatForFields as \"%s\"; expect field < 0, get field %d range %d-%d\n",
1805 aescstrdup(ubuf
, ulen
), field
, beginPos
, endPos
);
1815 ucal_setMillis(ucal
, date2015Feb25
, &status
);
1816 status
= U_ZERO_ERROR
;
1817 ulen
= udat_formatCalendarForFields(udfmt
, ucal
, ubuf
, kUBufFieldsLen
, fpositer
, &status
);
1818 if ( U_FAILURE(status
) ) {
1819 log_err("udat_formatCalendarForFields fails, status %s\n", u_errorName(status
));
1821 for (fptr
= expectedFields
; ; fptr
++) {
1822 field
= ufieldpositer_next(fpositer
, &beginPos
, &endPos
);
1823 if (field
!= fptr
->field
|| (field
>= 0 && (beginPos
!= fptr
->beginPos
|| endPos
!= fptr
->endPos
))) {
1824 if (fptr
->field
>= 0) {
1825 log_err("udat_formatFudat_formatCalendarForFieldsorFields as \"%s\"; expect field %d range %d-%d, get field %d range %d-%d\n",
1826 aescstrdup(ubuf
, ulen
), fptr
->field
, fptr
->beginPos
, fptr
->endPos
, field
, beginPos
, endPos
);
1828 log_err("udat_formatCalendarForFields as \"%s\"; expect field < 0, get field %d range %d-%d\n",
1829 aescstrdup(ubuf
, ulen
), field
, beginPos
, endPos
);
1842 ufieldpositer_close(fpositer
);
1847 static const UChar zoneGMT[] = { 0x47,0x4D,0x54,0 }; // "GMT"
1848 static const UDate date2015Feb25 = 1424841000000.0; // Wednesday, February 25, 2015 at 5:10:00 AM GMT
1850 static const UChar patternHmm
[] = { 0x48,0x3A,0x6D,0x6D,0 }; /* "H:mm" */
1851 static const UChar formattedHmm
[] = { 0x35,0x3A,0x31,0x30,0 }; /* "5:10" */
1853 enum { kUBufOverrideSepMax
= 32, kBBufOverrideSepMax
= 64 };
1855 static void TestApplyPatnOverridesTimeSep(void) {
1858 const char *locale
= "da"; /* uses period for time separator */
1859 UChar ubuf
[kUBufOverrideSepMax
];
1862 status
= U_ZERO_ERROR
;
1863 udfmt
= udat_open(UDAT_PATTERN
, UDAT_PATTERN
, locale
, zoneGMT
, -1, patternHmm
, -1, &status
);
1864 if ( U_FAILURE(status
) ) {
1865 log_err("udat_open(UDAT_PATTERN, UDAT_PATTERN, \"%s\",...) fails, status %s\n", locale
, u_errorName(status
));
1867 ulen
= udat_format(udfmt
, date2015Feb25
, ubuf
, kUBufOverrideSepMax
, NULL
, &status
);
1868 if ( U_FAILURE(status
) ) {
1869 log_err("udat_format fails for UDAT_PATTERN \"%s\", status %s\n", locale
, u_errorName(status
));
1870 } else if (u_strcmp(ubuf
, formattedHmm
) != 0) {
1871 char bbuf
[kBBufOverrideSepMax
];
1872 u_strToUTF8(bbuf
, kBBufOverrideSepMax
, NULL
, ubuf
, ulen
, &status
);
1873 log_err("udat_format fails for UDAT_PATTERN \"%s\", expected 5:10, got %s\n", locale
, bbuf
);
1878 status
= U_ZERO_ERROR
;
1879 udfmt
= udat_open(UDAT_SHORT
, UDAT_NONE
, locale
, zoneGMT
, -1, NULL
, 0, &status
);
1880 if ( U_FAILURE(status
) ) {
1881 log_err("udat_open(UDAT_SHORT, UDAT_NONE, \"%s\",...) fails, status %s\n", locale
, u_errorName(status
));
1883 udat_applyPattern(udfmt
, FALSE
, patternHmm
, -1);
1884 ulen
= udat_format(udfmt
, date2015Feb25
, ubuf
, kUBufOverrideSepMax
, NULL
, &status
);
1885 if ( U_FAILURE(status
) ) {
1886 log_err("udat_format fails for UDAT_SHORT \"%s\" + applyPattern, status %s\n", locale
, u_errorName(status
));
1887 } else if (u_strcmp(ubuf
, formattedHmm
) != 0) {
1888 char bbuf
[kBBufOverrideSepMax
];
1889 u_strToUTF8(bbuf
, kBBufOverrideSepMax
, NULL
, ubuf
, ulen
, &status
);
1890 log_err("udat_format fails for UDAT_SHORT \"%s\" + applyPattern, expected 5:10, got %s\n", locale
, bbuf
);
1901 UATimeUnitTimePattern patType
;
1902 const char* expect
; /* universal char subset + escaped Unicode chars */
1904 static const TimePatternItem timePatternItems
[] = {
1905 { "en", UATIMEUNITTIMEPAT_HM
, "h:mm" },
1906 { "en", UATIMEUNITTIMEPAT_HMS
, "h:mm:ss" },
1907 { "en", UATIMEUNITTIMEPAT_MS
, "m:ss" },
1908 { "da", UATIMEUNITTIMEPAT_HM
, "h.mm" },
1909 { "da", UATIMEUNITTIMEPAT_HMS
, "h.mm.ss" },
1910 { "da", UATIMEUNITTIMEPAT_MS
, "m.ss" },
1916 UATimeUnitStyle width
;
1917 UATimeUnitListPattern patType
;
1918 const char* expect
; /* universal char subset + escaped Unicode chars */
1920 static const ListPatternItem listPatternItems
[] = {
1921 { "en", UATIMEUNITSTYLE_FULL
, UATIMEUNITLISTPAT_TWO_ONLY
, "{0}, {1}" },
1922 { "en", UATIMEUNITSTYLE_FULL
, UATIMEUNITLISTPAT_END_PIECE
, "{0}, {1}" },
1923 { "en", UATIMEUNITSTYLE_FULL
, UATIMEUNITLISTPAT_MIDDLE_PIECE
, "{0}, {1}" },
1924 { "en", UATIMEUNITSTYLE_FULL
, UATIMEUNITLISTPAT_START_PIECE
, "{0}, {1}" },
1925 { "en", UATIMEUNITSTYLE_NARROW
, UATIMEUNITLISTPAT_TWO_ONLY
, "{0} {1}" },
1926 { "en", UATIMEUNITSTYLE_NARROW
, UATIMEUNITLISTPAT_END_PIECE
, "{0} {1}" },
1927 { "en", UATIMEUNITSTYLE_NARROW
, UATIMEUNITLISTPAT_MIDDLE_PIECE
, "{0} {1}" },
1928 { "en", UATIMEUNITSTYLE_NARROW
, UATIMEUNITLISTPAT_START_PIECE
, "{0} {1}" },
1929 { "fr", UATIMEUNITSTYLE_FULL
, UATIMEUNITLISTPAT_TWO_ONLY
, "{0} et {1}" },
1930 { "fr", UATIMEUNITSTYLE_FULL
, UATIMEUNITLISTPAT_END_PIECE
, "{0} et {1}" },
1931 { "fr", UATIMEUNITSTYLE_FULL
, UATIMEUNITLISTPAT_MIDDLE_PIECE
, "{0}, {1}" },
1932 { "fr", UATIMEUNITSTYLE_FULL
, UATIMEUNITLISTPAT_START_PIECE
, "{0}, {1}" },
1933 { "fr", UATIMEUNITSTYLE_NARROW
, UATIMEUNITLISTPAT_TWO_ONLY
, "{0} {1}" },
1934 { "fr", UATIMEUNITSTYLE_NARROW
, UATIMEUNITLISTPAT_END_PIECE
, "{0} {1}" },
1935 { "fr", UATIMEUNITSTYLE_NARROW
, UATIMEUNITLISTPAT_MIDDLE_PIECE
, "{0} {1}" },
1936 { "fr", UATIMEUNITSTYLE_NARROW
, UATIMEUNITLISTPAT_START_PIECE
, "{0} {1}" },
1937 { NULL
, 0, 0, NULL
}
1940 enum {kUBufTimeUnitLen
= 128, kBBufTimeUnitLen
= 256 };
1942 static void TestTimeUnitFormat(void) { /* Apple-specific */
1943 const TimePatternItem
* timePatItemPtr
;
1944 const ListPatternItem
* listPatItemPtr
;
1945 UChar uActual
[kUBufTimeUnitLen
];
1946 UChar uExpect
[kUBufTimeUnitLen
];
1948 for (timePatItemPtr
= timePatternItems
; timePatItemPtr
->locale
!= NULL
; timePatItemPtr
++) {
1949 UErrorCode status
= U_ZERO_ERROR
;
1950 int32_t ulenActual
= uatmufmt_getTimePattern(timePatItemPtr
->locale
, timePatItemPtr
->patType
, uActual
, kUBufTimeUnitLen
, &status
);
1951 if ( U_FAILURE(status
) ) {
1952 log_err("uatmufmt_getTimePattern for locale %s, patType %d: status %s\n", timePatItemPtr
->locale
, (int)timePatItemPtr
->patType
, u_errorName(status
));
1954 int32_t ulenExpect
= u_unescape(timePatItemPtr
->expect
, uExpect
, kUBufTimeUnitLen
);
1955 if (ulenActual
!= ulenExpect
|| u_strncmp(uActual
, uExpect
, ulenExpect
) != 0) {
1956 char bActual
[kBBufTimeUnitLen
];
1957 u_strToUTF8(bActual
, kBBufTimeUnitLen
, NULL
, uActual
, ulenActual
, &status
);
1958 log_err("uatmufmt_getTimePattern for locale %s, patType %d: unexpected result %s\n", timePatItemPtr
->locale
, (int)timePatItemPtr
->patType
, bActual
);
1963 for (listPatItemPtr
= listPatternItems
; listPatItemPtr
->locale
!= NULL
; listPatItemPtr
++) {
1964 UErrorCode status
= U_ZERO_ERROR
;
1965 int32_t ulenActual
= uatmufmt_getListPattern(listPatItemPtr
->locale
, listPatItemPtr
->width
, listPatItemPtr
->patType
, uActual
, kUBufTimeUnitLen
, &status
);
1966 if ( U_FAILURE(status
) ) {
1967 log_err("uatmufmt_getListPattern for locale %s, width %d, patType %d: status %s\n", listPatItemPtr
->locale
, (int)listPatItemPtr
->width
, (int)listPatItemPtr
->patType
, u_errorName(status
));
1969 int32_t ulenExpect
= u_unescape(listPatItemPtr
->expect
, uExpect
, kUBufTimeUnitLen
);
1970 if (ulenActual
!= ulenExpect
|| u_strncmp(uActual
, uExpect
, ulenExpect
) != 0) {
1971 char bActual
[kBBufTimeUnitLen
];
1972 u_strToUTF8(bActual
, kBBufTimeUnitLen
, NULL
, uActual
, ulenActual
, &status
);
1973 log_err("uatmufmt_getListPattern for locale %s, width %d, patType %d: unexpected result %s\n", listPatItemPtr
->locale
, (int)listPatItemPtr
->width
, (int)listPatItemPtr
->patType
, bActual
);
1980 typedef enum RemapTesttype
{
1981 REMAP_TESTTYPE_FULL
= UDAT_FULL
, // 0
1982 REMAP_TESTTYPE_LONG
= UDAT_LONG
, // 1
1983 REMAP_TESTTYPE_MEDIUM
= UDAT_MEDIUM
, // 2
1984 REMAP_TESTTYPE_SHORT
= UDAT_SHORT
, // 3
1985 REMAP_TESTTYPE_LONG_DF
= UDAT_LONG
+ 4, // 5 long time, full date
1986 REMAP_TESTTYPE_SHORT_DS
= UDAT_SHORT
+ 16, // 3 short time, short date
1987 REMAP_TESTTYPE_SKELETON
= -1,
1988 REMAP_TESTTYPE_PATTERN
= -2,
1992 const char * pattern
;
1993 RemapTesttype testtype
;
1995 } RemapPatternTestItem
;
1997 static const RemapPatternTestItem remapPatItems
[] = {
1998 { "full", REMAP_TESTTYPE_FULL
, 0 },
1999 { "full", REMAP_TESTTYPE_FULL
, UADATPG_FORCE_24_HOUR_CYCLE
},
2000 { "full", REMAP_TESTTYPE_FULL
, UADATPG_FORCE_12_HOUR_CYCLE
},
2001 { "long", REMAP_TESTTYPE_LONG
, 0 },
2002 { "long", REMAP_TESTTYPE_LONG
, UADATPG_FORCE_24_HOUR_CYCLE
},
2003 { "long", REMAP_TESTTYPE_LONG
, UADATPG_FORCE_12_HOUR_CYCLE
},
2004 { "medium", REMAP_TESTTYPE_MEDIUM
, 0 },
2005 { "medium", REMAP_TESTTYPE_MEDIUM
, UADATPG_FORCE_24_HOUR_CYCLE
},
2006 { "medium", REMAP_TESTTYPE_MEDIUM
, UADATPG_FORCE_12_HOUR_CYCLE
},
2007 { "short", REMAP_TESTTYPE_SHORT
, 0 },
2008 { "short", REMAP_TESTTYPE_SHORT
, UADATPG_FORCE_24_HOUR_CYCLE
},
2009 { "short", REMAP_TESTTYPE_SHORT
, UADATPG_FORCE_12_HOUR_CYCLE
},
2010 { "long_df", REMAP_TESTTYPE_LONG_DF
, 0 },
2011 { "long_df", REMAP_TESTTYPE_LONG_DF
, UADATPG_FORCE_24_HOUR_CYCLE
},
2012 { "long_df", REMAP_TESTTYPE_LONG_DF
, UADATPG_FORCE_12_HOUR_CYCLE
},
2013 { "short_ds", REMAP_TESTTYPE_SHORT_DS
, 0 },
2014 { "short_ds", REMAP_TESTTYPE_SHORT_DS
, UADATPG_FORCE_24_HOUR_CYCLE
},
2015 { "short_ds", REMAP_TESTTYPE_SHORT_DS
, UADATPG_FORCE_12_HOUR_CYCLE
},
2017 { "jmmss", REMAP_TESTTYPE_SKELETON
, 0 },
2018 { "jmmss", REMAP_TESTTYPE_SKELETON
, UADATPG_FORCE_24_HOUR_CYCLE
},
2019 { "jmmss", REMAP_TESTTYPE_SKELETON
, UADATPG_FORCE_12_HOUR_CYCLE
},
2020 { "jjmmss", REMAP_TESTTYPE_SKELETON
, 0 },
2021 { "jjmmss", REMAP_TESTTYPE_SKELETON
, UADATPG_FORCE_24_HOUR_CYCLE
},
2022 { "jjmmss", REMAP_TESTTYPE_SKELETON
, UADATPG_FORCE_24_HOUR_CYCLE
| UDATPG_MATCH_HOUR_FIELD_LENGTH
},
2023 { "jjmmss", REMAP_TESTTYPE_SKELETON
, UADATPG_FORCE_12_HOUR_CYCLE
},
2024 { "jjmmss", REMAP_TESTTYPE_SKELETON
, UADATPG_FORCE_12_HOUR_CYCLE
| UDATPG_MATCH_HOUR_FIELD_LENGTH
},
2025 { "Jmm", REMAP_TESTTYPE_SKELETON
, 0 },
2026 { "Jmm", REMAP_TESTTYPE_SKELETON
, UADATPG_FORCE_24_HOUR_CYCLE
},
2027 { "Jmm", REMAP_TESTTYPE_SKELETON
, UADATPG_FORCE_12_HOUR_CYCLE
},
2028 { "jmsv", REMAP_TESTTYPE_SKELETON
, 0 },
2029 { "jmsv", REMAP_TESTTYPE_SKELETON
, UADATPG_FORCE_24_HOUR_CYCLE
},
2030 { "jmsv", REMAP_TESTTYPE_SKELETON
, UADATPG_FORCE_12_HOUR_CYCLE
},
2031 { "jmsz", REMAP_TESTTYPE_SKELETON
, 0 },
2032 { "jmsz", REMAP_TESTTYPE_SKELETON
, UADATPG_FORCE_24_HOUR_CYCLE
},
2033 { "jmsz", REMAP_TESTTYPE_SKELETON
, UADATPG_FORCE_12_HOUR_CYCLE
},
2035 { "h:mm:ss a", REMAP_TESTTYPE_PATTERN
, UADATPG_FORCE_12_HOUR_CYCLE
}, // 12=hour patterns
2036 { "h:mm:ss a", REMAP_TESTTYPE_PATTERN
, UADATPG_FORCE_24_HOUR_CYCLE
},
2037 { "a'xx'h:mm:ss d MMM y", REMAP_TESTTYPE_PATTERN
, UADATPG_FORCE_12_HOUR_CYCLE
},
2038 { "a'xx'h:mm:ss d MMM y", REMAP_TESTTYPE_PATTERN
, UADATPG_FORCE_24_HOUR_CYCLE
},
2039 { "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", REMAP_TESTTYPE_PATTERN
, UADATPG_FORCE_12_HOUR_CYCLE
},
2040 { "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", REMAP_TESTTYPE_PATTERN
, UADATPG_FORCE_24_HOUR_CYCLE
},
2041 { "EEE, d MMM y 'aha' a'xx'h:mm:ss", REMAP_TESTTYPE_PATTERN
, UADATPG_FORCE_12_HOUR_CYCLE
},
2042 { "EEE, d MMM y 'aha' a'xx'h:mm:ss", REMAP_TESTTYPE_PATTERN
, UADATPG_FORCE_24_HOUR_CYCLE
},
2043 { "yyMMddhhmmss", REMAP_TESTTYPE_PATTERN
, UADATPG_FORCE_12_HOUR_CYCLE
},
2044 { "yyMMddhhmmss", REMAP_TESTTYPE_PATTERN
, UADATPG_FORCE_24_HOUR_CYCLE
},
2046 { "H:mm:ss", REMAP_TESTTYPE_PATTERN
, UADATPG_FORCE_12_HOUR_CYCLE
}, // 24=hour patterns
2047 { "H:mm:ss", REMAP_TESTTYPE_PATTERN
, UADATPG_FORCE_24_HOUR_CYCLE
},
2048 { "H:mm:ss d MMM y", REMAP_TESTTYPE_PATTERN
, UADATPG_FORCE_12_HOUR_CYCLE
},
2049 { "H:mm:ss d MMM y", REMAP_TESTTYPE_PATTERN
, UADATPG_FORCE_24_HOUR_CYCLE
},
2050 { "EEE, d MMM y 'aha' H:mm:ss 'hrs'", REMAP_TESTTYPE_PATTERN
, UADATPG_FORCE_12_HOUR_CYCLE
},
2051 { "EEE, d MMM y 'aha' H:mm:ss 'hrs'", REMAP_TESTTYPE_PATTERN
, UADATPG_FORCE_24_HOUR_CYCLE
},
2052 { "EEE, d MMM y 'aha' H'h'mm'm'ss", REMAP_TESTTYPE_PATTERN
, UADATPG_FORCE_12_HOUR_CYCLE
},
2053 { "EEE, d MMM y 'aha' H'h'mm'm'ss", REMAP_TESTTYPE_PATTERN
, UADATPG_FORCE_24_HOUR_CYCLE
},
2054 { NULL
, (RemapTesttype
)0, 0 }
2057 static const char * remapResults_root
[] = {
2058 "HH:mm:ss zzzz", // full
2059 "HH:mm:ss zzzz", // force24
2060 "h:mm:ss a zzzz", // force12
2061 "HH:mm:ss z", // long
2062 "HH:mm:ss z", // force24
2063 "h:mm:ss a z", // force12
2064 "HH:mm:ss", // medium
2065 "HH:mm:ss", // force24
2066 "h:mm:ss a", // force12
2069 "h:mm a", // force12
2070 "y MMMM d, EEEE HH:mm:ss z", // long_df
2071 "y MMMM d, EEEE HH:mm:ss z", // force24
2072 "y MMMM d, EEEE h:mm:ss a z", // force12
2073 "y-MM-dd HH:mm", // short_ds
2074 "y-MM-dd HH:mm", // force24
2075 "y-MM-dd h:mm a", // force12
2077 "HH:mm:ss", // jmmss
2078 "HH:mm:ss", // force24
2079 "h:mm:ss a", // force12
2080 "HH:mm:ss", // jjmmss
2081 "HH:mm:ss", // force24
2082 "HH:mm:ss", // force24 | match hour field length
2083 "h:mm:ss a", // force12
2084 "hh:mm:ss a", // force12 | match hour field length
2088 "HH:mm:ss v", // jmsv
2089 "HH:mm:ss v", // force24
2090 "h:mm:ss a v", // force12
2091 "HH:mm:ss z", // jmsz
2092 "HH:mm:ss z", // force24
2093 "h:mm:ss a z", // force12
2095 "h:mm:ss a", // "h:mm:ss"
2097 "a'xx'h:mm:ss d MMM y", // "a'xx'h:mm:ss d MMM y"
2098 "HH:mm:ss d MMM y", //
2099 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' h:mm:ss a 'hrs'"
2100 "EEE, d MMM y 'aha' HH:mm:ss 'hrs'", //
2101 "EEE, d MMM y 'aha' a'xx'h:mm:ss", // "EEE, d MMM y 'aha' a'xx'h:mm:ss"
2102 "EEE, d MMM y 'aha' HH:mm:ss", //
2103 "yyMMddhhmmss", // "yyMMddhhmmss"
2106 "h:mm:ss a", // "H:mm:ss"
2108 "h:mm:ss a d MMM y", // "H:mm:ss d MMM y"
2109 "H:mm:ss d MMM y", //
2110 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' H:mm:ss 'hrs'"
2111 "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
2112 "EEE, d MMM y 'aha' h'h'mm'm'ss a", // "EEE, d MMM y 'aha' H'h'mm'm'ss"
2113 "EEE, d MMM y 'aha' H'h'mm'm'ss", //
2117 static const char * remapResults_en
[] = {
2118 "h:mm:ss a zzzz", // full
2119 "HH:mm:ss zzzz", // force24
2120 "h:mm:ss a zzzz", // force12
2121 "h:mm:ss a z", // long
2122 "HH:mm:ss z", // force24
2123 "h:mm:ss a z", // force12
2124 "h:mm:ss a", // medium
2125 "HH:mm:ss", // force24
2126 "h:mm:ss a", // force12
2129 "h:mm a", // force12
2130 "EEEE, MMMM d, y 'at' h:mm:ss a z", // long_df
2131 "EEEE, MMMM d, y 'at' HH:mm:ss z", // force24
2132 "EEEE, MMMM d, y 'at' h:mm:ss a z", // force12
2133 "M/d/yy, h:mm a", // short_ds
2134 "M/d/yy, HH:mm", // force24
2135 "M/d/yy, h:mm a", // force12
2137 "h:mm:ss a", // jmmss
2138 "HH:mm:ss", // force24
2139 "h:mm:ss a", // force12
2140 "h:mm:ss a", // jjmmss
2141 "HH:mm:ss", // force24
2142 "HH:mm:ss", // force24 | match hour field length
2143 "h:mm:ss a", // force12
2144 "hh:mm:ss a", // force12 | match hour field length
2148 "h:mm:ss a v", // jmsv
2149 "HH:mm:ss v", // force24
2150 "h:mm:ss a v", // force12
2151 "h:mm:ss a z", // jmsz
2152 "HH:mm:ss z", // force24
2153 "h:mm:ss a z", // force12
2155 "h:mm:ss a", // "h:mm:ss"
2157 "a'xx'h:mm:ss d MMM y", // "a'xx'h:mm:ss d MMM y"
2158 "HH:mm:ss d MMM y", //
2159 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' h:mm:ss a 'hrs'"
2160 "EEE, d MMM y 'aha' HH:mm:ss 'hrs'", //
2161 "EEE, d MMM y 'aha' a'xx'h:mm:ss", // "EEE, d MMM y 'aha' a'xx'h:mm:ss"
2162 "EEE, d MMM y 'aha' HH:mm:ss", //
2163 "yyMMddhhmmss", // "yyMMddhhmmss"
2166 "h:mm:ss a", // "H:mm:ss"
2168 "h:mm:ss a d MMM y", // "H:mm:ss d MMM y"
2169 "H:mm:ss d MMM y", //
2170 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' H:mm:ss 'hrs'"
2171 "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
2172 "EEE, d MMM y 'aha' h'h'mm'm'ss a", // "EEE, d MMM y 'aha' H'h'mm'm'ss"
2173 "EEE, d MMM y 'aha' H'h'mm'm'ss", //
2177 static const char * remapResults_ja
[] = {
2178 "H\\u6642mm\\u5206ss\\u79D2 zzzz", // full
2179 "H\\u6642mm\\u5206ss\\u79D2 zzzz", // force24
2180 "aK:mm:ss zzzz", // force12
2181 "H:mm:ss z", // long
2182 "H:mm:ss z", // force24
2183 "aK:mm:ss z", // force12
2184 "H:mm:ss", // medium
2185 "H:mm:ss", // force24
2186 "aK:mm:ss", // force12
2190 "y\\u5E74M\\u6708d\\u65E5EEEE H:mm:ss z", // long_df
2191 "y\\u5E74M\\u6708d\\u65E5EEEE H:mm:ss z", // force24
2192 "y\\u5E74M\\u6708d\\u65E5EEEE aK:mm:ss z", // force12
2193 "y/MM/dd H:mm", // short_ds
2194 "y/MM/dd H:mm", // force24
2195 "y/MM/dd aK:mm", // force12
2198 "H:mm:ss", // force24
2199 "aK:mm:ss", // force12
2200 "H:mm:ss", // jjmmss
2201 "H:mm:ss", // force24
2202 "HH:mm:ss", // force24 | match hour field length
2203 "aK:mm:ss", // force12
2204 "aKK:mm:ss", // force12 | match hour field length
2208 "H:mm:ss v", // jmsv
2209 "H:mm:ss v", // force24
2210 "aK:mm:ss v", // force12
2211 "H:mm:ss z", // jmsz
2212 "H:mm:ss z", // force24
2213 "aK:mm:ss z", // force12
2215 "h:mm:ss a", // "h:mm:ss"
2217 "a'xx'h:mm:ss d MMM y", // "a'xx'h:mm:ss d MMM y"
2218 "H:mm:ss d MMM y", //
2219 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' h:mm:ss a 'hrs'"
2220 "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
2221 "EEE, d MMM y 'aha' a'xx'h:mm:ss", // "EEE, d MMM y 'aha' a'xx'h:mm:ss"
2222 "EEE, d MMM y 'aha' H:mm:ss", //
2223 "yyMMddhhmmss", // "yyMMddhhmmss"
2226 "aK:mm:ss", // "H:mm:ss"
2228 "aK:mm:ss d MMM y", // "H:mm:ss d MMM y"
2229 "H:mm:ss d MMM y", //
2230 "EEE, d MMM y 'aha' aK:mm:ss 'hrs'", // "EEE, d MMM y 'aha' H:mm:ss 'hrs'"
2231 "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
2232 "EEE, d MMM y 'aha' aK'h'mm'm'ss", // "EEE, d MMM y 'aha' H'h'mm'm'ss"
2233 "EEE, d MMM y 'aha' H'h'mm'm'ss", //
2237 static const char * remapResults_ko
[] = {
2238 "a h\\uC2DC m\\uBD84 s\\uCD08 zzzz", // full
2239 "H\\uC2DC m\\uBD84 s\\uCD08 zzzz", // force24
2240 "a h\\uC2DC m\\uBD84 s\\uCD08 zzzz", // force12
2241 "a h\\uC2DC m\\uBD84 s\\uCD08 z", // long
2242 "H\\uC2DC m\\uBD84 s\\uCD08 z", // force24
2243 "a h\\uC2DC m\\uBD84 s\\uCD08 z", // force12
2244 "a h:mm:ss", // medium
2245 "HH:mm:ss", // force24
2246 "a h:mm:ss", // force12
2249 "a h:mm", // force12
2250 "y\\uB144 M\\uC6D4 d\\uC77C EEEE a h\\uC2DC m\\uBD84 s\\uCD08 z", // long_df
2251 "y\\uB144 M\\uC6D4 d\\uC77C EEEE H\\uC2DC m\\uBD84 s\\uCD08 z", // force24
2252 "y\\uB144 M\\uC6D4 d\\uC77C EEEE a h\\uC2DC m\\uBD84 s\\uCD08 z", // force12
2253 "y. M. d. a h:mm", // short_ds
2254 "y. M. d. HH:mm", // force24
2255 "y. M. d. a h:mm", // force12
2257 "a h:mm:ss", // jmmss
2258 "HH:mm:ss", // force24
2259 "a h:mm:ss", // force12
2260 "a h:mm:ss", // jjmmss
2261 "HH:mm:ss", // force24
2262 "HH:mm:ss", // force24 | match hour field length
2263 "a h:mm:ss", // force12
2264 "a hh:mm:ss", // force12 | match hour field length
2268 "a h:mm:ss v", // jmsv
2269 "H\\uC2DC m\\uBD84 s\\uCD08 v", // force24
2270 "a h:mm:ss v", // force12
2271 "a h\\uC2DC m\\uBD84 s\\uCD08 z", // jmsz
2272 "H\\uC2DC m\\uBD84 s\\uCD08 z", // force24
2273 "a h\\uC2DC m\\uBD84 s\\uCD08 z", // force12
2275 "h:mm:ss a", // "h:mm:ss"
2277 "a'xx'h:mm:ss d MMM y", // "a'xx'h:mm:ss d MMM y"
2278 "HH:mm:ss d MMM y", //
2279 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' h:mm:ss a 'hrs'"
2280 "EEE, d MMM y 'aha' HH:mm:ss 'hrs'", //
2281 "EEE, d MMM y 'aha' a'xx'h:mm:ss", // "EEE, d MMM y 'aha' a'xx'h:mm:ss"
2282 "EEE, d MMM y 'aha' HH:mm:ss", //
2283 "yyMMddhhmmss", // "yyMMddhhmmss"
2286 "a h:mm:ss", // "H:mm:ss"
2288 "a h:mm:ss d MMM y", // "H:mm:ss d MMM y"
2289 "H:mm:ss d MMM y", //
2290 "EEE, d MMM y 'aha' a h:mm:ss 'hrs'", // "EEE, d MMM y 'aha' H:mm:ss 'hrs'"
2291 "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
2292 "EEE, d MMM y 'aha' a h'h'mm'm'ss", // "EEE, d MMM y 'aha' H'h'mm'm'ss"
2293 "EEE, d MMM y 'aha' H'h'mm'm'ss", //
2297 static const char * remapResults_th
[] = {
2298 "H \\u0E19\\u0E32\\u0E2C\\u0E34\\u0E01\\u0E32 mm \\u0E19\\u0E32\\u0E17\\u0E35 ss \\u0E27\\u0E34\\u0E19\\u0E32\\u0E17\\u0E35 zzzz", // full
2299 "H \\u0E19\\u0E32\\u0E2C\\u0E34\\u0E01\\u0E32 mm \\u0E19\\u0E32\\u0E17\\u0E35 ss \\u0E27\\u0E34\\u0E19\\u0E32\\u0E17\\u0E35 zzzz", // force24
2300 "h:mm:ss a zzzz", // force12
2301 "H \\u0E19\\u0E32\\u0E2C\\u0E34\\u0E01\\u0E32 mm \\u0E19\\u0E32\\u0E17\\u0E35 ss \\u0E27\\u0E34\\u0E19\\u0E32\\u0E17\\u0E35 z", // long
2302 "H \\u0E19\\u0E32\\u0E2C\\u0E34\\u0E01\\u0E32 mm \\u0E19\\u0E32\\u0E17\\u0E35 ss \\u0E27\\u0E34\\u0E19\\u0E32\\u0E17\\u0E35 z", // force24
2303 "h:mm:ss a z", // force12
2304 "HH:mm:ss", // medium
2305 "HH:mm:ss", // force24
2306 "h:mm:ss a", // force12
2309 "h:mm a", // force12
2310 "EEEE\\u0E17\\u0E35\\u0E48 d MMMM G y H \\u0E19\\u0E32\\u0E2C\\u0E34\\u0E01\\u0E32 mm \\u0E19\\u0E32\\u0E17\\u0E35 ss \\u0E27\\u0E34\\u0E19\\u0E32\\u0E17\\u0E35 z", // long_df
2311 "EEEE\\u0E17\\u0E35\\u0E48 d MMMM G y H \\u0E19\\u0E32\\u0E2C\\u0E34\\u0E01\\u0E32 mm \\u0E19\\u0E32\\u0E17\\u0E35 ss \\u0E27\\u0E34\\u0E19\\u0E32\\u0E17\\u0E35 z", // force24
2312 "EEEE\\u0E17\\u0E35\\u0E48 d MMMM G y h:mm:ss a z", // force12
2313 "d/M/yy HH:mm", // short_ds
2314 "d/M/yy HH:mm", // force24
2315 "d/M/yy h:mm a", // force12
2317 "HH:mm:ss", // jmmss
2318 "HH:mm:ss", // force24
2319 "h:mm:ss a", // force12
2320 "HH:mm:ss", // jjmmss
2321 "HH:mm:ss", // force24
2322 "HH:mm:ss", // force24 | match hour field length
2323 "h:mm:ss a", // force12
2324 "hh:mm:ss a", // force12 | match hour field length
2328 "H \\u0E19\\u0E32\\u0E2C\\u0E34\\u0E01\\u0E32 mm \\u0E19\\u0E32\\u0E17\\u0E35 ss \\u0E27\\u0E34\\u0E19\\u0E32\\u0E17\\u0E35 v", // jmsv
2329 "H \\u0E19\\u0E32\\u0E2C\\u0E34\\u0E01\\u0E32 mm \\u0E19\\u0E32\\u0E17\\u0E35 ss \\u0E27\\u0E34\\u0E19\\u0E32\\u0E17\\u0E35 v", // force24
2330 "h:mm:ss a v", // force12
2331 "H \\u0E19\\u0E32\\u0E2C\\u0E34\\u0E01\\u0E32 mm \\u0E19\\u0E32\\u0E17\\u0E35 ss \\u0E27\\u0E34\\u0E19\\u0E32\\u0E17\\u0E35 z", // jmsz
2332 "H \\u0E19\\u0E32\\u0E2C\\u0E34\\u0E01\\u0E32 mm \\u0E19\\u0E32\\u0E17\\u0E35 ss \\u0E27\\u0E34\\u0E19\\u0E32\\u0E17\\u0E35 z", // force24
2333 "h:mm:ss a z", // force12
2335 "h:mm:ss a", // "h:mm:ss"
2337 "a'xx'h:mm:ss d MMM y", // "a'xx'h:mm:ss d MMM y"
2338 "HH:mm:ss d MMM y", //
2339 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' h:mm:ss a 'hrs'"
2340 "EEE, d MMM y 'aha' HH:mm:ss 'hrs'", //
2341 "EEE, d MMM y 'aha' a'xx'h:mm:ss", // "EEE, d MMM y 'aha' a'xx'h:mm:ss"
2342 "EEE, d MMM y 'aha' HH:mm:ss", //
2343 "yyMMddhhmmss", // "yyMMddhhmmss"
2346 "h:mm:ss a", // "H:mm:ss"
2348 "h:mm:ss a d MMM y", // "H:mm:ss d MMM y"
2349 "H:mm:ss d MMM y", //
2350 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' H:mm:ss 'hrs'"
2351 "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
2352 "EEE, d MMM y 'aha' h'h'mm'm'ss a", // "EEE, d MMM y 'aha' H'h'mm'm'ss"
2353 "EEE, d MMM y 'aha' H'h'mm'm'ss", //
2357 static const char * remapResults_hi
[] = {
2358 "a h:mm:ss zzzz", // full
2359 "HH:mm:ss zzzz", // force24
2360 "a h:mm:ss zzzz", // force12
2361 "a h:mm:ss z", // long
2362 "HH:mm:ss z", // force24
2363 "a h:mm:ss z", // force12
2364 "a h:mm:ss", // medium
2365 "HH:mm:ss", // force24
2366 "a h:mm:ss", // force12
2369 "a h:mm", // force12
2370 "EEEE, d MMMM y, a h:mm:ss z", // long_df
2371 "EEEE, d MMMM y, HH:mm:ss z", // force24
2372 "EEEE, d MMMM y, a h:mm:ss z", // force12
2373 "d/M/yy, a h:mm", // short_ds
2374 "d/M/yy, HH:mm", // force24
2375 "d/M/yy, a h:mm", // force12
2377 "a h:mm:ss", // jmmss
2378 "HH:mm:ss", // force24
2379 "a h:mm:ss", // force12
2380 "a h:mm:ss", // jjmmss
2381 "HH:mm:ss", // force24
2382 "HH:mm:ss", // force24 | match hour field length
2383 "a h:mm:ss", // force12
2384 "a hh:mm:ss", // force12 | match hour field length
2388 "a h:mm:ss v", // jmsv
2389 "HH:mm:ss v", // force24
2390 "a h:mm:ss v", // force12
2391 "a h:mm:ss z", // jmsz
2392 "HH:mm:ss z", // force24
2393 "a h:mm:ss z", // force12
2395 "h:mm:ss a", // "h:mm:ss"
2397 "a'xx'h:mm:ss d MMM y", // "a'xx'h:mm:ss d MMM y"
2398 "HH:mm:ss d MMM y", //
2399 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' h:mm:ss a 'hrs'"
2400 "EEE, d MMM y 'aha' HH:mm:ss 'hrs'", //
2401 "EEE, d MMM y 'aha' a'xx'h:mm:ss", // "EEE, d MMM y 'aha' a'xx'h:mm:ss"
2402 "EEE, d MMM y 'aha' HH:mm:ss", //
2403 "yyMMddhhmmss", // "yyMMddhhmmss"
2406 "a h:mm:ss", // "H:mm:ss"
2408 "a h:mm:ss d MMM y", // "H:mm:ss d MMM y"
2409 "H:mm:ss d MMM y", //
2410 "EEE, d MMM y 'aha' a h:mm:ss 'hrs'", // "EEE, d MMM y 'aha' H:mm:ss 'hrs'"
2411 "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
2412 "EEE, d MMM y 'aha' a h'h'mm'm'ss", // "EEE, d MMM y 'aha' H'h'mm'm'ss"
2413 "EEE, d MMM y 'aha' H'h'mm'm'ss", //
2418 const char * locale
;
2419 const char ** resultsPtr
;
2420 } RemapPatternLocaleResults
;
2422 static const RemapPatternLocaleResults remapLocResults
[] = {
2423 { "root", remapResults_root
},
2424 { "en", remapResults_en
},
2425 { "ja", remapResults_ja
},
2426 { "ko", remapResults_ko
},
2427 { "th", remapResults_th
},
2428 { "hi", remapResults_hi
},
2432 enum { kUBufRemapMax
= 64, kBBufRemapMax
= 128 };
2434 static void TestRemapPatternWithOpts(void) { /* Apple-specific */
2435 const RemapPatternLocaleResults
* locResPtr
;
2436 for (locResPtr
= remapLocResults
; locResPtr
->locale
!= NULL
; locResPtr
++) {
2437 UErrorCode status
= U_ZERO_ERROR
;
2438 UDateTimePatternGenerator
* dtpg
= udatpg_open(locResPtr
->locale
, &status
);
2439 if ( U_FAILURE(status
) ) {
2440 log_data_err("udatpg_open fails for locale %s, status %s (Are you missing data?)\n", locResPtr
->locale
, u_errorName(status
));
2442 const RemapPatternTestItem
* testItemPtr
= remapPatItems
;
2443 const char ** expResultsPtr
= locResPtr
->resultsPtr
;
2444 for (; testItemPtr
->pattern
!= NULL
&& *expResultsPtr
!= NULL
; testItemPtr
++, expResultsPtr
++) {
2445 UChar uskel
[kUBufRemapMax
];
2446 UChar upatn
[kUBufRemapMax
];
2447 UChar uget
[kUBufRemapMax
];
2448 UChar uexp
[kUBufRemapMax
];
2449 int32_t uelen
, ulen
= 0;
2451 status
= U_ZERO_ERROR
;
2452 if (testItemPtr
->testtype
>= 0) {
2453 UDateFormatStyle timeStyle
= (UDateFormatStyle
)((int32_t)testItemPtr
->testtype
& 0x03);
2454 UDateFormatStyle dateStyle
= (UDateFormatStyle
)((((int32_t)testItemPtr
->testtype
>> 2) & 0x07) - 1);
2455 UDateFormat
* dfmt
= udat_open(timeStyle
, dateStyle
, locResPtr
->locale
, NULL
, 0, NULL
, 0, &status
);
2456 if ( U_FAILURE(status
) ) {
2457 log_data_err("udat_open fails for locale %s, status %s (Are you missing data?)\n", locResPtr
->locale
, u_errorName(status
));
2460 ulen
= udat_toPattern(dfmt
, FALSE
, upatn
, kUBufRemapMax
, &status
);
2462 if ( U_FAILURE(status
) ) {
2463 log_err("udat_toPattern fails for locale %s, status %s\n", locResPtr
->locale
, u_errorName(status
));
2467 } else if (testItemPtr
->testtype
== REMAP_TESTTYPE_SKELETON
) {
2468 u_strFromUTF8(uskel
, kUBufRemapMax
, &ulen
, testItemPtr
->pattern
, -1, &status
);
2469 ulen
= udatpg_getBestPatternWithOptions(dtpg
, uskel
, ulen
, (UDateTimePatternMatchOptions
)testItemPtr
->options
, upatn
, kUBufRemapMax
, &status
);
2470 if ( U_FAILURE(status
) ) {
2471 log_err("udatpg_getBestPatternWithOptions fails for locale %s, skeleton \"%s\": status %s\n", locResPtr
->locale
, testItemPtr
->pattern
, u_errorName(status
));
2475 ulen
= u_unescape(testItemPtr
->pattern
, upatn
, kUBufRemapMax
);
2477 uelen
= u_unescape(*expResultsPtr
, uexp
, kUBufRemapMax
);
2478 ulen
= uadatpg_remapPatternWithOptions(dtpg
, upatn
, ulen
, (UDateTimePatternMatchOptions
)testItemPtr
->options
, uget
, kUBufRemapMax
, &status
);
2479 if ( U_FAILURE(status
) ) {
2480 log_err("uadatpg_remapPatternWithOptions fails for locale %s pattern \"%s\" opts %08X: status %s\n",
2481 locResPtr
->locale
, testItemPtr
->pattern
, testItemPtr
->options
, u_errorName(status
));
2482 } else if (uelen
!= ulen
|| u_strncmp(uget
, uexp
, ulen
) != 0) {
2483 char bebuf
[kBBufRemapMax
];
2484 char bbuf
[kBBufRemapMax
];
2485 UErrorCode tempStatus
= U_ZERO_ERROR
;
2486 u_strToUTF8(bebuf
, kBBufRemapMax
, NULL
, uexp
, uelen
, &tempStatus
);
2487 u_strToUTF8(bbuf
, kBBufRemapMax
, NULL
, uget
, ulen
, &tempStatus
);
2488 log_err("uadatpg_remapPatternWithOptions for locale %s pattern \"%s\" opts %08X: expect \"%s\", get \"%s\"\n",
2489 locResPtr
->locale
, testItemPtr
->pattern
, testItemPtr
->options
, bebuf
, bbuf
);
2497 #endif /* #if !UCONFIG_NO_FORMATTING */