1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /********************************************************************
4 * COPYRIGHT:
5 * Copyright (c) 1997-2016, International Business Machines Corporation and
6 * others. All Rights Reserved.
7 ********************************************************************/
8 /********************************************************************************
9 *
10 * File CDATTST.C
11 *
12 * Modification History:
13 * Name Description
14 * Madhu Katragadda Creation
15 *********************************************************************************
16 */
17
18 /* C API TEST FOR DATE FORMAT */
19
20 #include "unicode/utypes.h"
21
22 #if !UCONFIG_NO_FORMATTING
23
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"
31 #include "cintltst.h"
32 #include "cdattst.h"
33 #include "cformtst.h"
34 #include "cmemory.h"
35
36 #include <math.h>
37
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);
45 static void TestForceGannenNumbering(void);
46
47 void addDateForTest(TestNode** root);
48
49 #define TESTCASE(x) addTest(root, &x, "tsformat/cdattst/" #x)
50
addDateForTest(TestNode ** root)51 void addDateForTest(TestNode** root)
52 {
53 TESTCASE(TestDateFormat);
54 TESTCASE(TestRelativeDateFormat);
55 TESTCASE(TestSymbols);
56 TESTCASE(TestDateFormatCalendar);
57 TESTCASE(TestExtremeDates);
58 TESTCASE(TestAllLocales);
59 TESTCASE(TestRelativeCrash);
60 TESTCASE(TestContext);
61 TESTCASE(TestCalendarDateParse);
62 TESTCASE(TestOverrideNumberFormat);
63 TESTCASE(TestParseErrorReturnValue);
64 TESTCASE(TestFormatForFields);
65 TESTCASE(TestForceGannenNumbering);
66 }
67 /* Testing the DateFormat API */
TestDateFormat()68 static void TestDateFormat()
69 {
70 UDateFormat *def, *fr, *it, *de, *def1, *fr_pat;
71 UDateFormat *any;
72 UDateFormat *copy;
73 UErrorCode status = U_ZERO_ERROR;
74 UChar* result = NULL;
75 const UCalendar *cal;
76 const UNumberFormat *numformat1, *numformat2;
77 UNumberFormat *adoptNF;
78 UChar temp[50];
79 int32_t numlocales;
80 UDate d1;
81 int i;
82 int32_t resultlength;
83 int32_t resultlengthneeded;
84 int32_t parsepos;
85 UDate d = 837039928046.0;
86 double num = -10456.37;
87 /*const char* str="yyyy.MM.dd G 'at' hh:mm:ss z";
88 const char t[]="2/3/76 2:50 AM";*/
89 /*Testing udat_open() to open a dateformat */
90
91 ctest_setTimeZone(NULL, &status);
92
93 log_verbose("\nTesting udat_open() with various parameters\n");
94 fr = udat_open(UDAT_FULL, UDAT_DEFAULT, "fr_FR", NULL,0, NULL, 0,&status);
95 if(U_FAILURE(status))
96 {
97 log_data_err("FAIL: error in creating the dateformat using full time style with french locale -> %s (Are you missing data?)\n",
98 myErrorName(status) );
99 return;
100 }
101 /* this is supposed to open default date format, but later on it treats it like it is "en_US"
102 - very bad if you try to run the tests on machine where default locale is NOT "en_US" */
103 /* def = udat_open(UDAT_SHORT, UDAT_SHORT, NULL, NULL, 0, &status); */
104 def = udat_open(UDAT_SHORT, UDAT_SHORT, "en_US", NULL, 0,NULL, 0, &status);
105 if(U_FAILURE(status))
106 {
107 log_err("FAIL: error in creating the dateformat using short date and time style\n %s\n",
108 myErrorName(status) );
109 return;
110 }
111 it = udat_open(UDAT_DEFAULT, UDAT_MEDIUM, "it_IT", NULL, 0, NULL, 0,&status);
112 if(U_FAILURE(status))
113 {
114 log_err("FAIL: error in creating the dateformat using medium date style with italian locale\n %s\n",
115 myErrorName(status) );
116 return;
117 }
118 de = udat_open(UDAT_LONG, UDAT_LONG, "de_DE", NULL, 0, NULL, 0,&status);
119 if(U_FAILURE(status))
120 {
121 log_err("FAIL: error in creating the dateformat using long time and date styles with german locale\n %s\n",
122 myErrorName(status));
123 return;
124 }
125 /*creating a default dateformat */
126 def1 = udat_open(UDAT_SHORT, UDAT_SHORT, NULL, NULL, 0,NULL, 0, &status);
127 if(U_FAILURE(status))
128 {
129 log_err("FAIL: error in creating the dateformat using short date and time style\n %s\n",
130 myErrorName(status) );
131 return;
132 }
133
134
135 /*Testing udat_getAvailable() and udat_countAvailable()*/
136 log_verbose("\nTesting getAvailableLocales and countAvailable()\n");
137 numlocales=udat_countAvailable();
138 /* use something sensible w/o hardcoding the count */
139 if(numlocales < 0)
140 log_data_err("FAIL: error in countAvailable\n");
141 log_verbose("The number of locales for which date/time formatting patterns are available is %d\n", numlocales);
142
143 for(i=0;i<numlocales;i++) {
144 UErrorCode subStatus = U_ZERO_ERROR;
145 log_verbose("Testing open of %s\n", udat_getAvailable(i));
146 any = udat_open(UDAT_SHORT, UDAT_SHORT, udat_getAvailable(i), NULL ,0, NULL, 0, &subStatus);
147 if(U_FAILURE(subStatus)) {
148 log_data_err("FAIL: date format %s (getAvailable(%d)) is not instantiable: %s\n", udat_getAvailable(i), i, u_errorName(subStatus));
149 }
150 udat_close(any);
151 }
152
153 /*Testing udat_clone()*/
154 log_verbose("\nTesting the udat_clone() function of date format\n");
155 copy=udat_clone(def, &status);
156 if(U_FAILURE(status)){
157 log_err("Error in creating the clone using udat_clone: %s\n", myErrorName(status) );
158 }
159 /*if(def != copy)
160 log_err("Error in udat_clone");*/ /*how should i check for equality???? */
161
162 /*Testing udat_format()*/
163 log_verbose("\nTesting the udat_format() function of date format\n");
164 u_uastrcpy(temp, "7/10/96, 4:05 PM");
165 /*format using def */
166 resultlength=0;
167 resultlengthneeded=udat_format(def, d, NULL, resultlength, NULL, &status);
168 if(status==U_BUFFER_OVERFLOW_ERROR)
169 {
170 status=U_ZERO_ERROR;
171 resultlength=resultlengthneeded+1;
172 if(result != NULL) {
173 free(result);
174 result = NULL;
175 }
176 result=(UChar*)malloc(sizeof(UChar) * resultlength);
177 udat_format(def, d, result, resultlength, NULL, &status);
178 }
179 if(U_FAILURE(status) || !result)
180 {
181 log_err("FAIL: Error in formatting using udat_format(.....) %s\n", myErrorName(status) );
182 return;
183 }
184 else
185 log_verbose("PASS: formatting successful\n");
186 if(u_strcmp(result, temp)==0)
187 log_verbose("PASS: Date Format for US locale successful using udat_format()\n");
188 else {
189 char xbuf[2048];
190 char gbuf[2048];
191 u_austrcpy(xbuf, temp);
192 u_austrcpy(gbuf, result);
193 log_err("FAIL: Date Format for US locale failed using udat_format() - expected %s got %s\n", xbuf, gbuf);
194 }
195 /*format using fr */
196
197 u_unescape("10 juil. 1996 \\u00E0 16:05:28 heure d\\u2019\\u00E9t\\u00E9 du Pacifique", temp, 50);
198 if(result != NULL) {
199 free(result);
200 result = NULL;
201 }
202 result=myDateFormat(fr, d);
203 if(u_strcmp(result, temp)==0)
204 log_verbose("PASS: Date Format for french locale successful using udat_format()\n");
205 else
206 log_data_err("FAIL: Date Format for french locale failed using udat_format().\n" );
207
208 /*format using it */
209 u_uastrcpy(temp, "10 lug 1996, 16:05:28");
210
211 {
212 UChar *fmtted;
213 char g[100];
214 char x[100];
215
216 fmtted = myDateFormat(it,d);
217 u_austrcpy(g, fmtted);
218 u_austrcpy(x, temp);
219 if(u_strcmp(fmtted, temp)==0) {
220 log_verbose("PASS: Date Format for italian locale successful uisng udat_format() - wanted %s, got %s\n", x, g);
221 } else {
222 log_data_err("FAIL: Date Format for italian locale failed using udat_format() - wanted %s, got %s\n", x, g);
223 }
224 }
225
226 /*Testing parsing using udat_parse()*/
227 log_verbose("\nTesting parsing using udat_parse()\n");
228 u_uastrcpy(temp,"2/3/76, 2:50 AM");
229 parsepos=0;
230 status=U_ZERO_ERROR;
231
232 d1=udat_parse(def, temp, u_strlen(temp), &parsepos, &status);
233 if(U_FAILURE(status))
234 {
235 log_err("FAIL: Error in parsing using udat_parse(.....) %s\n", myErrorName(status) );
236 }
237 else
238 log_verbose("PASS: parsing succesful\n");
239 /*format it back and check for equality */
240
241
242 if(u_strcmp(myDateFormat(def, d1),temp)!=0)
243 log_err("FAIL: error in parsing\n");
244
245 /*Testing parsing using udat_parse()*/
246 log_verbose("\nTesting parsing using udat_parse()\n");
247 u_uastrcpy(temp,"2/Don't parse this part");
248 status=U_ZERO_ERROR;
249
250 d1=udat_parse(def, temp, u_strlen(temp), NULL, &status);
251 if(status != U_PARSE_ERROR)
252 {
253 log_err("FAIL: udat_parse(\"bad string\") passed when it should have failed\n");
254 }
255 else
256 log_verbose("PASS: parsing succesful\n");
257
258
259
260 /*Testing udat_openPattern() */
261 status=U_ZERO_ERROR;
262 log_verbose("\nTesting the udat_openPattern with a specified pattern\n");
263 /*for french locale */
264 fr_pat=udat_open(UDAT_PATTERN, UDAT_PATTERN,"fr_FR",NULL,0,temp, u_strlen(temp), &status);
265 if(U_FAILURE(status))
266 {
267 log_err("FAIL: Error in creating a date format using udat_openPattern \n %s\n",
268 myErrorName(status) );
269 }
270 else
271 log_verbose("PASS: creating dateformat using udat_openPattern() succesful\n");
272
273
274 /*Testing applyPattern and toPattern */
275 log_verbose("\nTesting applyPattern and toPattern()\n");
276 udat_applyPattern(def1, FALSE, temp, u_strlen(temp));
277 log_verbose("Extracting the pattern\n");
278
279 resultlength=0;
280 resultlengthneeded=udat_toPattern(def1, FALSE, NULL, resultlength, &status);
281 if(status==U_BUFFER_OVERFLOW_ERROR)
282 {
283 status=U_ZERO_ERROR;
284 resultlength=resultlengthneeded + 1;
285 result=(UChar*)malloc(sizeof(UChar) * resultlength);
286 udat_toPattern(def1, FALSE, result, resultlength, &status);
287 }
288 if(U_FAILURE(status))
289 {
290 log_err("FAIL: error in extracting the pattern from UNumberFormat\n %s\n",
291 myErrorName(status) );
292 }
293 if(u_strcmp(result, temp)!=0)
294 log_err("FAIL: Error in extracting the pattern\n");
295 else
296 log_verbose("PASS: applyPattern and toPattern work fine\n");
297
298 if(result != NULL) {
299 free(result);
300 result = NULL;
301 }
302
303
304 /*Testing getter and setter functions*/
305 /*isLenient and setLenient()*/
306 log_verbose("\nTesting the isLenient and setLenient properties\n");
307 udat_setLenient(fr, udat_isLenient(it));
308 if(udat_isLenient(fr) != udat_isLenient(it))
309 log_err("ERROR: setLenient() failed\n");
310 else
311 log_verbose("PASS: setLenient() successful\n");
312
313
314 /*Test get2DigitYearStart set2DigitYearStart */
315 log_verbose("\nTesting the get and set 2DigitYearStart properties\n");
316 d1= udat_get2DigitYearStart(fr_pat,&status);
317 if(U_FAILURE(status)) {
318 log_err("ERROR: udat_get2DigitYearStart failed %s\n", myErrorName(status) );
319 }
320 status = U_ZERO_ERROR;
321 udat_set2DigitYearStart(def1 ,d1, &status);
322 if(U_FAILURE(status)) {
323 log_err("ERROR: udat_set2DigitYearStart failed %s\n", myErrorName(status) );
324 }
325 if(udat_get2DigitYearStart(fr_pat, &status) != udat_get2DigitYearStart(def1, &status))
326 log_err("FAIL: error in set2DigitYearStart\n");
327 else
328 log_verbose("PASS: set2DigitYearStart successful\n");
329 /*try setting it to another value */
330 udat_set2DigitYearStart(de, 2000.0, &status);
331 if(U_FAILURE(status)){
332 log_verbose("ERROR: udat_set2DigitYearStart failed %s\n", myErrorName(status) );
333 }
334 if(udat_get2DigitYearStart(de, &status) != 2000)
335 log_err("FAIL: error in set2DigitYearStart\n");
336 else
337 log_verbose("PASS: set2DigitYearStart successful\n");
338
339
340
341 /*Test getNumberFormat() and setNumberFormat() */
342 log_verbose("\nTesting the get and set NumberFormat properties of date format\n");
343 numformat1=udat_getNumberFormat(fr_pat);
344 udat_setNumberFormat(def1, numformat1);
345 numformat2=udat_getNumberFormat(def1);
346 if(u_strcmp(myNumformat(numformat1, num), myNumformat(numformat2, num)) !=0)
347 log_err("FAIL: error in setNumberFormat or getNumberFormat()\n");
348 else
349 log_verbose("PASS:setNumberFormat and getNumberFormat succesful\n");
350
351 /*Test getNumberFormat() and adoptNumberFormat() */
352 log_verbose("\nTesting the get and adopt NumberFormat properties of date format\n");
353 adoptNF= unum_open(UNUM_DEFAULT, NULL, 0, NULL, NULL, &status);
354 udat_adoptNumberFormat(def1, adoptNF);
355 numformat2=udat_getNumberFormat(def1);
356 if(u_strcmp(myNumformat(adoptNF, num), myNumformat(numformat2, num)) !=0)
357 log_err("FAIL: error in adoptNumberFormat or getNumberFormat()\n");
358 else
359 log_verbose("PASS:adoptNumberFormat and getNumberFormat succesful\n");
360
361 /*try setting the number format to another format */
362 numformat1=udat_getNumberFormat(def);
363 udat_setNumberFormat(def1, numformat1);
364 numformat2=udat_getNumberFormat(def1);
365 if(u_strcmp(myNumformat(numformat1, num), myNumformat(numformat2, num)) !=0)
366 log_err("FAIL: error in setNumberFormat or getNumberFormat()\n");
367 else
368 log_verbose("PASS: setNumberFormat and getNumberFormat succesful\n");
369
370
371
372 /*Test getCalendar and setCalendar*/
373 log_verbose("\nTesting the udat_getCalendar() and udat_setCalendar() properties\n");
374 cal=udat_getCalendar(fr_pat);
375
376
377 udat_setCalendar(def1, cal);
378 if(!ucal_equivalentTo(udat_getCalendar(fr_pat), udat_getCalendar(def1)))
379 log_err("FAIL: Error in setting and getting the calendar\n");
380 else
381 log_verbose("PASS: getting and setting calendar successful\n");
382
383 if(result!=NULL) {
384 free(result);
385 }
386
387 /*Closing the UDateForamt */
388 udat_close(def);
389 udat_close(fr);
390 udat_close(it);
391 udat_close(de);
392 udat_close(def1);
393 udat_close(fr_pat);
394 udat_close(copy);
395
396 ctest_resetTimeZone();
397 }
398
399 /*
400 Test combined relative date formatting (relative date + non-relative time).
401 This is a bit tricky since we can't have static test data for comparison, the
402 relative date formatting is relative to the time the tests are run. We generate
403 the data for comparison dynamically. However, the tests could fail if they are
404 run right at midnight Pacific time and the call to ucal_getNow() is before midnight
405 while the calls to udat_format are after midnight or span midnight.
406 */
407 static const UDate dayInterval = 24.0*60.0*60.0*1000.0;
408 static const UChar trdfZone[] = { 0x0055, 0x0053, 0x002F, 0x0050, 0x0061, 0x0063, 0x0069, 0x0066, 0x0069, 0x0063, 0 }; /* US/Pacific */
409 static const char trdfLocale[] = "en_US";
410 static const UChar minutesPatn[] = { 0x006D, 0x006D, 0 }; /* "mm" */
411 static const UChar monthLongPatn[] = { 0x004D, 0x004D, 0x004D, 0x004D, 0 }; /* "MMMM" */
412 static const UChar monthMediumPatn[] = { 0x004D, 0x004D, 0x004D, 0 }; /* "MMM" */
413 static const UChar monthShortPatn[] = { 0x004D, 0 }; /* "M" */
414 static const UDateFormatStyle dateStylesList[] = { UDAT_FULL, UDAT_LONG, UDAT_MEDIUM, UDAT_SHORT, UDAT_NONE };
415 static const UChar *monthPatnsList[] = { monthLongPatn, monthLongPatn, monthMediumPatn, monthShortPatn, NULL };
416 static const UChar newTimePatn[] = { 0x0048, 0x0048, 0x002C, 0x006D, 0x006D, 0 }; /* "HH,mm" */
417 static const UChar minutesStr[] = { 0x0034, 0x0039, 0 }; /* "49", minutes string to search for in output */
418 enum { kDateOrTimeOutMax = 96, kDateAndTimeOutMax = 192 };
419
420 static const UDate minutesTolerance = 2 * 60.0 * 1000.0;
421 static const UDate daysTolerance = 2 * 24.0 * 60.0 * 60.0 * 1000.0;
422
TestRelativeDateFormat()423 static void TestRelativeDateFormat()
424 {
425 UDate today = 0.0;
426 const UDateFormatStyle * stylePtr;
427 const UChar ** monthPtnPtr;
428 UErrorCode status = U_ZERO_ERROR;
429 UCalendar * ucal = ucal_open(trdfZone, -1, trdfLocale, UCAL_GREGORIAN, &status);
430 if ( U_SUCCESS(status) ) {
431 int32_t year, month, day;
432 ucal_setMillis(ucal, ucal_getNow(), &status);
433 year = ucal_get(ucal, UCAL_YEAR, &status);
434 month = ucal_get(ucal, UCAL_MONTH, &status);
435 day = ucal_get(ucal, UCAL_DATE, &status);
436 ucal_setDateTime(ucal, year, month, day, 18, 49, 0, &status); /* set to today at 18:49:00 */
437 today = ucal_getMillis(ucal, &status);
438 ucal_close(ucal);
439 }
440 if ( U_FAILURE(status) || today == 0.0 ) {
441 log_data_err("Generate UDate for a specified time today fails, error %s - (Are you missing data?)\n", myErrorName(status) );
442 return;
443 }
444 for (stylePtr = dateStylesList, monthPtnPtr = monthPatnsList; *stylePtr != UDAT_NONE; ++stylePtr, ++monthPtnPtr) {
445 UDateFormat* fmtRelDateTime;
446 UDateFormat* fmtRelDate;
447 UDateFormat* fmtTime;
448 int32_t dayOffset, limit;
449 UFieldPosition fp;
450 UChar strDateTime[kDateAndTimeOutMax];
451 UChar strDate[kDateOrTimeOutMax];
452 UChar strTime[kDateOrTimeOutMax];
453 UChar * strPtr;
454 int32_t dtpatLen;
455
456 fmtRelDateTime = udat_open(UDAT_SHORT, *stylePtr | UDAT_RELATIVE, trdfLocale, trdfZone, -1, NULL, 0, &status);
457 if ( U_FAILURE(status) ) {
458 log_data_err("udat_open timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s (Are you missing data?)\n", *stylePtr, myErrorName(status) );
459 continue;
460 }
461 fmtRelDate = udat_open(UDAT_NONE, *stylePtr | UDAT_RELATIVE, trdfLocale, trdfZone, -1, NULL, 0, &status);
462 if ( U_FAILURE(status) ) {
463 log_err("udat_open timeStyle NONE dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
464 udat_close(fmtRelDateTime);
465 continue;
466 }
467 fmtTime = udat_open(UDAT_SHORT, UDAT_NONE, trdfLocale, trdfZone, -1, NULL, 0, &status);
468 if ( U_FAILURE(status) ) {
469 log_err("udat_open timeStyle SHORT dateStyle NONE fails, error %s\n", myErrorName(status) );
470 udat_close(fmtRelDateTime);
471 udat_close(fmtRelDate);
472 continue;
473 }
474
475 dtpatLen = udat_toPatternRelativeDate(fmtRelDateTime, strDate, kDateAndTimeOutMax, &status);
476 if ( U_FAILURE(status) ) {
477 log_err("udat_toPatternRelativeDate timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
478 status = U_ZERO_ERROR;
479 } else if ( u_strstr(strDate, *monthPtnPtr) == NULL || dtpatLen != u_strlen(strDate) ) {
480 log_err("udat_toPatternRelativeDate timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) date pattern incorrect\n", *stylePtr );
481 }
482 dtpatLen = udat_toPatternRelativeTime(fmtRelDateTime, strTime, kDateAndTimeOutMax, &status);
483 if ( U_FAILURE(status) ) {
484 log_err("udat_toPatternRelativeTime timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
485 status = U_ZERO_ERROR;
486 } else if ( u_strstr(strTime, minutesPatn) == NULL || dtpatLen != u_strlen(strTime) ) {
487 log_err("udat_toPatternRelativeTime timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) time pattern incorrect\n", *stylePtr );
488 }
489 dtpatLen = udat_toPattern(fmtRelDateTime, FALSE, strDateTime, kDateAndTimeOutMax, &status);
490 if ( U_FAILURE(status) ) {
491 log_err("udat_toPattern timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
492 status = U_ZERO_ERROR;
493 } else if ( u_strstr(strDateTime, strDate) == NULL || u_strstr(strDateTime, strTime) == NULL || dtpatLen != u_strlen(strDateTime) ) {
494 log_err("udat_toPattern timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) dateTime pattern incorrect\n", *stylePtr );
495 }
496 udat_applyPatternRelative(fmtRelDateTime, strDate, u_strlen(strDate), newTimePatn, u_strlen(newTimePatn), &status);
497 if ( U_FAILURE(status) ) {
498 log_err("udat_applyPatternRelative timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
499 status = U_ZERO_ERROR;
500 } else {
501 udat_toPattern(fmtRelDateTime, FALSE, strDateTime, kDateAndTimeOutMax, &status);
502 if ( U_FAILURE(status) ) {
503 log_err("udat_toPattern timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
504 status = U_ZERO_ERROR;
505 } else if ( u_strstr(strDateTime, newTimePatn) == NULL ) {
506 log_err("udat_applyPatternRelative timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) didn't update time pattern\n", *stylePtr );
507 }
508 }
509 udat_applyPatternRelative(fmtRelDateTime, strDate, u_strlen(strDate), strTime, u_strlen(strTime), &status); /* restore original */
510
511 fp.field = UDAT_MINUTE_FIELD;
512 for (dayOffset = -2, limit = 2; dayOffset <= limit; ++dayOffset) {
513 UDate dateToUse = today + (float)dayOffset*dayInterval;
514
515 udat_format(fmtRelDateTime, dateToUse, strDateTime, kDateAndTimeOutMax, &fp, &status);
516 if ( U_FAILURE(status) ) {
517 log_err("udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
518 status = U_ZERO_ERROR;
519 } else {
520 int32_t parsePos = 0;
521 UDate dateResult = udat_parse(fmtRelDateTime, strDateTime, -1, &parsePos, &status);
522 UDate dateDiff = (dateResult >= dateToUse)? dateResult - dateToUse: dateToUse - dateResult;
523 if ( U_FAILURE(status) || dateDiff > minutesTolerance ) {
524 log_err("udat_parse timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s, expect approx %.1f, got %.1f, parsePos %d\n",
525 *stylePtr, myErrorName(status), dateToUse, dateResult, parsePos );
526 status = U_ZERO_ERROR;
527 }
528
529 udat_format(fmtRelDate, dateToUse, strDate, kDateOrTimeOutMax, NULL, &status);
530 if ( U_FAILURE(status) ) {
531 log_err("udat_format timeStyle NONE dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
532 status = U_ZERO_ERROR;
533 } else if ( u_strstr(strDateTime, strDate) == NULL ) {
534 log_err("relative date string not found in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", *stylePtr );
535 } else {
536 parsePos = 0;
537 dateResult = udat_parse(fmtRelDate, strDate, -1, &parsePos, &status);
538 dateDiff = (dateResult >= dateToUse)? dateResult - dateToUse: dateToUse - dateResult;
539 if ( U_FAILURE(status) || dateDiff > daysTolerance ) {
540 log_err("udat_parse timeStyle NONE dateStyle (%d | UDAT_RELATIVE) fails, error %s, expect approx %.1f, got %.1f, parsePos %d\n",
541 *stylePtr, myErrorName(status), dateToUse, dateResult, parsePos );
542 status = U_ZERO_ERROR;
543 }
544 }
545
546 udat_format(fmtTime, dateToUse, strTime, kDateOrTimeOutMax, NULL, &status);
547 if ( U_FAILURE(status) ) {
548 log_err("udat_format timeStyle SHORT dateStyle NONE fails, error %s\n", myErrorName(status) );
549 status = U_ZERO_ERROR;
550 } else if ( u_strstr(strDateTime, strTime) == NULL ) {
551 log_err("time string not found in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", *stylePtr );
552 }
553
554 strPtr = u_strstr(strDateTime, minutesStr);
555 if ( strPtr != NULL ) {
556 int32_t beginIndex = (int32_t)(strPtr - strDateTime);
557 if ( fp.beginIndex != beginIndex ) {
558 log_err("UFieldPosition beginIndex %d, expected %d, in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", fp.beginIndex, beginIndex, *stylePtr );
559 }
560 } else {
561 log_err("minutes string not found in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", *stylePtr );
562 }
563 }
564 }
565
566 udat_close(fmtRelDateTime);
567 udat_close(fmtRelDate);
568 udat_close(fmtTime);
569 }
570 }
571
572 /*Testing udat_getSymbols() and udat_setSymbols() and udat_countSymbols()*/
TestSymbols()573 static void TestSymbols()
574 {
575 UDateFormat *def, *fr, *zhChiCal;
576 UErrorCode status = U_ZERO_ERROR;
577 UChar *value=NULL;
578 UChar *result = NULL;
579 int32_t resultlength;
580 int32_t resultlengthout;
581 UChar *pattern;
582
583
584 /*creating a dateformat with french locale */
585 log_verbose("\ncreating a date format with french locale\n");
586 fr = udat_open(UDAT_FULL, UDAT_DEFAULT, "fr_FR", NULL, 0, NULL, 0, &status);
587 if(U_FAILURE(status))
588 {
589 log_data_err("error in creating the dateformat using full time style with french locale -> %s (Are you missing data?)\n",
590 myErrorName(status) );
591 return;
592 }
593 /*creating a default dateformat */
594 log_verbose("\ncreating a date format with default locale\n");
595 /* this is supposed to open default date format, but later on it treats it like it is "en_US"
596 - very bad if you try to run the tests on machine where default locale is NOT "en_US" */
597 /* def = udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,NULL, NULL, 0, &status); */
598 def = udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,"en_US", NULL, 0, NULL, 0, &status);
599 if(U_FAILURE(status))
600 {
601 log_err("error in creating the dateformat using short date and time style\n %s\n",
602 myErrorName(status) );
603 return;
604 }
605 /*creating a dateformat with zh locale */
606 log_verbose("\ncreating a date format with zh locale for chinese calendar\n");
607 zhChiCal = udat_open(UDAT_NONE, UDAT_FULL, "zh@calendar=chinese", NULL, 0, NULL, 0, &status);
608 if(U_FAILURE(status))
609 {
610 log_data_err("error in creating the dateformat using full date, no time, locale zh@calendar=chinese -> %s (Are you missing data?)\n",
611 myErrorName(status) );
612 return;
613 }
614
615
616 /*Testing countSymbols, getSymbols and setSymbols*/
617 log_verbose("\nTesting countSymbols\n");
618 /*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 */
619 if(udat_countSymbols(def, UDAT_ERAS)!=2 || udat_countSymbols(def, UDAT_MONTHS)!=12 ||
620 udat_countSymbols(def, UDAT_SHORT_MONTHS)!=12 || udat_countSymbols(def, UDAT_WEEKDAYS)!=8 ||
621 udat_countSymbols(def, UDAT_SHORT_WEEKDAYS)!=8 || udat_countSymbols(def, UDAT_AM_PMS)!=2 ||
622 udat_countSymbols(def, UDAT_QUARTERS) != 4 || udat_countSymbols(def, UDAT_SHORT_QUARTERS) != 4 ||
623 udat_countSymbols(def, UDAT_LOCALIZED_CHARS)!=1 || udat_countSymbols(def, UDAT_SHORTER_WEEKDAYS)!=8 ||
624 udat_countSymbols(zhChiCal, UDAT_CYCLIC_YEARS_NARROW)!=60 || udat_countSymbols(zhChiCal, UDAT_ZODIAC_NAMES_NARROW)!=12)
625 {
626 log_err("FAIL: error in udat_countSymbols\n");
627 }
628 else
629 log_verbose("PASS: udat_countSymbols() successful\n");
630
631 /*testing getSymbols*/
632 log_verbose("\nTesting getSymbols\n");
633 pattern=(UChar*)malloc(sizeof(UChar) * 10);
634 u_uastrcpy(pattern, "jeudi");
635 resultlength=0;
636 resultlengthout=udat_getSymbols(fr, UDAT_WEEKDAYS, 5 , NULL, resultlength, &status);
637 if(status==U_BUFFER_OVERFLOW_ERROR)
638 {
639 status=U_ZERO_ERROR;
640 resultlength=resultlengthout+1;
641 if(result != NULL) {
642 free(result);
643 result = NULL;
644 }
645 result=(UChar*)malloc(sizeof(UChar) * resultlength);
646 udat_getSymbols(fr, UDAT_WEEKDAYS, 5, result, resultlength, &status);
647
648 }
649 if(U_FAILURE(status))
650 {
651 log_err("FAIL: Error in udat_getSymbols().... %s\n", myErrorName(status) );
652 }
653 else
654 log_verbose("PASS: getSymbols succesful\n");
655
656 if(u_strcmp(result, pattern)==0)
657 log_verbose("PASS: getSymbols retrieved the right value\n");
658 else
659 log_data_err("FAIL: getSymbols retrieved the wrong value\n");
660
661 /*run series of tests to test getsymbols regressively*/
662 log_verbose("\nTesting getSymbols() regressively\n");
663 VerifygetSymbols(fr, UDAT_WEEKDAYS, 1, "dimanche");
664 VerifygetSymbols(def, UDAT_WEEKDAYS, 1, "Sunday");
665 VerifygetSymbols(fr, UDAT_SHORT_WEEKDAYS, 7, "sam.");
666 VerifygetSymbols(fr, UDAT_SHORTER_WEEKDAYS, 7, "sa");
667 VerifygetSymbols(def, UDAT_SHORT_WEEKDAYS, 7, "Sat");
668 VerifygetSymbols(def, UDAT_MONTHS, 11, "December");
669 VerifygetSymbols(def, UDAT_MONTHS, 0, "January");
670 VerifygetSymbols(fr, UDAT_ERAS, 0, "av. J.-C.");
671 VerifygetSymbols(def, UDAT_AM_PMS, 0, "AM");
672 VerifygetSymbols(def, UDAT_AM_PMS, 1, "PM");
673 VerifygetSymbols(fr, UDAT_SHORT_MONTHS, 0, "janv.");
674 VerifygetSymbols(def, UDAT_SHORT_MONTHS, 11, "Dec");
675 VerifygetSymbols(fr, UDAT_QUARTERS, 0, "1er trimestre");
676 VerifygetSymbols(def, UDAT_QUARTERS, 3, "4th quarter");
677 VerifygetSymbols(fr, UDAT_SHORT_QUARTERS, 1, "T2");
678 VerifygetSymbols(def, UDAT_SHORT_QUARTERS, 2, "Q3");
679 VerifygetSymbols(zhChiCal, UDAT_CYCLIC_YEARS_ABBREVIATED, 0, "\\u7532\\u5B50");
680 VerifygetSymbols(zhChiCal, UDAT_CYCLIC_YEARS_NARROW, 59, "\\u7678\\u4EA5");
681 VerifygetSymbols(zhChiCal, UDAT_ZODIAC_NAMES_ABBREVIATED, 0, "\\u9F20");
682 VerifygetSymbols(zhChiCal, UDAT_ZODIAC_NAMES_WIDE, 11, "\\u732A");
683 #if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
684 VerifygetSymbols(def,UDAT_LOCALIZED_CHARS, 0, "GyMdkHmsSEDFwWahKzYeugAZvcLQqVUOXxrbB:");
685 #else
686 VerifygetSymbols(def,UDAT_LOCALIZED_CHARS, 0, "GyMdkHmsSEDFwWahKzYeugAZvcLQqVUOXxrbB");
687 #endif
688
689
690 if(result != NULL) {
691 free(result);
692 result = NULL;
693 }
694 free(pattern);
695
696 log_verbose("\nTesting setSymbols\n");
697 /*applying the pattern so that setSymbolss works */
698 resultlength=0;
699 resultlengthout=udat_toPattern(fr, FALSE, NULL, resultlength, &status);
700 if(status==U_BUFFER_OVERFLOW_ERROR)
701 {
702 status=U_ZERO_ERROR;
703 resultlength=resultlengthout + 1;
704 pattern=(UChar*)malloc(sizeof(UChar) * resultlength);
705 udat_toPattern(fr, FALSE, pattern, resultlength, &status);
706 }
707 if(U_FAILURE(status))
708 {
709 log_err("FAIL: error in extracting the pattern from UNumberFormat\n %s\n",
710 myErrorName(status) );
711 }
712
713 udat_applyPattern(def, FALSE, pattern, u_strlen(pattern));
714 resultlength=0;
715 resultlengthout=udat_toPattern(def, FALSE, NULL, resultlength,&status);
716 if(status==U_BUFFER_OVERFLOW_ERROR)
717 {
718 status=U_ZERO_ERROR;
719 resultlength=resultlengthout + 1;
720 if(result != NULL) {
721 free(result);
722 result = NULL;
723 }
724 result=(UChar*)malloc(sizeof(UChar) * resultlength);
725 udat_toPattern(fr, FALSE,result, resultlength, &status);
726 }
727 if(U_FAILURE(status))
728 {
729 log_err("FAIL: error in extracting the pattern from UNumberFormat\n %s\n",
730 myErrorName(status) );
731 }
732 if(u_strcmp(result, pattern)==0)
733 log_verbose("Pattern applied properly\n");
734 else
735 log_err("pattern could not be applied properly\n");
736
737 free(pattern);
738 /*testing set symbols */
739 resultlength=0;
740 resultlengthout=udat_getSymbols(fr, UDAT_MONTHS, 11 , NULL, resultlength, &status);
741 if(status==U_BUFFER_OVERFLOW_ERROR){
742 status=U_ZERO_ERROR;
743 resultlength=resultlengthout+1;
744 if(result != NULL) {
745 free(result);
746 result = NULL;
747 }
748 result=(UChar*)malloc(sizeof(UChar) * resultlength);
749 udat_getSymbols(fr, UDAT_MONTHS, 11, result, resultlength, &status);
750
751 }
752 if(U_FAILURE(status))
753 log_err("FAIL: error in getSymbols() %s\n", myErrorName(status) );
754 resultlength=resultlengthout+1;
755
756 udat_setSymbols(def, UDAT_MONTHS, 11, result, resultlength, &status);
757 if(U_FAILURE(status))
758 {
759 log_err("FAIL: Error in udat_setSymbols() : %s\n", myErrorName(status) );
760 }
761 else
762 log_verbose("PASS: SetSymbols successful\n");
763
764 resultlength=0;
765 resultlengthout=udat_getSymbols(def, UDAT_MONTHS, 11, NULL, resultlength, &status);
766 if(status==U_BUFFER_OVERFLOW_ERROR){
767 status=U_ZERO_ERROR;
768 resultlength=resultlengthout+1;
769 value=(UChar*)malloc(sizeof(UChar) * resultlength);
770 udat_getSymbols(def, UDAT_MONTHS, 11, value, resultlength, &status);
771 }
772 if(U_FAILURE(status))
773 log_err("FAIL: error in retrieving the value using getSymbols i.e roundtrip\n");
774
775 if(u_strcmp(result, value)!=0)
776 log_data_err("FAIL: Error in settting and getting symbols\n");
777 else
778 log_verbose("PASS: setSymbols successful\n");
779
780
781 /*run series of tests to test setSymbols regressively*/
782 log_verbose("\nTesting setSymbols regressively\n");
783 VerifysetSymbols(def, UDAT_ERAS, 0, "BeforeChrist");
784 VerifysetSymbols(def, UDAT_ERA_NAMES, 1, "AnnoDomini");
785 VerifysetSymbols(def, UDAT_WEEKDAYS, 1, "Sundayweek");
786 VerifysetSymbols(def, UDAT_SHORT_WEEKDAYS, 7, "Satweek");
787 VerifysetSymbols(def, UDAT_NARROW_WEEKDAYS, 4, "M");
788 VerifysetSymbols(def, UDAT_STANDALONE_WEEKDAYS, 1, "Sonntagweek");
789 VerifysetSymbols(def, UDAT_STANDALONE_SHORT_WEEKDAYS, 7, "Sams");
790 VerifysetSymbols(def, UDAT_STANDALONE_NARROW_WEEKDAYS, 4, "V");
791 VerifysetSymbols(fr, UDAT_MONTHS, 11, "december");
792 VerifysetSymbols(fr, UDAT_SHORT_MONTHS, 0, "Jan");
793 VerifysetSymbols(fr, UDAT_NARROW_MONTHS, 1, "R");
794 VerifysetSymbols(fr, UDAT_STANDALONE_MONTHS, 11, "dezember");
795 VerifysetSymbols(fr, UDAT_STANDALONE_SHORT_MONTHS, 7, "Aug");
796 VerifysetSymbols(fr, UDAT_STANDALONE_NARROW_MONTHS, 2, "M");
797 VerifysetSymbols(fr, UDAT_QUARTERS, 0, "1. Quart");
798 VerifysetSymbols(fr, UDAT_SHORT_QUARTERS, 1, "QQ2");
799 VerifysetSymbols(fr, UDAT_STANDALONE_QUARTERS, 2, "3rd Quar.");
800 VerifysetSymbols(fr, UDAT_STANDALONE_SHORT_QUARTERS, 3, "4QQ");
801 VerifysetSymbols(zhChiCal, UDAT_CYCLIC_YEARS_ABBREVIATED, 1, "yi-chou");
802 VerifysetSymbols(zhChiCal, UDAT_ZODIAC_NAMES_ABBREVIATED, 1, "Ox");
803
804
805 /*run series of tests to test get and setSymbols regressively*/
806 log_verbose("\nTesting get and set symbols regressively\n");
807 VerifygetsetSymbols(fr, def, UDAT_WEEKDAYS, 1);
808 VerifygetsetSymbols(fr, def, UDAT_WEEKDAYS, 7);
809 VerifygetsetSymbols(fr, def, UDAT_SHORT_WEEKDAYS, 1);
810 VerifygetsetSymbols(fr, def, UDAT_SHORT_WEEKDAYS, 7);
811 VerifygetsetSymbols(fr, def, UDAT_MONTHS, 0);
812 VerifygetsetSymbols(fr, def, UDAT_SHORT_MONTHS, 0);
813 VerifygetsetSymbols(fr, def, UDAT_ERAS,1);
814 VerifygetsetSymbols(fr, def, UDAT_LOCALIZED_CHARS, 0);
815 VerifygetsetSymbols(fr, def, UDAT_AM_PMS, 1);
816
817
818 /*closing*/
819
820 udat_close(fr);
821 udat_close(def);
822 udat_close(zhChiCal);
823 if(result != NULL) {
824 free(result);
825 result = NULL;
826 }
827 free(value);
828
829 }
830
831 /**
832 * Test DateFormat(Calendar) API
833 */
TestDateFormatCalendar()834 static void TestDateFormatCalendar() {
835 UDateFormat *date=0, *time=0, *full=0;
836 UCalendar *cal=0;
837 UChar buf[256];
838 char cbuf[256];
839 int32_t pos;
840 UDate when;
841 UErrorCode ec = U_ZERO_ERROR;
842 UChar buf1[256];
843 int32_t len1;
844 const char *expected;
845 UChar uExpected[32];
846
847 ctest_setTimeZone(NULL, &ec);
848
849 /* Create a formatter for date fields. */
850 date = udat_open(UDAT_NONE, UDAT_SHORT, "en_US", NULL, 0, NULL, 0, &ec);
851 if (U_FAILURE(ec)) {
852 log_data_err("FAIL: udat_open(NONE, SHORT, en_US) failed with %s (Are you missing data?)\n",
853 u_errorName(ec));
854 goto FAIL;
855 }
856
857 /* Create a formatter for time fields. */
858 time = udat_open(UDAT_SHORT, UDAT_NONE, "en_US", NULL, 0, NULL, 0, &ec);
859 if (U_FAILURE(ec)) {
860 log_err("FAIL: udat_open(SHORT, NONE, en_US) failed with %s\n",
861 u_errorName(ec));
862 goto FAIL;
863 }
864
865 /* Create a full format for output */
866 full = udat_open(UDAT_FULL, UDAT_FULL, "en_US", NULL, 0, NULL, 0, &ec);
867 if (U_FAILURE(ec)) {
868 log_err("FAIL: udat_open(FULL, FULL, en_US) failed with %s\n",
869 u_errorName(ec));
870 goto FAIL;
871 }
872
873 /* Create a calendar */
874 cal = ucal_open(NULL, 0, "en_US", UCAL_GREGORIAN, &ec);
875 if (U_FAILURE(ec)) {
876 log_err("FAIL: ucal_open(en_US) failed with %s\n",
877 u_errorName(ec));
878 goto FAIL;
879 }
880
881 /* Parse the date */
882 ucal_clear(cal);
883 u_uastrcpy(buf, "4/5/2001");
884 pos = 0;
885 udat_parseCalendar(date, cal, buf, -1, &pos, &ec);
886 if (U_FAILURE(ec)) {
887 log_err("FAIL: udat_parseCalendar(4/5/2001) failed at %d with %s\n",
888 pos, u_errorName(ec));
889 goto FAIL;
890 }
891
892 /* Check if formatCalendar matches the original date */
893 len1 = udat_formatCalendar(date, cal, buf1, UPRV_LENGTHOF(buf1), NULL, &ec);
894 if (U_FAILURE(ec)) {
895 log_err("FAIL: udat_formatCalendar(4/5/2001) failed with %s\n",
896 u_errorName(ec));
897 goto FAIL;
898 }
899 expected = "4/5/01";
900 u_uastrcpy(uExpected, expected);
901 if (u_strlen(uExpected) != len1 || u_strncmp(uExpected, buf1, len1) != 0) {
902 log_err("FAIL: udat_formatCalendar(4/5/2001), expected: %s", expected);
903 }
904
905 /* Parse the time */
906 u_uastrcpy(buf, "5:45 PM");
907 pos = 0;
908 udat_parseCalendar(time, cal, buf, -1, &pos, &ec);
909 if (U_FAILURE(ec)) {
910 log_err("FAIL: udat_parseCalendar(17:45) failed at %d with %s\n",
911 pos, u_errorName(ec));
912 goto FAIL;
913 }
914
915 /* Check if formatCalendar matches the original time */
916 len1 = udat_formatCalendar(time, cal, buf1, UPRV_LENGTHOF(buf1), NULL, &ec);
917 if (U_FAILURE(ec)) {
918 log_err("FAIL: udat_formatCalendar(17:45) failed with %s\n",
919 u_errorName(ec));
920 goto FAIL;
921 }
922 expected = "5:45 PM";
923 u_uastrcpy(uExpected, expected);
924 if (u_strlen(uExpected) != len1 || u_strncmp(uExpected, buf1, len1) != 0) {
925 log_err("FAIL: udat_formatCalendar(17:45), expected: %s", expected);
926 }
927
928 /* Check result */
929 when = ucal_getMillis(cal, &ec);
930 if (U_FAILURE(ec)) {
931 log_err("FAIL: ucal_getMillis() failed with %s\n", u_errorName(ec));
932 goto FAIL;
933 }
934 udat_format(full, when, buf, sizeof(buf), NULL, &ec);
935 if (U_FAILURE(ec)) {
936 log_err("FAIL: udat_format() failed with %s\n", u_errorName(ec));
937 goto FAIL;
938 }
939 u_austrcpy(cbuf, buf);
940 /* Thursday, April 5, 2001 5:45:00 PM PDT 986517900000 */
941 if (when == 986517900000.0) {
942 log_verbose("Ok: Parsed result: %s\n", cbuf);
943 } else {
944 log_err("FAIL: Parsed result: %s, exp 4/5/2001 5:45 PM\n", cbuf);
945 }
946
947 FAIL:
948 udat_close(date);
949 udat_close(time);
950 udat_close(full);
951 ucal_close(cal);
952
953 ctest_resetTimeZone();
954 }
955
956
957
958 /**
959 * Test parsing two digit year against "YY" vs. "YYYY" patterns
960 */
TestCalendarDateParse()961 static void TestCalendarDateParse() {
962
963 int32_t result;
964 UErrorCode ec = U_ZERO_ERROR;
965 UDateFormat* simpleDateFormat = 0;
966 int32_t parsePos = 0;
967 int32_t twoDigitCenturyStart = 75;
968 int32_t currentTwoDigitYear = 0;
969 int32_t startCentury = 0;
970 UCalendar* tempCal = 0;
971 UCalendar* calendar = 0;
972
973 U_STRING_DECL(pattern, "yyyy", 4);
974 U_STRING_DECL(pattern2, "yy", 2);
975 U_STRING_DECL(text, "75", 2);
976
977 U_STRING_INIT(pattern, "yyyy", 4);
978 U_STRING_INIT(pattern2, "yy", 2);
979 U_STRING_INIT(text, "75", 2);
980
981 simpleDateFormat = udat_open(UDAT_FULL, UDAT_FULL, "en-GB", 0, 0, 0, 0, &ec);
982 if (U_FAILURE(ec)) {
983 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 return;
985 }
986 udat_applyPattern(simpleDateFormat, 0, pattern, u_strlen(pattern));
987 udat_setLenient(simpleDateFormat, 0);
988
989 currentTwoDigitYear = getCurrentYear() % 100;
990 startCentury = getCurrentYear() - currentTwoDigitYear;
991 if (twoDigitCenturyStart > currentTwoDigitYear) {
992 startCentury -= 100;
993 }
994 tempCal = ucal_open(NULL, -1, NULL, UCAL_GREGORIAN, &ec);
995 ucal_setMillis(tempCal, 0, &ec);
996 ucal_setDateTime(tempCal, startCentury + twoDigitCenturyStart, UCAL_JANUARY, 1, 0, 0, 0, &ec);
997 udat_set2DigitYearStart(simpleDateFormat, ucal_getMillis(tempCal, &ec), &ec);
998
999 calendar = ucal_open(NULL, -1, NULL, UCAL_GREGORIAN, &ec);
1000 ucal_setMillis(calendar, 0, &ec);
1001 ucal_setDateTime(calendar, twoDigitCenturyStart, UCAL_JANUARY, 1, 0, 0, 0, &ec);
1002
1003 udat_parseCalendar(simpleDateFormat, calendar, text, u_strlen(text), &parsePos, &ec);
1004
1005 /* Check result */
1006 result = ucal_get(calendar, UCAL_YEAR, &ec);
1007 if (U_FAILURE(ec)) {
1008 log_err("FAIL: ucal_get(UCAL_YEAR) failed with %s\n", u_errorName(ec));
1009 goto FAIL;
1010 }
1011
1012 if (result != 75) {
1013 log_err("FAIL: parsed incorrect year: %d\n", result);
1014 goto FAIL;
1015 }
1016
1017 parsePos = 0;
1018 udat_applyPattern(simpleDateFormat, 0, pattern2, u_strlen(pattern2));
1019 udat_parseCalendar(simpleDateFormat, calendar, text, u_strlen(text), &parsePos, &ec);
1020
1021 /* Check result */
1022 result = ucal_get(calendar, UCAL_YEAR, &ec);
1023 if (U_FAILURE(ec)) {
1024 log_err("FAIL: ucal_get(UCAL_YEAR) failed with %s\n", u_errorName(ec));
1025 goto FAIL;
1026 }
1027
1028 if (result != 1975) {
1029 log_err("FAIL: parsed incorrect year: %d\n", result);
1030 goto FAIL;
1031 }
1032
1033 FAIL:
1034 udat_close(simpleDateFormat);
1035 udat_close(tempCal);
1036 udat_close(calendar);
1037 }
1038
1039
1040 /*INTERNAL FUNCTIONS USED*/
getCurrentYear()1041 static int getCurrentYear() {
1042 static int currentYear = 0;
1043 if (currentYear == 0) {
1044 UErrorCode status = U_ZERO_ERROR;
1045 UCalendar *cal = ucal_open(NULL, -1, NULL, UCAL_GREGORIAN, &status);
1046 if (!U_FAILURE(status)) {
1047 /* Get the current year from the default UCalendar */
1048 currentYear = ucal_get(cal, UCAL_YEAR, &status);
1049 ucal_close(cal);
1050 }
1051 }
1052
1053 return currentYear;
1054 }
1055
1056 /* N.B.: use idx instead of index to avoid 'shadow' warnings in strict mode. */
VerifygetSymbols(UDateFormat * datfor,UDateFormatSymbolType type,int32_t idx,const char * expected)1057 static void VerifygetSymbols(UDateFormat* datfor, UDateFormatSymbolType type, int32_t idx, const char* expected)
1058 {
1059 UChar *pattern=NULL;
1060 UErrorCode status = U_ZERO_ERROR;
1061 UChar *result=NULL;
1062 int32_t resultlength, resultlengthout;
1063 int32_t patternSize = (int32_t)strlen(expected) + 1;
1064
1065 pattern=(UChar*)malloc(sizeof(UChar) * patternSize);
1066 u_unescape(expected, pattern, patternSize);
1067 resultlength=0;
1068 resultlengthout=udat_getSymbols(datfor, type, idx , NULL, resultlength, &status);
1069 if(status==U_BUFFER_OVERFLOW_ERROR)
1070 {
1071 status=U_ZERO_ERROR;
1072 resultlength=resultlengthout+1;
1073 result=(UChar*)malloc(sizeof(UChar) * resultlength);
1074 udat_getSymbols(datfor, type, idx, result, resultlength, &status);
1075
1076 }
1077 if(U_FAILURE(status))
1078 {
1079 log_err("FAIL: Error in udat_getSymbols()... %s\n", myErrorName(status) );
1080 return;
1081 }
1082 if(u_strcmp(result, pattern)==0)
1083 log_verbose("PASS: getSymbols retrieved the right value\n");
1084 else{
1085 log_data_err("FAIL: getSymbols retrieved the wrong value\n Expected %s Got %s\n", expected,
1086 aescstrdup(result,-1) );
1087 }
1088 free(result);
1089 free(pattern);
1090 }
1091
VerifysetSymbols(UDateFormat * datfor,UDateFormatSymbolType type,int32_t idx,const char * expected)1092 static void VerifysetSymbols(UDateFormat* datfor, UDateFormatSymbolType type, int32_t idx, const char* expected)
1093 {
1094 UChar *result=NULL;
1095 UChar *value=NULL;
1096 int32_t resultlength, resultlengthout;
1097 UErrorCode status = U_ZERO_ERROR;
1098 int32_t valueLen, valueSize = (int32_t)strlen(expected) + 1;
1099
1100 value=(UChar*)malloc(sizeof(UChar) * valueSize);
1101 valueLen = u_unescape(expected, value, valueSize);
1102 udat_setSymbols(datfor, type, idx, value, valueLen, &status);
1103 if(U_FAILURE(status))
1104 {
1105 log_err("FAIL: Error in udat_setSymbols() %s\n", myErrorName(status) );
1106 return;
1107 }
1108
1109 resultlength=0;
1110 resultlengthout=udat_getSymbols(datfor, type, idx, NULL, resultlength, &status);
1111 if(status==U_BUFFER_OVERFLOW_ERROR){
1112 status=U_ZERO_ERROR;
1113 resultlength=resultlengthout+1;
1114 result=(UChar*)malloc(sizeof(UChar) * resultlength);
1115 udat_getSymbols(datfor, type, idx, result, resultlength, &status);
1116 }
1117 if(U_FAILURE(status)){
1118 log_err("FAIL: error in retrieving the value using getSymbols after setting it previously\n %s\n",
1119 myErrorName(status) );
1120 return;
1121 }
1122
1123 if(u_strcmp(result, value)!=0){
1124 log_err("FAIL:Error in setting and then getting symbols\n Expected %s Got %s\n", expected,
1125 aescstrdup(result,-1) );
1126 }
1127 else
1128 log_verbose("PASS: setSymbols successful\n");
1129
1130 free(value);
1131 free(result);
1132 }
1133
1134
VerifygetsetSymbols(UDateFormat * from,UDateFormat * to,UDateFormatSymbolType type,int32_t idx)1135 static void VerifygetsetSymbols(UDateFormat* from, UDateFormat* to, UDateFormatSymbolType type, int32_t idx)
1136 {
1137 UChar *result=NULL;
1138 UChar *value=NULL;
1139 int32_t resultlength, resultlengthout;
1140 UErrorCode status = U_ZERO_ERROR;
1141
1142 resultlength=0;
1143 resultlengthout=udat_getSymbols(from, type, idx , NULL, resultlength, &status);
1144 if(status==U_BUFFER_OVERFLOW_ERROR){
1145 status=U_ZERO_ERROR;
1146 resultlength=resultlengthout+1;
1147 result=(UChar*)malloc(sizeof(UChar) * resultlength);
1148 udat_getSymbols(from, type, idx, result, resultlength, &status);
1149 }
1150 if(U_FAILURE(status)){
1151 log_err("FAIL: error in getSymbols() %s\n", myErrorName(status) );
1152 return;
1153 }
1154
1155 resultlength=resultlengthout+1;
1156 udat_setSymbols(to, type, idx, result, resultlength, &status);
1157 if(U_FAILURE(status))
1158 {
1159 log_err("FAIL: Error in udat_setSymbols() : %s\n", myErrorName(status) );
1160 return;
1161 }
1162
1163 resultlength=0;
1164 resultlengthout=udat_getSymbols(to, type, idx, NULL, resultlength, &status);
1165 if(status==U_BUFFER_OVERFLOW_ERROR){
1166 status=U_ZERO_ERROR;
1167 resultlength=resultlengthout+1;
1168 value=(UChar*)malloc(sizeof(UChar) * resultlength);
1169 udat_getSymbols(to, type, idx, value, resultlength, &status);
1170 }
1171 if(U_FAILURE(status)){
1172 log_err("FAIL: error in retrieving the value using getSymbols i.e roundtrip\n %s\n",
1173 myErrorName(status) );
1174 return;
1175 }
1176
1177 if(u_strcmp(result, value)!=0){
1178 log_data_err("FAIL:Error in setting and then getting symbols\n Expected %s Got %s\n", austrdup(result),
1179 austrdup(value) );
1180 }
1181 else
1182 log_verbose("PASS: setSymbols successful\n");
1183
1184 free(value);
1185 free(result);
1186 }
1187
1188
myNumformat(const UNumberFormat * numfor,double d)1189 static UChar* myNumformat(const UNumberFormat* numfor, double d)
1190 {
1191 UChar *result2=NULL;
1192 int32_t resultlength, resultlengthneeded;
1193 UErrorCode status = U_ZERO_ERROR;
1194
1195 resultlength=0;
1196 resultlengthneeded=unum_formatDouble(numfor, d, NULL, resultlength, NULL, &status);
1197 if(status==U_BUFFER_OVERFLOW_ERROR)
1198 {
1199 status=U_ZERO_ERROR;
1200 resultlength=resultlengthneeded+1;
1201 /*result2=(UChar*)malloc(sizeof(UChar) * resultlength);*/ /* this leaks */
1202 result2=(UChar*)ctst_malloc(sizeof(UChar) * resultlength); /*this won't*/
1203 unum_formatDouble(numfor, d, result2, resultlength, NULL, &status);
1204 }
1205 if(U_FAILURE(status))
1206 {
1207 log_err("FAIL: Error in formatting using unum_format(.....) %s\n", myErrorName(status) );
1208 return 0;
1209 }
1210
1211 return result2;
1212 }
1213
1214 /**
1215 * The search depth for TestExtremeDates. The total number of
1216 * dates that will be tested is (2^EXTREME_DATES_DEPTH) - 1.
1217 */
1218 #define EXTREME_DATES_DEPTH 8
1219
1220 /**
1221 * Support for TestExtremeDates (below).
1222 *
1223 * Test a single date to see whether udat_format handles it properly.
1224 */
_aux1ExtremeDates(UDateFormat * fmt,UDate date,UChar * buf,int32_t buflen,char * cbuf,UErrorCode * ec)1225 static UBool _aux1ExtremeDates(UDateFormat* fmt, UDate date,
1226 UChar* buf, int32_t buflen, char* cbuf,
1227 UErrorCode* ec) {
1228 int32_t len = udat_format(fmt, date, buf, buflen, 0, ec);
1229 if (!assertSuccess("udat_format", ec)) return FALSE;
1230 u_austrncpy(cbuf, buf, buflen);
1231 if (len < 4) {
1232 log_err("FAIL: udat_format(%g) => \"%s\"\n", date, cbuf);
1233 } else {
1234 log_verbose("udat_format(%g) => \"%s\"\n", date, cbuf);
1235 }
1236 return TRUE;
1237 }
1238
1239 /**
1240 * Support for TestExtremeDates (below).
1241 *
1242 * Recursively test between 'small' and 'large', up to the depth
1243 * limit specified by EXTREME_DATES_DEPTH.
1244 */
_aux2ExtremeDates(UDateFormat * fmt,UDate small,UDate large,UChar * buf,int32_t buflen,char * cbuf,int32_t count,UErrorCode * ec)1245 static UBool _aux2ExtremeDates(UDateFormat* fmt, UDate small, UDate large,
1246 UChar* buf, int32_t buflen, char* cbuf,
1247 int32_t count,
1248 UErrorCode* ec) {
1249 /* Logarithmic midpoint; see below */
1250 UDate mid = (UDate) exp((log(small) + log(large)) / 2);
1251 if (count == EXTREME_DATES_DEPTH) {
1252 return TRUE;
1253 }
1254 return
1255 _aux1ExtremeDates(fmt, mid, buf, buflen, cbuf, ec) &&
1256 _aux2ExtremeDates(fmt, small, mid, buf, buflen, cbuf, count+1, ec) &&
1257 _aux2ExtremeDates(fmt, mid, large, buf, buflen, cbuf, count+1, ec);
1258 }
1259
1260 /**
1261 * http://www.jtcsv.com/cgibin/icu-bugs?findid=3659
1262 *
1263 * For certain large dates, udat_format crashes on MacOS. This test
1264 * attempts to reproduce this problem by doing a recursive logarithmic*
1265 * binary search of a predefined interval (from 'small' to 'large').
1266 *
1267 * The limit of the search is given by EXTREME_DATES_DEPTH, above.
1268 *
1269 * *The search has to be logarithmic, not linear. A linear search of the
1270 * range 0..10^30, for example, will find 0.5*10^30, then 0.25*10^30 and
1271 * 0.75*10^30, etc. A logarithmic search will find 10^15, then 10^7.5
1272 * and 10^22.5, etc.
1273 */
TestExtremeDates()1274 static void TestExtremeDates() {
1275 UDateFormat *fmt;
1276 UErrorCode ec;
1277 UChar buf[256];
1278 char cbuf[256];
1279 const double small = 1000; /* 1 sec */
1280 const double large = 1e+30; /* well beyond usable UDate range */
1281
1282 /* There is no need to test larger values from 1e+30 to 1e+300;
1283 the failures occur around 1e+27, and never above 1e+30. */
1284
1285 ec = U_ZERO_ERROR;
1286 fmt = udat_open(UDAT_LONG, UDAT_LONG, "en_US",
1287 0, 0, 0, 0, &ec);
1288 if (U_FAILURE(ec)) {
1289 log_data_err("FAIL: udat_open (%s) (Are you missing data?)\n", u_errorName(ec));
1290 return;
1291 }
1292
1293 _aux2ExtremeDates(fmt, small, large, buf, UPRV_LENGTHOF(buf), cbuf, 0, &ec);
1294
1295 udat_close(fmt);
1296 }
1297
TestAllLocales(void)1298 static void TestAllLocales(void) {
1299 int32_t idx, dateIdx, timeIdx, localeCount;
1300 static const UDateFormatStyle style[] = {
1301 UDAT_FULL, UDAT_LONG, UDAT_MEDIUM, UDAT_SHORT
1302 };
1303 localeCount = uloc_countAvailable();
1304 for (idx = 0; idx < localeCount; idx++) {
1305 for (dateIdx = 0; dateIdx < UPRV_LENGTHOF(style); dateIdx++) {
1306 for (timeIdx = 0; timeIdx < UPRV_LENGTHOF(style); timeIdx++) {
1307 UErrorCode status = U_ZERO_ERROR;
1308 udat_close(udat_open(style[dateIdx], style[timeIdx],
1309 uloc_getAvailable(idx), NULL, 0, NULL, 0, &status));
1310 if (U_FAILURE(status)) {
1311 log_err("FAIL: udat_open(%s) failed with (%s) dateIdx=%d, timeIdx=%d\n",
1312 uloc_getAvailable(idx), u_errorName(status), dateIdx, timeIdx);
1313 }
1314 }
1315 }
1316 }
1317 }
1318
TestRelativeCrash(void)1319 static void TestRelativeCrash(void) {
1320 static const UChar tzName[] = { 0x0055, 0x0053, 0x002F, 0x0050, 0x0061, 0x0063, 0x0069, 0x0066, 0x0069, 0x0063, 0 };
1321 static const UDate aDate = -631152000000.0;
1322
1323 UErrorCode status = U_ZERO_ERROR;
1324 UErrorCode expectStatus = U_ILLEGAL_ARGUMENT_ERROR;
1325 UDateFormat icudf;
1326
1327 icudf = udat_open(UDAT_NONE, UDAT_SHORT_RELATIVE, "en", tzName, -1, NULL, 0, &status);
1328 if ( U_SUCCESS(status) ) {
1329 const char *what = "???";
1330 {
1331 UErrorCode subStatus = U_ZERO_ERROR;
1332 what = "udat_set2DigitYearStart";
1333 log_verbose("Trying %s on a relative date..\n", what);
1334 udat_set2DigitYearStart(icudf, aDate, &subStatus);
1335 if(subStatus == expectStatus) {
1336 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1337 } else {
1338 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
1339 }
1340 }
1341 {
1342 /* clone works polymorphically. try it anyways */
1343 UErrorCode subStatus = U_ZERO_ERROR;
1344 UDateFormat *oth;
1345 what = "clone";
1346 log_verbose("Trying %s on a relative date..\n", what);
1347 oth = udat_clone(icudf, &subStatus);
1348 if(subStatus == U_ZERO_ERROR) {
1349 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1350 udat_close(oth); /* ? */
1351 } else {
1352 log_err("FAIL: didn't crash on %s, but got %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
1353 }
1354 }
1355 {
1356 UErrorCode subStatus = U_ZERO_ERROR;
1357 what = "udat_get2DigitYearStart";
1358 log_verbose("Trying %s on a relative date..\n", what);
1359 udat_get2DigitYearStart(icudf, &subStatus);
1360 if(subStatus == expectStatus) {
1361 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1362 } else {
1363 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
1364 }
1365 }
1366 {
1367 /* Now udat_toPattern works for relative date formatters, unless localized is TRUE */
1368 UErrorCode subStatus = U_ZERO_ERROR;
1369 what = "udat_toPattern";
1370 log_verbose("Trying %s on a relative date..\n", what);
1371 udat_toPattern(icudf, TRUE,NULL,0, &subStatus);
1372 if(subStatus == expectStatus) {
1373 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1374 } else {
1375 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
1376 }
1377 }
1378 {
1379 UErrorCode subStatus = U_ZERO_ERROR;
1380 what = "udat_applyPattern";
1381 log_verbose("Trying %s on a relative date..\n", what);
1382 udat_applyPattern(icudf, FALSE,tzName,-1);
1383 subStatus = U_ILLEGAL_ARGUMENT_ERROR; /* what it should be, if this took an errorcode. */
1384 if(subStatus == expectStatus) {
1385 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1386 } else {
1387 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
1388 }
1389 }
1390 {
1391 UChar erabuf[32];
1392 UErrorCode subStatus = U_ZERO_ERROR;
1393 what = "udat_getSymbols";
1394 log_verbose("Trying %s on a relative date..\n", what);
1395 udat_getSymbols(icudf, UDAT_ERAS,0,erabuf,UPRV_LENGTHOF(erabuf), &subStatus);
1396 if(subStatus == U_ZERO_ERROR) {
1397 log_verbose("Success: %s returned %s.\n", what, u_errorName(subStatus));
1398 } else {
1399 log_err("FAIL: didn't crash on %s, but got %s instead of U_ZERO_ERROR.\n", what, u_errorName(subStatus));
1400 }
1401 }
1402 {
1403 UErrorCode subStatus = U_ZERO_ERROR;
1404 UChar symbolValue = 0x0041;
1405 what = "udat_setSymbols";
1406 log_verbose("Trying %s on a relative date..\n", what);
1407 udat_setSymbols(icudf, UDAT_ERAS,0,&symbolValue,1, &subStatus); /* bogus values */
1408 if(subStatus == expectStatus) {
1409 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1410 } else {
1411 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
1412 }
1413 }
1414 {
1415 UErrorCode subStatus = U_ZERO_ERROR;
1416 what = "udat_countSymbols";
1417 log_verbose("Trying %s on a relative date..\n", what);
1418 udat_countSymbols(icudf, UDAT_ERAS);
1419 subStatus = U_ILLEGAL_ARGUMENT_ERROR; /* should have an errorcode. */
1420 if(subStatus == expectStatus) {
1421 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1422 } else {
1423 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
1424 }
1425 }
1426
1427 udat_close(icudf);
1428 } else {
1429 log_data_err("FAIL: err calling udat_open() ->%s (Are you missing data?)\n", u_errorName(status));
1430 }
1431 }
1432
1433 static const UChar skeleton_yMMMM[] = { 0x79,0x4D,0x4D,0x4D,0x4D,0 }; /* "yMMMM"; fr maps to "MMMM y", cs maps to "LLLL y" */
1434 static const UChar july2008_frDefault[] = { 0x6A,0x75,0x69,0x6C,0x6C,0x65,0x74,0x20,0x32,0x30,0x30,0x38,0 }; /* "juillet 2008" */
1435 static const UChar july2008_frTitle[] = { 0x4A,0x75,0x69,0x6C,0x6C,0x65,0x74,0x20,0x32,0x30,0x30,0x38,0 }; /* "Juillet 2008" sentence-begin, standalone */
1436 static const UChar july2008_csDefault[] = { 0x10D,0x65,0x72,0x76,0x65,0x6E,0x65,0x63,0x20,0x32,0x30,0x30,0x38,0 }; /* "c(hacek)ervenec 2008" */
1437 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
1439 typedef struct {
1440 const char * locale;
1441 const UChar * skeleton;
1442 UDisplayContext capitalizationContext;
1443 const UChar * expectedFormat;
1444 } TestContextItem;
1445
1446 static const TestContextItem textContextItems[] = {
1447 { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_NONE, july2008_frDefault },
1448 #if !UCONFIG_NO_BREAK_ITERATION
1449 { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, july2008_frDefault },
1450 { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, july2008_frTitle },
1451 { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, july2008_frDefault },
1452 { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_STANDALONE, july2008_frTitle },
1453 #endif
1454 { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_NONE, july2008_csDefault },
1455 #if !UCONFIG_NO_BREAK_ITERATION
1456 { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, july2008_csDefault },
1457 { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, july2008_csTitle },
1458 { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, july2008_csTitle },
1459 { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_STANDALONE, july2008_csDefault },
1460 #endif
1461 { NULL, NULL, (UDisplayContext)0, NULL }
1462 };
1463
1464 static const UChar today_enDefault[] = { 0x74,0x6F,0x64,0x61,0x79,0 }; /* "today" */
1465 static const UChar today_enTitle[] = { 0x54,0x6F,0x64,0x61,0x79,0 }; /* "Today" sentence-begin, uiListOrMenu, standalone */
1466 static const UChar yesterday_enDefault[] = { 0x79,0x65,0x73,0x74,0x65,0x72,0x64,0x61,0x79,0 }; /* "yesterday" */
1467 static const UChar yesterday_enTitle[] = { 0x59,0x65,0x73,0x74,0x65,0x72,0x64,0x61,0x79,0 }; /* "Yesterday" sentence-begin, uiListOrMenu, standalone */
1468 static const UChar today_nbDefault[] = { 0x69,0x20,0x64,0x61,0x67,0 }; /* "i dag" */
1469 static const UChar today_nbTitle[] = { 0x49,0x20,0x64,0x61,0x67,0 }; /* "I dag" sentence-begin, standalone */
1470 static const UChar yesterday_nbDefault[] = { 0x69,0x20,0x67,0xE5,0x72,0 };
1471 static const UChar yesterday_nbTitle[] = { 0x49,0x20,0x67,0xE5,0x72,0 };
1472
1473 typedef struct {
1474 const char * locale;
1475 UDisplayContext capitalizationContext;
1476 const UChar * expectedFormatToday;
1477 const UChar * expectedFormatYesterday;
1478 } TestRelativeContextItem;
1479
1480 static const TestRelativeContextItem textContextRelativeItems[] = {
1481 { "en", UDISPCTX_CAPITALIZATION_NONE, today_enDefault, yesterday_enDefault },
1482 #if !UCONFIG_NO_BREAK_ITERATION
1483 { "en", UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, today_enDefault, yesterday_enDefault },
1484 { "en", UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, today_enTitle, yesterday_enTitle },
1485 { "en", UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, today_enTitle, yesterday_enTitle },
1486 { "en", UDISPCTX_CAPITALIZATION_FOR_STANDALONE, today_enTitle, yesterday_enTitle },
1487 #endif
1488 { "nb", UDISPCTX_CAPITALIZATION_NONE, today_nbDefault, yesterday_nbDefault },
1489 #if !UCONFIG_NO_BREAK_ITERATION
1490 { "nb", UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, today_nbDefault, yesterday_nbDefault },
1491 { "nb", UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, today_nbTitle, yesterday_nbTitle },
1492 { "nb", UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, today_nbDefault, yesterday_nbDefault },
1493 { "nb", UDISPCTX_CAPITALIZATION_FOR_STANDALONE, today_nbTitle, yesterday_nbTitle },
1494 #endif
1495 { NULL, (UDisplayContext)0, NULL, NULL }
1496 };
1497
1498 static const UChar zoneGMT[] = { 0x47,0x4D,0x54,0 }; /* "GMT" */
1499 static const UDate july022008 = 1215000000000.0;
1500 enum { kUbufMax = 64, kBbufMax = 3*kUbufMax };
1501
TestContext(void)1502 static void TestContext(void) {
1503 const TestContextItem* textContextItemPtr;
1504 const TestRelativeContextItem* textRelContextItemPtr;
1505 for (textContextItemPtr = textContextItems; textContextItemPtr->locale != NULL; ++textContextItemPtr) {
1506 UErrorCode status = U_ZERO_ERROR;
1507 UDateTimePatternGenerator* udtpg = udatpg_open(textContextItemPtr->locale, &status);
1508 if ( U_SUCCESS(status) ) {
1509 UChar ubuf[kUbufMax];
1510 int32_t len = udatpg_getBestPattern(udtpg, textContextItemPtr->skeleton, -1, ubuf, kUbufMax, &status);
1511 if ( U_SUCCESS(status) ) {
1512 UDateFormat* udfmt = udat_open(UDAT_PATTERN, UDAT_PATTERN, textContextItemPtr->locale, zoneGMT, -1, ubuf, len, &status);
1513 if ( U_SUCCESS(status) ) {
1514 udat_setContext(udfmt, textContextItemPtr->capitalizationContext, &status);
1515 if ( U_SUCCESS(status) ) {
1516 UDisplayContext getContext;
1517 len = udat_format(udfmt, july022008, ubuf, kUbufMax, NULL, &status);
1518 if ( U_FAILURE(status) ) {
1519 log_err("FAIL: udat_format for locale %s, capitalizationContext %d, status %s\n",
1520 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, u_errorName(status) );
1521 status = U_ZERO_ERROR;
1522 } else if (u_strncmp(ubuf, textContextItemPtr->expectedFormat, kUbufMax) != 0) {
1523 char bbuf1[kBbufMax];
1524 char bbuf2[kBbufMax];
1525 log_err("FAIL: udat_format for locale %s, capitalizationContext %d, expected %s, got %s\n",
1526 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext,
1527 u_austrncpy(bbuf1,textContextItemPtr->expectedFormat,kUbufMax), u_austrncpy(bbuf2,ubuf,kUbufMax) );
1528 }
1529 getContext = udat_getContext(udfmt, UDISPCTX_TYPE_CAPITALIZATION, &status);
1530 if ( U_FAILURE(status) ) {
1531 log_err("FAIL: udat_getContext for locale %s, capitalizationContext %d, status %s\n",
1532 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, u_errorName(status) );
1533 } else if (getContext != textContextItemPtr->capitalizationContext) {
1534 log_err("FAIL: udat_getContext for locale %s, capitalizationContext %d, got context %d\n",
1535 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, (int)getContext );
1536 }
1537 } else {
1538 log_err("FAIL: udat_setContext for locale %s, capitalizationContext %d, status %s\n",
1539 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, u_errorName(status) );
1540 }
1541 udat_close(udfmt);
1542 } else {
1543 log_data_err("FAIL: udat_open for locale %s, status %s\n", textContextItemPtr->locale, u_errorName(status) );
1544 }
1545 } else {
1546 log_err("FAIL: udatpg_getBestPattern for locale %s, status %s\n", textContextItemPtr->locale, u_errorName(status) );
1547 }
1548 udatpg_close(udtpg);
1549 } else {
1550 log_data_err("FAIL: udatpg_open for locale %s, status %s\n", textContextItemPtr->locale, u_errorName(status) );
1551 }
1552 }
1553 for (textRelContextItemPtr = textContextRelativeItems; textRelContextItemPtr->locale != NULL; ++textRelContextItemPtr) {
1554 UErrorCode status = U_ZERO_ERROR;
1555 UCalendar* ucal = ucal_open(zoneGMT, -1, "root", UCAL_GREGORIAN, &status);
1556 if ( U_SUCCESS(status) ) {
1557 UDateFormat* udfmt = udat_open(UDAT_NONE, UDAT_LONG_RELATIVE, textRelContextItemPtr->locale, zoneGMT, -1, NULL, 0, &status);
1558 if ( U_SUCCESS(status) ) {
1559 udat_setContext(udfmt, textRelContextItemPtr->capitalizationContext, &status);
1560 if ( U_SUCCESS(status) ) {
1561 UDate yesterday, today = ucal_getNow();
1562 UChar ubuf[kUbufMax];
1563 char bbuf1[kBbufMax];
1564 char bbuf2[kBbufMax];
1565 int32_t len = udat_format(udfmt, today, ubuf, kUbufMax, NULL, &status);
1566 (void)len;
1567 if ( U_FAILURE(status) ) {
1568 log_err("FAIL: udat_format today for locale %s, capitalizationContext %d, status %s\n",
1569 textRelContextItemPtr->locale, (int)textRelContextItemPtr->capitalizationContext, u_errorName(status) );
1570 } else if (u_strncmp(ubuf, textRelContextItemPtr->expectedFormatToday, kUbufMax) != 0) {
1571 log_err("FAIL: udat_format today for locale %s, capitalizationContext %d, expected %s, got %s\n",
1572 textRelContextItemPtr->locale, (int)textRelContextItemPtr->capitalizationContext,
1573 u_austrncpy(bbuf1,textRelContextItemPtr->expectedFormatToday,kUbufMax), u_austrncpy(bbuf2,ubuf,kUbufMax) );
1574 }
1575 status = U_ZERO_ERROR;
1576 ucal_setMillis(ucal, today, &status);
1577 ucal_add(ucal, UCAL_DATE, -1, &status);
1578 yesterday = ucal_getMillis(ucal, &status);
1579 if ( U_SUCCESS(status) ) {
1580 len = udat_format(udfmt, yesterday, ubuf, kUbufMax, NULL, &status);
1581 if ( U_FAILURE(status) ) {
1582 log_err("FAIL: udat_format yesterday for locale %s, capitalizationContext %d, status %s\n",
1583 textRelContextItemPtr->locale, (int)textRelContextItemPtr->capitalizationContext, u_errorName(status) );
1584 } else if (u_strncmp(ubuf, textRelContextItemPtr->expectedFormatYesterday, kUbufMax) != 0) {
1585 log_err("FAIL: udat_format yesterday for locale %s, capitalizationContext %d, expected %s, got %s\n",
1586 textRelContextItemPtr->locale, (int)textRelContextItemPtr->capitalizationContext,
1587 u_austrncpy(bbuf1,textRelContextItemPtr->expectedFormatYesterday,kUbufMax), u_austrncpy(bbuf2,ubuf,kUbufMax) );
1588 }
1589 }
1590 } else {
1591 log_err("FAIL: udat_setContext relative for locale %s, capitalizationContext %d, status %s\n",
1592 textRelContextItemPtr->locale, (int)textRelContextItemPtr->capitalizationContext, u_errorName(status) );
1593 }
1594 udat_close(udfmt);
1595 } else {
1596 log_data_err("FAIL: udat_open relative for locale %s, status %s\n", textRelContextItemPtr->locale, u_errorName(status) );
1597 }
1598 ucal_close(ucal);
1599 } else {
1600 log_data_err("FAIL: ucal_open for locale root, status %s\n", u_errorName(status) );
1601 }
1602 }
1603 }
1604
1605
1606 // overrideNumberFormat[i][0] is to tell which field to set,
1607 // overrideNumberFormat[i][1] is the expected result
1608 static const char * overrideNumberFormat[][2] = {
1609 {"", "\\u521D\\u4E03 \\u521D\\u4E8C"},
1610 {"d", "07 \\u521D\\u4E8C"},
1611 {"do", "07 \\u521D\\u4E8C"},
1612 {"Md", "\\u521D\\u4E03 \\u521D\\u4E8C"},
1613 {"MdMMd", "\\u521D\\u4E03 \\u521D\\u4E8C"},
1614 {"mixed", "\\u521D\\u4E03 \\u521D\\u4E8C"}
1615 };
1616
TestOverrideNumberFormat(void)1617 static void TestOverrideNumberFormat(void) {
1618 UErrorCode status = U_ZERO_ERROR;
1619 UChar pattern[50];
1620 UChar expected[50];
1621 UChar fields[50];
1622 char bbuf1[kBbufMax];
1623 char bbuf2[kBbufMax];
1624 const char* localeString = "zh@numbers=hanidays";
1625 UDateFormat* fmt;
1626 const UNumberFormat* getter_result;
1627 int32_t i;
1628
1629 u_uastrcpy(fields, "d");
1630 u_uastrcpy(pattern,"MM d");
1631
1632 fmt=udat_open(UDAT_PATTERN, UDAT_PATTERN, "en_US", zoneGMT, -1, pattern, u_strlen(pattern), &status);
1633 if (!assertSuccess("udat_open()", &status)) {
1634 return;
1635 }
1636
1637 // loop 5 times to check getter/setter
1638 for (i = 0; i < 5; i++){
1639 status = U_ZERO_ERROR;
1640 UNumberFormat* overrideFmt;
1641 overrideFmt = unum_open(UNUM_DEFAULT, NULL, 0, localeString, NULL, &status);
1642 assertSuccess("unum_open()", &status);
1643 udat_adoptNumberFormatForFields(fmt, fields, overrideFmt, &status);
1644 overrideFmt = NULL; // no longer valid
1645 assertSuccess("udat_setNumberFormatForField()", &status);
1646
1647 getter_result = udat_getNumberFormatForField(fmt, 0x0064 /*'d'*/);
1648 if(getter_result == NULL) {
1649 log_err("FAIL: udat_getNumberFormatForField did not return a valid pointer\n");
1650 }
1651 }
1652 {
1653 status = U_ZERO_ERROR;
1654 UNumberFormat* overrideFmt;
1655 overrideFmt = unum_open(UNUM_DEFAULT, NULL, 0, localeString, NULL, &status);
1656 assertSuccess("unum_open()", &status);
1657 if (U_SUCCESS(status)) {
1658 udat_setNumberFormat(fmt, overrideFmt); // test the same override NF will not crash
1659 }
1660 unum_close(overrideFmt);
1661 }
1662 udat_close(fmt);
1663
1664 for (i=0; i<UPRV_LENGTHOF(overrideNumberFormat); i++){
1665 status = U_ZERO_ERROR;
1666 UChar ubuf[kUbufMax];
1667 UDateFormat* fmt2;
1668 UNumberFormat* overrideFmt2;
1669
1670 fmt2 =udat_open(UDAT_PATTERN, UDAT_PATTERN,"en_US", zoneGMT, -1, pattern, u_strlen(pattern), &status);
1671 assertSuccess("udat_open() with en_US", &status);
1672
1673 overrideFmt2 = unum_open(UNUM_DEFAULT, NULL, 0, localeString, NULL, &status);
1674 assertSuccess("unum_open() in loop", &status);
1675
1676 if (U_FAILURE(status)) {
1677 continue;
1678 }
1679
1680 u_uastrcpy(fields, overrideNumberFormat[i][0]);
1681 u_unescape(overrideNumberFormat[i][1], expected, UPRV_LENGTHOF(expected));
1682
1683 if ( strcmp(overrideNumberFormat[i][0], "") == 0 ) { // use the one w/o field
1684 udat_adoptNumberFormat(fmt2, overrideFmt2);
1685 } else if ( strcmp(overrideNumberFormat[i][0], "mixed") == 0 ) { // set 1 field at first but then full override, both(M & d) should be override
1686 const char* singleLocale = "en@numbers=hebr";
1687 UNumberFormat* singleOverrideFmt;
1688 u_uastrcpy(fields, "d");
1689
1690 singleOverrideFmt = unum_open(UNUM_DEFAULT, NULL, 0, singleLocale, NULL, &status);
1691 assertSuccess("unum_open() in mixed", &status);
1692
1693 udat_adoptNumberFormatForFields(fmt2, fields, singleOverrideFmt, &status);
1694 assertSuccess("udat_setNumberFormatForField() in mixed", &status);
1695
1696 udat_adoptNumberFormat(fmt2, overrideFmt2);
1697 } else if ( strcmp(overrideNumberFormat[i][0], "do") == 0 ) { // o is an invalid field
1698 udat_adoptNumberFormatForFields(fmt2, fields, overrideFmt2, &status);
1699 if(status == U_INVALID_FORMAT_ERROR) {
1700 udat_close(fmt2);
1701 status = U_ZERO_ERROR;
1702 continue;
1703 }
1704 } else {
1705 udat_adoptNumberFormatForFields(fmt2, fields, overrideFmt2, &status);
1706 assertSuccess("udat_setNumberFormatForField() in loop", &status);
1707 }
1708
1709 udat_format(fmt2, july022008, ubuf, kUbufMax, NULL, &status);
1710 assertSuccess("udat_format() july022008", &status);
1711
1712 if (u_strncmp(ubuf, expected, kUbufMax) != 0)
1713 log_err("fail: udat_format for locale, expected %s, got %s\n",
1714 u_austrncpy(bbuf1,expected,kUbufMax), u_austrncpy(bbuf2,ubuf,kUbufMax) );
1715
1716 udat_close(fmt2);
1717 }
1718 }
1719
1720 /*
1721 * Ticket #11523
1722 * udat_parse and udat_parseCalendar should have the same error code when given the same invalid input.
1723 */
TestParseErrorReturnValue(void)1724 static void TestParseErrorReturnValue(void) {
1725 UErrorCode status = U_ZERO_ERROR;
1726 UErrorCode expectStatus = U_PARSE_ERROR;
1727 UDateFormat* df;
1728 UCalendar* cal;
1729
1730 df = udat_open(UDAT_DEFAULT, UDAT_DEFAULT, NULL, NULL, -1, NULL, -1, &status);
1731 if (!assertSuccessCheck("udat_open()", &status, TRUE)) {
1732 return;
1733 }
1734
1735 cal = ucal_open(NULL, 0, "en_US", UCAL_GREGORIAN, &status);
1736 if (!assertSuccess("ucal_open()", &status)) {
1737 return;
1738 }
1739
1740 udat_parse(df, NULL, -1, NULL, &status);
1741 if (status != expectStatus) {
1742 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));
1743 }
1744
1745 status = U_ZERO_ERROR;
1746 udat_parseCalendar(df, cal, NULL, -1, NULL, &status);
1747 if (status != expectStatus) {
1748 log_err("%s should have been returned by udat_parseCalendar when given an invalid input, instead got - %s\n", u_errorName(expectStatus), u_errorName(status));
1749 }
1750
1751 ucal_close(cal);
1752 udat_close(df);
1753 }
1754
1755 /*
1756 * Ticket #11553
1757 * Test new udat_formatForFields, udat_formatCalendarForFields (and UFieldPositionIterator)
1758 */
1759 static const char localeForFields[] = "en_US";
1760 /* zoneGMT[]defined above */
1761 static const UDate date2015Feb25 = 1424841000000.0; /* Wednesday, February 25, 2015 at 5:10:00 AM GMT */
1762 static const UChar patNoFields[] = { 0x0027, 0x0078, 0x0078, 0x0078, 0x0027, 0 }; /* "'xxx'" */
1763
1764 typedef struct {
1765 int32_t field;
1766 int32_t beginPos;
1767 int32_t endPos;
1768 } FieldsData;
1769 static const FieldsData expectedFields[] = {
1770 { UDAT_DAY_OF_WEEK_FIELD /* 9*/, 0, 9 },
1771 { UDAT_MONTH_FIELD /* 2*/, 11, 19 },
1772 { UDAT_DATE_FIELD /* 3*/, 20, 22 },
1773 { UDAT_YEAR_FIELD /* 1*/, 24, 28 },
1774 { UDAT_HOUR1_FIELD /*15*/, 32, 33 },
1775 #if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
1776 { UDAT_TIME_SEPARATOR_FIELD /*35*/, 33, 34 },
1777 #endif
1778 { UDAT_MINUTE_FIELD /* 6*/, 34, 36 },
1779 #if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
1780 { UDAT_TIME_SEPARATOR_FIELD /*35*/, 36, 37 },
1781 #endif
1782 { UDAT_SECOND_FIELD /* 7*/, 37, 39 },
1783 { UDAT_AM_PM_FIELD /*14*/, 40, 42 },
1784 { UDAT_TIMEZONE_FIELD /*17*/, 43, 46 },
1785 { -1, -1, -1 },
1786 };
1787
1788 enum {kUBufFieldsLen = 128, kBBufFieldsLen = 256 };
1789
TestFormatForFields(void)1790 static void TestFormatForFields(void) {
1791 UErrorCode status = U_ZERO_ERROR;
1792 UFieldPositionIterator* fpositer = ufieldpositer_open(&status);
1793 if ( U_FAILURE(status) ) {
1794 log_err("ufieldpositer_open fails, status %s\n", u_errorName(status));
1795 } else {
1796 UDateFormat* udfmt = udat_open(UDAT_LONG, UDAT_FULL, localeForFields, zoneGMT, -1, NULL, 0, &status);
1797 UCalendar* ucal = ucal_open(zoneGMT, -1, localeForFields, UCAL_DEFAULT, &status);
1798 if ( U_FAILURE(status) ) {
1799 log_data_err("udat_open or ucal_open fails for locale %s, status %s (Are you missing data?)\n", localeForFields, u_errorName(status));
1800 } else {
1801 int32_t ulen, field, beginPos, endPos;
1802 UChar ubuf[kUBufFieldsLen];
1803 const FieldsData * fptr;
1804
1805 status = U_ZERO_ERROR;
1806 ulen = udat_formatForFields(udfmt, date2015Feb25, ubuf, kUBufFieldsLen, fpositer, &status);
1807 if ( U_FAILURE(status) ) {
1808 log_err("udat_formatForFields fails, status %s\n", u_errorName(status));
1809 } else {
1810 for (fptr = expectedFields; ; fptr++) {
1811 field = ufieldpositer_next(fpositer, &beginPos, &endPos);
1812 if (field != fptr->field || (field >= 0 && (beginPos != fptr->beginPos || endPos != fptr->endPos))) {
1813 if (fptr->field >= 0) {
1814 log_err("udat_formatForFields as \"%s\"; expect field %d range %d-%d, get field %d range %d-%d\n",
1815 aescstrdup(ubuf, ulen), fptr->field, fptr->beginPos, fptr->endPos, field, beginPos, endPos);
1816 } else {
1817 log_err("udat_formatForFields as \"%s\"; expect field < 0, get field %d range %d-%d\n",
1818 aescstrdup(ubuf, ulen), field, beginPos, endPos);
1819 }
1820 break;
1821 }
1822 if (field < 0) {
1823 break;
1824 }
1825 }
1826 }
1827
1828 ucal_setMillis(ucal, date2015Feb25, &status);
1829 status = U_ZERO_ERROR;
1830 ulen = udat_formatCalendarForFields(udfmt, ucal, ubuf, kUBufFieldsLen, fpositer, &status);
1831 if ( U_FAILURE(status) ) {
1832 log_err("udat_formatCalendarForFields fails, status %s\n", u_errorName(status));
1833 } else {
1834 for (fptr = expectedFields; ; fptr++) {
1835 field = ufieldpositer_next(fpositer, &beginPos, &endPos);
1836 if (field != fptr->field || (field >= 0 && (beginPos != fptr->beginPos || endPos != fptr->endPos))) {
1837 if (fptr->field >= 0) {
1838 log_err("udat_formatFudat_formatCalendarForFieldsorFields as \"%s\"; expect field %d range %d-%d, get field %d range %d-%d\n",
1839 aescstrdup(ubuf, ulen), fptr->field, fptr->beginPos, fptr->endPos, field, beginPos, endPos);
1840 } else {
1841 log_err("udat_formatCalendarForFields as \"%s\"; expect field < 0, get field %d range %d-%d\n",
1842 aescstrdup(ubuf, ulen), field, beginPos, endPos);
1843 }
1844 break;
1845 }
1846 if (field < 0) {
1847 break;
1848 }
1849 }
1850 }
1851
1852 udat_applyPattern(udfmt, FALSE, patNoFields, -1);
1853 status = U_ZERO_ERROR;
1854 ulen = udat_formatForFields(udfmt, date2015Feb25, ubuf, kUBufFieldsLen, fpositer, &status);
1855 if ( U_FAILURE(status) ) {
1856 log_err("udat_formatForFields with no-field pattern fails, status %s\n", u_errorName(status));
1857 } else {
1858 field = ufieldpositer_next(fpositer, &beginPos, &endPos);
1859 if (field >= 0) {
1860 log_err("udat_formatForFields with no-field pattern as \"%s\"; expect field < 0, get field %d range %d-%d\n",
1861 aescstrdup(ubuf, ulen), field, beginPos, endPos);
1862 }
1863 }
1864
1865 ucal_close(ucal);
1866 udat_close(udfmt);
1867 }
1868 ufieldpositer_close(fpositer);
1869 }
1870 }
1871
TestForceGannenNumbering(void)1872 static void TestForceGannenNumbering(void) {
1873 UErrorCode status;
1874 const char* locID = "ja_JP@calendar=japanese";
1875 UDate refDate = 600336000000.0; // 1989 Jan 9 Monday = Heisei 1
1876 const UChar* testSkeleton = u"yMMMd";
1877
1878 // Test Gannen year forcing
1879 status = U_ZERO_ERROR;
1880 UDateTimePatternGenerator* dtpgen = udatpg_open(locID, &status);
1881 if (U_FAILURE(status)) {
1882 log_data_err("Fail in udatpg_open locale %s: %s", locID, u_errorName(status));
1883 } else {
1884 UChar pattern[kUbufMax];
1885 int32_t patlen = udatpg_getBestPattern(dtpgen, testSkeleton, -1, pattern, kUbufMax, &status);
1886 if (U_FAILURE(status)) {
1887 log_data_err("Fail in udatpg_getBestPattern locale %s: %s", locID, u_errorName(status));
1888 } else {
1889 UDateFormat *testFmt = udat_open(UDAT_PATTERN, UDAT_PATTERN, locID, NULL, 0, pattern, patlen, &status);
1890 if (U_FAILURE(status)) {
1891 log_data_err("Fail in udat_open locale %s: %s", locID, u_errorName(status));
1892 } else {
1893 UChar testString[kUbufMax];
1894 int32_t testStrLen = udat_format(testFmt, refDate, testString, kUbufMax, NULL, &status);
1895 if (U_FAILURE(status)) {
1896 log_err("Fail in udat_format locale %s: %s", locID, u_errorName(status));
1897 } else if (testStrLen < 3 || testString[2] != 0x5143) {
1898 char bbuf[kBbufMax];
1899 u_austrncpy(bbuf, testString, testStrLen);
1900 log_err("Formatting year 1 as Gannen, got%s but expected 3rd char to be 0x5143", bbuf);
1901 }
1902 udat_close(testFmt);
1903 }
1904 }
1905 udatpg_close(dtpgen);
1906 }
1907 }
1908 #endif /* #if !UCONFIG_NO_FORMATTING */
1909