1 /********************************************************************
3 * Copyright (c) 1997-2016, 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"
36 static void TestExtremeDates(void);
37 static void TestAllLocales(void);
38 static void TestRelativeCrash(void);
39 static void TestContext(void);
40 static void TestCalendarDateParse(void);
41 static void TestParseErrorReturnValue(void);
42 static void TestFormatForFields(void);
44 void addDateForTest(TestNode** root);
46 #define TESTCASE(x) addTest(root, &x, "tsformat/cdattst/" #x)
48 void addDateForTest(TestNode** root)
50 TESTCASE(TestDateFormat);
51 TESTCASE(TestRelativeDateFormat);
52 TESTCASE(TestSymbols);
53 TESTCASE(TestDateFormatCalendar);
54 TESTCASE(TestExtremeDates);
55 TESTCASE(TestAllLocales);
56 TESTCASE(TestRelativeCrash);
57 TESTCASE(TestContext);
58 TESTCASE(TestCalendarDateParse);
59 TESTCASE(TestOverrideNumberFormat);
60 TESTCASE(TestParseErrorReturnValue);
61 TESTCASE(TestFormatForFields);
63 /* Testing the DateFormat API */
64 static void TestDateFormat()
66 UDateFormat *def, *fr, *it, *de, *def1, *fr_pat;
69 UErrorCode status = U_ZERO_ERROR;
72 const UNumberFormat *numformat1, *numformat2;
73 UNumberFormat *adoptNF;
79 int32_t resultlengthneeded;
81 UDate d = 837039928046.0;
82 double num = -10456.37;
83 /*const char* str="yyyy.MM.dd G 'at' hh:mm:ss z";
84 const char t[]="2/3/76 2:50 AM";*/
85 /*Testing udat_open() to open a dateformat */
87 ctest_setTimeZone(NULL, &status);
89 log_verbose("\nTesting udat_open() with various parameters\n");
90 fr = udat_open(UDAT_FULL, UDAT_DEFAULT, "fr_FR", NULL,0, NULL, 0,&status);
93 log_data_err("FAIL: error in creating the dateformat using full time style with french locale -> %s (Are you missing data?)\n",
94 myErrorName(status) );
97 /* this is supposed to open default date format, but later on it treats it like it is "en_US"
98 - very bad if you try to run the tests on machine where default locale is NOT "en_US" */
99 /* def = udat_open(UDAT_SHORT, UDAT_SHORT, NULL, NULL, 0, &status); */
100 def = udat_open(UDAT_SHORT, UDAT_SHORT, "en_US", NULL, 0,NULL, 0, &status);
101 if(U_FAILURE(status))
103 log_err("FAIL: error in creating the dateformat using short date and time style\n %s\n",
104 myErrorName(status) );
107 it = udat_open(UDAT_DEFAULT, UDAT_MEDIUM, "it_IT", NULL, 0, NULL, 0,&status);
108 if(U_FAILURE(status))
110 log_err("FAIL: error in creating the dateformat using medium date style with italian locale\n %s\n",
111 myErrorName(status) );
114 de = udat_open(UDAT_LONG, UDAT_LONG, "de_DE", NULL, 0, NULL, 0,&status);
115 if(U_FAILURE(status))
117 log_err("FAIL: error in creating the dateformat using long time and date styles with german locale\n %s\n",
118 myErrorName(status));
121 /*creating a default dateformat */
122 def1 = udat_open(UDAT_SHORT, UDAT_SHORT, NULL, NULL, 0,NULL, 0, &status);
123 if(U_FAILURE(status))
125 log_err("FAIL: error in creating the dateformat using short date and time style\n %s\n",
126 myErrorName(status) );
131 /*Testing udat_getAvailable() and udat_countAvailable()*/
132 log_verbose("\nTesting getAvailableLocales and countAvailable()\n");
133 numlocales=udat_countAvailable();
134 /* use something sensible w/o hardcoding the count */
136 log_data_err("FAIL: error in countAvailable\n");
137 log_verbose("The number of locales for which date/time formatting patterns are available is %d\n", numlocales);
139 for(i=0;i<numlocales;i++) {
140 UErrorCode subStatus = U_ZERO_ERROR;
141 log_verbose("Testing open of %s\n", udat_getAvailable(i));
142 any = udat_open(UDAT_SHORT, UDAT_SHORT, udat_getAvailable(i), NULL ,0, NULL, 0, &subStatus);
143 if(U_FAILURE(subStatus)) {
144 log_data_err("FAIL: date format %s (getAvailable(%d)) is not instantiable: %s\n", udat_getAvailable(i), i, u_errorName(subStatus));
149 /*Testing udat_clone()*/
150 log_verbose("\nTesting the udat_clone() function of date format\n");
151 copy=udat_clone(def, &status);
152 if(U_FAILURE(status)){
153 log_err("Error in creating the clone using udat_clone: %s\n", myErrorName(status) );
156 log_err("Error in udat_clone");*/ /*how should i check for equality???? */
158 /*Testing udat_format()*/
159 log_verbose("\nTesting the udat_format() function of date format\n");
160 u_uastrcpy(temp, "7/10/96, 4:05 PM");
161 /*format using def */
163 resultlengthneeded=udat_format(def, d, NULL, resultlength, NULL, &status);
164 if(status==U_BUFFER_OVERFLOW_ERROR)
167 resultlength=resultlengthneeded+1;
172 result=(UChar*)malloc(sizeof(UChar) * resultlength);
173 udat_format(def, d, result, resultlength, NULL, &status);
175 if(U_FAILURE(status) || !result)
177 log_err("FAIL: Error in formatting using udat_format(.....) %s\n", myErrorName(status) );
181 log_verbose("PASS: formatting successful\n");
182 if(u_strcmp(result, temp)==0)
183 log_verbose("PASS: Date Format for US locale successful using udat_format()\n");
187 u_austrcpy(xbuf, temp);
188 u_austrcpy(gbuf, result);
189 log_err("FAIL: Date Format for US locale failed using udat_format() - expected %s got %s\n", xbuf, gbuf);
193 u_unescape("10 juil. 1996 \\u00E0 16:05:28 heure d\\u2019\\u00E9t\\u00E9 du Pacifique", temp, 50);
198 result=myDateFormat(fr, d);
199 if(u_strcmp(result, temp)==0)
200 log_verbose("PASS: Date Format for french locale successful using udat_format()\n");
202 log_data_err("FAIL: Date Format for french locale failed using udat_format().\n" );
205 u_uastrcpy(temp, "10 lug 1996, 16:05:28");
212 fmtted = myDateFormat(it,d);
213 u_austrcpy(g, fmtted);
215 if(u_strcmp(fmtted, temp)==0) {
216 log_verbose("PASS: Date Format for italian locale successful uisng udat_format() - wanted %s, got %s\n", x, g);
218 log_data_err("FAIL: Date Format for italian locale failed using udat_format() - wanted %s, got %s\n", x, g);
222 /*Testing parsing using udat_parse()*/
223 log_verbose("\nTesting parsing using udat_parse()\n");
224 u_uastrcpy(temp,"2/3/76, 2:50 AM");
228 d1=udat_parse(def, temp, u_strlen(temp), &parsepos, &status);
229 if(U_FAILURE(status))
231 log_err("FAIL: Error in parsing using udat_parse(.....) %s\n", myErrorName(status) );
234 log_verbose("PASS: parsing succesful\n");
235 /*format it back and check for equality */
238 if(u_strcmp(myDateFormat(def, d1),temp)!=0)
239 log_err("FAIL: error in parsing\n");
241 /*Testing parsing using udat_parse()*/
242 log_verbose("\nTesting parsing using udat_parse()\n");
243 u_uastrcpy(temp,"2/Don't parse this part");
246 d1=udat_parse(def, temp, u_strlen(temp), NULL, &status);
247 if(status != U_PARSE_ERROR)
249 log_err("FAIL: udat_parse(\"bad string\") passed when it should have failed\n");
252 log_verbose("PASS: parsing succesful\n");
256 /*Testing udat_openPattern() */
258 log_verbose("\nTesting the udat_openPattern with a specified pattern\n");
259 /*for french locale */
260 fr_pat=udat_open(UDAT_PATTERN, UDAT_PATTERN,"fr_FR",NULL,0,temp, u_strlen(temp), &status);
261 if(U_FAILURE(status))
263 log_err("FAIL: Error in creating a date format using udat_openPattern \n %s\n",
264 myErrorName(status) );
267 log_verbose("PASS: creating dateformat using udat_openPattern() succesful\n");
270 /*Testing applyPattern and toPattern */
271 log_verbose("\nTesting applyPattern and toPattern()\n");
272 udat_applyPattern(def1, FALSE, temp, u_strlen(temp));
273 log_verbose("Extracting the pattern\n");
276 resultlengthneeded=udat_toPattern(def1, FALSE, NULL, resultlength, &status);
277 if(status==U_BUFFER_OVERFLOW_ERROR)
280 resultlength=resultlengthneeded + 1;
281 result=(UChar*)malloc(sizeof(UChar) * resultlength);
282 udat_toPattern(def1, FALSE, result, resultlength, &status);
284 if(U_FAILURE(status))
286 log_err("FAIL: error in extracting the pattern from UNumberFormat\n %s\n",
287 myErrorName(status) );
289 if(u_strcmp(result, temp)!=0)
290 log_err("FAIL: Error in extracting the pattern\n");
292 log_verbose("PASS: applyPattern and toPattern work fine\n");
300 /*Testing getter and setter functions*/
301 /*isLenient and setLenient()*/
302 log_verbose("\nTesting the isLenient and setLenient properties\n");
303 udat_setLenient(fr, udat_isLenient(it));
304 if(udat_isLenient(fr) != udat_isLenient(it))
305 log_err("ERROR: setLenient() failed\n");
307 log_verbose("PASS: setLenient() successful\n");
310 /*Test get2DigitYearStart set2DigitYearStart */
311 log_verbose("\nTesting the get and set 2DigitYearStart properties\n");
312 d1= udat_get2DigitYearStart(fr_pat,&status);
313 if(U_FAILURE(status)) {
314 log_err("ERROR: udat_get2DigitYearStart failed %s\n", myErrorName(status) );
316 status = U_ZERO_ERROR;
317 udat_set2DigitYearStart(def1 ,d1, &status);
318 if(U_FAILURE(status)) {
319 log_err("ERROR: udat_set2DigitYearStart failed %s\n", myErrorName(status) );
321 if(udat_get2DigitYearStart(fr_pat, &status) != udat_get2DigitYearStart(def1, &status))
322 log_err("FAIL: error in set2DigitYearStart\n");
324 log_verbose("PASS: set2DigitYearStart successful\n");
325 /*try setting it to another value */
326 udat_set2DigitYearStart(de, 2000.0, &status);
327 if(U_FAILURE(status)){
328 log_verbose("ERROR: udat_set2DigitYearStart failed %s\n", myErrorName(status) );
330 if(udat_get2DigitYearStart(de, &status) != 2000)
331 log_err("FAIL: error in set2DigitYearStart\n");
333 log_verbose("PASS: set2DigitYearStart successful\n");
337 /*Test getNumberFormat() and setNumberFormat() */
338 log_verbose("\nTesting the get and set NumberFormat properties of date format\n");
339 numformat1=udat_getNumberFormat(fr_pat);
340 udat_setNumberFormat(def1, numformat1);
341 numformat2=udat_getNumberFormat(def1);
342 if(u_strcmp(myNumformat(numformat1, num), myNumformat(numformat2, num)) !=0)
343 log_err("FAIL: error in setNumberFormat or getNumberFormat()\n");
345 log_verbose("PASS:setNumberFormat and getNumberFormat succesful\n");
347 /*Test getNumberFormat() and adoptNumberFormat() */
348 log_verbose("\nTesting the get and adopt NumberFormat properties of date format\n");
349 adoptNF= unum_open(UNUM_DEFAULT, NULL, 0, NULL, NULL, &status);
350 udat_adoptNumberFormat(def1, adoptNF);
351 numformat2=udat_getNumberFormat(def1);
352 if(u_strcmp(myNumformat(adoptNF, num), myNumformat(numformat2, num)) !=0)
353 log_err("FAIL: error in adoptNumberFormat or getNumberFormat()\n");
355 log_verbose("PASS:adoptNumberFormat and getNumberFormat succesful\n");
357 /*try setting the number format to another format */
358 numformat1=udat_getNumberFormat(def);
359 udat_setNumberFormat(def1, numformat1);
360 numformat2=udat_getNumberFormat(def1);
361 if(u_strcmp(myNumformat(numformat1, num), myNumformat(numformat2, num)) !=0)
362 log_err("FAIL: error in setNumberFormat or getNumberFormat()\n");
364 log_verbose("PASS: setNumberFormat and getNumberFormat succesful\n");
368 /*Test getCalendar and setCalendar*/
369 log_verbose("\nTesting the udat_getCalendar() and udat_setCalendar() properties\n");
370 cal=udat_getCalendar(fr_pat);
373 udat_setCalendar(def1, cal);
374 if(!ucal_equivalentTo(udat_getCalendar(fr_pat), udat_getCalendar(def1)))
375 log_err("FAIL: Error in setting and getting the calendar\n");
377 log_verbose("PASS: getting and setting calendar successful\n");
383 /*Closing the UDateForamt */
392 ctest_resetTimeZone();
396 Test combined relative date formatting (relative date + non-relative time).
397 This is a bit tricky since we can't have static test data for comparison, the
398 relative date formatting is relative to the time the tests are run. We generate
399 the data for comparison dynamically. However, the tests could fail if they are
400 run right at midnight Pacific time and the call to ucal_getNow() is before midnight
401 while the calls to udat_format are after midnight or span midnight.
403 static const UDate dayInterval = 24.0*60.0*60.0*1000.0;
404 static const UChar trdfZone[] = { 0x0055, 0x0053, 0x002F, 0x0050, 0x0061, 0x0063, 0x0069, 0x0066, 0x0069, 0x0063, 0 }; /* US/Pacific */
405 static const char trdfLocale[] = "en_US";
406 static const UChar minutesPatn[] = { 0x006D, 0x006D, 0 }; /* "mm" */
407 static const UChar monthLongPatn[] = { 0x004D, 0x004D, 0x004D, 0x004D, 0 }; /* "MMMM" */
408 static const UChar monthMediumPatn[] = { 0x004D, 0x004D, 0x004D, 0 }; /* "MMM" */
409 static const UChar monthShortPatn[] = { 0x004D, 0 }; /* "M" */
410 static const UDateFormatStyle dateStylesList[] = { UDAT_FULL, UDAT_LONG, UDAT_MEDIUM, UDAT_SHORT, UDAT_NONE };
411 static const UChar *monthPatnsList[] = { monthLongPatn, monthLongPatn, monthMediumPatn, monthShortPatn, NULL };
412 static const UChar newTimePatn[] = { 0x0048, 0x0048, 0x002C, 0x006D, 0x006D, 0 }; /* "HH,mm" */
413 static const UChar minutesStr[] = { 0x0034, 0x0039, 0 }; /* "49", minutes string to search for in output */
414 enum { kDateOrTimeOutMax = 96, kDateAndTimeOutMax = 192 };
416 static const UDate minutesTolerance = 2 * 60.0 * 1000.0;
417 static const UDate daysTolerance = 2 * 24.0 * 60.0 * 60.0 * 1000.0;
419 static void TestRelativeDateFormat()
422 const UDateFormatStyle * stylePtr;
423 const UChar ** monthPtnPtr;
424 UErrorCode status = U_ZERO_ERROR;
425 UCalendar * ucal = ucal_open(trdfZone, -1, trdfLocale, UCAL_GREGORIAN, &status);
426 if ( U_SUCCESS(status) ) {
427 int32_t year, month, day;
428 ucal_setMillis(ucal, ucal_getNow(), &status);
429 year = ucal_get(ucal, UCAL_YEAR, &status);
430 month = ucal_get(ucal, UCAL_MONTH, &status);
431 day = ucal_get(ucal, UCAL_DATE, &status);
432 ucal_setDateTime(ucal, year, month, day, 18, 49, 0, &status); /* set to today at 18:49:00 */
433 today = ucal_getMillis(ucal, &status);
436 if ( U_FAILURE(status) || today == 0.0 ) {
437 log_data_err("Generate UDate for a specified time today fails, error %s - (Are you missing data?)\n", myErrorName(status) );
440 for (stylePtr = dateStylesList, monthPtnPtr = monthPatnsList; *stylePtr != UDAT_NONE; ++stylePtr, ++monthPtnPtr) {
441 UDateFormat* fmtRelDateTime;
442 UDateFormat* fmtRelDate;
443 UDateFormat* fmtTime;
444 int32_t dayOffset, limit;
446 UChar strDateTime[kDateAndTimeOutMax];
447 UChar strDate[kDateOrTimeOutMax];
448 UChar strTime[kDateOrTimeOutMax];
452 fmtRelDateTime = udat_open(UDAT_SHORT, *stylePtr | UDAT_RELATIVE, trdfLocale, trdfZone, -1, NULL, 0, &status);
453 if ( U_FAILURE(status) ) {
454 log_data_err("udat_open timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s (Are you missing data?)\n", *stylePtr, myErrorName(status) );
457 fmtRelDate = udat_open(UDAT_NONE, *stylePtr | UDAT_RELATIVE, trdfLocale, trdfZone, -1, NULL, 0, &status);
458 if ( U_FAILURE(status) ) {
459 log_err("udat_open timeStyle NONE dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
460 udat_close(fmtRelDateTime);
463 fmtTime = udat_open(UDAT_SHORT, UDAT_NONE, trdfLocale, trdfZone, -1, NULL, 0, &status);
464 if ( U_FAILURE(status) ) {
465 log_err("udat_open timeStyle SHORT dateStyle NONE fails, error %s\n", myErrorName(status) );
466 udat_close(fmtRelDateTime);
467 udat_close(fmtRelDate);
471 dtpatLen = udat_toPatternRelativeDate(fmtRelDateTime, strDate, kDateAndTimeOutMax, &status);
472 if ( U_FAILURE(status) ) {
473 log_err("udat_toPatternRelativeDate timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
474 status = U_ZERO_ERROR;
475 } else if ( u_strstr(strDate, *monthPtnPtr) == NULL || dtpatLen != u_strlen(strDate) ) {
476 log_err("udat_toPatternRelativeDate timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) date pattern incorrect\n", *stylePtr );
478 dtpatLen = udat_toPatternRelativeTime(fmtRelDateTime, strTime, kDateAndTimeOutMax, &status);
479 if ( U_FAILURE(status) ) {
480 log_err("udat_toPatternRelativeTime timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
481 status = U_ZERO_ERROR;
482 } else if ( u_strstr(strTime, minutesPatn) == NULL || dtpatLen != u_strlen(strTime) ) {
483 log_err("udat_toPatternRelativeTime timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) time pattern incorrect\n", *stylePtr );
485 dtpatLen = udat_toPattern(fmtRelDateTime, FALSE, strDateTime, kDateAndTimeOutMax, &status);
486 if ( U_FAILURE(status) ) {
487 log_err("udat_toPattern timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
488 status = U_ZERO_ERROR;
489 } else if ( u_strstr(strDateTime, strDate) == NULL || u_strstr(strDateTime, strTime) == NULL || dtpatLen != u_strlen(strDateTime) ) {
490 log_err("udat_toPattern timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) dateTime pattern incorrect\n", *stylePtr );
492 udat_applyPatternRelative(fmtRelDateTime, strDate, u_strlen(strDate), newTimePatn, u_strlen(newTimePatn), &status);
493 if ( U_FAILURE(status) ) {
494 log_err("udat_applyPatternRelative timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
495 status = U_ZERO_ERROR;
497 udat_toPattern(fmtRelDateTime, FALSE, strDateTime, kDateAndTimeOutMax, &status);
498 if ( U_FAILURE(status) ) {
499 log_err("udat_toPattern timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
500 status = U_ZERO_ERROR;
501 } else if ( u_strstr(strDateTime, newTimePatn) == NULL ) {
502 log_err("udat_applyPatternRelative timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) didn't update time pattern\n", *stylePtr );
505 udat_applyPatternRelative(fmtRelDateTime, strDate, u_strlen(strDate), strTime, u_strlen(strTime), &status); /* restore original */
507 fp.field = UDAT_MINUTE_FIELD;
508 for (dayOffset = -2, limit = 2; dayOffset <= limit; ++dayOffset) {
509 UDate dateToUse = today + (float)dayOffset*dayInterval;
511 udat_format(fmtRelDateTime, dateToUse, strDateTime, kDateAndTimeOutMax, &fp, &status);
512 if ( U_FAILURE(status) ) {
513 log_err("udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
514 status = U_ZERO_ERROR;
516 int32_t parsePos = 0;
517 UDate dateResult = udat_parse(fmtRelDateTime, strDateTime, -1, &parsePos, &status);
518 UDate dateDiff = (dateResult >= dateToUse)? dateResult - dateToUse: dateToUse - dateResult;
519 if ( U_FAILURE(status) || dateDiff > minutesTolerance ) {
520 log_err("udat_parse timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s, expect approx %.1f, got %.1f, parsePos %d\n",
521 *stylePtr, myErrorName(status), dateToUse, dateResult, parsePos );
522 status = U_ZERO_ERROR;
525 udat_format(fmtRelDate, dateToUse, strDate, kDateOrTimeOutMax, NULL, &status);
526 if ( U_FAILURE(status) ) {
527 log_err("udat_format timeStyle NONE dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
528 status = U_ZERO_ERROR;
529 } else if ( u_strstr(strDateTime, strDate) == NULL ) {
530 log_err("relative date string not found in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", *stylePtr );
533 dateResult = udat_parse(fmtRelDate, strDate, -1, &parsePos, &status);
534 dateDiff = (dateResult >= dateToUse)? dateResult - dateToUse: dateToUse - dateResult;
535 if ( U_FAILURE(status) || dateDiff > daysTolerance ) {
536 log_err("udat_parse timeStyle NONE dateStyle (%d | UDAT_RELATIVE) fails, error %s, expect approx %.1f, got %.1f, parsePos %d\n",
537 *stylePtr, myErrorName(status), dateToUse, dateResult, parsePos );
538 status = U_ZERO_ERROR;
542 udat_format(fmtTime, dateToUse, strTime, kDateOrTimeOutMax, NULL, &status);
543 if ( U_FAILURE(status) ) {
544 log_err("udat_format timeStyle SHORT dateStyle NONE fails, error %s\n", myErrorName(status) );
545 status = U_ZERO_ERROR;
546 } else if ( u_strstr(strDateTime, strTime) == NULL ) {
547 log_err("time string not found in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", *stylePtr );
550 strPtr = u_strstr(strDateTime, minutesStr);
551 if ( strPtr != NULL ) {
552 int32_t beginIndex = strPtr - strDateTime;
553 if ( fp.beginIndex != beginIndex ) {
554 log_err("UFieldPosition beginIndex %d, expected %d, in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", fp.beginIndex, beginIndex, *stylePtr );
557 log_err("minutes string not found in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", *stylePtr );
562 udat_close(fmtRelDateTime);
563 udat_close(fmtRelDate);
568 /*Testing udat_getSymbols() and udat_setSymbols() and udat_countSymbols()*/
569 static void TestSymbols()
571 UDateFormat *def, *fr, *zhChiCal;
572 UErrorCode status = U_ZERO_ERROR;
574 UChar *result = NULL;
575 int32_t resultlength;
576 int32_t resultlengthout;
580 /*creating a dateformat with french locale */
581 log_verbose("\ncreating a date format with french locale\n");
582 fr = udat_open(UDAT_FULL, UDAT_DEFAULT, "fr_FR", NULL, 0, NULL, 0, &status);
583 if(U_FAILURE(status))
585 log_data_err("error in creating the dateformat using full time style with french locale -> %s (Are you missing data?)\n",
586 myErrorName(status) );
589 /*creating a default dateformat */
590 log_verbose("\ncreating a date format with default locale\n");
591 /* this is supposed to open default date format, but later on it treats it like it is "en_US"
592 - very bad if you try to run the tests on machine where default locale is NOT "en_US" */
593 /* def = udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,NULL, NULL, 0, &status); */
594 def = udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,"en_US", NULL, 0, NULL, 0, &status);
595 if(U_FAILURE(status))
597 log_err("error in creating the dateformat using short date and time style\n %s\n",
598 myErrorName(status) );
601 /*creating a dateformat with zh locale */
602 log_verbose("\ncreating a date format with zh locale for chinese calendar\n");
603 zhChiCal = udat_open(UDAT_NONE, UDAT_FULL, "zh@calendar=chinese", NULL, 0, NULL, 0, &status);
604 if(U_FAILURE(status))
606 log_data_err("error in creating the dateformat using full date, no time, locale zh@calendar=chinese -> %s (Are you missing data?)\n",
607 myErrorName(status) );
612 /*Testing countSymbols, getSymbols and setSymbols*/
613 log_verbose("\nTesting countSymbols\n");
614 /*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 */
615 if(udat_countSymbols(def, UDAT_ERAS)!=2 || udat_countSymbols(def, UDAT_MONTHS)!=12 ||
616 udat_countSymbols(def, UDAT_SHORT_MONTHS)!=12 || udat_countSymbols(def, UDAT_WEEKDAYS)!=8 ||
617 udat_countSymbols(def, UDAT_SHORT_WEEKDAYS)!=8 || udat_countSymbols(def, UDAT_AM_PMS)!=2 ||
618 udat_countSymbols(def, UDAT_QUARTERS) != 4 || udat_countSymbols(def, UDAT_SHORT_QUARTERS) != 4 ||
619 udat_countSymbols(def, UDAT_LOCALIZED_CHARS)!=1 || udat_countSymbols(def, UDAT_SHORTER_WEEKDAYS)!=8 ||
620 udat_countSymbols(zhChiCal, UDAT_CYCLIC_YEARS_NARROW)!=60 || udat_countSymbols(zhChiCal, UDAT_ZODIAC_NAMES_NARROW)!=12)
622 log_err("FAIL: error in udat_countSymbols\n");
625 log_verbose("PASS: udat_countSymbols() successful\n");
627 /*testing getSymbols*/
628 log_verbose("\nTesting getSymbols\n");
629 pattern=(UChar*)malloc(sizeof(UChar) * 10);
630 u_uastrcpy(pattern, "jeudi");
632 resultlengthout=udat_getSymbols(fr, UDAT_WEEKDAYS, 5 , NULL, resultlength, &status);
633 if(status==U_BUFFER_OVERFLOW_ERROR)
636 resultlength=resultlengthout+1;
641 result=(UChar*)malloc(sizeof(UChar) * resultlength);
642 udat_getSymbols(fr, UDAT_WEEKDAYS, 5, result, resultlength, &status);
645 if(U_FAILURE(status))
647 log_err("FAIL: Error in udat_getSymbols().... %s\n", myErrorName(status) );
650 log_verbose("PASS: getSymbols succesful\n");
652 if(u_strcmp(result, pattern)==0)
653 log_verbose("PASS: getSymbols retrieved the right value\n");
655 log_data_err("FAIL: getSymbols retrieved the wrong value\n");
657 /*run series of tests to test getsymbols regressively*/
658 log_verbose("\nTesting getSymbols() regressively\n");
659 VerifygetSymbols(fr, UDAT_WEEKDAYS, 1, "dimanche");
660 VerifygetSymbols(def, UDAT_WEEKDAYS, 1, "Sunday");
661 VerifygetSymbols(fr, UDAT_SHORT_WEEKDAYS, 7, "sam.");
662 VerifygetSymbols(fr, UDAT_SHORTER_WEEKDAYS, 7, "sa");
663 VerifygetSymbols(def, UDAT_SHORT_WEEKDAYS, 7, "Sat");
664 VerifygetSymbols(def, UDAT_MONTHS, 11, "December");
665 VerifygetSymbols(def, UDAT_MONTHS, 0, "January");
666 VerifygetSymbols(fr, UDAT_ERAS, 0, "av. J.-C.");
667 VerifygetSymbols(def, UDAT_AM_PMS, 0, "AM");
668 VerifygetSymbols(def, UDAT_AM_PMS, 1, "PM");
669 VerifygetSymbols(fr, UDAT_SHORT_MONTHS, 0, "janv.");
670 VerifygetSymbols(def, UDAT_SHORT_MONTHS, 11, "Dec");
671 VerifygetSymbols(fr, UDAT_QUARTERS, 0, "1er trimestre");
672 VerifygetSymbols(def, UDAT_QUARTERS, 3, "4th quarter");
673 VerifygetSymbols(fr, UDAT_SHORT_QUARTERS, 1, "T2");
674 VerifygetSymbols(def, UDAT_SHORT_QUARTERS, 2, "Q3");
675 VerifygetSymbols(zhChiCal, UDAT_CYCLIC_YEARS_ABBREVIATED, 0, "\\u7532\\u5B50");
676 VerifygetSymbols(zhChiCal, UDAT_CYCLIC_YEARS_NARROW, 59, "\\u7678\\u4EA5");
677 VerifygetSymbols(zhChiCal, UDAT_ZODIAC_NAMES_ABBREVIATED, 0, "\\u9F20");
678 VerifygetSymbols(zhChiCal, UDAT_ZODIAC_NAMES_WIDE, 11, "\\u732A");
679 #if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
680 VerifygetSymbols(def,UDAT_LOCALIZED_CHARS, 0, "GyMdkHmsSEDFwWahKzYeugAZvcLQqVUOXxrbB:");
682 VerifygetSymbols(def,UDAT_LOCALIZED_CHARS, 0, "GyMdkHmsSEDFwWahKzYeugAZvcLQqVUOXxrbB");
692 log_verbose("\nTesting setSymbols\n");
693 /*applying the pattern so that setSymbolss works */
695 resultlengthout=udat_toPattern(fr, FALSE, NULL, resultlength, &status);
696 if(status==U_BUFFER_OVERFLOW_ERROR)
699 resultlength=resultlengthout + 1;
700 pattern=(UChar*)malloc(sizeof(UChar) * resultlength);
701 udat_toPattern(fr, FALSE, pattern, resultlength, &status);
703 if(U_FAILURE(status))
705 log_err("FAIL: error in extracting the pattern from UNumberFormat\n %s\n",
706 myErrorName(status) );
709 udat_applyPattern(def, FALSE, pattern, u_strlen(pattern));
711 resultlengthout=udat_toPattern(def, FALSE, NULL, resultlength,&status);
712 if(status==U_BUFFER_OVERFLOW_ERROR)
715 resultlength=resultlengthout + 1;
720 result=(UChar*)malloc(sizeof(UChar) * resultlength);
721 udat_toPattern(fr, FALSE,result, resultlength, &status);
723 if(U_FAILURE(status))
725 log_err("FAIL: error in extracting the pattern from UNumberFormat\n %s\n",
726 myErrorName(status) );
728 if(u_strcmp(result, pattern)==0)
729 log_verbose("Pattern applied properly\n");
731 log_err("pattern could not be applied properly\n");
734 /*testing set symbols */
736 resultlengthout=udat_getSymbols(fr, UDAT_MONTHS, 11 , NULL, resultlength, &status);
737 if(status==U_BUFFER_OVERFLOW_ERROR){
739 resultlength=resultlengthout+1;
744 result=(UChar*)malloc(sizeof(UChar) * resultlength);
745 udat_getSymbols(fr, UDAT_MONTHS, 11, result, resultlength, &status);
748 if(U_FAILURE(status))
749 log_err("FAIL: error in getSymbols() %s\n", myErrorName(status) );
750 resultlength=resultlengthout+1;
752 udat_setSymbols(def, UDAT_MONTHS, 11, result, resultlength, &status);
753 if(U_FAILURE(status))
755 log_err("FAIL: Error in udat_setSymbols() : %s\n", myErrorName(status) );
758 log_verbose("PASS: SetSymbols successful\n");
761 resultlengthout=udat_getSymbols(def, UDAT_MONTHS, 11, NULL, resultlength, &status);
762 if(status==U_BUFFER_OVERFLOW_ERROR){
764 resultlength=resultlengthout+1;
765 value=(UChar*)malloc(sizeof(UChar) * resultlength);
766 udat_getSymbols(def, UDAT_MONTHS, 11, value, resultlength, &status);
768 if(U_FAILURE(status))
769 log_err("FAIL: error in retrieving the value using getSymbols i.e roundtrip\n");
771 if(u_strcmp(result, value)!=0)
772 log_data_err("FAIL: Error in settting and getting symbols\n");
774 log_verbose("PASS: setSymbols successful\n");
777 /*run series of tests to test setSymbols regressively*/
778 log_verbose("\nTesting setSymbols regressively\n");
779 VerifysetSymbols(def, UDAT_ERAS, 0, "BeforeChrist");
780 VerifysetSymbols(def, UDAT_ERA_NAMES, 1, "AnnoDomini");
781 VerifysetSymbols(def, UDAT_WEEKDAYS, 1, "Sundayweek");
782 VerifysetSymbols(def, UDAT_SHORT_WEEKDAYS, 7, "Satweek");
783 VerifysetSymbols(def, UDAT_NARROW_WEEKDAYS, 4, "M");
784 VerifysetSymbols(def, UDAT_STANDALONE_WEEKDAYS, 1, "Sonntagweek");
785 VerifysetSymbols(def, UDAT_STANDALONE_SHORT_WEEKDAYS, 7, "Sams");
786 VerifysetSymbols(def, UDAT_STANDALONE_NARROW_WEEKDAYS, 4, "V");
787 VerifysetSymbols(fr, UDAT_MONTHS, 11, "december");
788 VerifysetSymbols(fr, UDAT_SHORT_MONTHS, 0, "Jan");
789 VerifysetSymbols(fr, UDAT_NARROW_MONTHS, 1, "R");
790 VerifysetSymbols(fr, UDAT_STANDALONE_MONTHS, 11, "dezember");
791 VerifysetSymbols(fr, UDAT_STANDALONE_SHORT_MONTHS, 7, "Aug");
792 VerifysetSymbols(fr, UDAT_STANDALONE_NARROW_MONTHS, 2, "M");
793 VerifysetSymbols(fr, UDAT_QUARTERS, 0, "1. Quart");
794 VerifysetSymbols(fr, UDAT_SHORT_QUARTERS, 1, "QQ2");
795 VerifysetSymbols(fr, UDAT_STANDALONE_QUARTERS, 2, "3rd Quar.");
796 VerifysetSymbols(fr, UDAT_STANDALONE_SHORT_QUARTERS, 3, "4QQ");
797 VerifysetSymbols(zhChiCal, UDAT_CYCLIC_YEARS_ABBREVIATED, 1, "yi-chou");
798 VerifysetSymbols(zhChiCal, UDAT_ZODIAC_NAMES_ABBREVIATED, 1, "Ox");
801 /*run series of tests to test get and setSymbols regressively*/
802 log_verbose("\nTesting get and set symbols regressively\n");
803 VerifygetsetSymbols(fr, def, UDAT_WEEKDAYS, 1);
804 VerifygetsetSymbols(fr, def, UDAT_WEEKDAYS, 7);
805 VerifygetsetSymbols(fr, def, UDAT_SHORT_WEEKDAYS, 1);
806 VerifygetsetSymbols(fr, def, UDAT_SHORT_WEEKDAYS, 7);
807 VerifygetsetSymbols(fr, def, UDAT_MONTHS, 0);
808 VerifygetsetSymbols(fr, def, UDAT_SHORT_MONTHS, 0);
809 VerifygetsetSymbols(fr, def, UDAT_ERAS,1);
810 VerifygetsetSymbols(fr, def, UDAT_LOCALIZED_CHARS, 0);
811 VerifygetsetSymbols(fr, def, UDAT_AM_PMS, 1);
818 udat_close(zhChiCal);
828 * Test DateFormat(Calendar) API
830 static void TestDateFormatCalendar() {
831 UDateFormat *date=0, *time=0, *full=0;
837 UErrorCode ec = U_ZERO_ERROR;
840 const char *expected;
843 ctest_setTimeZone(NULL, &ec);
845 /* Create a formatter for date fields. */
846 date = udat_open(UDAT_NONE, UDAT_SHORT, "en_US", NULL, 0, NULL, 0, &ec);
848 log_data_err("FAIL: udat_open(NONE, SHORT, en_US) failed with %s (Are you missing data?)\n",
853 /* Create a formatter for time fields. */
854 time = udat_open(UDAT_SHORT, UDAT_NONE, "en_US", NULL, 0, NULL, 0, &ec);
856 log_err("FAIL: udat_open(SHORT, NONE, en_US) failed with %s\n",
861 /* Create a full format for output */
862 full = udat_open(UDAT_FULL, UDAT_FULL, "en_US", NULL, 0, NULL, 0, &ec);
864 log_err("FAIL: udat_open(FULL, FULL, en_US) failed with %s\n",
869 /* Create a calendar */
870 cal = ucal_open(NULL, 0, "en_US", UCAL_GREGORIAN, &ec);
872 log_err("FAIL: ucal_open(en_US) failed with %s\n",
879 u_uastrcpy(buf, "4/5/2001");
881 udat_parseCalendar(date, cal, buf, -1, &pos, &ec);
883 log_err("FAIL: udat_parseCalendar(4/5/2001) failed at %d with %s\n",
884 pos, u_errorName(ec));
888 /* Check if formatCalendar matches the original date */
889 len1 = udat_formatCalendar(date, cal, buf1, UPRV_LENGTHOF(buf1), NULL, &ec);
891 log_err("FAIL: udat_formatCalendar(4/5/2001) failed with %s\n",
896 u_uastrcpy(uExpected, expected);
897 if (u_strlen(uExpected) != len1 || u_strncmp(uExpected, buf1, len1) != 0) {
898 log_err("FAIL: udat_formatCalendar(4/5/2001), expected: %s", expected);
902 u_uastrcpy(buf, "5:45 PM");
904 udat_parseCalendar(time, cal, buf, -1, &pos, &ec);
906 log_err("FAIL: udat_parseCalendar(17:45) failed at %d with %s\n",
907 pos, u_errorName(ec));
911 /* Check if formatCalendar matches the original time */
912 len1 = udat_formatCalendar(time, cal, buf1, UPRV_LENGTHOF(buf1), NULL, &ec);
914 log_err("FAIL: udat_formatCalendar(17:45) failed with %s\n",
918 expected = "5:45 PM";
919 u_uastrcpy(uExpected, expected);
920 if (u_strlen(uExpected) != len1 || u_strncmp(uExpected, buf1, len1) != 0) {
921 log_err("FAIL: udat_formatCalendar(17:45), expected: %s", expected);
925 when = ucal_getMillis(cal, &ec);
927 log_err("FAIL: ucal_getMillis() failed with %s\n", u_errorName(ec));
930 udat_format(full, when, buf, sizeof(buf), NULL, &ec);
932 log_err("FAIL: udat_format() failed with %s\n", u_errorName(ec));
935 u_austrcpy(cbuf, buf);
936 /* Thursday, April 5, 2001 5:45:00 PM PDT 986517900000 */
937 if (when == 986517900000.0) {
938 log_verbose("Ok: Parsed result: %s\n", cbuf);
940 log_err("FAIL: Parsed result: %s, exp 4/5/2001 5:45 PM\n", cbuf);
949 ctest_resetTimeZone();
955 * Test parsing two digit year against "YY" vs. "YYYY" patterns
957 static void TestCalendarDateParse() {
960 UErrorCode ec = U_ZERO_ERROR;
961 UDateFormat* simpleDateFormat = 0;
962 int32_t parsePos = 0;
963 int32_t twoDigitCenturyStart = 75;
964 int32_t currentTwoDigitYear = 0;
965 int32_t startCentury = 0;
966 UCalendar* tempCal = 0;
967 UCalendar* calendar = 0;
969 U_STRING_DECL(pattern, "yyyy", 4);
970 U_STRING_DECL(pattern2, "yy", 2);
971 U_STRING_DECL(text, "75", 2);
973 U_STRING_INIT(pattern, "yyyy", 4);
974 U_STRING_INIT(pattern2, "yy", 2);
975 U_STRING_INIT(text, "75", 2);
977 simpleDateFormat = udat_open(UDAT_FULL, UDAT_FULL, "en-GB", 0, 0, 0, 0, &ec);
979 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));
982 udat_applyPattern(simpleDateFormat, 0, pattern, u_strlen(pattern));
983 udat_setLenient(simpleDateFormat, 0);
985 currentTwoDigitYear = getCurrentYear() % 100;
986 startCentury = getCurrentYear() - currentTwoDigitYear;
987 if (twoDigitCenturyStart > currentTwoDigitYear) {
990 tempCal = ucal_open(NULL, -1, NULL, UCAL_GREGORIAN, &ec);
991 ucal_setMillis(tempCal, 0, &ec);
992 ucal_setDateTime(tempCal, startCentury + twoDigitCenturyStart, UCAL_JANUARY, 1, 0, 0, 0, &ec);
993 udat_set2DigitYearStart(simpleDateFormat, ucal_getMillis(tempCal, &ec), &ec);
995 calendar = ucal_open(NULL, -1, NULL, UCAL_GREGORIAN, &ec);
996 ucal_setMillis(calendar, 0, &ec);
997 ucal_setDateTime(calendar, twoDigitCenturyStart, UCAL_JANUARY, 1, 0, 0, 0, &ec);
999 udat_parseCalendar(simpleDateFormat, calendar, text, u_strlen(text), &parsePos, &ec);
1002 result = ucal_get(calendar, UCAL_YEAR, &ec);
1003 if (U_FAILURE(ec)) {
1004 log_err("FAIL: ucal_get(UCAL_YEAR) failed with %s\n", u_errorName(ec));
1009 log_err("FAIL: parsed incorrect year: %d\n", result);
1014 udat_applyPattern(simpleDateFormat, 0, pattern2, u_strlen(pattern2));
1015 udat_parseCalendar(simpleDateFormat, calendar, text, u_strlen(text), &parsePos, &ec);
1018 result = ucal_get(calendar, UCAL_YEAR, &ec);
1019 if (U_FAILURE(ec)) {
1020 log_err("FAIL: ucal_get(UCAL_YEAR) failed with %s\n", u_errorName(ec));
1024 if (result != 1975) {
1025 log_err("FAIL: parsed incorrect year: %d\n", result);
1030 udat_close(simpleDateFormat);
1031 udat_close(tempCal);
1032 udat_close(calendar);
1036 /*INTERNAL FUNCTIONS USED*/
1037 static int getCurrentYear() {
1038 static int currentYear = 0;
1039 if (currentYear == 0) {
1040 UErrorCode status = U_ZERO_ERROR;
1041 UCalendar *cal = ucal_open(NULL, -1, NULL, UCAL_GREGORIAN, &status);
1042 if (!U_FAILURE(status)) {
1043 /* Get the current year from the default UCalendar */
1044 currentYear = ucal_get(cal, UCAL_YEAR, &status);
1052 /* N.B.: use idx instead of index to avoid 'shadow' warnings in strict mode. */
1053 static void VerifygetSymbols(UDateFormat* datfor, UDateFormatSymbolType type, int32_t idx, const char* expected)
1055 UChar *pattern=NULL;
1056 UErrorCode status = U_ZERO_ERROR;
1058 int32_t resultlength, resultlengthout;
1059 int32_t patternSize = strlen(expected) + 1;
1061 pattern=(UChar*)malloc(sizeof(UChar) * patternSize);
1062 u_unescape(expected, pattern, patternSize);
1064 resultlengthout=udat_getSymbols(datfor, type, idx , NULL, resultlength, &status);
1065 if(status==U_BUFFER_OVERFLOW_ERROR)
1067 status=U_ZERO_ERROR;
1068 resultlength=resultlengthout+1;
1069 result=(UChar*)malloc(sizeof(UChar) * resultlength);
1070 udat_getSymbols(datfor, type, idx, result, resultlength, &status);
1073 if(U_FAILURE(status))
1075 log_err("FAIL: Error in udat_getSymbols()... %s\n", myErrorName(status) );
1078 if(u_strcmp(result, pattern)==0)
1079 log_verbose("PASS: getSymbols retrieved the right value\n");
1081 log_data_err("FAIL: getSymbols retrieved the wrong value\n Expected %s Got %s\n", expected,
1082 aescstrdup(result,-1) );
1088 static void VerifysetSymbols(UDateFormat* datfor, UDateFormatSymbolType type, int32_t idx, const char* expected)
1092 int32_t resultlength, resultlengthout;
1093 UErrorCode status = U_ZERO_ERROR;
1094 int32_t valueLen, valueSize = strlen(expected) + 1;
1096 value=(UChar*)malloc(sizeof(UChar) * valueSize);
1097 valueLen = u_unescape(expected, value, valueSize);
1098 udat_setSymbols(datfor, type, idx, value, valueLen, &status);
1099 if(U_FAILURE(status))
1101 log_err("FAIL: Error in udat_setSymbols() %s\n", myErrorName(status) );
1106 resultlengthout=udat_getSymbols(datfor, type, idx, NULL, resultlength, &status);
1107 if(status==U_BUFFER_OVERFLOW_ERROR){
1108 status=U_ZERO_ERROR;
1109 resultlength=resultlengthout+1;
1110 result=(UChar*)malloc(sizeof(UChar) * resultlength);
1111 udat_getSymbols(datfor, type, idx, result, resultlength, &status);
1113 if(U_FAILURE(status)){
1114 log_err("FAIL: error in retrieving the value using getSymbols after setting it previously\n %s\n",
1115 myErrorName(status) );
1119 if(u_strcmp(result, value)!=0){
1120 log_err("FAIL:Error in setting and then getting symbols\n Expected %s Got %s\n", expected,
1121 aescstrdup(result,-1) );
1124 log_verbose("PASS: setSymbols successful\n");
1131 static void VerifygetsetSymbols(UDateFormat* from, UDateFormat* to, UDateFormatSymbolType type, int32_t idx)
1135 int32_t resultlength, resultlengthout;
1136 UErrorCode status = U_ZERO_ERROR;
1139 resultlengthout=udat_getSymbols(from, type, idx , NULL, resultlength, &status);
1140 if(status==U_BUFFER_OVERFLOW_ERROR){
1141 status=U_ZERO_ERROR;
1142 resultlength=resultlengthout+1;
1143 result=(UChar*)malloc(sizeof(UChar) * resultlength);
1144 udat_getSymbols(from, type, idx, result, resultlength, &status);
1146 if(U_FAILURE(status)){
1147 log_err("FAIL: error in getSymbols() %s\n", myErrorName(status) );
1151 resultlength=resultlengthout+1;
1152 udat_setSymbols(to, type, idx, result, resultlength, &status);
1153 if(U_FAILURE(status))
1155 log_err("FAIL: Error in udat_setSymbols() : %s\n", myErrorName(status) );
1160 resultlengthout=udat_getSymbols(to, type, idx, NULL, resultlength, &status);
1161 if(status==U_BUFFER_OVERFLOW_ERROR){
1162 status=U_ZERO_ERROR;
1163 resultlength=resultlengthout+1;
1164 value=(UChar*)malloc(sizeof(UChar) * resultlength);
1165 udat_getSymbols(to, type, idx, value, resultlength, &status);
1167 if(U_FAILURE(status)){
1168 log_err("FAIL: error in retrieving the value using getSymbols i.e roundtrip\n %s\n",
1169 myErrorName(status) );
1173 if(u_strcmp(result, value)!=0){
1174 log_data_err("FAIL:Error in setting and then getting symbols\n Expected %s Got %s\n", austrdup(result),
1178 log_verbose("PASS: setSymbols successful\n");
1185 static UChar* myNumformat(const UNumberFormat* numfor, double d)
1187 UChar *result2=NULL;
1188 int32_t resultlength, resultlengthneeded;
1189 UErrorCode status = U_ZERO_ERROR;
1192 resultlengthneeded=unum_formatDouble(numfor, d, NULL, resultlength, NULL, &status);
1193 if(status==U_BUFFER_OVERFLOW_ERROR)
1195 status=U_ZERO_ERROR;
1196 resultlength=resultlengthneeded+1;
1197 /*result2=(UChar*)malloc(sizeof(UChar) * resultlength);*/ /* this leaks */
1198 result2=(UChar*)ctst_malloc(sizeof(UChar) * resultlength); /*this won't*/
1199 unum_formatDouble(numfor, d, result2, resultlength, NULL, &status);
1201 if(U_FAILURE(status))
1203 log_err("FAIL: Error in formatting using unum_format(.....) %s\n", myErrorName(status) );
1211 * The search depth for TestExtremeDates. The total number of
1212 * dates that will be tested is (2^EXTREME_DATES_DEPTH) - 1.
1214 #define EXTREME_DATES_DEPTH 8
1217 * Support for TestExtremeDates (below).
1219 * Test a single date to see whether udat_format handles it properly.
1221 static UBool _aux1ExtremeDates(UDateFormat* fmt, UDate date,
1222 UChar* buf, int32_t buflen, char* cbuf,
1224 int32_t len = udat_format(fmt, date, buf, buflen, 0, ec);
1225 if (!assertSuccess("udat_format", ec)) return FALSE;
1226 u_austrncpy(cbuf, buf, buflen);
1228 log_err("FAIL: udat_format(%g) => \"%s\"\n", date, cbuf);
1230 log_verbose("udat_format(%g) => \"%s\"\n", date, cbuf);
1236 * Support for TestExtremeDates (below).
1238 * Recursively test between 'small' and 'large', up to the depth
1239 * limit specified by EXTREME_DATES_DEPTH.
1241 static UBool _aux2ExtremeDates(UDateFormat* fmt, UDate small, UDate large,
1242 UChar* buf, int32_t buflen, char* cbuf,
1245 /* Logarithmic midpoint; see below */
1246 UDate mid = (UDate) exp((log(small) + log(large)) / 2);
1247 if (count == EXTREME_DATES_DEPTH) {
1251 _aux1ExtremeDates(fmt, mid, buf, buflen, cbuf, ec) &&
1252 _aux2ExtremeDates(fmt, small, mid, buf, buflen, cbuf, count+1, ec) &&
1253 _aux2ExtremeDates(fmt, mid, large, buf, buflen, cbuf, count+1, ec);
1257 * http://www.jtcsv.com/cgibin/icu-bugs?findid=3659
1259 * For certain large dates, udat_format crashes on MacOS. This test
1260 * attempts to reproduce this problem by doing a recursive logarithmic*
1261 * binary search of a predefined interval (from 'small' to 'large').
1263 * The limit of the search is given by EXTREME_DATES_DEPTH, above.
1265 * *The search has to be logarithmic, not linear. A linear search of the
1266 * range 0..10^30, for example, will find 0.5*10^30, then 0.25*10^30 and
1267 * 0.75*10^30, etc. A logarithmic search will find 10^15, then 10^7.5
1270 static void TestExtremeDates() {
1275 const double small = 1000; /* 1 sec */
1276 const double large = 1e+30; /* well beyond usable UDate range */
1278 /* There is no need to test larger values from 1e+30 to 1e+300;
1279 the failures occur around 1e+27, and never above 1e+30. */
1282 fmt = udat_open(UDAT_LONG, UDAT_LONG, "en_US",
1284 if (U_FAILURE(ec)) {
1285 log_data_err("FAIL: udat_open (%s) (Are you missing data?)\n", u_errorName(ec));
1289 _aux2ExtremeDates(fmt, small, large, buf, UPRV_LENGTHOF(buf), cbuf, 0, &ec);
1294 static void TestAllLocales(void) {
1295 int32_t idx, dateIdx, timeIdx, localeCount;
1296 static const UDateFormatStyle style[] = {
1297 UDAT_FULL, UDAT_LONG, UDAT_MEDIUM, UDAT_SHORT
1299 localeCount = uloc_countAvailable();
1300 for (idx = 0; idx < localeCount; idx++) {
1301 for (dateIdx = 0; dateIdx < UPRV_LENGTHOF(style); dateIdx++) {
1302 for (timeIdx = 0; timeIdx < UPRV_LENGTHOF(style); timeIdx++) {
1303 UErrorCode status = U_ZERO_ERROR;
1304 udat_close(udat_open(style[dateIdx], style[timeIdx],
1305 uloc_getAvailable(idx), NULL, 0, NULL, 0, &status));
1306 if (U_FAILURE(status)) {
1307 log_err("FAIL: udat_open(%s) failed with (%s) dateIdx=%d, timeIdx=%d\n",
1308 uloc_getAvailable(idx), u_errorName(status), dateIdx, timeIdx);
1315 static void TestRelativeCrash(void) {
1316 static const UChar tzName[] = { 0x0055, 0x0053, 0x002F, 0x0050, 0x0061, 0x0063, 0x0069, 0x0066, 0x0069, 0x0063, 0 };
1317 static const UDate aDate = -631152000000.0;
1319 UErrorCode status = U_ZERO_ERROR;
1320 UErrorCode expectStatus = U_ILLEGAL_ARGUMENT_ERROR;
1323 icudf = udat_open(UDAT_NONE, UDAT_SHORT_RELATIVE, "en", tzName, -1, NULL, 0, &status);
1324 if ( U_SUCCESS(status) ) {
1325 const char *what = "???";
1327 UErrorCode subStatus = U_ZERO_ERROR;
1328 what = "udat_set2DigitYearStart";
1329 log_verbose("Trying %s on a relative date..\n", what);
1330 udat_set2DigitYearStart(icudf, aDate, &subStatus);
1331 if(subStatus == expectStatus) {
1332 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1334 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
1338 /* clone works polymorphically. try it anyways */
1339 UErrorCode subStatus = U_ZERO_ERROR;
1342 log_verbose("Trying %s on a relative date..\n", what);
1343 oth = udat_clone(icudf, &subStatus);
1344 if(subStatus == U_ZERO_ERROR) {
1345 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1346 udat_close(oth); /* ? */
1348 log_err("FAIL: didn't crash on %s, but got %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
1352 UErrorCode subStatus = U_ZERO_ERROR;
1353 what = "udat_get2DigitYearStart";
1354 log_verbose("Trying %s on a relative date..\n", what);
1355 udat_get2DigitYearStart(icudf, &subStatus);
1356 if(subStatus == expectStatus) {
1357 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1359 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
1363 /* Now udat_toPattern works for relative date formatters, unless localized is TRUE */
1364 UErrorCode subStatus = U_ZERO_ERROR;
1365 what = "udat_toPattern";
1366 log_verbose("Trying %s on a relative date..\n", what);
1367 udat_toPattern(icudf, TRUE,NULL,0, &subStatus);
1368 if(subStatus == expectStatus) {
1369 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1371 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
1375 UErrorCode subStatus = U_ZERO_ERROR;
1376 what = "udat_applyPattern";
1377 log_verbose("Trying %s on a relative date..\n", what);
1378 udat_applyPattern(icudf, FALSE,tzName,-1);
1379 subStatus = U_ILLEGAL_ARGUMENT_ERROR; /* what it should be, if this took an errorcode. */
1380 if(subStatus == expectStatus) {
1381 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1383 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
1388 UErrorCode subStatus = U_ZERO_ERROR;
1389 what = "udat_getSymbols";
1390 log_verbose("Trying %s on a relative date..\n", what);
1391 udat_getSymbols(icudf, UDAT_ERAS,0,erabuf,UPRV_LENGTHOF(erabuf), &subStatus);
1392 if(subStatus == U_ZERO_ERROR) {
1393 log_verbose("Success: %s returned %s.\n", what, u_errorName(subStatus));
1395 log_err("FAIL: didn't crash on %s, but got %s instead of U_ZERO_ERROR.\n", what, u_errorName(subStatus));
1399 UErrorCode subStatus = U_ZERO_ERROR;
1400 UChar symbolValue = 0x0041;
1401 what = "udat_setSymbols";
1402 log_verbose("Trying %s on a relative date..\n", what);
1403 udat_setSymbols(icudf, UDAT_ERAS,0,&symbolValue,1, &subStatus); /* bogus values */
1404 if(subStatus == expectStatus) {
1405 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1407 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
1411 UErrorCode subStatus = U_ZERO_ERROR;
1412 what = "udat_countSymbols";
1413 log_verbose("Trying %s on a relative date..\n", what);
1414 udat_countSymbols(icudf, UDAT_ERAS);
1415 subStatus = U_ILLEGAL_ARGUMENT_ERROR; /* should have an errorcode. */
1416 if(subStatus == expectStatus) {
1417 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1419 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
1425 log_data_err("FAIL: err calling udat_open() ->%s (Are you missing data?)\n", u_errorName(status));
1429 static const UChar skeleton_yMMMM[] = { 0x79,0x4D,0x4D,0x4D,0x4D,0 }; /* "yMMMM"; fr maps to "MMMM y", cs maps to "LLLL y" */
1430 static const UChar july2008_frDefault[] = { 0x6A,0x75,0x69,0x6C,0x6C,0x65,0x74,0x20,0x32,0x30,0x30,0x38,0 }; /* "juillet 2008" */
1431 static const UChar july2008_frTitle[] = { 0x4A,0x75,0x69,0x6C,0x6C,0x65,0x74,0x20,0x32,0x30,0x30,0x38,0 }; /* "Juillet 2008" sentence-begin, standalone */
1432 static const UChar july2008_csDefault[] = { 0x10D,0x65,0x72,0x76,0x65,0x6E,0x65,0x63,0x20,0x32,0x30,0x30,0x38,0 }; /* "c(hacek)ervenec 2008" */
1433 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 */
1436 const char * locale;
1437 const UChar * skeleton;
1438 UDisplayContext capitalizationContext;
1439 const UChar * expectedFormat;
1442 static const TestContextItem textContextItems[] = {
1443 { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_NONE, july2008_frDefault },
1444 #if !UCONFIG_NO_BREAK_ITERATION
1445 { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, july2008_frDefault },
1446 { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, july2008_frTitle },
1447 { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, july2008_frDefault },
1448 { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_STANDALONE, july2008_frTitle },
1450 { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_NONE, july2008_csDefault },
1451 #if !UCONFIG_NO_BREAK_ITERATION
1452 { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, july2008_csDefault },
1453 { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, july2008_csTitle },
1454 { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, july2008_csTitle },
1455 { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_STANDALONE, july2008_csDefault },
1457 { NULL, NULL, (UDisplayContext)0, NULL }
1460 static const UChar today_enDefault[] = { 0x74,0x6F,0x64,0x61,0x79,0 }; /* "today" */
1461 static const UChar today_enTitle[] = { 0x54,0x6F,0x64,0x61,0x79,0 }; /* "Today" sentence-begin, uiListOrMenu, standalone */
1462 static const UChar yesterday_enDefault[] = { 0x79,0x65,0x73,0x74,0x65,0x72,0x64,0x61,0x79,0 }; /* "yesterday" */
1463 static const UChar yesterday_enTitle[] = { 0x59,0x65,0x73,0x74,0x65,0x72,0x64,0x61,0x79,0 }; /* "Yesterday" sentence-begin, uiListOrMenu, standalone */
1464 static const UChar today_nbDefault[] = { 0x69,0x20,0x64,0x61,0x67,0 }; /* "i dag" */
1465 static const UChar today_nbTitle[] = { 0x49,0x20,0x64,0x61,0x67,0 }; /* "I dag" sentence-begin, standalone */
1466 static const UChar yesterday_nbDefault[] = { 0x69,0x20,0x67,0xE5,0x72,0 };
1467 static const UChar yesterday_nbTitle[] = { 0x49,0x20,0x67,0xE5,0x72,0 };
1470 const char * locale;
1471 UDisplayContext capitalizationContext;
1472 const UChar * expectedFormatToday;
1473 const UChar * expectedFormatYesterday;
1474 } TestRelativeContextItem;
1476 static const TestRelativeContextItem textContextRelativeItems[] = {
1477 { "en", UDISPCTX_CAPITALIZATION_NONE, today_enDefault, yesterday_enDefault },
1478 #if !UCONFIG_NO_BREAK_ITERATION
1479 { "en", UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, today_enDefault, yesterday_enDefault },
1480 { "en", UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, today_enTitle, yesterday_enTitle },
1481 { "en", UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, today_enTitle, yesterday_enTitle },
1482 { "en", UDISPCTX_CAPITALIZATION_FOR_STANDALONE, today_enTitle, yesterday_enTitle },
1484 { "nb", UDISPCTX_CAPITALIZATION_NONE, today_nbDefault, yesterday_nbDefault },
1485 #if !UCONFIG_NO_BREAK_ITERATION
1486 { "nb", UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, today_nbDefault, yesterday_nbDefault },
1487 { "nb", UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, today_nbTitle, yesterday_nbTitle },
1488 { "nb", UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, today_nbDefault, yesterday_nbDefault },
1489 { "nb", UDISPCTX_CAPITALIZATION_FOR_STANDALONE, today_nbTitle, yesterday_nbTitle },
1491 { NULL, (UDisplayContext)0, NULL, NULL }
1494 static const UChar zoneGMT[] = { 0x47,0x4D,0x54,0 }; /* "GMT" */
1495 static const UDate july022008 = 1215000000000.0;
1496 enum { kUbufMax = 64, kBbufMax = 3*kUbufMax };
1498 static void TestContext(void) {
1499 const TestContextItem* textContextItemPtr;
1500 const TestRelativeContextItem* textRelContextItemPtr;
1501 for (textContextItemPtr = textContextItems; textContextItemPtr->locale != NULL; ++textContextItemPtr) {
1502 UErrorCode status = U_ZERO_ERROR;
1503 UDateTimePatternGenerator* udtpg = udatpg_open(textContextItemPtr->locale, &status);
1504 if ( U_SUCCESS(status) ) {
1505 UChar ubuf[kUbufMax];
1506 int32_t len = udatpg_getBestPattern(udtpg, textContextItemPtr->skeleton, -1, ubuf, kUbufMax, &status);
1507 if ( U_SUCCESS(status) ) {
1508 UDateFormat* udfmt = udat_open(UDAT_PATTERN, UDAT_PATTERN, textContextItemPtr->locale, zoneGMT, -1, ubuf, len, &status);
1509 if ( U_SUCCESS(status) ) {
1510 udat_setContext(udfmt, textContextItemPtr->capitalizationContext, &status);
1511 if ( U_SUCCESS(status) ) {
1512 UDisplayContext getContext;
1513 len = udat_format(udfmt, july022008, ubuf, kUbufMax, NULL, &status);
1514 if ( U_FAILURE(status) ) {
1515 log_err("FAIL: udat_format for locale %s, capitalizationContext %d, status %s\n",
1516 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, u_errorName(status) );
1517 status = U_ZERO_ERROR;
1518 } else if (u_strncmp(ubuf, textContextItemPtr->expectedFormat, kUbufMax) != 0) {
1519 char bbuf1[kBbufMax];
1520 char bbuf2[kBbufMax];
1521 log_err("FAIL: udat_format for locale %s, capitalizationContext %d, expected %s, got %s\n",
1522 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext,
1523 u_austrncpy(bbuf1,textContextItemPtr->expectedFormat,kUbufMax), u_austrncpy(bbuf2,ubuf,kUbufMax) );
1525 getContext = udat_getContext(udfmt, UDISPCTX_TYPE_CAPITALIZATION, &status);
1526 if ( U_FAILURE(status) ) {
1527 log_err("FAIL: udat_getContext for locale %s, capitalizationContext %d, status %s\n",
1528 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, u_errorName(status) );
1529 } else if (getContext != textContextItemPtr->capitalizationContext) {
1530 log_err("FAIL: udat_getContext for locale %s, capitalizationContext %d, got context %d\n",
1531 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, (int)getContext );
1534 log_err("FAIL: udat_setContext for locale %s, capitalizationContext %d, status %s\n",
1535 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, u_errorName(status) );
1539 log_data_err("FAIL: udat_open for locale %s, status %s\n", textContextItemPtr->locale, u_errorName(status) );
1542 log_err("FAIL: udatpg_getBestPattern for locale %s, status %s\n", textContextItemPtr->locale, u_errorName(status) );
1544 udatpg_close(udtpg);
1546 log_data_err("FAIL: udatpg_open for locale %s, status %s\n", textContextItemPtr->locale, u_errorName(status) );
1549 for (textRelContextItemPtr = textContextRelativeItems; textRelContextItemPtr->locale != NULL; ++textRelContextItemPtr) {
1550 UErrorCode status = U_ZERO_ERROR;
1551 UCalendar* ucal = ucal_open(zoneGMT, -1, "root", UCAL_GREGORIAN, &status);
1552 if ( U_SUCCESS(status) ) {
1553 UDateFormat* udfmt = udat_open(UDAT_NONE, UDAT_LONG_RELATIVE, textRelContextItemPtr->locale, zoneGMT, -1, NULL, 0, &status);
1554 if ( U_SUCCESS(status) ) {
1555 udat_setContext(udfmt, textRelContextItemPtr->capitalizationContext, &status);
1556 if ( U_SUCCESS(status) ) {
1557 UDate yesterday, today = ucal_getNow();
1558 UChar ubuf[kUbufMax];
1559 char bbuf1[kBbufMax];
1560 char bbuf2[kBbufMax];
1561 int32_t len = udat_format(udfmt, today, ubuf, kUbufMax, NULL, &status);
1563 if ( U_FAILURE(status) ) {
1564 log_err("FAIL: udat_format today for locale %s, capitalizationContext %d, status %s\n",
1565 textRelContextItemPtr->locale, (int)textRelContextItemPtr->capitalizationContext, u_errorName(status) );
1566 } else if (u_strncmp(ubuf, textRelContextItemPtr->expectedFormatToday, kUbufMax) != 0) {
1567 log_err("FAIL: udat_format today for locale %s, capitalizationContext %d, expected %s, got %s\n",
1568 textRelContextItemPtr->locale, (int)textRelContextItemPtr->capitalizationContext,
1569 u_austrncpy(bbuf1,textRelContextItemPtr->expectedFormatToday,kUbufMax), u_austrncpy(bbuf2,ubuf,kUbufMax) );
1571 status = U_ZERO_ERROR;
1572 ucal_setMillis(ucal, today, &status);
1573 ucal_add(ucal, UCAL_DATE, -1, &status);
1574 yesterday = ucal_getMillis(ucal, &status);
1575 if ( U_SUCCESS(status) ) {
1576 len = udat_format(udfmt, yesterday, ubuf, kUbufMax, NULL, &status);
1577 if ( U_FAILURE(status) ) {
1578 log_err("FAIL: udat_format yesterday for locale %s, capitalizationContext %d, status %s\n",
1579 textRelContextItemPtr->locale, (int)textRelContextItemPtr->capitalizationContext, u_errorName(status) );
1580 } else if (u_strncmp(ubuf, textRelContextItemPtr->expectedFormatYesterday, kUbufMax) != 0) {
1581 log_err("FAIL: udat_format yesterday for locale %s, capitalizationContext %d, expected %s, got %s\n",
1582 textRelContextItemPtr->locale, (int)textRelContextItemPtr->capitalizationContext,
1583 u_austrncpy(bbuf1,textRelContextItemPtr->expectedFormatYesterday,kUbufMax), u_austrncpy(bbuf2,ubuf,kUbufMax) );
1587 log_err("FAIL: udat_setContext relative for locale %s, capitalizationContext %d, status %s\n",
1588 textRelContextItemPtr->locale, (int)textRelContextItemPtr->capitalizationContext, u_errorName(status) );
1592 log_data_err("FAIL: udat_open relative for locale %s, status %s\n", textRelContextItemPtr->locale, u_errorName(status) );
1596 log_data_err("FAIL: ucal_open for locale root, status %s\n", u_errorName(status) );
1602 // overrideNumberFormat[i][0] is to tell which field to set,
1603 // overrideNumberFormat[i][1] is the expected result
1604 static const char * overrideNumberFormat[][2] = {
1605 {"", "\\u521D\\u4E03 \\u521D\\u4E8C"},
1606 {"d", "07 \\u521D\\u4E8C"},
1607 {"do", "07 \\u521D\\u4E8C"},
1608 {"Md", "\\u521D\\u4E03 \\u521D\\u4E8C"},
1609 {"MdMMd", "\\u521D\\u4E03 \\u521D\\u4E8C"},
1610 {"mixed", "\\u521D\\u4E03 \\u521D\\u4E8C"}
1613 static void TestOverrideNumberFormat(void) {
1614 UErrorCode status = U_ZERO_ERROR;
1618 char bbuf1[kBbufMax];
1619 char bbuf2[kBbufMax];
1620 const char* localeString = "zh@numbers=hanidays";
1622 const UNumberFormat* getter_result;
1625 u_uastrcpy(fields, "d");
1626 u_uastrcpy(pattern,"MM d");
1628 fmt=udat_open(UDAT_PATTERN, UDAT_PATTERN, "en_US", zoneGMT, -1, pattern, u_strlen(pattern), &status);
1629 if (!assertSuccess("udat_open()", &status)) {
1633 // loop 5 times to check getter/setter
1634 for (i = 0; i < 5; i++){
1635 UNumberFormat* overrideFmt;
1636 overrideFmt = unum_open(UNUM_DEFAULT, NULL, 0, localeString, NULL, &status);
1637 assertSuccess("unum_open()", &status);
1638 udat_adoptNumberFormatForFields(fmt, fields, overrideFmt, &status);
1639 overrideFmt = NULL; // no longer valid
1640 assertSuccess("udat_setNumberFormatForField()", &status);
1642 getter_result = udat_getNumberFormatForField(fmt, 'd');
1643 if(getter_result == NULL) {
1644 log_err("FAIL: udat_getNumberFormatForField did not return a valid pointer\n");
1648 UNumberFormat* overrideFmt;
1649 overrideFmt = unum_open(UNUM_DEFAULT, NULL, 0, localeString, NULL, &status);
1650 assertSuccess("unum_open()", &status);
1651 udat_setNumberFormat(fmt, overrideFmt); // test the same override NF will not crash
1652 unum_close(overrideFmt);
1656 for (i=0; i<UPRV_LENGTHOF(overrideNumberFormat); i++){
1657 UChar ubuf[kUbufMax];
1659 UNumberFormat* overrideFmt2;
1661 fmt2 =udat_open(UDAT_PATTERN, UDAT_PATTERN,"en_US", zoneGMT, -1, pattern, u_strlen(pattern), &status);
1662 assertSuccess("udat_open() with en_US", &status);
1664 overrideFmt2 = unum_open(UNUM_DEFAULT, NULL, 0, localeString, NULL, &status);
1665 assertSuccess("unum_open() in loop", &status);
1667 u_uastrcpy(fields, overrideNumberFormat[i][0]);
1668 u_unescape(overrideNumberFormat[i][1], expected, UPRV_LENGTHOF(expected));
1670 if ( strcmp(overrideNumberFormat[i][0], "") == 0 ) { // use the one w/o field
1671 udat_adoptNumberFormat(fmt2, overrideFmt2);
1672 } else if ( strcmp(overrideNumberFormat[i][0], "mixed") == 0 ) { // set 1 field at first but then full override, both(M & d) should be override
1673 const char* singleLocale = "en@numbers=hebr";
1674 UNumberFormat* singleOverrideFmt;
1675 u_uastrcpy(fields, "d");
1677 singleOverrideFmt = unum_open(UNUM_DEFAULT, NULL, 0, singleLocale, NULL, &status);
1678 assertSuccess("unum_open() in mixed", &status);
1680 udat_adoptNumberFormatForFields(fmt2, fields, singleOverrideFmt, &status);
1681 assertSuccess("udat_setNumberFormatForField() in mixed", &status);
1683 udat_adoptNumberFormat(fmt2, overrideFmt2);
1684 } else if ( strcmp(overrideNumberFormat[i][0], "do") == 0 ) { // o is an invalid field
1685 udat_adoptNumberFormatForFields(fmt2, fields, overrideFmt2, &status);
1686 if(status == U_INVALID_FORMAT_ERROR) {
1688 status = U_ZERO_ERROR;
1692 udat_adoptNumberFormatForFields(fmt2, fields, overrideFmt2, &status);
1693 assertSuccess("udat_setNumberFormatForField() in loop", &status);
1696 udat_format(fmt2, july022008, ubuf, kUbufMax, NULL, &status);
1697 assertSuccess("udat_format() july022008", &status);
1699 if (u_strncmp(ubuf, expected, kUbufMax) != 0)
1700 log_err("fail: udat_format for locale, expected %s, got %s\n",
1701 u_austrncpy(bbuf1,expected,kUbufMax), u_austrncpy(bbuf2,ubuf,kUbufMax) );
1709 * udat_parse and udat_parseCalendar should have the same error code when given the same invalid input.
1711 static void TestParseErrorReturnValue(void) {
1712 UErrorCode status = U_ZERO_ERROR;
1713 UErrorCode expectStatus = U_PARSE_ERROR;
1717 df = udat_open(UDAT_DEFAULT, UDAT_DEFAULT, NULL, NULL, -1, NULL, -1, &status);
1718 if (!assertSuccessCheck("udat_open()", &status, TRUE)) {
1722 cal = ucal_open(NULL, 0, "en_US", UCAL_GREGORIAN, &status);
1723 if (!assertSuccess("ucal_open()", &status)) {
1727 udat_parse(df, NULL, -1, NULL, &status);
1728 if (status != expectStatus) {
1729 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));
1732 status = U_ZERO_ERROR;
1733 udat_parseCalendar(df, cal, NULL, -1, NULL, &status);
1734 if (status != expectStatus) {
1735 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));
1744 * Test new udat_formatForFields, udat_formatCalendarForFields (and UFieldPositionIterator)
1746 static const char localeForFields[] = "en_US";
1747 /* zoneGMT[]defined above */
1748 static const UDate date2015Feb25 = 1424841000000.0; /* Wednesday, February 25, 2015 at 5:10:00 AM GMT */
1755 static const FieldsData expectedFields[] = {
1756 { UDAT_DAY_OF_WEEK_FIELD /* 9*/, 0, 9 },
1757 { UDAT_MONTH_FIELD /* 2*/, 11, 19 },
1758 { UDAT_DATE_FIELD /* 3*/, 20, 22 },
1759 { UDAT_YEAR_FIELD /* 1*/, 24, 28 },
1760 { UDAT_HOUR1_FIELD /*15*/, 32, 33 },
1761 #if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
1762 { UDAT_TIME_SEPARATOR_FIELD /*35*/, 33, 34 },
1764 { UDAT_MINUTE_FIELD /* 6*/, 34, 36 },
1765 #if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
1766 { UDAT_TIME_SEPARATOR_FIELD /*35*/, 36, 37 },
1768 { UDAT_SECOND_FIELD /* 7*/, 37, 39 },
1769 { UDAT_AM_PM_FIELD /*14*/, 40, 42 },
1770 { UDAT_TIMEZONE_FIELD /*17*/, 43, 46 },
1774 enum {kUBufFieldsLen = 128, kBBufFieldsLen = 256 };
1776 static void TestFormatForFields(void) {
1777 UErrorCode status = U_ZERO_ERROR;
1778 UFieldPositionIterator* fpositer = ufieldpositer_open(&status);
1779 if ( U_FAILURE(status) ) {
1780 log_err("ufieldpositer_open fails, status %s\n", u_errorName(status));
1782 UDateFormat* udfmt = udat_open(UDAT_LONG, UDAT_FULL, localeForFields, zoneGMT, -1, NULL, 0, &status);
1783 UCalendar* ucal = ucal_open(zoneGMT, -1, localeForFields, UCAL_DEFAULT, &status);
1784 if ( U_FAILURE(status) ) {
1785 log_data_err("udat_open or ucal_open fails for locale %s, status %s (Are you missing data?)\n", localeForFields, u_errorName(status));
1787 int32_t ulen, field, beginPos, endPos;
1788 UChar ubuf[kUBufFieldsLen];
1789 const FieldsData * fptr;
1791 status = U_ZERO_ERROR;
1792 ulen = udat_formatForFields(udfmt, date2015Feb25, ubuf, kUBufFieldsLen, fpositer, &status);
1793 if ( U_FAILURE(status) ) {
1794 log_err("udat_formatForFields fails, status %s\n", u_errorName(status));
1796 for (fptr = expectedFields; ; fptr++) {
1797 field = ufieldpositer_next(fpositer, &beginPos, &endPos);
1798 if (field != fptr->field || (field >= 0 && (beginPos != fptr->beginPos || endPos != fptr->endPos))) {
1799 if (fptr->field >= 0) {
1800 log_err("udat_formatForFields as \"%s\"; expect field %d range %d-%d, get field %d range %d-%d\n",
1801 aescstrdup(ubuf, ulen), fptr->field, fptr->beginPos, fptr->endPos, field, beginPos, endPos);
1803 log_err("udat_formatForFields as \"%s\"; expect field < 0, get field %d range %d-%d\n",
1804 aescstrdup(ubuf, ulen), field, beginPos, endPos);
1814 ucal_setMillis(ucal, date2015Feb25, &status);
1815 status = U_ZERO_ERROR;
1816 ulen = udat_formatCalendarForFields(udfmt, ucal, ubuf, kUBufFieldsLen, fpositer, &status);
1817 if ( U_FAILURE(status) ) {
1818 log_err("udat_formatCalendarForFields fails, status %s\n", u_errorName(status));
1820 for (fptr = expectedFields; ; fptr++) {
1821 field = ufieldpositer_next(fpositer, &beginPos, &endPos);
1822 if (field != fptr->field || (field >= 0 && (beginPos != fptr->beginPos || endPos != fptr->endPos))) {
1823 if (fptr->field >= 0) {
1824 log_err("udat_formatFudat_formatCalendarForFieldsorFields as \"%s\"; expect field %d range %d-%d, get field %d range %d-%d\n",
1825 aescstrdup(ubuf, ulen), fptr->field, fptr->beginPos, fptr->endPos, field, beginPos, endPos);
1827 log_err("udat_formatCalendarForFields as \"%s\"; expect field < 0, get field %d range %d-%d\n",
1828 aescstrdup(ubuf, ulen), field, beginPos, endPos);
1841 ufieldpositer_close(fpositer);
1845 #endif /* #if !UCONFIG_NO_FORMATTING */