1 // Copyright (C) 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /********************************************************************
5 * Copyright (c) 1997-2016, International Business Machines Corporation and
6 * others. All Rights Reserved.
7 ********************************************************************/
8 /********************************************************************************
12 * Modification History:
14 * Madhu Katragadda Creation
15 *********************************************************************************
18 /* C API TEST FOR DATE FORMAT */
20 #include "unicode/utypes.h"
22 #if !UCONFIG_NO_FORMATTING
24 #include "unicode/uloc.h"
25 #include "unicode/udat.h"
26 #include "unicode/udatpg.h"
27 #include "unicode/ucal.h"
28 #include "unicode/unum.h"
29 #include "unicode/ustring.h"
30 #include "unicode/ufieldpositer.h"
38 static void TestExtremeDates(void);
39 static void TestAllLocales(void);
40 static void TestRelativeCrash(void);
41 static void TestContext(void);
42 static void TestCalendarDateParse(void);
43 static void TestParseErrorReturnValue(void);
44 static void TestFormatForFields(void);
46 void addDateForTest(TestNode** root);
48 #define TESTCASE(x) addTest(root, &x, "tsformat/cdattst/" #x)
50 void addDateForTest(TestNode** root)
52 TESTCASE(TestDateFormat);
53 TESTCASE(TestRelativeDateFormat);
54 TESTCASE(TestSymbols);
55 TESTCASE(TestDateFormatCalendar);
56 TESTCASE(TestExtremeDates);
57 TESTCASE(TestAllLocales);
58 TESTCASE(TestRelativeCrash);
59 TESTCASE(TestContext);
60 TESTCASE(TestCalendarDateParse);
61 TESTCASE(TestOverrideNumberFormat);
62 TESTCASE(TestParseErrorReturnValue);
63 TESTCASE(TestFormatForFields);
65 /* Testing the DateFormat API */
66 static void TestDateFormat()
68 UDateFormat *def, *fr, *it, *de, *def1, *fr_pat;
71 UErrorCode status = U_ZERO_ERROR;
74 const UNumberFormat *numformat1, *numformat2;
75 UNumberFormat *adoptNF;
81 int32_t resultlengthneeded;
83 UDate d = 837039928046.0;
84 double num = -10456.37;
85 /*const char* str="yyyy.MM.dd G 'at' hh:mm:ss z";
86 const char t[]="2/3/76 2:50 AM";*/
87 /*Testing udat_open() to open a dateformat */
89 ctest_setTimeZone(NULL, &status);
91 log_verbose("\nTesting udat_open() with various parameters\n");
92 fr = udat_open(UDAT_FULL, UDAT_DEFAULT, "fr_FR", NULL,0, NULL, 0,&status);
95 log_data_err("FAIL: error in creating the dateformat using full time style with french locale -> %s (Are you missing data?)\n",
96 myErrorName(status) );
99 /* this is supposed to open default date format, but later on it treats it like it is "en_US"
100 - very bad if you try to run the tests on machine where default locale is NOT "en_US" */
101 /* def = udat_open(UDAT_SHORT, UDAT_SHORT, NULL, NULL, 0, &status); */
102 def = udat_open(UDAT_SHORT, UDAT_SHORT, "en_US", NULL, 0,NULL, 0, &status);
103 if(U_FAILURE(status))
105 log_err("FAIL: error in creating the dateformat using short date and time style\n %s\n",
106 myErrorName(status) );
109 it = udat_open(UDAT_DEFAULT, UDAT_MEDIUM, "it_IT", NULL, 0, NULL, 0,&status);
110 if(U_FAILURE(status))
112 log_err("FAIL: error in creating the dateformat using medium date style with italian locale\n %s\n",
113 myErrorName(status) );
116 de = udat_open(UDAT_LONG, UDAT_LONG, "de_DE", NULL, 0, NULL, 0,&status);
117 if(U_FAILURE(status))
119 log_err("FAIL: error in creating the dateformat using long time and date styles with german locale\n %s\n",
120 myErrorName(status));
123 /*creating a default dateformat */
124 def1 = udat_open(UDAT_SHORT, UDAT_SHORT, NULL, NULL, 0,NULL, 0, &status);
125 if(U_FAILURE(status))
127 log_err("FAIL: error in creating the dateformat using short date and time style\n %s\n",
128 myErrorName(status) );
133 /*Testing udat_getAvailable() and udat_countAvailable()*/
134 log_verbose("\nTesting getAvailableLocales and countAvailable()\n");
135 numlocales=udat_countAvailable();
136 /* use something sensible w/o hardcoding the count */
138 log_data_err("FAIL: error in countAvailable\n");
139 log_verbose("The number of locales for which date/time formatting patterns are available is %d\n", numlocales);
141 for(i=0;i<numlocales;i++) {
142 UErrorCode subStatus = U_ZERO_ERROR;
143 log_verbose("Testing open of %s\n", udat_getAvailable(i));
144 any = udat_open(UDAT_SHORT, UDAT_SHORT, udat_getAvailable(i), NULL ,0, NULL, 0, &subStatus);
145 if(U_FAILURE(subStatus)) {
146 log_data_err("FAIL: date format %s (getAvailable(%d)) is not instantiable: %s\n", udat_getAvailable(i), i, u_errorName(subStatus));
151 /*Testing udat_clone()*/
152 log_verbose("\nTesting the udat_clone() function of date format\n");
153 copy=udat_clone(def, &status);
154 if(U_FAILURE(status)){
155 log_err("Error in creating the clone using udat_clone: %s\n", myErrorName(status) );
158 log_err("Error in udat_clone");*/ /*how should i check for equality???? */
160 /*Testing udat_format()*/
161 log_verbose("\nTesting the udat_format() function of date format\n");
162 u_uastrcpy(temp, "7/10/96, 4:05 PM");
163 /*format using def */
165 resultlengthneeded=udat_format(def, d, NULL, resultlength, NULL, &status);
166 if(status==U_BUFFER_OVERFLOW_ERROR)
169 resultlength=resultlengthneeded+1;
174 result=(UChar*)malloc(sizeof(UChar) * resultlength);
175 udat_format(def, d, result, resultlength, NULL, &status);
177 if(U_FAILURE(status) || !result)
179 log_err("FAIL: Error in formatting using udat_format(.....) %s\n", myErrorName(status) );
183 log_verbose("PASS: formatting successful\n");
184 if(u_strcmp(result, temp)==0)
185 log_verbose("PASS: Date Format for US locale successful using udat_format()\n");
189 u_austrcpy(xbuf, temp);
190 u_austrcpy(gbuf, result);
191 log_err("FAIL: Date Format for US locale failed using udat_format() - expected %s got %s\n", xbuf, gbuf);
195 u_unescape("10 juil. 1996 \\u00E0 16:05:28 heure d\\u2019\\u00E9t\\u00E9 du Pacifique", temp, 50);
200 result=myDateFormat(fr, d);
201 if(u_strcmp(result, temp)==0)
202 log_verbose("PASS: Date Format for french locale successful using udat_format()\n");
204 log_data_err("FAIL: Date Format for french locale failed using udat_format().\n" );
207 u_uastrcpy(temp, "10 lug 1996, 16:05:28");
214 fmtted = myDateFormat(it,d);
215 u_austrcpy(g, fmtted);
217 if(u_strcmp(fmtted, temp)==0) {
218 log_verbose("PASS: Date Format for italian locale successful uisng udat_format() - wanted %s, got %s\n", x, g);
220 log_data_err("FAIL: Date Format for italian locale failed using udat_format() - wanted %s, got %s\n", x, g);
224 /*Testing parsing using udat_parse()*/
225 log_verbose("\nTesting parsing using udat_parse()\n");
226 u_uastrcpy(temp,"2/3/76, 2:50 AM");
230 d1=udat_parse(def, temp, u_strlen(temp), &parsepos, &status);
231 if(U_FAILURE(status))
233 log_err("FAIL: Error in parsing using udat_parse(.....) %s\n", myErrorName(status) );
236 log_verbose("PASS: parsing succesful\n");
237 /*format it back and check for equality */
240 if(u_strcmp(myDateFormat(def, d1),temp)!=0)
241 log_err("FAIL: error in parsing\n");
243 /*Testing parsing using udat_parse()*/
244 log_verbose("\nTesting parsing using udat_parse()\n");
245 u_uastrcpy(temp,"2/Don't parse this part");
248 d1=udat_parse(def, temp, u_strlen(temp), NULL, &status);
249 if(status != U_PARSE_ERROR)
251 log_err("FAIL: udat_parse(\"bad string\") passed when it should have failed\n");
254 log_verbose("PASS: parsing succesful\n");
258 /*Testing udat_openPattern() */
260 log_verbose("\nTesting the udat_openPattern with a specified pattern\n");
261 /*for french locale */
262 fr_pat=udat_open(UDAT_PATTERN, UDAT_PATTERN,"fr_FR",NULL,0,temp, u_strlen(temp), &status);
263 if(U_FAILURE(status))
265 log_err("FAIL: Error in creating a date format using udat_openPattern \n %s\n",
266 myErrorName(status) );
269 log_verbose("PASS: creating dateformat using udat_openPattern() succesful\n");
272 /*Testing applyPattern and toPattern */
273 log_verbose("\nTesting applyPattern and toPattern()\n");
274 udat_applyPattern(def1, FALSE, temp, u_strlen(temp));
275 log_verbose("Extracting the pattern\n");
278 resultlengthneeded=udat_toPattern(def1, FALSE, NULL, resultlength, &status);
279 if(status==U_BUFFER_OVERFLOW_ERROR)
282 resultlength=resultlengthneeded + 1;
283 result=(UChar*)malloc(sizeof(UChar) * resultlength);
284 udat_toPattern(def1, FALSE, result, resultlength, &status);
286 if(U_FAILURE(status))
288 log_err("FAIL: error in extracting the pattern from UNumberFormat\n %s\n",
289 myErrorName(status) );
291 if(u_strcmp(result, temp)!=0)
292 log_err("FAIL: Error in extracting the pattern\n");
294 log_verbose("PASS: applyPattern and toPattern work fine\n");
302 /*Testing getter and setter functions*/
303 /*isLenient and setLenient()*/
304 log_verbose("\nTesting the isLenient and setLenient properties\n");
305 udat_setLenient(fr, udat_isLenient(it));
306 if(udat_isLenient(fr) != udat_isLenient(it))
307 log_err("ERROR: setLenient() failed\n");
309 log_verbose("PASS: setLenient() successful\n");
312 /*Test get2DigitYearStart set2DigitYearStart */
313 log_verbose("\nTesting the get and set 2DigitYearStart properties\n");
314 d1= udat_get2DigitYearStart(fr_pat,&status);
315 if(U_FAILURE(status)) {
316 log_err("ERROR: udat_get2DigitYearStart failed %s\n", myErrorName(status) );
318 status = U_ZERO_ERROR;
319 udat_set2DigitYearStart(def1 ,d1, &status);
320 if(U_FAILURE(status)) {
321 log_err("ERROR: udat_set2DigitYearStart failed %s\n", myErrorName(status) );
323 if(udat_get2DigitYearStart(fr_pat, &status) != udat_get2DigitYearStart(def1, &status))
324 log_err("FAIL: error in set2DigitYearStart\n");
326 log_verbose("PASS: set2DigitYearStart successful\n");
327 /*try setting it to another value */
328 udat_set2DigitYearStart(de, 2000.0, &status);
329 if(U_FAILURE(status)){
330 log_verbose("ERROR: udat_set2DigitYearStart failed %s\n", myErrorName(status) );
332 if(udat_get2DigitYearStart(de, &status) != 2000)
333 log_err("FAIL: error in set2DigitYearStart\n");
335 log_verbose("PASS: set2DigitYearStart successful\n");
339 /*Test getNumberFormat() and setNumberFormat() */
340 log_verbose("\nTesting the get and set NumberFormat properties of date format\n");
341 numformat1=udat_getNumberFormat(fr_pat);
342 udat_setNumberFormat(def1, numformat1);
343 numformat2=udat_getNumberFormat(def1);
344 if(u_strcmp(myNumformat(numformat1, num), myNumformat(numformat2, num)) !=0)
345 log_err("FAIL: error in setNumberFormat or getNumberFormat()\n");
347 log_verbose("PASS:setNumberFormat and getNumberFormat succesful\n");
349 /*Test getNumberFormat() and adoptNumberFormat() */
350 log_verbose("\nTesting the get and adopt NumberFormat properties of date format\n");
351 adoptNF= unum_open(UNUM_DEFAULT, NULL, 0, NULL, NULL, &status);
352 udat_adoptNumberFormat(def1, adoptNF);
353 numformat2=udat_getNumberFormat(def1);
354 if(u_strcmp(myNumformat(adoptNF, num), myNumformat(numformat2, num)) !=0)
355 log_err("FAIL: error in adoptNumberFormat or getNumberFormat()\n");
357 log_verbose("PASS:adoptNumberFormat and getNumberFormat succesful\n");
359 /*try setting the number format to another format */
360 numformat1=udat_getNumberFormat(def);
361 udat_setNumberFormat(def1, numformat1);
362 numformat2=udat_getNumberFormat(def1);
363 if(u_strcmp(myNumformat(numformat1, num), myNumformat(numformat2, num)) !=0)
364 log_err("FAIL: error in setNumberFormat or getNumberFormat()\n");
366 log_verbose("PASS: setNumberFormat and getNumberFormat succesful\n");
370 /*Test getCalendar and setCalendar*/
371 log_verbose("\nTesting the udat_getCalendar() and udat_setCalendar() properties\n");
372 cal=udat_getCalendar(fr_pat);
375 udat_setCalendar(def1, cal);
376 if(!ucal_equivalentTo(udat_getCalendar(fr_pat), udat_getCalendar(def1)))
377 log_err("FAIL: Error in setting and getting the calendar\n");
379 log_verbose("PASS: getting and setting calendar successful\n");
385 /*Closing the UDateForamt */
394 ctest_resetTimeZone();
398 Test combined relative date formatting (relative date + non-relative time).
399 This is a bit tricky since we can't have static test data for comparison, the
400 relative date formatting is relative to the time the tests are run. We generate
401 the data for comparison dynamically. However, the tests could fail if they are
402 run right at midnight Pacific time and the call to ucal_getNow() is before midnight
403 while the calls to udat_format are after midnight or span midnight.
405 static const UDate dayInterval = 24.0*60.0*60.0*1000.0;
406 static const UChar trdfZone[] = { 0x0055, 0x0053, 0x002F, 0x0050, 0x0061, 0x0063, 0x0069, 0x0066, 0x0069, 0x0063, 0 }; /* US/Pacific */
407 static const char trdfLocale[] = "en_US";
408 static const UChar minutesPatn[] = { 0x006D, 0x006D, 0 }; /* "mm" */
409 static const UChar monthLongPatn[] = { 0x004D, 0x004D, 0x004D, 0x004D, 0 }; /* "MMMM" */
410 static const UChar monthMediumPatn[] = { 0x004D, 0x004D, 0x004D, 0 }; /* "MMM" */
411 static const UChar monthShortPatn[] = { 0x004D, 0 }; /* "M" */
412 static const UDateFormatStyle dateStylesList[] = { UDAT_FULL, UDAT_LONG, UDAT_MEDIUM, UDAT_SHORT, UDAT_NONE };
413 static const UChar *monthPatnsList[] = { monthLongPatn, monthLongPatn, monthMediumPatn, monthShortPatn, NULL };
414 static const UChar newTimePatn[] = { 0x0048, 0x0048, 0x002C, 0x006D, 0x006D, 0 }; /* "HH,mm" */
415 static const UChar minutesStr[] = { 0x0034, 0x0039, 0 }; /* "49", minutes string to search for in output */
416 enum { kDateOrTimeOutMax = 96, kDateAndTimeOutMax = 192 };
418 static const UDate minutesTolerance = 2 * 60.0 * 1000.0;
419 static const UDate daysTolerance = 2 * 24.0 * 60.0 * 60.0 * 1000.0;
421 static void TestRelativeDateFormat()
424 const UDateFormatStyle * stylePtr;
425 const UChar ** monthPtnPtr;
426 UErrorCode status = U_ZERO_ERROR;
427 UCalendar * ucal = ucal_open(trdfZone, -1, trdfLocale, UCAL_GREGORIAN, &status);
428 if ( U_SUCCESS(status) ) {
429 int32_t year, month, day;
430 ucal_setMillis(ucal, ucal_getNow(), &status);
431 year = ucal_get(ucal, UCAL_YEAR, &status);
432 month = ucal_get(ucal, UCAL_MONTH, &status);
433 day = ucal_get(ucal, UCAL_DATE, &status);
434 ucal_setDateTime(ucal, year, month, day, 18, 49, 0, &status); /* set to today at 18:49:00 */
435 today = ucal_getMillis(ucal, &status);
438 if ( U_FAILURE(status) || today == 0.0 ) {
439 log_data_err("Generate UDate for a specified time today fails, error %s - (Are you missing data?)\n", myErrorName(status) );
442 for (stylePtr = dateStylesList, monthPtnPtr = monthPatnsList; *stylePtr != UDAT_NONE; ++stylePtr, ++monthPtnPtr) {
443 UDateFormat* fmtRelDateTime;
444 UDateFormat* fmtRelDate;
445 UDateFormat* fmtTime;
446 int32_t dayOffset, limit;
448 UChar strDateTime[kDateAndTimeOutMax];
449 UChar strDate[kDateOrTimeOutMax];
450 UChar strTime[kDateOrTimeOutMax];
454 fmtRelDateTime = udat_open(UDAT_SHORT, *stylePtr | UDAT_RELATIVE, trdfLocale, trdfZone, -1, NULL, 0, &status);
455 if ( U_FAILURE(status) ) {
456 log_data_err("udat_open timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s (Are you missing data?)\n", *stylePtr, myErrorName(status) );
459 fmtRelDate = udat_open(UDAT_NONE, *stylePtr | UDAT_RELATIVE, trdfLocale, trdfZone, -1, NULL, 0, &status);
460 if ( U_FAILURE(status) ) {
461 log_err("udat_open timeStyle NONE dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
462 udat_close(fmtRelDateTime);
465 fmtTime = udat_open(UDAT_SHORT, UDAT_NONE, trdfLocale, trdfZone, -1, NULL, 0, &status);
466 if ( U_FAILURE(status) ) {
467 log_err("udat_open timeStyle SHORT dateStyle NONE fails, error %s\n", myErrorName(status) );
468 udat_close(fmtRelDateTime);
469 udat_close(fmtRelDate);
473 dtpatLen = udat_toPatternRelativeDate(fmtRelDateTime, strDate, kDateAndTimeOutMax, &status);
474 if ( U_FAILURE(status) ) {
475 log_err("udat_toPatternRelativeDate timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
476 status = U_ZERO_ERROR;
477 } else if ( u_strstr(strDate, *monthPtnPtr) == NULL || dtpatLen != u_strlen(strDate) ) {
478 log_err("udat_toPatternRelativeDate timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) date pattern incorrect\n", *stylePtr );
480 dtpatLen = udat_toPatternRelativeTime(fmtRelDateTime, strTime, kDateAndTimeOutMax, &status);
481 if ( U_FAILURE(status) ) {
482 log_err("udat_toPatternRelativeTime timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
483 status = U_ZERO_ERROR;
484 } else if ( u_strstr(strTime, minutesPatn) == NULL || dtpatLen != u_strlen(strTime) ) {
485 log_err("udat_toPatternRelativeTime timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) time pattern incorrect\n", *stylePtr );
487 dtpatLen = udat_toPattern(fmtRelDateTime, FALSE, strDateTime, kDateAndTimeOutMax, &status);
488 if ( U_FAILURE(status) ) {
489 log_err("udat_toPattern timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
490 status = U_ZERO_ERROR;
491 } else if ( u_strstr(strDateTime, strDate) == NULL || u_strstr(strDateTime, strTime) == NULL || dtpatLen != u_strlen(strDateTime) ) {
492 log_err("udat_toPattern timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) dateTime pattern incorrect\n", *stylePtr );
494 udat_applyPatternRelative(fmtRelDateTime, strDate, u_strlen(strDate), newTimePatn, u_strlen(newTimePatn), &status);
495 if ( U_FAILURE(status) ) {
496 log_err("udat_applyPatternRelative timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
497 status = U_ZERO_ERROR;
499 udat_toPattern(fmtRelDateTime, FALSE, strDateTime, kDateAndTimeOutMax, &status);
500 if ( U_FAILURE(status) ) {
501 log_err("udat_toPattern timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
502 status = U_ZERO_ERROR;
503 } else if ( u_strstr(strDateTime, newTimePatn) == NULL ) {
504 log_err("udat_applyPatternRelative timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) didn't update time pattern\n", *stylePtr );
507 udat_applyPatternRelative(fmtRelDateTime, strDate, u_strlen(strDate), strTime, u_strlen(strTime), &status); /* restore original */
509 fp.field = UDAT_MINUTE_FIELD;
510 for (dayOffset = -2, limit = 2; dayOffset <= limit; ++dayOffset) {
511 UDate dateToUse = today + (float)dayOffset*dayInterval;
513 udat_format(fmtRelDateTime, dateToUse, strDateTime, kDateAndTimeOutMax, &fp, &status);
514 if ( U_FAILURE(status) ) {
515 log_err("udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
516 status = U_ZERO_ERROR;
518 int32_t parsePos = 0;
519 UDate dateResult = udat_parse(fmtRelDateTime, strDateTime, -1, &parsePos, &status);
520 UDate dateDiff = (dateResult >= dateToUse)? dateResult - dateToUse: dateToUse - dateResult;
521 if ( U_FAILURE(status) || dateDiff > minutesTolerance ) {
522 log_err("udat_parse timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s, expect approx %.1f, got %.1f, parsePos %d\n",
523 *stylePtr, myErrorName(status), dateToUse, dateResult, parsePos );
524 status = U_ZERO_ERROR;
527 udat_format(fmtRelDate, dateToUse, strDate, kDateOrTimeOutMax, NULL, &status);
528 if ( U_FAILURE(status) ) {
529 log_err("udat_format timeStyle NONE dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
530 status = U_ZERO_ERROR;
531 } else if ( u_strstr(strDateTime, strDate) == NULL ) {
532 log_err("relative date string not found in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", *stylePtr );
535 dateResult = udat_parse(fmtRelDate, strDate, -1, &parsePos, &status);
536 dateDiff = (dateResult >= dateToUse)? dateResult - dateToUse: dateToUse - dateResult;
537 if ( U_FAILURE(status) || dateDiff > daysTolerance ) {
538 log_err("udat_parse timeStyle NONE dateStyle (%d | UDAT_RELATIVE) fails, error %s, expect approx %.1f, got %.1f, parsePos %d\n",
539 *stylePtr, myErrorName(status), dateToUse, dateResult, parsePos );
540 status = U_ZERO_ERROR;
544 udat_format(fmtTime, dateToUse, strTime, kDateOrTimeOutMax, NULL, &status);
545 if ( U_FAILURE(status) ) {
546 log_err("udat_format timeStyle SHORT dateStyle NONE fails, error %s\n", myErrorName(status) );
547 status = U_ZERO_ERROR;
548 } else if ( u_strstr(strDateTime, strTime) == NULL ) {
549 log_err("time string not found in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", *stylePtr );
552 strPtr = u_strstr(strDateTime, minutesStr);
553 if ( strPtr != NULL ) {
554 int32_t beginIndex = strPtr - strDateTime;
555 if ( fp.beginIndex != beginIndex ) {
556 log_err("UFieldPosition beginIndex %d, expected %d, in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", fp.beginIndex, beginIndex, *stylePtr );
559 log_err("minutes string not found in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", *stylePtr );
564 udat_close(fmtRelDateTime);
565 udat_close(fmtRelDate);
570 /*Testing udat_getSymbols() and udat_setSymbols() and udat_countSymbols()*/
571 static void TestSymbols()
573 UDateFormat *def, *fr, *zhChiCal;
574 UErrorCode status = U_ZERO_ERROR;
576 UChar *result = NULL;
577 int32_t resultlength;
578 int32_t resultlengthout;
582 /*creating a dateformat with french locale */
583 log_verbose("\ncreating a date format with french locale\n");
584 fr = udat_open(UDAT_FULL, UDAT_DEFAULT, "fr_FR", NULL, 0, NULL, 0, &status);
585 if(U_FAILURE(status))
587 log_data_err("error in creating the dateformat using full time style with french locale -> %s (Are you missing data?)\n",
588 myErrorName(status) );
591 /*creating a default dateformat */
592 log_verbose("\ncreating a date format with default locale\n");
593 /* this is supposed to open default date format, but later on it treats it like it is "en_US"
594 - very bad if you try to run the tests on machine where default locale is NOT "en_US" */
595 /* def = udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,NULL, NULL, 0, &status); */
596 def = udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,"en_US", NULL, 0, NULL, 0, &status);
597 if(U_FAILURE(status))
599 log_err("error in creating the dateformat using short date and time style\n %s\n",
600 myErrorName(status) );
603 /*creating a dateformat with zh locale */
604 log_verbose("\ncreating a date format with zh locale for chinese calendar\n");
605 zhChiCal = udat_open(UDAT_NONE, UDAT_FULL, "zh@calendar=chinese", NULL, 0, NULL, 0, &status);
606 if(U_FAILURE(status))
608 log_data_err("error in creating the dateformat using full date, no time, locale zh@calendar=chinese -> %s (Are you missing data?)\n",
609 myErrorName(status) );
614 /*Testing countSymbols, getSymbols and setSymbols*/
615 log_verbose("\nTesting countSymbols\n");
616 /*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 */
617 if(udat_countSymbols(def, UDAT_ERAS)!=2 || udat_countSymbols(def, UDAT_MONTHS)!=12 ||
618 udat_countSymbols(def, UDAT_SHORT_MONTHS)!=12 || udat_countSymbols(def, UDAT_WEEKDAYS)!=8 ||
619 udat_countSymbols(def, UDAT_SHORT_WEEKDAYS)!=8 || udat_countSymbols(def, UDAT_AM_PMS)!=2 ||
620 udat_countSymbols(def, UDAT_QUARTERS) != 4 || udat_countSymbols(def, UDAT_SHORT_QUARTERS) != 4 ||
621 udat_countSymbols(def, UDAT_LOCALIZED_CHARS)!=1 || udat_countSymbols(def, UDAT_SHORTER_WEEKDAYS)!=8 ||
622 udat_countSymbols(zhChiCal, UDAT_CYCLIC_YEARS_NARROW)!=60 || udat_countSymbols(zhChiCal, UDAT_ZODIAC_NAMES_NARROW)!=12)
624 log_err("FAIL: error in udat_countSymbols\n");
627 log_verbose("PASS: udat_countSymbols() successful\n");
629 /*testing getSymbols*/
630 log_verbose("\nTesting getSymbols\n");
631 pattern=(UChar*)malloc(sizeof(UChar) * 10);
632 u_uastrcpy(pattern, "jeudi");
634 resultlengthout=udat_getSymbols(fr, UDAT_WEEKDAYS, 5 , NULL, resultlength, &status);
635 if(status==U_BUFFER_OVERFLOW_ERROR)
638 resultlength=resultlengthout+1;
643 result=(UChar*)malloc(sizeof(UChar) * resultlength);
644 udat_getSymbols(fr, UDAT_WEEKDAYS, 5, result, resultlength, &status);
647 if(U_FAILURE(status))
649 log_err("FAIL: Error in udat_getSymbols().... %s\n", myErrorName(status) );
652 log_verbose("PASS: getSymbols succesful\n");
654 if(u_strcmp(result, pattern)==0)
655 log_verbose("PASS: getSymbols retrieved the right value\n");
657 log_data_err("FAIL: getSymbols retrieved the wrong value\n");
659 /*run series of tests to test getsymbols regressively*/
660 log_verbose("\nTesting getSymbols() regressively\n");
661 VerifygetSymbols(fr, UDAT_WEEKDAYS, 1, "dimanche");
662 VerifygetSymbols(def, UDAT_WEEKDAYS, 1, "Sunday");
663 VerifygetSymbols(fr, UDAT_SHORT_WEEKDAYS, 7, "sam.");
664 VerifygetSymbols(fr, UDAT_SHORTER_WEEKDAYS, 7, "sa");
665 VerifygetSymbols(def, UDAT_SHORT_WEEKDAYS, 7, "Sat");
666 VerifygetSymbols(def, UDAT_MONTHS, 11, "December");
667 VerifygetSymbols(def, UDAT_MONTHS, 0, "January");
668 VerifygetSymbols(fr, UDAT_ERAS, 0, "av. J.-C.");
669 VerifygetSymbols(def, UDAT_AM_PMS, 0, "AM");
670 VerifygetSymbols(def, UDAT_AM_PMS, 1, "PM");
671 VerifygetSymbols(fr, UDAT_SHORT_MONTHS, 0, "janv.");
672 VerifygetSymbols(def, UDAT_SHORT_MONTHS, 11, "Dec");
673 VerifygetSymbols(fr, UDAT_QUARTERS, 0, "1er trimestre");
674 VerifygetSymbols(def, UDAT_QUARTERS, 3, "4th quarter");
675 VerifygetSymbols(fr, UDAT_SHORT_QUARTERS, 1, "T2");
676 VerifygetSymbols(def, UDAT_SHORT_QUARTERS, 2, "Q3");
677 VerifygetSymbols(zhChiCal, UDAT_CYCLIC_YEARS_ABBREVIATED, 0, "\\u7532\\u5B50");
678 VerifygetSymbols(zhChiCal, UDAT_CYCLIC_YEARS_NARROW, 59, "\\u7678\\u4EA5");
679 VerifygetSymbols(zhChiCal, UDAT_ZODIAC_NAMES_ABBREVIATED, 0, "\\u9F20");
680 VerifygetSymbols(zhChiCal, UDAT_ZODIAC_NAMES_WIDE, 11, "\\u732A");
681 #if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
682 VerifygetSymbols(def,UDAT_LOCALIZED_CHARS, 0, "GyMdkHmsSEDFwWahKzYeugAZvcLQqVUOXxrbB:");
684 VerifygetSymbols(def,UDAT_LOCALIZED_CHARS, 0, "GyMdkHmsSEDFwWahKzYeugAZvcLQqVUOXxrbB");
694 log_verbose("\nTesting setSymbols\n");
695 /*applying the pattern so that setSymbolss works */
697 resultlengthout=udat_toPattern(fr, FALSE, NULL, resultlength, &status);
698 if(status==U_BUFFER_OVERFLOW_ERROR)
701 resultlength=resultlengthout + 1;
702 pattern=(UChar*)malloc(sizeof(UChar) * resultlength);
703 udat_toPattern(fr, FALSE, pattern, resultlength, &status);
705 if(U_FAILURE(status))
707 log_err("FAIL: error in extracting the pattern from UNumberFormat\n %s\n",
708 myErrorName(status) );
711 udat_applyPattern(def, FALSE, pattern, u_strlen(pattern));
713 resultlengthout=udat_toPattern(def, FALSE, NULL, resultlength,&status);
714 if(status==U_BUFFER_OVERFLOW_ERROR)
717 resultlength=resultlengthout + 1;
722 result=(UChar*)malloc(sizeof(UChar) * resultlength);
723 udat_toPattern(fr, FALSE,result, resultlength, &status);
725 if(U_FAILURE(status))
727 log_err("FAIL: error in extracting the pattern from UNumberFormat\n %s\n",
728 myErrorName(status) );
730 if(u_strcmp(result, pattern)==0)
731 log_verbose("Pattern applied properly\n");
733 log_err("pattern could not be applied properly\n");
736 /*testing set symbols */
738 resultlengthout=udat_getSymbols(fr, UDAT_MONTHS, 11 , NULL, resultlength, &status);
739 if(status==U_BUFFER_OVERFLOW_ERROR){
741 resultlength=resultlengthout+1;
746 result=(UChar*)malloc(sizeof(UChar) * resultlength);
747 udat_getSymbols(fr, UDAT_MONTHS, 11, result, resultlength, &status);
750 if(U_FAILURE(status))
751 log_err("FAIL: error in getSymbols() %s\n", myErrorName(status) );
752 resultlength=resultlengthout+1;
754 udat_setSymbols(def, UDAT_MONTHS, 11, result, resultlength, &status);
755 if(U_FAILURE(status))
757 log_err("FAIL: Error in udat_setSymbols() : %s\n", myErrorName(status) );
760 log_verbose("PASS: SetSymbols successful\n");
763 resultlengthout=udat_getSymbols(def, UDAT_MONTHS, 11, NULL, resultlength, &status);
764 if(status==U_BUFFER_OVERFLOW_ERROR){
766 resultlength=resultlengthout+1;
767 value=(UChar*)malloc(sizeof(UChar) * resultlength);
768 udat_getSymbols(def, UDAT_MONTHS, 11, value, resultlength, &status);
770 if(U_FAILURE(status))
771 log_err("FAIL: error in retrieving the value using getSymbols i.e roundtrip\n");
773 if(u_strcmp(result, value)!=0)
774 log_data_err("FAIL: Error in settting and getting symbols\n");
776 log_verbose("PASS: setSymbols successful\n");
779 /*run series of tests to test setSymbols regressively*/
780 log_verbose("\nTesting setSymbols regressively\n");
781 VerifysetSymbols(def, UDAT_ERAS, 0, "BeforeChrist");
782 VerifysetSymbols(def, UDAT_ERA_NAMES, 1, "AnnoDomini");
783 VerifysetSymbols(def, UDAT_WEEKDAYS, 1, "Sundayweek");
784 VerifysetSymbols(def, UDAT_SHORT_WEEKDAYS, 7, "Satweek");
785 VerifysetSymbols(def, UDAT_NARROW_WEEKDAYS, 4, "M");
786 VerifysetSymbols(def, UDAT_STANDALONE_WEEKDAYS, 1, "Sonntagweek");
787 VerifysetSymbols(def, UDAT_STANDALONE_SHORT_WEEKDAYS, 7, "Sams");
788 VerifysetSymbols(def, UDAT_STANDALONE_NARROW_WEEKDAYS, 4, "V");
789 VerifysetSymbols(fr, UDAT_MONTHS, 11, "december");
790 VerifysetSymbols(fr, UDAT_SHORT_MONTHS, 0, "Jan");
791 VerifysetSymbols(fr, UDAT_NARROW_MONTHS, 1, "R");
792 VerifysetSymbols(fr, UDAT_STANDALONE_MONTHS, 11, "dezember");
793 VerifysetSymbols(fr, UDAT_STANDALONE_SHORT_MONTHS, 7, "Aug");
794 VerifysetSymbols(fr, UDAT_STANDALONE_NARROW_MONTHS, 2, "M");
795 VerifysetSymbols(fr, UDAT_QUARTERS, 0, "1. Quart");
796 VerifysetSymbols(fr, UDAT_SHORT_QUARTERS, 1, "QQ2");
797 VerifysetSymbols(fr, UDAT_STANDALONE_QUARTERS, 2, "3rd Quar.");
798 VerifysetSymbols(fr, UDAT_STANDALONE_SHORT_QUARTERS, 3, "4QQ");
799 VerifysetSymbols(zhChiCal, UDAT_CYCLIC_YEARS_ABBREVIATED, 1, "yi-chou");
800 VerifysetSymbols(zhChiCal, UDAT_ZODIAC_NAMES_ABBREVIATED, 1, "Ox");
803 /*run series of tests to test get and setSymbols regressively*/
804 log_verbose("\nTesting get and set symbols regressively\n");
805 VerifygetsetSymbols(fr, def, UDAT_WEEKDAYS, 1);
806 VerifygetsetSymbols(fr, def, UDAT_WEEKDAYS, 7);
807 VerifygetsetSymbols(fr, def, UDAT_SHORT_WEEKDAYS, 1);
808 VerifygetsetSymbols(fr, def, UDAT_SHORT_WEEKDAYS, 7);
809 VerifygetsetSymbols(fr, def, UDAT_MONTHS, 0);
810 VerifygetsetSymbols(fr, def, UDAT_SHORT_MONTHS, 0);
811 VerifygetsetSymbols(fr, def, UDAT_ERAS,1);
812 VerifygetsetSymbols(fr, def, UDAT_LOCALIZED_CHARS, 0);
813 VerifygetsetSymbols(fr, def, UDAT_AM_PMS, 1);
820 udat_close(zhChiCal);
830 * Test DateFormat(Calendar) API
832 static void TestDateFormatCalendar() {
833 UDateFormat *date=0, *time=0, *full=0;
839 UErrorCode ec = U_ZERO_ERROR;
842 const char *expected;
845 ctest_setTimeZone(NULL, &ec);
847 /* Create a formatter for date fields. */
848 date = udat_open(UDAT_NONE, UDAT_SHORT, "en_US", NULL, 0, NULL, 0, &ec);
850 log_data_err("FAIL: udat_open(NONE, SHORT, en_US) failed with %s (Are you missing data?)\n",
855 /* Create a formatter for time fields. */
856 time = udat_open(UDAT_SHORT, UDAT_NONE, "en_US", NULL, 0, NULL, 0, &ec);
858 log_err("FAIL: udat_open(SHORT, NONE, en_US) failed with %s\n",
863 /* Create a full format for output */
864 full = udat_open(UDAT_FULL, UDAT_FULL, "en_US", NULL, 0, NULL, 0, &ec);
866 log_err("FAIL: udat_open(FULL, FULL, en_US) failed with %s\n",
871 /* Create a calendar */
872 cal = ucal_open(NULL, 0, "en_US", UCAL_GREGORIAN, &ec);
874 log_err("FAIL: ucal_open(en_US) failed with %s\n",
881 u_uastrcpy(buf, "4/5/2001");
883 udat_parseCalendar(date, cal, buf, -1, &pos, &ec);
885 log_err("FAIL: udat_parseCalendar(4/5/2001) failed at %d with %s\n",
886 pos, u_errorName(ec));
890 /* Check if formatCalendar matches the original date */
891 len1 = udat_formatCalendar(date, cal, buf1, UPRV_LENGTHOF(buf1), NULL, &ec);
893 log_err("FAIL: udat_formatCalendar(4/5/2001) failed with %s\n",
898 u_uastrcpy(uExpected, expected);
899 if (u_strlen(uExpected) != len1 || u_strncmp(uExpected, buf1, len1) != 0) {
900 log_err("FAIL: udat_formatCalendar(4/5/2001), expected: %s", expected);
904 u_uastrcpy(buf, "5:45 PM");
906 udat_parseCalendar(time, cal, buf, -1, &pos, &ec);
908 log_err("FAIL: udat_parseCalendar(17:45) failed at %d with %s\n",
909 pos, u_errorName(ec));
913 /* Check if formatCalendar matches the original time */
914 len1 = udat_formatCalendar(time, cal, buf1, UPRV_LENGTHOF(buf1), NULL, &ec);
916 log_err("FAIL: udat_formatCalendar(17:45) failed with %s\n",
920 expected = "5:45 PM";
921 u_uastrcpy(uExpected, expected);
922 if (u_strlen(uExpected) != len1 || u_strncmp(uExpected, buf1, len1) != 0) {
923 log_err("FAIL: udat_formatCalendar(17:45), expected: %s", expected);
927 when = ucal_getMillis(cal, &ec);
929 log_err("FAIL: ucal_getMillis() failed with %s\n", u_errorName(ec));
932 udat_format(full, when, buf, sizeof(buf), NULL, &ec);
934 log_err("FAIL: udat_format() failed with %s\n", u_errorName(ec));
937 u_austrcpy(cbuf, buf);
938 /* Thursday, April 5, 2001 5:45:00 PM PDT 986517900000 */
939 if (when == 986517900000.0) {
940 log_verbose("Ok: Parsed result: %s\n", cbuf);
942 log_err("FAIL: Parsed result: %s, exp 4/5/2001 5:45 PM\n", cbuf);
951 ctest_resetTimeZone();
957 * Test parsing two digit year against "YY" vs. "YYYY" patterns
959 static void TestCalendarDateParse() {
962 UErrorCode ec = U_ZERO_ERROR;
963 UDateFormat* simpleDateFormat = 0;
964 int32_t parsePos = 0;
965 int32_t twoDigitCenturyStart = 75;
966 int32_t currentTwoDigitYear = 0;
967 int32_t startCentury = 0;
968 UCalendar* tempCal = 0;
969 UCalendar* calendar = 0;
971 U_STRING_DECL(pattern, "yyyy", 4);
972 U_STRING_DECL(pattern2, "yy", 2);
973 U_STRING_DECL(text, "75", 2);
975 U_STRING_INIT(pattern, "yyyy", 4);
976 U_STRING_INIT(pattern2, "yy", 2);
977 U_STRING_INIT(text, "75", 2);
979 simpleDateFormat = udat_open(UDAT_FULL, UDAT_FULL, "en-GB", 0, 0, 0, 0, &ec);
981 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));
984 udat_applyPattern(simpleDateFormat, 0, pattern, u_strlen(pattern));
985 udat_setLenient(simpleDateFormat, 0);
987 currentTwoDigitYear = getCurrentYear() % 100;
988 startCentury = getCurrentYear() - currentTwoDigitYear;
989 if (twoDigitCenturyStart > currentTwoDigitYear) {
992 tempCal = ucal_open(NULL, -1, NULL, UCAL_GREGORIAN, &ec);
993 ucal_setMillis(tempCal, 0, &ec);
994 ucal_setDateTime(tempCal, startCentury + twoDigitCenturyStart, UCAL_JANUARY, 1, 0, 0, 0, &ec);
995 udat_set2DigitYearStart(simpleDateFormat, ucal_getMillis(tempCal, &ec), &ec);
997 calendar = ucal_open(NULL, -1, NULL, UCAL_GREGORIAN, &ec);
998 ucal_setMillis(calendar, 0, &ec);
999 ucal_setDateTime(calendar, twoDigitCenturyStart, UCAL_JANUARY, 1, 0, 0, 0, &ec);
1001 udat_parseCalendar(simpleDateFormat, calendar, text, u_strlen(text), &parsePos, &ec);
1004 result = ucal_get(calendar, UCAL_YEAR, &ec);
1005 if (U_FAILURE(ec)) {
1006 log_err("FAIL: ucal_get(UCAL_YEAR) failed with %s\n", u_errorName(ec));
1011 log_err("FAIL: parsed incorrect year: %d\n", result);
1016 udat_applyPattern(simpleDateFormat, 0, pattern2, u_strlen(pattern2));
1017 udat_parseCalendar(simpleDateFormat, calendar, text, u_strlen(text), &parsePos, &ec);
1020 result = ucal_get(calendar, UCAL_YEAR, &ec);
1021 if (U_FAILURE(ec)) {
1022 log_err("FAIL: ucal_get(UCAL_YEAR) failed with %s\n", u_errorName(ec));
1026 if (result != 1975) {
1027 log_err("FAIL: parsed incorrect year: %d\n", result);
1032 udat_close(simpleDateFormat);
1033 udat_close(tempCal);
1034 udat_close(calendar);
1038 /*INTERNAL FUNCTIONS USED*/
1039 static int getCurrentYear() {
1040 static int currentYear = 0;
1041 if (currentYear == 0) {
1042 UErrorCode status = U_ZERO_ERROR;
1043 UCalendar *cal = ucal_open(NULL, -1, NULL, UCAL_GREGORIAN, &status);
1044 if (!U_FAILURE(status)) {
1045 /* Get the current year from the default UCalendar */
1046 currentYear = ucal_get(cal, UCAL_YEAR, &status);
1054 /* N.B.: use idx instead of index to avoid 'shadow' warnings in strict mode. */
1055 static void VerifygetSymbols(UDateFormat* datfor, UDateFormatSymbolType type, int32_t idx, const char* expected)
1057 UChar *pattern=NULL;
1058 UErrorCode status = U_ZERO_ERROR;
1060 int32_t resultlength, resultlengthout;
1061 int32_t patternSize = strlen(expected) + 1;
1063 pattern=(UChar*)malloc(sizeof(UChar) * patternSize);
1064 u_unescape(expected, pattern, patternSize);
1066 resultlengthout=udat_getSymbols(datfor, type, idx , NULL, resultlength, &status);
1067 if(status==U_BUFFER_OVERFLOW_ERROR)
1069 status=U_ZERO_ERROR;
1070 resultlength=resultlengthout+1;
1071 result=(UChar*)malloc(sizeof(UChar) * resultlength);
1072 udat_getSymbols(datfor, type, idx, result, resultlength, &status);
1075 if(U_FAILURE(status))
1077 log_err("FAIL: Error in udat_getSymbols()... %s\n", myErrorName(status) );
1080 if(u_strcmp(result, pattern)==0)
1081 log_verbose("PASS: getSymbols retrieved the right value\n");
1083 log_data_err("FAIL: getSymbols retrieved the wrong value\n Expected %s Got %s\n", expected,
1084 aescstrdup(result,-1) );
1090 static void VerifysetSymbols(UDateFormat* datfor, UDateFormatSymbolType type, int32_t idx, const char* expected)
1094 int32_t resultlength, resultlengthout;
1095 UErrorCode status = U_ZERO_ERROR;
1096 int32_t valueLen, valueSize = strlen(expected) + 1;
1098 value=(UChar*)malloc(sizeof(UChar) * valueSize);
1099 valueLen = u_unescape(expected, value, valueSize);
1100 udat_setSymbols(datfor, type, idx, value, valueLen, &status);
1101 if(U_FAILURE(status))
1103 log_err("FAIL: Error in udat_setSymbols() %s\n", myErrorName(status) );
1108 resultlengthout=udat_getSymbols(datfor, type, idx, NULL, resultlength, &status);
1109 if(status==U_BUFFER_OVERFLOW_ERROR){
1110 status=U_ZERO_ERROR;
1111 resultlength=resultlengthout+1;
1112 result=(UChar*)malloc(sizeof(UChar) * resultlength);
1113 udat_getSymbols(datfor, type, idx, result, resultlength, &status);
1115 if(U_FAILURE(status)){
1116 log_err("FAIL: error in retrieving the value using getSymbols after setting it previously\n %s\n",
1117 myErrorName(status) );
1121 if(u_strcmp(result, value)!=0){
1122 log_err("FAIL:Error in setting and then getting symbols\n Expected %s Got %s\n", expected,
1123 aescstrdup(result,-1) );
1126 log_verbose("PASS: setSymbols successful\n");
1133 static void VerifygetsetSymbols(UDateFormat* from, UDateFormat* to, UDateFormatSymbolType type, int32_t idx)
1137 int32_t resultlength, resultlengthout;
1138 UErrorCode status = U_ZERO_ERROR;
1141 resultlengthout=udat_getSymbols(from, type, idx , NULL, resultlength, &status);
1142 if(status==U_BUFFER_OVERFLOW_ERROR){
1143 status=U_ZERO_ERROR;
1144 resultlength=resultlengthout+1;
1145 result=(UChar*)malloc(sizeof(UChar) * resultlength);
1146 udat_getSymbols(from, type, idx, result, resultlength, &status);
1148 if(U_FAILURE(status)){
1149 log_err("FAIL: error in getSymbols() %s\n", myErrorName(status) );
1153 resultlength=resultlengthout+1;
1154 udat_setSymbols(to, type, idx, result, resultlength, &status);
1155 if(U_FAILURE(status))
1157 log_err("FAIL: Error in udat_setSymbols() : %s\n", myErrorName(status) );
1162 resultlengthout=udat_getSymbols(to, type, idx, NULL, resultlength, &status);
1163 if(status==U_BUFFER_OVERFLOW_ERROR){
1164 status=U_ZERO_ERROR;
1165 resultlength=resultlengthout+1;
1166 value=(UChar*)malloc(sizeof(UChar) * resultlength);
1167 udat_getSymbols(to, type, idx, value, resultlength, &status);
1169 if(U_FAILURE(status)){
1170 log_err("FAIL: error in retrieving the value using getSymbols i.e roundtrip\n %s\n",
1171 myErrorName(status) );
1175 if(u_strcmp(result, value)!=0){
1176 log_data_err("FAIL:Error in setting and then getting symbols\n Expected %s Got %s\n", austrdup(result),
1180 log_verbose("PASS: setSymbols successful\n");
1187 static UChar* myNumformat(const UNumberFormat* numfor, double d)
1189 UChar *result2=NULL;
1190 int32_t resultlength, resultlengthneeded;
1191 UErrorCode status = U_ZERO_ERROR;
1194 resultlengthneeded=unum_formatDouble(numfor, d, NULL, resultlength, NULL, &status);
1195 if(status==U_BUFFER_OVERFLOW_ERROR)
1197 status=U_ZERO_ERROR;
1198 resultlength=resultlengthneeded+1;
1199 /*result2=(UChar*)malloc(sizeof(UChar) * resultlength);*/ /* this leaks */
1200 result2=(UChar*)ctst_malloc(sizeof(UChar) * resultlength); /*this won't*/
1201 unum_formatDouble(numfor, d, result2, resultlength, NULL, &status);
1203 if(U_FAILURE(status))
1205 log_err("FAIL: Error in formatting using unum_format(.....) %s\n", myErrorName(status) );
1213 * The search depth for TestExtremeDates. The total number of
1214 * dates that will be tested is (2^EXTREME_DATES_DEPTH) - 1.
1216 #define EXTREME_DATES_DEPTH 8
1219 * Support for TestExtremeDates (below).
1221 * Test a single date to see whether udat_format handles it properly.
1223 static UBool _aux1ExtremeDates(UDateFormat* fmt, UDate date,
1224 UChar* buf, int32_t buflen, char* cbuf,
1226 int32_t len = udat_format(fmt, date, buf, buflen, 0, ec);
1227 if (!assertSuccess("udat_format", ec)) return FALSE;
1228 u_austrncpy(cbuf, buf, buflen);
1230 log_err("FAIL: udat_format(%g) => \"%s\"\n", date, cbuf);
1232 log_verbose("udat_format(%g) => \"%s\"\n", date, cbuf);
1238 * Support for TestExtremeDates (below).
1240 * Recursively test between 'small' and 'large', up to the depth
1241 * limit specified by EXTREME_DATES_DEPTH.
1243 static UBool _aux2ExtremeDates(UDateFormat* fmt, UDate small, UDate large,
1244 UChar* buf, int32_t buflen, char* cbuf,
1247 /* Logarithmic midpoint; see below */
1248 UDate mid = (UDate) exp((log(small) + log(large)) / 2);
1249 if (count == EXTREME_DATES_DEPTH) {
1253 _aux1ExtremeDates(fmt, mid, buf, buflen, cbuf, ec) &&
1254 _aux2ExtremeDates(fmt, small, mid, buf, buflen, cbuf, count+1, ec) &&
1255 _aux2ExtremeDates(fmt, mid, large, buf, buflen, cbuf, count+1, ec);
1259 * http://www.jtcsv.com/cgibin/icu-bugs?findid=3659
1261 * For certain large dates, udat_format crashes on MacOS. This test
1262 * attempts to reproduce this problem by doing a recursive logarithmic*
1263 * binary search of a predefined interval (from 'small' to 'large').
1265 * The limit of the search is given by EXTREME_DATES_DEPTH, above.
1267 * *The search has to be logarithmic, not linear. A linear search of the
1268 * range 0..10^30, for example, will find 0.5*10^30, then 0.25*10^30 and
1269 * 0.75*10^30, etc. A logarithmic search will find 10^15, then 10^7.5
1272 static void TestExtremeDates() {
1277 const double small = 1000; /* 1 sec */
1278 const double large = 1e+30; /* well beyond usable UDate range */
1280 /* There is no need to test larger values from 1e+30 to 1e+300;
1281 the failures occur around 1e+27, and never above 1e+30. */
1284 fmt = udat_open(UDAT_LONG, UDAT_LONG, "en_US",
1286 if (U_FAILURE(ec)) {
1287 log_data_err("FAIL: udat_open (%s) (Are you missing data?)\n", u_errorName(ec));
1291 _aux2ExtremeDates(fmt, small, large, buf, UPRV_LENGTHOF(buf), cbuf, 0, &ec);
1296 static void TestAllLocales(void) {
1297 int32_t idx, dateIdx, timeIdx, localeCount;
1298 static const UDateFormatStyle style[] = {
1299 UDAT_FULL, UDAT_LONG, UDAT_MEDIUM, UDAT_SHORT
1301 localeCount = uloc_countAvailable();
1302 for (idx = 0; idx < localeCount; idx++) {
1303 for (dateIdx = 0; dateIdx < UPRV_LENGTHOF(style); dateIdx++) {
1304 for (timeIdx = 0; timeIdx < UPRV_LENGTHOF(style); timeIdx++) {
1305 UErrorCode status = U_ZERO_ERROR;
1306 udat_close(udat_open(style[dateIdx], style[timeIdx],
1307 uloc_getAvailable(idx), NULL, 0, NULL, 0, &status));
1308 if (U_FAILURE(status)) {
1309 log_err("FAIL: udat_open(%s) failed with (%s) dateIdx=%d, timeIdx=%d\n",
1310 uloc_getAvailable(idx), u_errorName(status), dateIdx, timeIdx);
1317 static void TestRelativeCrash(void) {
1318 static const UChar tzName[] = { 0x0055, 0x0053, 0x002F, 0x0050, 0x0061, 0x0063, 0x0069, 0x0066, 0x0069, 0x0063, 0 };
1319 static const UDate aDate = -631152000000.0;
1321 UErrorCode status = U_ZERO_ERROR;
1322 UErrorCode expectStatus = U_ILLEGAL_ARGUMENT_ERROR;
1325 icudf = udat_open(UDAT_NONE, UDAT_SHORT_RELATIVE, "en", tzName, -1, NULL, 0, &status);
1326 if ( U_SUCCESS(status) ) {
1327 const char *what = "???";
1329 UErrorCode subStatus = U_ZERO_ERROR;
1330 what = "udat_set2DigitYearStart";
1331 log_verbose("Trying %s on a relative date..\n", what);
1332 udat_set2DigitYearStart(icudf, aDate, &subStatus);
1333 if(subStatus == expectStatus) {
1334 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1336 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
1340 /* clone works polymorphically. try it anyways */
1341 UErrorCode subStatus = U_ZERO_ERROR;
1344 log_verbose("Trying %s on a relative date..\n", what);
1345 oth = udat_clone(icudf, &subStatus);
1346 if(subStatus == U_ZERO_ERROR) {
1347 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1348 udat_close(oth); /* ? */
1350 log_err("FAIL: didn't crash on %s, but got %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
1354 UErrorCode subStatus = U_ZERO_ERROR;
1355 what = "udat_get2DigitYearStart";
1356 log_verbose("Trying %s on a relative date..\n", what);
1357 udat_get2DigitYearStart(icudf, &subStatus);
1358 if(subStatus == expectStatus) {
1359 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1361 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
1365 /* Now udat_toPattern works for relative date formatters, unless localized is TRUE */
1366 UErrorCode subStatus = U_ZERO_ERROR;
1367 what = "udat_toPattern";
1368 log_verbose("Trying %s on a relative date..\n", what);
1369 udat_toPattern(icudf, TRUE,NULL,0, &subStatus);
1370 if(subStatus == expectStatus) {
1371 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1373 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
1377 UErrorCode subStatus = U_ZERO_ERROR;
1378 what = "udat_applyPattern";
1379 log_verbose("Trying %s on a relative date..\n", what);
1380 udat_applyPattern(icudf, FALSE,tzName,-1);
1381 subStatus = U_ILLEGAL_ARGUMENT_ERROR; /* what it should be, if this took an errorcode. */
1382 if(subStatus == expectStatus) {
1383 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1385 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
1390 UErrorCode subStatus = U_ZERO_ERROR;
1391 what = "udat_getSymbols";
1392 log_verbose("Trying %s on a relative date..\n", what);
1393 udat_getSymbols(icudf, UDAT_ERAS,0,erabuf,UPRV_LENGTHOF(erabuf), &subStatus);
1394 if(subStatus == U_ZERO_ERROR) {
1395 log_verbose("Success: %s returned %s.\n", what, u_errorName(subStatus));
1397 log_err("FAIL: didn't crash on %s, but got %s instead of U_ZERO_ERROR.\n", what, u_errorName(subStatus));
1401 UErrorCode subStatus = U_ZERO_ERROR;
1402 UChar symbolValue = 0x0041;
1403 what = "udat_setSymbols";
1404 log_verbose("Trying %s on a relative date..\n", what);
1405 udat_setSymbols(icudf, UDAT_ERAS,0,&symbolValue,1, &subStatus); /* bogus values */
1406 if(subStatus == expectStatus) {
1407 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1409 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
1413 UErrorCode subStatus = U_ZERO_ERROR;
1414 what = "udat_countSymbols";
1415 log_verbose("Trying %s on a relative date..\n", what);
1416 udat_countSymbols(icudf, UDAT_ERAS);
1417 subStatus = U_ILLEGAL_ARGUMENT_ERROR; /* should have an errorcode. */
1418 if(subStatus == expectStatus) {
1419 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1421 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
1427 log_data_err("FAIL: err calling udat_open() ->%s (Are you missing data?)\n", u_errorName(status));
1431 static const UChar skeleton_yMMMM[] = { 0x79,0x4D,0x4D,0x4D,0x4D,0 }; /* "yMMMM"; fr maps to "MMMM y", cs maps to "LLLL y" */
1432 static const UChar july2008_frDefault[] = { 0x6A,0x75,0x69,0x6C,0x6C,0x65,0x74,0x20,0x32,0x30,0x30,0x38,0 }; /* "juillet 2008" */
1433 static const UChar july2008_frTitle[] = { 0x4A,0x75,0x69,0x6C,0x6C,0x65,0x74,0x20,0x32,0x30,0x30,0x38,0 }; /* "Juillet 2008" sentence-begin, standalone */
1434 static const UChar july2008_csDefault[] = { 0x10D,0x65,0x72,0x76,0x65,0x6E,0x65,0x63,0x20,0x32,0x30,0x30,0x38,0 }; /* "c(hacek)ervenec 2008" */
1435 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 */
1438 const char * locale;
1439 const UChar * skeleton;
1440 UDisplayContext capitalizationContext;
1441 const UChar * expectedFormat;
1444 static const TestContextItem textContextItems[] = {
1445 { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_NONE, july2008_frDefault },
1446 #if !UCONFIG_NO_BREAK_ITERATION
1447 { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, july2008_frDefault },
1448 { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, july2008_frTitle },
1449 { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, july2008_frDefault },
1450 { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_STANDALONE, july2008_frTitle },
1452 { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_NONE, july2008_csDefault },
1453 #if !UCONFIG_NO_BREAK_ITERATION
1454 { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, july2008_csDefault },
1455 { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, july2008_csTitle },
1456 { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, july2008_csTitle },
1457 { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_STANDALONE, july2008_csDefault },
1459 { NULL, NULL, (UDisplayContext)0, NULL }
1462 static const UChar today_enDefault[] = { 0x74,0x6F,0x64,0x61,0x79,0 }; /* "today" */
1463 static const UChar today_enTitle[] = { 0x54,0x6F,0x64,0x61,0x79,0 }; /* "Today" sentence-begin, uiListOrMenu, standalone */
1464 static const UChar yesterday_enDefault[] = { 0x79,0x65,0x73,0x74,0x65,0x72,0x64,0x61,0x79,0 }; /* "yesterday" */
1465 static const UChar yesterday_enTitle[] = { 0x59,0x65,0x73,0x74,0x65,0x72,0x64,0x61,0x79,0 }; /* "Yesterday" sentence-begin, uiListOrMenu, standalone */
1466 static const UChar today_nbDefault[] = { 0x69,0x20,0x64,0x61,0x67,0 }; /* "i dag" */
1467 static const UChar today_nbTitle[] = { 0x49,0x20,0x64,0x61,0x67,0 }; /* "I dag" sentence-begin, standalone */
1468 static const UChar yesterday_nbDefault[] = { 0x69,0x20,0x67,0xE5,0x72,0 };
1469 static const UChar yesterday_nbTitle[] = { 0x49,0x20,0x67,0xE5,0x72,0 };
1472 const char * locale;
1473 UDisplayContext capitalizationContext;
1474 const UChar * expectedFormatToday;
1475 const UChar * expectedFormatYesterday;
1476 } TestRelativeContextItem;
1478 static const TestRelativeContextItem textContextRelativeItems[] = {
1479 { "en", UDISPCTX_CAPITALIZATION_NONE, today_enDefault, yesterday_enDefault },
1480 #if !UCONFIG_NO_BREAK_ITERATION
1481 { "en", UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, today_enDefault, yesterday_enDefault },
1482 { "en", UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, today_enTitle, yesterday_enTitle },
1483 { "en", UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, today_enTitle, yesterday_enTitle },
1484 { "en", UDISPCTX_CAPITALIZATION_FOR_STANDALONE, today_enTitle, yesterday_enTitle },
1486 { "nb", UDISPCTX_CAPITALIZATION_NONE, today_nbDefault, yesterday_nbDefault },
1487 #if !UCONFIG_NO_BREAK_ITERATION
1488 { "nb", UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, today_nbDefault, yesterday_nbDefault },
1489 { "nb", UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, today_nbTitle, yesterday_nbTitle },
1490 { "nb", UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, today_nbDefault, yesterday_nbDefault },
1491 { "nb", UDISPCTX_CAPITALIZATION_FOR_STANDALONE, today_nbTitle, yesterday_nbTitle },
1493 { NULL, (UDisplayContext)0, NULL, NULL }
1496 static const UChar zoneGMT[] = { 0x47,0x4D,0x54,0 }; /* "GMT" */
1497 static const UDate july022008 = 1215000000000.0;
1498 enum { kUbufMax = 64, kBbufMax = 3*kUbufMax };
1500 static void TestContext(void) {
1501 const TestContextItem* textContextItemPtr;
1502 const TestRelativeContextItem* textRelContextItemPtr;
1503 for (textContextItemPtr = textContextItems; textContextItemPtr->locale != NULL; ++textContextItemPtr) {
1504 UErrorCode status = U_ZERO_ERROR;
1505 UDateTimePatternGenerator* udtpg = udatpg_open(textContextItemPtr->locale, &status);
1506 if ( U_SUCCESS(status) ) {
1507 UChar ubuf[kUbufMax];
1508 int32_t len = udatpg_getBestPattern(udtpg, textContextItemPtr->skeleton, -1, ubuf, kUbufMax, &status);
1509 if ( U_SUCCESS(status) ) {
1510 UDateFormat* udfmt = udat_open(UDAT_PATTERN, UDAT_PATTERN, textContextItemPtr->locale, zoneGMT, -1, ubuf, len, &status);
1511 if ( U_SUCCESS(status) ) {
1512 udat_setContext(udfmt, textContextItemPtr->capitalizationContext, &status);
1513 if ( U_SUCCESS(status) ) {
1514 UDisplayContext getContext;
1515 len = udat_format(udfmt, july022008, ubuf, kUbufMax, NULL, &status);
1516 if ( U_FAILURE(status) ) {
1517 log_err("FAIL: udat_format for locale %s, capitalizationContext %d, status %s\n",
1518 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, u_errorName(status) );
1519 status = U_ZERO_ERROR;
1520 } else if (u_strncmp(ubuf, textContextItemPtr->expectedFormat, kUbufMax) != 0) {
1521 char bbuf1[kBbufMax];
1522 char bbuf2[kBbufMax];
1523 log_err("FAIL: udat_format for locale %s, capitalizationContext %d, expected %s, got %s\n",
1524 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext,
1525 u_austrncpy(bbuf1,textContextItemPtr->expectedFormat,kUbufMax), u_austrncpy(bbuf2,ubuf,kUbufMax) );
1527 getContext = udat_getContext(udfmt, UDISPCTX_TYPE_CAPITALIZATION, &status);
1528 if ( U_FAILURE(status) ) {
1529 log_err("FAIL: udat_getContext for locale %s, capitalizationContext %d, status %s\n",
1530 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, u_errorName(status) );
1531 } else if (getContext != textContextItemPtr->capitalizationContext) {
1532 log_err("FAIL: udat_getContext for locale %s, capitalizationContext %d, got context %d\n",
1533 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, (int)getContext );
1536 log_err("FAIL: udat_setContext for locale %s, capitalizationContext %d, status %s\n",
1537 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, u_errorName(status) );
1541 log_data_err("FAIL: udat_open for locale %s, status %s\n", textContextItemPtr->locale, u_errorName(status) );
1544 log_err("FAIL: udatpg_getBestPattern for locale %s, status %s\n", textContextItemPtr->locale, u_errorName(status) );
1546 udatpg_close(udtpg);
1548 log_data_err("FAIL: udatpg_open for locale %s, status %s\n", textContextItemPtr->locale, u_errorName(status) );
1551 for (textRelContextItemPtr = textContextRelativeItems; textRelContextItemPtr->locale != NULL; ++textRelContextItemPtr) {
1552 UErrorCode status = U_ZERO_ERROR;
1553 UCalendar* ucal = ucal_open(zoneGMT, -1, "root", UCAL_GREGORIAN, &status);
1554 if ( U_SUCCESS(status) ) {
1555 UDateFormat* udfmt = udat_open(UDAT_NONE, UDAT_LONG_RELATIVE, textRelContextItemPtr->locale, zoneGMT, -1, NULL, 0, &status);
1556 if ( U_SUCCESS(status) ) {
1557 udat_setContext(udfmt, textRelContextItemPtr->capitalizationContext, &status);
1558 if ( U_SUCCESS(status) ) {
1559 UDate yesterday, today = ucal_getNow();
1560 UChar ubuf[kUbufMax];
1561 char bbuf1[kBbufMax];
1562 char bbuf2[kBbufMax];
1563 int32_t len = udat_format(udfmt, today, ubuf, kUbufMax, NULL, &status);
1565 if ( U_FAILURE(status) ) {
1566 log_err("FAIL: udat_format today for locale %s, capitalizationContext %d, status %s\n",
1567 textRelContextItemPtr->locale, (int)textRelContextItemPtr->capitalizationContext, u_errorName(status) );
1568 } else if (u_strncmp(ubuf, textRelContextItemPtr->expectedFormatToday, kUbufMax) != 0) {
1569 log_err("FAIL: udat_format today for locale %s, capitalizationContext %d, expected %s, got %s\n",
1570 textRelContextItemPtr->locale, (int)textRelContextItemPtr->capitalizationContext,
1571 u_austrncpy(bbuf1,textRelContextItemPtr->expectedFormatToday,kUbufMax), u_austrncpy(bbuf2,ubuf,kUbufMax) );
1573 status = U_ZERO_ERROR;
1574 ucal_setMillis(ucal, today, &status);
1575 ucal_add(ucal, UCAL_DATE, -1, &status);
1576 yesterday = ucal_getMillis(ucal, &status);
1577 if ( U_SUCCESS(status) ) {
1578 len = udat_format(udfmt, yesterday, ubuf, kUbufMax, NULL, &status);
1579 if ( U_FAILURE(status) ) {
1580 log_err("FAIL: udat_format yesterday for locale %s, capitalizationContext %d, status %s\n",
1581 textRelContextItemPtr->locale, (int)textRelContextItemPtr->capitalizationContext, u_errorName(status) );
1582 } else if (u_strncmp(ubuf, textRelContextItemPtr->expectedFormatYesterday, kUbufMax) != 0) {
1583 log_err("FAIL: udat_format yesterday for locale %s, capitalizationContext %d, expected %s, got %s\n",
1584 textRelContextItemPtr->locale, (int)textRelContextItemPtr->capitalizationContext,
1585 u_austrncpy(bbuf1,textRelContextItemPtr->expectedFormatYesterday,kUbufMax), u_austrncpy(bbuf2,ubuf,kUbufMax) );
1589 log_err("FAIL: udat_setContext relative for locale %s, capitalizationContext %d, status %s\n",
1590 textRelContextItemPtr->locale, (int)textRelContextItemPtr->capitalizationContext, u_errorName(status) );
1594 log_data_err("FAIL: udat_open relative for locale %s, status %s\n", textRelContextItemPtr->locale, u_errorName(status) );
1598 log_data_err("FAIL: ucal_open for locale root, status %s\n", u_errorName(status) );
1604 // overrideNumberFormat[i][0] is to tell which field to set,
1605 // overrideNumberFormat[i][1] is the expected result
1606 static const char * overrideNumberFormat[][2] = {
1607 {"", "\\u521D\\u4E03 \\u521D\\u4E8C"},
1608 {"d", "07 \\u521D\\u4E8C"},
1609 {"do", "07 \\u521D\\u4E8C"},
1610 {"Md", "\\u521D\\u4E03 \\u521D\\u4E8C"},
1611 {"MdMMd", "\\u521D\\u4E03 \\u521D\\u4E8C"},
1612 {"mixed", "\\u521D\\u4E03 \\u521D\\u4E8C"}
1615 static void TestOverrideNumberFormat(void) {
1616 UErrorCode status = U_ZERO_ERROR;
1620 char bbuf1[kBbufMax];
1621 char bbuf2[kBbufMax];
1622 const char* localeString = "zh@numbers=hanidays";
1624 const UNumberFormat* getter_result;
1627 u_uastrcpy(fields, "d");
1628 u_uastrcpy(pattern,"MM d");
1630 fmt=udat_open(UDAT_PATTERN, UDAT_PATTERN, "en_US", zoneGMT, -1, pattern, u_strlen(pattern), &status);
1631 if (!assertSuccess("udat_open()", &status)) {
1635 // loop 5 times to check getter/setter
1636 for (i = 0; i < 5; i++){
1637 UNumberFormat* overrideFmt;
1638 overrideFmt = unum_open(UNUM_DEFAULT, NULL, 0, localeString, NULL, &status);
1639 assertSuccess("unum_open()", &status);
1640 udat_adoptNumberFormatForFields(fmt, fields, overrideFmt, &status);
1641 overrideFmt = NULL; // no longer valid
1642 assertSuccess("udat_setNumberFormatForField()", &status);
1644 getter_result = udat_getNumberFormatForField(fmt, 0x0064 /*'d'*/);
1645 if(getter_result == NULL) {
1646 log_err("FAIL: udat_getNumberFormatForField did not return a valid pointer\n");
1650 UNumberFormat* overrideFmt;
1651 overrideFmt = unum_open(UNUM_DEFAULT, NULL, 0, localeString, NULL, &status);
1652 assertSuccess("unum_open()", &status);
1653 udat_setNumberFormat(fmt, overrideFmt); // test the same override NF will not crash
1654 unum_close(overrideFmt);
1658 for (i=0; i<UPRV_LENGTHOF(overrideNumberFormat); i++){
1659 UChar ubuf[kUbufMax];
1661 UNumberFormat* overrideFmt2;
1663 fmt2 =udat_open(UDAT_PATTERN, UDAT_PATTERN,"en_US", zoneGMT, -1, pattern, u_strlen(pattern), &status);
1664 assertSuccess("udat_open() with en_US", &status);
1666 overrideFmt2 = unum_open(UNUM_DEFAULT, NULL, 0, localeString, NULL, &status);
1667 assertSuccess("unum_open() in loop", &status);
1669 u_uastrcpy(fields, overrideNumberFormat[i][0]);
1670 u_unescape(overrideNumberFormat[i][1], expected, UPRV_LENGTHOF(expected));
1672 if ( strcmp(overrideNumberFormat[i][0], "") == 0 ) { // use the one w/o field
1673 udat_adoptNumberFormat(fmt2, overrideFmt2);
1674 } else if ( strcmp(overrideNumberFormat[i][0], "mixed") == 0 ) { // set 1 field at first but then full override, both(M & d) should be override
1675 const char* singleLocale = "en@numbers=hebr";
1676 UNumberFormat* singleOverrideFmt;
1677 u_uastrcpy(fields, "d");
1679 singleOverrideFmt = unum_open(UNUM_DEFAULT, NULL, 0, singleLocale, NULL, &status);
1680 assertSuccess("unum_open() in mixed", &status);
1682 udat_adoptNumberFormatForFields(fmt2, fields, singleOverrideFmt, &status);
1683 assertSuccess("udat_setNumberFormatForField() in mixed", &status);
1685 udat_adoptNumberFormat(fmt2, overrideFmt2);
1686 } else if ( strcmp(overrideNumberFormat[i][0], "do") == 0 ) { // o is an invalid field
1687 udat_adoptNumberFormatForFields(fmt2, fields, overrideFmt2, &status);
1688 if(status == U_INVALID_FORMAT_ERROR) {
1690 status = U_ZERO_ERROR;
1694 udat_adoptNumberFormatForFields(fmt2, fields, overrideFmt2, &status);
1695 assertSuccess("udat_setNumberFormatForField() in loop", &status);
1698 udat_format(fmt2, july022008, ubuf, kUbufMax, NULL, &status);
1699 assertSuccess("udat_format() july022008", &status);
1701 if (u_strncmp(ubuf, expected, kUbufMax) != 0)
1702 log_err("fail: udat_format for locale, expected %s, got %s\n",
1703 u_austrncpy(bbuf1,expected,kUbufMax), u_austrncpy(bbuf2,ubuf,kUbufMax) );
1711 * udat_parse and udat_parseCalendar should have the same error code when given the same invalid input.
1713 static void TestParseErrorReturnValue(void) {
1714 UErrorCode status = U_ZERO_ERROR;
1715 UErrorCode expectStatus = U_PARSE_ERROR;
1719 df = udat_open(UDAT_DEFAULT, UDAT_DEFAULT, NULL, NULL, -1, NULL, -1, &status);
1720 if (!assertSuccessCheck("udat_open()", &status, TRUE)) {
1724 cal = ucal_open(NULL, 0, "en_US", UCAL_GREGORIAN, &status);
1725 if (!assertSuccess("ucal_open()", &status)) {
1729 udat_parse(df, NULL, -1, NULL, &status);
1730 if (status != expectStatus) {
1731 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));
1734 status = U_ZERO_ERROR;
1735 udat_parseCalendar(df, cal, NULL, -1, NULL, &status);
1736 if (status != expectStatus) {
1737 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));
1746 * Test new udat_formatForFields, udat_formatCalendarForFields (and UFieldPositionIterator)
1748 static const char localeForFields[] = "en_US";
1749 /* zoneGMT[]defined above */
1750 static const UDate date2015Feb25 = 1424841000000.0; /* Wednesday, February 25, 2015 at 5:10:00 AM GMT */
1751 static const UChar patNoFields[] = { 0x0027, 0x0078, 0x0078, 0x0078, 0x0027, 0 }; /* "'xxx'" */
1758 static const FieldsData expectedFields[] = {
1759 { UDAT_DAY_OF_WEEK_FIELD /* 9*/, 0, 9 },
1760 { UDAT_MONTH_FIELD /* 2*/, 11, 19 },
1761 { UDAT_DATE_FIELD /* 3*/, 20, 22 },
1762 { UDAT_YEAR_FIELD /* 1*/, 24, 28 },
1763 { UDAT_HOUR1_FIELD /*15*/, 32, 33 },
1764 #if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
1765 { UDAT_TIME_SEPARATOR_FIELD /*35*/, 33, 34 },
1767 { UDAT_MINUTE_FIELD /* 6*/, 34, 36 },
1768 #if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
1769 { UDAT_TIME_SEPARATOR_FIELD /*35*/, 36, 37 },
1771 { UDAT_SECOND_FIELD /* 7*/, 37, 39 },
1772 { UDAT_AM_PM_FIELD /*14*/, 40, 42 },
1773 { UDAT_TIMEZONE_FIELD /*17*/, 43, 46 },
1777 enum {kUBufFieldsLen = 128, kBBufFieldsLen = 256 };
1779 static void TestFormatForFields(void) {
1780 UErrorCode status = U_ZERO_ERROR;
1781 UFieldPositionIterator* fpositer = ufieldpositer_open(&status);
1782 if ( U_FAILURE(status) ) {
1783 log_err("ufieldpositer_open fails, status %s\n", u_errorName(status));
1785 UDateFormat* udfmt = udat_open(UDAT_LONG, UDAT_FULL, localeForFields, zoneGMT, -1, NULL, 0, &status);
1786 UCalendar* ucal = ucal_open(zoneGMT, -1, localeForFields, UCAL_DEFAULT, &status);
1787 if ( U_FAILURE(status) ) {
1788 log_data_err("udat_open or ucal_open fails for locale %s, status %s (Are you missing data?)\n", localeForFields, u_errorName(status));
1790 int32_t ulen, field, beginPos, endPos;
1791 UChar ubuf[kUBufFieldsLen];
1792 const FieldsData * fptr;
1794 status = U_ZERO_ERROR;
1795 ulen = udat_formatForFields(udfmt, date2015Feb25, ubuf, kUBufFieldsLen, fpositer, &status);
1796 if ( U_FAILURE(status) ) {
1797 log_err("udat_formatForFields fails, status %s\n", u_errorName(status));
1799 for (fptr = expectedFields; ; fptr++) {
1800 field = ufieldpositer_next(fpositer, &beginPos, &endPos);
1801 if (field != fptr->field || (field >= 0 && (beginPos != fptr->beginPos || endPos != fptr->endPos))) {
1802 if (fptr->field >= 0) {
1803 log_err("udat_formatForFields as \"%s\"; expect field %d range %d-%d, get field %d range %d-%d\n",
1804 aescstrdup(ubuf, ulen), fptr->field, fptr->beginPos, fptr->endPos, field, beginPos, endPos);
1806 log_err("udat_formatForFields as \"%s\"; expect field < 0, get field %d range %d-%d\n",
1807 aescstrdup(ubuf, ulen), field, beginPos, endPos);
1817 ucal_setMillis(ucal, date2015Feb25, &status);
1818 status = U_ZERO_ERROR;
1819 ulen = udat_formatCalendarForFields(udfmt, ucal, ubuf, kUBufFieldsLen, fpositer, &status);
1820 if ( U_FAILURE(status) ) {
1821 log_err("udat_formatCalendarForFields fails, status %s\n", u_errorName(status));
1823 for (fptr = expectedFields; ; fptr++) {
1824 field = ufieldpositer_next(fpositer, &beginPos, &endPos);
1825 if (field != fptr->field || (field >= 0 && (beginPos != fptr->beginPos || endPos != fptr->endPos))) {
1826 if (fptr->field >= 0) {
1827 log_err("udat_formatFudat_formatCalendarForFieldsorFields as \"%s\"; expect field %d range %d-%d, get field %d range %d-%d\n",
1828 aescstrdup(ubuf, ulen), fptr->field, fptr->beginPos, fptr->endPos, field, beginPos, endPos);
1830 log_err("udat_formatCalendarForFields as \"%s\"; expect field < 0, get field %d range %d-%d\n",
1831 aescstrdup(ubuf, ulen), field, beginPos, endPos);
1841 udat_applyPattern(udfmt, FALSE, patNoFields, -1);
1842 status = U_ZERO_ERROR;
1843 ulen = udat_formatForFields(udfmt, date2015Feb25, ubuf, kUBufFieldsLen, fpositer, &status);
1844 if ( U_FAILURE(status) ) {
1845 log_err("udat_formatForFields with no-field pattern fails, status %s\n", u_errorName(status));
1847 field = ufieldpositer_next(fpositer, &beginPos, &endPos);
1849 log_err("udat_formatForFields with no-field pattern as \"%s\"; expect field < 0, get field %d range %d-%d\n",
1850 aescstrdup(ubuf, ulen), field, beginPos, endPos);
1857 ufieldpositer_close(fpositer);
1861 #endif /* #if !UCONFIG_NO_FORMATTING */