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