]> git.saurik.com Git - apple/icu.git/blame - icuSources/test/cintltst/cdattst.c
ICU-57132.0.1.tar.gz
[apple/icu.git] / icuSources / test / cintltst / cdattst.c
CommitLineData
b75a7d8f 1/********************************************************************
2ca993e8
A
2 * COPYRIGHT:
3 * Copyright (c) 1997-2016, International Business Machines Corporation and
b75a7d8f
A
4 * others. All Rights Reserved.
5 ********************************************************************/
6/********************************************************************************
7*
8* File CDATTST.C
9*
10* Modification History:
2ca993e8 11* Name Description
b75a7d8f
A
12* Madhu Katragadda Creation
13*********************************************************************************
14*/
15
16/* C API TEST FOR DATE FORMAT */
17
18#include "unicode/utypes.h"
19
20#if !UCONFIG_NO_FORMATTING
21
22#include "unicode/uloc.h"
23#include "unicode/udat.h"
4388f060 24#include "unicode/udatpg.h"
b75a7d8f
A
25#include "unicode/ucal.h"
26#include "unicode/unum.h"
27#include "unicode/ustring.h"
b331163b 28#include "unicode/ufieldpositer.h"
b75a7d8f
A
29#include "cintltst.h"
30#include "cdattst.h"
31#include "cformtst.h"
32#include "cmemory.h"
b331163b 33#include "unicode/uatimeunitformat.h" /* Apple-specific */
b75a7d8f 34
374ca955
A
35#include <math.h>
36
37static void TestExtremeDates(void);
73c04bcf 38static void TestAllLocales(void);
46f4442e 39static void TestRelativeCrash(void);
4388f060 40static void TestContext(void);
51004dcb 41static void TestCalendarDateParse(void);
b331163b
A
42static void TestParseErrorReturnValue(void);
43static void TestFormatForFields(void);
2ca993e8 44static void TestStandardPatterns(void);
b331163b 45static void TestApplyPatnOverridesTimeSep(void);
2ca993e8 46static void Test12HrFormats(void);
b331163b
A
47static void TestTimeUnitFormat(void); /* Apple-specific */
48static void TestRemapPatternWithOpts(void); /* Apple-specific */
374ca955 49
b75a7d8f
A
50void addDateForTest(TestNode** root);
51
374ca955 52#define TESTCASE(x) addTest(root, &x, "tsformat/cdattst/" #x)
b75a7d8f
A
53
54void addDateForTest(TestNode** root)
55{
374ca955 56 TESTCASE(TestDateFormat);
46f4442e 57 TESTCASE(TestRelativeDateFormat);
374ca955
A
58 TESTCASE(TestSymbols);
59 TESTCASE(TestDateFormatCalendar);
60 TESTCASE(TestExtremeDates);
73c04bcf 61 TESTCASE(TestAllLocales);
46f4442e 62 TESTCASE(TestRelativeCrash);
4388f060 63 TESTCASE(TestContext);
51004dcb 64 TESTCASE(TestCalendarDateParse);
b331163b
A
65 TESTCASE(TestOverrideNumberFormat);
66 TESTCASE(TestParseErrorReturnValue);
67 TESTCASE(TestFormatForFields);
2ca993e8 68 TESTCASE(TestStandardPatterns);
b331163b 69 TESTCASE(TestApplyPatnOverridesTimeSep);
2ca993e8 70 TESTCASE(Test12HrFormats);
b331163b
A
71 TESTCASE(TestTimeUnitFormat); /* Apple-specific */
72 TESTCASE(TestRemapPatternWithOpts); /* Apple-specific */
b75a7d8f
A
73}
74/* Testing the DateFormat API */
75static void TestDateFormat()
76{
77 UDateFormat *def, *fr, *it, *de, *def1, *fr_pat;
78 UDateFormat *any;
79 UDateFormat *copy;
80 UErrorCode status = U_ZERO_ERROR;
81 UChar* result = NULL;
82 const UCalendar *cal;
83 const UNumberFormat *numformat1, *numformat2;
b331163b 84 UNumberFormat *adoptNF;
46f4442e 85 UChar temp[50];
b75a7d8f
A
86 int32_t numlocales;
87 UDate d1;
88 int i;
89 int32_t resultlength;
90 int32_t resultlengthneeded;
91 int32_t parsepos;
92 UDate d = 837039928046.0;
93 double num = -10456.37;
94 /*const char* str="yyyy.MM.dd G 'at' hh:mm:ss z";
95 const char t[]="2/3/76 2:50 AM";*/
96 /*Testing udat_open() to open a dateformat */
374ca955
A
97
98 ctest_setTimeZone(NULL, &status);
99
b75a7d8f
A
100 log_verbose("\nTesting udat_open() with various parameters\n");
101 fr = udat_open(UDAT_FULL, UDAT_DEFAULT, "fr_FR", NULL,0, NULL, 0,&status);
102 if(U_FAILURE(status))
103 {
2ca993e8 104 log_data_err("FAIL: error in creating the dateformat using full time style with french locale -> %s (Are you missing data?)\n",
b75a7d8f
A
105 myErrorName(status) );
106 return;
107 }
2ca993e8 108 /* this is supposed to open default date format, but later on it treats it like it is "en_US"
b75a7d8f
A
109 - very bad if you try to run the tests on machine where default locale is NOT "en_US" */
110 /* def = udat_open(UDAT_SHORT, UDAT_SHORT, NULL, NULL, 0, &status); */
111 def = udat_open(UDAT_SHORT, UDAT_SHORT, "en_US", NULL, 0,NULL, 0, &status);
112 if(U_FAILURE(status))
113 {
2ca993e8 114 log_err("FAIL: error in creating the dateformat using short date and time style\n %s\n",
b75a7d8f
A
115 myErrorName(status) );
116 return;
117 }
118 it = udat_open(UDAT_DEFAULT, UDAT_MEDIUM, "it_IT", NULL, 0, NULL, 0,&status);
119 if(U_FAILURE(status))
120 {
2ca993e8 121 log_err("FAIL: error in creating the dateformat using medium date style with italian locale\n %s\n",
b75a7d8f
A
122 myErrorName(status) );
123 return;
124 }
125 de = udat_open(UDAT_LONG, UDAT_LONG, "de_DE", NULL, 0, NULL, 0,&status);
126 if(U_FAILURE(status))
127 {
128 log_err("FAIL: error in creating the dateformat using long time and date styles with german locale\n %s\n",
129 myErrorName(status));
130 return;
131 }
132 /*creating a default dateformat */
133 def1 = udat_open(UDAT_SHORT, UDAT_SHORT, NULL, NULL, 0,NULL, 0, &status);
134 if(U_FAILURE(status))
135 {
2ca993e8 136 log_err("FAIL: error in creating the dateformat using short date and time style\n %s\n",
b75a7d8f
A
137 myErrorName(status) );
138 return;
139 }
140
141
2ca993e8 142 /*Testing udat_getAvailable() and udat_countAvailable()*/
b75a7d8f
A
143 log_verbose("\nTesting getAvailableLocales and countAvailable()\n");
144 numlocales=udat_countAvailable();
145 /* use something sensible w/o hardcoding the count */
146 if(numlocales < 0)
147 log_data_err("FAIL: error in countAvailable\n");
148 log_verbose("The number of locales for which date/time formatting patterns are available is %d\n", numlocales);
2ca993e8 149
b75a7d8f
A
150 for(i=0;i<numlocales;i++) {
151 UErrorCode subStatus = U_ZERO_ERROR;
152 log_verbose("Testing open of %s\n", udat_getAvailable(i));
73c04bcf 153 any = udat_open(UDAT_SHORT, UDAT_SHORT, udat_getAvailable(i), NULL ,0, NULL, 0, &subStatus);
b75a7d8f 154 if(U_FAILURE(subStatus)) {
73c04bcf 155 log_data_err("FAIL: date format %s (getAvailable(%d)) is not instantiable: %s\n", udat_getAvailable(i), i, u_errorName(subStatus));
b75a7d8f
A
156 }
157 udat_close(any);
158 }
159
160 /*Testing udat_clone()*/
161 log_verbose("\nTesting the udat_clone() function of date format\n");
162 copy=udat_clone(def, &status);
163 if(U_FAILURE(status)){
164 log_err("Error in creating the clone using udat_clone: %s\n", myErrorName(status) );
165 }
166 /*if(def != copy)
167 log_err("Error in udat_clone");*/ /*how should i check for equality???? */
2ca993e8 168
b75a7d8f
A
169 /*Testing udat_format()*/
170 log_verbose("\nTesting the udat_format() function of date format\n");
51004dcb 171 u_uastrcpy(temp, "7/10/96, 4:05 PM");
b75a7d8f
A
172 /*format using def */
173 resultlength=0;
174 resultlengthneeded=udat_format(def, d, NULL, resultlength, NULL, &status);
175 if(status==U_BUFFER_OVERFLOW_ERROR)
176 {
177 status=U_ZERO_ERROR;
178 resultlength=resultlengthneeded+1;
179 if(result != NULL) {
180 free(result);
181 result = NULL;
182 }
183 result=(UChar*)malloc(sizeof(UChar) * resultlength);
184 udat_format(def, d, result, resultlength, NULL, &status);
185 }
186 if(U_FAILURE(status) || !result)
187 {
188 log_err("FAIL: Error in formatting using udat_format(.....) %s\n", myErrorName(status) );
189 return;
190 }
191 else
192 log_verbose("PASS: formatting successful\n");
193 if(u_strcmp(result, temp)==0)
46f4442e 194 log_verbose("PASS: Date Format for US locale successful using udat_format()\n");
729e4ab9
A
195 else {
196 char xbuf[2048];
197 char gbuf[2048];
198 u_austrcpy(xbuf, temp);
199 u_austrcpy(gbuf, result);
200 log_err("FAIL: Date Format for US locale failed using udat_format() - expected %s got %s\n", xbuf, gbuf);
201 }
b75a7d8f 202 /*format using fr */
2ca993e8
A
203
204 u_unescape("10 juil. 1996 \\u00E0 16:05:28 heure d\\u2019\\u00E9t\\u00E9 du Pacifique", temp, 50);
b75a7d8f
A
205 if(result != NULL) {
206 free(result);
207 result = NULL;
208 }
209 result=myDateFormat(fr, d);
210 if(u_strcmp(result, temp)==0)
374ca955 211 log_verbose("PASS: Date Format for french locale successful using udat_format()\n");
b75a7d8f 212 else
46f4442e
A
213 log_data_err("FAIL: Date Format for french locale failed using udat_format().\n" );
214
374ca955 215 /*format using it */
b331163b 216 u_uastrcpy(temp, "10 lug 1996, 16:05:28");
2ca993e8
A
217
218 {
46f4442e
A
219 UChar *fmtted;
220 char g[100];
221 char x[100];
2ca993e8 222
46f4442e
A
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 }
2ca993e8 232
b75a7d8f
A
233 /*Testing parsing using udat_parse()*/
234 log_verbose("\nTesting parsing using udat_parse()\n");
51004dcb 235 u_uastrcpy(temp,"2/3/76, 2:50 AM");
b75a7d8f 236 parsepos=0;
374ca955 237 status=U_ZERO_ERROR;
2ca993e8 238
b75a7d8f
A
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 */
2ca993e8
A
247
248
b75a7d8f
A
249 if(u_strcmp(myDateFormat(def, d1),temp)!=0)
250 log_err("FAIL: error in parsing\n");
251
374ca955
A
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;
2ca993e8 256
374ca955
A
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");
2ca993e8
A
264
265
266
b75a7d8f
A
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 */
51004dcb 271 fr_pat=udat_open(UDAT_PATTERN, UDAT_PATTERN,"fr_FR",NULL,0,temp, u_strlen(temp), &status);
b75a7d8f
A
272 if(U_FAILURE(status))
273 {
2ca993e8 274 log_err("FAIL: Error in creating a date format using udat_openPattern \n %s\n",
b75a7d8f
A
275 myErrorName(status) );
276 }
277 else
278 log_verbose("PASS: creating dateformat using udat_openPattern() succesful\n");
279
2ca993e8 280
b75a7d8f
A
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 {
2ca993e8 297 log_err("FAIL: error in extracting the pattern from UNumberFormat\n %s\n",
b75a7d8f
A
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");
2ca993e8 304
b75a7d8f 305 if(result != NULL) {
2ca993e8 306 free(result);
b75a7d8f
A
307 result = NULL;
308 }
2ca993e8
A
309
310
b75a7d8f
A
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));
2ca993e8 315 if(udat_isLenient(fr) != udat_isLenient(it))
b75a7d8f
A
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
2ca993e8 346
b75a7d8f
A
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");
2ca993e8 357
b331163b
A
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");
b75a7d8f
A
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);
2ca993e8
A
382
383
b75a7d8f
A
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");
2ca993e8 389
b75a7d8f
A
390 if(result!=NULL) {
391 free(result);
392 }
2ca993e8 393
b75a7d8f
A
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);
2ca993e8 402
374ca955 403 ctest_resetTimeZone();
b75a7d8f
A
404}
405
46f4442e
A
406/*
407Test combined relative date formatting (relative date + non-relative time).
408This is a bit tricky since we can't have static test data for comparison, the
409relative date formatting is relative to the time the tests are run. We generate
410the data for comparison dynamically. However, the tests could fail if they are
411run right at midnight Pacific time and the call to ucal_getNow() is before midnight
412while the calls to udat_format are after midnight or span midnight.
413*/
414static const UDate dayInterval = 24.0*60.0*60.0*1000.0;
415static const UChar trdfZone[] = { 0x0055, 0x0053, 0x002F, 0x0050, 0x0061, 0x0063, 0x0069, 0x0066, 0x0069, 0x0063, 0 }; /* US/Pacific */
416static const char trdfLocale[] = "en_US";
417static const UChar minutesPatn[] = { 0x006D, 0x006D, 0 }; /* "mm" */
418static const UChar monthLongPatn[] = { 0x004D, 0x004D, 0x004D, 0x004D, 0 }; /* "MMMM" */
419static const UChar monthMediumPatn[] = { 0x004D, 0x004D, 0x004D, 0 }; /* "MMM" */
420static const UChar monthShortPatn[] = { 0x004D, 0 }; /* "M" */
421static const UDateFormatStyle dateStylesList[] = { UDAT_FULL, UDAT_LONG, UDAT_MEDIUM, UDAT_SHORT, UDAT_NONE };
422static const UChar *monthPatnsList[] = { monthLongPatn, monthLongPatn, monthMediumPatn, monthShortPatn, NULL };
423static const UChar newTimePatn[] = { 0x0048, 0x0048, 0x002C, 0x006D, 0x006D, 0 }; /* "HH,mm" */
424static const UChar minutesStr[] = { 0x0034, 0x0039, 0 }; /* "49", minutes string to search for in output */
425enum { kDateOrTimeOutMax = 96, kDateAndTimeOutMax = 192 };
426
51004dcb
A
427static const UDate minutesTolerance = 2 * 60.0 * 1000.0;
428static const UDate daysTolerance = 2 * 24.0 * 60.0 * 60.0 * 1000.0;
429
46f4442e
A
430static 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 ) {
729e4ab9 448 log_data_err("Generate UDate for a specified time today fails, error %s - (Are you missing data?)\n", myErrorName(status) );
46f4442e
A
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;
51004dcb
A
457 UChar strDateTime[kDateAndTimeOutMax];
458 UChar strDate[kDateOrTimeOutMax];
459 UChar strTime[kDateOrTimeOutMax];
460 UChar * strPtr;
46f4442e
A
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) ) {
729e4ab9 465 log_data_err("udat_open timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s (Are you missing data?)\n", *stylePtr, myErrorName(status) );
46f4442e
A
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) ) {
51004dcb
A
484 log_err("udat_toPatternRelativeDate timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
485 status = U_ZERO_ERROR;
46f4442e 486 } else if ( u_strstr(strDate, *monthPtnPtr) == NULL || dtpatLen != u_strlen(strDate) ) {
51004dcb 487 log_err("udat_toPatternRelativeDate timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) date pattern incorrect\n", *stylePtr );
46f4442e
A
488 }
489 dtpatLen = udat_toPatternRelativeTime(fmtRelDateTime, strTime, kDateAndTimeOutMax, &status);
490 if ( U_FAILURE(status) ) {
51004dcb
A
491 log_err("udat_toPatternRelativeTime timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
492 status = U_ZERO_ERROR;
46f4442e 493 } else if ( u_strstr(strTime, minutesPatn) == NULL || dtpatLen != u_strlen(strTime) ) {
51004dcb 494 log_err("udat_toPatternRelativeTime timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) time pattern incorrect\n", *stylePtr );
46f4442e
A
495 }
496 dtpatLen = udat_toPattern(fmtRelDateTime, FALSE, strDateTime, kDateAndTimeOutMax, &status);
497 if ( U_FAILURE(status) ) {
51004dcb
A
498 log_err("udat_toPattern timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
499 status = U_ZERO_ERROR;
46f4442e 500 } else if ( u_strstr(strDateTime, strDate) == NULL || u_strstr(strDateTime, strTime) == NULL || dtpatLen != u_strlen(strDateTime) ) {
51004dcb 501 log_err("udat_toPattern timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) dateTime pattern incorrect\n", *stylePtr );
46f4442e
A
502 }
503 udat_applyPatternRelative(fmtRelDateTime, strDate, u_strlen(strDate), newTimePatn, u_strlen(newTimePatn), &status);
504 if ( U_FAILURE(status) ) {
51004dcb
A
505 log_err("udat_applyPatternRelative timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
506 status = U_ZERO_ERROR;
46f4442e 507 } else {
51004dcb
A
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 }
46f4442e
A
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 {
51004dcb
A
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;
2ca993e8 534 }
51004dcb 535
46f4442e
A
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 );
51004dcb
A
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;
2ca993e8 550 }
46f4442e
A
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 = 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
b75a7d8f
A
579/*Testing udat_getSymbols() and udat_setSymbols() and udat_countSymbols()*/
580static void TestSymbols()
581{
b331163b 582 UDateFormat *def, *fr, *zhChiCal;
b75a7d8f 583 UErrorCode status = U_ZERO_ERROR;
2ca993e8 584 UChar *value=NULL;
b75a7d8f
A
585 UChar *result = NULL;
586 int32_t resultlength;
587 int32_t resultlengthout;
588 UChar *pattern;
2ca993e8 589
b75a7d8f
A
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 {
2ca993e8 596 log_data_err("error in creating the dateformat using full time style with french locale -> %s (Are you missing data?)\n",
b75a7d8f
A
597 myErrorName(status) );
598 return;
599 }
600 /*creating a default dateformat */
601 log_verbose("\ncreating a date format with default locale\n");
2ca993e8 602 /* this is supposed to open default date format, but later on it treats it like it is "en_US"
b75a7d8f
A
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 {
2ca993e8 608 log_err("error in creating the dateformat using short date and time style\n %s\n",
b75a7d8f
A
609 myErrorName(status) );
610 return;
611 }
b331163b
A
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 {
2ca993e8 617 log_data_err("error in creating the dateformat using full date, no time, locale zh@calendar=chinese -> %s (Are you missing data?)\n",
b331163b
A
618 myErrorName(status) );
619 return;
620 }
2ca993e8
A
621
622
b75a7d8f
A
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 */
2ca993e8 626 if(udat_countSymbols(def, UDAT_ERAS)!=2 || udat_countSymbols(def, UDAT_MONTHS)!=12 ||
b75a7d8f
A
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 ||
73c04bcf 629 udat_countSymbols(def, UDAT_QUARTERS) != 4 || udat_countSymbols(def, UDAT_SHORT_QUARTERS) != 4 ||
b331163b
A
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)
b75a7d8f
A
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);
2ca993e8 654
b75a7d8f
A
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.");
51004dcb 673 VerifygetSymbols(fr, UDAT_SHORTER_WEEKDAYS, 7, "sa");
b75a7d8f
A
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");
73c04bcf
A
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");
b331163b
A
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");
2ca993e8
A
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
b75a7d8f
A
695
696
697 if(result != NULL) {
698 free(result);
699 result = NULL;
700 }
2ca993e8
A
701free(pattern);
702
b75a7d8f
A
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 {
2ca993e8 716 log_err("FAIL: error in extracting the pattern from UNumberFormat\n %s\n",
b75a7d8f
A
717 myErrorName(status) );
718 }
2ca993e8 719
b75a7d8f
A
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 {
2ca993e8 736 log_err("FAIL: error in extracting the pattern from UNumberFormat\n %s\n",
b75a7d8f
A
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
744free(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);
2ca993e8 757
b75a7d8f
A
758 }
759 if(U_FAILURE(status))
760 log_err("FAIL: error in getSymbols() %s\n", myErrorName(status) );
761 resultlength=resultlengthout+1;
2ca993e8 762
b75a7d8f
A
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");
2ca993e8 770
b75a7d8f
A
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");
2ca993e8 781
b75a7d8f
A
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");
2ca993e8
A
786
787
b75a7d8f
A
788 /*run series of tests to test setSymbols regressively*/
789 log_verbose("\nTesting setSymbols regressively\n");
b75a7d8f 790 VerifysetSymbols(def, UDAT_ERAS, 0, "BeforeChrist");
73c04bcf
A
791 VerifysetSymbols(def, UDAT_ERA_NAMES, 1, "AnnoDomini");
792 VerifysetSymbols(def, UDAT_WEEKDAYS, 1, "Sundayweek");
b75a7d8f 793 VerifysetSymbols(def, UDAT_SHORT_WEEKDAYS, 7, "Satweek");
73c04bcf
A
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");
b75a7d8f
A
798 VerifysetSymbols(fr, UDAT_MONTHS, 11, "december");
799 VerifysetSymbols(fr, UDAT_SHORT_MONTHS, 0, "Jan");
73c04bcf
A
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");
b331163b
A
808 VerifysetSymbols(zhChiCal, UDAT_CYCLIC_YEARS_ABBREVIATED, 1, "yi-chou");
809 VerifysetSymbols(zhChiCal, UDAT_ZODIAC_NAMES_ABBREVIATED, 1, "Ox");
810
b75a7d8f 811
b75a7d8f
A
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*/
2ca993e8 826
b75a7d8f
A
827 udat_close(fr);
828 udat_close(def);
b331163b 829 udat_close(zhChiCal);
b75a7d8f
A
830 if(result != NULL) {
831 free(result);
832 result = NULL;
833 }
834 free(value);
2ca993e8 835
b75a7d8f
A
836}
837
838/**
839 * Test DateFormat(Calendar) API
840 */
841static 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;
b331163b
A
849 UChar buf1[256];
850 int32_t len1;
851 const char *expected;
852 UChar uExpected[32];
b75a7d8f 853
374ca955
A
854 ctest_setTimeZone(NULL, &ec);
855
b75a7d8f
A
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)) {
2ca993e8 859 log_data_err("FAIL: udat_open(NONE, SHORT, en_US) failed with %s (Are you missing data?)\n",
b75a7d8f
A
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)) {
2ca993e8 867 log_err("FAIL: udat_open(SHORT, NONE, en_US) failed with %s\n",
b75a7d8f
A
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)) {
2ca993e8 875 log_err("FAIL: udat_open(FULL, FULL, en_US) failed with %s\n",
b75a7d8f
A
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)) {
2ca993e8 883 log_err("FAIL: ucal_open(en_US) failed with %s\n",
b75a7d8f
A
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
b331163b
A
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
b75a7d8f
A
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 }
b331163b
A
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
b75a7d8f
A
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 {
374ca955 951 log_err("FAIL: Parsed result: %s, exp 4/5/2001 5:45 PM\n", cbuf);
b75a7d8f
A
952 }
953
2ca993e8 954 FAIL:
b75a7d8f
A
955 udat_close(date);
956 udat_close(time);
957 udat_close(full);
958 ucal_close(cal);
374ca955
A
959
960 ctest_resetTimeZone();
b75a7d8f
A
961}
962
51004dcb
A
963
964
965/**
57a6839d 966 * Test parsing two digit year against "YY" vs. "YYYY" patterns
51004dcb
A
967 */
968static void TestCalendarDateParse() {
969
57a6839d
A
970 int32_t result;
971 UErrorCode ec = U_ZERO_ERROR;
51004dcb 972 UDateFormat* simpleDateFormat = 0;
57a6839d
A
973 int32_t parsePos = 0;
974 int32_t twoDigitCenturyStart = 75;
975 int32_t currentTwoDigitYear = 0;
976 int32_t startCentury = 0;
51004dcb
A
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) {
57a6839d 999 startCentury -= 100;
51004dcb 1000 }
57a6839d
A
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);
51004dcb 1005
57a6839d
A
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);
51004dcb 1009
57a6839d 1010 udat_parseCalendar(simpleDateFormat, calendar, text, u_strlen(text), &parsePos, &ec);
51004dcb
A
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));
57a6839d 1026 udat_parseCalendar(simpleDateFormat, calendar, text, u_strlen(text), &parsePos, &ec);
51004dcb
A
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
b75a7d8f 1047/*INTERNAL FUNCTIONS USED*/
51004dcb
A
1048static 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
729e4ab9
A
1063/* N.B.: use idx instead of index to avoid 'shadow' warnings in strict mode. */
1064static void VerifygetSymbols(UDateFormat* datfor, UDateFormatSymbolType type, int32_t idx, const char* expected)
b75a7d8f
A
1065{
1066 UChar *pattern=NULL;
1067 UErrorCode status = U_ZERO_ERROR;
1068 UChar *result=NULL;
1069 int32_t resultlength, resultlengthout;
b331163b 1070 int32_t patternSize = strlen(expected) + 1;
2ca993e8 1071
b331163b
A
1072 pattern=(UChar*)malloc(sizeof(UChar) * patternSize);
1073 u_unescape(expected, pattern, patternSize);
b75a7d8f 1074 resultlength=0;
729e4ab9 1075 resultlengthout=udat_getSymbols(datfor, type, idx , NULL, resultlength, &status);
b75a7d8f
A
1076 if(status==U_BUFFER_OVERFLOW_ERROR)
1077 {
1078 status=U_ZERO_ERROR;
1079 resultlength=resultlengthout+1;
1080 result=(UChar*)malloc(sizeof(UChar) * resultlength);
729e4ab9 1081 udat_getSymbols(datfor, type, idx, result, resultlength, &status);
2ca993e8 1082
b75a7d8f
A
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{
2ca993e8 1092 log_data_err("FAIL: getSymbols retrieved the wrong value\n Expected %s Got %s\n", expected,
b331163b 1093 aescstrdup(result,-1) );
b75a7d8f
A
1094 }
1095 free(result);
1096 free(pattern);
1097}
1098
729e4ab9 1099static void VerifysetSymbols(UDateFormat* datfor, UDateFormatSymbolType type, int32_t idx, const char* expected)
b75a7d8f
A
1100{
1101 UChar *result=NULL;
1102 UChar *value=NULL;
1103 int32_t resultlength, resultlengthout;
1104 UErrorCode status = U_ZERO_ERROR;
b331163b 1105 int32_t valueLen, valueSize = strlen(expected) + 1;
b75a7d8f 1106
b331163b
A
1107 value=(UChar*)malloc(sizeof(UChar) * valueSize);
1108 valueLen = u_unescape(expected, value, valueSize);
1109 udat_setSymbols(datfor, type, idx, value, valueLen, &status);
b75a7d8f
A
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;
729e4ab9 1117 resultlengthout=udat_getSymbols(datfor, type, idx, NULL, resultlength, &status);
b75a7d8f
A
1118 if(status==U_BUFFER_OVERFLOW_ERROR){
1119 status=U_ZERO_ERROR;
1120 resultlength=resultlengthout+1;
1121 result=(UChar*)malloc(sizeof(UChar) * resultlength);
729e4ab9 1122 udat_getSymbols(datfor, type, idx, result, resultlength, &status);
b75a7d8f
A
1123 }
1124 if(U_FAILURE(status)){
2ca993e8 1125 log_err("FAIL: error in retrieving the value using getSymbols after setting it previously\n %s\n",
b75a7d8f
A
1126 myErrorName(status) );
1127 return;
1128 }
2ca993e8 1129
b75a7d8f 1130 if(u_strcmp(result, value)!=0){
b331163b
A
1131 log_err("FAIL:Error in setting and then getting symbols\n Expected %s Got %s\n", expected,
1132 aescstrdup(result,-1) );
b75a7d8f
A
1133 }
1134 else
1135 log_verbose("PASS: setSymbols successful\n");
1136
1137 free(value);
1138 free(result);
1139}
1140
1141
729e4ab9 1142static void VerifygetsetSymbols(UDateFormat* from, UDateFormat* to, UDateFormatSymbolType type, int32_t idx)
b75a7d8f
A
1143{
1144 UChar *result=NULL;
1145 UChar *value=NULL;
1146 int32_t resultlength, resultlengthout;
1147 UErrorCode status = U_ZERO_ERROR;
2ca993e8 1148
b75a7d8f 1149 resultlength=0;
729e4ab9 1150 resultlengthout=udat_getSymbols(from, type, idx , NULL, resultlength, &status);
b75a7d8f
A
1151 if(status==U_BUFFER_OVERFLOW_ERROR){
1152 status=U_ZERO_ERROR;
1153 resultlength=resultlengthout+1;
1154 result=(UChar*)malloc(sizeof(UChar) * resultlength);
729e4ab9 1155 udat_getSymbols(from, type, idx, result, resultlength, &status);
b75a7d8f
A
1156 }
1157 if(U_FAILURE(status)){
1158 log_err("FAIL: error in getSymbols() %s\n", myErrorName(status) );
1159 return;
1160 }
2ca993e8 1161
b75a7d8f 1162 resultlength=resultlengthout+1;
729e4ab9 1163 udat_setSymbols(to, type, idx, result, resultlength, &status);
b75a7d8f
A
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;
729e4ab9 1171 resultlengthout=udat_getSymbols(to, type, idx, NULL, resultlength, &status);
b75a7d8f
A
1172 if(status==U_BUFFER_OVERFLOW_ERROR){
1173 status=U_ZERO_ERROR;
1174 resultlength=resultlengthout+1;
1175 value=(UChar*)malloc(sizeof(UChar) * resultlength);
729e4ab9 1176 udat_getSymbols(to, type, idx, value, resultlength, &status);
b75a7d8f
A
1177 }
1178 if(U_FAILURE(status)){
2ca993e8 1179 log_err("FAIL: error in retrieving the value using getSymbols i.e roundtrip\n %s\n",
b75a7d8f
A
1180 myErrorName(status) );
1181 return;
1182 }
2ca993e8 1183
b75a7d8f
A
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
1196static UChar* myNumformat(const UNumberFormat* numfor, double d)
1197{
1198 UChar *result2=NULL;
1199 int32_t resultlength, resultlengthneeded;
1200 UErrorCode status = U_ZERO_ERROR;
2ca993e8 1201
b75a7d8f
A
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 }
2ca993e8 1217
b75a7d8f
A
1218 return result2;
1219}
1220
374ca955
A
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 */
1232static 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 */
1252static 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 */
1281static 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. */
2ca993e8 1291
374ca955
A
1292 ec = U_ZERO_ERROR;
1293 fmt = udat_open(UDAT_LONG, UDAT_LONG, "en_US",
1294 0, 0, 0, 0, &ec);
729e4ab9
A
1295 if (U_FAILURE(ec)) {
1296 log_data_err("FAIL: udat_open (%s) (Are you missing data?)\n", u_errorName(ec));
1297 return;
1298 }
374ca955 1299
2ca993e8 1300 _aux2ExtremeDates(fmt, small, large, buf, UPRV_LENGTHOF(buf), cbuf, 0, &ec);
374ca955
A
1301
1302 udat_close(fmt);
1303}
1304
73c04bcf
A
1305static 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++) {
2ca993e8
A
1312 for (dateIdx = 0; dateIdx < UPRV_LENGTHOF(style); dateIdx++) {
1313 for (timeIdx = 0; timeIdx < UPRV_LENGTHOF(style); timeIdx++) {
73c04bcf
A
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
46f4442e
A
1326static 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);
2ca993e8 1341 udat_set2DigitYearStart(icudf, aDate, &subStatus);
46f4442e
A
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));
2ca993e8 1346 }
46f4442e
A
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));
2ca993e8 1360 }
46f4442e
A
1361 }
1362 {
1363 UErrorCode subStatus = U_ZERO_ERROR;
1364 what = "udat_get2DigitYearStart";
1365 log_verbose("Trying %s on a relative date..\n", what);
2ca993e8 1366 udat_get2DigitYearStart(icudf, &subStatus);
46f4442e
A
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));
2ca993e8 1371 }
46f4442e
A
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);
2ca993e8 1378 udat_toPattern(icudf, TRUE,NULL,0, &subStatus);
46f4442e
A
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));
2ca993e8 1383 }
46f4442e
A
1384 }
1385 {
1386 UErrorCode subStatus = U_ZERO_ERROR;
1387 what = "udat_applyPattern";
1388 log_verbose("Trying %s on a relative date..\n", what);
2ca993e8 1389 udat_applyPattern(icudf, FALSE,tzName,-1);
46f4442e
A
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));
2ca993e8 1395 }
46f4442e
A
1396 }
1397 {
51004dcb 1398 UChar erabuf[32];
46f4442e
A
1399 UErrorCode subStatus = U_ZERO_ERROR;
1400 what = "udat_getSymbols";
1401 log_verbose("Trying %s on a relative date..\n", what);
2ca993e8 1402 udat_getSymbols(icudf, UDAT_ERAS,0,erabuf,UPRV_LENGTHOF(erabuf), &subStatus);
729e4ab9
A
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));
2ca993e8 1407 }
729e4ab9
A
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 */
46f4442e
A
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));
2ca993e8 1419 }
46f4442e
A
1420 }
1421 {
1422 UErrorCode subStatus = U_ZERO_ERROR;
1423 what = "udat_countSymbols";
1424 log_verbose("Trying %s on a relative date..\n", what);
2ca993e8 1425 udat_countSymbols(icudf, UDAT_ERAS);
46f4442e
A
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));
2ca993e8 1431 }
46f4442e 1432 }
2ca993e8 1433
46f4442e
A
1434 udat_close(icudf);
1435 } else {
729e4ab9 1436 log_data_err("FAIL: err calling udat_open() ->%s (Are you missing data?)\n", u_errorName(status));
46f4442e
A
1437 }
1438}
1439
4388f060
A
1440static const UChar skeleton_yMMMM[] = { 0x79,0x4D,0x4D,0x4D,0x4D,0 }; /* "yMMMM"; fr maps to "MMMM y", cs maps to "LLLL y" */
1441static const UChar july2008_frDefault[] = { 0x6A,0x75,0x69,0x6C,0x6C,0x65,0x74,0x20,0x32,0x30,0x30,0x38,0 }; /* "juillet 2008" */
1442static const UChar july2008_frTitle[] = { 0x4A,0x75,0x69,0x6C,0x6C,0x65,0x74,0x20,0x32,0x30,0x30,0x38,0 }; /* "Juillet 2008" sentence-begin, standalone */
1443static const UChar july2008_csDefault[] = { 0x10D,0x65,0x72,0x76,0x65,0x6E,0x65,0x63,0x20,0x32,0x30,0x30,0x38,0 }; /* "c(hacek)ervenec 2008" */
1444static 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
1446typedef struct {
1447 const char * locale;
1448 const UChar * skeleton;
51004dcb 1449 UDisplayContext capitalizationContext;
4388f060
A
1450 const UChar * expectedFormat;
1451} TestContextItem;
1452
1453static const TestContextItem textContextItems[] = {
51004dcb 1454 { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_NONE, july2008_frDefault },
4388f060 1455#if !UCONFIG_NO_BREAK_ITERATION
51004dcb
A
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 },
4388f060 1460#endif
51004dcb 1461 { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_NONE, july2008_csDefault },
4388f060 1462#if !UCONFIG_NO_BREAK_ITERATION
51004dcb
A
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 },
4388f060 1467#endif
51004dcb 1468 { NULL, NULL, (UDisplayContext)0, NULL }
4388f060
A
1469};
1470
57a6839d
A
1471static const UChar today_enDefault[] = { 0x74,0x6F,0x64,0x61,0x79,0 }; /* "today" */
1472static const UChar today_enTitle[] = { 0x54,0x6F,0x64,0x61,0x79,0 }; /* "Today" sentence-begin, uiListOrMenu, standalone */
1473static const UChar yesterday_enDefault[] = { 0x79,0x65,0x73,0x74,0x65,0x72,0x64,0x61,0x79,0 }; /* "yesterday" */
1474static const UChar yesterday_enTitle[] = { 0x59,0x65,0x73,0x74,0x65,0x72,0x64,0x61,0x79,0 }; /* "Yesterday" sentence-begin, uiListOrMenu, standalone */
1475static const UChar today_nbDefault[] = { 0x69,0x20,0x64,0x61,0x67,0 }; /* "i dag" */
1476static const UChar today_nbTitle[] = { 0x49,0x20,0x64,0x61,0x67,0 }; /* "I dag" sentence-begin, standalone */
1477static const UChar yesterday_nbDefault[] = { 0x69,0x20,0x67,0xE5,0x72,0 };
1478static const UChar yesterday_nbTitle[] = { 0x49,0x20,0x67,0xE5,0x72,0 };
1479
1480typedef struct {
1481 const char * locale;
1482 UDisplayContext capitalizationContext;
1483 const UChar * expectedFormatToday;
1484 const UChar * expectedFormatYesterday;
1485} TestRelativeContextItem;
1486
1487static 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
1505static const UChar zoneGMT[] = { 0x47,0x4D,0x54,0 }; /* "GMT" */
1506static const UDate july022008 = 1215000000000.0;
4388f060
A
1507enum { kUbufMax = 64, kBbufMax = 3*kUbufMax };
1508
1509static void TestContext(void) {
57a6839d
A
1510 const TestContextItem* textContextItemPtr;
1511 const TestRelativeContextItem* textRelContextItemPtr;
1512 for (textContextItemPtr = textContextItems; textContextItemPtr->locale != NULL; ++textContextItemPtr) {
4388f060 1513 UErrorCode status = U_ZERO_ERROR;
57a6839d
A
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) ) {
51004dcb 1521 udat_setContext(udfmt, textContextItemPtr->capitalizationContext, &status);
57a6839d 1522 if ( U_SUCCESS(status) ) {
51004dcb 1523 UDisplayContext getContext;
4388f060
A
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 }
51004dcb 1536 getContext = udat_getContext(udfmt, UDISPCTX_TYPE_CAPITALIZATION, &status);
4388f060 1537 if ( U_FAILURE(status) ) {
51004dcb 1538 log_err("FAIL: udat_getContext for locale %s, capitalizationContext %d, status %s\n",
4388f060 1539 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, u_errorName(status) );
51004dcb
A
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 );
4388f060 1543 }
57a6839d
A
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) );
4388f060 1547 }
57a6839d
A
1548 udat_close(udfmt);
1549 } else {
1550 log_data_err("FAIL: udat_open for locale %s, status %s\n", textContextItemPtr->locale, u_errorName(status) );
4388f060 1551 }
57a6839d
A
1552 } else {
1553 log_err("FAIL: udatpg_getBestPattern for locale %s, status %s\n", textContextItemPtr->locale, u_errorName(status) );
4388f060 1554 }
57a6839d
A
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) );
4388f060
A
1608 }
1609 }
1610}
1611
b331163b 1612
2ca993e8 1613// overrideNumberFormat[i][0] is to tell which field to set,
b331163b 1614// overrideNumberFormat[i][1] is the expected result
2ca993e8 1615static const char * overrideNumberFormat[][2] = {
b331163b
A
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
1624static 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 UNumberFormat* overrideFmt;
1647 overrideFmt = unum_open(UNUM_DEFAULT, NULL, 0, localeString, NULL, &status);
1648 assertSuccess("unum_open()", &status);
1649 udat_adoptNumberFormatForFields(fmt, fields, overrideFmt, &status);
1650 overrideFmt = NULL; // no longer valid
1651 assertSuccess("udat_setNumberFormatForField()", &status);
1652
1653 getter_result = udat_getNumberFormatForField(fmt, 'd');
1654 if(getter_result == NULL) {
1655 log_err("FAIL: udat_getNumberFormatForField did not return a valid pointer\n");
1656 }
1657 }
1658 {
1659 UNumberFormat* overrideFmt;
1660 overrideFmt = unum_open(UNUM_DEFAULT, NULL, 0, localeString, NULL, &status);
1661 assertSuccess("unum_open()", &status);
1662 udat_setNumberFormat(fmt, overrideFmt); // test the same override NF will not crash
1663 unum_close(overrideFmt);
1664 }
1665 udat_close(fmt);
2ca993e8 1666
b331163b
A
1667 for (i=0; i<UPRV_LENGTHOF(overrideNumberFormat); i++){
1668 UChar ubuf[kUbufMax];
1669 UDateFormat* fmt2;
1670 UNumberFormat* overrideFmt2;
1671
1672 fmt2 =udat_open(UDAT_PATTERN, UDAT_PATTERN,"en_US", zoneGMT, -1, pattern, u_strlen(pattern), &status);
1673 assertSuccess("udat_open() with en_US", &status);
1674
1675 overrideFmt2 = unum_open(UNUM_DEFAULT, NULL, 0, localeString, NULL, &status);
1676 assertSuccess("unum_open() in loop", &status);
1677
1678 u_uastrcpy(fields, overrideNumberFormat[i][0]);
1679 u_unescape(overrideNumberFormat[i][1], expected, UPRV_LENGTHOF(expected));
1680
1681 if ( strcmp(overrideNumberFormat[i][0], "") == 0 ) { // use the one w/o field
1682 udat_adoptNumberFormat(fmt2, overrideFmt2);
1683 } else if ( strcmp(overrideNumberFormat[i][0], "mixed") == 0 ) { // set 1 field at first but then full override, both(M & d) should be override
1684 const char* singleLocale = "en@numbers=hebr";
1685 UNumberFormat* singleOverrideFmt;
1686 u_uastrcpy(fields, "d");
1687
1688 singleOverrideFmt = unum_open(UNUM_DEFAULT, NULL, 0, singleLocale, NULL, &status);
1689 assertSuccess("unum_open() in mixed", &status);
1690
1691 udat_adoptNumberFormatForFields(fmt2, fields, singleOverrideFmt, &status);
1692 assertSuccess("udat_setNumberFormatForField() in mixed", &status);
1693
1694 udat_adoptNumberFormat(fmt2, overrideFmt2);
1695 } else if ( strcmp(overrideNumberFormat[i][0], "do") == 0 ) { // o is an invalid field
1696 udat_adoptNumberFormatForFields(fmt2, fields, overrideFmt2, &status);
1697 if(status == U_INVALID_FORMAT_ERROR) {
1698 udat_close(fmt2);
1699 status = U_ZERO_ERROR;
1700 continue;
1701 }
1702 } else {
1703 udat_adoptNumberFormatForFields(fmt2, fields, overrideFmt2, &status);
1704 assertSuccess("udat_setNumberFormatForField() in loop", &status);
1705 }
1706
1707 udat_format(fmt2, july022008, ubuf, kUbufMax, NULL, &status);
1708 assertSuccess("udat_format() july022008", &status);
1709
2ca993e8 1710 if (u_strncmp(ubuf, expected, kUbufMax) != 0)
b331163b
A
1711 log_err("fail: udat_format for locale, expected %s, got %s\n",
1712 u_austrncpy(bbuf1,expected,kUbufMax), u_austrncpy(bbuf2,ubuf,kUbufMax) );
1713
1714 udat_close(fmt2);
1715 }
1716}
1717
1718/*
1719 * Ticket #11523
1720 * udat_parse and udat_parseCalendar should have the same error code when given the same invalid input.
1721 */
1722static void TestParseErrorReturnValue(void) {
1723 UErrorCode status = U_ZERO_ERROR;
1724 UErrorCode expectStatus = U_PARSE_ERROR;
1725 UDateFormat* df;
1726 UCalendar* cal;
1727
1728 df = udat_open(UDAT_DEFAULT, UDAT_DEFAULT, NULL, NULL, -1, NULL, -1, &status);
1729 if (!assertSuccessCheck("udat_open()", &status, TRUE)) {
1730 return;
1731 }
1732
1733 cal = ucal_open(NULL, 0, "en_US", UCAL_GREGORIAN, &status);
1734 if (!assertSuccess("ucal_open()", &status)) {
1735 return;
1736 }
1737
1738 udat_parse(df, NULL, -1, NULL, &status);
1739 if (status != expectStatus) {
1740 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));
1741 }
1742
1743 status = U_ZERO_ERROR;
1744 udat_parseCalendar(df, cal, NULL, -1, NULL, &status);
1745 if (status != expectStatus) {
1746 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));
1747 }
1748
1749 ucal_close(cal);
1750 udat_close(df);
1751}
1752
1753/*
1754 * Ticket #11553
1755 * Test new udat_formatForFields, udat_formatCalendarForFields (and UFieldPositionIterator)
1756 */
1757static const char localeForFields[] = "en_US";
1758/* zoneGMT[]defined above */
1759static const UDate date2015Feb25 = 1424841000000.0; /* Wednesday, February 25, 2015 at 5:10:00 AM GMT */
1760
1761typedef struct {
1762 int32_t field;
1763 int32_t beginPos;
1764 int32_t endPos;
1765} FieldsData;
1766static const FieldsData expectedFields[] = {
1767 { UDAT_DAY_OF_WEEK_FIELD /* 9*/, 0, 9 },
1768 { UDAT_MONTH_FIELD /* 2*/, 11, 19 },
1769 { UDAT_DATE_FIELD /* 3*/, 20, 22 },
1770 { UDAT_YEAR_FIELD /* 1*/, 24, 28 },
1771 { UDAT_HOUR1_FIELD /*15*/, 32, 33 },
2ca993e8
A
1772#if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
1773 { UDAT_TIME_SEPARATOR_FIELD /*35*/, 33, 34 },
1774#endif
b331163b 1775 { UDAT_MINUTE_FIELD /* 6*/, 34, 36 },
2ca993e8
A
1776#if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
1777 { UDAT_TIME_SEPARATOR_FIELD /*35*/, 36, 37 },
1778#endif
b331163b
A
1779 { UDAT_SECOND_FIELD /* 7*/, 37, 39 },
1780 { UDAT_AM_PM_FIELD /*14*/, 40, 42 },
1781 { UDAT_TIMEZONE_FIELD /*17*/, 43, 46 },
1782 { -1, -1, -1 },
1783};
1784
1785enum {kUBufFieldsLen = 128, kBBufFieldsLen = 256 };
1786
1787static void TestFormatForFields(void) {
1788 UErrorCode status = U_ZERO_ERROR;
1789 UFieldPositionIterator* fpositer = ufieldpositer_open(&status);
1790 if ( U_FAILURE(status) ) {
1791 log_err("ufieldpositer_open fails, status %s\n", u_errorName(status));
1792 } else {
1793 UDateFormat* udfmt = udat_open(UDAT_LONG, UDAT_FULL, localeForFields, zoneGMT, -1, NULL, 0, &status);
1794 UCalendar* ucal = ucal_open(zoneGMT, -1, localeForFields, UCAL_DEFAULT, &status);
1795 if ( U_FAILURE(status) ) {
1796 log_data_err("udat_open or ucal_open fails for locale %s, status %s (Are you missing data?)\n", localeForFields, u_errorName(status));
1797 } else {
1798 int32_t ulen, field, beginPos, endPos;
1799 UChar ubuf[kUBufFieldsLen];
1800 const FieldsData * fptr;
2ca993e8 1801
b331163b
A
1802 status = U_ZERO_ERROR;
1803 ulen = udat_formatForFields(udfmt, date2015Feb25, ubuf, kUBufFieldsLen, fpositer, &status);
1804 if ( U_FAILURE(status) ) {
1805 log_err("udat_formatForFields fails, status %s\n", u_errorName(status));
1806 } else {
1807 for (fptr = expectedFields; ; fptr++) {
1808 field = ufieldpositer_next(fpositer, &beginPos, &endPos);
1809 if (field != fptr->field || (field >= 0 && (beginPos != fptr->beginPos || endPos != fptr->endPos))) {
1810 if (fptr->field >= 0) {
1811 log_err("udat_formatForFields as \"%s\"; expect field %d range %d-%d, get field %d range %d-%d\n",
1812 aescstrdup(ubuf, ulen), fptr->field, fptr->beginPos, fptr->endPos, field, beginPos, endPos);
1813 } else {
1814 log_err("udat_formatForFields as \"%s\"; expect field < 0, get field %d range %d-%d\n",
1815 aescstrdup(ubuf, ulen), field, beginPos, endPos);
1816 }
1817 break;
1818 }
1819 if (field < 0) {
1820 break;
1821 }
1822 }
1823 }
2ca993e8 1824
b331163b
A
1825 ucal_setMillis(ucal, date2015Feb25, &status);
1826 status = U_ZERO_ERROR;
1827 ulen = udat_formatCalendarForFields(udfmt, ucal, ubuf, kUBufFieldsLen, fpositer, &status);
1828 if ( U_FAILURE(status) ) {
1829 log_err("udat_formatCalendarForFields fails, status %s\n", u_errorName(status));
1830 } else {
1831 for (fptr = expectedFields; ; fptr++) {
1832 field = ufieldpositer_next(fpositer, &beginPos, &endPos);
1833 if (field != fptr->field || (field >= 0 && (beginPos != fptr->beginPos || endPos != fptr->endPos))) {
1834 if (fptr->field >= 0) {
1835 log_err("udat_formatFudat_formatCalendarForFieldsorFields as \"%s\"; expect field %d range %d-%d, get field %d range %d-%d\n",
1836 aescstrdup(ubuf, ulen), fptr->field, fptr->beginPos, fptr->endPos, field, beginPos, endPos);
1837 } else {
1838 log_err("udat_formatCalendarForFields as \"%s\"; expect field < 0, get field %d range %d-%d\n",
1839 aescstrdup(ubuf, ulen), field, beginPos, endPos);
1840 }
1841 break;
1842 }
1843 if (field < 0) {
1844 break;
1845 }
1846 }
1847 }
1848
1849 ucal_close(ucal);
1850 udat_close(udfmt);
1851 }
1852 ufieldpositer_close(fpositer);
1853 }
1854}
1855
2ca993e8
A
1856/* defined above
1857static const UChar zoneGMT[] = { 0x47,0x4D,0x54,0 }; // "GMT"
1858static const UDate date2015Feb25 = 1424841000000.0; // Wednesday, February 25, 2015 at 5:10:00 AM GMT
1859*/
1860
1861typedef struct {
1862 const char * locale;
1863 UDateFormatStyle dateStyle;
1864 UDateFormatStyle timeStyle;
1865 const char * expect; /* for zoneGMT and date2015Feb25 */
1866} StandardPatternItem;
1867
1868static const StandardPatternItem stdPatternItems[] = {
1869 { "en_JP", UDAT_MEDIUM, UDAT_SHORT, "2015 Feb 25 5:10" },
1870 { "en_CN", UDAT_MEDIUM, UDAT_SHORT, "25 Feb 2015, 5:10 AM" },
1871 { "en_TW", UDAT_MEDIUM, UDAT_SHORT, "25 Feb 2015, 5:10 AM" },
1872 { "en_KR", UDAT_MEDIUM, UDAT_SHORT, "25 Feb 2015, 5:10 AM" },
1873 { NULL, (UDateFormatStyle)0, (UDateFormatStyle)0, NULL } /* terminator */
1874};
1875
1876enum { kUbufStdMax = 64, kBbufStdMax = 3*kUbufStdMax };
1877
1878static void TestStandardPatterns(void) {
1879 const StandardPatternItem* itemPtr;
1880 for (itemPtr = stdPatternItems; itemPtr->locale != NULL; itemPtr++) {
1881 UErrorCode status = U_ZERO_ERROR;
1882 UDateFormat* udfmt = udat_open(itemPtr->timeStyle, itemPtr->dateStyle, itemPtr->locale, zoneGMT, -1, NULL, 0, &status);
1883 if ( U_FAILURE(status) ) {
1884 log_err("udat_open(%d, %d, \"%s\",...) fails, status %s\n",
1885 (int)itemPtr->timeStyle, (int)itemPtr->dateStyle, itemPtr->locale, u_errorName(status));
1886 } else {
1887 UChar uget[kUbufStdMax];
1888 int32_t ugetlen = udat_format(udfmt, date2015Feb25, uget, kUbufStdMax, NULL, &status);
1889 if ( U_FAILURE(status) ) {
1890 log_err("udat_format for (%d, %d, \"%s\",...) fails, status %s\n",
1891 (int)itemPtr->timeStyle, (int)itemPtr->dateStyle, itemPtr->locale, u_errorName(status));
1892 } else {
1893 UChar uexpect[kUbufStdMax];
1894 int32_t uexpectlen = u_unescape(itemPtr->expect, uexpect, kUbufStdMax);
1895 if (ugetlen != uexpectlen || u_strncmp(uget, uexpect, uexpectlen) != 0) {
1896 char bexpect[kBbufStdMax];
1897 char bget[kBbufStdMax];
1898 u_austrcpy(bexpect, uexpect);
1899 u_austrcpy(bget, uget);
1900 log_err("udat_format for (%d, %d, \"%s\",...):\n expect %s\n get %s\n",
1901 (int)itemPtr->timeStyle, (int)itemPtr->dateStyle, itemPtr->locale, bexpect, bget);
1902 }
1903 }
1904 udat_close(udfmt);
1905 }
1906 }
1907}
1908
b331163b
A
1909/* defined above
1910static const UChar zoneGMT[] = { 0x47,0x4D,0x54,0 }; // "GMT"
1911static const UDate date2015Feb25 = 1424841000000.0; // Wednesday, February 25, 2015 at 5:10:00 AM GMT
1912*/
1913static const UChar patternHmm[] = { 0x48,0x3A,0x6D,0x6D,0 }; /* "H:mm" */
1914static const UChar formattedHmm[] = { 0x35,0x3A,0x31,0x30,0 }; /* "5:10" */
1915
1916enum { kUBufOverrideSepMax = 32, kBBufOverrideSepMax = 64 };
1917
1918static void TestApplyPatnOverridesTimeSep(void) {
1919 UErrorCode status;
1920 UDateFormat* udfmt;
1921 const char *locale = "da"; /* uses period for time separator */
1922 UChar ubuf[kUBufOverrideSepMax];
1923 int32_t ulen;
1924
1925 status = U_ZERO_ERROR;
1926 udfmt = udat_open(UDAT_PATTERN, UDAT_PATTERN, locale, zoneGMT, -1, patternHmm, -1, &status);
1927 if ( U_FAILURE(status) ) {
1928 log_err("udat_open(UDAT_PATTERN, UDAT_PATTERN, \"%s\",...) fails, status %s\n", locale, u_errorName(status));
1929 } else {
1930 ulen = udat_format(udfmt, date2015Feb25, ubuf, kUBufOverrideSepMax, NULL, &status);
1931 if ( U_FAILURE(status) ) {
1932 log_err("udat_format fails for UDAT_PATTERN \"%s\", status %s\n", locale, u_errorName(status));
1933 } else if (u_strcmp(ubuf, formattedHmm) != 0) {
1934 char bbuf[kBBufOverrideSepMax];
1935 u_strToUTF8(bbuf, kBBufOverrideSepMax, NULL, ubuf, ulen, &status);
1936 log_err("udat_format fails for UDAT_PATTERN \"%s\", expected 5:10, got %s\n", locale, bbuf);
1937 }
1938 udat_close(udfmt);
1939 }
1940
1941 status = U_ZERO_ERROR;
1942 udfmt = udat_open(UDAT_SHORT, UDAT_NONE, locale, zoneGMT, -1, NULL, 0, &status);
1943 if ( U_FAILURE(status) ) {
1944 log_err("udat_open(UDAT_SHORT, UDAT_NONE, \"%s\",...) fails, status %s\n", locale, u_errorName(status));
1945 } else {
1946 udat_applyPattern(udfmt, FALSE, patternHmm, -1);
1947 ulen = udat_format(udfmt, date2015Feb25, ubuf, kUBufOverrideSepMax, NULL, &status);
1948 if ( U_FAILURE(status) ) {
1949 log_err("udat_format fails for UDAT_SHORT \"%s\" + applyPattern, status %s\n", locale, u_errorName(status));
1950 } else if (u_strcmp(ubuf, formattedHmm) != 0) {
1951 char bbuf[kBBufOverrideSepMax];
1952 u_strToUTF8(bbuf, kBBufOverrideSepMax, NULL, ubuf, ulen, &status);
1953 log_err("udat_format fails for UDAT_SHORT \"%s\" + applyPattern, expected 5:10, got %s\n", locale, bbuf);
1954 }
1955 udat_close(udfmt);
1956 }
1957
1958}
1959
2ca993e8
A
1960#define UDATE_SECOND (1000.0)
1961#define UDATE_MINUTE (60.0*UDATE_SECOND)
1962#define UDATE_HOUR (60.0*UDATE_MINUTE)
1963
1964static const double dayOffsets[] = {
1965 0.0, /* 00:00:00 */
1966 UDATE_SECOND, /* 00:00:01 */
1967 UDATE_MINUTE, /* 00:01:00 */
1968 UDATE_HOUR, /* 01:00:00 */
1969 11.0*UDATE_HOUR + 59.0*UDATE_MINUTE, /* 11:59:00 */
1970 12.0*UDATE_HOUR, /* 12:00:00 */
1971 12.0*UDATE_HOUR + UDATE_SECOND, /* 12:00:01 */
1972 12.0*UDATE_HOUR + UDATE_MINUTE, /* 12:01:00 */
1973 13.0*UDATE_HOUR, /* 13:00:00 */
1974 23.0*UDATE_HOUR + 59.0*UDATE_MINUTE, /* 23:59:00 */
1975};
1976enum { kNumDayOffsets = UPRV_LENGTHOF(dayOffsets) };
1977
1978static const char* ja12HrFmt_hm[kNumDayOffsets] = { /* aK:mm */
1979 "\\u5348\\u524D0:00", /* "午前0:00" */
1980 "\\u5348\\u524D0:00",
1981 "\\u5348\\u524D0:01",
1982 "\\u5348\\u524D1:00",
1983 "\\u5348\\u524D11:59",
1984 "\\u5348\\u5F8C0:00", /* "午後0:00" */
1985 "\\u5348\\u5F8C0:00",
1986 "\\u5348\\u5F8C0:01", /* "午後0:01" */
1987 "\\u5348\\u5F8C1:00",
1988 "\\u5348\\u5F8C11:59",
1989};
1990
1991static const char* ja12HrFmt_h[kNumDayOffsets] = { /* aK時 */
1992 "\\u5348\\u524D0\\u6642", /* "午前0時" */
1993 "\\u5348\\u524D0\\u6642",
1994 "\\u5348\\u524D0\\u6642",
1995 "\\u5348\\u524D1\\u6642",
1996 "\\u5348\\u524D11\\u6642",
1997 "\\u5348\\u5F8C0\\u6642", /* "午後0時" */
1998 "\\u5348\\u5F8C0\\u6642",
1999 "\\u5348\\u5F8C0\\u6642", /* "午後0時" */
2000 "\\u5348\\u5F8C1\\u6642",
2001 "\\u5348\\u5F8C11\\u6642",
2002};
2003typedef struct {
2004 const char* locale;
2005 const char* skeleton;
2006 const char ** expected;
2007} Test12HrFmtItem;
2008
2009static const Test12HrFmtItem test12HrFmtItems[] = {
2010 { "ja", "hm", ja12HrFmt_hm },
2011 { "ja", "h", ja12HrFmt_h },
2012 { NULL, NULL, NULL } /* terminator */
2013};
2014
2015enum { kUBufMax = 128, };
2016static void Test12HrFormats(void) {
2017 const Test12HrFmtItem* itemPtr;
2018 for (itemPtr = test12HrFmtItems; itemPtr->locale != NULL; itemPtr++) {
2019 UErrorCode status = U_ZERO_ERROR;
2020 UCalendar* ucal = ucal_open(NULL, 0, itemPtr->locale, UCAL_DEFAULT, &status);
2021 if ( U_FAILURE(status) ) {
2022 log_data_err("ucal_open fails for locale %s: status %s (Are you missing data?)\n", itemPtr->locale, u_errorName(status));
2023 } else {
2024 ucal_clear(ucal);
2025 ucal_setDateTime(ucal, 2016, UCAL_JANUARY, 1, 0, 0, 0, &status);
2026 UDate baseDate = ucal_getMillis(ucal, &status);
2027 if ( U_FAILURE(status) ) {
2028 log_err("ucal_setDateTime or ucal_getMillis fails for locale %s: status %s\n", itemPtr->locale, u_errorName(status));
2029 } else {
2030 UDateTimePatternGenerator* udatpg = udatpg_open(itemPtr->locale, &status);
2031 if ( U_FAILURE(status) ) {
2032 log_data_err("udatpg_open fails for locale %s: status %s (Are you missing data?)\n", itemPtr->locale, u_errorName(status));
2033 } else {
2034 UChar ubuf1[kUbufMax], ubuf2[kUbufMax];
2035 int32_t ulen1 = u_unescape(itemPtr->skeleton, ubuf1, kUbufMax);
2036 int32_t ulen2 = udatpg_getBestPattern(udatpg, ubuf1, ulen1, ubuf2, kUbufMax, &status);
2037 if ( U_FAILURE(status) ) {
2038 log_err("udatpg_getBestPattern fails for locale %s, skeleton %s: status %s\n",
2039 itemPtr->locale, itemPtr->skeleton, u_errorName(status));
2040 } else {
2041 UDateFormat* udat = udat_open(UDAT_PATTERN, UDAT_PATTERN, itemPtr->locale, NULL, 0, ubuf2, ulen2, &status);
2042 if ( U_FAILURE(status) ) {
2043 log_data_err("udat_open fails for locale %s, skeleton %s: status %s (Are you missing data?)\n",
2044 itemPtr->locale, itemPtr->skeleton, u_errorName(status));
2045 } else {
2046 int32_t iDayOffset;
2047 for (iDayOffset = 0; iDayOffset < kNumDayOffsets; iDayOffset++) {
2048 status = U_ZERO_ERROR;
2049 ulen1 = udat_format(udat, baseDate + dayOffsets[iDayOffset], ubuf1, kUbufMax, NULL, &status);
2050 if ( U_FAILURE(status) ) {
2051 log_err("udat_format fails for locale %s, skeleton %s, iDayOffset %d: status %s\n",
2052 itemPtr->locale, itemPtr->skeleton, iDayOffset, u_errorName(status));
2053 } else {
2054 ulen2 = u_unescape(itemPtr->expected[iDayOffset], ubuf2, kUbufMax);
2055 if (ulen1 != ulen2 || u_strncmp(ubuf1, ubuf2, ulen2) != 0) {
2056 char bbuf1[kBbufMax], bbuf2[kBbufMax];
2057 u_austrncpy(bbuf1, ubuf1, ulen1);
2058 u_austrncpy(bbuf2, ubuf2, ulen2);
2059 log_err("udat_format fails for locale %s, skeleton %s, iDayOffset %d:\n expect %s\n get %s\n",
2060 itemPtr->locale, itemPtr->skeleton, iDayOffset, bbuf2, bbuf1);
2061 }
2062 }
2063
2064 }
2065 udat_close(udat);
2066 }
2067 }
2068 udatpg_close(udatpg);
2069 }
2070 }
2071 ucal_close(ucal);
2072 }
2073 }
2074}
2075
b331163b
A
2076/* *** */
2077
2078typedef struct {
2079 const char* locale;
2080 UATimeUnitTimePattern patType;
2081 const char* expect; /* universal char subset + escaped Unicode chars */
2082} TimePatternItem;
2083static const TimePatternItem timePatternItems[] = {
2084 { "en", UATIMEUNITTIMEPAT_HM, "h:mm" },
2085 { "en", UATIMEUNITTIMEPAT_HMS, "h:mm:ss" },
2086 { "en", UATIMEUNITTIMEPAT_MS, "m:ss" },
2087 { "da", UATIMEUNITTIMEPAT_HM, "h.mm" },
2088 { "da", UATIMEUNITTIMEPAT_HMS, "h.mm.ss" },
2089 { "da", UATIMEUNITTIMEPAT_MS, "m.ss" },
2090 { NULL, 0, NULL }
2091};
2092
2093typedef struct {
2094 const char* locale;
2095 UATimeUnitStyle width;
2096 UATimeUnitListPattern patType;
2097 const char* expect; /* universal char subset + escaped Unicode chars */
2098} ListPatternItem;
2099static const ListPatternItem listPatternItems[] = {
2100 { "en", UATIMEUNITSTYLE_FULL, UATIMEUNITLISTPAT_TWO_ONLY, "{0}, {1}" },
2101 { "en", UATIMEUNITSTYLE_FULL, UATIMEUNITLISTPAT_END_PIECE, "{0}, {1}" },
2102 { "en", UATIMEUNITSTYLE_FULL, UATIMEUNITLISTPAT_MIDDLE_PIECE, "{0}, {1}" },
2103 { "en", UATIMEUNITSTYLE_FULL, UATIMEUNITLISTPAT_START_PIECE, "{0}, {1}" },
2104 { "en", UATIMEUNITSTYLE_NARROW, UATIMEUNITLISTPAT_TWO_ONLY, "{0} {1}" },
2105 { "en", UATIMEUNITSTYLE_NARROW, UATIMEUNITLISTPAT_END_PIECE, "{0} {1}" },
2106 { "en", UATIMEUNITSTYLE_NARROW, UATIMEUNITLISTPAT_MIDDLE_PIECE, "{0} {1}" },
2107 { "en", UATIMEUNITSTYLE_NARROW, UATIMEUNITLISTPAT_START_PIECE, "{0} {1}" },
2ca993e8 2108 { "en", UATIMEUNITSTYLE_SHORTER, UATIMEUNITLISTPAT_TWO_ONLY, "{0} {1}" },
b331163b
A
2109 { "fr", UATIMEUNITSTYLE_FULL, UATIMEUNITLISTPAT_TWO_ONLY, "{0} et {1}" },
2110 { "fr", UATIMEUNITSTYLE_FULL, UATIMEUNITLISTPAT_END_PIECE, "{0} et {1}" },
2111 { "fr", UATIMEUNITSTYLE_FULL, UATIMEUNITLISTPAT_MIDDLE_PIECE, "{0}, {1}" },
2112 { "fr", UATIMEUNITSTYLE_FULL, UATIMEUNITLISTPAT_START_PIECE, "{0}, {1}" },
2113 { "fr", UATIMEUNITSTYLE_NARROW, UATIMEUNITLISTPAT_TWO_ONLY, "{0} {1}" },
2114 { "fr", UATIMEUNITSTYLE_NARROW, UATIMEUNITLISTPAT_END_PIECE, "{0} {1}" },
2115 { "fr", UATIMEUNITSTYLE_NARROW, UATIMEUNITLISTPAT_MIDDLE_PIECE, "{0} {1}" },
2116 { "fr", UATIMEUNITSTYLE_NARROW, UATIMEUNITLISTPAT_START_PIECE, "{0} {1}" },
2ca993e8 2117 { "fr", UATIMEUNITSTYLE_SHORTER, UATIMEUNITLISTPAT_TWO_ONLY, "{0} {1}" },
b331163b
A
2118 { NULL, 0, 0, NULL }
2119};
2120
2121enum {kUBufTimeUnitLen = 128, kBBufTimeUnitLen = 256 };
2122
2123static void TestTimeUnitFormat(void) { /* Apple-specific */
2124 const TimePatternItem* timePatItemPtr;
2125 const ListPatternItem* listPatItemPtr;
2126 UChar uActual[kUBufTimeUnitLen];
2127 UChar uExpect[kUBufTimeUnitLen];
2128
2129 for (timePatItemPtr = timePatternItems; timePatItemPtr->locale != NULL; timePatItemPtr++) {
2130 UErrorCode status = U_ZERO_ERROR;
2131 int32_t ulenActual = uatmufmt_getTimePattern(timePatItemPtr->locale, timePatItemPtr->patType, uActual, kUBufTimeUnitLen, &status);
2132 if ( U_FAILURE(status) ) {
2133 log_err("uatmufmt_getTimePattern for locale %s, patType %d: status %s\n", timePatItemPtr->locale, (int)timePatItemPtr->patType, u_errorName(status));
2134 } else {
2135 int32_t ulenExpect = u_unescape(timePatItemPtr->expect, uExpect, kUBufTimeUnitLen);
2136 if (ulenActual != ulenExpect || u_strncmp(uActual, uExpect, ulenExpect) != 0) {
2137 char bActual[kBBufTimeUnitLen];
2138 u_strToUTF8(bActual, kBBufTimeUnitLen, NULL, uActual, ulenActual, &status);
2139 log_err("uatmufmt_getTimePattern for locale %s, patType %d: unexpected result %s\n", timePatItemPtr->locale, (int)timePatItemPtr->patType, bActual);
2140 }
2141 }
2142 }
2143
2144 for (listPatItemPtr = listPatternItems; listPatItemPtr->locale != NULL; listPatItemPtr++) {
2145 UErrorCode status = U_ZERO_ERROR;
2146 int32_t ulenActual = uatmufmt_getListPattern(listPatItemPtr->locale, listPatItemPtr->width, listPatItemPtr->patType, uActual, kUBufTimeUnitLen, &status);
2147 if ( U_FAILURE(status) ) {
2148 log_err("uatmufmt_getListPattern for locale %s, width %d, patType %d: status %s\n", listPatItemPtr->locale, (int)listPatItemPtr->width, (int)listPatItemPtr->patType, u_errorName(status));
2149 } else {
2150 int32_t ulenExpect = u_unescape(listPatItemPtr->expect, uExpect, kUBufTimeUnitLen);
2151 if (ulenActual != ulenExpect || u_strncmp(uActual, uExpect, ulenExpect) != 0) {
2152 char bActual[kBBufTimeUnitLen];
2153 u_strToUTF8(bActual, kBBufTimeUnitLen, NULL, uActual, ulenActual, &status);
2154 log_err("uatmufmt_getListPattern for locale %s, width %d, patType %d: unexpected result %s\n", listPatItemPtr->locale, (int)listPatItemPtr->width, (int)listPatItemPtr->patType, bActual);
2155 }
2156 }
2157 }
2158
2159}
2160
2161typedef enum RemapTesttype {
2162 REMAP_TESTTYPE_FULL = UDAT_FULL, // 0
2163 REMAP_TESTTYPE_LONG = UDAT_LONG, // 1
2164 REMAP_TESTTYPE_MEDIUM = UDAT_MEDIUM, // 2
2165 REMAP_TESTTYPE_SHORT = UDAT_SHORT, // 3
2166 REMAP_TESTTYPE_LONG_DF = UDAT_LONG + 4, // 5 long time, full date
2167 REMAP_TESTTYPE_SHORT_DS = UDAT_SHORT + 16, // 3 short time, short date
2168 REMAP_TESTTYPE_SKELETON = -1,
2169 REMAP_TESTTYPE_PATTERN = -2,
2170} RemapTesttype;
2171
2172typedef struct {
2173 const char * pattern;
2174 RemapTesttype testtype;
2175 uint32_t options;
2176} RemapPatternTestItem;
2177
2178static const RemapPatternTestItem remapPatItems[] = {
2179 { "full", REMAP_TESTTYPE_FULL, 0 },
2180 { "full", REMAP_TESTTYPE_FULL, UADATPG_FORCE_24_HOUR_CYCLE },
2181 { "full", REMAP_TESTTYPE_FULL, UADATPG_FORCE_12_HOUR_CYCLE },
2182 { "long", REMAP_TESTTYPE_LONG, 0 },
2183 { "long", REMAP_TESTTYPE_LONG, UADATPG_FORCE_24_HOUR_CYCLE },
2184 { "long", REMAP_TESTTYPE_LONG, UADATPG_FORCE_12_HOUR_CYCLE },
2185 { "medium", REMAP_TESTTYPE_MEDIUM, 0 },
2186 { "medium", REMAP_TESTTYPE_MEDIUM, UADATPG_FORCE_24_HOUR_CYCLE },
2187 { "medium", REMAP_TESTTYPE_MEDIUM, UADATPG_FORCE_12_HOUR_CYCLE },
2188 { "short", REMAP_TESTTYPE_SHORT, 0 },
2189 { "short", REMAP_TESTTYPE_SHORT, UADATPG_FORCE_24_HOUR_CYCLE },
2190 { "short", REMAP_TESTTYPE_SHORT, UADATPG_FORCE_12_HOUR_CYCLE },
2191 { "long_df", REMAP_TESTTYPE_LONG_DF, 0 },
2192 { "long_df", REMAP_TESTTYPE_LONG_DF, UADATPG_FORCE_24_HOUR_CYCLE },
2193 { "long_df", REMAP_TESTTYPE_LONG_DF, UADATPG_FORCE_12_HOUR_CYCLE },
2194 { "short_ds", REMAP_TESTTYPE_SHORT_DS, 0 },
2195 { "short_ds", REMAP_TESTTYPE_SHORT_DS, UADATPG_FORCE_24_HOUR_CYCLE },
2196 { "short_ds", REMAP_TESTTYPE_SHORT_DS, UADATPG_FORCE_12_HOUR_CYCLE },
2197
2198 { "jmmss", REMAP_TESTTYPE_SKELETON, 0 },
2199 { "jmmss", REMAP_TESTTYPE_SKELETON, UADATPG_FORCE_24_HOUR_CYCLE },
2200 { "jmmss", REMAP_TESTTYPE_SKELETON, UADATPG_FORCE_12_HOUR_CYCLE },
2201 { "jjmmss", REMAP_TESTTYPE_SKELETON, 0 },
2202 { "jjmmss", REMAP_TESTTYPE_SKELETON, UADATPG_FORCE_24_HOUR_CYCLE },
2203 { "jjmmss", REMAP_TESTTYPE_SKELETON, UADATPG_FORCE_24_HOUR_CYCLE | UDATPG_MATCH_HOUR_FIELD_LENGTH },
2204 { "jjmmss", REMAP_TESTTYPE_SKELETON, UADATPG_FORCE_12_HOUR_CYCLE },
2205 { "jjmmss", REMAP_TESTTYPE_SKELETON, UADATPG_FORCE_12_HOUR_CYCLE | UDATPG_MATCH_HOUR_FIELD_LENGTH },
2206 { "Jmm", REMAP_TESTTYPE_SKELETON, 0 },
2207 { "Jmm", REMAP_TESTTYPE_SKELETON, UADATPG_FORCE_24_HOUR_CYCLE },
2208 { "Jmm", REMAP_TESTTYPE_SKELETON, UADATPG_FORCE_12_HOUR_CYCLE },
2209 { "jmsv", REMAP_TESTTYPE_SKELETON, 0 },
2210 { "jmsv", REMAP_TESTTYPE_SKELETON, UADATPG_FORCE_24_HOUR_CYCLE },
2211 { "jmsv", REMAP_TESTTYPE_SKELETON, UADATPG_FORCE_12_HOUR_CYCLE },
2212 { "jmsz", REMAP_TESTTYPE_SKELETON, 0 },
2213 { "jmsz", REMAP_TESTTYPE_SKELETON, UADATPG_FORCE_24_HOUR_CYCLE },
2214 { "jmsz", REMAP_TESTTYPE_SKELETON, UADATPG_FORCE_12_HOUR_CYCLE },
2215
2216 { "h:mm:ss a", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_12_HOUR_CYCLE }, // 12=hour patterns
2217 { "h:mm:ss a", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_24_HOUR_CYCLE },
2218 { "a'xx'h:mm:ss d MMM y", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_12_HOUR_CYCLE },
2219 { "a'xx'h:mm:ss d MMM y", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_24_HOUR_CYCLE },
2220 { "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_12_HOUR_CYCLE },
2221 { "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_24_HOUR_CYCLE },
2222 { "EEE, d MMM y 'aha' a'xx'h:mm:ss", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_12_HOUR_CYCLE },
2223 { "EEE, d MMM y 'aha' a'xx'h:mm:ss", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_24_HOUR_CYCLE },
2224 { "yyMMddhhmmss", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_12_HOUR_CYCLE },
2225 { "yyMMddhhmmss", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_24_HOUR_CYCLE },
2226
2227 { "H:mm:ss", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_12_HOUR_CYCLE }, // 24=hour patterns
2228 { "H:mm:ss", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_24_HOUR_CYCLE },
2229 { "H:mm:ss d MMM y", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_12_HOUR_CYCLE },
2230 { "H:mm:ss d MMM y", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_24_HOUR_CYCLE },
2231 { "EEE, d MMM y 'aha' H:mm:ss 'hrs'", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_12_HOUR_CYCLE },
2232 { "EEE, d MMM y 'aha' H:mm:ss 'hrs'", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_24_HOUR_CYCLE },
2233 { "EEE, d MMM y 'aha' H'h'mm'm'ss", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_12_HOUR_CYCLE },
2234 { "EEE, d MMM y 'aha' H'h'mm'm'ss", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_24_HOUR_CYCLE },
2235 { NULL, (RemapTesttype)0, 0 }
2236};
2237
2238static const char * remapResults_root[] = {
2239 "HH:mm:ss zzzz", // full
2240 "HH:mm:ss zzzz", // force24
2241 "h:mm:ss a zzzz", // force12
2242 "HH:mm:ss z", // long
2243 "HH:mm:ss z", // force24
2244 "h:mm:ss a z", // force12
2245 "HH:mm:ss", // medium
2246 "HH:mm:ss", // force24
2247 "h:mm:ss a", // force12
2248 "HH:mm", // short
2249 "HH:mm", // force24
2250 "h:mm a", // force12
2251 "y MMMM d, EEEE HH:mm:ss z", // long_df
2252 "y MMMM d, EEEE HH:mm:ss z", // force24
2253 "y MMMM d, EEEE h:mm:ss a z", // force12
2254 "y-MM-dd HH:mm", // short_ds
2255 "y-MM-dd HH:mm", // force24
2256 "y-MM-dd h:mm a", // force12
2257
2258 "HH:mm:ss", // jmmss
2259 "HH:mm:ss", // force24
2260 "h:mm:ss a", // force12
2261 "HH:mm:ss", // jjmmss
2262 "HH:mm:ss", // force24
2263 "HH:mm:ss", // force24 | match hour field length
2264 "h:mm:ss a", // force12
2265 "hh:mm:ss a", // force12 | match hour field length
2266 "HH:mm", // Jmm
2267 "HH:mm", // force24
2268 "hh:mm", // force12
2269 "HH:mm:ss v", // jmsv
2270 "HH:mm:ss v", // force24
2271 "h:mm:ss a v", // force12
2272 "HH:mm:ss z", // jmsz
2273 "HH:mm:ss z", // force24
2274 "h:mm:ss a z", // force12
2275
2276 "h:mm:ss a", // "h:mm:ss"
2277 "HH:mm:ss", //
2278 "a'xx'h:mm:ss d MMM y", // "a'xx'h:mm:ss d MMM y"
2279 "HH:mm:ss d MMM y", //
2280 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' h:mm:ss a 'hrs'"
2281 "EEE, d MMM y 'aha' HH:mm:ss 'hrs'", //
2282 "EEE, d MMM y 'aha' a'xx'h:mm:ss", // "EEE, d MMM y 'aha' a'xx'h:mm:ss"
2283 "EEE, d MMM y 'aha' HH:mm:ss", //
2284 "yyMMddhhmmss", // "yyMMddhhmmss"
2285 "yyMMddHHmmss", //
2286
2287 "h:mm:ss a", // "H:mm:ss"
2288 "H:mm:ss", //
2289 "h:mm:ss a d MMM y", // "H:mm:ss d MMM y"
2290 "H:mm:ss d MMM y", //
2291 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' H:mm:ss 'hrs'"
2292 "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
2293 "EEE, d MMM y 'aha' h'h'mm'm'ss a", // "EEE, d MMM y 'aha' H'h'mm'm'ss"
2294 "EEE, d MMM y 'aha' H'h'mm'm'ss", //
2295 NULL
2296};
2297
2298static const char * remapResults_en[] = {
2299 "h:mm:ss a zzzz", // full
2300 "HH:mm:ss zzzz", // force24
2301 "h:mm:ss a zzzz", // force12
2302 "h:mm:ss a z", // long
2303 "HH:mm:ss z", // force24
2304 "h:mm:ss a z", // force12
2305 "h:mm:ss a", // medium
2306 "HH:mm:ss", // force24
2307 "h:mm:ss a", // force12
2308 "h:mm a", // short
2309 "HH:mm", // force24
2310 "h:mm a", // force12
2311 "EEEE, MMMM d, y 'at' h:mm:ss a z", // long_df
2312 "EEEE, MMMM d, y 'at' HH:mm:ss z", // force24
2313 "EEEE, MMMM d, y 'at' h:mm:ss a z", // force12
2314 "M/d/yy, h:mm a", // short_ds
2315 "M/d/yy, HH:mm", // force24
2316 "M/d/yy, h:mm a", // force12
2317
2318 "h:mm:ss a", // jmmss
2319 "HH:mm:ss", // force24
2320 "h:mm:ss a", // force12
2321 "h:mm:ss a", // jjmmss
2322 "HH:mm:ss", // force24
2323 "HH:mm:ss", // force24 | match hour field length
2324 "h:mm:ss a", // force12
2325 "hh:mm:ss a", // force12 | match hour field length
2326 "hh:mm", // Jmm
2327 "HH:mm", // force24
2328 "hh:mm", // force12
2329 "h:mm:ss a v", // jmsv
2330 "HH:mm:ss v", // force24
2331 "h:mm:ss a v", // force12
2332 "h:mm:ss a z", // jmsz
2333 "HH:mm:ss z", // force24
2334 "h:mm:ss a z", // force12
2335
2336 "h:mm:ss a", // "h:mm:ss"
2337 "HH:mm:ss", //
2338 "a'xx'h:mm:ss d MMM y", // "a'xx'h:mm:ss d MMM y"
2339 "HH:mm:ss d MMM y", //
2340 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' h:mm:ss a 'hrs'"
2341 "EEE, d MMM y 'aha' HH:mm:ss 'hrs'", //
2342 "EEE, d MMM y 'aha' a'xx'h:mm:ss", // "EEE, d MMM y 'aha' a'xx'h:mm:ss"
2343 "EEE, d MMM y 'aha' HH:mm:ss", //
2344 "yyMMddhhmmss", // "yyMMddhhmmss"
2345 "yyMMddHHmmss", //
2346
2347 "h:mm:ss a", // "H:mm:ss"
2348 "H:mm:ss", //
2349 "h:mm:ss a d MMM y", // "H:mm:ss d MMM y"
2350 "H:mm:ss d MMM y", //
2351 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' H:mm:ss 'hrs'"
2352 "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
2353 "EEE, d MMM y 'aha' h'h'mm'm'ss a", // "EEE, d MMM y 'aha' H'h'mm'm'ss"
2354 "EEE, d MMM y 'aha' H'h'mm'm'ss", //
2355 NULL
2356};
2357
2358static const char * remapResults_ja[] = {
2359 "H\\u6642mm\\u5206ss\\u79D2 zzzz", // full
2360 "H\\u6642mm\\u5206ss\\u79D2 zzzz", // force24
2361 "aK:mm:ss zzzz", // force12
2362 "H:mm:ss z", // long
2363 "H:mm:ss z", // force24
2364 "aK:mm:ss z", // force12
2365 "H:mm:ss", // medium
2366 "H:mm:ss", // force24
2367 "aK:mm:ss", // force12
2368 "H:mm", // short
2369 "H:mm", // force24
2370 "aK:mm", // force12
2371 "y\\u5E74M\\u6708d\\u65E5EEEE H:mm:ss z", // long_df
2372 "y\\u5E74M\\u6708d\\u65E5EEEE H:mm:ss z", // force24
2373 "y\\u5E74M\\u6708d\\u65E5EEEE aK:mm:ss z", // force12
2374 "y/MM/dd H:mm", // short_ds
2375 "y/MM/dd H:mm", // force24
2376 "y/MM/dd aK:mm", // force12
2377
2378 "H:mm:ss", // jmmss
2379 "H:mm:ss", // force24
2380 "aK:mm:ss", // force12
2381 "H:mm:ss", // jjmmss
2382 "H:mm:ss", // force24
2383 "HH:mm:ss", // force24 | match hour field length
2384 "aK:mm:ss", // force12
2385 "aKK:mm:ss", // force12 | match hour field length
2386 "H:mm", // Jmm
2387 "H:mm", // force24
2388 "h:mm", // force12
2389 "H:mm:ss v", // jmsv
2390 "H:mm:ss v", // force24
2391 "aK:mm:ss v", // force12
2392 "H:mm:ss z", // jmsz
2393 "H:mm:ss z", // force24
2394 "aK:mm:ss z", // force12
2395
2396 "h:mm:ss a", // "h:mm:ss"
2397 "H:mm:ss", //
2398 "a'xx'h:mm:ss d MMM y", // "a'xx'h:mm:ss d MMM y"
2399 "H:mm:ss d MMM y", //
2400 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' h:mm:ss a 'hrs'"
2401 "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
2402 "EEE, d MMM y 'aha' a'xx'h:mm:ss", // "EEE, d MMM y 'aha' a'xx'h:mm:ss"
2403 "EEE, d MMM y 'aha' H:mm:ss", //
2404 "yyMMddhhmmss", // "yyMMddhhmmss"
2405 "yyMMddHHmmss", //
2406
2407 "aK:mm:ss", // "H:mm:ss"
2408 "H:mm:ss", //
2409 "aK:mm:ss d MMM y", // "H:mm:ss d MMM y"
2410 "H:mm:ss d MMM y", //
2411 "EEE, d MMM y 'aha' aK:mm:ss 'hrs'", // "EEE, d MMM y 'aha' H:mm:ss 'hrs'"
2412 "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
2413 "EEE, d MMM y 'aha' aK'h'mm'm'ss", // "EEE, d MMM y 'aha' H'h'mm'm'ss"
2414 "EEE, d MMM y 'aha' H'h'mm'm'ss", //
2415 NULL
2416};
2417
2418static const char * remapResults_ko[] = {
2419 "a h\\uC2DC m\\uBD84 s\\uCD08 zzzz", // full
2420 "H\\uC2DC m\\uBD84 s\\uCD08 zzzz", // force24
2421 "a h\\uC2DC m\\uBD84 s\\uCD08 zzzz", // force12
2422 "a h\\uC2DC m\\uBD84 s\\uCD08 z", // long
2423 "H\\uC2DC m\\uBD84 s\\uCD08 z", // force24
2424 "a h\\uC2DC m\\uBD84 s\\uCD08 z", // force12
2425 "a h:mm:ss", // medium
2426 "HH:mm:ss", // force24
2427 "a h:mm:ss", // force12
2428 "a h:mm", // short
2429 "HH:mm", // force24
2430 "a h:mm", // force12
2431 "y\\uB144 M\\uC6D4 d\\uC77C EEEE a h\\uC2DC m\\uBD84 s\\uCD08 z", // long_df
2432 "y\\uB144 M\\uC6D4 d\\uC77C EEEE H\\uC2DC m\\uBD84 s\\uCD08 z", // force24
2433 "y\\uB144 M\\uC6D4 d\\uC77C EEEE a h\\uC2DC m\\uBD84 s\\uCD08 z", // force12
2434 "y. M. d. a h:mm", // short_ds
2435 "y. M. d. HH:mm", // force24
2436 "y. M. d. a h:mm", // force12
2437
2438 "a h:mm:ss", // jmmss
2439 "HH:mm:ss", // force24
2440 "a h:mm:ss", // force12
2441 "a h:mm:ss", // jjmmss
2442 "HH:mm:ss", // force24
2443 "HH:mm:ss", // force24 | match hour field length
2444 "a h:mm:ss", // force12
2445 "a hh:mm:ss", // force12 | match hour field length
2446 "hh:mm", // Jmm
2447 "HH:mm", // force24
2448 "hh:mm", // force12
2449 "a h:mm:ss v", // jmsv
2450 "H\\uC2DC m\\uBD84 s\\uCD08 v", // force24
2451 "a h:mm:ss v", // force12
2452 "a h\\uC2DC m\\uBD84 s\\uCD08 z", // jmsz
2453 "H\\uC2DC m\\uBD84 s\\uCD08 z", // force24
2454 "a h\\uC2DC m\\uBD84 s\\uCD08 z", // force12
2455
2456 "h:mm:ss a", // "h:mm:ss"
2457 "HH:mm:ss", //
2458 "a'xx'h:mm:ss d MMM y", // "a'xx'h:mm:ss d MMM y"
2459 "HH:mm:ss d MMM y", //
2460 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' h:mm:ss a 'hrs'"
2461 "EEE, d MMM y 'aha' HH:mm:ss 'hrs'", //
2462 "EEE, d MMM y 'aha' a'xx'h:mm:ss", // "EEE, d MMM y 'aha' a'xx'h:mm:ss"
2463 "EEE, d MMM y 'aha' HH:mm:ss", //
2464 "yyMMddhhmmss", // "yyMMddhhmmss"
2465 "yyMMddHHmmss", //
2466
2467 "a h:mm:ss", // "H:mm:ss"
2468 "H:mm:ss", //
2469 "a h:mm:ss d MMM y", // "H:mm:ss d MMM y"
2470 "H:mm:ss d MMM y", //
2471 "EEE, d MMM y 'aha' a h:mm:ss 'hrs'", // "EEE, d MMM y 'aha' H:mm:ss 'hrs'"
2472 "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
2473 "EEE, d MMM y 'aha' a h'h'mm'm'ss", // "EEE, d MMM y 'aha' H'h'mm'm'ss"
2474 "EEE, d MMM y 'aha' H'h'mm'm'ss", //
2475 NULL
2476};
2477
2478static const char * remapResults_th[] = {
2479 "H \\u0E19\\u0E32\\u0E2C\\u0E34\\u0E01\\u0E32 mm \\u0E19\\u0E32\\u0E17\\u0E35 ss \\u0E27\\u0E34\\u0E19\\u0E32\\u0E17\\u0E35 zzzz", // full
2480 "H \\u0E19\\u0E32\\u0E2C\\u0E34\\u0E01\\u0E32 mm \\u0E19\\u0E32\\u0E17\\u0E35 ss \\u0E27\\u0E34\\u0E19\\u0E32\\u0E17\\u0E35 zzzz", // force24
2481 "h:mm:ss a zzzz", // force12
2482 "H \\u0E19\\u0E32\\u0E2C\\u0E34\\u0E01\\u0E32 mm \\u0E19\\u0E32\\u0E17\\u0E35 ss \\u0E27\\u0E34\\u0E19\\u0E32\\u0E17\\u0E35 z", // long
2483 "H \\u0E19\\u0E32\\u0E2C\\u0E34\\u0E01\\u0E32 mm \\u0E19\\u0E32\\u0E17\\u0E35 ss \\u0E27\\u0E34\\u0E19\\u0E32\\u0E17\\u0E35 z", // force24
2484 "h:mm:ss a z", // force12
2485 "HH:mm:ss", // medium
2486 "HH:mm:ss", // force24
2487 "h:mm:ss a", // force12
2488 "HH:mm", // short
2489 "HH:mm", // force24
2490 "h:mm a", // force12
2491 "EEEE\\u0E17\\u0E35\\u0E48 d MMMM G y H \\u0E19\\u0E32\\u0E2C\\u0E34\\u0E01\\u0E32 mm \\u0E19\\u0E32\\u0E17\\u0E35 ss \\u0E27\\u0E34\\u0E19\\u0E32\\u0E17\\u0E35 z", // long_df
2492 "EEEE\\u0E17\\u0E35\\u0E48 d MMMM G y H \\u0E19\\u0E32\\u0E2C\\u0E34\\u0E01\\u0E32 mm \\u0E19\\u0E32\\u0E17\\u0E35 ss \\u0E27\\u0E34\\u0E19\\u0E32\\u0E17\\u0E35 z", // force24
2493 "EEEE\\u0E17\\u0E35\\u0E48 d MMMM G y h:mm:ss a z", // force12
2494 "d/M/yy HH:mm", // short_ds
2495 "d/M/yy HH:mm", // force24
2496 "d/M/yy h:mm a", // force12
2497
2498 "HH:mm:ss", // jmmss
2499 "HH:mm:ss", // force24
2500 "h:mm:ss a", // force12
2501 "HH:mm:ss", // jjmmss
2502 "HH:mm:ss", // force24
2503 "HH:mm:ss", // force24 | match hour field length
2504 "h:mm:ss a", // force12
2505 "hh:mm:ss a", // force12 | match hour field length
2506 "HH:mm", // Jmm
2507 "HH:mm", // force24
2508 "hh:mm", // force12
2509 "H \\u0E19\\u0E32\\u0E2C\\u0E34\\u0E01\\u0E32 mm \\u0E19\\u0E32\\u0E17\\u0E35 ss \\u0E27\\u0E34\\u0E19\\u0E32\\u0E17\\u0E35 v", // jmsv
2510 "H \\u0E19\\u0E32\\u0E2C\\u0E34\\u0E01\\u0E32 mm \\u0E19\\u0E32\\u0E17\\u0E35 ss \\u0E27\\u0E34\\u0E19\\u0E32\\u0E17\\u0E35 v", // force24
2511 "h:mm:ss a v", // force12
2512 "H \\u0E19\\u0E32\\u0E2C\\u0E34\\u0E01\\u0E32 mm \\u0E19\\u0E32\\u0E17\\u0E35 ss \\u0E27\\u0E34\\u0E19\\u0E32\\u0E17\\u0E35 z", // jmsz
2513 "H \\u0E19\\u0E32\\u0E2C\\u0E34\\u0E01\\u0E32 mm \\u0E19\\u0E32\\u0E17\\u0E35 ss \\u0E27\\u0E34\\u0E19\\u0E32\\u0E17\\u0E35 z", // force24
2514 "h:mm:ss a z", // force12
2515
2516 "h:mm:ss a", // "h:mm:ss"
2517 "HH:mm:ss", //
2518 "a'xx'h:mm:ss d MMM y", // "a'xx'h:mm:ss d MMM y"
2519 "HH:mm:ss d MMM y", //
2520 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' h:mm:ss a 'hrs'"
2521 "EEE, d MMM y 'aha' HH:mm:ss 'hrs'", //
2522 "EEE, d MMM y 'aha' a'xx'h:mm:ss", // "EEE, d MMM y 'aha' a'xx'h:mm:ss"
2523 "EEE, d MMM y 'aha' HH:mm:ss", //
2524 "yyMMddhhmmss", // "yyMMddhhmmss"
2525 "yyMMddHHmmss", //
2526
2527 "h:mm:ss a", // "H:mm:ss"
2528 "H:mm:ss", //
2529 "h:mm:ss a d MMM y", // "H:mm:ss d MMM y"
2530 "H:mm:ss d MMM y", //
2531 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' H:mm:ss 'hrs'"
2532 "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
2533 "EEE, d MMM y 'aha' h'h'mm'm'ss a", // "EEE, d MMM y 'aha' H'h'mm'm'ss"
2534 "EEE, d MMM y 'aha' H'h'mm'm'ss", //
2535 NULL
2536};
2537
2538static const char * remapResults_hi[] = {
2539 "a h:mm:ss zzzz", // full
2540 "HH:mm:ss zzzz", // force24
2541 "a h:mm:ss zzzz", // force12
2542 "a h:mm:ss z", // long
2543 "HH:mm:ss z", // force24
2544 "a h:mm:ss z", // force12
2545 "a h:mm:ss", // medium
2546 "HH:mm:ss", // force24
2547 "a h:mm:ss", // force12
2548 "a h:mm", // short
2549 "HH:mm", // force24
2550 "a h:mm", // force12
2551 "EEEE, d MMMM y, a h:mm:ss z", // long_df
2552 "EEEE, d MMMM y, HH:mm:ss z", // force24
2553 "EEEE, d MMMM y, a h:mm:ss z", // force12
2554 "d/M/yy, a h:mm", // short_ds
2555 "d/M/yy, HH:mm", // force24
2556 "d/M/yy, a h:mm", // force12
2557
2558 "a h:mm:ss", // jmmss
2559 "HH:mm:ss", // force24
2560 "a h:mm:ss", // force12
2561 "a h:mm:ss", // jjmmss
2562 "HH:mm:ss", // force24
2563 "HH:mm:ss", // force24 | match hour field length
2564 "a h:mm:ss", // force12
2565 "a hh:mm:ss", // force12 | match hour field length
2566 "hh:mm", // Jmm
2567 "HH:mm", // force24
2568 "hh:mm", // force12
2569 "a h:mm:ss v", // jmsv
2570 "HH:mm:ss v", // force24
2571 "a h:mm:ss v", // force12
2572 "a h:mm:ss z", // jmsz
2573 "HH:mm:ss z", // force24
2574 "a h:mm:ss z", // force12
2575
2576 "h:mm:ss a", // "h:mm:ss"
2577 "HH:mm:ss", //
2578 "a'xx'h:mm:ss d MMM y", // "a'xx'h:mm:ss d MMM y"
2579 "HH:mm:ss d MMM y", //
2580 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' h:mm:ss a 'hrs'"
2581 "EEE, d MMM y 'aha' HH:mm:ss 'hrs'", //
2582 "EEE, d MMM y 'aha' a'xx'h:mm:ss", // "EEE, d MMM y 'aha' a'xx'h:mm:ss"
2583 "EEE, d MMM y 'aha' HH:mm:ss", //
2584 "yyMMddhhmmss", // "yyMMddhhmmss"
2585 "yyMMddHHmmss", //
2586
2587 "a h:mm:ss", // "H:mm:ss"
2588 "H:mm:ss", //
2589 "a h:mm:ss d MMM y", // "H:mm:ss d MMM y"
2590 "H:mm:ss d MMM y", //
2591 "EEE, d MMM y 'aha' a h:mm:ss 'hrs'", // "EEE, d MMM y 'aha' H:mm:ss 'hrs'"
2592 "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
2593 "EEE, d MMM y 'aha' a h'h'mm'm'ss", // "EEE, d MMM y 'aha' H'h'mm'm'ss"
2594 "EEE, d MMM y 'aha' H'h'mm'm'ss", //
2595 NULL
2596};
2597
2598typedef struct {
2599 const char * locale;
2600 const char ** resultsPtr;
2601} RemapPatternLocaleResults;
2602
2603static const RemapPatternLocaleResults remapLocResults[] = {
2604 { "root", remapResults_root },
2605 { "en", remapResults_en },
2606 { "ja", remapResults_ja },
2607 { "ko", remapResults_ko },
2608 { "th", remapResults_th },
2609 { "hi", remapResults_hi },
2610 { NULL, NULL }
2611};
2612
2613enum { kUBufRemapMax = 64, kBBufRemapMax = 128 };
2614
2615static void TestRemapPatternWithOpts(void) { /* Apple-specific */
2616 const RemapPatternLocaleResults * locResPtr;
2617 for (locResPtr = remapLocResults; locResPtr->locale != NULL; locResPtr++) {
2618 UErrorCode status = U_ZERO_ERROR;
2619 UDateTimePatternGenerator* dtpg = udatpg_open(locResPtr->locale, &status);
2620 if ( U_FAILURE(status) ) {
2621 log_data_err("udatpg_open fails for locale %s, status %s (Are you missing data?)\n", locResPtr->locale, u_errorName(status));
2622 } else {
2623 const RemapPatternTestItem * testItemPtr = remapPatItems;
2624 const char ** expResultsPtr = locResPtr->resultsPtr;
2625 for (; testItemPtr->pattern != NULL && *expResultsPtr != NULL; testItemPtr++, expResultsPtr++) {
2626 UChar uskel[kUBufRemapMax];
2627 UChar upatn[kUBufRemapMax];
2628 UChar uget[kUBufRemapMax];
2629 UChar uexp[kUBufRemapMax];
2630 int32_t uelen, ulen = 0;
2631
2632 status = U_ZERO_ERROR;
2633 if (testItemPtr->testtype >= 0) {
2634 UDateFormatStyle timeStyle = (UDateFormatStyle)((int32_t)testItemPtr->testtype & 0x03);
2635 UDateFormatStyle dateStyle = (UDateFormatStyle)((((int32_t)testItemPtr->testtype >> 2) & 0x07) - 1);
2636 UDateFormat* dfmt = udat_open(timeStyle, dateStyle, locResPtr->locale, NULL, 0, NULL, 0, &status);
2637 if ( U_FAILURE(status) ) {
2638 log_data_err("udat_open fails for locale %s, status %s (Are you missing data?)\n", locResPtr->locale, u_errorName(status));
2639 continue;
2640 } else {
2641 ulen = udat_toPattern(dfmt, FALSE, upatn, kUBufRemapMax, &status);
2642 udat_close(dfmt);
2643 if ( U_FAILURE(status) ) {
2644 log_err("udat_toPattern fails for locale %s, status %s\n", locResPtr->locale, u_errorName(status));
2645 continue;
2646 }
2647 }
2648 } else if (testItemPtr->testtype == REMAP_TESTTYPE_SKELETON) {
2649 u_strFromUTF8(uskel, kUBufRemapMax, &ulen, testItemPtr->pattern, -1, &status);
2650 ulen = udatpg_getBestPatternWithOptions(dtpg, uskel, ulen, (UDateTimePatternMatchOptions)testItemPtr->options, upatn, kUBufRemapMax, &status);
2651 if ( U_FAILURE(status) ) {
2652 log_err("udatpg_getBestPatternWithOptions fails for locale %s, skeleton \"%s\": status %s\n", locResPtr->locale, testItemPtr->pattern, u_errorName(status));
2653 continue;
2654 }
2655 } else {
2656 ulen = u_unescape(testItemPtr->pattern, upatn, kUBufRemapMax);
2657 }
2658 uelen = u_unescape(*expResultsPtr, uexp, kUBufRemapMax);
2659 ulen = uadatpg_remapPatternWithOptions(dtpg, upatn, ulen, (UDateTimePatternMatchOptions)testItemPtr->options, uget, kUBufRemapMax, &status);
2660 if ( U_FAILURE(status) ) {
2661 log_err("uadatpg_remapPatternWithOptions fails for locale %s pattern \"%s\" opts %08X: status %s\n",
2662 locResPtr->locale, testItemPtr->pattern, testItemPtr->options, u_errorName(status));
2663 } else if (uelen != ulen || u_strncmp(uget, uexp, ulen) != 0) {
2664 char bebuf[kBBufRemapMax];
2665 char bbuf[kBBufRemapMax];
2666 UErrorCode tempStatus = U_ZERO_ERROR;
2667 u_strToUTF8(bebuf, kBBufRemapMax, NULL, uexp, uelen, &tempStatus);
2668 u_strToUTF8(bbuf, kBBufRemapMax, NULL, uget, ulen, &tempStatus);
2669 log_err("uadatpg_remapPatternWithOptions for locale %s pattern \"%s\" opts %08X: expect \"%s\", get \"%s\"\n",
2670 locResPtr->locale, testItemPtr->pattern, testItemPtr->options, bebuf, bbuf);
2671 }
2672 }
2673 udatpg_close(dtpg);
2674 }
2675 }
2676}
2677
b75a7d8f 2678#endif /* #if !UCONFIG_NO_FORMATTING */