]> git.saurik.com Git - apple/icu.git/blame - icuSources/test/cintltst/cdattst.c
ICU-64260.0.1.tar.gz
[apple/icu.git] / icuSources / test / cintltst / cdattst.c
CommitLineData
f3c0d7a5
A
1// © 2016 and later: Unicode, Inc. and others.
2// License & terms of use: http://www.unicode.org/copyright.html
b75a7d8f 3/********************************************************************
2ca993e8
A
4 * COPYRIGHT:
5 * Copyright (c) 1997-2016, International Business Machines Corporation and
b75a7d8f
A
6 * others. All Rights Reserved.
7 ********************************************************************/
8/********************************************************************************
9*
10* File CDATTST.C
11*
12* Modification History:
2ca993e8 13* Name Description
b75a7d8f
A
14* Madhu Katragadda Creation
15*********************************************************************************
16*/
17
18/* C API TEST FOR DATE FORMAT */
19
20#include "unicode/utypes.h"
21
22#if !UCONFIG_NO_FORMATTING
23
24#include "unicode/uloc.h"
25#include "unicode/udat.h"
4388f060 26#include "unicode/udatpg.h"
b75a7d8f
A
27#include "unicode/ucal.h"
28#include "unicode/unum.h"
29#include "unicode/ustring.h"
b331163b 30#include "unicode/ufieldpositer.h"
b75a7d8f
A
31#include "cintltst.h"
32#include "cdattst.h"
33#include "cformtst.h"
34#include "cmemory.h"
4f1e1a09 35#if !U_PLATFORM_HAS_WIN32_API
b331163b 36#include "unicode/uatimeunitformat.h" /* Apple-specific */
4f1e1a09 37#endif
b75a7d8f 38
374ca955
A
39#include <math.h>
40
3d1f044b
A
41#define ADD_ALLOC_TEST 0
42#define WRITE_HOUR_MISMATCH_ERRS 0
43
44#if ADD_ALLOC_TEST
45static void TestPerf(void);
46#endif
374ca955 47static void TestExtremeDates(void);
73c04bcf 48static void TestAllLocales(void);
46f4442e 49static void TestRelativeCrash(void);
4388f060 50static void TestContext(void);
51004dcb 51static void TestCalendarDateParse(void);
b331163b
A
52static void TestParseErrorReturnValue(void);
53static void TestFormatForFields(void);
1546d4af 54static void TestForceGannenNumbering(void);
2ca993e8 55static void TestStandardPatterns(void);
b331163b 56static void TestApplyPatnOverridesTimeSep(void);
2ca993e8 57static void Test12HrFormats(void);
4f1e1a09 58#if !U_PLATFORM_HAS_WIN32_API
b331163b 59static void TestTimeUnitFormat(void); /* Apple-specific */
3d1f044b 60static void TestTimeUnitFormatWithNumStyle(void); /* Apple-specific */
4f1e1a09 61#endif
b331163b 62static void TestRemapPatternWithOpts(void); /* Apple-specific */
3d1f044b
A
63#if WRITE_HOUR_MISMATCH_ERRS
64static void WriteHourMismatchErrs(void); /* 52980140*/
65#endif
374ca955 66
b75a7d8f
A
67void addDateForTest(TestNode** root);
68
374ca955 69#define TESTCASE(x) addTest(root, &x, "tsformat/cdattst/" #x)
b75a7d8f
A
70
71void addDateForTest(TestNode** root)
72{
3d1f044b
A
73#if ADD_ALLOC_TEST
74 TESTCASE(TestPerf);
75#endif
374ca955 76 TESTCASE(TestDateFormat);
46f4442e 77 TESTCASE(TestRelativeDateFormat);
374ca955
A
78 TESTCASE(TestSymbols);
79 TESTCASE(TestDateFormatCalendar);
80 TESTCASE(TestExtremeDates);
73c04bcf 81 TESTCASE(TestAllLocales);
46f4442e 82 TESTCASE(TestRelativeCrash);
4388f060 83 TESTCASE(TestContext);
51004dcb 84 TESTCASE(TestCalendarDateParse);
b331163b
A
85 TESTCASE(TestOverrideNumberFormat);
86 TESTCASE(TestParseErrorReturnValue);
87 TESTCASE(TestFormatForFields);
1546d4af 88 TESTCASE(TestForceGannenNumbering);
2ca993e8 89 TESTCASE(TestStandardPatterns);
b331163b 90 TESTCASE(TestApplyPatnOverridesTimeSep);
2ca993e8 91 TESTCASE(Test12HrFormats);
4f1e1a09 92#if !U_PLATFORM_HAS_WIN32_API
b331163b 93 TESTCASE(TestTimeUnitFormat); /* Apple-specific */
3d1f044b 94 TESTCASE(TestTimeUnitFormatWithNumStyle); /* Apple-specific */
4f1e1a09 95#endif
b331163b 96 TESTCASE(TestRemapPatternWithOpts); /* Apple-specific */
3d1f044b
A
97#if WRITE_HOUR_MISMATCH_ERRS
98 TESTCASE(WriteHourMismatchErrs); /* 52980140 */
99#endif
b75a7d8f
A
100}
101/* Testing the DateFormat API */
102static void TestDateFormat()
103{
104 UDateFormat *def, *fr, *it, *de, *def1, *fr_pat;
105 UDateFormat *any;
106 UDateFormat *copy;
107 UErrorCode status = U_ZERO_ERROR;
108 UChar* result = NULL;
109 const UCalendar *cal;
110 const UNumberFormat *numformat1, *numformat2;
b331163b 111 UNumberFormat *adoptNF;
46f4442e 112 UChar temp[50];
b75a7d8f
A
113 int32_t numlocales;
114 UDate d1;
115 int i;
116 int32_t resultlength;
117 int32_t resultlengthneeded;
118 int32_t parsepos;
119 UDate d = 837039928046.0;
120 double num = -10456.37;
121 /*const char* str="yyyy.MM.dd G 'at' hh:mm:ss z";
122 const char t[]="2/3/76 2:50 AM";*/
123 /*Testing udat_open() to open a dateformat */
374ca955
A
124
125 ctest_setTimeZone(NULL, &status);
126
b75a7d8f
A
127 log_verbose("\nTesting udat_open() with various parameters\n");
128 fr = udat_open(UDAT_FULL, UDAT_DEFAULT, "fr_FR", NULL,0, NULL, 0,&status);
129 if(U_FAILURE(status))
130 {
2ca993e8 131 log_data_err("FAIL: error in creating the dateformat using full time style with french locale -> %s (Are you missing data?)\n",
b75a7d8f
A
132 myErrorName(status) );
133 return;
134 }
2ca993e8 135 /* this is supposed to open default date format, but later on it treats it like it is "en_US"
b75a7d8f
A
136 - very bad if you try to run the tests on machine where default locale is NOT "en_US" */
137 /* def = udat_open(UDAT_SHORT, UDAT_SHORT, NULL, NULL, 0, &status); */
138 def = udat_open(UDAT_SHORT, UDAT_SHORT, "en_US", NULL, 0,NULL, 0, &status);
139 if(U_FAILURE(status))
140 {
2ca993e8 141 log_err("FAIL: error in creating the dateformat using short date and time style\n %s\n",
b75a7d8f
A
142 myErrorName(status) );
143 return;
144 }
145 it = udat_open(UDAT_DEFAULT, UDAT_MEDIUM, "it_IT", NULL, 0, NULL, 0,&status);
146 if(U_FAILURE(status))
147 {
2ca993e8 148 log_err("FAIL: error in creating the dateformat using medium date style with italian locale\n %s\n",
b75a7d8f
A
149 myErrorName(status) );
150 return;
151 }
152 de = udat_open(UDAT_LONG, UDAT_LONG, "de_DE", NULL, 0, NULL, 0,&status);
153 if(U_FAILURE(status))
154 {
155 log_err("FAIL: error in creating the dateformat using long time and date styles with german locale\n %s\n",
156 myErrorName(status));
157 return;
158 }
159 /*creating a default dateformat */
160 def1 = udat_open(UDAT_SHORT, UDAT_SHORT, NULL, NULL, 0,NULL, 0, &status);
161 if(U_FAILURE(status))
162 {
2ca993e8 163 log_err("FAIL: error in creating the dateformat using short date and time style\n %s\n",
b75a7d8f
A
164 myErrorName(status) );
165 return;
166 }
167
168
2ca993e8 169 /*Testing udat_getAvailable() and udat_countAvailable()*/
b75a7d8f
A
170 log_verbose("\nTesting getAvailableLocales and countAvailable()\n");
171 numlocales=udat_countAvailable();
172 /* use something sensible w/o hardcoding the count */
173 if(numlocales < 0)
174 log_data_err("FAIL: error in countAvailable\n");
175 log_verbose("The number of locales for which date/time formatting patterns are available is %d\n", numlocales);
2ca993e8 176
b75a7d8f
A
177 for(i=0;i<numlocales;i++) {
178 UErrorCode subStatus = U_ZERO_ERROR;
179 log_verbose("Testing open of %s\n", udat_getAvailable(i));
73c04bcf 180 any = udat_open(UDAT_SHORT, UDAT_SHORT, udat_getAvailable(i), NULL ,0, NULL, 0, &subStatus);
b75a7d8f 181 if(U_FAILURE(subStatus)) {
73c04bcf 182 log_data_err("FAIL: date format %s (getAvailable(%d)) is not instantiable: %s\n", udat_getAvailable(i), i, u_errorName(subStatus));
b75a7d8f
A
183 }
184 udat_close(any);
185 }
186
187 /*Testing udat_clone()*/
188 log_verbose("\nTesting the udat_clone() function of date format\n");
189 copy=udat_clone(def, &status);
190 if(U_FAILURE(status)){
191 log_err("Error in creating the clone using udat_clone: %s\n", myErrorName(status) );
192 }
193 /*if(def != copy)
194 log_err("Error in udat_clone");*/ /*how should i check for equality???? */
2ca993e8 195
b75a7d8f
A
196 /*Testing udat_format()*/
197 log_verbose("\nTesting the udat_format() function of date format\n");
51004dcb 198 u_uastrcpy(temp, "7/10/96, 4:05 PM");
b75a7d8f
A
199 /*format using def */
200 resultlength=0;
201 resultlengthneeded=udat_format(def, d, NULL, resultlength, NULL, &status);
202 if(status==U_BUFFER_OVERFLOW_ERROR)
203 {
204 status=U_ZERO_ERROR;
205 resultlength=resultlengthneeded+1;
206 if(result != NULL) {
207 free(result);
208 result = NULL;
209 }
210 result=(UChar*)malloc(sizeof(UChar) * resultlength);
211 udat_format(def, d, result, resultlength, NULL, &status);
212 }
213 if(U_FAILURE(status) || !result)
214 {
215 log_err("FAIL: Error in formatting using udat_format(.....) %s\n", myErrorName(status) );
216 return;
217 }
218 else
219 log_verbose("PASS: formatting successful\n");
220 if(u_strcmp(result, temp)==0)
46f4442e 221 log_verbose("PASS: Date Format for US locale successful using udat_format()\n");
729e4ab9
A
222 else {
223 char xbuf[2048];
224 char gbuf[2048];
225 u_austrcpy(xbuf, temp);
226 u_austrcpy(gbuf, result);
227 log_err("FAIL: Date Format for US locale failed using udat_format() - expected %s got %s\n", xbuf, gbuf);
228 }
b75a7d8f 229 /*format using fr */
2ca993e8
A
230
231 u_unescape("10 juil. 1996 \\u00E0 16:05:28 heure d\\u2019\\u00E9t\\u00E9 du Pacifique", temp, 50);
b75a7d8f
A
232 if(result != NULL) {
233 free(result);
234 result = NULL;
235 }
236 result=myDateFormat(fr, d);
237 if(u_strcmp(result, temp)==0)
374ca955 238 log_verbose("PASS: Date Format for french locale successful using udat_format()\n");
b75a7d8f 239 else
46f4442e
A
240 log_data_err("FAIL: Date Format for french locale failed using udat_format().\n" );
241
374ca955 242 /*format using it */
b331163b 243 u_uastrcpy(temp, "10 lug 1996, 16:05:28");
2ca993e8
A
244
245 {
46f4442e
A
246 UChar *fmtted;
247 char g[100];
248 char x[100];
2ca993e8 249
46f4442e
A
250 fmtted = myDateFormat(it,d);
251 u_austrcpy(g, fmtted);
252 u_austrcpy(x, temp);
253 if(u_strcmp(fmtted, temp)==0) {
254 log_verbose("PASS: Date Format for italian locale successful uisng udat_format() - wanted %s, got %s\n", x, g);
255 } else {
256 log_data_err("FAIL: Date Format for italian locale failed using udat_format() - wanted %s, got %s\n", x, g);
257 }
258 }
2ca993e8 259
b75a7d8f
A
260 /*Testing parsing using udat_parse()*/
261 log_verbose("\nTesting parsing using udat_parse()\n");
51004dcb 262 u_uastrcpy(temp,"2/3/76, 2:50 AM");
b75a7d8f 263 parsepos=0;
374ca955 264 status=U_ZERO_ERROR;
2ca993e8 265
b75a7d8f
A
266 d1=udat_parse(def, temp, u_strlen(temp), &parsepos, &status);
267 if(U_FAILURE(status))
268 {
269 log_err("FAIL: Error in parsing using udat_parse(.....) %s\n", myErrorName(status) );
270 }
271 else
272 log_verbose("PASS: parsing succesful\n");
273 /*format it back and check for equality */
2ca993e8
A
274
275
b75a7d8f
A
276 if(u_strcmp(myDateFormat(def, d1),temp)!=0)
277 log_err("FAIL: error in parsing\n");
278
374ca955
A
279 /*Testing parsing using udat_parse()*/
280 log_verbose("\nTesting parsing using udat_parse()\n");
281 u_uastrcpy(temp,"2/Don't parse this part");
282 status=U_ZERO_ERROR;
2ca993e8 283
374ca955
A
284 d1=udat_parse(def, temp, u_strlen(temp), NULL, &status);
285 if(status != U_PARSE_ERROR)
286 {
287 log_err("FAIL: udat_parse(\"bad string\") passed when it should have failed\n");
288 }
289 else
290 log_verbose("PASS: parsing succesful\n");
2ca993e8
A
291
292
293
b75a7d8f
A
294 /*Testing udat_openPattern() */
295 status=U_ZERO_ERROR;
296 log_verbose("\nTesting the udat_openPattern with a specified pattern\n");
297 /*for french locale */
51004dcb 298 fr_pat=udat_open(UDAT_PATTERN, UDAT_PATTERN,"fr_FR",NULL,0,temp, u_strlen(temp), &status);
b75a7d8f
A
299 if(U_FAILURE(status))
300 {
2ca993e8 301 log_err("FAIL: Error in creating a date format using udat_openPattern \n %s\n",
b75a7d8f
A
302 myErrorName(status) );
303 }
304 else
305 log_verbose("PASS: creating dateformat using udat_openPattern() succesful\n");
306
2ca993e8 307
b75a7d8f
A
308 /*Testing applyPattern and toPattern */
309 log_verbose("\nTesting applyPattern and toPattern()\n");
310 udat_applyPattern(def1, FALSE, temp, u_strlen(temp));
311 log_verbose("Extracting the pattern\n");
312
313 resultlength=0;
314 resultlengthneeded=udat_toPattern(def1, FALSE, NULL, resultlength, &status);
315 if(status==U_BUFFER_OVERFLOW_ERROR)
316 {
317 status=U_ZERO_ERROR;
318 resultlength=resultlengthneeded + 1;
319 result=(UChar*)malloc(sizeof(UChar) * resultlength);
320 udat_toPattern(def1, FALSE, result, resultlength, &status);
321 }
322 if(U_FAILURE(status))
323 {
2ca993e8 324 log_err("FAIL: error in extracting the pattern from UNumberFormat\n %s\n",
b75a7d8f
A
325 myErrorName(status) );
326 }
327 if(u_strcmp(result, temp)!=0)
328 log_err("FAIL: Error in extracting the pattern\n");
329 else
330 log_verbose("PASS: applyPattern and toPattern work fine\n");
2ca993e8 331
b75a7d8f 332 if(result != NULL) {
2ca993e8 333 free(result);
b75a7d8f
A
334 result = NULL;
335 }
2ca993e8
A
336
337
b75a7d8f
A
338 /*Testing getter and setter functions*/
339 /*isLenient and setLenient()*/
340 log_verbose("\nTesting the isLenient and setLenient properties\n");
341 udat_setLenient(fr, udat_isLenient(it));
2ca993e8 342 if(udat_isLenient(fr) != udat_isLenient(it))
b75a7d8f
A
343 log_err("ERROR: setLenient() failed\n");
344 else
345 log_verbose("PASS: setLenient() successful\n");
346
347
348 /*Test get2DigitYearStart set2DigitYearStart */
349 log_verbose("\nTesting the get and set 2DigitYearStart properties\n");
350 d1= udat_get2DigitYearStart(fr_pat,&status);
351 if(U_FAILURE(status)) {
352 log_err("ERROR: udat_get2DigitYearStart failed %s\n", myErrorName(status) );
353 }
354 status = U_ZERO_ERROR;
355 udat_set2DigitYearStart(def1 ,d1, &status);
356 if(U_FAILURE(status)) {
357 log_err("ERROR: udat_set2DigitYearStart failed %s\n", myErrorName(status) );
358 }
359 if(udat_get2DigitYearStart(fr_pat, &status) != udat_get2DigitYearStart(def1, &status))
360 log_err("FAIL: error in set2DigitYearStart\n");
361 else
362 log_verbose("PASS: set2DigitYearStart successful\n");
363 /*try setting it to another value */
364 udat_set2DigitYearStart(de, 2000.0, &status);
365 if(U_FAILURE(status)){
366 log_verbose("ERROR: udat_set2DigitYearStart failed %s\n", myErrorName(status) );
367 }
368 if(udat_get2DigitYearStart(de, &status) != 2000)
369 log_err("FAIL: error in set2DigitYearStart\n");
370 else
371 log_verbose("PASS: set2DigitYearStart successful\n");
372
2ca993e8 373
b75a7d8f
A
374
375 /*Test getNumberFormat() and setNumberFormat() */
376 log_verbose("\nTesting the get and set NumberFormat properties of date format\n");
377 numformat1=udat_getNumberFormat(fr_pat);
378 udat_setNumberFormat(def1, numformat1);
379 numformat2=udat_getNumberFormat(def1);
380 if(u_strcmp(myNumformat(numformat1, num), myNumformat(numformat2, num)) !=0)
381 log_err("FAIL: error in setNumberFormat or getNumberFormat()\n");
382 else
383 log_verbose("PASS:setNumberFormat and getNumberFormat succesful\n");
2ca993e8 384
b331163b
A
385 /*Test getNumberFormat() and adoptNumberFormat() */
386 log_verbose("\nTesting the get and adopt NumberFormat properties of date format\n");
387 adoptNF= unum_open(UNUM_DEFAULT, NULL, 0, NULL, NULL, &status);
388 udat_adoptNumberFormat(def1, adoptNF);
389 numformat2=udat_getNumberFormat(def1);
390 if(u_strcmp(myNumformat(adoptNF, num), myNumformat(numformat2, num)) !=0)
391 log_err("FAIL: error in adoptNumberFormat or getNumberFormat()\n");
392 else
393 log_verbose("PASS:adoptNumberFormat and getNumberFormat succesful\n");
b75a7d8f
A
394
395 /*try setting the number format to another format */
396 numformat1=udat_getNumberFormat(def);
397 udat_setNumberFormat(def1, numformat1);
398 numformat2=udat_getNumberFormat(def1);
399 if(u_strcmp(myNumformat(numformat1, num), myNumformat(numformat2, num)) !=0)
400 log_err("FAIL: error in setNumberFormat or getNumberFormat()\n");
401 else
402 log_verbose("PASS: setNumberFormat and getNumberFormat succesful\n");
403
404
405
406 /*Test getCalendar and setCalendar*/
407 log_verbose("\nTesting the udat_getCalendar() and udat_setCalendar() properties\n");
408 cal=udat_getCalendar(fr_pat);
2ca993e8
A
409
410
b75a7d8f
A
411 udat_setCalendar(def1, cal);
412 if(!ucal_equivalentTo(udat_getCalendar(fr_pat), udat_getCalendar(def1)))
413 log_err("FAIL: Error in setting and getting the calendar\n");
414 else
415 log_verbose("PASS: getting and setting calendar successful\n");
2ca993e8 416
b75a7d8f
A
417 if(result!=NULL) {
418 free(result);
419 }
2ca993e8 420
b75a7d8f
A
421 /*Closing the UDateForamt */
422 udat_close(def);
423 udat_close(fr);
424 udat_close(it);
425 udat_close(de);
426 udat_close(def1);
427 udat_close(fr_pat);
428 udat_close(copy);
2ca993e8 429
374ca955 430 ctest_resetTimeZone();
b75a7d8f
A
431}
432
46f4442e
A
433/*
434Test combined relative date formatting (relative date + non-relative time).
435This is a bit tricky since we can't have static test data for comparison, the
436relative date formatting is relative to the time the tests are run. We generate
437the data for comparison dynamically. However, the tests could fail if they are
438run right at midnight Pacific time and the call to ucal_getNow() is before midnight
439while the calls to udat_format are after midnight or span midnight.
440*/
441static const UDate dayInterval = 24.0*60.0*60.0*1000.0;
442static const UChar trdfZone[] = { 0x0055, 0x0053, 0x002F, 0x0050, 0x0061, 0x0063, 0x0069, 0x0066, 0x0069, 0x0063, 0 }; /* US/Pacific */
443static const char trdfLocale[] = "en_US";
444static const UChar minutesPatn[] = { 0x006D, 0x006D, 0 }; /* "mm" */
445static const UChar monthLongPatn[] = { 0x004D, 0x004D, 0x004D, 0x004D, 0 }; /* "MMMM" */
446static const UChar monthMediumPatn[] = { 0x004D, 0x004D, 0x004D, 0 }; /* "MMM" */
447static const UChar monthShortPatn[] = { 0x004D, 0 }; /* "M" */
448static const UDateFormatStyle dateStylesList[] = { UDAT_FULL, UDAT_LONG, UDAT_MEDIUM, UDAT_SHORT, UDAT_NONE };
449static const UChar *monthPatnsList[] = { monthLongPatn, monthLongPatn, monthMediumPatn, monthShortPatn, NULL };
450static const UChar newTimePatn[] = { 0x0048, 0x0048, 0x002C, 0x006D, 0x006D, 0 }; /* "HH,mm" */
451static const UChar minutesStr[] = { 0x0034, 0x0039, 0 }; /* "49", minutes string to search for in output */
452enum { kDateOrTimeOutMax = 96, kDateAndTimeOutMax = 192 };
453
51004dcb
A
454static const UDate minutesTolerance = 2 * 60.0 * 1000.0;
455static const UDate daysTolerance = 2 * 24.0 * 60.0 * 60.0 * 1000.0;
456
46f4442e
A
457static void TestRelativeDateFormat()
458{
459 UDate today = 0.0;
460 const UDateFormatStyle * stylePtr;
461 const UChar ** monthPtnPtr;
462 UErrorCode status = U_ZERO_ERROR;
463 UCalendar * ucal = ucal_open(trdfZone, -1, trdfLocale, UCAL_GREGORIAN, &status);
464 if ( U_SUCCESS(status) ) {
465 int32_t year, month, day;
466 ucal_setMillis(ucal, ucal_getNow(), &status);
467 year = ucal_get(ucal, UCAL_YEAR, &status);
468 month = ucal_get(ucal, UCAL_MONTH, &status);
469 day = ucal_get(ucal, UCAL_DATE, &status);
470 ucal_setDateTime(ucal, year, month, day, 18, 49, 0, &status); /* set to today at 18:49:00 */
471 today = ucal_getMillis(ucal, &status);
472 ucal_close(ucal);
473 }
474 if ( U_FAILURE(status) || today == 0.0 ) {
729e4ab9 475 log_data_err("Generate UDate for a specified time today fails, error %s - (Are you missing data?)\n", myErrorName(status) );
46f4442e
A
476 return;
477 }
478 for (stylePtr = dateStylesList, monthPtnPtr = monthPatnsList; *stylePtr != UDAT_NONE; ++stylePtr, ++monthPtnPtr) {
479 UDateFormat* fmtRelDateTime;
480 UDateFormat* fmtRelDate;
481 UDateFormat* fmtTime;
482 int32_t dayOffset, limit;
483 UFieldPosition fp;
51004dcb
A
484 UChar strDateTime[kDateAndTimeOutMax];
485 UChar strDate[kDateOrTimeOutMax];
486 UChar strTime[kDateOrTimeOutMax];
487 UChar * strPtr;
46f4442e
A
488 int32_t dtpatLen;
489
490 fmtRelDateTime = udat_open(UDAT_SHORT, *stylePtr | UDAT_RELATIVE, trdfLocale, trdfZone, -1, NULL, 0, &status);
491 if ( U_FAILURE(status) ) {
729e4ab9 492 log_data_err("udat_open timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s (Are you missing data?)\n", *stylePtr, myErrorName(status) );
46f4442e
A
493 continue;
494 }
495 fmtRelDate = udat_open(UDAT_NONE, *stylePtr | UDAT_RELATIVE, trdfLocale, trdfZone, -1, NULL, 0, &status);
496 if ( U_FAILURE(status) ) {
497 log_err("udat_open timeStyle NONE dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
498 udat_close(fmtRelDateTime);
499 continue;
500 }
501 fmtTime = udat_open(UDAT_SHORT, UDAT_NONE, trdfLocale, trdfZone, -1, NULL, 0, &status);
502 if ( U_FAILURE(status) ) {
503 log_err("udat_open timeStyle SHORT dateStyle NONE fails, error %s\n", myErrorName(status) );
504 udat_close(fmtRelDateTime);
505 udat_close(fmtRelDate);
506 continue;
507 }
508
509 dtpatLen = udat_toPatternRelativeDate(fmtRelDateTime, strDate, kDateAndTimeOutMax, &status);
510 if ( U_FAILURE(status) ) {
51004dcb
A
511 log_err("udat_toPatternRelativeDate timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
512 status = U_ZERO_ERROR;
46f4442e 513 } else if ( u_strstr(strDate, *monthPtnPtr) == NULL || dtpatLen != u_strlen(strDate) ) {
51004dcb 514 log_err("udat_toPatternRelativeDate timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) date pattern incorrect\n", *stylePtr );
46f4442e
A
515 }
516 dtpatLen = udat_toPatternRelativeTime(fmtRelDateTime, strTime, kDateAndTimeOutMax, &status);
517 if ( U_FAILURE(status) ) {
51004dcb
A
518 log_err("udat_toPatternRelativeTime timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
519 status = U_ZERO_ERROR;
46f4442e 520 } else if ( u_strstr(strTime, minutesPatn) == NULL || dtpatLen != u_strlen(strTime) ) {
51004dcb 521 log_err("udat_toPatternRelativeTime timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) time pattern incorrect\n", *stylePtr );
46f4442e
A
522 }
523 dtpatLen = udat_toPattern(fmtRelDateTime, FALSE, strDateTime, kDateAndTimeOutMax, &status);
524 if ( U_FAILURE(status) ) {
51004dcb
A
525 log_err("udat_toPattern timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
526 status = U_ZERO_ERROR;
46f4442e 527 } else if ( u_strstr(strDateTime, strDate) == NULL || u_strstr(strDateTime, strTime) == NULL || dtpatLen != u_strlen(strDateTime) ) {
51004dcb 528 log_err("udat_toPattern timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) dateTime pattern incorrect\n", *stylePtr );
46f4442e
A
529 }
530 udat_applyPatternRelative(fmtRelDateTime, strDate, u_strlen(strDate), newTimePatn, u_strlen(newTimePatn), &status);
531 if ( U_FAILURE(status) ) {
51004dcb
A
532 log_err("udat_applyPatternRelative timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
533 status = U_ZERO_ERROR;
46f4442e 534 } else {
51004dcb
A
535 udat_toPattern(fmtRelDateTime, FALSE, strDateTime, kDateAndTimeOutMax, &status);
536 if ( U_FAILURE(status) ) {
537 log_err("udat_toPattern timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
538 status = U_ZERO_ERROR;
539 } else if ( u_strstr(strDateTime, newTimePatn) == NULL ) {
540 log_err("udat_applyPatternRelative timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) didn't update time pattern\n", *stylePtr );
541 }
46f4442e
A
542 }
543 udat_applyPatternRelative(fmtRelDateTime, strDate, u_strlen(strDate), strTime, u_strlen(strTime), &status); /* restore original */
544
545 fp.field = UDAT_MINUTE_FIELD;
546 for (dayOffset = -2, limit = 2; dayOffset <= limit; ++dayOffset) {
547 UDate dateToUse = today + (float)dayOffset*dayInterval;
548
549 udat_format(fmtRelDateTime, dateToUse, strDateTime, kDateAndTimeOutMax, &fp, &status);
550 if ( U_FAILURE(status) ) {
551 log_err("udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
552 status = U_ZERO_ERROR;
553 } else {
51004dcb
A
554 int32_t parsePos = 0;
555 UDate dateResult = udat_parse(fmtRelDateTime, strDateTime, -1, &parsePos, &status);
556 UDate dateDiff = (dateResult >= dateToUse)? dateResult - dateToUse: dateToUse - dateResult;
557 if ( U_FAILURE(status) || dateDiff > minutesTolerance ) {
558 log_err("udat_parse timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s, expect approx %.1f, got %.1f, parsePos %d\n",
559 *stylePtr, myErrorName(status), dateToUse, dateResult, parsePos );
560 status = U_ZERO_ERROR;
2ca993e8 561 }
51004dcb 562
46f4442e
A
563 udat_format(fmtRelDate, dateToUse, strDate, kDateOrTimeOutMax, NULL, &status);
564 if ( U_FAILURE(status) ) {
565 log_err("udat_format timeStyle NONE dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
566 status = U_ZERO_ERROR;
567 } else if ( u_strstr(strDateTime, strDate) == NULL ) {
568 log_err("relative date string not found in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", *stylePtr );
51004dcb
A
569 } else {
570 parsePos = 0;
571 dateResult = udat_parse(fmtRelDate, strDate, -1, &parsePos, &status);
572 dateDiff = (dateResult >= dateToUse)? dateResult - dateToUse: dateToUse - dateResult;
573 if ( U_FAILURE(status) || dateDiff > daysTolerance ) {
574 log_err("udat_parse timeStyle NONE dateStyle (%d | UDAT_RELATIVE) fails, error %s, expect approx %.1f, got %.1f, parsePos %d\n",
575 *stylePtr, myErrorName(status), dateToUse, dateResult, parsePos );
576 status = U_ZERO_ERROR;
2ca993e8 577 }
46f4442e
A
578 }
579
580 udat_format(fmtTime, dateToUse, strTime, kDateOrTimeOutMax, NULL, &status);
581 if ( U_FAILURE(status) ) {
582 log_err("udat_format timeStyle SHORT dateStyle NONE fails, error %s\n", myErrorName(status) );
583 status = U_ZERO_ERROR;
584 } else if ( u_strstr(strDateTime, strTime) == NULL ) {
585 log_err("time string not found in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", *stylePtr );
586 }
587
588 strPtr = u_strstr(strDateTime, minutesStr);
589 if ( strPtr != NULL ) {
3d1f044b 590 int32_t beginIndex = (int32_t)(strPtr - strDateTime);
46f4442e
A
591 if ( fp.beginIndex != beginIndex ) {
592 log_err("UFieldPosition beginIndex %d, expected %d, in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", fp.beginIndex, beginIndex, *stylePtr );
593 }
594 } else {
595 log_err("minutes string not found in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", *stylePtr );
596 }
597 }
598 }
599
600 udat_close(fmtRelDateTime);
601 udat_close(fmtRelDate);
602 udat_close(fmtTime);
603 }
604}
605
b75a7d8f
A
606/*Testing udat_getSymbols() and udat_setSymbols() and udat_countSymbols()*/
607static void TestSymbols()
608{
1a147d09 609 UDateFormat *def, *fr, *zhChiCal, *esMX;
b75a7d8f 610 UErrorCode status = U_ZERO_ERROR;
2ca993e8 611 UChar *value=NULL;
b75a7d8f
A
612 UChar *result = NULL;
613 int32_t resultlength;
614 int32_t resultlengthout;
615 UChar *pattern;
2ca993e8 616
b75a7d8f
A
617
618 /*creating a dateformat with french locale */
619 log_verbose("\ncreating a date format with french locale\n");
620 fr = udat_open(UDAT_FULL, UDAT_DEFAULT, "fr_FR", NULL, 0, NULL, 0, &status);
621 if(U_FAILURE(status))
622 {
2ca993e8 623 log_data_err("error in creating the dateformat using full time style with french locale -> %s (Are you missing data?)\n",
b75a7d8f
A
624 myErrorName(status) );
625 return;
626 }
627 /*creating a default dateformat */
628 log_verbose("\ncreating a date format with default locale\n");
2ca993e8 629 /* this is supposed to open default date format, but later on it treats it like it is "en_US"
b75a7d8f
A
630 - very bad if you try to run the tests on machine where default locale is NOT "en_US" */
631 /* def = udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,NULL, NULL, 0, &status); */
632 def = udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,"en_US", NULL, 0, NULL, 0, &status);
633 if(U_FAILURE(status))
634 {
2ca993e8 635 log_err("error in creating the dateformat using short date and time style\n %s\n",
b75a7d8f
A
636 myErrorName(status) );
637 return;
638 }
b331163b
A
639 /*creating a dateformat with zh locale */
640 log_verbose("\ncreating a date format with zh locale for chinese calendar\n");
641 zhChiCal = udat_open(UDAT_NONE, UDAT_FULL, "zh@calendar=chinese", NULL, 0, NULL, 0, &status);
642 if(U_FAILURE(status))
643 {
2ca993e8 644 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
645 myErrorName(status) );
646 return;
647 }
1a147d09
A
648 /*creating a dateformat with es_MX locale */
649 log_verbose("\ncreating a date format with es_MX locale\n");
650 esMX = udat_open(UDAT_SHORT, UDAT_NONE, "es_MX", NULL, 0, NULL, 0, &status);
651 if(U_FAILURE(status))
652 {
653 log_data_err("error in creating the dateformat using no date, short time, locale es_MX -> %s (Are you missing data?)\n",
654 myErrorName(status) );
655 return;
656 }
2ca993e8
A
657
658
b75a7d8f
A
659 /*Testing countSymbols, getSymbols and setSymbols*/
660 log_verbose("\nTesting countSymbols\n");
661 /*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 662 if(udat_countSymbols(def, UDAT_ERAS)!=2 || udat_countSymbols(def, UDAT_MONTHS)!=12 ||
b75a7d8f
A
663 udat_countSymbols(def, UDAT_SHORT_MONTHS)!=12 || udat_countSymbols(def, UDAT_WEEKDAYS)!=8 ||
664 udat_countSymbols(def, UDAT_SHORT_WEEKDAYS)!=8 || udat_countSymbols(def, UDAT_AM_PMS)!=2 ||
73c04bcf 665 udat_countSymbols(def, UDAT_QUARTERS) != 4 || udat_countSymbols(def, UDAT_SHORT_QUARTERS) != 4 ||
b331163b
A
666 udat_countSymbols(def, UDAT_LOCALIZED_CHARS)!=1 || udat_countSymbols(def, UDAT_SHORTER_WEEKDAYS)!=8 ||
667 udat_countSymbols(zhChiCal, UDAT_CYCLIC_YEARS_NARROW)!=60 || udat_countSymbols(zhChiCal, UDAT_ZODIAC_NAMES_NARROW)!=12)
b75a7d8f
A
668 {
669 log_err("FAIL: error in udat_countSymbols\n");
670 }
671 else
672 log_verbose("PASS: udat_countSymbols() successful\n");
673
674 /*testing getSymbols*/
675 log_verbose("\nTesting getSymbols\n");
676 pattern=(UChar*)malloc(sizeof(UChar) * 10);
677 u_uastrcpy(pattern, "jeudi");
678 resultlength=0;
679 resultlengthout=udat_getSymbols(fr, UDAT_WEEKDAYS, 5 , NULL, resultlength, &status);
680 if(status==U_BUFFER_OVERFLOW_ERROR)
681 {
682 status=U_ZERO_ERROR;
683 resultlength=resultlengthout+1;
684 if(result != NULL) {
685 free(result);
686 result = NULL;
687 }
688 result=(UChar*)malloc(sizeof(UChar) * resultlength);
689 udat_getSymbols(fr, UDAT_WEEKDAYS, 5, result, resultlength, &status);
2ca993e8 690
b75a7d8f
A
691 }
692 if(U_FAILURE(status))
693 {
694 log_err("FAIL: Error in udat_getSymbols().... %s\n", myErrorName(status) );
695 }
696 else
697 log_verbose("PASS: getSymbols succesful\n");
698
699 if(u_strcmp(result, pattern)==0)
700 log_verbose("PASS: getSymbols retrieved the right value\n");
701 else
702 log_data_err("FAIL: getSymbols retrieved the wrong value\n");
703
704 /*run series of tests to test getsymbols regressively*/
705 log_verbose("\nTesting getSymbols() regressively\n");
706 VerifygetSymbols(fr, UDAT_WEEKDAYS, 1, "dimanche");
707 VerifygetSymbols(def, UDAT_WEEKDAYS, 1, "Sunday");
708 VerifygetSymbols(fr, UDAT_SHORT_WEEKDAYS, 7, "sam.");
51004dcb 709 VerifygetSymbols(fr, UDAT_SHORTER_WEEKDAYS, 7, "sa");
b75a7d8f
A
710 VerifygetSymbols(def, UDAT_SHORT_WEEKDAYS, 7, "Sat");
711 VerifygetSymbols(def, UDAT_MONTHS, 11, "December");
712 VerifygetSymbols(def, UDAT_MONTHS, 0, "January");
713 VerifygetSymbols(fr, UDAT_ERAS, 0, "av. J.-C.");
714 VerifygetSymbols(def, UDAT_AM_PMS, 0, "AM");
715 VerifygetSymbols(def, UDAT_AM_PMS, 1, "PM");
716 VerifygetSymbols(fr, UDAT_SHORT_MONTHS, 0, "janv.");
717 VerifygetSymbols(def, UDAT_SHORT_MONTHS, 11, "Dec");
73c04bcf
A
718 VerifygetSymbols(fr, UDAT_QUARTERS, 0, "1er trimestre");
719 VerifygetSymbols(def, UDAT_QUARTERS, 3, "4th quarter");
720 VerifygetSymbols(fr, UDAT_SHORT_QUARTERS, 1, "T2");
721 VerifygetSymbols(def, UDAT_SHORT_QUARTERS, 2, "Q3");
b331163b
A
722 VerifygetSymbols(zhChiCal, UDAT_CYCLIC_YEARS_ABBREVIATED, 0, "\\u7532\\u5B50");
723 VerifygetSymbols(zhChiCal, UDAT_CYCLIC_YEARS_NARROW, 59, "\\u7678\\u4EA5");
724 VerifygetSymbols(zhChiCal, UDAT_ZODIAC_NAMES_ABBREVIATED, 0, "\\u9F20");
725 VerifygetSymbols(zhChiCal, UDAT_ZODIAC_NAMES_WIDE, 11, "\\u732A");
1a147d09
A
726 VerifygetSymbols(esMX, UDAT_AM_PMS, 0, "a.m."); // see <rdar://problem/52923924>
727 VerifygetSymbols(esMX, UDAT_AM_PMS, 1, "p.m."); // see <rdar://problem/52923924>
2ca993e8
A
728#if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
729 VerifygetSymbols(def,UDAT_LOCALIZED_CHARS, 0, "GyMdkHmsSEDFwWahKzYeugAZvcLQqVUOXxrbB:");
730#else
731 VerifygetSymbols(def,UDAT_LOCALIZED_CHARS, 0, "GyMdkHmsSEDFwWahKzYeugAZvcLQqVUOXxrbB");
732#endif
b75a7d8f
A
733
734
735 if(result != NULL) {
736 free(result);
737 result = NULL;
738 }
2ca993e8
A
739free(pattern);
740
b75a7d8f
A
741 log_verbose("\nTesting setSymbols\n");
742 /*applying the pattern so that setSymbolss works */
743 resultlength=0;
744 resultlengthout=udat_toPattern(fr, FALSE, NULL, resultlength, &status);
745 if(status==U_BUFFER_OVERFLOW_ERROR)
746 {
747 status=U_ZERO_ERROR;
748 resultlength=resultlengthout + 1;
749 pattern=(UChar*)malloc(sizeof(UChar) * resultlength);
750 udat_toPattern(fr, FALSE, pattern, resultlength, &status);
751 }
752 if(U_FAILURE(status))
753 {
2ca993e8 754 log_err("FAIL: error in extracting the pattern from UNumberFormat\n %s\n",
b75a7d8f
A
755 myErrorName(status) );
756 }
2ca993e8 757
b75a7d8f
A
758 udat_applyPattern(def, FALSE, pattern, u_strlen(pattern));
759 resultlength=0;
760 resultlengthout=udat_toPattern(def, FALSE, NULL, resultlength,&status);
761 if(status==U_BUFFER_OVERFLOW_ERROR)
762 {
763 status=U_ZERO_ERROR;
764 resultlength=resultlengthout + 1;
765 if(result != NULL) {
766 free(result);
767 result = NULL;
768 }
769 result=(UChar*)malloc(sizeof(UChar) * resultlength);
770 udat_toPattern(fr, FALSE,result, resultlength, &status);
771 }
772 if(U_FAILURE(status))
773 {
2ca993e8 774 log_err("FAIL: error in extracting the pattern from UNumberFormat\n %s\n",
b75a7d8f
A
775 myErrorName(status) );
776 }
777 if(u_strcmp(result, pattern)==0)
778 log_verbose("Pattern applied properly\n");
779 else
780 log_err("pattern could not be applied properly\n");
781
782free(pattern);
783 /*testing set symbols */
784 resultlength=0;
785 resultlengthout=udat_getSymbols(fr, UDAT_MONTHS, 11 , NULL, resultlength, &status);
786 if(status==U_BUFFER_OVERFLOW_ERROR){
787 status=U_ZERO_ERROR;
788 resultlength=resultlengthout+1;
789 if(result != NULL) {
790 free(result);
791 result = NULL;
792 }
793 result=(UChar*)malloc(sizeof(UChar) * resultlength);
794 udat_getSymbols(fr, UDAT_MONTHS, 11, result, resultlength, &status);
2ca993e8 795
b75a7d8f
A
796 }
797 if(U_FAILURE(status))
798 log_err("FAIL: error in getSymbols() %s\n", myErrorName(status) );
799 resultlength=resultlengthout+1;
2ca993e8 800
b75a7d8f
A
801 udat_setSymbols(def, UDAT_MONTHS, 11, result, resultlength, &status);
802 if(U_FAILURE(status))
803 {
804 log_err("FAIL: Error in udat_setSymbols() : %s\n", myErrorName(status) );
805 }
806 else
807 log_verbose("PASS: SetSymbols successful\n");
2ca993e8 808
b75a7d8f
A
809 resultlength=0;
810 resultlengthout=udat_getSymbols(def, UDAT_MONTHS, 11, NULL, resultlength, &status);
811 if(status==U_BUFFER_OVERFLOW_ERROR){
812 status=U_ZERO_ERROR;
813 resultlength=resultlengthout+1;
814 value=(UChar*)malloc(sizeof(UChar) * resultlength);
815 udat_getSymbols(def, UDAT_MONTHS, 11, value, resultlength, &status);
816 }
817 if(U_FAILURE(status))
818 log_err("FAIL: error in retrieving the value using getSymbols i.e roundtrip\n");
2ca993e8 819
b75a7d8f
A
820 if(u_strcmp(result, value)!=0)
821 log_data_err("FAIL: Error in settting and getting symbols\n");
822 else
823 log_verbose("PASS: setSymbols successful\n");
2ca993e8
A
824
825
b75a7d8f
A
826 /*run series of tests to test setSymbols regressively*/
827 log_verbose("\nTesting setSymbols regressively\n");
b75a7d8f 828 VerifysetSymbols(def, UDAT_ERAS, 0, "BeforeChrist");
73c04bcf
A
829 VerifysetSymbols(def, UDAT_ERA_NAMES, 1, "AnnoDomini");
830 VerifysetSymbols(def, UDAT_WEEKDAYS, 1, "Sundayweek");
b75a7d8f 831 VerifysetSymbols(def, UDAT_SHORT_WEEKDAYS, 7, "Satweek");
73c04bcf
A
832 VerifysetSymbols(def, UDAT_NARROW_WEEKDAYS, 4, "M");
833 VerifysetSymbols(def, UDAT_STANDALONE_WEEKDAYS, 1, "Sonntagweek");
834 VerifysetSymbols(def, UDAT_STANDALONE_SHORT_WEEKDAYS, 7, "Sams");
835 VerifysetSymbols(def, UDAT_STANDALONE_NARROW_WEEKDAYS, 4, "V");
b75a7d8f
A
836 VerifysetSymbols(fr, UDAT_MONTHS, 11, "december");
837 VerifysetSymbols(fr, UDAT_SHORT_MONTHS, 0, "Jan");
73c04bcf
A
838 VerifysetSymbols(fr, UDAT_NARROW_MONTHS, 1, "R");
839 VerifysetSymbols(fr, UDAT_STANDALONE_MONTHS, 11, "dezember");
840 VerifysetSymbols(fr, UDAT_STANDALONE_SHORT_MONTHS, 7, "Aug");
841 VerifysetSymbols(fr, UDAT_STANDALONE_NARROW_MONTHS, 2, "M");
842 VerifysetSymbols(fr, UDAT_QUARTERS, 0, "1. Quart");
843 VerifysetSymbols(fr, UDAT_SHORT_QUARTERS, 1, "QQ2");
844 VerifysetSymbols(fr, UDAT_STANDALONE_QUARTERS, 2, "3rd Quar.");
845 VerifysetSymbols(fr, UDAT_STANDALONE_SHORT_QUARTERS, 3, "4QQ");
b331163b
A
846 VerifysetSymbols(zhChiCal, UDAT_CYCLIC_YEARS_ABBREVIATED, 1, "yi-chou");
847 VerifysetSymbols(zhChiCal, UDAT_ZODIAC_NAMES_ABBREVIATED, 1, "Ox");
848
b75a7d8f 849
b75a7d8f
A
850 /*run series of tests to test get and setSymbols regressively*/
851 log_verbose("\nTesting get and set symbols regressively\n");
852 VerifygetsetSymbols(fr, def, UDAT_WEEKDAYS, 1);
853 VerifygetsetSymbols(fr, def, UDAT_WEEKDAYS, 7);
854 VerifygetsetSymbols(fr, def, UDAT_SHORT_WEEKDAYS, 1);
855 VerifygetsetSymbols(fr, def, UDAT_SHORT_WEEKDAYS, 7);
856 VerifygetsetSymbols(fr, def, UDAT_MONTHS, 0);
857 VerifygetsetSymbols(fr, def, UDAT_SHORT_MONTHS, 0);
858 VerifygetsetSymbols(fr, def, UDAT_ERAS,1);
859 VerifygetsetSymbols(fr, def, UDAT_LOCALIZED_CHARS, 0);
860 VerifygetsetSymbols(fr, def, UDAT_AM_PMS, 1);
861
862
863 /*closing*/
2ca993e8 864
b75a7d8f
A
865 udat_close(fr);
866 udat_close(def);
b331163b 867 udat_close(zhChiCal);
1a147d09 868 udat_close(esMX);
b75a7d8f
A
869 if(result != NULL) {
870 free(result);
871 result = NULL;
872 }
873 free(value);
2ca993e8 874
b75a7d8f
A
875}
876
877/**
878 * Test DateFormat(Calendar) API
879 */
880static void TestDateFormatCalendar() {
881 UDateFormat *date=0, *time=0, *full=0;
882 UCalendar *cal=0;
883 UChar buf[256];
884 char cbuf[256];
885 int32_t pos;
886 UDate when;
887 UErrorCode ec = U_ZERO_ERROR;
b331163b
A
888 UChar buf1[256];
889 int32_t len1;
890 const char *expected;
891 UChar uExpected[32];
b75a7d8f 892
374ca955
A
893 ctest_setTimeZone(NULL, &ec);
894
b75a7d8f
A
895 /* Create a formatter for date fields. */
896 date = udat_open(UDAT_NONE, UDAT_SHORT, "en_US", NULL, 0, NULL, 0, &ec);
897 if (U_FAILURE(ec)) {
2ca993e8 898 log_data_err("FAIL: udat_open(NONE, SHORT, en_US) failed with %s (Are you missing data?)\n",
b75a7d8f
A
899 u_errorName(ec));
900 goto FAIL;
901 }
902
903 /* Create a formatter for time fields. */
904 time = udat_open(UDAT_SHORT, UDAT_NONE, "en_US", NULL, 0, NULL, 0, &ec);
905 if (U_FAILURE(ec)) {
2ca993e8 906 log_err("FAIL: udat_open(SHORT, NONE, en_US) failed with %s\n",
b75a7d8f
A
907 u_errorName(ec));
908 goto FAIL;
909 }
910
911 /* Create a full format for output */
912 full = udat_open(UDAT_FULL, UDAT_FULL, "en_US", NULL, 0, NULL, 0, &ec);
913 if (U_FAILURE(ec)) {
2ca993e8 914 log_err("FAIL: udat_open(FULL, FULL, en_US) failed with %s\n",
b75a7d8f
A
915 u_errorName(ec));
916 goto FAIL;
917 }
918
919 /* Create a calendar */
920 cal = ucal_open(NULL, 0, "en_US", UCAL_GREGORIAN, &ec);
921 if (U_FAILURE(ec)) {
2ca993e8 922 log_err("FAIL: ucal_open(en_US) failed with %s\n",
b75a7d8f
A
923 u_errorName(ec));
924 goto FAIL;
925 }
926
927 /* Parse the date */
928 ucal_clear(cal);
929 u_uastrcpy(buf, "4/5/2001");
930 pos = 0;
931 udat_parseCalendar(date, cal, buf, -1, &pos, &ec);
932 if (U_FAILURE(ec)) {
933 log_err("FAIL: udat_parseCalendar(4/5/2001) failed at %d with %s\n",
934 pos, u_errorName(ec));
935 goto FAIL;
936 }
937
b331163b
A
938 /* Check if formatCalendar matches the original date */
939 len1 = udat_formatCalendar(date, cal, buf1, UPRV_LENGTHOF(buf1), NULL, &ec);
940 if (U_FAILURE(ec)) {
941 log_err("FAIL: udat_formatCalendar(4/5/2001) failed with %s\n",
942 u_errorName(ec));
943 goto FAIL;
944 }
945 expected = "4/5/01";
946 u_uastrcpy(uExpected, expected);
947 if (u_strlen(uExpected) != len1 || u_strncmp(uExpected, buf1, len1) != 0) {
948 log_err("FAIL: udat_formatCalendar(4/5/2001), expected: %s", expected);
949 }
950
b75a7d8f
A
951 /* Parse the time */
952 u_uastrcpy(buf, "5:45 PM");
953 pos = 0;
954 udat_parseCalendar(time, cal, buf, -1, &pos, &ec);
955 if (U_FAILURE(ec)) {
956 log_err("FAIL: udat_parseCalendar(17:45) failed at %d with %s\n",
957 pos, u_errorName(ec));
958 goto FAIL;
959 }
b331163b
A
960
961 /* Check if formatCalendar matches the original time */
962 len1 = udat_formatCalendar(time, cal, buf1, UPRV_LENGTHOF(buf1), NULL, &ec);
963 if (U_FAILURE(ec)) {
964 log_err("FAIL: udat_formatCalendar(17:45) failed with %s\n",
965 u_errorName(ec));
966 goto FAIL;
967 }
968 expected = "5:45 PM";
969 u_uastrcpy(uExpected, expected);
970 if (u_strlen(uExpected) != len1 || u_strncmp(uExpected, buf1, len1) != 0) {
971 log_err("FAIL: udat_formatCalendar(17:45), expected: %s", expected);
972 }
973
b75a7d8f
A
974 /* Check result */
975 when = ucal_getMillis(cal, &ec);
976 if (U_FAILURE(ec)) {
977 log_err("FAIL: ucal_getMillis() failed with %s\n", u_errorName(ec));
978 goto FAIL;
979 }
980 udat_format(full, when, buf, sizeof(buf), NULL, &ec);
981 if (U_FAILURE(ec)) {
982 log_err("FAIL: udat_format() failed with %s\n", u_errorName(ec));
983 goto FAIL;
984 }
985 u_austrcpy(cbuf, buf);
986 /* Thursday, April 5, 2001 5:45:00 PM PDT 986517900000 */
987 if (when == 986517900000.0) {
988 log_verbose("Ok: Parsed result: %s\n", cbuf);
989 } else {
374ca955 990 log_err("FAIL: Parsed result: %s, exp 4/5/2001 5:45 PM\n", cbuf);
b75a7d8f
A
991 }
992
2ca993e8 993 FAIL:
b75a7d8f
A
994 udat_close(date);
995 udat_close(time);
996 udat_close(full);
997 ucal_close(cal);
374ca955
A
998
999 ctest_resetTimeZone();
b75a7d8f
A
1000}
1001
51004dcb
A
1002
1003
1004/**
57a6839d 1005 * Test parsing two digit year against "YY" vs. "YYYY" patterns
51004dcb
A
1006 */
1007static void TestCalendarDateParse() {
1008
57a6839d
A
1009 int32_t result;
1010 UErrorCode ec = U_ZERO_ERROR;
51004dcb 1011 UDateFormat* simpleDateFormat = 0;
57a6839d
A
1012 int32_t parsePos = 0;
1013 int32_t twoDigitCenturyStart = 75;
1014 int32_t currentTwoDigitYear = 0;
1015 int32_t startCentury = 0;
51004dcb
A
1016 UCalendar* tempCal = 0;
1017 UCalendar* calendar = 0;
1018
1019 U_STRING_DECL(pattern, "yyyy", 4);
1020 U_STRING_DECL(pattern2, "yy", 2);
1021 U_STRING_DECL(text, "75", 2);
1022
1023 U_STRING_INIT(pattern, "yyyy", 4);
1024 U_STRING_INIT(pattern2, "yy", 2);
1025 U_STRING_INIT(text, "75", 2);
1026
1027 simpleDateFormat = udat_open(UDAT_FULL, UDAT_FULL, "en-GB", 0, 0, 0, 0, &ec);
1028 if (U_FAILURE(ec)) {
1029 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));
1030 return;
1031 }
1032 udat_applyPattern(simpleDateFormat, 0, pattern, u_strlen(pattern));
1033 udat_setLenient(simpleDateFormat, 0);
1034
1035 currentTwoDigitYear = getCurrentYear() % 100;
1036 startCentury = getCurrentYear() - currentTwoDigitYear;
1037 if (twoDigitCenturyStart > currentTwoDigitYear) {
57a6839d 1038 startCentury -= 100;
51004dcb 1039 }
57a6839d
A
1040 tempCal = ucal_open(NULL, -1, NULL, UCAL_GREGORIAN, &ec);
1041 ucal_setMillis(tempCal, 0, &ec);
1042 ucal_setDateTime(tempCal, startCentury + twoDigitCenturyStart, UCAL_JANUARY, 1, 0, 0, 0, &ec);
1043 udat_set2DigitYearStart(simpleDateFormat, ucal_getMillis(tempCal, &ec), &ec);
51004dcb 1044
57a6839d
A
1045 calendar = ucal_open(NULL, -1, NULL, UCAL_GREGORIAN, &ec);
1046 ucal_setMillis(calendar, 0, &ec);
1047 ucal_setDateTime(calendar, twoDigitCenturyStart, UCAL_JANUARY, 1, 0, 0, 0, &ec);
51004dcb 1048
57a6839d 1049 udat_parseCalendar(simpleDateFormat, calendar, text, u_strlen(text), &parsePos, &ec);
51004dcb
A
1050
1051 /* Check result */
1052 result = ucal_get(calendar, UCAL_YEAR, &ec);
1053 if (U_FAILURE(ec)) {
1054 log_err("FAIL: ucal_get(UCAL_YEAR) failed with %s\n", u_errorName(ec));
1055 goto FAIL;
1056 }
1057
1058 if (result != 75) {
1059 log_err("FAIL: parsed incorrect year: %d\n", result);
1060 goto FAIL;
1061 }
1062
1063 parsePos = 0;
1064 udat_applyPattern(simpleDateFormat, 0, pattern2, u_strlen(pattern2));
57a6839d 1065 udat_parseCalendar(simpleDateFormat, calendar, text, u_strlen(text), &parsePos, &ec);
51004dcb
A
1066
1067 /* Check result */
1068 result = ucal_get(calendar, UCAL_YEAR, &ec);
1069 if (U_FAILURE(ec)) {
1070 log_err("FAIL: ucal_get(UCAL_YEAR) failed with %s\n", u_errorName(ec));
1071 goto FAIL;
1072 }
1073
1074 if (result != 1975) {
1075 log_err("FAIL: parsed incorrect year: %d\n", result);
1076 goto FAIL;
1077 }
1078
1079 FAIL:
1080 udat_close(simpleDateFormat);
1081 udat_close(tempCal);
1082 udat_close(calendar);
1083}
1084
1085
b75a7d8f 1086/*INTERNAL FUNCTIONS USED*/
51004dcb
A
1087static int getCurrentYear() {
1088 static int currentYear = 0;
1089 if (currentYear == 0) {
1090 UErrorCode status = U_ZERO_ERROR;
1091 UCalendar *cal = ucal_open(NULL, -1, NULL, UCAL_GREGORIAN, &status);
1092 if (!U_FAILURE(status)) {
1093 /* Get the current year from the default UCalendar */
1094 currentYear = ucal_get(cal, UCAL_YEAR, &status);
1095 ucal_close(cal);
1096 }
1097 }
1098
1099 return currentYear;
1100}
1101
729e4ab9
A
1102/* N.B.: use idx instead of index to avoid 'shadow' warnings in strict mode. */
1103static void VerifygetSymbols(UDateFormat* datfor, UDateFormatSymbolType type, int32_t idx, const char* expected)
b75a7d8f
A
1104{
1105 UChar *pattern=NULL;
1106 UErrorCode status = U_ZERO_ERROR;
1107 UChar *result=NULL;
1108 int32_t resultlength, resultlengthout;
3d1f044b 1109 int32_t patternSize = (int32_t)strlen(expected) + 1;
2ca993e8 1110
b331163b
A
1111 pattern=(UChar*)malloc(sizeof(UChar) * patternSize);
1112 u_unescape(expected, pattern, patternSize);
b75a7d8f 1113 resultlength=0;
729e4ab9 1114 resultlengthout=udat_getSymbols(datfor, type, idx , NULL, resultlength, &status);
b75a7d8f
A
1115 if(status==U_BUFFER_OVERFLOW_ERROR)
1116 {
1117 status=U_ZERO_ERROR;
1118 resultlength=resultlengthout+1;
1119 result=(UChar*)malloc(sizeof(UChar) * resultlength);
729e4ab9 1120 udat_getSymbols(datfor, type, idx, result, resultlength, &status);
2ca993e8 1121
b75a7d8f
A
1122 }
1123 if(U_FAILURE(status))
1124 {
1125 log_err("FAIL: Error in udat_getSymbols()... %s\n", myErrorName(status) );
1126 return;
1127 }
1128 if(u_strcmp(result, pattern)==0)
1129 log_verbose("PASS: getSymbols retrieved the right value\n");
1130 else{
2ca993e8 1131 log_data_err("FAIL: getSymbols retrieved the wrong value\n Expected %s Got %s\n", expected,
b331163b 1132 aescstrdup(result,-1) );
b75a7d8f
A
1133 }
1134 free(result);
1135 free(pattern);
1136}
1137
729e4ab9 1138static void VerifysetSymbols(UDateFormat* datfor, UDateFormatSymbolType type, int32_t idx, const char* expected)
b75a7d8f
A
1139{
1140 UChar *result=NULL;
1141 UChar *value=NULL;
1142 int32_t resultlength, resultlengthout;
1143 UErrorCode status = U_ZERO_ERROR;
3d1f044b 1144 int32_t valueLen, valueSize = (int32_t)strlen(expected) + 1;
b75a7d8f 1145
b331163b
A
1146 value=(UChar*)malloc(sizeof(UChar) * valueSize);
1147 valueLen = u_unescape(expected, value, valueSize);
1148 udat_setSymbols(datfor, type, idx, value, valueLen, &status);
b75a7d8f
A
1149 if(U_FAILURE(status))
1150 {
1151 log_err("FAIL: Error in udat_setSymbols() %s\n", myErrorName(status) );
1152 return;
1153 }
1154
1155 resultlength=0;
729e4ab9 1156 resultlengthout=udat_getSymbols(datfor, type, idx, NULL, resultlength, &status);
b75a7d8f
A
1157 if(status==U_BUFFER_OVERFLOW_ERROR){
1158 status=U_ZERO_ERROR;
1159 resultlength=resultlengthout+1;
1160 result=(UChar*)malloc(sizeof(UChar) * resultlength);
729e4ab9 1161 udat_getSymbols(datfor, type, idx, result, resultlength, &status);
b75a7d8f
A
1162 }
1163 if(U_FAILURE(status)){
2ca993e8 1164 log_err("FAIL: error in retrieving the value using getSymbols after setting it previously\n %s\n",
b75a7d8f
A
1165 myErrorName(status) );
1166 return;
1167 }
2ca993e8 1168
b75a7d8f 1169 if(u_strcmp(result, value)!=0){
b331163b
A
1170 log_err("FAIL:Error in setting and then getting symbols\n Expected %s Got %s\n", expected,
1171 aescstrdup(result,-1) );
b75a7d8f
A
1172 }
1173 else
1174 log_verbose("PASS: setSymbols successful\n");
1175
1176 free(value);
1177 free(result);
1178}
1179
1180
729e4ab9 1181static void VerifygetsetSymbols(UDateFormat* from, UDateFormat* to, UDateFormatSymbolType type, int32_t idx)
b75a7d8f
A
1182{
1183 UChar *result=NULL;
1184 UChar *value=NULL;
1185 int32_t resultlength, resultlengthout;
1186 UErrorCode status = U_ZERO_ERROR;
2ca993e8 1187
b75a7d8f 1188 resultlength=0;
729e4ab9 1189 resultlengthout=udat_getSymbols(from, type, idx , NULL, resultlength, &status);
b75a7d8f
A
1190 if(status==U_BUFFER_OVERFLOW_ERROR){
1191 status=U_ZERO_ERROR;
1192 resultlength=resultlengthout+1;
1193 result=(UChar*)malloc(sizeof(UChar) * resultlength);
729e4ab9 1194 udat_getSymbols(from, type, idx, result, resultlength, &status);
b75a7d8f
A
1195 }
1196 if(U_FAILURE(status)){
1197 log_err("FAIL: error in getSymbols() %s\n", myErrorName(status) );
1198 return;
1199 }
2ca993e8 1200
b75a7d8f 1201 resultlength=resultlengthout+1;
729e4ab9 1202 udat_setSymbols(to, type, idx, result, resultlength, &status);
b75a7d8f
A
1203 if(U_FAILURE(status))
1204 {
1205 log_err("FAIL: Error in udat_setSymbols() : %s\n", myErrorName(status) );
1206 return;
1207 }
1208
1209 resultlength=0;
729e4ab9 1210 resultlengthout=udat_getSymbols(to, type, idx, NULL, resultlength, &status);
b75a7d8f
A
1211 if(status==U_BUFFER_OVERFLOW_ERROR){
1212 status=U_ZERO_ERROR;
1213 resultlength=resultlengthout+1;
1214 value=(UChar*)malloc(sizeof(UChar) * resultlength);
729e4ab9 1215 udat_getSymbols(to, type, idx, value, resultlength, &status);
b75a7d8f
A
1216 }
1217 if(U_FAILURE(status)){
2ca993e8 1218 log_err("FAIL: error in retrieving the value using getSymbols i.e roundtrip\n %s\n",
b75a7d8f
A
1219 myErrorName(status) );
1220 return;
1221 }
2ca993e8 1222
b75a7d8f
A
1223 if(u_strcmp(result, value)!=0){
1224 log_data_err("FAIL:Error in setting and then getting symbols\n Expected %s Got %s\n", austrdup(result),
1225 austrdup(value) );
1226 }
1227 else
1228 log_verbose("PASS: setSymbols successful\n");
1229
1230 free(value);
1231 free(result);
1232}
1233
1234
1235static UChar* myNumformat(const UNumberFormat* numfor, double d)
1236{
1237 UChar *result2=NULL;
1238 int32_t resultlength, resultlengthneeded;
1239 UErrorCode status = U_ZERO_ERROR;
2ca993e8 1240
b75a7d8f
A
1241 resultlength=0;
1242 resultlengthneeded=unum_formatDouble(numfor, d, NULL, resultlength, NULL, &status);
1243 if(status==U_BUFFER_OVERFLOW_ERROR)
1244 {
1245 status=U_ZERO_ERROR;
1246 resultlength=resultlengthneeded+1;
1247 /*result2=(UChar*)malloc(sizeof(UChar) * resultlength);*/ /* this leaks */
1248 result2=(UChar*)ctst_malloc(sizeof(UChar) * resultlength); /*this won't*/
1249 unum_formatDouble(numfor, d, result2, resultlength, NULL, &status);
1250 }
1251 if(U_FAILURE(status))
1252 {
1253 log_err("FAIL: Error in formatting using unum_format(.....) %s\n", myErrorName(status) );
1254 return 0;
1255 }
2ca993e8 1256
b75a7d8f
A
1257 return result2;
1258}
1259
374ca955
A
1260/**
1261 * The search depth for TestExtremeDates. The total number of
1262 * dates that will be tested is (2^EXTREME_DATES_DEPTH) - 1.
1263 */
1264#define EXTREME_DATES_DEPTH 8
1265
1266/**
1267 * Support for TestExtremeDates (below).
1268 *
1269 * Test a single date to see whether udat_format handles it properly.
1270 */
1271static UBool _aux1ExtremeDates(UDateFormat* fmt, UDate date,
1272 UChar* buf, int32_t buflen, char* cbuf,
1273 UErrorCode* ec) {
1274 int32_t len = udat_format(fmt, date, buf, buflen, 0, ec);
1275 if (!assertSuccess("udat_format", ec)) return FALSE;
1276 u_austrncpy(cbuf, buf, buflen);
1277 if (len < 4) {
1278 log_err("FAIL: udat_format(%g) => \"%s\"\n", date, cbuf);
1279 } else {
1280 log_verbose("udat_format(%g) => \"%s\"\n", date, cbuf);
1281 }
1282 return TRUE;
1283}
1284
1285/**
1286 * Support for TestExtremeDates (below).
1287 *
1288 * Recursively test between 'small' and 'large', up to the depth
1289 * limit specified by EXTREME_DATES_DEPTH.
1290 */
1291static UBool _aux2ExtremeDates(UDateFormat* fmt, UDate small, UDate large,
1292 UChar* buf, int32_t buflen, char* cbuf,
1293 int32_t count,
1294 UErrorCode* ec) {
1295 /* Logarithmic midpoint; see below */
1296 UDate mid = (UDate) exp((log(small) + log(large)) / 2);
1297 if (count == EXTREME_DATES_DEPTH) {
1298 return TRUE;
1299 }
1300 return
1301 _aux1ExtremeDates(fmt, mid, buf, buflen, cbuf, ec) &&
1302 _aux2ExtremeDates(fmt, small, mid, buf, buflen, cbuf, count+1, ec) &&
1303 _aux2ExtremeDates(fmt, mid, large, buf, buflen, cbuf, count+1, ec);
1304}
1305
1306/**
1307 * http://www.jtcsv.com/cgibin/icu-bugs?findid=3659
1308 *
1309 * For certain large dates, udat_format crashes on MacOS. This test
1310 * attempts to reproduce this problem by doing a recursive logarithmic*
1311 * binary search of a predefined interval (from 'small' to 'large').
1312 *
1313 * The limit of the search is given by EXTREME_DATES_DEPTH, above.
1314 *
1315 * *The search has to be logarithmic, not linear. A linear search of the
1316 * range 0..10^30, for example, will find 0.5*10^30, then 0.25*10^30 and
1317 * 0.75*10^30, etc. A logarithmic search will find 10^15, then 10^7.5
1318 * and 10^22.5, etc.
1319 */
1320static void TestExtremeDates() {
1321 UDateFormat *fmt;
1322 UErrorCode ec;
1323 UChar buf[256];
1324 char cbuf[256];
1325 const double small = 1000; /* 1 sec */
1326 const double large = 1e+30; /* well beyond usable UDate range */
1327
1328 /* There is no need to test larger values from 1e+30 to 1e+300;
1329 the failures occur around 1e+27, and never above 1e+30. */
2ca993e8 1330
374ca955
A
1331 ec = U_ZERO_ERROR;
1332 fmt = udat_open(UDAT_LONG, UDAT_LONG, "en_US",
1333 0, 0, 0, 0, &ec);
729e4ab9
A
1334 if (U_FAILURE(ec)) {
1335 log_data_err("FAIL: udat_open (%s) (Are you missing data?)\n", u_errorName(ec));
1336 return;
1337 }
374ca955 1338
2ca993e8 1339 _aux2ExtremeDates(fmt, small, large, buf, UPRV_LENGTHOF(buf), cbuf, 0, &ec);
374ca955
A
1340
1341 udat_close(fmt);
1342}
1343
73c04bcf
A
1344static void TestAllLocales(void) {
1345 int32_t idx, dateIdx, timeIdx, localeCount;
1346 static const UDateFormatStyle style[] = {
1347 UDAT_FULL, UDAT_LONG, UDAT_MEDIUM, UDAT_SHORT
1348 };
1349 localeCount = uloc_countAvailable();
1350 for (idx = 0; idx < localeCount; idx++) {
2ca993e8
A
1351 for (dateIdx = 0; dateIdx < UPRV_LENGTHOF(style); dateIdx++) {
1352 for (timeIdx = 0; timeIdx < UPRV_LENGTHOF(style); timeIdx++) {
73c04bcf
A
1353 UErrorCode status = U_ZERO_ERROR;
1354 udat_close(udat_open(style[dateIdx], style[timeIdx],
1355 uloc_getAvailable(idx), NULL, 0, NULL, 0, &status));
1356 if (U_FAILURE(status)) {
1357 log_err("FAIL: udat_open(%s) failed with (%s) dateIdx=%d, timeIdx=%d\n",
1358 uloc_getAvailable(idx), u_errorName(status), dateIdx, timeIdx);
1359 }
1360 }
1361 }
1362 }
1363}
1364
46f4442e
A
1365static void TestRelativeCrash(void) {
1366 static const UChar tzName[] = { 0x0055, 0x0053, 0x002F, 0x0050, 0x0061, 0x0063, 0x0069, 0x0066, 0x0069, 0x0063, 0 };
1367 static const UDate aDate = -631152000000.0;
1368
1369 UErrorCode status = U_ZERO_ERROR;
1370 UErrorCode expectStatus = U_ILLEGAL_ARGUMENT_ERROR;
1371 UDateFormat icudf;
1372
1373 icudf = udat_open(UDAT_NONE, UDAT_SHORT_RELATIVE, "en", tzName, -1, NULL, 0, &status);
1374 if ( U_SUCCESS(status) ) {
1375 const char *what = "???";
1376 {
1377 UErrorCode subStatus = U_ZERO_ERROR;
1378 what = "udat_set2DigitYearStart";
1379 log_verbose("Trying %s on a relative date..\n", what);
2ca993e8 1380 udat_set2DigitYearStart(icudf, aDate, &subStatus);
46f4442e
A
1381 if(subStatus == expectStatus) {
1382 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1383 } else {
1384 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
2ca993e8 1385 }
46f4442e
A
1386 }
1387 {
1388 /* clone works polymorphically. try it anyways */
1389 UErrorCode subStatus = U_ZERO_ERROR;
1390 UDateFormat *oth;
1391 what = "clone";
1392 log_verbose("Trying %s on a relative date..\n", what);
1393 oth = udat_clone(icudf, &subStatus);
1394 if(subStatus == U_ZERO_ERROR) {
1395 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1396 udat_close(oth); /* ? */
1397 } else {
1398 log_err("FAIL: didn't crash on %s, but got %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
2ca993e8 1399 }
46f4442e
A
1400 }
1401 {
1402 UErrorCode subStatus = U_ZERO_ERROR;
1403 what = "udat_get2DigitYearStart";
1404 log_verbose("Trying %s on a relative date..\n", what);
2ca993e8 1405 udat_get2DigitYearStart(icudf, &subStatus);
46f4442e
A
1406 if(subStatus == expectStatus) {
1407 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1408 } else {
1409 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
2ca993e8 1410 }
46f4442e
A
1411 }
1412 {
1413 /* Now udat_toPattern works for relative date formatters, unless localized is TRUE */
1414 UErrorCode subStatus = U_ZERO_ERROR;
1415 what = "udat_toPattern";
1416 log_verbose("Trying %s on a relative date..\n", what);
2ca993e8 1417 udat_toPattern(icudf, TRUE,NULL,0, &subStatus);
46f4442e
A
1418 if(subStatus == expectStatus) {
1419 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1420 } else {
1421 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
2ca993e8 1422 }
46f4442e
A
1423 }
1424 {
1425 UErrorCode subStatus = U_ZERO_ERROR;
1426 what = "udat_applyPattern";
1427 log_verbose("Trying %s on a relative date..\n", what);
2ca993e8 1428 udat_applyPattern(icudf, FALSE,tzName,-1);
46f4442e
A
1429 subStatus = U_ILLEGAL_ARGUMENT_ERROR; /* what it should be, if this took an errorcode. */
1430 if(subStatus == expectStatus) {
1431 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1432 } else {
1433 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
2ca993e8 1434 }
46f4442e
A
1435 }
1436 {
51004dcb 1437 UChar erabuf[32];
46f4442e
A
1438 UErrorCode subStatus = U_ZERO_ERROR;
1439 what = "udat_getSymbols";
1440 log_verbose("Trying %s on a relative date..\n", what);
2ca993e8 1441 udat_getSymbols(icudf, UDAT_ERAS,0,erabuf,UPRV_LENGTHOF(erabuf), &subStatus);
729e4ab9
A
1442 if(subStatus == U_ZERO_ERROR) {
1443 log_verbose("Success: %s returned %s.\n", what, u_errorName(subStatus));
1444 } else {
1445 log_err("FAIL: didn't crash on %s, but got %s instead of U_ZERO_ERROR.\n", what, u_errorName(subStatus));
2ca993e8 1446 }
729e4ab9
A
1447 }
1448 {
1449 UErrorCode subStatus = U_ZERO_ERROR;
1450 UChar symbolValue = 0x0041;
1451 what = "udat_setSymbols";
1452 log_verbose("Trying %s on a relative date..\n", what);
1453 udat_setSymbols(icudf, UDAT_ERAS,0,&symbolValue,1, &subStatus); /* bogus values */
46f4442e
A
1454 if(subStatus == expectStatus) {
1455 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1456 } else {
1457 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
2ca993e8 1458 }
46f4442e
A
1459 }
1460 {
1461 UErrorCode subStatus = U_ZERO_ERROR;
1462 what = "udat_countSymbols";
1463 log_verbose("Trying %s on a relative date..\n", what);
2ca993e8 1464 udat_countSymbols(icudf, UDAT_ERAS);
46f4442e
A
1465 subStatus = U_ILLEGAL_ARGUMENT_ERROR; /* should have an errorcode. */
1466 if(subStatus == expectStatus) {
1467 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1468 } else {
1469 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
2ca993e8 1470 }
46f4442e 1471 }
2ca993e8 1472
46f4442e
A
1473 udat_close(icudf);
1474 } else {
729e4ab9 1475 log_data_err("FAIL: err calling udat_open() ->%s (Are you missing data?)\n", u_errorName(status));
46f4442e
A
1476 }
1477}
1478
4388f060
A
1479static const UChar skeleton_yMMMM[] = { 0x79,0x4D,0x4D,0x4D,0x4D,0 }; /* "yMMMM"; fr maps to "MMMM y", cs maps to "LLLL y" */
1480static const UChar july2008_frDefault[] = { 0x6A,0x75,0x69,0x6C,0x6C,0x65,0x74,0x20,0x32,0x30,0x30,0x38,0 }; /* "juillet 2008" */
1481static const UChar july2008_frTitle[] = { 0x4A,0x75,0x69,0x6C,0x6C,0x65,0x74,0x20,0x32,0x30,0x30,0x38,0 }; /* "Juillet 2008" sentence-begin, standalone */
1482static const UChar july2008_csDefault[] = { 0x10D,0x65,0x72,0x76,0x65,0x6E,0x65,0x63,0x20,0x32,0x30,0x30,0x38,0 }; /* "c(hacek)ervenec 2008" */
1483static 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 */
1484
1485typedef struct {
1486 const char * locale;
1487 const UChar * skeleton;
51004dcb 1488 UDisplayContext capitalizationContext;
4388f060
A
1489 const UChar * expectedFormat;
1490} TestContextItem;
1491
1492static const TestContextItem textContextItems[] = {
51004dcb 1493 { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_NONE, july2008_frDefault },
4388f060 1494#if !UCONFIG_NO_BREAK_ITERATION
51004dcb
A
1495 { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, july2008_frDefault },
1496 { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, july2008_frTitle },
1497 { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, july2008_frDefault },
1498 { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_STANDALONE, july2008_frTitle },
4388f060 1499#endif
51004dcb 1500 { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_NONE, july2008_csDefault },
4388f060 1501#if !UCONFIG_NO_BREAK_ITERATION
51004dcb
A
1502 { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, july2008_csDefault },
1503 { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, july2008_csTitle },
1504 { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, july2008_csTitle },
1505 { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_STANDALONE, july2008_csDefault },
4388f060 1506#endif
51004dcb 1507 { NULL, NULL, (UDisplayContext)0, NULL }
4388f060
A
1508};
1509
57a6839d
A
1510static const UChar today_enDefault[] = { 0x74,0x6F,0x64,0x61,0x79,0 }; /* "today" */
1511static const UChar today_enTitle[] = { 0x54,0x6F,0x64,0x61,0x79,0 }; /* "Today" sentence-begin, uiListOrMenu, standalone */
1512static const UChar yesterday_enDefault[] = { 0x79,0x65,0x73,0x74,0x65,0x72,0x64,0x61,0x79,0 }; /* "yesterday" */
1513static const UChar yesterday_enTitle[] = { 0x59,0x65,0x73,0x74,0x65,0x72,0x64,0x61,0x79,0 }; /* "Yesterday" sentence-begin, uiListOrMenu, standalone */
1514static const UChar today_nbDefault[] = { 0x69,0x20,0x64,0x61,0x67,0 }; /* "i dag" */
1515static const UChar today_nbTitle[] = { 0x49,0x20,0x64,0x61,0x67,0 }; /* "I dag" sentence-begin, standalone */
1516static const UChar yesterday_nbDefault[] = { 0x69,0x20,0x67,0xE5,0x72,0 };
1517static const UChar yesterday_nbTitle[] = { 0x49,0x20,0x67,0xE5,0x72,0 };
1518
1519typedef struct {
1520 const char * locale;
1521 UDisplayContext capitalizationContext;
1522 const UChar * expectedFormatToday;
1523 const UChar * expectedFormatYesterday;
1524} TestRelativeContextItem;
1525
1526static const TestRelativeContextItem textContextRelativeItems[] = {
1527 { "en", UDISPCTX_CAPITALIZATION_NONE, today_enDefault, yesterday_enDefault },
1528#if !UCONFIG_NO_BREAK_ITERATION
1529 { "en", UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, today_enDefault, yesterday_enDefault },
1530 { "en", UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, today_enTitle, yesterday_enTitle },
1531 { "en", UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, today_enTitle, yesterday_enTitle },
1532 { "en", UDISPCTX_CAPITALIZATION_FOR_STANDALONE, today_enTitle, yesterday_enTitle },
1533#endif
1534 { "nb", UDISPCTX_CAPITALIZATION_NONE, today_nbDefault, yesterday_nbDefault },
1535#if !UCONFIG_NO_BREAK_ITERATION
1536 { "nb", UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, today_nbDefault, yesterday_nbDefault },
1537 { "nb", UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, today_nbTitle, yesterday_nbTitle },
1538 { "nb", UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, today_nbDefault, yesterday_nbDefault },
1539 { "nb", UDISPCTX_CAPITALIZATION_FOR_STANDALONE, today_nbTitle, yesterday_nbTitle },
1540#endif
1541 { NULL, (UDisplayContext)0, NULL, NULL }
1542};
1543
a62d09fc
A
1544static const UChar january_esDefault[] = { 0x65,0x6E,0x65,0x72,0x6F,0 }; /* "enero" */
1545static const UChar january_esTitle[] = { 0x45,0x6E,0x65,0x72,0x6F,0 }; /* "Enero */
1546static const UChar monday_daDefault[] = { 0x6D,0x61,0x6E,0x64,0x61,0x67,0 }; /* "mandag" */
1547static const UChar monday_daTitle[] = { 0x4D,0x61,0x6E,0x64,0x61,0x67,0 }; /* "Mandag */
1548
1549typedef struct {
1550 const char * locale;
1551 UDateFormatSymbolType type;
1552 int32_t index;
1553 UDisplayContext capitalizationContext;
1554 const UChar * expectedFormat;
1555} TestSymbolContextItem;
1556
1557static const TestSymbolContextItem testContextSymbolItems[] = {
1558 { "es", UDAT_MONTHS, 0, UDISPCTX_CAPITALIZATION_NONE, january_esDefault },
1559#if !UCONFIG_NO_BREAK_ITERATION
1560 { "es", UDAT_MONTHS, 0, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, january_esDefault },
1561 { "es", UDAT_MONTHS, 0, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, january_esTitle },
1562 { "es", UDAT_MONTHS, 0, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, january_esTitle },
1563 { "es", UDAT_MONTHS, 0, UDISPCTX_CAPITALIZATION_FOR_STANDALONE, january_esTitle },
1564#endif
1565 { "da", UDAT_WEEKDAYS, 2, UDISPCTX_CAPITALIZATION_NONE, monday_daDefault },
1566#if !UCONFIG_NO_BREAK_ITERATION
1567 { "da", UDAT_WEEKDAYS, 2, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, monday_daDefault },
1568 { "da", UDAT_WEEKDAYS, 2, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, monday_daTitle },
1569 { "da", UDAT_WEEKDAYS, 2, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, monday_daDefault },
1570 { "da", UDAT_WEEKDAYS, 2, UDISPCTX_CAPITALIZATION_FOR_STANDALONE, monday_daDefault },
1571#endif
1572 { NULL, (UDateFormatSymbolType)0, 0, (UDisplayContext)0, NULL }
1573};
1574
57a6839d
A
1575static const UChar zoneGMT[] = { 0x47,0x4D,0x54,0 }; /* "GMT" */
1576static const UDate july022008 = 1215000000000.0;
4388f060
A
1577enum { kUbufMax = 64, kBbufMax = 3*kUbufMax };
1578
1579static void TestContext(void) {
57a6839d
A
1580 const TestContextItem* textContextItemPtr;
1581 const TestRelativeContextItem* textRelContextItemPtr;
a62d09fc
A
1582 const TestSymbolContextItem* testSymContextItemPtr;
1583
57a6839d 1584 for (textContextItemPtr = textContextItems; textContextItemPtr->locale != NULL; ++textContextItemPtr) {
4388f060 1585 UErrorCode status = U_ZERO_ERROR;
57a6839d
A
1586 UDateTimePatternGenerator* udtpg = udatpg_open(textContextItemPtr->locale, &status);
1587 if ( U_SUCCESS(status) ) {
1588 UChar ubuf[kUbufMax];
1589 int32_t len = udatpg_getBestPattern(udtpg, textContextItemPtr->skeleton, -1, ubuf, kUbufMax, &status);
1590 if ( U_SUCCESS(status) ) {
1591 UDateFormat* udfmt = udat_open(UDAT_PATTERN, UDAT_PATTERN, textContextItemPtr->locale, zoneGMT, -1, ubuf, len, &status);
1592 if ( U_SUCCESS(status) ) {
51004dcb 1593 udat_setContext(udfmt, textContextItemPtr->capitalizationContext, &status);
57a6839d 1594 if ( U_SUCCESS(status) ) {
51004dcb 1595 UDisplayContext getContext;
4388f060
A
1596 len = udat_format(udfmt, july022008, ubuf, kUbufMax, NULL, &status);
1597 if ( U_FAILURE(status) ) {
1598 log_err("FAIL: udat_format for locale %s, capitalizationContext %d, status %s\n",
1599 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, u_errorName(status) );
1600 status = U_ZERO_ERROR;
1601 } else if (u_strncmp(ubuf, textContextItemPtr->expectedFormat, kUbufMax) != 0) {
1602 char bbuf1[kBbufMax];
1603 char bbuf2[kBbufMax];
1604 log_err("FAIL: udat_format for locale %s, capitalizationContext %d, expected %s, got %s\n",
1605 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext,
1606 u_austrncpy(bbuf1,textContextItemPtr->expectedFormat,kUbufMax), u_austrncpy(bbuf2,ubuf,kUbufMax) );
1607 }
51004dcb 1608 getContext = udat_getContext(udfmt, UDISPCTX_TYPE_CAPITALIZATION, &status);
4388f060 1609 if ( U_FAILURE(status) ) {
51004dcb 1610 log_err("FAIL: udat_getContext for locale %s, capitalizationContext %d, status %s\n",
4388f060 1611 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, u_errorName(status) );
51004dcb
A
1612 } else if (getContext != textContextItemPtr->capitalizationContext) {
1613 log_err("FAIL: udat_getContext for locale %s, capitalizationContext %d, got context %d\n",
1614 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, (int)getContext );
4388f060 1615 }
57a6839d
A
1616 } else {
1617 log_err("FAIL: udat_setContext for locale %s, capitalizationContext %d, status %s\n",
1618 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, u_errorName(status) );
4388f060 1619 }
57a6839d
A
1620 udat_close(udfmt);
1621 } else {
1622 log_data_err("FAIL: udat_open for locale %s, status %s\n", textContextItemPtr->locale, u_errorName(status) );
4388f060 1623 }
57a6839d
A
1624 } else {
1625 log_err("FAIL: udatpg_getBestPattern for locale %s, status %s\n", textContextItemPtr->locale, u_errorName(status) );
4388f060 1626 }
57a6839d
A
1627 udatpg_close(udtpg);
1628 } else {
1629 log_data_err("FAIL: udatpg_open for locale %s, status %s\n", textContextItemPtr->locale, u_errorName(status) );
1630 }
1631 }
1632 for (textRelContextItemPtr = textContextRelativeItems; textRelContextItemPtr->locale != NULL; ++textRelContextItemPtr) {
1633 UErrorCode status = U_ZERO_ERROR;
1634 UCalendar* ucal = ucal_open(zoneGMT, -1, "root", UCAL_GREGORIAN, &status);
1635 if ( U_SUCCESS(status) ) {
1636 UDateFormat* udfmt = udat_open(UDAT_NONE, UDAT_LONG_RELATIVE, textRelContextItemPtr->locale, zoneGMT, -1, NULL, 0, &status);
1637 if ( U_SUCCESS(status) ) {
1638 udat_setContext(udfmt, textRelContextItemPtr->capitalizationContext, &status);
1639 if ( U_SUCCESS(status) ) {
1640 UDate yesterday, today = ucal_getNow();
1641 UChar ubuf[kUbufMax];
1642 char bbuf1[kBbufMax];
1643 char bbuf2[kBbufMax];
1644 int32_t len = udat_format(udfmt, today, ubuf, kUbufMax, NULL, &status);
1645 (void)len;
1646 if ( U_FAILURE(status) ) {
1647 log_err("FAIL: udat_format today for locale %s, capitalizationContext %d, status %s\n",
1648 textRelContextItemPtr->locale, (int)textRelContextItemPtr->capitalizationContext, u_errorName(status) );
1649 } else if (u_strncmp(ubuf, textRelContextItemPtr->expectedFormatToday, kUbufMax) != 0) {
1650 log_err("FAIL: udat_format today for locale %s, capitalizationContext %d, expected %s, got %s\n",
1651 textRelContextItemPtr->locale, (int)textRelContextItemPtr->capitalizationContext,
1652 u_austrncpy(bbuf1,textRelContextItemPtr->expectedFormatToday,kUbufMax), u_austrncpy(bbuf2,ubuf,kUbufMax) );
1653 }
1654 status = U_ZERO_ERROR;
1655 ucal_setMillis(ucal, today, &status);
1656 ucal_add(ucal, UCAL_DATE, -1, &status);
1657 yesterday = ucal_getMillis(ucal, &status);
1658 if ( U_SUCCESS(status) ) {
1659 len = udat_format(udfmt, yesterday, ubuf, kUbufMax, NULL, &status);
1660 if ( U_FAILURE(status) ) {
1661 log_err("FAIL: udat_format yesterday for locale %s, capitalizationContext %d, status %s\n",
1662 textRelContextItemPtr->locale, (int)textRelContextItemPtr->capitalizationContext, u_errorName(status) );
1663 } else if (u_strncmp(ubuf, textRelContextItemPtr->expectedFormatYesterday, kUbufMax) != 0) {
1664 log_err("FAIL: udat_format yesterday for locale %s, capitalizationContext %d, expected %s, got %s\n",
1665 textRelContextItemPtr->locale, (int)textRelContextItemPtr->capitalizationContext,
1666 u_austrncpy(bbuf1,textRelContextItemPtr->expectedFormatYesterday,kUbufMax), u_austrncpy(bbuf2,ubuf,kUbufMax) );
1667 }
1668 }
1669 } else {
1670 log_err("FAIL: udat_setContext relative for locale %s, capitalizationContext %d, status %s\n",
1671 textRelContextItemPtr->locale, (int)textRelContextItemPtr->capitalizationContext, u_errorName(status) );
1672 }
1673 udat_close(udfmt);
1674 } else {
1675 log_data_err("FAIL: udat_open relative for locale %s, status %s\n", textRelContextItemPtr->locale, u_errorName(status) );
1676 }
1677 ucal_close(ucal);
1678 } else {
1679 log_data_err("FAIL: ucal_open for locale root, status %s\n", u_errorName(status) );
4388f060
A
1680 }
1681 }
a62d09fc
A
1682
1683 for (testSymContextItemPtr = testContextSymbolItems; testSymContextItemPtr->locale != NULL; ++testSymContextItemPtr) {
1684 UErrorCode status = U_ZERO_ERROR;
1685 UDateFormat* udfmt = udat_open(UDAT_MEDIUM, UDAT_FULL, testSymContextItemPtr->locale, zoneGMT, -1, NULL, 0, &status);
1686 if ( U_SUCCESS(status) ) {
1687 udat_setContext(udfmt, testSymContextItemPtr->capitalizationContext, &status);
1688 if ( U_SUCCESS(status) ) {
1689 UChar ubuf[kUbufMax];
1690 int32_t len = udat_getSymbols(udfmt, testSymContextItemPtr->type, testSymContextItemPtr->index, ubuf, kUbufMax, &status);
1691 if ( U_FAILURE(status) ) {
1692 log_err("FAIL: udat_getSymbols for locale %s, capitalizationContext %d, status %s\n",
1693 testSymContextItemPtr->locale, (int)testSymContextItemPtr->capitalizationContext, u_errorName(status) );
1694 } else if (u_strncmp(ubuf, testSymContextItemPtr->expectedFormat, kUbufMax) != 0) {
1695 char bbuf1[kBbufMax];
1696 char bbuf2[kBbufMax];
1697 log_err("FAIL: udat_getSymbols for locale %s, capitalizationContext %d, expected %s, got %s\n",
1698 testSymContextItemPtr->locale, (int)testSymContextItemPtr->capitalizationContext,
1699 u_austrncpy(bbuf1,testSymContextItemPtr->expectedFormat,kUbufMax), u_austrncpy(bbuf2,ubuf,kUbufMax) );
1700 }
1701 } else {
1702 log_err("FAIL: udat_setContext std for locale %s, capitalizationContext %d, status %s\n",
1703 testSymContextItemPtr->locale, (int)testSymContextItemPtr->capitalizationContext, u_errorName(status) );
1704 }
1705 udat_close(udfmt);
1706 } else {
1707 log_data_err("FAIL: udat_open std for locale %s, status %s\n", testSymContextItemPtr->locale, u_errorName(status) );
1708 }
1709 }
4388f060
A
1710}
1711
b331163b 1712
2ca993e8 1713// overrideNumberFormat[i][0] is to tell which field to set,
b331163b 1714// overrideNumberFormat[i][1] is the expected result
2ca993e8 1715static const char * overrideNumberFormat[][2] = {
b331163b
A
1716 {"", "\\u521D\\u4E03 \\u521D\\u4E8C"},
1717 {"d", "07 \\u521D\\u4E8C"},
1718 {"do", "07 \\u521D\\u4E8C"},
1719 {"Md", "\\u521D\\u4E03 \\u521D\\u4E8C"},
1720 {"MdMMd", "\\u521D\\u4E03 \\u521D\\u4E8C"},
1721 {"mixed", "\\u521D\\u4E03 \\u521D\\u4E8C"}
1722};
1723
1724static void TestOverrideNumberFormat(void) {
1725 UErrorCode status = U_ZERO_ERROR;
1726 UChar pattern[50];
1727 UChar expected[50];
1728 UChar fields[50];
1729 char bbuf1[kBbufMax];
1730 char bbuf2[kBbufMax];
1731 const char* localeString = "zh@numbers=hanidays";
1732 UDateFormat* fmt;
1733 const UNumberFormat* getter_result;
1734 int32_t i;
1735
1736 u_uastrcpy(fields, "d");
1737 u_uastrcpy(pattern,"MM d");
1738
1739 fmt=udat_open(UDAT_PATTERN, UDAT_PATTERN, "en_US", zoneGMT, -1, pattern, u_strlen(pattern), &status);
1740 if (!assertSuccess("udat_open()", &status)) {
1741 return;
1742 }
1743
1744 // loop 5 times to check getter/setter
1745 for (i = 0; i < 5; i++){
3d1f044b 1746 status = U_ZERO_ERROR;
b331163b
A
1747 UNumberFormat* overrideFmt;
1748 overrideFmt = unum_open(UNUM_DEFAULT, NULL, 0, localeString, NULL, &status);
1749 assertSuccess("unum_open()", &status);
1750 udat_adoptNumberFormatForFields(fmt, fields, overrideFmt, &status);
1751 overrideFmt = NULL; // no longer valid
1752 assertSuccess("udat_setNumberFormatForField()", &status);
1753
f3c0d7a5 1754 getter_result = udat_getNumberFormatForField(fmt, 0x0064 /*'d'*/);
b331163b
A
1755 if(getter_result == NULL) {
1756 log_err("FAIL: udat_getNumberFormatForField did not return a valid pointer\n");
1757 }
1758 }
1759 {
3d1f044b 1760 status = U_ZERO_ERROR;
b331163b
A
1761 UNumberFormat* overrideFmt;
1762 overrideFmt = unum_open(UNUM_DEFAULT, NULL, 0, localeString, NULL, &status);
1763 assertSuccess("unum_open()", &status);
3d1f044b
A
1764 if (U_SUCCESS(status)) {
1765 udat_setNumberFormat(fmt, overrideFmt); // test the same override NF will not crash
1766 }
b331163b
A
1767 unum_close(overrideFmt);
1768 }
1769 udat_close(fmt);
2ca993e8 1770
b331163b 1771 for (i=0; i<UPRV_LENGTHOF(overrideNumberFormat); i++){
3d1f044b 1772 status = U_ZERO_ERROR;
b331163b
A
1773 UChar ubuf[kUbufMax];
1774 UDateFormat* fmt2;
1775 UNumberFormat* overrideFmt2;
1776
1777 fmt2 =udat_open(UDAT_PATTERN, UDAT_PATTERN,"en_US", zoneGMT, -1, pattern, u_strlen(pattern), &status);
1778 assertSuccess("udat_open() with en_US", &status);
1779
1780 overrideFmt2 = unum_open(UNUM_DEFAULT, NULL, 0, localeString, NULL, &status);
1781 assertSuccess("unum_open() in loop", &status);
1782
3d1f044b
A
1783 if (U_FAILURE(status)) {
1784 continue;
1785 }
1786
b331163b
A
1787 u_uastrcpy(fields, overrideNumberFormat[i][0]);
1788 u_unescape(overrideNumberFormat[i][1], expected, UPRV_LENGTHOF(expected));
1789
1790 if ( strcmp(overrideNumberFormat[i][0], "") == 0 ) { // use the one w/o field
1791 udat_adoptNumberFormat(fmt2, overrideFmt2);
1792 } else if ( strcmp(overrideNumberFormat[i][0], "mixed") == 0 ) { // set 1 field at first but then full override, both(M & d) should be override
1793 const char* singleLocale = "en@numbers=hebr";
1794 UNumberFormat* singleOverrideFmt;
1795 u_uastrcpy(fields, "d");
1796
1797 singleOverrideFmt = unum_open(UNUM_DEFAULT, NULL, 0, singleLocale, NULL, &status);
1798 assertSuccess("unum_open() in mixed", &status);
1799
1800 udat_adoptNumberFormatForFields(fmt2, fields, singleOverrideFmt, &status);
1801 assertSuccess("udat_setNumberFormatForField() in mixed", &status);
1802
1803 udat_adoptNumberFormat(fmt2, overrideFmt2);
1804 } else if ( strcmp(overrideNumberFormat[i][0], "do") == 0 ) { // o is an invalid field
1805 udat_adoptNumberFormatForFields(fmt2, fields, overrideFmt2, &status);
1806 if(status == U_INVALID_FORMAT_ERROR) {
1807 udat_close(fmt2);
1808 status = U_ZERO_ERROR;
1809 continue;
1810 }
1811 } else {
1812 udat_adoptNumberFormatForFields(fmt2, fields, overrideFmt2, &status);
1813 assertSuccess("udat_setNumberFormatForField() in loop", &status);
1814 }
1815
1816 udat_format(fmt2, july022008, ubuf, kUbufMax, NULL, &status);
1817 assertSuccess("udat_format() july022008", &status);
1818
2ca993e8 1819 if (u_strncmp(ubuf, expected, kUbufMax) != 0)
b331163b
A
1820 log_err("fail: udat_format for locale, expected %s, got %s\n",
1821 u_austrncpy(bbuf1,expected,kUbufMax), u_austrncpy(bbuf2,ubuf,kUbufMax) );
1822
1823 udat_close(fmt2);
1824 }
1825}
1826
1827/*
1828 * Ticket #11523
1829 * udat_parse and udat_parseCalendar should have the same error code when given the same invalid input.
1830 */
1831static void TestParseErrorReturnValue(void) {
1832 UErrorCode status = U_ZERO_ERROR;
1833 UErrorCode expectStatus = U_PARSE_ERROR;
1834 UDateFormat* df;
1835 UCalendar* cal;
1836
1837 df = udat_open(UDAT_DEFAULT, UDAT_DEFAULT, NULL, NULL, -1, NULL, -1, &status);
1838 if (!assertSuccessCheck("udat_open()", &status, TRUE)) {
1839 return;
1840 }
1841
1842 cal = ucal_open(NULL, 0, "en_US", UCAL_GREGORIAN, &status);
1843 if (!assertSuccess("ucal_open()", &status)) {
1844 return;
1845 }
1846
1847 udat_parse(df, NULL, -1, NULL, &status);
1848 if (status != expectStatus) {
1849 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));
1850 }
1851
1852 status = U_ZERO_ERROR;
1853 udat_parseCalendar(df, cal, NULL, -1, NULL, &status);
1854 if (status != expectStatus) {
1855 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));
1856 }
1857
1858 ucal_close(cal);
1859 udat_close(df);
1860}
1861
1862/*
1863 * Ticket #11553
1864 * Test new udat_formatForFields, udat_formatCalendarForFields (and UFieldPositionIterator)
1865 */
1866static const char localeForFields[] = "en_US";
1867/* zoneGMT[]defined above */
1868static const UDate date2015Feb25 = 1424841000000.0; /* Wednesday, February 25, 2015 at 5:10:00 AM GMT */
f3c0d7a5 1869static const UChar patNoFields[] = { 0x0027, 0x0078, 0x0078, 0x0078, 0x0027, 0 }; /* "'xxx'" */
b331163b
A
1870
1871typedef struct {
1872 int32_t field;
1873 int32_t beginPos;
1874 int32_t endPos;
1875} FieldsData;
1876static const FieldsData expectedFields[] = {
1877 { UDAT_DAY_OF_WEEK_FIELD /* 9*/, 0, 9 },
1878 { UDAT_MONTH_FIELD /* 2*/, 11, 19 },
1879 { UDAT_DATE_FIELD /* 3*/, 20, 22 },
1880 { UDAT_YEAR_FIELD /* 1*/, 24, 28 },
1881 { UDAT_HOUR1_FIELD /*15*/, 32, 33 },
2ca993e8
A
1882#if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
1883 { UDAT_TIME_SEPARATOR_FIELD /*35*/, 33, 34 },
1884#endif
b331163b 1885 { UDAT_MINUTE_FIELD /* 6*/, 34, 36 },
2ca993e8
A
1886#if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
1887 { UDAT_TIME_SEPARATOR_FIELD /*35*/, 36, 37 },
1888#endif
b331163b
A
1889 { UDAT_SECOND_FIELD /* 7*/, 37, 39 },
1890 { UDAT_AM_PM_FIELD /*14*/, 40, 42 },
1891 { UDAT_TIMEZONE_FIELD /*17*/, 43, 46 },
1892 { -1, -1, -1 },
1893};
1894
1895enum {kUBufFieldsLen = 128, kBBufFieldsLen = 256 };
1896
1897static void TestFormatForFields(void) {
1898 UErrorCode status = U_ZERO_ERROR;
1899 UFieldPositionIterator* fpositer = ufieldpositer_open(&status);
1900 if ( U_FAILURE(status) ) {
1901 log_err("ufieldpositer_open fails, status %s\n", u_errorName(status));
1902 } else {
1903 UDateFormat* udfmt = udat_open(UDAT_LONG, UDAT_FULL, localeForFields, zoneGMT, -1, NULL, 0, &status);
1904 UCalendar* ucal = ucal_open(zoneGMT, -1, localeForFields, UCAL_DEFAULT, &status);
1905 if ( U_FAILURE(status) ) {
1906 log_data_err("udat_open or ucal_open fails for locale %s, status %s (Are you missing data?)\n", localeForFields, u_errorName(status));
1907 } else {
1908 int32_t ulen, field, beginPos, endPos;
1909 UChar ubuf[kUBufFieldsLen];
1910 const FieldsData * fptr;
2ca993e8 1911
b331163b
A
1912 status = U_ZERO_ERROR;
1913 ulen = udat_formatForFields(udfmt, date2015Feb25, ubuf, kUBufFieldsLen, fpositer, &status);
1914 if ( U_FAILURE(status) ) {
1915 log_err("udat_formatForFields fails, status %s\n", u_errorName(status));
1916 } else {
1917 for (fptr = expectedFields; ; fptr++) {
1918 field = ufieldpositer_next(fpositer, &beginPos, &endPos);
1919 if (field != fptr->field || (field >= 0 && (beginPos != fptr->beginPos || endPos != fptr->endPos))) {
1920 if (fptr->field >= 0) {
1921 log_err("udat_formatForFields as \"%s\"; expect field %d range %d-%d, get field %d range %d-%d\n",
1922 aescstrdup(ubuf, ulen), fptr->field, fptr->beginPos, fptr->endPos, field, beginPos, endPos);
1923 } else {
1924 log_err("udat_formatForFields as \"%s\"; expect field < 0, get field %d range %d-%d\n",
1925 aescstrdup(ubuf, ulen), field, beginPos, endPos);
1926 }
1927 break;
1928 }
1929 if (field < 0) {
1930 break;
1931 }
1932 }
1933 }
2ca993e8 1934
b331163b
A
1935 ucal_setMillis(ucal, date2015Feb25, &status);
1936 status = U_ZERO_ERROR;
1937 ulen = udat_formatCalendarForFields(udfmt, ucal, ubuf, kUBufFieldsLen, fpositer, &status);
1938 if ( U_FAILURE(status) ) {
1939 log_err("udat_formatCalendarForFields fails, status %s\n", u_errorName(status));
1940 } else {
1941 for (fptr = expectedFields; ; fptr++) {
1942 field = ufieldpositer_next(fpositer, &beginPos, &endPos);
1943 if (field != fptr->field || (field >= 0 && (beginPos != fptr->beginPos || endPos != fptr->endPos))) {
1944 if (fptr->field >= 0) {
1945 log_err("udat_formatFudat_formatCalendarForFieldsorFields as \"%s\"; expect field %d range %d-%d, get field %d range %d-%d\n",
1946 aescstrdup(ubuf, ulen), fptr->field, fptr->beginPos, fptr->endPos, field, beginPos, endPos);
1947 } else {
1948 log_err("udat_formatCalendarForFields as \"%s\"; expect field < 0, get field %d range %d-%d\n",
1949 aescstrdup(ubuf, ulen), field, beginPos, endPos);
1950 }
1951 break;
1952 }
1953 if (field < 0) {
1954 break;
1955 }
1956 }
1957 }
1958
f3c0d7a5
A
1959 udat_applyPattern(udfmt, FALSE, patNoFields, -1);
1960 status = U_ZERO_ERROR;
1961 ulen = udat_formatForFields(udfmt, date2015Feb25, ubuf, kUBufFieldsLen, fpositer, &status);
1962 if ( U_FAILURE(status) ) {
1963 log_err("udat_formatForFields with no-field pattern fails, status %s\n", u_errorName(status));
1964 } else {
1965 field = ufieldpositer_next(fpositer, &beginPos, &endPos);
1966 if (field >= 0) {
1967 log_err("udat_formatForFields with no-field pattern as \"%s\"; expect field < 0, get field %d range %d-%d\n",
1968 aescstrdup(ubuf, ulen), field, beginPos, endPos);
1969 }
1970 }
1971
b331163b
A
1972 ucal_close(ucal);
1973 udat_close(udfmt);
1974 }
1975 ufieldpositer_close(fpositer);
1976 }
1977}
1978
1546d4af
A
1979static void TestForceGannenNumbering(void) {
1980 UErrorCode status;
1981 const char* locID = "ja_JP@calendar=japanese";
1982 UDate refDate = 600336000000.0; // 1989 Jan 9 Monday = Heisei 1
1983 const UChar* testSkeleton = u"yMMMd";
1984
1985 // Test Gannen year forcing
1986 status = U_ZERO_ERROR;
1987 UDateTimePatternGenerator* dtpgen = udatpg_open(locID, &status);
1988 if (U_FAILURE(status)) {
1989 log_data_err("Fail in udatpg_open locale %s: %s", locID, u_errorName(status));
1990 } else {
1991 UChar pattern[kUbufMax];
1992 int32_t patlen = udatpg_getBestPattern(dtpgen, testSkeleton, -1, pattern, kUbufMax, &status);
1993 if (U_FAILURE(status)) {
1994 log_data_err("Fail in udatpg_getBestPattern locale %s: %s", locID, u_errorName(status));
1995 } else {
1996 UDateFormat *testFmt = udat_open(UDAT_PATTERN, UDAT_PATTERN, locID, NULL, 0, pattern, patlen, &status);
1997 if (U_FAILURE(status)) {
1998 log_data_err("Fail in udat_open locale %s: %s", locID, u_errorName(status));
1999 } else {
2000 UChar testString[kUbufMax];
2001 int32_t testStrLen = udat_format(testFmt, refDate, testString, kUbufMax, NULL, &status);
2002 if (U_FAILURE(status)) {
2003 log_err("Fail in udat_format locale %s: %s", locID, u_errorName(status));
2004 } else if (testStrLen < 3 || testString[2] != 0x5143) {
2005 char bbuf[kBbufMax];
3d1f044b
A
2006 u_austrncpy(bbuf, testString, testStrLen);
2007 log_err("Formatting year 1 as Gannen, got%s but expected 3rd char to be 0x5143", bbuf);
1546d4af
A
2008 }
2009 udat_close(testFmt);
2010 }
2011 }
2012 udatpg_close(dtpgen);
2013 }
2014}
2015
2ca993e8
A
2016/* defined above
2017static const UChar zoneGMT[] = { 0x47,0x4D,0x54,0 }; // "GMT"
2018static const UDate date2015Feb25 = 1424841000000.0; // Wednesday, February 25, 2015 at 5:10:00 AM GMT
2019*/
2020
2021typedef struct {
2022 const char * locale;
2023 UDateFormatStyle dateStyle;
2024 UDateFormatStyle timeStyle;
2025 const char * expect; /* for zoneGMT and date2015Feb25 */
2026} StandardPatternItem;
2027
2028static const StandardPatternItem stdPatternItems[] = {
a62d09fc 2029 { "en_JP", UDAT_MEDIUM, UDAT_SHORT, "Feb 25, 2015 5:10" },
9f1b1155
A
2030 { "en_CN", UDAT_MEDIUM, UDAT_SHORT, "Feb 25, 2015 at 5:10 AM" },
2031 { "en_TW", UDAT_MEDIUM, UDAT_SHORT, "Feb 25, 2015 at 5:10 AM" },
3d1f044b
A
2032 { "en_KR", UDAT_MEDIUM, UDAT_SHORT, "Feb 25, 2015 5:10 AM" },
2033 // Add tests for Apple <rdar://problem/51014042>; currently no specific locales for these
2034 { "en_AZ", UDAT_MEDIUM, UDAT_SHORT, "Feb 25, 2015 at 05:10" }, // en uses h, AZ Azerbaijanvpref cycle H
2035 { "fr_US", UDAT_NONE, UDAT_SHORT, "5:10 AM" }, // fr uses H, US pref cycle h
2036 { "rkt", UDAT_NONE, UDAT_SHORT, "5:10 AM" }, // rkt (no locale) => rkt_Beng_BD, BD pref cycle h unlike root H
2037 // Add tests for Apple <rdar://problem/47494884>
2038 { "ur_PK", UDAT_MEDIUM, UDAT_SHORT, "25 \\u0641\\u0631\\u0648\\u060C 2015 5:10 \\u0642.\\u062F." },
2039 { "ur_IN", UDAT_MEDIUM, UDAT_SHORT, "\\u06F2\\u06F5 \\u0641\\u0631\\u0648\\u060C \\u06F2\\u06F0\\u06F1\\u06F5 \\u06F5:\\u06F1\\u06F0 \\u0642.\\u062F." },
2040 { "ur_Arab", UDAT_MEDIUM, UDAT_SHORT, "25 \\u0641\\u0631\\u0648\\u060C 2015 5:10 \\u0642.\\u062F." },
2041 { "ur_Aran", UDAT_MEDIUM, UDAT_SHORT, "25 \\u0641\\u0631\\u0648\\u060C 2015 5:10 \\u0642.\\u062F." },
2042 { "ur_Arab_PK", UDAT_MEDIUM, UDAT_SHORT, "25 \\u0641\\u0631\\u0648\\u060C 2015 5:10 \\u0642.\\u062F." },
2043 { "ur_Aran_PK", UDAT_MEDIUM, UDAT_SHORT, "25 \\u0641\\u0631\\u0648\\u060C 2015 5:10 \\u0642.\\u062F." },
2044 { "ur_Arab_IN", UDAT_MEDIUM, UDAT_SHORT, "\\u06F2\\u06F5 \\u0641\\u0631\\u0648\\u060C \\u06F2\\u06F0\\u06F1\\u06F5 \\u06F5:\\u06F1\\u06F0 \\u0642.\\u062F." },
2045 { "ur_Aran_IN", UDAT_MEDIUM, UDAT_SHORT, "\\u06F2\\u06F5 \\u0641\\u0631\\u0648\\u060C \\u06F2\\u06F0\\u06F1\\u06F5 \\u06F5:\\u06F1\\u06F0 \\u0642.\\u062F." },
2ca993e8
A
2046 { NULL, (UDateFormatStyle)0, (UDateFormatStyle)0, NULL } /* terminator */
2047};
2048
2049enum { kUbufStdMax = 64, kBbufStdMax = 3*kUbufStdMax };
2050
2051static void TestStandardPatterns(void) {
2052 const StandardPatternItem* itemPtr;
2053 for (itemPtr = stdPatternItems; itemPtr->locale != NULL; itemPtr++) {
2054 UErrorCode status = U_ZERO_ERROR;
2055 UDateFormat* udfmt = udat_open(itemPtr->timeStyle, itemPtr->dateStyle, itemPtr->locale, zoneGMT, -1, NULL, 0, &status);
2056 if ( U_FAILURE(status) ) {
2057 log_err("udat_open(%d, %d, \"%s\",...) fails, status %s\n",
2058 (int)itemPtr->timeStyle, (int)itemPtr->dateStyle, itemPtr->locale, u_errorName(status));
2059 } else {
2060 UChar uget[kUbufStdMax];
2061 int32_t ugetlen = udat_format(udfmt, date2015Feb25, uget, kUbufStdMax, NULL, &status);
2062 if ( U_FAILURE(status) ) {
2063 log_err("udat_format for (%d, %d, \"%s\",...) fails, status %s\n",
2064 (int)itemPtr->timeStyle, (int)itemPtr->dateStyle, itemPtr->locale, u_errorName(status));
2065 } else {
2066 UChar uexpect[kUbufStdMax];
2067 int32_t uexpectlen = u_unescape(itemPtr->expect, uexpect, kUbufStdMax);
2068 if (ugetlen != uexpectlen || u_strncmp(uget, uexpect, uexpectlen) != 0) {
2069 char bexpect[kBbufStdMax];
2070 char bget[kBbufStdMax];
2071 u_austrcpy(bexpect, uexpect);
2072 u_austrcpy(bget, uget);
2073 log_err("udat_format for (%d, %d, \"%s\",...):\n expect %s\n get %s\n",
2074 (int)itemPtr->timeStyle, (int)itemPtr->dateStyle, itemPtr->locale, bexpect, bget);
2075 }
2076 }
2077 udat_close(udfmt);
2078 }
2079 }
2080}
2081
b331163b
A
2082/* defined above
2083static const UChar zoneGMT[] = { 0x47,0x4D,0x54,0 }; // "GMT"
2084static const UDate date2015Feb25 = 1424841000000.0; // Wednesday, February 25, 2015 at 5:10:00 AM GMT
2085*/
2086static const UChar patternHmm[] = { 0x48,0x3A,0x6D,0x6D,0 }; /* "H:mm" */
2087static const UChar formattedHmm[] = { 0x35,0x3A,0x31,0x30,0 }; /* "5:10" */
2088
2089enum { kUBufOverrideSepMax = 32, kBBufOverrideSepMax = 64 };
2090
2091static void TestApplyPatnOverridesTimeSep(void) {
2092 UErrorCode status;
2093 UDateFormat* udfmt;
2094 const char *locale = "da"; /* uses period for time separator */
2095 UChar ubuf[kUBufOverrideSepMax];
2096 int32_t ulen;
2097
2098 status = U_ZERO_ERROR;
2099 udfmt = udat_open(UDAT_PATTERN, UDAT_PATTERN, locale, zoneGMT, -1, patternHmm, -1, &status);
2100 if ( U_FAILURE(status) ) {
2101 log_err("udat_open(UDAT_PATTERN, UDAT_PATTERN, \"%s\",...) fails, status %s\n", locale, u_errorName(status));
2102 } else {
2103 ulen = udat_format(udfmt, date2015Feb25, ubuf, kUBufOverrideSepMax, NULL, &status);
2104 if ( U_FAILURE(status) ) {
2105 log_err("udat_format fails for UDAT_PATTERN \"%s\", status %s\n", locale, u_errorName(status));
2106 } else if (u_strcmp(ubuf, formattedHmm) != 0) {
2107 char bbuf[kBBufOverrideSepMax];
2108 u_strToUTF8(bbuf, kBBufOverrideSepMax, NULL, ubuf, ulen, &status);
2109 log_err("udat_format fails for UDAT_PATTERN \"%s\", expected 5:10, got %s\n", locale, bbuf);
2110 }
2111 udat_close(udfmt);
2112 }
2113
2114 status = U_ZERO_ERROR;
2115 udfmt = udat_open(UDAT_SHORT, UDAT_NONE, locale, zoneGMT, -1, NULL, 0, &status);
2116 if ( U_FAILURE(status) ) {
2117 log_err("udat_open(UDAT_SHORT, UDAT_NONE, \"%s\",...) fails, status %s\n", locale, u_errorName(status));
2118 } else {
2119 udat_applyPattern(udfmt, FALSE, patternHmm, -1);
2120 ulen = udat_format(udfmt, date2015Feb25, ubuf, kUBufOverrideSepMax, NULL, &status);
2121 if ( U_FAILURE(status) ) {
2122 log_err("udat_format fails for UDAT_SHORT \"%s\" + applyPattern, status %s\n", locale, u_errorName(status));
2123 } else if (u_strcmp(ubuf, formattedHmm) != 0) {
2124 char bbuf[kBBufOverrideSepMax];
2125 u_strToUTF8(bbuf, kBBufOverrideSepMax, NULL, ubuf, ulen, &status);
2126 log_err("udat_format fails for UDAT_SHORT \"%s\" + applyPattern, expected 5:10, got %s\n", locale, bbuf);
2127 }
2128 udat_close(udfmt);
2129 }
2130
2131}
2132
2ca993e8
A
2133#define UDATE_SECOND (1000.0)
2134#define UDATE_MINUTE (60.0*UDATE_SECOND)
2135#define UDATE_HOUR (60.0*UDATE_MINUTE)
2136
2137static const double dayOffsets[] = {
2138 0.0, /* 00:00:00 */
2139 UDATE_SECOND, /* 00:00:01 */
2140 UDATE_MINUTE, /* 00:01:00 */
2141 UDATE_HOUR, /* 01:00:00 */
2142 11.0*UDATE_HOUR + 59.0*UDATE_MINUTE, /* 11:59:00 */
2143 12.0*UDATE_HOUR, /* 12:00:00 */
2144 12.0*UDATE_HOUR + UDATE_SECOND, /* 12:00:01 */
2145 12.0*UDATE_HOUR + UDATE_MINUTE, /* 12:01:00 */
2146 13.0*UDATE_HOUR, /* 13:00:00 */
2147 23.0*UDATE_HOUR + 59.0*UDATE_MINUTE, /* 23:59:00 */
2148};
2149enum { kNumDayOffsets = UPRV_LENGTHOF(dayOffsets) };
2150
2151static const char* ja12HrFmt_hm[kNumDayOffsets] = { /* aK:mm */
2152 "\\u5348\\u524D0:00", /* "午前0:00" */
2153 "\\u5348\\u524D0:00",
2154 "\\u5348\\u524D0:01",
2155 "\\u5348\\u524D1:00",
2156 "\\u5348\\u524D11:59",
2157 "\\u5348\\u5F8C0:00", /* "午後0:00" */
2158 "\\u5348\\u5F8C0:00",
2159 "\\u5348\\u5F8C0:01", /* "午後0:01" */
2160 "\\u5348\\u5F8C1:00",
2161 "\\u5348\\u5F8C11:59",
2162};
2163
2164static const char* ja12HrFmt_h[kNumDayOffsets] = { /* aK時 */
2165 "\\u5348\\u524D0\\u6642", /* "午前0時" */
2166 "\\u5348\\u524D0\\u6642",
2167 "\\u5348\\u524D0\\u6642",
2168 "\\u5348\\u524D1\\u6642",
2169 "\\u5348\\u524D11\\u6642",
2170 "\\u5348\\u5F8C0\\u6642", /* "午後0時" */
2171 "\\u5348\\u5F8C0\\u6642",
2172 "\\u5348\\u5F8C0\\u6642", /* "午後0時" */
2173 "\\u5348\\u5F8C1\\u6642",
2174 "\\u5348\\u5F8C11\\u6642",
2175};
2176typedef struct {
2177 const char* locale;
2178 const char* skeleton;
2179 const char ** expected;
2180} Test12HrFmtItem;
2181
2182static const Test12HrFmtItem test12HrFmtItems[] = {
2183 { "ja", "hm", ja12HrFmt_hm },
2184 { "ja", "h", ja12HrFmt_h },
2185 { NULL, NULL, NULL } /* terminator */
2186};
2187
2188enum { kUBufMax = 128, };
2189static void Test12HrFormats(void) {
2190 const Test12HrFmtItem* itemPtr;
2191 for (itemPtr = test12HrFmtItems; itemPtr->locale != NULL; itemPtr++) {
2192 UErrorCode status = U_ZERO_ERROR;
2193 UCalendar* ucal = ucal_open(NULL, 0, itemPtr->locale, UCAL_DEFAULT, &status);
2194 if ( U_FAILURE(status) ) {
2195 log_data_err("ucal_open fails for locale %s: status %s (Are you missing data?)\n", itemPtr->locale, u_errorName(status));
2196 } else {
2197 ucal_clear(ucal);
2198 ucal_setDateTime(ucal, 2016, UCAL_JANUARY, 1, 0, 0, 0, &status);
2199 UDate baseDate = ucal_getMillis(ucal, &status);
2200 if ( U_FAILURE(status) ) {
2201 log_err("ucal_setDateTime or ucal_getMillis fails for locale %s: status %s\n", itemPtr->locale, u_errorName(status));
2202 } else {
2203 UDateTimePatternGenerator* udatpg = udatpg_open(itemPtr->locale, &status);
2204 if ( U_FAILURE(status) ) {
2205 log_data_err("udatpg_open fails for locale %s: status %s (Are you missing data?)\n", itemPtr->locale, u_errorName(status));
2206 } else {
2207 UChar ubuf1[kUbufMax], ubuf2[kUbufMax];
2208 int32_t ulen1 = u_unescape(itemPtr->skeleton, ubuf1, kUbufMax);
2209 int32_t ulen2 = udatpg_getBestPattern(udatpg, ubuf1, ulen1, ubuf2, kUbufMax, &status);
2210 if ( U_FAILURE(status) ) {
2211 log_err("udatpg_getBestPattern fails for locale %s, skeleton %s: status %s\n",
2212 itemPtr->locale, itemPtr->skeleton, u_errorName(status));
2213 } else {
2214 UDateFormat* udat = udat_open(UDAT_PATTERN, UDAT_PATTERN, itemPtr->locale, NULL, 0, ubuf2, ulen2, &status);
2215 if ( U_FAILURE(status) ) {
2216 log_data_err("udat_open fails for locale %s, skeleton %s: status %s (Are you missing data?)\n",
2217 itemPtr->locale, itemPtr->skeleton, u_errorName(status));
2218 } else {
2219 int32_t iDayOffset;
2220 for (iDayOffset = 0; iDayOffset < kNumDayOffsets; iDayOffset++) {
2221 status = U_ZERO_ERROR;
2222 ulen1 = udat_format(udat, baseDate + dayOffsets[iDayOffset], ubuf1, kUbufMax, NULL, &status);
2223 if ( U_FAILURE(status) ) {
2224 log_err("udat_format fails for locale %s, skeleton %s, iDayOffset %d: status %s\n",
2225 itemPtr->locale, itemPtr->skeleton, iDayOffset, u_errorName(status));
2226 } else {
2227 ulen2 = u_unescape(itemPtr->expected[iDayOffset], ubuf2, kUbufMax);
2228 if (ulen1 != ulen2 || u_strncmp(ubuf1, ubuf2, ulen2) != 0) {
2229 char bbuf1[kBbufMax], bbuf2[kBbufMax];
2230 u_austrncpy(bbuf1, ubuf1, ulen1);
2231 u_austrncpy(bbuf2, ubuf2, ulen2);
2232 log_err("udat_format fails for locale %s, skeleton %s, iDayOffset %d:\n expect %s\n get %s\n",
2233 itemPtr->locale, itemPtr->skeleton, iDayOffset, bbuf2, bbuf1);
2234 }
2235 }
2236
2237 }
2238 udat_close(udat);
2239 }
2240 }
2241 udatpg_close(udatpg);
2242 }
2243 }
2244 ucal_close(ucal);
2245 }
2246 }
2247}
2248
4f1e1a09 2249#if !U_PLATFORM_HAS_WIN32_API
b331163b
A
2250
2251typedef struct {
2252 const char* locale;
2253 UATimeUnitTimePattern patType;
2254 const char* expect; /* universal char subset + escaped Unicode chars */
2255} TimePatternItem;
2256static const TimePatternItem timePatternItems[] = {
2257 { "en", UATIMEUNITTIMEPAT_HM, "h:mm" },
2258 { "en", UATIMEUNITTIMEPAT_HMS, "h:mm:ss" },
2259 { "en", UATIMEUNITTIMEPAT_MS, "m:ss" },
2260 { "da", UATIMEUNITTIMEPAT_HM, "h.mm" },
2261 { "da", UATIMEUNITTIMEPAT_HMS, "h.mm.ss" },
2262 { "da", UATIMEUNITTIMEPAT_MS, "m.ss" },
2263 { NULL, 0, NULL }
2264};
2265
2266typedef struct {
2267 const char* locale;
2268 UATimeUnitStyle width;
2269 UATimeUnitListPattern patType;
2270 const char* expect; /* universal char subset + escaped Unicode chars */
2271} ListPatternItem;
2272static const ListPatternItem listPatternItems[] = {
2273 { "en", UATIMEUNITSTYLE_FULL, UATIMEUNITLISTPAT_TWO_ONLY, "{0}, {1}" },
2274 { "en", UATIMEUNITSTYLE_FULL, UATIMEUNITLISTPAT_END_PIECE, "{0}, {1}" },
2275 { "en", UATIMEUNITSTYLE_FULL, UATIMEUNITLISTPAT_MIDDLE_PIECE, "{0}, {1}" },
2276 { "en", UATIMEUNITSTYLE_FULL, UATIMEUNITLISTPAT_START_PIECE, "{0}, {1}" },
2277 { "en", UATIMEUNITSTYLE_NARROW, UATIMEUNITLISTPAT_TWO_ONLY, "{0} {1}" },
2278 { "en", UATIMEUNITSTYLE_NARROW, UATIMEUNITLISTPAT_END_PIECE, "{0} {1}" },
2279 { "en", UATIMEUNITSTYLE_NARROW, UATIMEUNITLISTPAT_MIDDLE_PIECE, "{0} {1}" },
2280 { "en", UATIMEUNITSTYLE_NARROW, UATIMEUNITLISTPAT_START_PIECE, "{0} {1}" },
2ca993e8 2281 { "en", UATIMEUNITSTYLE_SHORTER, UATIMEUNITLISTPAT_TWO_ONLY, "{0} {1}" },
b331163b
A
2282 { "fr", UATIMEUNITSTYLE_FULL, UATIMEUNITLISTPAT_TWO_ONLY, "{0} et {1}" },
2283 { "fr", UATIMEUNITSTYLE_FULL, UATIMEUNITLISTPAT_END_PIECE, "{0} et {1}" },
2284 { "fr", UATIMEUNITSTYLE_FULL, UATIMEUNITLISTPAT_MIDDLE_PIECE, "{0}, {1}" },
2285 { "fr", UATIMEUNITSTYLE_FULL, UATIMEUNITLISTPAT_START_PIECE, "{0}, {1}" },
2286 { "fr", UATIMEUNITSTYLE_NARROW, UATIMEUNITLISTPAT_TWO_ONLY, "{0} {1}" },
2287 { "fr", UATIMEUNITSTYLE_NARROW, UATIMEUNITLISTPAT_END_PIECE, "{0} {1}" },
2288 { "fr", UATIMEUNITSTYLE_NARROW, UATIMEUNITLISTPAT_MIDDLE_PIECE, "{0} {1}" },
2289 { "fr", UATIMEUNITSTYLE_NARROW, UATIMEUNITLISTPAT_START_PIECE, "{0} {1}" },
2ca993e8 2290 { "fr", UATIMEUNITSTYLE_SHORTER, UATIMEUNITLISTPAT_TWO_ONLY, "{0} {1}" },
b331163b
A
2291 { NULL, 0, 0, NULL }
2292};
2293
2294enum {kUBufTimeUnitLen = 128, kBBufTimeUnitLen = 256 };
2295
2296static void TestTimeUnitFormat(void) { /* Apple-specific */
2297 const TimePatternItem* timePatItemPtr;
2298 const ListPatternItem* listPatItemPtr;
2299 UChar uActual[kUBufTimeUnitLen];
2300 UChar uExpect[kUBufTimeUnitLen];
2301
2302 for (timePatItemPtr = timePatternItems; timePatItemPtr->locale != NULL; timePatItemPtr++) {
2303 UErrorCode status = U_ZERO_ERROR;
2304 int32_t ulenActual = uatmufmt_getTimePattern(timePatItemPtr->locale, timePatItemPtr->patType, uActual, kUBufTimeUnitLen, &status);
2305 if ( U_FAILURE(status) ) {
2306 log_err("uatmufmt_getTimePattern for locale %s, patType %d: status %s\n", timePatItemPtr->locale, (int)timePatItemPtr->patType, u_errorName(status));
2307 } else {
2308 int32_t ulenExpect = u_unescape(timePatItemPtr->expect, uExpect, kUBufTimeUnitLen);
2309 if (ulenActual != ulenExpect || u_strncmp(uActual, uExpect, ulenExpect) != 0) {
2310 char bActual[kBBufTimeUnitLen];
2311 u_strToUTF8(bActual, kBBufTimeUnitLen, NULL, uActual, ulenActual, &status);
2312 log_err("uatmufmt_getTimePattern for locale %s, patType %d: unexpected result %s\n", timePatItemPtr->locale, (int)timePatItemPtr->patType, bActual);
2313 }
2314 }
2315 }
2316
2317 for (listPatItemPtr = listPatternItems; listPatItemPtr->locale != NULL; listPatItemPtr++) {
2318 UErrorCode status = U_ZERO_ERROR;
2319 int32_t ulenActual = uatmufmt_getListPattern(listPatItemPtr->locale, listPatItemPtr->width, listPatItemPtr->patType, uActual, kUBufTimeUnitLen, &status);
2320 if ( U_FAILURE(status) ) {
2321 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));
2322 } else {
2323 int32_t ulenExpect = u_unescape(listPatItemPtr->expect, uExpect, kUBufTimeUnitLen);
2324 if (ulenActual != ulenExpect || u_strncmp(uActual, uExpect, ulenExpect) != 0) {
2325 char bActual[kBBufTimeUnitLen];
2326 u_strToUTF8(bActual, kBBufTimeUnitLen, NULL, uActual, ulenActual, &status);
2327 log_err("uatmufmt_getListPattern for locale %s, width %d, patType %d: unexpected result %s\n", listPatItemPtr->locale, (int)listPatItemPtr->width, (int)listPatItemPtr->patType, bActual);
2328 }
2329 }
2330 }
2331
2332}
3d1f044b
A
2333
2334typedef struct {
2335 const char* locale;
2336 UNumberFormatStyle numStyle;
2337 UATimeUnitStyle width;
2338 UATimeUnitField field;
2339 double value;
2340 const UChar* expect;
2341} TimeUnitWithNumStyleItem;
2342static const TimeUnitWithNumStyleItem tuNumStyleItems[] = {
2343 { "en_US", UNUM_PATTERN_DECIMAL/*0*/, UATIMEUNITSTYLE_FULL/*0*/, UATIMEUNITFIELD_SECOND/*6*/, 0.0, u"0 seconds" },
2344 { "en_US", UNUM_DECIMAL, UATIMEUNITSTYLE_FULL, UATIMEUNITFIELD_SECOND, 0.0, u"0 seconds" },
2345 { "en_US", UNUM_CURRENCY, UATIMEUNITSTYLE_FULL, UATIMEUNITFIELD_SECOND, 0.0, u"$0.00 seconds" },
2346 { "en_US", UNUM_PERCENT, UATIMEUNITSTYLE_FULL, UATIMEUNITFIELD_SECOND, 0.0, u"0% seconds" },
2347 { "en_US", UNUM_SCIENTIFIC/*4*/, UATIMEUNITSTYLE_FULL, UATIMEUNITFIELD_SECOND, 0.0, u"0E0 seconds" },
2348 { "en_US", UNUM_SPELLOUT/*5*/, UATIMEUNITSTYLE_FULL, UATIMEUNITFIELD_SECOND, 0.0, u"zero seconds" }, // uses RuleBasedNumberFormat, got U_UNSUPPORTED_ERROR
2349 { "en_US", UNUM_ORDINAL, UATIMEUNITSTYLE_FULL, UATIMEUNITFIELD_SECOND, 0.0, u"0th seconds" }, // uses RuleBasedNumberFormat, got U_UNSUPPORTED_ERROR
2350 { "en_US", UNUM_DURATION, UATIMEUNITSTYLE_FULL, UATIMEUNITFIELD_SECOND, 0.0, u"0 sec. seconds" }, // uses RuleBasedNumberFormat, got U_UNSUPPORTED_ERROR
2351 { "en_US", UNUM_NUMBERING_SYSTEM/*8*/, UATIMEUNITSTYLE_FULL, UATIMEUNITFIELD_SECOND, 0.0, u"௦ seconds" }, // uses RuleBasedNumberFormat, got U_UNSUPPORTED_ERROR
2352 // skip UNUM_PATTERN_RULEBASED/*9*/ // uses RuleBasedNumberFormat
2353 // { "en_US", UNUM_CURRENCY_ISO/*10*/, UATIMEUNITSTYLE_FULL, UATIMEUNITFIELD_SECOND, 0.0, u"USD 0.00 seconds" }, // currently produces u"USD 0.0 seconds0"
2354 { "en_US", UNUM_CURRENCY_PLURAL, UATIMEUNITSTYLE_FULL, UATIMEUNITFIELD_SECOND, 0.0, u"0.00 US dollars seconds" },
2355 { "en_US", UNUM_CURRENCY_ACCOUNTING, UATIMEUNITSTYLE_FULL, UATIMEUNITFIELD_SECOND, 0.0, u"$0.00 seconds" },
2356 { "en_US", UNUM_CASH_CURRENCY, UATIMEUNITSTYLE_FULL, UATIMEUNITFIELD_SECOND, 0.0, u"$0.00 seconds" },
2357 { "en_US", UNUM_DECIMAL_COMPACT_SHORT, UATIMEUNITSTYLE_FULL, UATIMEUNITFIELD_SECOND, 0.0, u"0 seconds" },
2358 { "en_US", UNUM_DECIMAL_COMPACT_LONG, UATIMEUNITSTYLE_FULL, UATIMEUNITFIELD_SECOND, 0.0, u"0 seconds" },
2359 { "en_US", UNUM_CURRENCY_STANDARD/*16*/,UATIMEUNITSTYLE_FULL, UATIMEUNITFIELD_SECOND, 0.0, u"$0.00 seconds" },
2360 { NULL, 0, 0, 0, 0.0, NULL }
2361};
2362
2363enum { kBBufMax = 196 };
2364
2365static void TestTimeUnitFormatWithNumStyle(void) { /* Apple-specific */
2366 const TimeUnitWithNumStyleItem* itemPtr;
2367 for (itemPtr = tuNumStyleItems; itemPtr->locale != NULL; itemPtr++) {
2368 UErrorCode status = U_ZERO_ERROR;
2369 UNumberFormat *numFormat = unum_open(itemPtr->numStyle, NULL, 0, itemPtr->locale, NULL, &status);
2370 if ( U_FAILURE(status) ) {
2371 log_data_err("unum_open for locale %s, style %d: status %s\n", itemPtr->locale, itemPtr->numStyle, u_errorName(status));
2372 } else {
2373 UATimeUnitFormat *tuFormat = uatmufmt_openWithNumberFormat(itemPtr->locale, itemPtr->width, numFormat, &status);
2374 if ( U_FAILURE(status) ) {
2375 log_data_err("uatmufmt_openWithNumberFormat for locale %s, numStyle %d, width %d: status %s\n", itemPtr->locale, itemPtr->numStyle, itemPtr->width, u_errorName(status));
2376 } else {
2377 UChar ubuf[kUBufMax] = {0};
2378 int32_t ulen = uatmufmt_format(tuFormat, itemPtr->value, itemPtr->field, ubuf, kUBufMax, &status);
2379 if ( U_FAILURE(status) ) {
2380 log_err("uatmufmt_format for locale %s, numStyle %d, width %d, field %d: status %s\n", itemPtr->locale, itemPtr->numStyle, itemPtr->width, itemPtr->field, u_errorName(status));
2381 } else if (u_strcmp(ubuf, itemPtr->expect) != 0) {
2382 char bbufExp[kBBufMax];
2383 char bbufGet[kBBufMax];
2384 u_strToUTF8(bbufExp, kBBufMax, NULL, itemPtr->expect, -1, &status);
2385 u_strToUTF8(bbufGet, kBBufMax, NULL, ubuf, ulen, &status);
2386 log_err("uatmufmt_format for locale %s, numStyle %d, width %d, field %d:\n expect %s\n get %s\n", itemPtr->locale, itemPtr->numStyle, itemPtr->width, itemPtr->field, bbufExp, bbufGet);
2387 }
2388 uatmufmt_close(tuFormat);
2389 }
2390 }
2391 }
2392}
2393
4f1e1a09 2394#endif
b331163b
A
2395
2396typedef enum RemapTesttype {
2397 REMAP_TESTTYPE_FULL = UDAT_FULL, // 0
2398 REMAP_TESTTYPE_LONG = UDAT_LONG, // 1
2399 REMAP_TESTTYPE_MEDIUM = UDAT_MEDIUM, // 2
2400 REMAP_TESTTYPE_SHORT = UDAT_SHORT, // 3
2401 REMAP_TESTTYPE_LONG_DF = UDAT_LONG + 4, // 5 long time, full date
2402 REMAP_TESTTYPE_SHORT_DS = UDAT_SHORT + 16, // 3 short time, short date
2403 REMAP_TESTTYPE_SKELETON = -1,
2404 REMAP_TESTTYPE_PATTERN = -2,
2405} RemapTesttype;
2406
2407typedef struct {
2408 const char * pattern;
2409 RemapTesttype testtype;
2410 uint32_t options;
2411} RemapPatternTestItem;
2412
2413static const RemapPatternTestItem remapPatItems[] = {
2414 { "full", REMAP_TESTTYPE_FULL, 0 },
2415 { "full", REMAP_TESTTYPE_FULL, UADATPG_FORCE_24_HOUR_CYCLE },
2416 { "full", REMAP_TESTTYPE_FULL, UADATPG_FORCE_12_HOUR_CYCLE },
2417 { "long", REMAP_TESTTYPE_LONG, 0 },
2418 { "long", REMAP_TESTTYPE_LONG, UADATPG_FORCE_24_HOUR_CYCLE },
2419 { "long", REMAP_TESTTYPE_LONG, UADATPG_FORCE_12_HOUR_CYCLE },
2420 { "medium", REMAP_TESTTYPE_MEDIUM, 0 },
2421 { "medium", REMAP_TESTTYPE_MEDIUM, UADATPG_FORCE_24_HOUR_CYCLE },
2422 { "medium", REMAP_TESTTYPE_MEDIUM, UADATPG_FORCE_12_HOUR_CYCLE },
2423 { "short", REMAP_TESTTYPE_SHORT, 0 },
2424 { "short", REMAP_TESTTYPE_SHORT, UADATPG_FORCE_24_HOUR_CYCLE },
2425 { "short", REMAP_TESTTYPE_SHORT, UADATPG_FORCE_12_HOUR_CYCLE },
2426 { "long_df", REMAP_TESTTYPE_LONG_DF, 0 },
2427 { "long_df", REMAP_TESTTYPE_LONG_DF, UADATPG_FORCE_24_HOUR_CYCLE },
2428 { "long_df", REMAP_TESTTYPE_LONG_DF, UADATPG_FORCE_12_HOUR_CYCLE },
2429 { "short_ds", REMAP_TESTTYPE_SHORT_DS, 0 },
2430 { "short_ds", REMAP_TESTTYPE_SHORT_DS, UADATPG_FORCE_24_HOUR_CYCLE },
2431 { "short_ds", REMAP_TESTTYPE_SHORT_DS, UADATPG_FORCE_12_HOUR_CYCLE },
2432
2433 { "jmmss", REMAP_TESTTYPE_SKELETON, 0 },
2434 { "jmmss", REMAP_TESTTYPE_SKELETON, UADATPG_FORCE_24_HOUR_CYCLE },
2435 { "jmmss", REMAP_TESTTYPE_SKELETON, UADATPG_FORCE_12_HOUR_CYCLE },
2436 { "jjmmss", REMAP_TESTTYPE_SKELETON, 0 },
2437 { "jjmmss", REMAP_TESTTYPE_SKELETON, UADATPG_FORCE_24_HOUR_CYCLE },
2438 { "jjmmss", REMAP_TESTTYPE_SKELETON, UADATPG_FORCE_24_HOUR_CYCLE | UDATPG_MATCH_HOUR_FIELD_LENGTH },
2439 { "jjmmss", REMAP_TESTTYPE_SKELETON, UADATPG_FORCE_12_HOUR_CYCLE },
2440 { "jjmmss", REMAP_TESTTYPE_SKELETON, UADATPG_FORCE_12_HOUR_CYCLE | UDATPG_MATCH_HOUR_FIELD_LENGTH },
2441 { "Jmm", REMAP_TESTTYPE_SKELETON, 0 },
2442 { "Jmm", REMAP_TESTTYPE_SKELETON, UADATPG_FORCE_24_HOUR_CYCLE },
2443 { "Jmm", REMAP_TESTTYPE_SKELETON, UADATPG_FORCE_12_HOUR_CYCLE },
2444 { "jmsv", REMAP_TESTTYPE_SKELETON, 0 },
2445 { "jmsv", REMAP_TESTTYPE_SKELETON, UADATPG_FORCE_24_HOUR_CYCLE },
2446 { "jmsv", REMAP_TESTTYPE_SKELETON, UADATPG_FORCE_12_HOUR_CYCLE },
2447 { "jmsz", REMAP_TESTTYPE_SKELETON, 0 },
2448 { "jmsz", REMAP_TESTTYPE_SKELETON, UADATPG_FORCE_24_HOUR_CYCLE },
2449 { "jmsz", REMAP_TESTTYPE_SKELETON, UADATPG_FORCE_12_HOUR_CYCLE },
2450
2451 { "h:mm:ss a", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_12_HOUR_CYCLE }, // 12=hour patterns
2452 { "h:mm:ss a", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_24_HOUR_CYCLE },
2453 { "a'xx'h:mm:ss d MMM y", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_12_HOUR_CYCLE },
2454 { "a'xx'h:mm:ss d MMM y", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_24_HOUR_CYCLE },
2455 { "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_12_HOUR_CYCLE },
2456 { "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_24_HOUR_CYCLE },
2457 { "EEE, d MMM y 'aha' a'xx'h:mm:ss", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_12_HOUR_CYCLE },
2458 { "EEE, d MMM y 'aha' a'xx'h:mm:ss", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_24_HOUR_CYCLE },
2459 { "yyMMddhhmmss", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_12_HOUR_CYCLE },
2460 { "yyMMddhhmmss", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_24_HOUR_CYCLE },
2461
2462 { "H:mm:ss", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_12_HOUR_CYCLE }, // 24=hour patterns
2463 { "H:mm:ss", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_24_HOUR_CYCLE },
2464 { "H:mm:ss d MMM y", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_12_HOUR_CYCLE },
2465 { "H:mm:ss d MMM y", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_24_HOUR_CYCLE },
2466 { "EEE, d MMM y 'aha' H:mm:ss 'hrs'", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_12_HOUR_CYCLE },
2467 { "EEE, d MMM y 'aha' H:mm:ss 'hrs'", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_24_HOUR_CYCLE },
2468 { "EEE, d MMM y 'aha' H'h'mm'm'ss", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_12_HOUR_CYCLE },
2469 { "EEE, d MMM y 'aha' H'h'mm'm'ss", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_24_HOUR_CYCLE },
0f5d89e8
A
2470
2471 // special cases per bugs
2472 { "uuuu-MM-dd HH:mm:ss '+0000'", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_12_HOUR_CYCLE }, // <rdar://problem/38826484>
2473
b331163b
A
2474 { NULL, (RemapTesttype)0, 0 }
2475};
2476
2477static const char * remapResults_root[] = {
2478 "HH:mm:ss zzzz", // full
2479 "HH:mm:ss zzzz", // force24
2480 "h:mm:ss a zzzz", // force12
2481 "HH:mm:ss z", // long
2482 "HH:mm:ss z", // force24
2483 "h:mm:ss a z", // force12
2484 "HH:mm:ss", // medium
2485 "HH:mm:ss", // force24
2486 "h:mm:ss a", // force12
2487 "HH:mm", // short
2488 "HH:mm", // force24
2489 "h:mm a", // force12
2490 "y MMMM d, EEEE HH:mm:ss z", // long_df
2491 "y MMMM d, EEEE HH:mm:ss z", // force24
2492 "y MMMM d, EEEE h:mm:ss a z", // force12
2493 "y-MM-dd HH:mm", // short_ds
2494 "y-MM-dd HH:mm", // force24
2495 "y-MM-dd h:mm a", // force12
2496
2497 "HH:mm:ss", // jmmss
2498 "HH:mm:ss", // force24
2499 "h:mm:ss a", // force12
2500 "HH:mm:ss", // jjmmss
2501 "HH:mm:ss", // force24
2502 "HH:mm:ss", // force24 | match hour field length
2503 "h:mm:ss a", // force12
2504 "hh:mm:ss a", // force12 | match hour field length
2505 "HH:mm", // Jmm
2506 "HH:mm", // force24
2507 "hh:mm", // force12
2508 "HH:mm:ss v", // jmsv
2509 "HH:mm:ss v", // force24
2510 "h:mm:ss a v", // force12
2511 "HH:mm:ss z", // jmsz
2512 "HH:mm:ss z", // force24
2513 "h:mm:ss a z", // force12
2514
2515 "h:mm:ss a", // "h:mm:ss"
2516 "HH:mm:ss", //
2517 "a'xx'h:mm:ss d MMM y", // "a'xx'h:mm:ss d MMM y"
2518 "HH:mm:ss d MMM y", //
2519 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' h:mm:ss a 'hrs'"
2520 "EEE, d MMM y 'aha' HH:mm:ss 'hrs'", //
2521 "EEE, d MMM y 'aha' a'xx'h:mm:ss", // "EEE, d MMM y 'aha' a'xx'h:mm:ss"
2522 "EEE, d MMM y 'aha' HH:mm:ss", //
2523 "yyMMddhhmmss", // "yyMMddhhmmss"
2524 "yyMMddHHmmss", //
2525
2526 "h:mm:ss a", // "H:mm:ss"
2527 "H:mm:ss", //
2528 "h:mm:ss a d MMM y", // "H:mm:ss d MMM y"
2529 "H:mm:ss d MMM y", //
2530 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' H:mm:ss 'hrs'"
2531 "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
2532 "EEE, d MMM y 'aha' h'h'mm'm'ss a", // "EEE, d MMM y 'aha' H'h'mm'm'ss"
2533 "EEE, d MMM y 'aha' H'h'mm'm'ss", //
0f5d89e8
A
2534
2535 "uuuu-MM-dd h:mm:ss a '+0000'", //
2536
b331163b
A
2537 NULL
2538};
2539
2540static const char * remapResults_en[] = {
2541 "h:mm:ss a zzzz", // full
2542 "HH:mm:ss zzzz", // force24
2543 "h:mm:ss a zzzz", // force12
2544 "h:mm:ss a z", // long
2545 "HH:mm:ss z", // force24
2546 "h:mm:ss a z", // force12
2547 "h:mm:ss a", // medium
2548 "HH:mm:ss", // force24
2549 "h:mm:ss a", // force12
2550 "h:mm a", // short
2551 "HH:mm", // force24
2552 "h:mm a", // force12
2553 "EEEE, MMMM d, y 'at' h:mm:ss a z", // long_df
2554 "EEEE, MMMM d, y 'at' HH:mm:ss z", // force24
2555 "EEEE, MMMM d, y 'at' h:mm:ss a z", // force12
2556 "M/d/yy, h:mm a", // short_ds
2557 "M/d/yy, HH:mm", // force24
2558 "M/d/yy, h:mm a", // force12
2559
2560 "h:mm:ss a", // jmmss
2561 "HH:mm:ss", // force24
2562 "h:mm:ss a", // force12
2563 "h:mm:ss a", // jjmmss
2564 "HH:mm:ss", // force24
2565 "HH:mm:ss", // force24 | match hour field length
2566 "h:mm:ss a", // force12
2567 "hh:mm:ss a", // force12 | match hour field length
2568 "hh:mm", // Jmm
2569 "HH:mm", // force24
2570 "hh:mm", // force12
2571 "h:mm:ss a v", // jmsv
2572 "HH:mm:ss v", // force24
2573 "h:mm:ss a v", // force12
2574 "h:mm:ss a z", // jmsz
2575 "HH:mm:ss z", // force24
2576 "h:mm:ss a z", // force12
2577
2578 "h:mm:ss a", // "h:mm:ss"
2579 "HH:mm:ss", //
2580 "a'xx'h:mm:ss d MMM y", // "a'xx'h:mm:ss d MMM y"
2581 "HH:mm:ss d MMM y", //
2582 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' h:mm:ss a 'hrs'"
2583 "EEE, d MMM y 'aha' HH:mm:ss 'hrs'", //
2584 "EEE, d MMM y 'aha' a'xx'h:mm:ss", // "EEE, d MMM y 'aha' a'xx'h:mm:ss"
2585 "EEE, d MMM y 'aha' HH:mm:ss", //
2586 "yyMMddhhmmss", // "yyMMddhhmmss"
2587 "yyMMddHHmmss", //
2588
2589 "h:mm:ss a", // "H:mm:ss"
2590 "H:mm:ss", //
2591 "h:mm:ss a d MMM y", // "H:mm:ss d MMM y"
2592 "H:mm:ss d MMM y", //
2593 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' H:mm:ss 'hrs'"
2594 "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
2595 "EEE, d MMM y 'aha' h'h'mm'm'ss a", // "EEE, d MMM y 'aha' H'h'mm'm'ss"
2596 "EEE, d MMM y 'aha' H'h'mm'm'ss", //
0f5d89e8
A
2597
2598 "uuuu-MM-dd h:mm:ss a '+0000'", //
2599
b331163b
A
2600 NULL
2601};
2602
2603static const char * remapResults_ja[] = {
2604 "H\\u6642mm\\u5206ss\\u79D2 zzzz", // full
2605 "H\\u6642mm\\u5206ss\\u79D2 zzzz", // force24
2606 "aK:mm:ss zzzz", // force12
2607 "H:mm:ss z", // long
2608 "H:mm:ss z", // force24
2609 "aK:mm:ss z", // force12
2610 "H:mm:ss", // medium
2611 "H:mm:ss", // force24
2612 "aK:mm:ss", // force12
2613 "H:mm", // short
2614 "H:mm", // force24
2615 "aK:mm", // force12
f3c0d7a5
A
2616 "y\\u5E74M\\u6708d\\u65E5 EEEE H:mm:ss z", // long_df
2617 "y\\u5E74M\\u6708d\\u65E5 EEEE H:mm:ss z", // force24
2618 "y\\u5E74M\\u6708d\\u65E5 EEEE aK:mm:ss z", // force12
b331163b
A
2619 "y/MM/dd H:mm", // short_ds
2620 "y/MM/dd H:mm", // force24
2621 "y/MM/dd aK:mm", // force12
2622
2623 "H:mm:ss", // jmmss
2624 "H:mm:ss", // force24
2625 "aK:mm:ss", // force12
2626 "H:mm:ss", // jjmmss
2627 "H:mm:ss", // force24
2628 "HH:mm:ss", // force24 | match hour field length
2629 "aK:mm:ss", // force12
2630 "aKK:mm:ss", // force12 | match hour field length
2631 "H:mm", // Jmm
2632 "H:mm", // force24
2633 "h:mm", // force12
2634 "H:mm:ss v", // jmsv
2635 "H:mm:ss v", // force24
2636 "aK:mm:ss v", // force12
2637 "H:mm:ss z", // jmsz
2638 "H:mm:ss z", // force24
2639 "aK:mm:ss z", // force12
2640
2641 "h:mm:ss a", // "h:mm:ss"
2642 "H:mm:ss", //
2643 "a'xx'h:mm:ss d MMM y", // "a'xx'h:mm:ss d MMM y"
2644 "H:mm:ss d MMM y", //
2645 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' h:mm:ss a 'hrs'"
2646 "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
2647 "EEE, d MMM y 'aha' a'xx'h:mm:ss", // "EEE, d MMM y 'aha' a'xx'h:mm:ss"
2648 "EEE, d MMM y 'aha' H:mm:ss", //
2649 "yyMMddhhmmss", // "yyMMddhhmmss"
2650 "yyMMddHHmmss", //
2651
2652 "aK:mm:ss", // "H:mm:ss"
2653 "H:mm:ss", //
2654 "aK:mm:ss d MMM y", // "H:mm:ss d MMM y"
2655 "H:mm:ss d MMM y", //
2656 "EEE, d MMM y 'aha' aK:mm:ss 'hrs'", // "EEE, d MMM y 'aha' H:mm:ss 'hrs'"
2657 "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
2658 "EEE, d MMM y 'aha' aK'h'mm'm'ss", // "EEE, d MMM y 'aha' H'h'mm'm'ss"
2659 "EEE, d MMM y 'aha' H'h'mm'm'ss", //
0f5d89e8
A
2660
2661 "uuuu-MM-dd aK:mm:ss '+0000'", //
2662
b331163b
A
2663 NULL
2664};
2665
2666static const char * remapResults_ko[] = {
2667 "a h\\uC2DC m\\uBD84 s\\uCD08 zzzz", // full
2668 "H\\uC2DC m\\uBD84 s\\uCD08 zzzz", // force24
2669 "a h\\uC2DC m\\uBD84 s\\uCD08 zzzz", // force12
2670 "a h\\uC2DC m\\uBD84 s\\uCD08 z", // long
2671 "H\\uC2DC m\\uBD84 s\\uCD08 z", // force24
2672 "a h\\uC2DC m\\uBD84 s\\uCD08 z", // force12
2673 "a h:mm:ss", // medium
2674 "HH:mm:ss", // force24
2675 "a h:mm:ss", // force12
2676 "a h:mm", // short
2677 "HH:mm", // force24
2678 "a h:mm", // force12
2679 "y\\uB144 M\\uC6D4 d\\uC77C EEEE a h\\uC2DC m\\uBD84 s\\uCD08 z", // long_df
2680 "y\\uB144 M\\uC6D4 d\\uC77C EEEE H\\uC2DC m\\uBD84 s\\uCD08 z", // force24
2681 "y\\uB144 M\\uC6D4 d\\uC77C EEEE a h\\uC2DC m\\uBD84 s\\uCD08 z", // force12
2682 "y. M. d. a h:mm", // short_ds
2683 "y. M. d. HH:mm", // force24
2684 "y. M. d. a h:mm", // force12
2685
2686 "a h:mm:ss", // jmmss
2687 "HH:mm:ss", // force24
2688 "a h:mm:ss", // force12
2689 "a h:mm:ss", // jjmmss
2690 "HH:mm:ss", // force24
2691 "HH:mm:ss", // force24 | match hour field length
2692 "a h:mm:ss", // force12
2693 "a hh:mm:ss", // force12 | match hour field length
2694 "hh:mm", // Jmm
2695 "HH:mm", // force24
2696 "hh:mm", // force12
2697 "a h:mm:ss v", // jmsv
2698 "H\\uC2DC m\\uBD84 s\\uCD08 v", // force24
2699 "a h:mm:ss v", // force12
2700 "a h\\uC2DC m\\uBD84 s\\uCD08 z", // jmsz
2701 "H\\uC2DC m\\uBD84 s\\uCD08 z", // force24
2702 "a h\\uC2DC m\\uBD84 s\\uCD08 z", // force12
2703
2704 "h:mm:ss a", // "h:mm:ss"
2705 "HH:mm:ss", //
2706 "a'xx'h:mm:ss d MMM y", // "a'xx'h:mm:ss d MMM y"
2707 "HH:mm:ss d MMM y", //
2708 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' h:mm:ss a 'hrs'"
2709 "EEE, d MMM y 'aha' HH:mm:ss 'hrs'", //
2710 "EEE, d MMM y 'aha' a'xx'h:mm:ss", // "EEE, d MMM y 'aha' a'xx'h:mm:ss"
2711 "EEE, d MMM y 'aha' HH:mm:ss", //
2712 "yyMMddhhmmss", // "yyMMddhhmmss"
2713 "yyMMddHHmmss", //
2714
2715 "a h:mm:ss", // "H:mm:ss"
2716 "H:mm:ss", //
2717 "a h:mm:ss d MMM y", // "H:mm:ss d MMM y"
2718 "H:mm:ss d MMM y", //
2719 "EEE, d MMM y 'aha' a h:mm:ss 'hrs'", // "EEE, d MMM y 'aha' H:mm:ss 'hrs'"
2720 "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
2721 "EEE, d MMM y 'aha' a h'h'mm'm'ss", // "EEE, d MMM y 'aha' H'h'mm'm'ss"
2722 "EEE, d MMM y 'aha' H'h'mm'm'ss", //
0f5d89e8
A
2723
2724 "uuuu-MM-dd a h:mm:ss '+0000'", //
2725
b331163b
A
2726 NULL
2727};
2728
2729static const char * remapResults_th[] = {
2730 "H \\u0E19\\u0E32\\u0E2C\\u0E34\\u0E01\\u0E32 mm \\u0E19\\u0E32\\u0E17\\u0E35 ss \\u0E27\\u0E34\\u0E19\\u0E32\\u0E17\\u0E35 zzzz", // full
2731 "H \\u0E19\\u0E32\\u0E2C\\u0E34\\u0E01\\u0E32 mm \\u0E19\\u0E32\\u0E17\\u0E35 ss \\u0E27\\u0E34\\u0E19\\u0E32\\u0E17\\u0E35 zzzz", // force24
2732 "h:mm:ss a zzzz", // force12
2733 "H \\u0E19\\u0E32\\u0E2C\\u0E34\\u0E01\\u0E32 mm \\u0E19\\u0E32\\u0E17\\u0E35 ss \\u0E27\\u0E34\\u0E19\\u0E32\\u0E17\\u0E35 z", // long
2734 "H \\u0E19\\u0E32\\u0E2C\\u0E34\\u0E01\\u0E32 mm \\u0E19\\u0E32\\u0E17\\u0E35 ss \\u0E27\\u0E34\\u0E19\\u0E32\\u0E17\\u0E35 z", // force24
2735 "h:mm:ss a z", // force12
2736 "HH:mm:ss", // medium
2737 "HH:mm:ss", // force24
2738 "h:mm:ss a", // force12
2739 "HH:mm", // short
2740 "HH:mm", // force24
2741 "h:mm a", // force12
2742 "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
2743 "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
2744 "EEEE\\u0E17\\u0E35\\u0E48 d MMMM G y h:mm:ss a z", // force12
2745 "d/M/yy HH:mm", // short_ds
2746 "d/M/yy HH:mm", // force24
2747 "d/M/yy h:mm a", // force12
2748
2749 "HH:mm:ss", // jmmss
2750 "HH:mm:ss", // force24
2751 "h:mm:ss a", // force12
2752 "HH:mm:ss", // jjmmss
2753 "HH:mm:ss", // force24
2754 "HH:mm:ss", // force24 | match hour field length
2755 "h:mm:ss a", // force12
2756 "hh:mm:ss a", // force12 | match hour field length
2757 "HH:mm", // Jmm
2758 "HH:mm", // force24
2759 "hh:mm", // force12
2760 "H \\u0E19\\u0E32\\u0E2C\\u0E34\\u0E01\\u0E32 mm \\u0E19\\u0E32\\u0E17\\u0E35 ss \\u0E27\\u0E34\\u0E19\\u0E32\\u0E17\\u0E35 v", // jmsv
2761 "H \\u0E19\\u0E32\\u0E2C\\u0E34\\u0E01\\u0E32 mm \\u0E19\\u0E32\\u0E17\\u0E35 ss \\u0E27\\u0E34\\u0E19\\u0E32\\u0E17\\u0E35 v", // force24
2762 "h:mm:ss a v", // force12
2763 "H \\u0E19\\u0E32\\u0E2C\\u0E34\\u0E01\\u0E32 mm \\u0E19\\u0E32\\u0E17\\u0E35 ss \\u0E27\\u0E34\\u0E19\\u0E32\\u0E17\\u0E35 z", // jmsz
2764 "H \\u0E19\\u0E32\\u0E2C\\u0E34\\u0E01\\u0E32 mm \\u0E19\\u0E32\\u0E17\\u0E35 ss \\u0E27\\u0E34\\u0E19\\u0E32\\u0E17\\u0E35 z", // force24
2765 "h:mm:ss a z", // force12
2766
2767 "h:mm:ss a", // "h:mm:ss"
2768 "HH:mm:ss", //
2769 "a'xx'h:mm:ss d MMM y", // "a'xx'h:mm:ss d MMM y"
2770 "HH:mm:ss d MMM y", //
2771 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' h:mm:ss a 'hrs'"
2772 "EEE, d MMM y 'aha' HH:mm:ss 'hrs'", //
2773 "EEE, d MMM y 'aha' a'xx'h:mm:ss", // "EEE, d MMM y 'aha' a'xx'h:mm:ss"
2774 "EEE, d MMM y 'aha' HH:mm:ss", //
2775 "yyMMddhhmmss", // "yyMMddhhmmss"
2776 "yyMMddHHmmss", //
2777
2778 "h:mm:ss a", // "H:mm:ss"
2779 "H:mm:ss", //
2780 "h:mm:ss a d MMM y", // "H:mm:ss d MMM y"
2781 "H:mm:ss d MMM y", //
2782 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' H:mm:ss 'hrs'"
2783 "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
2784 "EEE, d MMM y 'aha' h'h'mm'm'ss a", // "EEE, d MMM y 'aha' H'h'mm'm'ss"
2785 "EEE, d MMM y 'aha' H'h'mm'm'ss", //
0f5d89e8
A
2786
2787 "uuuu-MM-dd h:mm:ss a '+0000'", //
2788
b331163b
A
2789 NULL
2790};
2791
2792static const char * remapResults_hi[] = {
2793 "a h:mm:ss zzzz", // full
2794 "HH:mm:ss zzzz", // force24
2795 "a h:mm:ss zzzz", // force12
2796 "a h:mm:ss z", // long
2797 "HH:mm:ss z", // force24
2798 "a h:mm:ss z", // force12
2799 "a h:mm:ss", // medium
2800 "HH:mm:ss", // force24
2801 "a h:mm:ss", // force12
2802 "a h:mm", // short
2803 "HH:mm", // force24
2804 "a h:mm", // force12
2805 "EEEE, d MMMM y, a h:mm:ss z", // long_df
2806 "EEEE, d MMMM y, HH:mm:ss z", // force24
2807 "EEEE, d MMMM y, a h:mm:ss z", // force12
2808 "d/M/yy, a h:mm", // short_ds
2809 "d/M/yy, HH:mm", // force24
2810 "d/M/yy, a h:mm", // force12
2811
2812 "a h:mm:ss", // jmmss
2813 "HH:mm:ss", // force24
2814 "a h:mm:ss", // force12
2815 "a h:mm:ss", // jjmmss
2816 "HH:mm:ss", // force24
2817 "HH:mm:ss", // force24 | match hour field length
2818 "a h:mm:ss", // force12
2819 "a hh:mm:ss", // force12 | match hour field length
2820 "hh:mm", // Jmm
2821 "HH:mm", // force24
2822 "hh:mm", // force12
2823 "a h:mm:ss v", // jmsv
2824 "HH:mm:ss v", // force24
2825 "a h:mm:ss v", // force12
2826 "a h:mm:ss z", // jmsz
2827 "HH:mm:ss z", // force24
2828 "a h:mm:ss z", // force12
2829
2830 "h:mm:ss a", // "h:mm:ss"
2831 "HH:mm:ss", //
2832 "a'xx'h:mm:ss d MMM y", // "a'xx'h:mm:ss d MMM y"
2833 "HH:mm:ss d MMM y", //
2834 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' h:mm:ss a 'hrs'"
2835 "EEE, d MMM y 'aha' HH:mm:ss 'hrs'", //
2836 "EEE, d MMM y 'aha' a'xx'h:mm:ss", // "EEE, d MMM y 'aha' a'xx'h:mm:ss"
2837 "EEE, d MMM y 'aha' HH:mm:ss", //
2838 "yyMMddhhmmss", // "yyMMddhhmmss"
2839 "yyMMddHHmmss", //
2840
2841 "a h:mm:ss", // "H:mm:ss"
2842 "H:mm:ss", //
2843 "a h:mm:ss d MMM y", // "H:mm:ss d MMM y"
2844 "H:mm:ss d MMM y", //
2845 "EEE, d MMM y 'aha' a h:mm:ss 'hrs'", // "EEE, d MMM y 'aha' H:mm:ss 'hrs'"
2846 "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
2847 "EEE, d MMM y 'aha' a h'h'mm'm'ss", // "EEE, d MMM y 'aha' H'h'mm'm'ss"
2848 "EEE, d MMM y 'aha' H'h'mm'm'ss", //
0f5d89e8
A
2849
2850 "uuuu-MM-dd a h:mm:ss '+0000'", //
2851
b331163b
A
2852 NULL
2853};
2854
f3c0d7a5
A
2855static const char * remapResults_ar[] = {
2856 "h:mm:ss\\u00A0a zzzz", // full
2857 "HH:mm:ss zzzz", // force24
2858 "h:mm:ss\\u00A0a zzzz", // force12
2859 "h:mm:ss\\u00A0a z", // long
2860 "HH:mm:ss z", // force24
2861 "h:mm:ss\\u00A0a z", // force12
2862 "h:mm:ss\\u00A0a", // medium
2863 "HH:mm:ss", // force24
2864 "h:mm:ss\\u00A0a", // force12
2865 "h:mm\\u00A0a", // short
2866 "HH:mm", // force24
2867 "h:mm\\u00A0a", // force12
2868 "EEEE\\u060C d MMMM\\u060C y\\u060C h:mm:ss\\u00A0a z", // long_df
2869 "EEEE\\u060C d MMMM\\u060C y\\u060C HH:mm:ss z", // force24
2870 "EEEE\\u060C d MMMM\\u060C y\\u060C h:mm:ss\\u00A0a z", // force12
2871 "d\\u200F/M\\u200F/y\\u060C h:mm\\u00A0a", // short_ds
2872 "d\\u200F/M\\u200F/y\\u060C HH:mm", // force24
2873 "d\\u200F/M\\u200F/y\\u060C h:mm\\u00A0a", // force12
2874
2875 "h:mm:ss\\u00A0a", // jmmss
2876 "HH:mm:ss", // force24
2877 "h:mm:ss\\u00A0a", // force12
2878 "h:mm:ss\\u00A0a", // jjmmss
2879 "HH:mm:ss", // force24
2880 "HH:mm:ss", // force24 | match hour field length
2881 "h:mm:ss\\u00A0a", // force12
2882 "hh:mm:ss\\u00A0a", // force12 | match hour field length
2883 "hh:mm", // Jmm
2884 "HH:mm", // force24
2885 "hh:mm", // force12
2886 "h:mm:ss\\u00A0a v", // jmsv
2887 "HH:mm:ss v", // force24
2888 "h:mm:ss\\u00A0a v", // force12
2889 "h:mm:ss\\u00A0a z", // jmsz
2890 "HH:mm:ss z", // force24
2891 "h:mm:ss\\u00A0a z", // force12
2892
2893 "h:mm:ss a", // "h:mm:ss"
2894 "HH:mm:ss", //
2895 "a'xx'h:mm:ss d MMM y", // "a'xx'h:mm:ss d MMM y"
2896 "HH:mm:ss d MMM y", //
2897 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' h:mm:ss a 'hrs'"
2898 "EEE, d MMM y 'aha' HH:mm:ss 'hrs'", //
2899 "EEE, d MMM y 'aha' a'xx'h:mm:ss", // "EEE, d MMM y 'aha' a'xx'h:mm:ss"
2900 "EEE, d MMM y 'aha' HH:mm:ss", //
2901 "yyMMddhhmmss", // "yyMMddhhmmss"
2902 "yyMMddHHmmss", //
2903
2904 "h:mm:ssa", // "H:mm:ss" (should there be \\u00A0 before a?)
2905 "H:mm:ss", //
2906 "h:mm:ssa d MMM y", // "H:mm:ss d MMM y" (should there be \\u00A0 before a?)
2907 "H:mm:ss d MMM y", //
2908 "EEE, d MMM y 'aha' h:mm:ssa 'hrs'", // "EEE, d MMM y 'aha' H:mm:ss 'hrs'" (should there be \\u00A0 before a?)
2909 "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
2910 "EEE, d MMM y 'aha' h'h'mm'm'ssa", // "EEE, d MMM y 'aha' H'h'mm'm'ss" (should there be \\u00A0 before a?)
2911 "EEE, d MMM y 'aha' H'h'mm'm'ss", //
0f5d89e8
A
2912
2913 "uuuu-MM-dd h:mm:ss\\u00A0a '+0000'", //
2914
2915 NULL
2916};
2917
2918static const char * remapResults_en_IL[] = {
2919 "H:mm:ss zzzz", // full
2920 "H:mm:ss zzzz", // force24
2921 "h:mm:ss a zzzz", // force12
2922 "H:mm:ss z", // long
2923 "H:mm:ss z", // force24
2924 "h:mm:ss a z", // force12
2925 "H:mm:ss", // medium
2926 "H:mm:ss", // force24
2927 "h:mm:ss a", // force12
2928 "H:mm", // short
2929 "H:mm", // force24
2930 "h:mm a", // force12
2931 "EEEE, d MMMM y 'at' H:mm:ss z", // long_df
2932 "EEEE, d MMMM y 'at' H:mm:ss z", // force24
2933 "EEEE, d MMMM y 'at' h:mm:ss a z", // force12
2934 "dd/MM/y, H:mm", // short_ds
2935 "dd/MM/y, H:mm", // force24
2936 "dd/MM/y, h:mm a", // force12
2937
2938 "H:mm:ss", // jmmss
2939 "H:mm:ss", // force24
2940 "h:mm:ss a", // force12
2941 "H:mm:ss", // jjmmss
2942 "H:mm:ss", // force24
2943 "HH:mm:ss", // force24 | match hour field length
2944 "h:mm:ss a", // force12
2945 "hh:mm:ss a", // force12 | match hour field length
2946 "H:mm", // Jmm
2947 "H:mm", // force24
2948 "h:mm", // force12
2949 "H:mm:ss v", // jmsv
2950 "H:mm:ss v", // force24
2951 "h:mm:ss a v", // force12
2952 "H:mm:ss z", // jmsz
2953 "H:mm:ss z", // force24
2954 "h:mm:ss a z", // force12
2955
2956 "h:mm:ss a", // "h:mm:ss"
2957 "H:mm:ss", //
2958 "a'xx'h:mm:ss d MMM y", // "a'xx'h:mm:ss d MMM y"
2959 "H:mm:ss d MMM y", //
2960 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' h:mm:ss a 'hrs'"
2961 "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
2962 "EEE, d MMM y 'aha' a'xx'h:mm:ss", // "EEE, d MMM y 'aha' a'xx'h:mm:ss"
2963 "EEE, d MMM y 'aha' H:mm:ss", //
2964 "yyMMddhhmmss", // "yyMMddhhmmss"
2965 "yyMMddHHmmss", //
2966
2967 "h:mm:ss a", // "H:mm:ss"
2968 "H:mm:ss", //
2969 "h:mm:ss a d MMM y", // "H:mm:ss d MMM y"
2970 "H:mm:ss d MMM y", //
2971 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' H:mm:ss 'hrs'"
2972 "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
2973 "EEE, d MMM y 'aha' h'h'mm'm'ss a", // "EEE, d MMM y 'aha' H'h'mm'm'ss"
2974 "EEE, d MMM y 'aha' H'h'mm'm'ss", //
2975
2976 "uuuu-MM-dd h:mm:ss a '+0000'", //
2977
f3c0d7a5
A
2978 NULL
2979};
2980
3d1f044b
A
2981static const char * remapResults_es_PR_japanese[] = { // rdar://52461062
2982 "h:mm:ss a zzzz", // full
2983 "HH:mm:ss zzzz", // force24
2984 "h:mm:ss a zzzz", // force12
2985 "h:mm:ss a z", // long
2986 "HH:mm:ss z", // force24
2987 "h:mm:ss a z", // force12
2988 "h:mm:ss a", // medium
2989 "HH:mm:ss", // force24
2990 "h:mm:ss a", // force12
2991 "h:mm a", // short
2992 "HH:mm", // force24
2993 "h:mm a", // force12
2994 "EEEE, d 'de' MMMM 'de' y G, h:mm:ss a z", // long_df
2995 "EEEE, d 'de' MMMM 'de' y G, HH:mm:ss z", // force24
2996 "EEEE, d 'de' MMMM 'de' y G, h:mm:ss a z", // force12
2997 "MM/dd/yy GGGGG h:mm a", // short_ds
2998 "MM/dd/yy GGGGG HH:mm", // force24
2999 "MM/dd/yy GGGGG h:mm a", // force12
3000
3001 "h:mm:ss a", // jmmss
3002 "HH:mm:ss", // force24
3003 "h:mm:ss a", // force12
3004 "h:mm:ss a", // jjmmss
3005 "HH:mm:ss", // force24
3006 "HH:mm:ss", // force24 | match hour field length
3007 "h:mm:ss a", // force12
3008 "hh:mm:ss a", // force12 | match hour field length
3009 "hh:mm", // Jmm
3010 "HH:mm", // force24
3011 "hh:mm", // force12
3012 "h:mm:ss a v", // jmsv
3013 "HH:mm:ss v", // force24
3014 "h:mm:ss a v", // force12
3015 "h:mm:ss a z", // jmsz
3016 "HH:mm:ss z", // force24
3017 "h:mm:ss a z", // force12
3018
3019 "h:mm:ss a", // "h:mm:ss"
3020 "HH:mm:ss", //
3021 "a'xx'h:mm:ss d MMM y", // "a'xx'h:mm:ss d MMM y"
3022 "HH:mm:ss d MMM y", //
3023 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' h:mm:ss a 'hrs'"
3024 "EEE, d MMM y 'aha' HH:mm:ss 'hrs'", //
3025 "EEE, d MMM y 'aha' a'xx'h:mm:ss", // "EEE, d MMM y 'aha' a'xx'h:mm:ss"
3026 "EEE, d MMM y 'aha' HH:mm:ss", //
3027 "yyMMddhhmmss", // "yyMMddhhmmss"
3028 "yyMMddHHmmss", //
3029
3030 "h:mm:ss a", // "H:mm:ss"
3031 "H:mm:ss", //
3032 "h:mm:ss a d MMM y", // "H:mm:ss d MMM y"
3033 "H:mm:ss d MMM y", //
3034 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' H:mm:ss 'hrs'"
3035 "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
3036 "EEE, d MMM y 'aha' h'h'mm'm'ss a", // "EEE, d MMM y 'aha' H'h'mm'm'ss"
3037 "EEE, d MMM y 'aha' H'h'mm'm'ss", //
3038
3039 "uuuu-MM-dd h:mm:ss a '+0000'", //
3040
3041 NULL
3042};
3043
1a147d09
A
3044static const char * remapResults_en_IN[] = { // rdar://56309604
3045 "h:mm:ss a zzzz", // full
3046 "HH:mm:ss zzzz", // force24
3047 "h:mm:ss a zzzz", // force12
3048 "h:mm:ss a z", // long
3049 "HH:mm:ss z", // force24
3050 "h:mm:ss a z", // force12
3051 "h:mm:ss a", // medium
3052 "HH:mm:ss", // force24
3053 "h:mm:ss a", // force12
3054 "h:mm a", // short
3055 "HH:mm", // force24
3056 "h:mm a", // force12
3057 "EEEE, d MMMM y 'at' h:mm:ss a z", // long_df
3058 "EEEE, d MMMM y 'at' HH:mm:ss z", // force24
3059 "EEEE, d MMMM y 'at' h:mm:ss a z", // force12
3060 "dd/MM/yy, h:mm a", // short_ds
3061 "dd/MM/yy, HH:mm", // force24
3062 "dd/MM/yy, h:mm a", // force12
3063
3064 "h:mm:ss a", // jmmss
3065 "HH:mm:ss", // force24
3066 "h:mm:ss a", // force12
3067 "h:mm:ss a", // jjmmss
3068 "HH:mm:ss", // force24
3069 "HH:mm:ss", // force24 | match hour field length
3070 "h:mm:ss a", // force12
3071 "hh:mm:ss a", // force12 | match hour field length
3072 "hh:mm", // Jmm
3073 "HH:mm", // force24
3074 "hh:mm", // force12
3075 "h:mm:ss a v", // jmsv
3076 "HH:mm:ss v", // force24
3077 "h:mm:ss a v", // force12
3078 "h:mm:ss a z", // jmsz
3079 "HH:mm:ss z", // force24
3080 "h:mm:ss a z", // force12
3081
3082 "h:mm:ss a", // "h:mm:ss"
3083 "HH:mm:ss", //
3084 "a'xx'h:mm:ss d MMM y", // "a'xx'h:mm:ss d MMM y"
3085 "HH:mm:ss d MMM y", //
3086 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' h:mm:ss a 'hrs'"
3087 "EEE, d MMM y 'aha' HH:mm:ss 'hrs'", //
3088 "EEE, d MMM y 'aha' a'xx'h:mm:ss", // "EEE, d MMM y 'aha' a'xx'h:mm:ss"
3089 "EEE, d MMM y 'aha' HH:mm:ss", //
3090 "yyMMddhhmmss", // "yyMMddhhmmss"
3091 "yyMMddHHmmss", //
3092
3093 "h:mm:ss a", // "H:mm:ss"
3094 "H:mm:ss", //
3095 "h:mm:ss a d MMM y", // "H:mm:ss d MMM y"
3096 "H:mm:ss d MMM y", //
3097 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' H:mm:ss 'hrs'"
3098 "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
3099 "EEE, d MMM y 'aha' h'h'mm'm'ss a", // "EEE, d MMM y 'aha' H'h'mm'm'ss"
3100 "EEE, d MMM y 'aha' H'h'mm'm'ss", //
3101
3102 "uuuu-MM-dd h:mm:ss a '+0000'", //
3103
3104 NULL
3105};
3106
3107static const char * remapResults_en_IN_japanese[] = { // rdar://56309604
3108 "h:mm:ss a zzzz", // full
3109 "HH:mm:ss zzzz", // force24
3110 "h:mm:ss a zzzz", // force12
3111 "h:mm:ss a z", // long
3112 "HH:mm:ss z", // force24
3113 "h:mm:ss a z", // force12
3114 "h:mm:ss a", // medium
3115 "HH:mm:ss", // force24
3116 "h:mm:ss a", // force12
3117 "h:mm a", // short
3118 "HH:mm", // force24
3119 "h:mm a", // force12
3120 "EEEE, d MMMM y G 'at' h:mm:ss a z", // long_df
3121 "EEEE, d MMMM y G 'at' HH:mm:ss z", // force24
3122 "EEEE, d MMMM y G 'at' h:mm:ss a z", // force12
3123 "dd/MM/y GGGGG, h:mm a", // short_ds
3124 "dd/MM/y GGGGG, HH:mm", // force24
3125 "dd/MM/y GGGGG, h:mm a", // force12
3126
3127 "h:mm:ss a", // jmmss
3128 "HH:mm:ss", // force24
3129 "h:mm:ss a", // force12
3130 "h:mm:ss a", // jjmmss
3131 "HH:mm:ss", // force24
3132 "HH:mm:ss", // force24 | match hour field length
3133 "h:mm:ss a", // force12
3134 "hh:mm:ss a", // force12 | match hour field length
3135 "hh:mm", // Jmm
3136 "HH:mm", // force24
3137 "hh:mm", // force12
3138 "h:mm:ss a v", // jmsv
3139 "HH:mm:ss v", // force24
3140 "h:mm:ss a v", // force12
3141 "h:mm:ss a z", // jmsz
3142 "HH:mm:ss z", // force24
3143 "h:mm:ss a z", // force12
3144
3145 "h:mm:ss a", // "h:mm:ss"
3146 "HH:mm:ss", //
3147 "a'xx'h:mm:ss d MMM y", // "a'xx'h:mm:ss d MMM y"
3148 "HH:mm:ss d MMM y", //
3149 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' h:mm:ss a 'hrs'"
3150 "EEE, d MMM y 'aha' HH:mm:ss 'hrs'", //
3151 "EEE, d MMM y 'aha' a'xx'h:mm:ss", // "EEE, d MMM y 'aha' a'xx'h:mm:ss"
3152 "EEE, d MMM y 'aha' HH:mm:ss", //
3153 "yyMMddhhmmss", // "yyMMddhhmmss"
3154 "yyMMddHHmmss", //
3155
3156 "h:mm:ss a", // "H:mm:ss"
3157 "H:mm:ss", //
3158 "h:mm:ss a d MMM y", // "H:mm:ss d MMM y"
3159 "H:mm:ss d MMM y", //
3160 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' H:mm:ss 'hrs'"
3161 "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
3162 "EEE, d MMM y 'aha' h'h'mm'm'ss a", // "EEE, d MMM y 'aha' H'h'mm'm'ss"
3163 "EEE, d MMM y 'aha' H'h'mm'm'ss", //
3164
3165 "uuuu-MM-dd h:mm:ss a '+0000'", //
3166
3167 NULL
3168};
3169
3170static const char * remapResults_en_BE[] = { // rdar://56309604
3171 "HH:mm:ss zzzz", // full
3172 "HH:mm:ss zzzz", // force24
3173 "h:mm:ss a zzzz", // force12
3174 "HH:mm:ss z", // long
3175 "HH:mm:ss z", // force24
3176 "h:mm:ss a z", // force12
3177 "HH:mm:ss", // medium
3178 "HH:mm:ss", // force24
3179 "h:mm:ss a", // force12
3180 "HH:mm", // short
3181 "HH:mm", // force24
3182 "h:mm a", // force12
3183 "EEEE, d MMMM y 'at' HH:mm:ss z", // long_df
3184 "EEEE, d MMMM y 'at' HH:mm:ss z", // force24
3185 "EEEE, d MMMM y 'at' h:mm:ss a z", // force12
3186 "dd/MM/y, HH:mm", // short_ds
3187 "dd/MM/y, HH:mm", // force24
3188 "dd/MM/y, h:mm a", // force12
3189
3190 "HH:mm:ss", // jmmss
3191 "HH:mm:ss", // force24
3192 "h:mm:ss a", // force12
3193 "HH:mm:ss", // jjmmss
3194 "HH:mm:ss", // force24
3195 "HH:mm:ss", // force24 | match hour field length
3196 "h:mm:ss a", // force12
3197 "hh:mm:ss a", // force12 | match hour field length
3198 "HH:mm", // Jmm
3199 "HH:mm", // force24
3200 "hh:mm", // force12
3201 "HH:mm:ss v", // jmsv
3202 "HH:mm:ss v", // force24
3203 "h:mm:ss a v", // force12
3204 "HH:mm:ss z", // jmsz
3205 "HH:mm:ss z", // force24
3206 "h:mm:ss a z", // force12
3207
3208 "h:mm:ss a", // "h:mm:ss" force12
3209 "HH:mm:ss", // force24
3210 "a'xx'h:mm:ss d MMM y", // "a'xx'h:mm:ss d MMM y" force12
3211 "HH:mm:ss d MMM y", // force24
3212 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' h:mm:ss a 'hrs'" force12
3213 "EEE, d MMM y 'aha' HH:mm:ss 'hrs'", //
3214 "EEE, d MMM y 'aha' a'xx'h:mm:ss", // "EEE, d MMM y 'aha' a'xx'h:mm:ss"
3215 "EEE, d MMM y 'aha' HH:mm:ss", //
3216 "yyMMddhhmmss", // "yyMMddhhmmss" force12
3217 "yyMMddHHmmss", //
3218
3219 "h:mm:ss a", // "H:mm:ss"
3220 "H:mm:ss", //
3221 "h:mm:ss a d MMM y", // "H:mm:ss d MMM y"
3222 "H:mm:ss d MMM y", //
3223 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' H:mm:ss 'hrs'"
3224 "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
3225 "EEE, d MMM y 'aha' h'h'mm'm'ss a", // "EEE, d MMM y 'aha' H'h'mm'm'ss"
3226 "EEE, d MMM y 'aha' H'h'mm'm'ss", //
3227
3228 "uuuu-MM-dd h:mm:ss a '+0000'", //
3229
3230 NULL
3231};
3232
3233static const char * remapResults_en_BE_japanese[] = { // rdar://56309604
3234 "HH:mm:ss zzzz", // full
3235 "HH:mm:ss zzzz", // force24
3236 "h:mm:ss a zzzz", // force12
3237 "HH:mm:ss z", // long
3238 "HH:mm:ss z", // force24
3239 "h:mm:ss a z", // force12
3240 "HH:mm:ss", // medium
3241 "HH:mm:ss", // force24
3242 "h:mm:ss a", // force12
3243 "HH:mm", // short
3244 "HH:mm", // force24
3245 "h:mm a", // force12
3246 "EEEE, d MMMM y G 'at' HH:mm:ss z", // long_df
3247 "EEEE, d MMMM y G 'at' HH:mm:ss z", // force24
3248 "EEEE, d MMMM y G 'at' h:mm:ss a z", // force12
3249 "dd/MM/y GGGGG, HH:mm", // short_ds
3250 "dd/MM/y GGGGG, HH:mm", // force24
3251 "dd/MM/y GGGGG, h:mm a", // force12
3252
3253 "HH:mm:ss", // jmmss
3254 "HH:mm:ss", // force24
3255 "h:mm:ss a", // force12
3256 "HH:mm:ss", // jjmmss
3257 "HH:mm:ss", // force24
3258 "HH:mm:ss", // force24 | match hour field length
3259 "h:mm:ss a", // force12
3260 "hh:mm:ss a", // force12 | match hour field length
3261 "HH:mm", // Jmm
3262 "HH:mm", // force24
3263 "hh:mm", // force12
3264 "HH:mm:ss v", // jmsv
3265 "HH:mm:ss v", // force24
3266 "h:mm:ss a v", // force12
3267 "HH:mm:ss z", // jmsz
3268 "HH:mm:ss z", // force24
3269 "h:mm:ss a z", // force12
3270
3271 "h:mm:ss a", // "h:mm:ss" force12
3272 "HH:mm:ss", // force24
3273 "a'xx'h:mm:ss d MMM y", // "a'xx'h:mm:ss d MMM y" force12
3274 "HH:mm:ss d MMM y", // force24
3275 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' h:mm:ss a 'hrs'" force12
3276 "EEE, d MMM y 'aha' HH:mm:ss 'hrs'", //
3277 "EEE, d MMM y 'aha' a'xx'h:mm:ss", // "EEE, d MMM y 'aha' a'xx'h:mm:ss"
3278 "EEE, d MMM y 'aha' HH:mm:ss", //
3279 "yyMMddhhmmss", // "yyMMddhhmmss" force12
3280 "yyMMddHHmmss", //
3281
3282 "h:mm:ss a", // "H:mm:ss"
3283 "H:mm:ss", //
3284 "h:mm:ss a d MMM y", // "H:mm:ss d MMM y"
3285 "H:mm:ss d MMM y", //
3286 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' H:mm:ss 'hrs'"
3287 "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
3288 "EEE, d MMM y 'aha' h'h'mm'm'ss a", // "EEE, d MMM y 'aha' H'h'mm'm'ss"
3289 "EEE, d MMM y 'aha' H'h'mm'm'ss", //
3290
3291 "uuuu-MM-dd h:mm:ss a '+0000'", //
3292
3293 NULL
3294};
3295
b331163b
A
3296typedef struct {
3297 const char * locale;
3298 const char ** resultsPtr;
3299} RemapPatternLocaleResults;
3300
3301static const RemapPatternLocaleResults remapLocResults[] = {
3302 { "root", remapResults_root },
3303 { "en", remapResults_en },
3304 { "ja", remapResults_ja },
3305 { "ko", remapResults_ko },
3306 { "th", remapResults_th },
3307 { "hi", remapResults_hi },
f3c0d7a5 3308 { "ar", remapResults_ar },
0f5d89e8 3309 { "en_IL", remapResults_en_IL },
3d1f044b 3310 { "es_PR@calendar=japanese", remapResults_es_PR_japanese },
1a147d09
A
3311 { "en_IN", remapResults_en_IN },
3312 { "en_IN@calendar=japanese", remapResults_en_IN_japanese },
3313 { "en_BE", remapResults_en_BE },
3314 { "en_BE@calendar=japanese", remapResults_en_BE_japanese },
b331163b
A
3315 { NULL, NULL }
3316};
3317
3318enum { kUBufRemapMax = 64, kBBufRemapMax = 128 };
3319
3320static void TestRemapPatternWithOpts(void) { /* Apple-specific */
3321 const RemapPatternLocaleResults * locResPtr;
3322 for (locResPtr = remapLocResults; locResPtr->locale != NULL; locResPtr++) {
3323 UErrorCode status = U_ZERO_ERROR;
3324 UDateTimePatternGenerator* dtpg = udatpg_open(locResPtr->locale, &status);
3325 if ( U_FAILURE(status) ) {
3326 log_data_err("udatpg_open fails for locale %s, status %s (Are you missing data?)\n", locResPtr->locale, u_errorName(status));
3327 } else {
3328 const RemapPatternTestItem * testItemPtr = remapPatItems;
3329 const char ** expResultsPtr = locResPtr->resultsPtr;
3330 for (; testItemPtr->pattern != NULL && *expResultsPtr != NULL; testItemPtr++, expResultsPtr++) {
3331 UChar uskel[kUBufRemapMax];
3332 UChar upatn[kUBufRemapMax];
3333 UChar uget[kUBufRemapMax];
3334 UChar uexp[kUBufRemapMax];
3335 int32_t uelen, ulen = 0;
3336
3337 status = U_ZERO_ERROR;
3338 if (testItemPtr->testtype >= 0) {
3339 UDateFormatStyle timeStyle = (UDateFormatStyle)((int32_t)testItemPtr->testtype & 0x03);
3340 UDateFormatStyle dateStyle = (UDateFormatStyle)((((int32_t)testItemPtr->testtype >> 2) & 0x07) - 1);
3341 UDateFormat* dfmt = udat_open(timeStyle, dateStyle, locResPtr->locale, NULL, 0, NULL, 0, &status);
3342 if ( U_FAILURE(status) ) {
3343 log_data_err("udat_open fails for locale %s, status %s (Are you missing data?)\n", locResPtr->locale, u_errorName(status));
3344 continue;
3345 } else {
3346 ulen = udat_toPattern(dfmt, FALSE, upatn, kUBufRemapMax, &status);
3347 udat_close(dfmt);
3348 if ( U_FAILURE(status) ) {
3349 log_err("udat_toPattern fails for locale %s, status %s\n", locResPtr->locale, u_errorName(status));
3350 continue;
3351 }
3352 }
3353 } else if (testItemPtr->testtype == REMAP_TESTTYPE_SKELETON) {
3354 u_strFromUTF8(uskel, kUBufRemapMax, &ulen, testItemPtr->pattern, -1, &status);
3355 ulen = udatpg_getBestPatternWithOptions(dtpg, uskel, ulen, (UDateTimePatternMatchOptions)testItemPtr->options, upatn, kUBufRemapMax, &status);
3356 if ( U_FAILURE(status) ) {
3357 log_err("udatpg_getBestPatternWithOptions fails for locale %s, skeleton \"%s\": status %s\n", locResPtr->locale, testItemPtr->pattern, u_errorName(status));
3358 continue;
3359 }
3360 } else {
3361 ulen = u_unescape(testItemPtr->pattern, upatn, kUBufRemapMax);
3362 }
3363 uelen = u_unescape(*expResultsPtr, uexp, kUBufRemapMax);
3364 ulen = uadatpg_remapPatternWithOptions(dtpg, upatn, ulen, (UDateTimePatternMatchOptions)testItemPtr->options, uget, kUBufRemapMax, &status);
3365 if ( U_FAILURE(status) ) {
3366 log_err("uadatpg_remapPatternWithOptions fails for locale %s pattern \"%s\" opts %08X: status %s\n",
3367 locResPtr->locale, testItemPtr->pattern, testItemPtr->options, u_errorName(status));
3368 } else if (uelen != ulen || u_strncmp(uget, uexp, ulen) != 0) {
3369 char bebuf[kBBufRemapMax];
3370 char bbuf[kBBufRemapMax];
3371 UErrorCode tempStatus = U_ZERO_ERROR;
3372 u_strToUTF8(bebuf, kBBufRemapMax, NULL, uexp, uelen, &tempStatus);
3373 u_strToUTF8(bbuf, kBBufRemapMax, NULL, uget, ulen, &tempStatus);
3374 log_err("uadatpg_remapPatternWithOptions for locale %s pattern \"%s\" opts %08X: expect \"%s\", get \"%s\"\n",
3375 locResPtr->locale, testItemPtr->pattern, testItemPtr->options, bebuf, bbuf);
3376 }
3377 }
3378 udatpg_close(dtpg);
3379 }
3380 }
3381}
3382
3d1f044b
A
3383#if ADD_ALLOC_TEST
3384#include <stdio.h>
3385#include <unistd.h>
3386static const UChar* tzName = u"US/Pacific";
3387static const UDate udatToUse = 1290714600000.0; // Thurs, Nov. 25, 2010 11:50:00 AM PT
3388static const UChar* dateStrEST = u"Thursday, November 25, 2010 at 11:50:00 AM EST";
3389enum { kUCharsOutMax = 128, kBytesOutMax = 256, kRepeatCount = 100, SLEEPSECS = 6 };
3390
3391static void TestPerf(void) {
3392 UDateFormat *udatfmt;
3393 UErrorCode status = U_ZERO_ERROR;
3394 printf("\n# TestPerf start; sleeping %d seconds to check heap.\n", SLEEPSECS); sleep(SLEEPSECS);
3395 udatfmt = udat_open(UDAT_FULL, UDAT_FULL, "en_US", tzName, -1, NULL, 0, &status);
3396 if ( U_SUCCESS(status) ) {
3397 UChar outUChars[kUCharsOutMax];
3398 int32_t count, datlen, datlen2, parsePos;
3399 UDate dateParsed, dateParsed2;
3400
3401 datlen = udat_format(udatfmt, udatToUse, outUChars, kUCharsOutMax, NULL, &status);
3402 printf("# TestPerf after first open & format, status %d; sleeping %d seconds to check heap.\n", status, SLEEPSECS); sleep(SLEEPSECS);
3403
3404 for (count = kRepeatCount; count-- > 0;) {
3405 status = U_ZERO_ERROR;
3406 datlen2 = udat_format(udatfmt, udatToUse, outUChars, kUCharsOutMax, NULL, &status);
3407 if ( U_FAILURE(status) || datlen2 != datlen ) {
3408 printf("# TestPerf udat_format unexpected result.\n");
3409 break;
3410 }
3411 }
3412 printf("# TestPerf after many more format, status %d; sleeping %d seconds to check heap.\n", status, SLEEPSECS); sleep(SLEEPSECS);
3413
3414 udat_setLenient(udatfmt, TRUE);
3415 status = U_ZERO_ERROR;
3416 parsePos = 0;
3417 dateParsed = udat_parse(udatfmt, dateStrEST, -1, &parsePos, &status);
3418 printf("# TestPerf after first parse lenient diff style/zone, status %d; sleeping %d seconds to check heap.\n", status, SLEEPSECS); sleep(SLEEPSECS);
3419
3420 for (count = kRepeatCount; count-- > 0;) {
3421 status = U_ZERO_ERROR;
3422 parsePos = 0;
3423 dateParsed2 = udat_parse(udatfmt, dateStrEST, -1, &parsePos, &status);
3424 if ( U_FAILURE(status) || dateParsed2 != dateParsed ) {
3425 printf("# TestPerf udat_parse unexpected result.\n");
3426 break;
3427 }
3428 }
3429 printf("# TestPerf after many more parse, status %d; sleeping %d seconds to check heap.\n", status, SLEEPSECS); sleep(SLEEPSECS);
3430
3431 udat_close(udatfmt);
3432 printf("# TestPerf after udat_close; sleeping %d seconds to check heap.\n", SLEEPSECS); sleep(SLEEPSECS);
3433 }
3434}
3435#endif /* #if ADD_ALLOC_TEST */
3436
3437#if WRITE_HOUR_MISMATCH_ERRS
3438// WriteHourMismatchErrs stuff 52980140
3439#include <stdio.h>
3440#include <string.h>
3441#include <stdlib.h>
3442
3443static const char* langs[] = {
3444 "ar", "ca", "cs", "da", "de", "el", "en", "es", "fi", "fr", "he",
3445 "hi", "hr", "hu", "id", "it", "ja", "ko", "ms", "nb", "nl", "pl",
3446 "pt", "ro", "ru", "sk", "sv", "th", "tr", "uk", "vi", "zh" }; // handle "yue" separately
3447enum { kNlangs = sizeof(langs)/sizeof(langs[0]) };
3448
3449static const char* cals[] = {
3450 "buddhist",
3451 "chinese",
3452 "coptic",
3453 "ethiopic",
3454 "gregorian",
3455 "hebrew",
3456 "indian",
3457 "islamic-umalqura",
3458 "islamic",
3459 "japanese",
3460 "persian",
3461 NULL
3462};
3463
3464enum { kLBufMax = 63 };
3465
3466static int compKeys(const void* keyval, const void* baseval) {
3467 const char* keystr = (const char*)keyval;
3468 const char* basestr = *(const char**)baseval;
3469 return strcmp(keystr,basestr);
3470}
3471
3472static UBool useLocale(const char* locale) {
3473 if (strncmp(locale, "yue", 3) == 0) {
3474 return TRUE;
3475 }
3476 if (locale[2]==0 || locale[2]=='_') {
3477 char lang[3] = {0,0,0};
3478 strncpy(lang,locale,2);
3479 if (bsearch(&lang, langs, kNlangs, sizeof(char*), compKeys) != NULL) {
3480 return TRUE;
3481 }
3482 }
3483 return FALSE;
3484}
3485
3486static UBool patIsBad(const UChar* ubuf) {
3487 return (u_strchr(ubuf,0x251C)!=NULL || u_strchr(ubuf,0x2524)!=NULL || u_strstr(ubuf,u": ")!=NULL);
3488}
3489
3490
3491static void WriteHourMismatchErrs(void) { /* Apple-specific */
3492 int32_t iloc, nloc = uloc_countAvailable();
3493 int32_t errcnt = 0;
3494 printf("# uloc_countAvailable: %d\n", nloc);
3495 for (iloc = 0; iloc < nloc; iloc++) {
3496 const char* locale = uloc_getAvailable(iloc);
3497 if (useLocale(locale)) {
3498 const char** calsPtr = cals;
3499 const char* cal;
3500 while ((cal = *calsPtr++) != NULL) {
3501 char fullLocale[kLBufMax+1];
3502 UErrorCode status = U_ZERO_ERROR;
3503 strncpy(fullLocale, locale, kLBufMax);
3504 fullLocale[kLBufMax] = 0;
3505 uloc_setKeywordValue("calendar", cal, fullLocale, kLBufMax, &status);
3506 if ( U_SUCCESS(status) ) {
3507 fullLocale[kLBufMax] = 0;
3508 UDateFormat* udat = udat_open(UDAT_SHORT, UDAT_NONE, fullLocale, NULL, 0, NULL, 0, &status);
3509 UDateTimePatternGenerator* udatpg = udatpg_open(fullLocale, &status);
3510 if ( U_FAILURE(status) ) {
3511 printf("# udat_open/udatpg_open for locale %s: %s\n", fullLocale, u_errorName(status));
3512 } else {
3513 UChar ubufs[kUBufMax];
3514 UChar ubufp[kUBufMax];
3515 char bbufs[kBBufMax];
3516 char bbufpj[kBBufMax];
3517 char bbufpH[kBBufMax];
3518 char bbufph[kBBufMax];
3519 int32_t ulen;
3520 int8_t errors[4] = {0,0,0,0};
3521
3522 status = U_ZERO_ERROR;
3523 ulen = udat_toPattern(udat, FALSE, ubufs, kUBufMax, &status);
3524 u_strToUTF8(bbufs, kBBufMax, NULL, ubufs, ulen, &status);
3525 if ( U_FAILURE(status) ) {
3526 printf("# udat_toPattern for locale %s: %s\n", fullLocale, u_errorName(status));
3527 strcpy(bbufs, "****");
3528 errors[0] = 3;
3529 } else if (patIsBad(ubufs)) {
3530 errors[0] = 2;
3531 }
3532
3533 status = U_ZERO_ERROR;
3534 ulen = udatpg_getBestPattern(udatpg, u"jmm", 3, ubufp, kUBufMax, &status);
3535 u_strToUTF8(bbufpj, kBBufMax, NULL, ubufp, ulen, &status);
3536 if ( U_FAILURE(status) ) {
3537 printf("# udatpg_getBestPat jmm for locale %s: %s\n", fullLocale, u_errorName(status));
3538 strcpy(bbufpj, "****");
3539 errors[1] = 3;
3540 } else if (patIsBad(ubufp)) {
3541 errors[1] = 2;
3542 } else if (errors[0] == 0 && u_strcmp(ubufp,ubufs) != 0) {
3543 errors[0] = 1;
3544 }
3545
3546 status = U_ZERO_ERROR;
3547 ulen = udatpg_getBestPattern(udatpg, u"Hmm", 3, ubufp, kUBufMax, &status);
3548 u_strToUTF8(bbufpH, kBBufMax, NULL, ubufp, ulen, &status);
3549 if ( U_FAILURE(status) ) {
3550 printf("# udatpg_getBestPat Hmm for locale %s: %s\n", fullLocale, u_errorName(status));
3551 strcpy(bbufpH, "****");
3552 errors[2] = 3;
3553 } else if (patIsBad(ubufp)) {
3554 errors[2] = 2;
3555 }
3556
3557 status = U_ZERO_ERROR;
3558 ulen = udatpg_getBestPattern(udatpg, u"hmm", 3, ubufp, kUBufMax, &status);
3559 u_strToUTF8(bbufph, kBBufMax, NULL, ubufp, ulen, &status);
3560 if ( U_FAILURE(status) ) {
3561 printf("# udatpg_getBestPat hmm for locale %s: %s\n", fullLocale, u_errorName(status));
3562 strcpy(bbufph, "****");
3563 errors[3] = 3;
3564 } else if (patIsBad(ubufp)) {
3565 errors[3] = 2;
3566 }
3567
3568 if ( errors[0] || errors[1] || errors[2] || errors[3]) {
3569 printf("%-36s\tshr-%d %-8s\tjmm-%d %-18s\tHmm-%d %-18s\thmm-%d %-18s\n", fullLocale,
3570 errors[0], bbufs, errors[1], bbufpj, errors[2], bbufpH, errors[3], bbufph);
3571 errcnt++;
3572 }
3573
3574 udatpg_close(udatpg);
3575 udat_close(udat);
3576 }
3577 }
3578 }
3579 }
3580 }
3581 printf("# total err lines: %d\n", errcnt);
3582}
3583#endif /* #if WRITE_HOUR_MISMATCH_ERRS */
3584
b75a7d8f 3585#endif /* #if !UCONFIG_NO_FORMATTING */