]> git.saurik.com Git - apple/icu.git/blame_incremental - icuSources/test/cintltst/cdattst.c
ICU-57149.0.1.tar.gz
[apple/icu.git] / icuSources / test / cintltst / cdattst.c
... / ...
CommitLineData
1/********************************************************************
2 * COPYRIGHT:
3 * Copyright (c) 1997-2016, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ********************************************************************/
6/********************************************************************************
7*
8* File CDATTST.C
9*
10* Modification History:
11* Name Description
12* Madhu Katragadda Creation
13*********************************************************************************
14*/
15
16/* C API TEST FOR DATE FORMAT */
17
18#include "unicode/utypes.h"
19
20#if !UCONFIG_NO_FORMATTING
21
22#include "unicode/uloc.h"
23#include "unicode/udat.h"
24#include "unicode/udatpg.h"
25#include "unicode/ucal.h"
26#include "unicode/unum.h"
27#include "unicode/ustring.h"
28#include "unicode/ufieldpositer.h"
29#include "cintltst.h"
30#include "cdattst.h"
31#include "cformtst.h"
32#include "cmemory.h"
33#include "unicode/uatimeunitformat.h" /* Apple-specific */
34
35#include <math.h>
36
37static void TestExtremeDates(void);
38static void TestAllLocales(void);
39static void TestRelativeCrash(void);
40static void TestContext(void);
41static void TestCalendarDateParse(void);
42static void TestParseErrorReturnValue(void);
43static void TestFormatForFields(void);
44static void TestStandardPatterns(void);
45static void TestApplyPatnOverridesTimeSep(void);
46static void Test12HrFormats(void);
47static void TestTimeUnitFormat(void); /* Apple-specific */
48static void TestRemapPatternWithOpts(void); /* Apple-specific */
49
50void addDateForTest(TestNode** root);
51
52#define TESTCASE(x) addTest(root, &x, "tsformat/cdattst/" #x)
53
54void addDateForTest(TestNode** root)
55{
56 TESTCASE(TestDateFormat);
57 TESTCASE(TestRelativeDateFormat);
58 TESTCASE(TestSymbols);
59 TESTCASE(TestDateFormatCalendar);
60 TESTCASE(TestExtremeDates);
61 TESTCASE(TestAllLocales);
62 TESTCASE(TestRelativeCrash);
63 TESTCASE(TestContext);
64 TESTCASE(TestCalendarDateParse);
65 TESTCASE(TestOverrideNumberFormat);
66 TESTCASE(TestParseErrorReturnValue);
67 TESTCASE(TestFormatForFields);
68 TESTCASE(TestStandardPatterns);
69 TESTCASE(TestApplyPatnOverridesTimeSep);
70 TESTCASE(Test12HrFormats);
71 TESTCASE(TestTimeUnitFormat); /* Apple-specific */
72 TESTCASE(TestRemapPatternWithOpts); /* Apple-specific */
73}
74/* Testing the DateFormat API */
75static void TestDateFormat()
76{
77 UDateFormat *def, *fr, *it, *de, *def1, *fr_pat;
78 UDateFormat *any;
79 UDateFormat *copy;
80 UErrorCode status = U_ZERO_ERROR;
81 UChar* result = NULL;
82 const UCalendar *cal;
83 const UNumberFormat *numformat1, *numformat2;
84 UNumberFormat *adoptNF;
85 UChar temp[50];
86 int32_t numlocales;
87 UDate d1;
88 int i;
89 int32_t resultlength;
90 int32_t resultlengthneeded;
91 int32_t parsepos;
92 UDate d = 837039928046.0;
93 double num = -10456.37;
94 /*const char* str="yyyy.MM.dd G 'at' hh:mm:ss z";
95 const char t[]="2/3/76 2:50 AM";*/
96 /*Testing udat_open() to open a dateformat */
97
98 ctest_setTimeZone(NULL, &status);
99
100 log_verbose("\nTesting udat_open() with various parameters\n");
101 fr = udat_open(UDAT_FULL, UDAT_DEFAULT, "fr_FR", NULL,0, NULL, 0,&status);
102 if(U_FAILURE(status))
103 {
104 log_data_err("FAIL: error in creating the dateformat using full time style with french locale -> %s (Are you missing data?)\n",
105 myErrorName(status) );
106 return;
107 }
108 /* this is supposed to open default date format, but later on it treats it like it is "en_US"
109 - very bad if you try to run the tests on machine where default locale is NOT "en_US" */
110 /* def = udat_open(UDAT_SHORT, UDAT_SHORT, NULL, NULL, 0, &status); */
111 def = udat_open(UDAT_SHORT, UDAT_SHORT, "en_US", NULL, 0,NULL, 0, &status);
112 if(U_FAILURE(status))
113 {
114 log_err("FAIL: error in creating the dateformat using short date and time style\n %s\n",
115 myErrorName(status) );
116 return;
117 }
118 it = udat_open(UDAT_DEFAULT, UDAT_MEDIUM, "it_IT", NULL, 0, NULL, 0,&status);
119 if(U_FAILURE(status))
120 {
121 log_err("FAIL: error in creating the dateformat using medium date style with italian locale\n %s\n",
122 myErrorName(status) );
123 return;
124 }
125 de = udat_open(UDAT_LONG, UDAT_LONG, "de_DE", NULL, 0, NULL, 0,&status);
126 if(U_FAILURE(status))
127 {
128 log_err("FAIL: error in creating the dateformat using long time and date styles with german locale\n %s\n",
129 myErrorName(status));
130 return;
131 }
132 /*creating a default dateformat */
133 def1 = udat_open(UDAT_SHORT, UDAT_SHORT, NULL, NULL, 0,NULL, 0, &status);
134 if(U_FAILURE(status))
135 {
136 log_err("FAIL: error in creating the dateformat using short date and time style\n %s\n",
137 myErrorName(status) );
138 return;
139 }
140
141
142 /*Testing udat_getAvailable() and udat_countAvailable()*/
143 log_verbose("\nTesting getAvailableLocales and countAvailable()\n");
144 numlocales=udat_countAvailable();
145 /* use something sensible w/o hardcoding the count */
146 if(numlocales < 0)
147 log_data_err("FAIL: error in countAvailable\n");
148 log_verbose("The number of locales for which date/time formatting patterns are available is %d\n", numlocales);
149
150 for(i=0;i<numlocales;i++) {
151 UErrorCode subStatus = U_ZERO_ERROR;
152 log_verbose("Testing open of %s\n", udat_getAvailable(i));
153 any = udat_open(UDAT_SHORT, UDAT_SHORT, udat_getAvailable(i), NULL ,0, NULL, 0, &subStatus);
154 if(U_FAILURE(subStatus)) {
155 log_data_err("FAIL: date format %s (getAvailable(%d)) is not instantiable: %s\n", udat_getAvailable(i), i, u_errorName(subStatus));
156 }
157 udat_close(any);
158 }
159
160 /*Testing udat_clone()*/
161 log_verbose("\nTesting the udat_clone() function of date format\n");
162 copy=udat_clone(def, &status);
163 if(U_FAILURE(status)){
164 log_err("Error in creating the clone using udat_clone: %s\n", myErrorName(status) );
165 }
166 /*if(def != copy)
167 log_err("Error in udat_clone");*/ /*how should i check for equality???? */
168
169 /*Testing udat_format()*/
170 log_verbose("\nTesting the udat_format() function of date format\n");
171 u_uastrcpy(temp, "7/10/96, 4:05 PM");
172 /*format using def */
173 resultlength=0;
174 resultlengthneeded=udat_format(def, d, NULL, resultlength, NULL, &status);
175 if(status==U_BUFFER_OVERFLOW_ERROR)
176 {
177 status=U_ZERO_ERROR;
178 resultlength=resultlengthneeded+1;
179 if(result != NULL) {
180 free(result);
181 result = NULL;
182 }
183 result=(UChar*)malloc(sizeof(UChar) * resultlength);
184 udat_format(def, d, result, resultlength, NULL, &status);
185 }
186 if(U_FAILURE(status) || !result)
187 {
188 log_err("FAIL: Error in formatting using udat_format(.....) %s\n", myErrorName(status) );
189 return;
190 }
191 else
192 log_verbose("PASS: formatting successful\n");
193 if(u_strcmp(result, temp)==0)
194 log_verbose("PASS: Date Format for US locale successful using udat_format()\n");
195 else {
196 char xbuf[2048];
197 char gbuf[2048];
198 u_austrcpy(xbuf, temp);
199 u_austrcpy(gbuf, result);
200 log_err("FAIL: Date Format for US locale failed using udat_format() - expected %s got %s\n", xbuf, gbuf);
201 }
202 /*format using fr */
203
204 u_unescape("10 juil. 1996 \\u00E0 16:05:28 heure d\\u2019\\u00E9t\\u00E9 du Pacifique", temp, 50);
205 if(result != NULL) {
206 free(result);
207 result = NULL;
208 }
209 result=myDateFormat(fr, d);
210 if(u_strcmp(result, temp)==0)
211 log_verbose("PASS: Date Format for french locale successful using udat_format()\n");
212 else
213 log_data_err("FAIL: Date Format for french locale failed using udat_format().\n" );
214
215 /*format using it */
216 u_uastrcpy(temp, "10 lug 1996, 16:05:28");
217
218 {
219 UChar *fmtted;
220 char g[100];
221 char x[100];
222
223 fmtted = myDateFormat(it,d);
224 u_austrcpy(g, fmtted);
225 u_austrcpy(x, temp);
226 if(u_strcmp(fmtted, temp)==0) {
227 log_verbose("PASS: Date Format for italian locale successful uisng udat_format() - wanted %s, got %s\n", x, g);
228 } else {
229 log_data_err("FAIL: Date Format for italian locale failed using udat_format() - wanted %s, got %s\n", x, g);
230 }
231 }
232
233 /*Testing parsing using udat_parse()*/
234 log_verbose("\nTesting parsing using udat_parse()\n");
235 u_uastrcpy(temp,"2/3/76, 2:50 AM");
236 parsepos=0;
237 status=U_ZERO_ERROR;
238
239 d1=udat_parse(def, temp, u_strlen(temp), &parsepos, &status);
240 if(U_FAILURE(status))
241 {
242 log_err("FAIL: Error in parsing using udat_parse(.....) %s\n", myErrorName(status) );
243 }
244 else
245 log_verbose("PASS: parsing succesful\n");
246 /*format it back and check for equality */
247
248
249 if(u_strcmp(myDateFormat(def, d1),temp)!=0)
250 log_err("FAIL: error in parsing\n");
251
252 /*Testing parsing using udat_parse()*/
253 log_verbose("\nTesting parsing using udat_parse()\n");
254 u_uastrcpy(temp,"2/Don't parse this part");
255 status=U_ZERO_ERROR;
256
257 d1=udat_parse(def, temp, u_strlen(temp), NULL, &status);
258 if(status != U_PARSE_ERROR)
259 {
260 log_err("FAIL: udat_parse(\"bad string\") passed when it should have failed\n");
261 }
262 else
263 log_verbose("PASS: parsing succesful\n");
264
265
266
267 /*Testing udat_openPattern() */
268 status=U_ZERO_ERROR;
269 log_verbose("\nTesting the udat_openPattern with a specified pattern\n");
270 /*for french locale */
271 fr_pat=udat_open(UDAT_PATTERN, UDAT_PATTERN,"fr_FR",NULL,0,temp, u_strlen(temp), &status);
272 if(U_FAILURE(status))
273 {
274 log_err("FAIL: Error in creating a date format using udat_openPattern \n %s\n",
275 myErrorName(status) );
276 }
277 else
278 log_verbose("PASS: creating dateformat using udat_openPattern() succesful\n");
279
280
281 /*Testing applyPattern and toPattern */
282 log_verbose("\nTesting applyPattern and toPattern()\n");
283 udat_applyPattern(def1, FALSE, temp, u_strlen(temp));
284 log_verbose("Extracting the pattern\n");
285
286 resultlength=0;
287 resultlengthneeded=udat_toPattern(def1, FALSE, NULL, resultlength, &status);
288 if(status==U_BUFFER_OVERFLOW_ERROR)
289 {
290 status=U_ZERO_ERROR;
291 resultlength=resultlengthneeded + 1;
292 result=(UChar*)malloc(sizeof(UChar) * resultlength);
293 udat_toPattern(def1, FALSE, result, resultlength, &status);
294 }
295 if(U_FAILURE(status))
296 {
297 log_err("FAIL: error in extracting the pattern from UNumberFormat\n %s\n",
298 myErrorName(status) );
299 }
300 if(u_strcmp(result, temp)!=0)
301 log_err("FAIL: Error in extracting the pattern\n");
302 else
303 log_verbose("PASS: applyPattern and toPattern work fine\n");
304
305 if(result != NULL) {
306 free(result);
307 result = NULL;
308 }
309
310
311 /*Testing getter and setter functions*/
312 /*isLenient and setLenient()*/
313 log_verbose("\nTesting the isLenient and setLenient properties\n");
314 udat_setLenient(fr, udat_isLenient(it));
315 if(udat_isLenient(fr) != udat_isLenient(it))
316 log_err("ERROR: setLenient() failed\n");
317 else
318 log_verbose("PASS: setLenient() successful\n");
319
320
321 /*Test get2DigitYearStart set2DigitYearStart */
322 log_verbose("\nTesting the get and set 2DigitYearStart properties\n");
323 d1= udat_get2DigitYearStart(fr_pat,&status);
324 if(U_FAILURE(status)) {
325 log_err("ERROR: udat_get2DigitYearStart failed %s\n", myErrorName(status) );
326 }
327 status = U_ZERO_ERROR;
328 udat_set2DigitYearStart(def1 ,d1, &status);
329 if(U_FAILURE(status)) {
330 log_err("ERROR: udat_set2DigitYearStart failed %s\n", myErrorName(status) );
331 }
332 if(udat_get2DigitYearStart(fr_pat, &status) != udat_get2DigitYearStart(def1, &status))
333 log_err("FAIL: error in set2DigitYearStart\n");
334 else
335 log_verbose("PASS: set2DigitYearStart successful\n");
336 /*try setting it to another value */
337 udat_set2DigitYearStart(de, 2000.0, &status);
338 if(U_FAILURE(status)){
339 log_verbose("ERROR: udat_set2DigitYearStart failed %s\n", myErrorName(status) );
340 }
341 if(udat_get2DigitYearStart(de, &status) != 2000)
342 log_err("FAIL: error in set2DigitYearStart\n");
343 else
344 log_verbose("PASS: set2DigitYearStart successful\n");
345
346
347
348 /*Test getNumberFormat() and setNumberFormat() */
349 log_verbose("\nTesting the get and set NumberFormat properties of date format\n");
350 numformat1=udat_getNumberFormat(fr_pat);
351 udat_setNumberFormat(def1, numformat1);
352 numformat2=udat_getNumberFormat(def1);
353 if(u_strcmp(myNumformat(numformat1, num), myNumformat(numformat2, num)) !=0)
354 log_err("FAIL: error in setNumberFormat or getNumberFormat()\n");
355 else
356 log_verbose("PASS:setNumberFormat and getNumberFormat succesful\n");
357
358 /*Test getNumberFormat() and adoptNumberFormat() */
359 log_verbose("\nTesting the get and adopt NumberFormat properties of date format\n");
360 adoptNF= unum_open(UNUM_DEFAULT, NULL, 0, NULL, NULL, &status);
361 udat_adoptNumberFormat(def1, adoptNF);
362 numformat2=udat_getNumberFormat(def1);
363 if(u_strcmp(myNumformat(adoptNF, num), myNumformat(numformat2, num)) !=0)
364 log_err("FAIL: error in adoptNumberFormat or getNumberFormat()\n");
365 else
366 log_verbose("PASS:adoptNumberFormat and getNumberFormat succesful\n");
367
368 /*try setting the number format to another format */
369 numformat1=udat_getNumberFormat(def);
370 udat_setNumberFormat(def1, numformat1);
371 numformat2=udat_getNumberFormat(def1);
372 if(u_strcmp(myNumformat(numformat1, num), myNumformat(numformat2, num)) !=0)
373 log_err("FAIL: error in setNumberFormat or getNumberFormat()\n");
374 else
375 log_verbose("PASS: setNumberFormat and getNumberFormat succesful\n");
376
377
378
379 /*Test getCalendar and setCalendar*/
380 log_verbose("\nTesting the udat_getCalendar() and udat_setCalendar() properties\n");
381 cal=udat_getCalendar(fr_pat);
382
383
384 udat_setCalendar(def1, cal);
385 if(!ucal_equivalentTo(udat_getCalendar(fr_pat), udat_getCalendar(def1)))
386 log_err("FAIL: Error in setting and getting the calendar\n");
387 else
388 log_verbose("PASS: getting and setting calendar successful\n");
389
390 if(result!=NULL) {
391 free(result);
392 }
393
394 /*Closing the UDateForamt */
395 udat_close(def);
396 udat_close(fr);
397 udat_close(it);
398 udat_close(de);
399 udat_close(def1);
400 udat_close(fr_pat);
401 udat_close(copy);
402
403 ctest_resetTimeZone();
404}
405
406/*
407Test combined relative date formatting (relative date + non-relative time).
408This is a bit tricky since we can't have static test data for comparison, the
409relative date formatting is relative to the time the tests are run. We generate
410the data for comparison dynamically. However, the tests could fail if they are
411run right at midnight Pacific time and the call to ucal_getNow() is before midnight
412while the calls to udat_format are after midnight or span midnight.
413*/
414static const UDate dayInterval = 24.0*60.0*60.0*1000.0;
415static const UChar trdfZone[] = { 0x0055, 0x0053, 0x002F, 0x0050, 0x0061, 0x0063, 0x0069, 0x0066, 0x0069, 0x0063, 0 }; /* US/Pacific */
416static const char trdfLocale[] = "en_US";
417static const UChar minutesPatn[] = { 0x006D, 0x006D, 0 }; /* "mm" */
418static const UChar monthLongPatn[] = { 0x004D, 0x004D, 0x004D, 0x004D, 0 }; /* "MMMM" */
419static const UChar monthMediumPatn[] = { 0x004D, 0x004D, 0x004D, 0 }; /* "MMM" */
420static const UChar monthShortPatn[] = { 0x004D, 0 }; /* "M" */
421static const UDateFormatStyle dateStylesList[] = { UDAT_FULL, UDAT_LONG, UDAT_MEDIUM, UDAT_SHORT, UDAT_NONE };
422static const UChar *monthPatnsList[] = { monthLongPatn, monthLongPatn, monthMediumPatn, monthShortPatn, NULL };
423static const UChar newTimePatn[] = { 0x0048, 0x0048, 0x002C, 0x006D, 0x006D, 0 }; /* "HH,mm" */
424static const UChar minutesStr[] = { 0x0034, 0x0039, 0 }; /* "49", minutes string to search for in output */
425enum { kDateOrTimeOutMax = 96, kDateAndTimeOutMax = 192 };
426
427static const UDate minutesTolerance = 2 * 60.0 * 1000.0;
428static const UDate daysTolerance = 2 * 24.0 * 60.0 * 60.0 * 1000.0;
429
430static void TestRelativeDateFormat()
431{
432 UDate today = 0.0;
433 const UDateFormatStyle * stylePtr;
434 const UChar ** monthPtnPtr;
435 UErrorCode status = U_ZERO_ERROR;
436 UCalendar * ucal = ucal_open(trdfZone, -1, trdfLocale, UCAL_GREGORIAN, &status);
437 if ( U_SUCCESS(status) ) {
438 int32_t year, month, day;
439 ucal_setMillis(ucal, ucal_getNow(), &status);
440 year = ucal_get(ucal, UCAL_YEAR, &status);
441 month = ucal_get(ucal, UCAL_MONTH, &status);
442 day = ucal_get(ucal, UCAL_DATE, &status);
443 ucal_setDateTime(ucal, year, month, day, 18, 49, 0, &status); /* set to today at 18:49:00 */
444 today = ucal_getMillis(ucal, &status);
445 ucal_close(ucal);
446 }
447 if ( U_FAILURE(status) || today == 0.0 ) {
448 log_data_err("Generate UDate for a specified time today fails, error %s - (Are you missing data?)\n", myErrorName(status) );
449 return;
450 }
451 for (stylePtr = dateStylesList, monthPtnPtr = monthPatnsList; *stylePtr != UDAT_NONE; ++stylePtr, ++monthPtnPtr) {
452 UDateFormat* fmtRelDateTime;
453 UDateFormat* fmtRelDate;
454 UDateFormat* fmtTime;
455 int32_t dayOffset, limit;
456 UFieldPosition fp;
457 UChar strDateTime[kDateAndTimeOutMax];
458 UChar strDate[kDateOrTimeOutMax];
459 UChar strTime[kDateOrTimeOutMax];
460 UChar * strPtr;
461 int32_t dtpatLen;
462
463 fmtRelDateTime = udat_open(UDAT_SHORT, *stylePtr | UDAT_RELATIVE, trdfLocale, trdfZone, -1, NULL, 0, &status);
464 if ( U_FAILURE(status) ) {
465 log_data_err("udat_open timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s (Are you missing data?)\n", *stylePtr, myErrorName(status) );
466 continue;
467 }
468 fmtRelDate = udat_open(UDAT_NONE, *stylePtr | UDAT_RELATIVE, trdfLocale, trdfZone, -1, NULL, 0, &status);
469 if ( U_FAILURE(status) ) {
470 log_err("udat_open timeStyle NONE dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
471 udat_close(fmtRelDateTime);
472 continue;
473 }
474 fmtTime = udat_open(UDAT_SHORT, UDAT_NONE, trdfLocale, trdfZone, -1, NULL, 0, &status);
475 if ( U_FAILURE(status) ) {
476 log_err("udat_open timeStyle SHORT dateStyle NONE fails, error %s\n", myErrorName(status) );
477 udat_close(fmtRelDateTime);
478 udat_close(fmtRelDate);
479 continue;
480 }
481
482 dtpatLen = udat_toPatternRelativeDate(fmtRelDateTime, strDate, kDateAndTimeOutMax, &status);
483 if ( U_FAILURE(status) ) {
484 log_err("udat_toPatternRelativeDate timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
485 status = U_ZERO_ERROR;
486 } else if ( u_strstr(strDate, *monthPtnPtr) == NULL || dtpatLen != u_strlen(strDate) ) {
487 log_err("udat_toPatternRelativeDate timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) date pattern incorrect\n", *stylePtr );
488 }
489 dtpatLen = udat_toPatternRelativeTime(fmtRelDateTime, strTime, kDateAndTimeOutMax, &status);
490 if ( U_FAILURE(status) ) {
491 log_err("udat_toPatternRelativeTime timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
492 status = U_ZERO_ERROR;
493 } else if ( u_strstr(strTime, minutesPatn) == NULL || dtpatLen != u_strlen(strTime) ) {
494 log_err("udat_toPatternRelativeTime timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) time pattern incorrect\n", *stylePtr );
495 }
496 dtpatLen = udat_toPattern(fmtRelDateTime, FALSE, strDateTime, kDateAndTimeOutMax, &status);
497 if ( U_FAILURE(status) ) {
498 log_err("udat_toPattern timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
499 status = U_ZERO_ERROR;
500 } else if ( u_strstr(strDateTime, strDate) == NULL || u_strstr(strDateTime, strTime) == NULL || dtpatLen != u_strlen(strDateTime) ) {
501 log_err("udat_toPattern timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) dateTime pattern incorrect\n", *stylePtr );
502 }
503 udat_applyPatternRelative(fmtRelDateTime, strDate, u_strlen(strDate), newTimePatn, u_strlen(newTimePatn), &status);
504 if ( U_FAILURE(status) ) {
505 log_err("udat_applyPatternRelative timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
506 status = U_ZERO_ERROR;
507 } else {
508 udat_toPattern(fmtRelDateTime, FALSE, strDateTime, kDateAndTimeOutMax, &status);
509 if ( U_FAILURE(status) ) {
510 log_err("udat_toPattern timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
511 status = U_ZERO_ERROR;
512 } else if ( u_strstr(strDateTime, newTimePatn) == NULL ) {
513 log_err("udat_applyPatternRelative timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) didn't update time pattern\n", *stylePtr );
514 }
515 }
516 udat_applyPatternRelative(fmtRelDateTime, strDate, u_strlen(strDate), strTime, u_strlen(strTime), &status); /* restore original */
517
518 fp.field = UDAT_MINUTE_FIELD;
519 for (dayOffset = -2, limit = 2; dayOffset <= limit; ++dayOffset) {
520 UDate dateToUse = today + (float)dayOffset*dayInterval;
521
522 udat_format(fmtRelDateTime, dateToUse, strDateTime, kDateAndTimeOutMax, &fp, &status);
523 if ( U_FAILURE(status) ) {
524 log_err("udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
525 status = U_ZERO_ERROR;
526 } else {
527 int32_t parsePos = 0;
528 UDate dateResult = udat_parse(fmtRelDateTime, strDateTime, -1, &parsePos, &status);
529 UDate dateDiff = (dateResult >= dateToUse)? dateResult - dateToUse: dateToUse - dateResult;
530 if ( U_FAILURE(status) || dateDiff > minutesTolerance ) {
531 log_err("udat_parse timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s, expect approx %.1f, got %.1f, parsePos %d\n",
532 *stylePtr, myErrorName(status), dateToUse, dateResult, parsePos );
533 status = U_ZERO_ERROR;
534 }
535
536 udat_format(fmtRelDate, dateToUse, strDate, kDateOrTimeOutMax, NULL, &status);
537 if ( U_FAILURE(status) ) {
538 log_err("udat_format timeStyle NONE dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
539 status = U_ZERO_ERROR;
540 } else if ( u_strstr(strDateTime, strDate) == NULL ) {
541 log_err("relative date string not found in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", *stylePtr );
542 } else {
543 parsePos = 0;
544 dateResult = udat_parse(fmtRelDate, strDate, -1, &parsePos, &status);
545 dateDiff = (dateResult >= dateToUse)? dateResult - dateToUse: dateToUse - dateResult;
546 if ( U_FAILURE(status) || dateDiff > daysTolerance ) {
547 log_err("udat_parse timeStyle NONE dateStyle (%d | UDAT_RELATIVE) fails, error %s, expect approx %.1f, got %.1f, parsePos %d\n",
548 *stylePtr, myErrorName(status), dateToUse, dateResult, parsePos );
549 status = U_ZERO_ERROR;
550 }
551 }
552
553 udat_format(fmtTime, dateToUse, strTime, kDateOrTimeOutMax, NULL, &status);
554 if ( U_FAILURE(status) ) {
555 log_err("udat_format timeStyle SHORT dateStyle NONE fails, error %s\n", myErrorName(status) );
556 status = U_ZERO_ERROR;
557 } else if ( u_strstr(strDateTime, strTime) == NULL ) {
558 log_err("time string not found in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", *stylePtr );
559 }
560
561 strPtr = u_strstr(strDateTime, minutesStr);
562 if ( strPtr != NULL ) {
563 int32_t beginIndex = strPtr - strDateTime;
564 if ( fp.beginIndex != beginIndex ) {
565 log_err("UFieldPosition beginIndex %d, expected %d, in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", fp.beginIndex, beginIndex, *stylePtr );
566 }
567 } else {
568 log_err("minutes string not found in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", *stylePtr );
569 }
570 }
571 }
572
573 udat_close(fmtRelDateTime);
574 udat_close(fmtRelDate);
575 udat_close(fmtTime);
576 }
577}
578
579/*Testing udat_getSymbols() and udat_setSymbols() and udat_countSymbols()*/
580static void TestSymbols()
581{
582 UDateFormat *def, *fr, *zhChiCal;
583 UErrorCode status = U_ZERO_ERROR;
584 UChar *value=NULL;
585 UChar *result = NULL;
586 int32_t resultlength;
587 int32_t resultlengthout;
588 UChar *pattern;
589
590
591 /*creating a dateformat with french locale */
592 log_verbose("\ncreating a date format with french locale\n");
593 fr = udat_open(UDAT_FULL, UDAT_DEFAULT, "fr_FR", NULL, 0, NULL, 0, &status);
594 if(U_FAILURE(status))
595 {
596 log_data_err("error in creating the dateformat using full time style with french locale -> %s (Are you missing data?)\n",
597 myErrorName(status) );
598 return;
599 }
600 /*creating a default dateformat */
601 log_verbose("\ncreating a date format with default locale\n");
602 /* this is supposed to open default date format, but later on it treats it like it is "en_US"
603 - very bad if you try to run the tests on machine where default locale is NOT "en_US" */
604 /* def = udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,NULL, NULL, 0, &status); */
605 def = udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,"en_US", NULL, 0, NULL, 0, &status);
606 if(U_FAILURE(status))
607 {
608 log_err("error in creating the dateformat using short date and time style\n %s\n",
609 myErrorName(status) );
610 return;
611 }
612 /*creating a dateformat with zh locale */
613 log_verbose("\ncreating a date format with zh locale for chinese calendar\n");
614 zhChiCal = udat_open(UDAT_NONE, UDAT_FULL, "zh@calendar=chinese", NULL, 0, NULL, 0, &status);
615 if(U_FAILURE(status))
616 {
617 log_data_err("error in creating the dateformat using full date, no time, locale zh@calendar=chinese -> %s (Are you missing data?)\n",
618 myErrorName(status) );
619 return;
620 }
621
622
623 /*Testing countSymbols, getSymbols and setSymbols*/
624 log_verbose("\nTesting countSymbols\n");
625 /*since the month names has the last string empty and week names are 1 based 1.e first string in the weeknames array is empty */
626 if(udat_countSymbols(def, UDAT_ERAS)!=2 || udat_countSymbols(def, UDAT_MONTHS)!=12 ||
627 udat_countSymbols(def, UDAT_SHORT_MONTHS)!=12 || udat_countSymbols(def, UDAT_WEEKDAYS)!=8 ||
628 udat_countSymbols(def, UDAT_SHORT_WEEKDAYS)!=8 || udat_countSymbols(def, UDAT_AM_PMS)!=2 ||
629 udat_countSymbols(def, UDAT_QUARTERS) != 4 || udat_countSymbols(def, UDAT_SHORT_QUARTERS) != 4 ||
630 udat_countSymbols(def, UDAT_LOCALIZED_CHARS)!=1 || udat_countSymbols(def, UDAT_SHORTER_WEEKDAYS)!=8 ||
631 udat_countSymbols(zhChiCal, UDAT_CYCLIC_YEARS_NARROW)!=60 || udat_countSymbols(zhChiCal, UDAT_ZODIAC_NAMES_NARROW)!=12)
632 {
633 log_err("FAIL: error in udat_countSymbols\n");
634 }
635 else
636 log_verbose("PASS: udat_countSymbols() successful\n");
637
638 /*testing getSymbols*/
639 log_verbose("\nTesting getSymbols\n");
640 pattern=(UChar*)malloc(sizeof(UChar) * 10);
641 u_uastrcpy(pattern, "jeudi");
642 resultlength=0;
643 resultlengthout=udat_getSymbols(fr, UDAT_WEEKDAYS, 5 , NULL, resultlength, &status);
644 if(status==U_BUFFER_OVERFLOW_ERROR)
645 {
646 status=U_ZERO_ERROR;
647 resultlength=resultlengthout+1;
648 if(result != NULL) {
649 free(result);
650 result = NULL;
651 }
652 result=(UChar*)malloc(sizeof(UChar) * resultlength);
653 udat_getSymbols(fr, UDAT_WEEKDAYS, 5, result, resultlength, &status);
654
655 }
656 if(U_FAILURE(status))
657 {
658 log_err("FAIL: Error in udat_getSymbols().... %s\n", myErrorName(status) );
659 }
660 else
661 log_verbose("PASS: getSymbols succesful\n");
662
663 if(u_strcmp(result, pattern)==0)
664 log_verbose("PASS: getSymbols retrieved the right value\n");
665 else
666 log_data_err("FAIL: getSymbols retrieved the wrong value\n");
667
668 /*run series of tests to test getsymbols regressively*/
669 log_verbose("\nTesting getSymbols() regressively\n");
670 VerifygetSymbols(fr, UDAT_WEEKDAYS, 1, "dimanche");
671 VerifygetSymbols(def, UDAT_WEEKDAYS, 1, "Sunday");
672 VerifygetSymbols(fr, UDAT_SHORT_WEEKDAYS, 7, "sam.");
673 VerifygetSymbols(fr, UDAT_SHORTER_WEEKDAYS, 7, "sa");
674 VerifygetSymbols(def, UDAT_SHORT_WEEKDAYS, 7, "Sat");
675 VerifygetSymbols(def, UDAT_MONTHS, 11, "December");
676 VerifygetSymbols(def, UDAT_MONTHS, 0, "January");
677 VerifygetSymbols(fr, UDAT_ERAS, 0, "av. J.-C.");
678 VerifygetSymbols(def, UDAT_AM_PMS, 0, "AM");
679 VerifygetSymbols(def, UDAT_AM_PMS, 1, "PM");
680 VerifygetSymbols(fr, UDAT_SHORT_MONTHS, 0, "janv.");
681 VerifygetSymbols(def, UDAT_SHORT_MONTHS, 11, "Dec");
682 VerifygetSymbols(fr, UDAT_QUARTERS, 0, "1er trimestre");
683 VerifygetSymbols(def, UDAT_QUARTERS, 3, "4th quarter");
684 VerifygetSymbols(fr, UDAT_SHORT_QUARTERS, 1, "T2");
685 VerifygetSymbols(def, UDAT_SHORT_QUARTERS, 2, "Q3");
686 VerifygetSymbols(zhChiCal, UDAT_CYCLIC_YEARS_ABBREVIATED, 0, "\\u7532\\u5B50");
687 VerifygetSymbols(zhChiCal, UDAT_CYCLIC_YEARS_NARROW, 59, "\\u7678\\u4EA5");
688 VerifygetSymbols(zhChiCal, UDAT_ZODIAC_NAMES_ABBREVIATED, 0, "\\u9F20");
689 VerifygetSymbols(zhChiCal, UDAT_ZODIAC_NAMES_WIDE, 11, "\\u732A");
690#if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
691 VerifygetSymbols(def,UDAT_LOCALIZED_CHARS, 0, "GyMdkHmsSEDFwWahKzYeugAZvcLQqVUOXxrbB:");
692#else
693 VerifygetSymbols(def,UDAT_LOCALIZED_CHARS, 0, "GyMdkHmsSEDFwWahKzYeugAZvcLQqVUOXxrbB");
694#endif
695
696
697 if(result != NULL) {
698 free(result);
699 result = NULL;
700 }
701free(pattern);
702
703 log_verbose("\nTesting setSymbols\n");
704 /*applying the pattern so that setSymbolss works */
705 resultlength=0;
706 resultlengthout=udat_toPattern(fr, FALSE, NULL, resultlength, &status);
707 if(status==U_BUFFER_OVERFLOW_ERROR)
708 {
709 status=U_ZERO_ERROR;
710 resultlength=resultlengthout + 1;
711 pattern=(UChar*)malloc(sizeof(UChar) * resultlength);
712 udat_toPattern(fr, FALSE, pattern, resultlength, &status);
713 }
714 if(U_FAILURE(status))
715 {
716 log_err("FAIL: error in extracting the pattern from UNumberFormat\n %s\n",
717 myErrorName(status) );
718 }
719
720 udat_applyPattern(def, FALSE, pattern, u_strlen(pattern));
721 resultlength=0;
722 resultlengthout=udat_toPattern(def, FALSE, NULL, resultlength,&status);
723 if(status==U_BUFFER_OVERFLOW_ERROR)
724 {
725 status=U_ZERO_ERROR;
726 resultlength=resultlengthout + 1;
727 if(result != NULL) {
728 free(result);
729 result = NULL;
730 }
731 result=(UChar*)malloc(sizeof(UChar) * resultlength);
732 udat_toPattern(fr, FALSE,result, resultlength, &status);
733 }
734 if(U_FAILURE(status))
735 {
736 log_err("FAIL: error in extracting the pattern from UNumberFormat\n %s\n",
737 myErrorName(status) );
738 }
739 if(u_strcmp(result, pattern)==0)
740 log_verbose("Pattern applied properly\n");
741 else
742 log_err("pattern could not be applied properly\n");
743
744free(pattern);
745 /*testing set symbols */
746 resultlength=0;
747 resultlengthout=udat_getSymbols(fr, UDAT_MONTHS, 11 , NULL, resultlength, &status);
748 if(status==U_BUFFER_OVERFLOW_ERROR){
749 status=U_ZERO_ERROR;
750 resultlength=resultlengthout+1;
751 if(result != NULL) {
752 free(result);
753 result = NULL;
754 }
755 result=(UChar*)malloc(sizeof(UChar) * resultlength);
756 udat_getSymbols(fr, UDAT_MONTHS, 11, result, resultlength, &status);
757
758 }
759 if(U_FAILURE(status))
760 log_err("FAIL: error in getSymbols() %s\n", myErrorName(status) );
761 resultlength=resultlengthout+1;
762
763 udat_setSymbols(def, UDAT_MONTHS, 11, result, resultlength, &status);
764 if(U_FAILURE(status))
765 {
766 log_err("FAIL: Error in udat_setSymbols() : %s\n", myErrorName(status) );
767 }
768 else
769 log_verbose("PASS: SetSymbols successful\n");
770
771 resultlength=0;
772 resultlengthout=udat_getSymbols(def, UDAT_MONTHS, 11, NULL, resultlength, &status);
773 if(status==U_BUFFER_OVERFLOW_ERROR){
774 status=U_ZERO_ERROR;
775 resultlength=resultlengthout+1;
776 value=(UChar*)malloc(sizeof(UChar) * resultlength);
777 udat_getSymbols(def, UDAT_MONTHS, 11, value, resultlength, &status);
778 }
779 if(U_FAILURE(status))
780 log_err("FAIL: error in retrieving the value using getSymbols i.e roundtrip\n");
781
782 if(u_strcmp(result, value)!=0)
783 log_data_err("FAIL: Error in settting and getting symbols\n");
784 else
785 log_verbose("PASS: setSymbols successful\n");
786
787
788 /*run series of tests to test setSymbols regressively*/
789 log_verbose("\nTesting setSymbols regressively\n");
790 VerifysetSymbols(def, UDAT_ERAS, 0, "BeforeChrist");
791 VerifysetSymbols(def, UDAT_ERA_NAMES, 1, "AnnoDomini");
792 VerifysetSymbols(def, UDAT_WEEKDAYS, 1, "Sundayweek");
793 VerifysetSymbols(def, UDAT_SHORT_WEEKDAYS, 7, "Satweek");
794 VerifysetSymbols(def, UDAT_NARROW_WEEKDAYS, 4, "M");
795 VerifysetSymbols(def, UDAT_STANDALONE_WEEKDAYS, 1, "Sonntagweek");
796 VerifysetSymbols(def, UDAT_STANDALONE_SHORT_WEEKDAYS, 7, "Sams");
797 VerifysetSymbols(def, UDAT_STANDALONE_NARROW_WEEKDAYS, 4, "V");
798 VerifysetSymbols(fr, UDAT_MONTHS, 11, "december");
799 VerifysetSymbols(fr, UDAT_SHORT_MONTHS, 0, "Jan");
800 VerifysetSymbols(fr, UDAT_NARROW_MONTHS, 1, "R");
801 VerifysetSymbols(fr, UDAT_STANDALONE_MONTHS, 11, "dezember");
802 VerifysetSymbols(fr, UDAT_STANDALONE_SHORT_MONTHS, 7, "Aug");
803 VerifysetSymbols(fr, UDAT_STANDALONE_NARROW_MONTHS, 2, "M");
804 VerifysetSymbols(fr, UDAT_QUARTERS, 0, "1. Quart");
805 VerifysetSymbols(fr, UDAT_SHORT_QUARTERS, 1, "QQ2");
806 VerifysetSymbols(fr, UDAT_STANDALONE_QUARTERS, 2, "3rd Quar.");
807 VerifysetSymbols(fr, UDAT_STANDALONE_SHORT_QUARTERS, 3, "4QQ");
808 VerifysetSymbols(zhChiCal, UDAT_CYCLIC_YEARS_ABBREVIATED, 1, "yi-chou");
809 VerifysetSymbols(zhChiCal, UDAT_ZODIAC_NAMES_ABBREVIATED, 1, "Ox");
810
811
812 /*run series of tests to test get and setSymbols regressively*/
813 log_verbose("\nTesting get and set symbols regressively\n");
814 VerifygetsetSymbols(fr, def, UDAT_WEEKDAYS, 1);
815 VerifygetsetSymbols(fr, def, UDAT_WEEKDAYS, 7);
816 VerifygetsetSymbols(fr, def, UDAT_SHORT_WEEKDAYS, 1);
817 VerifygetsetSymbols(fr, def, UDAT_SHORT_WEEKDAYS, 7);
818 VerifygetsetSymbols(fr, def, UDAT_MONTHS, 0);
819 VerifygetsetSymbols(fr, def, UDAT_SHORT_MONTHS, 0);
820 VerifygetsetSymbols(fr, def, UDAT_ERAS,1);
821 VerifygetsetSymbols(fr, def, UDAT_LOCALIZED_CHARS, 0);
822 VerifygetsetSymbols(fr, def, UDAT_AM_PMS, 1);
823
824
825 /*closing*/
826
827 udat_close(fr);
828 udat_close(def);
829 udat_close(zhChiCal);
830 if(result != NULL) {
831 free(result);
832 result = NULL;
833 }
834 free(value);
835
836}
837
838/**
839 * Test DateFormat(Calendar) API
840 */
841static void TestDateFormatCalendar() {
842 UDateFormat *date=0, *time=0, *full=0;
843 UCalendar *cal=0;
844 UChar buf[256];
845 char cbuf[256];
846 int32_t pos;
847 UDate when;
848 UErrorCode ec = U_ZERO_ERROR;
849 UChar buf1[256];
850 int32_t len1;
851 const char *expected;
852 UChar uExpected[32];
853
854 ctest_setTimeZone(NULL, &ec);
855
856 /* Create a formatter for date fields. */
857 date = udat_open(UDAT_NONE, UDAT_SHORT, "en_US", NULL, 0, NULL, 0, &ec);
858 if (U_FAILURE(ec)) {
859 log_data_err("FAIL: udat_open(NONE, SHORT, en_US) failed with %s (Are you missing data?)\n",
860 u_errorName(ec));
861 goto FAIL;
862 }
863
864 /* Create a formatter for time fields. */
865 time = udat_open(UDAT_SHORT, UDAT_NONE, "en_US", NULL, 0, NULL, 0, &ec);
866 if (U_FAILURE(ec)) {
867 log_err("FAIL: udat_open(SHORT, NONE, en_US) failed with %s\n",
868 u_errorName(ec));
869 goto FAIL;
870 }
871
872 /* Create a full format for output */
873 full = udat_open(UDAT_FULL, UDAT_FULL, "en_US", NULL, 0, NULL, 0, &ec);
874 if (U_FAILURE(ec)) {
875 log_err("FAIL: udat_open(FULL, FULL, en_US) failed with %s\n",
876 u_errorName(ec));
877 goto FAIL;
878 }
879
880 /* Create a calendar */
881 cal = ucal_open(NULL, 0, "en_US", UCAL_GREGORIAN, &ec);
882 if (U_FAILURE(ec)) {
883 log_err("FAIL: ucal_open(en_US) failed with %s\n",
884 u_errorName(ec));
885 goto FAIL;
886 }
887
888 /* Parse the date */
889 ucal_clear(cal);
890 u_uastrcpy(buf, "4/5/2001");
891 pos = 0;
892 udat_parseCalendar(date, cal, buf, -1, &pos, &ec);
893 if (U_FAILURE(ec)) {
894 log_err("FAIL: udat_parseCalendar(4/5/2001) failed at %d with %s\n",
895 pos, u_errorName(ec));
896 goto FAIL;
897 }
898
899 /* Check if formatCalendar matches the original date */
900 len1 = udat_formatCalendar(date, cal, buf1, UPRV_LENGTHOF(buf1), NULL, &ec);
901 if (U_FAILURE(ec)) {
902 log_err("FAIL: udat_formatCalendar(4/5/2001) failed with %s\n",
903 u_errorName(ec));
904 goto FAIL;
905 }
906 expected = "4/5/01";
907 u_uastrcpy(uExpected, expected);
908 if (u_strlen(uExpected) != len1 || u_strncmp(uExpected, buf1, len1) != 0) {
909 log_err("FAIL: udat_formatCalendar(4/5/2001), expected: %s", expected);
910 }
911
912 /* Parse the time */
913 u_uastrcpy(buf, "5:45 PM");
914 pos = 0;
915 udat_parseCalendar(time, cal, buf, -1, &pos, &ec);
916 if (U_FAILURE(ec)) {
917 log_err("FAIL: udat_parseCalendar(17:45) failed at %d with %s\n",
918 pos, u_errorName(ec));
919 goto FAIL;
920 }
921
922 /* Check if formatCalendar matches the original time */
923 len1 = udat_formatCalendar(time, cal, buf1, UPRV_LENGTHOF(buf1), NULL, &ec);
924 if (U_FAILURE(ec)) {
925 log_err("FAIL: udat_formatCalendar(17:45) failed with %s\n",
926 u_errorName(ec));
927 goto FAIL;
928 }
929 expected = "5:45 PM";
930 u_uastrcpy(uExpected, expected);
931 if (u_strlen(uExpected) != len1 || u_strncmp(uExpected, buf1, len1) != 0) {
932 log_err("FAIL: udat_formatCalendar(17:45), expected: %s", expected);
933 }
934
935 /* Check result */
936 when = ucal_getMillis(cal, &ec);
937 if (U_FAILURE(ec)) {
938 log_err("FAIL: ucal_getMillis() failed with %s\n", u_errorName(ec));
939 goto FAIL;
940 }
941 udat_format(full, when, buf, sizeof(buf), NULL, &ec);
942 if (U_FAILURE(ec)) {
943 log_err("FAIL: udat_format() failed with %s\n", u_errorName(ec));
944 goto FAIL;
945 }
946 u_austrcpy(cbuf, buf);
947 /* Thursday, April 5, 2001 5:45:00 PM PDT 986517900000 */
948 if (when == 986517900000.0) {
949 log_verbose("Ok: Parsed result: %s\n", cbuf);
950 } else {
951 log_err("FAIL: Parsed result: %s, exp 4/5/2001 5:45 PM\n", cbuf);
952 }
953
954 FAIL:
955 udat_close(date);
956 udat_close(time);
957 udat_close(full);
958 ucal_close(cal);
959
960 ctest_resetTimeZone();
961}
962
963
964
965/**
966 * Test parsing two digit year against "YY" vs. "YYYY" patterns
967 */
968static void TestCalendarDateParse() {
969
970 int32_t result;
971 UErrorCode ec = U_ZERO_ERROR;
972 UDateFormat* simpleDateFormat = 0;
973 int32_t parsePos = 0;
974 int32_t twoDigitCenturyStart = 75;
975 int32_t currentTwoDigitYear = 0;
976 int32_t startCentury = 0;
977 UCalendar* tempCal = 0;
978 UCalendar* calendar = 0;
979
980 U_STRING_DECL(pattern, "yyyy", 4);
981 U_STRING_DECL(pattern2, "yy", 2);
982 U_STRING_DECL(text, "75", 2);
983
984 U_STRING_INIT(pattern, "yyyy", 4);
985 U_STRING_INIT(pattern2, "yy", 2);
986 U_STRING_INIT(text, "75", 2);
987
988 simpleDateFormat = udat_open(UDAT_FULL, UDAT_FULL, "en-GB", 0, 0, 0, 0, &ec);
989 if (U_FAILURE(ec)) {
990 log_data_err("udat_open(UDAT_FULL, UDAT_FULL, \"en-GB\", 0, 0, 0, 0, &ec) failed: %s - (Are you missing data?)\n", u_errorName(ec));
991 return;
992 }
993 udat_applyPattern(simpleDateFormat, 0, pattern, u_strlen(pattern));
994 udat_setLenient(simpleDateFormat, 0);
995
996 currentTwoDigitYear = getCurrentYear() % 100;
997 startCentury = getCurrentYear() - currentTwoDigitYear;
998 if (twoDigitCenturyStart > currentTwoDigitYear) {
999 startCentury -= 100;
1000 }
1001 tempCal = ucal_open(NULL, -1, NULL, UCAL_GREGORIAN, &ec);
1002 ucal_setMillis(tempCal, 0, &ec);
1003 ucal_setDateTime(tempCal, startCentury + twoDigitCenturyStart, UCAL_JANUARY, 1, 0, 0, 0, &ec);
1004 udat_set2DigitYearStart(simpleDateFormat, ucal_getMillis(tempCal, &ec), &ec);
1005
1006 calendar = ucal_open(NULL, -1, NULL, UCAL_GREGORIAN, &ec);
1007 ucal_setMillis(calendar, 0, &ec);
1008 ucal_setDateTime(calendar, twoDigitCenturyStart, UCAL_JANUARY, 1, 0, 0, 0, &ec);
1009
1010 udat_parseCalendar(simpleDateFormat, calendar, text, u_strlen(text), &parsePos, &ec);
1011
1012 /* Check result */
1013 result = ucal_get(calendar, UCAL_YEAR, &ec);
1014 if (U_FAILURE(ec)) {
1015 log_err("FAIL: ucal_get(UCAL_YEAR) failed with %s\n", u_errorName(ec));
1016 goto FAIL;
1017 }
1018
1019 if (result != 75) {
1020 log_err("FAIL: parsed incorrect year: %d\n", result);
1021 goto FAIL;
1022 }
1023
1024 parsePos = 0;
1025 udat_applyPattern(simpleDateFormat, 0, pattern2, u_strlen(pattern2));
1026 udat_parseCalendar(simpleDateFormat, calendar, text, u_strlen(text), &parsePos, &ec);
1027
1028 /* Check result */
1029 result = ucal_get(calendar, UCAL_YEAR, &ec);
1030 if (U_FAILURE(ec)) {
1031 log_err("FAIL: ucal_get(UCAL_YEAR) failed with %s\n", u_errorName(ec));
1032 goto FAIL;
1033 }
1034
1035 if (result != 1975) {
1036 log_err("FAIL: parsed incorrect year: %d\n", result);
1037 goto FAIL;
1038 }
1039
1040 FAIL:
1041 udat_close(simpleDateFormat);
1042 udat_close(tempCal);
1043 udat_close(calendar);
1044}
1045
1046
1047/*INTERNAL FUNCTIONS USED*/
1048static int getCurrentYear() {
1049 static int currentYear = 0;
1050 if (currentYear == 0) {
1051 UErrorCode status = U_ZERO_ERROR;
1052 UCalendar *cal = ucal_open(NULL, -1, NULL, UCAL_GREGORIAN, &status);
1053 if (!U_FAILURE(status)) {
1054 /* Get the current year from the default UCalendar */
1055 currentYear = ucal_get(cal, UCAL_YEAR, &status);
1056 ucal_close(cal);
1057 }
1058 }
1059
1060 return currentYear;
1061}
1062
1063/* N.B.: use idx instead of index to avoid 'shadow' warnings in strict mode. */
1064static void VerifygetSymbols(UDateFormat* datfor, UDateFormatSymbolType type, int32_t idx, const char* expected)
1065{
1066 UChar *pattern=NULL;
1067 UErrorCode status = U_ZERO_ERROR;
1068 UChar *result=NULL;
1069 int32_t resultlength, resultlengthout;
1070 int32_t patternSize = strlen(expected) + 1;
1071
1072 pattern=(UChar*)malloc(sizeof(UChar) * patternSize);
1073 u_unescape(expected, pattern, patternSize);
1074 resultlength=0;
1075 resultlengthout=udat_getSymbols(datfor, type, idx , NULL, resultlength, &status);
1076 if(status==U_BUFFER_OVERFLOW_ERROR)
1077 {
1078 status=U_ZERO_ERROR;
1079 resultlength=resultlengthout+1;
1080 result=(UChar*)malloc(sizeof(UChar) * resultlength);
1081 udat_getSymbols(datfor, type, idx, result, resultlength, &status);
1082
1083 }
1084 if(U_FAILURE(status))
1085 {
1086 log_err("FAIL: Error in udat_getSymbols()... %s\n", myErrorName(status) );
1087 return;
1088 }
1089 if(u_strcmp(result, pattern)==0)
1090 log_verbose("PASS: getSymbols retrieved the right value\n");
1091 else{
1092 log_data_err("FAIL: getSymbols retrieved the wrong value\n Expected %s Got %s\n", expected,
1093 aescstrdup(result,-1) );
1094 }
1095 free(result);
1096 free(pattern);
1097}
1098
1099static void VerifysetSymbols(UDateFormat* datfor, UDateFormatSymbolType type, int32_t idx, const char* expected)
1100{
1101 UChar *result=NULL;
1102 UChar *value=NULL;
1103 int32_t resultlength, resultlengthout;
1104 UErrorCode status = U_ZERO_ERROR;
1105 int32_t valueLen, valueSize = strlen(expected) + 1;
1106
1107 value=(UChar*)malloc(sizeof(UChar) * valueSize);
1108 valueLen = u_unescape(expected, value, valueSize);
1109 udat_setSymbols(datfor, type, idx, value, valueLen, &status);
1110 if(U_FAILURE(status))
1111 {
1112 log_err("FAIL: Error in udat_setSymbols() %s\n", myErrorName(status) );
1113 return;
1114 }
1115
1116 resultlength=0;
1117 resultlengthout=udat_getSymbols(datfor, type, idx, NULL, resultlength, &status);
1118 if(status==U_BUFFER_OVERFLOW_ERROR){
1119 status=U_ZERO_ERROR;
1120 resultlength=resultlengthout+1;
1121 result=(UChar*)malloc(sizeof(UChar) * resultlength);
1122 udat_getSymbols(datfor, type, idx, result, resultlength, &status);
1123 }
1124 if(U_FAILURE(status)){
1125 log_err("FAIL: error in retrieving the value using getSymbols after setting it previously\n %s\n",
1126 myErrorName(status) );
1127 return;
1128 }
1129
1130 if(u_strcmp(result, value)!=0){
1131 log_err("FAIL:Error in setting and then getting symbols\n Expected %s Got %s\n", expected,
1132 aescstrdup(result,-1) );
1133 }
1134 else
1135 log_verbose("PASS: setSymbols successful\n");
1136
1137 free(value);
1138 free(result);
1139}
1140
1141
1142static void VerifygetsetSymbols(UDateFormat* from, UDateFormat* to, UDateFormatSymbolType type, int32_t idx)
1143{
1144 UChar *result=NULL;
1145 UChar *value=NULL;
1146 int32_t resultlength, resultlengthout;
1147 UErrorCode status = U_ZERO_ERROR;
1148
1149 resultlength=0;
1150 resultlengthout=udat_getSymbols(from, type, idx , NULL, resultlength, &status);
1151 if(status==U_BUFFER_OVERFLOW_ERROR){
1152 status=U_ZERO_ERROR;
1153 resultlength=resultlengthout+1;
1154 result=(UChar*)malloc(sizeof(UChar) * resultlength);
1155 udat_getSymbols(from, type, idx, result, resultlength, &status);
1156 }
1157 if(U_FAILURE(status)){
1158 log_err("FAIL: error in getSymbols() %s\n", myErrorName(status) );
1159 return;
1160 }
1161
1162 resultlength=resultlengthout+1;
1163 udat_setSymbols(to, type, idx, result, resultlength, &status);
1164 if(U_FAILURE(status))
1165 {
1166 log_err("FAIL: Error in udat_setSymbols() : %s\n", myErrorName(status) );
1167 return;
1168 }
1169
1170 resultlength=0;
1171 resultlengthout=udat_getSymbols(to, type, idx, NULL, resultlength, &status);
1172 if(status==U_BUFFER_OVERFLOW_ERROR){
1173 status=U_ZERO_ERROR;
1174 resultlength=resultlengthout+1;
1175 value=(UChar*)malloc(sizeof(UChar) * resultlength);
1176 udat_getSymbols(to, type, idx, value, resultlength, &status);
1177 }
1178 if(U_FAILURE(status)){
1179 log_err("FAIL: error in retrieving the value using getSymbols i.e roundtrip\n %s\n",
1180 myErrorName(status) );
1181 return;
1182 }
1183
1184 if(u_strcmp(result, value)!=0){
1185 log_data_err("FAIL:Error in setting and then getting symbols\n Expected %s Got %s\n", austrdup(result),
1186 austrdup(value) );
1187 }
1188 else
1189 log_verbose("PASS: setSymbols successful\n");
1190
1191 free(value);
1192 free(result);
1193}
1194
1195
1196static UChar* myNumformat(const UNumberFormat* numfor, double d)
1197{
1198 UChar *result2=NULL;
1199 int32_t resultlength, resultlengthneeded;
1200 UErrorCode status = U_ZERO_ERROR;
1201
1202 resultlength=0;
1203 resultlengthneeded=unum_formatDouble(numfor, d, NULL, resultlength, NULL, &status);
1204 if(status==U_BUFFER_OVERFLOW_ERROR)
1205 {
1206 status=U_ZERO_ERROR;
1207 resultlength=resultlengthneeded+1;
1208 /*result2=(UChar*)malloc(sizeof(UChar) * resultlength);*/ /* this leaks */
1209 result2=(UChar*)ctst_malloc(sizeof(UChar) * resultlength); /*this won't*/
1210 unum_formatDouble(numfor, d, result2, resultlength, NULL, &status);
1211 }
1212 if(U_FAILURE(status))
1213 {
1214 log_err("FAIL: Error in formatting using unum_format(.....) %s\n", myErrorName(status) );
1215 return 0;
1216 }
1217
1218 return result2;
1219}
1220
1221/**
1222 * The search depth for TestExtremeDates. The total number of
1223 * dates that will be tested is (2^EXTREME_DATES_DEPTH) - 1.
1224 */
1225#define EXTREME_DATES_DEPTH 8
1226
1227/**
1228 * Support for TestExtremeDates (below).
1229 *
1230 * Test a single date to see whether udat_format handles it properly.
1231 */
1232static UBool _aux1ExtremeDates(UDateFormat* fmt, UDate date,
1233 UChar* buf, int32_t buflen, char* cbuf,
1234 UErrorCode* ec) {
1235 int32_t len = udat_format(fmt, date, buf, buflen, 0, ec);
1236 if (!assertSuccess("udat_format", ec)) return FALSE;
1237 u_austrncpy(cbuf, buf, buflen);
1238 if (len < 4) {
1239 log_err("FAIL: udat_format(%g) => \"%s\"\n", date, cbuf);
1240 } else {
1241 log_verbose("udat_format(%g) => \"%s\"\n", date, cbuf);
1242 }
1243 return TRUE;
1244}
1245
1246/**
1247 * Support for TestExtremeDates (below).
1248 *
1249 * Recursively test between 'small' and 'large', up to the depth
1250 * limit specified by EXTREME_DATES_DEPTH.
1251 */
1252static UBool _aux2ExtremeDates(UDateFormat* fmt, UDate small, UDate large,
1253 UChar* buf, int32_t buflen, char* cbuf,
1254 int32_t count,
1255 UErrorCode* ec) {
1256 /* Logarithmic midpoint; see below */
1257 UDate mid = (UDate) exp((log(small) + log(large)) / 2);
1258 if (count == EXTREME_DATES_DEPTH) {
1259 return TRUE;
1260 }
1261 return
1262 _aux1ExtremeDates(fmt, mid, buf, buflen, cbuf, ec) &&
1263 _aux2ExtremeDates(fmt, small, mid, buf, buflen, cbuf, count+1, ec) &&
1264 _aux2ExtremeDates(fmt, mid, large, buf, buflen, cbuf, count+1, ec);
1265}
1266
1267/**
1268 * http://www.jtcsv.com/cgibin/icu-bugs?findid=3659
1269 *
1270 * For certain large dates, udat_format crashes on MacOS. This test
1271 * attempts to reproduce this problem by doing a recursive logarithmic*
1272 * binary search of a predefined interval (from 'small' to 'large').
1273 *
1274 * The limit of the search is given by EXTREME_DATES_DEPTH, above.
1275 *
1276 * *The search has to be logarithmic, not linear. A linear search of the
1277 * range 0..10^30, for example, will find 0.5*10^30, then 0.25*10^30 and
1278 * 0.75*10^30, etc. A logarithmic search will find 10^15, then 10^7.5
1279 * and 10^22.5, etc.
1280 */
1281static void TestExtremeDates() {
1282 UDateFormat *fmt;
1283 UErrorCode ec;
1284 UChar buf[256];
1285 char cbuf[256];
1286 const double small = 1000; /* 1 sec */
1287 const double large = 1e+30; /* well beyond usable UDate range */
1288
1289 /* There is no need to test larger values from 1e+30 to 1e+300;
1290 the failures occur around 1e+27, and never above 1e+30. */
1291
1292 ec = U_ZERO_ERROR;
1293 fmt = udat_open(UDAT_LONG, UDAT_LONG, "en_US",
1294 0, 0, 0, 0, &ec);
1295 if (U_FAILURE(ec)) {
1296 log_data_err("FAIL: udat_open (%s) (Are you missing data?)\n", u_errorName(ec));
1297 return;
1298 }
1299
1300 _aux2ExtremeDates(fmt, small, large, buf, UPRV_LENGTHOF(buf), cbuf, 0, &ec);
1301
1302 udat_close(fmt);
1303}
1304
1305static void TestAllLocales(void) {
1306 int32_t idx, dateIdx, timeIdx, localeCount;
1307 static const UDateFormatStyle style[] = {
1308 UDAT_FULL, UDAT_LONG, UDAT_MEDIUM, UDAT_SHORT
1309 };
1310 localeCount = uloc_countAvailable();
1311 for (idx = 0; idx < localeCount; idx++) {
1312 for (dateIdx = 0; dateIdx < UPRV_LENGTHOF(style); dateIdx++) {
1313 for (timeIdx = 0; timeIdx < UPRV_LENGTHOF(style); timeIdx++) {
1314 UErrorCode status = U_ZERO_ERROR;
1315 udat_close(udat_open(style[dateIdx], style[timeIdx],
1316 uloc_getAvailable(idx), NULL, 0, NULL, 0, &status));
1317 if (U_FAILURE(status)) {
1318 log_err("FAIL: udat_open(%s) failed with (%s) dateIdx=%d, timeIdx=%d\n",
1319 uloc_getAvailable(idx), u_errorName(status), dateIdx, timeIdx);
1320 }
1321 }
1322 }
1323 }
1324}
1325
1326static void TestRelativeCrash(void) {
1327 static const UChar tzName[] = { 0x0055, 0x0053, 0x002F, 0x0050, 0x0061, 0x0063, 0x0069, 0x0066, 0x0069, 0x0063, 0 };
1328 static const UDate aDate = -631152000000.0;
1329
1330 UErrorCode status = U_ZERO_ERROR;
1331 UErrorCode expectStatus = U_ILLEGAL_ARGUMENT_ERROR;
1332 UDateFormat icudf;
1333
1334 icudf = udat_open(UDAT_NONE, UDAT_SHORT_RELATIVE, "en", tzName, -1, NULL, 0, &status);
1335 if ( U_SUCCESS(status) ) {
1336 const char *what = "???";
1337 {
1338 UErrorCode subStatus = U_ZERO_ERROR;
1339 what = "udat_set2DigitYearStart";
1340 log_verbose("Trying %s on a relative date..\n", what);
1341 udat_set2DigitYearStart(icudf, aDate, &subStatus);
1342 if(subStatus == expectStatus) {
1343 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1344 } else {
1345 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
1346 }
1347 }
1348 {
1349 /* clone works polymorphically. try it anyways */
1350 UErrorCode subStatus = U_ZERO_ERROR;
1351 UDateFormat *oth;
1352 what = "clone";
1353 log_verbose("Trying %s on a relative date..\n", what);
1354 oth = udat_clone(icudf, &subStatus);
1355 if(subStatus == U_ZERO_ERROR) {
1356 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1357 udat_close(oth); /* ? */
1358 } else {
1359 log_err("FAIL: didn't crash on %s, but got %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
1360 }
1361 }
1362 {
1363 UErrorCode subStatus = U_ZERO_ERROR;
1364 what = "udat_get2DigitYearStart";
1365 log_verbose("Trying %s on a relative date..\n", what);
1366 udat_get2DigitYearStart(icudf, &subStatus);
1367 if(subStatus == expectStatus) {
1368 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1369 } else {
1370 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
1371 }
1372 }
1373 {
1374 /* Now udat_toPattern works for relative date formatters, unless localized is TRUE */
1375 UErrorCode subStatus = U_ZERO_ERROR;
1376 what = "udat_toPattern";
1377 log_verbose("Trying %s on a relative date..\n", what);
1378 udat_toPattern(icudf, TRUE,NULL,0, &subStatus);
1379 if(subStatus == expectStatus) {
1380 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1381 } else {
1382 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
1383 }
1384 }
1385 {
1386 UErrorCode subStatus = U_ZERO_ERROR;
1387 what = "udat_applyPattern";
1388 log_verbose("Trying %s on a relative date..\n", what);
1389 udat_applyPattern(icudf, FALSE,tzName,-1);
1390 subStatus = U_ILLEGAL_ARGUMENT_ERROR; /* what it should be, if this took an errorcode. */
1391 if(subStatus == expectStatus) {
1392 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1393 } else {
1394 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
1395 }
1396 }
1397 {
1398 UChar erabuf[32];
1399 UErrorCode subStatus = U_ZERO_ERROR;
1400 what = "udat_getSymbols";
1401 log_verbose("Trying %s on a relative date..\n", what);
1402 udat_getSymbols(icudf, UDAT_ERAS,0,erabuf,UPRV_LENGTHOF(erabuf), &subStatus);
1403 if(subStatus == U_ZERO_ERROR) {
1404 log_verbose("Success: %s returned %s.\n", what, u_errorName(subStatus));
1405 } else {
1406 log_err("FAIL: didn't crash on %s, but got %s instead of U_ZERO_ERROR.\n", what, u_errorName(subStatus));
1407 }
1408 }
1409 {
1410 UErrorCode subStatus = U_ZERO_ERROR;
1411 UChar symbolValue = 0x0041;
1412 what = "udat_setSymbols";
1413 log_verbose("Trying %s on a relative date..\n", what);
1414 udat_setSymbols(icudf, UDAT_ERAS,0,&symbolValue,1, &subStatus); /* bogus values */
1415 if(subStatus == expectStatus) {
1416 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1417 } else {
1418 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
1419 }
1420 }
1421 {
1422 UErrorCode subStatus = U_ZERO_ERROR;
1423 what = "udat_countSymbols";
1424 log_verbose("Trying %s on a relative date..\n", what);
1425 udat_countSymbols(icudf, UDAT_ERAS);
1426 subStatus = U_ILLEGAL_ARGUMENT_ERROR; /* should have an errorcode. */
1427 if(subStatus == expectStatus) {
1428 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1429 } else {
1430 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
1431 }
1432 }
1433
1434 udat_close(icudf);
1435 } else {
1436 log_data_err("FAIL: err calling udat_open() ->%s (Are you missing data?)\n", u_errorName(status));
1437 }
1438}
1439
1440static const UChar skeleton_yMMMM[] = { 0x79,0x4D,0x4D,0x4D,0x4D,0 }; /* "yMMMM"; fr maps to "MMMM y", cs maps to "LLLL y" */
1441static const UChar july2008_frDefault[] = { 0x6A,0x75,0x69,0x6C,0x6C,0x65,0x74,0x20,0x32,0x30,0x30,0x38,0 }; /* "juillet 2008" */
1442static const UChar july2008_frTitle[] = { 0x4A,0x75,0x69,0x6C,0x6C,0x65,0x74,0x20,0x32,0x30,0x30,0x38,0 }; /* "Juillet 2008" sentence-begin, standalone */
1443static const UChar july2008_csDefault[] = { 0x10D,0x65,0x72,0x76,0x65,0x6E,0x65,0x63,0x20,0x32,0x30,0x30,0x38,0 }; /* "c(hacek)ervenec 2008" */
1444static const UChar july2008_csTitle[] = { 0x10C,0x65,0x72,0x76,0x65,0x6E,0x65,0x63,0x20,0x32,0x30,0x30,0x38,0 }; /* "C(hacek)ervenec 2008" sentence-begin, uiListOrMenu */
1445
1446typedef struct {
1447 const char * locale;
1448 const UChar * skeleton;
1449 UDisplayContext capitalizationContext;
1450 const UChar * expectedFormat;
1451} TestContextItem;
1452
1453static const TestContextItem textContextItems[] = {
1454 { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_NONE, july2008_frDefault },
1455#if !UCONFIG_NO_BREAK_ITERATION
1456 { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, july2008_frDefault },
1457 { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, july2008_frTitle },
1458 { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, july2008_frDefault },
1459 { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_STANDALONE, july2008_frTitle },
1460#endif
1461 { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_NONE, july2008_csDefault },
1462#if !UCONFIG_NO_BREAK_ITERATION
1463 { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, july2008_csDefault },
1464 { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, july2008_csTitle },
1465 { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, july2008_csTitle },
1466 { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_STANDALONE, july2008_csDefault },
1467#endif
1468 { NULL, NULL, (UDisplayContext)0, NULL }
1469};
1470
1471static const UChar today_enDefault[] = { 0x74,0x6F,0x64,0x61,0x79,0 }; /* "today" */
1472static const UChar today_enTitle[] = { 0x54,0x6F,0x64,0x61,0x79,0 }; /* "Today" sentence-begin, uiListOrMenu, standalone */
1473static const UChar yesterday_enDefault[] = { 0x79,0x65,0x73,0x74,0x65,0x72,0x64,0x61,0x79,0 }; /* "yesterday" */
1474static const UChar yesterday_enTitle[] = { 0x59,0x65,0x73,0x74,0x65,0x72,0x64,0x61,0x79,0 }; /* "Yesterday" sentence-begin, uiListOrMenu, standalone */
1475static const UChar today_nbDefault[] = { 0x69,0x20,0x64,0x61,0x67,0 }; /* "i dag" */
1476static const UChar today_nbTitle[] = { 0x49,0x20,0x64,0x61,0x67,0 }; /* "I dag" sentence-begin, standalone */
1477static const UChar yesterday_nbDefault[] = { 0x69,0x20,0x67,0xE5,0x72,0 };
1478static const UChar yesterday_nbTitle[] = { 0x49,0x20,0x67,0xE5,0x72,0 };
1479
1480typedef struct {
1481 const char * locale;
1482 UDisplayContext capitalizationContext;
1483 const UChar * expectedFormatToday;
1484 const UChar * expectedFormatYesterday;
1485} TestRelativeContextItem;
1486
1487static const TestRelativeContextItem textContextRelativeItems[] = {
1488 { "en", UDISPCTX_CAPITALIZATION_NONE, today_enDefault, yesterday_enDefault },
1489#if !UCONFIG_NO_BREAK_ITERATION
1490 { "en", UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, today_enDefault, yesterday_enDefault },
1491 { "en", UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, today_enTitle, yesterday_enTitle },
1492 { "en", UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, today_enTitle, yesterday_enTitle },
1493 { "en", UDISPCTX_CAPITALIZATION_FOR_STANDALONE, today_enTitle, yesterday_enTitle },
1494#endif
1495 { "nb", UDISPCTX_CAPITALIZATION_NONE, today_nbDefault, yesterday_nbDefault },
1496#if !UCONFIG_NO_BREAK_ITERATION
1497 { "nb", UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, today_nbDefault, yesterday_nbDefault },
1498 { "nb", UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, today_nbTitle, yesterday_nbTitle },
1499 { "nb", UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, today_nbDefault, yesterday_nbDefault },
1500 { "nb", UDISPCTX_CAPITALIZATION_FOR_STANDALONE, today_nbTitle, yesterday_nbTitle },
1501#endif
1502 { NULL, (UDisplayContext)0, NULL, NULL }
1503};
1504
1505static const UChar january_esDefault[] = { 0x65,0x6E,0x65,0x72,0x6F,0 }; /* "enero" */
1506static const UChar january_esTitle[] = { 0x45,0x6E,0x65,0x72,0x6F,0 }; /* "Enero */
1507static const UChar monday_daDefault[] = { 0x6D,0x61,0x6E,0x64,0x61,0x67,0 }; /* "mandag" */
1508static const UChar monday_daTitle[] = { 0x4D,0x61,0x6E,0x64,0x61,0x67,0 }; /* "Mandag */
1509
1510typedef struct {
1511 const char * locale;
1512 UDateFormatSymbolType type;
1513 int32_t index;
1514 UDisplayContext capitalizationContext;
1515 const UChar * expectedFormat;
1516} TestSymbolContextItem;
1517
1518static const TestSymbolContextItem testContextSymbolItems[] = {
1519 { "es", UDAT_MONTHS, 0, UDISPCTX_CAPITALIZATION_NONE, january_esDefault },
1520#if !UCONFIG_NO_BREAK_ITERATION
1521 { "es", UDAT_MONTHS, 0, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, january_esDefault },
1522 { "es", UDAT_MONTHS, 0, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, january_esTitle },
1523 { "es", UDAT_MONTHS, 0, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, january_esTitle },
1524 { "es", UDAT_MONTHS, 0, UDISPCTX_CAPITALIZATION_FOR_STANDALONE, january_esTitle },
1525#endif
1526 { "da", UDAT_WEEKDAYS, 2, UDISPCTX_CAPITALIZATION_NONE, monday_daDefault },
1527#if !UCONFIG_NO_BREAK_ITERATION
1528 { "da", UDAT_WEEKDAYS, 2, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, monday_daDefault },
1529 { "da", UDAT_WEEKDAYS, 2, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, monday_daTitle },
1530 { "da", UDAT_WEEKDAYS, 2, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, monday_daDefault },
1531 { "da", UDAT_WEEKDAYS, 2, UDISPCTX_CAPITALIZATION_FOR_STANDALONE, monday_daDefault },
1532#endif
1533 { NULL, (UDateFormatSymbolType)0, 0, (UDisplayContext)0, NULL }
1534};
1535
1536static const UChar zoneGMT[] = { 0x47,0x4D,0x54,0 }; /* "GMT" */
1537static const UDate july022008 = 1215000000000.0;
1538enum { kUbufMax = 64, kBbufMax = 3*kUbufMax };
1539
1540static void TestContext(void) {
1541 const TestContextItem* textContextItemPtr;
1542 const TestRelativeContextItem* textRelContextItemPtr;
1543 const TestSymbolContextItem* testSymContextItemPtr;
1544
1545 for (textContextItemPtr = textContextItems; textContextItemPtr->locale != NULL; ++textContextItemPtr) {
1546 UErrorCode status = U_ZERO_ERROR;
1547 UDateTimePatternGenerator* udtpg = udatpg_open(textContextItemPtr->locale, &status);
1548 if ( U_SUCCESS(status) ) {
1549 UChar ubuf[kUbufMax];
1550 int32_t len = udatpg_getBestPattern(udtpg, textContextItemPtr->skeleton, -1, ubuf, kUbufMax, &status);
1551 if ( U_SUCCESS(status) ) {
1552 UDateFormat* udfmt = udat_open(UDAT_PATTERN, UDAT_PATTERN, textContextItemPtr->locale, zoneGMT, -1, ubuf, len, &status);
1553 if ( U_SUCCESS(status) ) {
1554 udat_setContext(udfmt, textContextItemPtr->capitalizationContext, &status);
1555 if ( U_SUCCESS(status) ) {
1556 UDisplayContext getContext;
1557 len = udat_format(udfmt, july022008, ubuf, kUbufMax, NULL, &status);
1558 if ( U_FAILURE(status) ) {
1559 log_err("FAIL: udat_format for locale %s, capitalizationContext %d, status %s\n",
1560 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, u_errorName(status) );
1561 status = U_ZERO_ERROR;
1562 } else if (u_strncmp(ubuf, textContextItemPtr->expectedFormat, kUbufMax) != 0) {
1563 char bbuf1[kBbufMax];
1564 char bbuf2[kBbufMax];
1565 log_err("FAIL: udat_format for locale %s, capitalizationContext %d, expected %s, got %s\n",
1566 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext,
1567 u_austrncpy(bbuf1,textContextItemPtr->expectedFormat,kUbufMax), u_austrncpy(bbuf2,ubuf,kUbufMax) );
1568 }
1569 getContext = udat_getContext(udfmt, UDISPCTX_TYPE_CAPITALIZATION, &status);
1570 if ( U_FAILURE(status) ) {
1571 log_err("FAIL: udat_getContext for locale %s, capitalizationContext %d, status %s\n",
1572 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, u_errorName(status) );
1573 } else if (getContext != textContextItemPtr->capitalizationContext) {
1574 log_err("FAIL: udat_getContext for locale %s, capitalizationContext %d, got context %d\n",
1575 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, (int)getContext );
1576 }
1577 } else {
1578 log_err("FAIL: udat_setContext for locale %s, capitalizationContext %d, status %s\n",
1579 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, u_errorName(status) );
1580 }
1581 udat_close(udfmt);
1582 } else {
1583 log_data_err("FAIL: udat_open for locale %s, status %s\n", textContextItemPtr->locale, u_errorName(status) );
1584 }
1585 } else {
1586 log_err("FAIL: udatpg_getBestPattern for locale %s, status %s\n", textContextItemPtr->locale, u_errorName(status) );
1587 }
1588 udatpg_close(udtpg);
1589 } else {
1590 log_data_err("FAIL: udatpg_open for locale %s, status %s\n", textContextItemPtr->locale, u_errorName(status) );
1591 }
1592 }
1593
1594 for (textRelContextItemPtr = textContextRelativeItems; textRelContextItemPtr->locale != NULL; ++textRelContextItemPtr) {
1595 UErrorCode status = U_ZERO_ERROR;
1596 UCalendar* ucal = ucal_open(zoneGMT, -1, "root", UCAL_GREGORIAN, &status);
1597 if ( U_SUCCESS(status) ) {
1598 UDateFormat* udfmt = udat_open(UDAT_NONE, UDAT_LONG_RELATIVE, textRelContextItemPtr->locale, zoneGMT, -1, NULL, 0, &status);
1599 if ( U_SUCCESS(status) ) {
1600 udat_setContext(udfmt, textRelContextItemPtr->capitalizationContext, &status);
1601 if ( U_SUCCESS(status) ) {
1602 UDate yesterday, today = ucal_getNow();
1603 UChar ubuf[kUbufMax];
1604 char bbuf1[kBbufMax];
1605 char bbuf2[kBbufMax];
1606 int32_t len = udat_format(udfmt, today, ubuf, kUbufMax, NULL, &status);
1607 (void)len;
1608 if ( U_FAILURE(status) ) {
1609 log_err("FAIL: udat_format today for locale %s, capitalizationContext %d, status %s\n",
1610 textRelContextItemPtr->locale, (int)textRelContextItemPtr->capitalizationContext, u_errorName(status) );
1611 } else if (u_strncmp(ubuf, textRelContextItemPtr->expectedFormatToday, kUbufMax) != 0) {
1612 log_err("FAIL: udat_format today for locale %s, capitalizationContext %d, expected %s, got %s\n",
1613 textRelContextItemPtr->locale, (int)textRelContextItemPtr->capitalizationContext,
1614 u_austrncpy(bbuf1,textRelContextItemPtr->expectedFormatToday,kUbufMax), u_austrncpy(bbuf2,ubuf,kUbufMax) );
1615 }
1616 status = U_ZERO_ERROR;
1617 ucal_setMillis(ucal, today, &status);
1618 ucal_add(ucal, UCAL_DATE, -1, &status);
1619 yesterday = ucal_getMillis(ucal, &status);
1620 if ( U_SUCCESS(status) ) {
1621 len = udat_format(udfmt, yesterday, ubuf, kUbufMax, NULL, &status);
1622 if ( U_FAILURE(status) ) {
1623 log_err("FAIL: udat_format yesterday for locale %s, capitalizationContext %d, status %s\n",
1624 textRelContextItemPtr->locale, (int)textRelContextItemPtr->capitalizationContext, u_errorName(status) );
1625 } else if (u_strncmp(ubuf, textRelContextItemPtr->expectedFormatYesterday, kUbufMax) != 0) {
1626 log_err("FAIL: udat_format yesterday for locale %s, capitalizationContext %d, expected %s, got %s\n",
1627 textRelContextItemPtr->locale, (int)textRelContextItemPtr->capitalizationContext,
1628 u_austrncpy(bbuf1,textRelContextItemPtr->expectedFormatYesterday,kUbufMax), u_austrncpy(bbuf2,ubuf,kUbufMax) );
1629 }
1630 }
1631 } else {
1632 log_err("FAIL: udat_setContext relative for locale %s, capitalizationContext %d, status %s\n",
1633 textRelContextItemPtr->locale, (int)textRelContextItemPtr->capitalizationContext, u_errorName(status) );
1634 }
1635 udat_close(udfmt);
1636 } else {
1637 log_data_err("FAIL: udat_open relative for locale %s, status %s\n", textRelContextItemPtr->locale, u_errorName(status) );
1638 }
1639 ucal_close(ucal);
1640 } else {
1641 log_data_err("FAIL: ucal_open for locale root, status %s\n", u_errorName(status) );
1642 }
1643 }
1644
1645 for (testSymContextItemPtr = testContextSymbolItems; testSymContextItemPtr->locale != NULL; ++testSymContextItemPtr) {
1646 UErrorCode status = U_ZERO_ERROR;
1647 UDateFormat* udfmt = udat_open(UDAT_MEDIUM, UDAT_FULL, testSymContextItemPtr->locale, zoneGMT, -1, NULL, 0, &status);
1648 if ( U_SUCCESS(status) ) {
1649 udat_setContext(udfmt, testSymContextItemPtr->capitalizationContext, &status);
1650 if ( U_SUCCESS(status) ) {
1651 UChar ubuf[kUbufMax];
1652 int32_t len = udat_getSymbols(udfmt, testSymContextItemPtr->type, testSymContextItemPtr->index, ubuf, kUbufMax, &status);
1653 if ( U_FAILURE(status) ) {
1654 log_err("FAIL: udat_getSymbols for locale %s, capitalizationContext %d, status %s\n",
1655 testSymContextItemPtr->locale, (int)testSymContextItemPtr->capitalizationContext, u_errorName(status) );
1656 } else if (u_strncmp(ubuf, testSymContextItemPtr->expectedFormat, kUbufMax) != 0) {
1657 char bbuf1[kBbufMax];
1658 char bbuf2[kBbufMax];
1659 log_err("FAIL: udat_getSymbols for locale %s, capitalizationContext %d, expected %s, got %s\n",
1660 testSymContextItemPtr->locale, (int)testSymContextItemPtr->capitalizationContext,
1661 u_austrncpy(bbuf1,testSymContextItemPtr->expectedFormat,kUbufMax), u_austrncpy(bbuf2,ubuf,kUbufMax) );
1662 }
1663 } else {
1664 log_err("FAIL: udat_setContext std for locale %s, capitalizationContext %d, status %s\n",
1665 testSymContextItemPtr->locale, (int)testSymContextItemPtr->capitalizationContext, u_errorName(status) );
1666 }
1667 udat_close(udfmt);
1668 } else {
1669 log_data_err("FAIL: udat_open std for locale %s, status %s\n", testSymContextItemPtr->locale, u_errorName(status) );
1670 }
1671 }
1672}
1673
1674
1675// overrideNumberFormat[i][0] is to tell which field to set,
1676// overrideNumberFormat[i][1] is the expected result
1677static const char * overrideNumberFormat[][2] = {
1678 {"", "\\u521D\\u4E03 \\u521D\\u4E8C"},
1679 {"d", "07 \\u521D\\u4E8C"},
1680 {"do", "07 \\u521D\\u4E8C"},
1681 {"Md", "\\u521D\\u4E03 \\u521D\\u4E8C"},
1682 {"MdMMd", "\\u521D\\u4E03 \\u521D\\u4E8C"},
1683 {"mixed", "\\u521D\\u4E03 \\u521D\\u4E8C"}
1684};
1685
1686static void TestOverrideNumberFormat(void) {
1687 UErrorCode status = U_ZERO_ERROR;
1688 UChar pattern[50];
1689 UChar expected[50];
1690 UChar fields[50];
1691 char bbuf1[kBbufMax];
1692 char bbuf2[kBbufMax];
1693 const char* localeString = "zh@numbers=hanidays";
1694 UDateFormat* fmt;
1695 const UNumberFormat* getter_result;
1696 int32_t i;
1697
1698 u_uastrcpy(fields, "d");
1699 u_uastrcpy(pattern,"MM d");
1700
1701 fmt=udat_open(UDAT_PATTERN, UDAT_PATTERN, "en_US", zoneGMT, -1, pattern, u_strlen(pattern), &status);
1702 if (!assertSuccess("udat_open()", &status)) {
1703 return;
1704 }
1705
1706 // loop 5 times to check getter/setter
1707 for (i = 0; i < 5; i++){
1708 UNumberFormat* overrideFmt;
1709 overrideFmt = unum_open(UNUM_DEFAULT, NULL, 0, localeString, NULL, &status);
1710 assertSuccess("unum_open()", &status);
1711 udat_adoptNumberFormatForFields(fmt, fields, overrideFmt, &status);
1712 overrideFmt = NULL; // no longer valid
1713 assertSuccess("udat_setNumberFormatForField()", &status);
1714
1715 getter_result = udat_getNumberFormatForField(fmt, 'd');
1716 if(getter_result == NULL) {
1717 log_err("FAIL: udat_getNumberFormatForField did not return a valid pointer\n");
1718 }
1719 }
1720 {
1721 UNumberFormat* overrideFmt;
1722 overrideFmt = unum_open(UNUM_DEFAULT, NULL, 0, localeString, NULL, &status);
1723 assertSuccess("unum_open()", &status);
1724 udat_setNumberFormat(fmt, overrideFmt); // test the same override NF will not crash
1725 unum_close(overrideFmt);
1726 }
1727 udat_close(fmt);
1728
1729 for (i=0; i<UPRV_LENGTHOF(overrideNumberFormat); i++){
1730 UChar ubuf[kUbufMax];
1731 UDateFormat* fmt2;
1732 UNumberFormat* overrideFmt2;
1733
1734 fmt2 =udat_open(UDAT_PATTERN, UDAT_PATTERN,"en_US", zoneGMT, -1, pattern, u_strlen(pattern), &status);
1735 assertSuccess("udat_open() with en_US", &status);
1736
1737 overrideFmt2 = unum_open(UNUM_DEFAULT, NULL, 0, localeString, NULL, &status);
1738 assertSuccess("unum_open() in loop", &status);
1739
1740 u_uastrcpy(fields, overrideNumberFormat[i][0]);
1741 u_unescape(overrideNumberFormat[i][1], expected, UPRV_LENGTHOF(expected));
1742
1743 if ( strcmp(overrideNumberFormat[i][0], "") == 0 ) { // use the one w/o field
1744 udat_adoptNumberFormat(fmt2, overrideFmt2);
1745 } else if ( strcmp(overrideNumberFormat[i][0], "mixed") == 0 ) { // set 1 field at first but then full override, both(M & d) should be override
1746 const char* singleLocale = "en@numbers=hebr";
1747 UNumberFormat* singleOverrideFmt;
1748 u_uastrcpy(fields, "d");
1749
1750 singleOverrideFmt = unum_open(UNUM_DEFAULT, NULL, 0, singleLocale, NULL, &status);
1751 assertSuccess("unum_open() in mixed", &status);
1752
1753 udat_adoptNumberFormatForFields(fmt2, fields, singleOverrideFmt, &status);
1754 assertSuccess("udat_setNumberFormatForField() in mixed", &status);
1755
1756 udat_adoptNumberFormat(fmt2, overrideFmt2);
1757 } else if ( strcmp(overrideNumberFormat[i][0], "do") == 0 ) { // o is an invalid field
1758 udat_adoptNumberFormatForFields(fmt2, fields, overrideFmt2, &status);
1759 if(status == U_INVALID_FORMAT_ERROR) {
1760 udat_close(fmt2);
1761 status = U_ZERO_ERROR;
1762 continue;
1763 }
1764 } else {
1765 udat_adoptNumberFormatForFields(fmt2, fields, overrideFmt2, &status);
1766 assertSuccess("udat_setNumberFormatForField() in loop", &status);
1767 }
1768
1769 udat_format(fmt2, july022008, ubuf, kUbufMax, NULL, &status);
1770 assertSuccess("udat_format() july022008", &status);
1771
1772 if (u_strncmp(ubuf, expected, kUbufMax) != 0)
1773 log_err("fail: udat_format for locale, expected %s, got %s\n",
1774 u_austrncpy(bbuf1,expected,kUbufMax), u_austrncpy(bbuf2,ubuf,kUbufMax) );
1775
1776 udat_close(fmt2);
1777 }
1778}
1779
1780/*
1781 * Ticket #11523
1782 * udat_parse and udat_parseCalendar should have the same error code when given the same invalid input.
1783 */
1784static void TestParseErrorReturnValue(void) {
1785 UErrorCode status = U_ZERO_ERROR;
1786 UErrorCode expectStatus = U_PARSE_ERROR;
1787 UDateFormat* df;
1788 UCalendar* cal;
1789
1790 df = udat_open(UDAT_DEFAULT, UDAT_DEFAULT, NULL, NULL, -1, NULL, -1, &status);
1791 if (!assertSuccessCheck("udat_open()", &status, TRUE)) {
1792 return;
1793 }
1794
1795 cal = ucal_open(NULL, 0, "en_US", UCAL_GREGORIAN, &status);
1796 if (!assertSuccess("ucal_open()", &status)) {
1797 return;
1798 }
1799
1800 udat_parse(df, NULL, -1, NULL, &status);
1801 if (status != expectStatus) {
1802 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));
1803 }
1804
1805 status = U_ZERO_ERROR;
1806 udat_parseCalendar(df, cal, NULL, -1, NULL, &status);
1807 if (status != expectStatus) {
1808 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));
1809 }
1810
1811 ucal_close(cal);
1812 udat_close(df);
1813}
1814
1815/*
1816 * Ticket #11553
1817 * Test new udat_formatForFields, udat_formatCalendarForFields (and UFieldPositionIterator)
1818 */
1819static const char localeForFields[] = "en_US";
1820/* zoneGMT[]defined above */
1821static const UDate date2015Feb25 = 1424841000000.0; /* Wednesday, February 25, 2015 at 5:10:00 AM GMT */
1822
1823typedef struct {
1824 int32_t field;
1825 int32_t beginPos;
1826 int32_t endPos;
1827} FieldsData;
1828static const FieldsData expectedFields[] = {
1829 { UDAT_DAY_OF_WEEK_FIELD /* 9*/, 0, 9 },
1830 { UDAT_MONTH_FIELD /* 2*/, 11, 19 },
1831 { UDAT_DATE_FIELD /* 3*/, 20, 22 },
1832 { UDAT_YEAR_FIELD /* 1*/, 24, 28 },
1833 { UDAT_HOUR1_FIELD /*15*/, 32, 33 },
1834#if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
1835 { UDAT_TIME_SEPARATOR_FIELD /*35*/, 33, 34 },
1836#endif
1837 { UDAT_MINUTE_FIELD /* 6*/, 34, 36 },
1838#if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR
1839 { UDAT_TIME_SEPARATOR_FIELD /*35*/, 36, 37 },
1840#endif
1841 { UDAT_SECOND_FIELD /* 7*/, 37, 39 },
1842 { UDAT_AM_PM_FIELD /*14*/, 40, 42 },
1843 { UDAT_TIMEZONE_FIELD /*17*/, 43, 46 },
1844 { -1, -1, -1 },
1845};
1846
1847enum {kUBufFieldsLen = 128, kBBufFieldsLen = 256 };
1848
1849static void TestFormatForFields(void) {
1850 UErrorCode status = U_ZERO_ERROR;
1851 UFieldPositionIterator* fpositer = ufieldpositer_open(&status);
1852 if ( U_FAILURE(status) ) {
1853 log_err("ufieldpositer_open fails, status %s\n", u_errorName(status));
1854 } else {
1855 UDateFormat* udfmt = udat_open(UDAT_LONG, UDAT_FULL, localeForFields, zoneGMT, -1, NULL, 0, &status);
1856 UCalendar* ucal = ucal_open(zoneGMT, -1, localeForFields, UCAL_DEFAULT, &status);
1857 if ( U_FAILURE(status) ) {
1858 log_data_err("udat_open or ucal_open fails for locale %s, status %s (Are you missing data?)\n", localeForFields, u_errorName(status));
1859 } else {
1860 int32_t ulen, field, beginPos, endPos;
1861 UChar ubuf[kUBufFieldsLen];
1862 const FieldsData * fptr;
1863
1864 status = U_ZERO_ERROR;
1865 ulen = udat_formatForFields(udfmt, date2015Feb25, ubuf, kUBufFieldsLen, fpositer, &status);
1866 if ( U_FAILURE(status) ) {
1867 log_err("udat_formatForFields fails, status %s\n", u_errorName(status));
1868 } else {
1869 for (fptr = expectedFields; ; fptr++) {
1870 field = ufieldpositer_next(fpositer, &beginPos, &endPos);
1871 if (field != fptr->field || (field >= 0 && (beginPos != fptr->beginPos || endPos != fptr->endPos))) {
1872 if (fptr->field >= 0) {
1873 log_err("udat_formatForFields as \"%s\"; expect field %d range %d-%d, get field %d range %d-%d\n",
1874 aescstrdup(ubuf, ulen), fptr->field, fptr->beginPos, fptr->endPos, field, beginPos, endPos);
1875 } else {
1876 log_err("udat_formatForFields as \"%s\"; expect field < 0, get field %d range %d-%d\n",
1877 aescstrdup(ubuf, ulen), field, beginPos, endPos);
1878 }
1879 break;
1880 }
1881 if (field < 0) {
1882 break;
1883 }
1884 }
1885 }
1886
1887 ucal_setMillis(ucal, date2015Feb25, &status);
1888 status = U_ZERO_ERROR;
1889 ulen = udat_formatCalendarForFields(udfmt, ucal, ubuf, kUBufFieldsLen, fpositer, &status);
1890 if ( U_FAILURE(status) ) {
1891 log_err("udat_formatCalendarForFields fails, status %s\n", u_errorName(status));
1892 } else {
1893 for (fptr = expectedFields; ; fptr++) {
1894 field = ufieldpositer_next(fpositer, &beginPos, &endPos);
1895 if (field != fptr->field || (field >= 0 && (beginPos != fptr->beginPos || endPos != fptr->endPos))) {
1896 if (fptr->field >= 0) {
1897 log_err("udat_formatFudat_formatCalendarForFieldsorFields as \"%s\"; expect field %d range %d-%d, get field %d range %d-%d\n",
1898 aescstrdup(ubuf, ulen), fptr->field, fptr->beginPos, fptr->endPos, field, beginPos, endPos);
1899 } else {
1900 log_err("udat_formatCalendarForFields as \"%s\"; expect field < 0, get field %d range %d-%d\n",
1901 aescstrdup(ubuf, ulen), field, beginPos, endPos);
1902 }
1903 break;
1904 }
1905 if (field < 0) {
1906 break;
1907 }
1908 }
1909 }
1910
1911 ucal_close(ucal);
1912 udat_close(udfmt);
1913 }
1914 ufieldpositer_close(fpositer);
1915 }
1916}
1917
1918/* defined above
1919static const UChar zoneGMT[] = { 0x47,0x4D,0x54,0 }; // "GMT"
1920static const UDate date2015Feb25 = 1424841000000.0; // Wednesday, February 25, 2015 at 5:10:00 AM GMT
1921*/
1922
1923typedef struct {
1924 const char * locale;
1925 UDateFormatStyle dateStyle;
1926 UDateFormatStyle timeStyle;
1927 const char * expect; /* for zoneGMT and date2015Feb25 */
1928} StandardPatternItem;
1929
1930static const StandardPatternItem stdPatternItems[] = {
1931 { "en_JP", UDAT_MEDIUM, UDAT_SHORT, "Feb 25, 2015 5:10" },
1932 { "en_CN", UDAT_MEDIUM, UDAT_SHORT, "25 Feb 2015, 5:10 AM" },
1933 { "en_TW", UDAT_MEDIUM, UDAT_SHORT, "25 Feb 2015, 5:10 AM" },
1934 { "en_KR", UDAT_MEDIUM, UDAT_SHORT, "25 Feb 2015, 5:10 AM" },
1935 { NULL, (UDateFormatStyle)0, (UDateFormatStyle)0, NULL } /* terminator */
1936};
1937
1938enum { kUbufStdMax = 64, kBbufStdMax = 3*kUbufStdMax };
1939
1940static void TestStandardPatterns(void) {
1941 const StandardPatternItem* itemPtr;
1942 for (itemPtr = stdPatternItems; itemPtr->locale != NULL; itemPtr++) {
1943 UErrorCode status = U_ZERO_ERROR;
1944 UDateFormat* udfmt = udat_open(itemPtr->timeStyle, itemPtr->dateStyle, itemPtr->locale, zoneGMT, -1, NULL, 0, &status);
1945 if ( U_FAILURE(status) ) {
1946 log_err("udat_open(%d, %d, \"%s\",...) fails, status %s\n",
1947 (int)itemPtr->timeStyle, (int)itemPtr->dateStyle, itemPtr->locale, u_errorName(status));
1948 } else {
1949 UChar uget[kUbufStdMax];
1950 int32_t ugetlen = udat_format(udfmt, date2015Feb25, uget, kUbufStdMax, NULL, &status);
1951 if ( U_FAILURE(status) ) {
1952 log_err("udat_format for (%d, %d, \"%s\",...) fails, status %s\n",
1953 (int)itemPtr->timeStyle, (int)itemPtr->dateStyle, itemPtr->locale, u_errorName(status));
1954 } else {
1955 UChar uexpect[kUbufStdMax];
1956 int32_t uexpectlen = u_unescape(itemPtr->expect, uexpect, kUbufStdMax);
1957 if (ugetlen != uexpectlen || u_strncmp(uget, uexpect, uexpectlen) != 0) {
1958 char bexpect[kBbufStdMax];
1959 char bget[kBbufStdMax];
1960 u_austrcpy(bexpect, uexpect);
1961 u_austrcpy(bget, uget);
1962 log_err("udat_format for (%d, %d, \"%s\",...):\n expect %s\n get %s\n",
1963 (int)itemPtr->timeStyle, (int)itemPtr->dateStyle, itemPtr->locale, bexpect, bget);
1964 }
1965 }
1966 udat_close(udfmt);
1967 }
1968 }
1969}
1970
1971/* defined above
1972static const UChar zoneGMT[] = { 0x47,0x4D,0x54,0 }; // "GMT"
1973static const UDate date2015Feb25 = 1424841000000.0; // Wednesday, February 25, 2015 at 5:10:00 AM GMT
1974*/
1975static const UChar patternHmm[] = { 0x48,0x3A,0x6D,0x6D,0 }; /* "H:mm" */
1976static const UChar formattedHmm[] = { 0x35,0x3A,0x31,0x30,0 }; /* "5:10" */
1977
1978enum { kUBufOverrideSepMax = 32, kBBufOverrideSepMax = 64 };
1979
1980static void TestApplyPatnOverridesTimeSep(void) {
1981 UErrorCode status;
1982 UDateFormat* udfmt;
1983 const char *locale = "da"; /* uses period for time separator */
1984 UChar ubuf[kUBufOverrideSepMax];
1985 int32_t ulen;
1986
1987 status = U_ZERO_ERROR;
1988 udfmt = udat_open(UDAT_PATTERN, UDAT_PATTERN, locale, zoneGMT, -1, patternHmm, -1, &status);
1989 if ( U_FAILURE(status) ) {
1990 log_err("udat_open(UDAT_PATTERN, UDAT_PATTERN, \"%s\",...) fails, status %s\n", locale, u_errorName(status));
1991 } else {
1992 ulen = udat_format(udfmt, date2015Feb25, ubuf, kUBufOverrideSepMax, NULL, &status);
1993 if ( U_FAILURE(status) ) {
1994 log_err("udat_format fails for UDAT_PATTERN \"%s\", status %s\n", locale, u_errorName(status));
1995 } else if (u_strcmp(ubuf, formattedHmm) != 0) {
1996 char bbuf[kBBufOverrideSepMax];
1997 u_strToUTF8(bbuf, kBBufOverrideSepMax, NULL, ubuf, ulen, &status);
1998 log_err("udat_format fails for UDAT_PATTERN \"%s\", expected 5:10, got %s\n", locale, bbuf);
1999 }
2000 udat_close(udfmt);
2001 }
2002
2003 status = U_ZERO_ERROR;
2004 udfmt = udat_open(UDAT_SHORT, UDAT_NONE, locale, zoneGMT, -1, NULL, 0, &status);
2005 if ( U_FAILURE(status) ) {
2006 log_err("udat_open(UDAT_SHORT, UDAT_NONE, \"%s\",...) fails, status %s\n", locale, u_errorName(status));
2007 } else {
2008 udat_applyPattern(udfmt, FALSE, patternHmm, -1);
2009 ulen = udat_format(udfmt, date2015Feb25, ubuf, kUBufOverrideSepMax, NULL, &status);
2010 if ( U_FAILURE(status) ) {
2011 log_err("udat_format fails for UDAT_SHORT \"%s\" + applyPattern, status %s\n", locale, u_errorName(status));
2012 } else if (u_strcmp(ubuf, formattedHmm) != 0) {
2013 char bbuf[kBBufOverrideSepMax];
2014 u_strToUTF8(bbuf, kBBufOverrideSepMax, NULL, ubuf, ulen, &status);
2015 log_err("udat_format fails for UDAT_SHORT \"%s\" + applyPattern, expected 5:10, got %s\n", locale, bbuf);
2016 }
2017 udat_close(udfmt);
2018 }
2019
2020}
2021
2022#define UDATE_SECOND (1000.0)
2023#define UDATE_MINUTE (60.0*UDATE_SECOND)
2024#define UDATE_HOUR (60.0*UDATE_MINUTE)
2025
2026static const double dayOffsets[] = {
2027 0.0, /* 00:00:00 */
2028 UDATE_SECOND, /* 00:00:01 */
2029 UDATE_MINUTE, /* 00:01:00 */
2030 UDATE_HOUR, /* 01:00:00 */
2031 11.0*UDATE_HOUR + 59.0*UDATE_MINUTE, /* 11:59:00 */
2032 12.0*UDATE_HOUR, /* 12:00:00 */
2033 12.0*UDATE_HOUR + UDATE_SECOND, /* 12:00:01 */
2034 12.0*UDATE_HOUR + UDATE_MINUTE, /* 12:01:00 */
2035 13.0*UDATE_HOUR, /* 13:00:00 */
2036 23.0*UDATE_HOUR + 59.0*UDATE_MINUTE, /* 23:59:00 */
2037};
2038enum { kNumDayOffsets = UPRV_LENGTHOF(dayOffsets) };
2039
2040static const char* ja12HrFmt_hm[kNumDayOffsets] = { /* aK:mm */
2041 "\\u5348\\u524D0:00", /* "午前0:00" */
2042 "\\u5348\\u524D0:00",
2043 "\\u5348\\u524D0:01",
2044 "\\u5348\\u524D1:00",
2045 "\\u5348\\u524D11:59",
2046 "\\u5348\\u5F8C0:00", /* "午後0:00" */
2047 "\\u5348\\u5F8C0:00",
2048 "\\u5348\\u5F8C0:01", /* "午後0:01" */
2049 "\\u5348\\u5F8C1:00",
2050 "\\u5348\\u5F8C11:59",
2051};
2052
2053static const char* ja12HrFmt_h[kNumDayOffsets] = { /* aK時 */
2054 "\\u5348\\u524D0\\u6642", /* "午前0時" */
2055 "\\u5348\\u524D0\\u6642",
2056 "\\u5348\\u524D0\\u6642",
2057 "\\u5348\\u524D1\\u6642",
2058 "\\u5348\\u524D11\\u6642",
2059 "\\u5348\\u5F8C0\\u6642", /* "午後0時" */
2060 "\\u5348\\u5F8C0\\u6642",
2061 "\\u5348\\u5F8C0\\u6642", /* "午後0時" */
2062 "\\u5348\\u5F8C1\\u6642",
2063 "\\u5348\\u5F8C11\\u6642",
2064};
2065typedef struct {
2066 const char* locale;
2067 const char* skeleton;
2068 const char ** expected;
2069} Test12HrFmtItem;
2070
2071static const Test12HrFmtItem test12HrFmtItems[] = {
2072 { "ja", "hm", ja12HrFmt_hm },
2073 { "ja", "h", ja12HrFmt_h },
2074 { NULL, NULL, NULL } /* terminator */
2075};
2076
2077enum { kUBufMax = 128, };
2078static void Test12HrFormats(void) {
2079 const Test12HrFmtItem* itemPtr;
2080 for (itemPtr = test12HrFmtItems; itemPtr->locale != NULL; itemPtr++) {
2081 UErrorCode status = U_ZERO_ERROR;
2082 UCalendar* ucal = ucal_open(NULL, 0, itemPtr->locale, UCAL_DEFAULT, &status);
2083 if ( U_FAILURE(status) ) {
2084 log_data_err("ucal_open fails for locale %s: status %s (Are you missing data?)\n", itemPtr->locale, u_errorName(status));
2085 } else {
2086 ucal_clear(ucal);
2087 ucal_setDateTime(ucal, 2016, UCAL_JANUARY, 1, 0, 0, 0, &status);
2088 UDate baseDate = ucal_getMillis(ucal, &status);
2089 if ( U_FAILURE(status) ) {
2090 log_err("ucal_setDateTime or ucal_getMillis fails for locale %s: status %s\n", itemPtr->locale, u_errorName(status));
2091 } else {
2092 UDateTimePatternGenerator* udatpg = udatpg_open(itemPtr->locale, &status);
2093 if ( U_FAILURE(status) ) {
2094 log_data_err("udatpg_open fails for locale %s: status %s (Are you missing data?)\n", itemPtr->locale, u_errorName(status));
2095 } else {
2096 UChar ubuf1[kUbufMax], ubuf2[kUbufMax];
2097 int32_t ulen1 = u_unescape(itemPtr->skeleton, ubuf1, kUbufMax);
2098 int32_t ulen2 = udatpg_getBestPattern(udatpg, ubuf1, ulen1, ubuf2, kUbufMax, &status);
2099 if ( U_FAILURE(status) ) {
2100 log_err("udatpg_getBestPattern fails for locale %s, skeleton %s: status %s\n",
2101 itemPtr->locale, itemPtr->skeleton, u_errorName(status));
2102 } else {
2103 UDateFormat* udat = udat_open(UDAT_PATTERN, UDAT_PATTERN, itemPtr->locale, NULL, 0, ubuf2, ulen2, &status);
2104 if ( U_FAILURE(status) ) {
2105 log_data_err("udat_open fails for locale %s, skeleton %s: status %s (Are you missing data?)\n",
2106 itemPtr->locale, itemPtr->skeleton, u_errorName(status));
2107 } else {
2108 int32_t iDayOffset;
2109 for (iDayOffset = 0; iDayOffset < kNumDayOffsets; iDayOffset++) {
2110 status = U_ZERO_ERROR;
2111 ulen1 = udat_format(udat, baseDate + dayOffsets[iDayOffset], ubuf1, kUbufMax, NULL, &status);
2112 if ( U_FAILURE(status) ) {
2113 log_err("udat_format fails for locale %s, skeleton %s, iDayOffset %d: status %s\n",
2114 itemPtr->locale, itemPtr->skeleton, iDayOffset, u_errorName(status));
2115 } else {
2116 ulen2 = u_unescape(itemPtr->expected[iDayOffset], ubuf2, kUbufMax);
2117 if (ulen1 != ulen2 || u_strncmp(ubuf1, ubuf2, ulen2) != 0) {
2118 char bbuf1[kBbufMax], bbuf2[kBbufMax];
2119 u_austrncpy(bbuf1, ubuf1, ulen1);
2120 u_austrncpy(bbuf2, ubuf2, ulen2);
2121 log_err("udat_format fails for locale %s, skeleton %s, iDayOffset %d:\n expect %s\n get %s\n",
2122 itemPtr->locale, itemPtr->skeleton, iDayOffset, bbuf2, bbuf1);
2123 }
2124 }
2125
2126 }
2127 udat_close(udat);
2128 }
2129 }
2130 udatpg_close(udatpg);
2131 }
2132 }
2133 ucal_close(ucal);
2134 }
2135 }
2136}
2137
2138/* *** */
2139
2140typedef struct {
2141 const char* locale;
2142 UATimeUnitTimePattern patType;
2143 const char* expect; /* universal char subset + escaped Unicode chars */
2144} TimePatternItem;
2145static const TimePatternItem timePatternItems[] = {
2146 { "en", UATIMEUNITTIMEPAT_HM, "h:mm" },
2147 { "en", UATIMEUNITTIMEPAT_HMS, "h:mm:ss" },
2148 { "en", UATIMEUNITTIMEPAT_MS, "m:ss" },
2149 { "da", UATIMEUNITTIMEPAT_HM, "h.mm" },
2150 { "da", UATIMEUNITTIMEPAT_HMS, "h.mm.ss" },
2151 { "da", UATIMEUNITTIMEPAT_MS, "m.ss" },
2152 { NULL, 0, NULL }
2153};
2154
2155typedef struct {
2156 const char* locale;
2157 UATimeUnitStyle width;
2158 UATimeUnitListPattern patType;
2159 const char* expect; /* universal char subset + escaped Unicode chars */
2160} ListPatternItem;
2161static const ListPatternItem listPatternItems[] = {
2162 { "en", UATIMEUNITSTYLE_FULL, UATIMEUNITLISTPAT_TWO_ONLY, "{0}, {1}" },
2163 { "en", UATIMEUNITSTYLE_FULL, UATIMEUNITLISTPAT_END_PIECE, "{0}, {1}" },
2164 { "en", UATIMEUNITSTYLE_FULL, UATIMEUNITLISTPAT_MIDDLE_PIECE, "{0}, {1}" },
2165 { "en", UATIMEUNITSTYLE_FULL, UATIMEUNITLISTPAT_START_PIECE, "{0}, {1}" },
2166 { "en", UATIMEUNITSTYLE_NARROW, UATIMEUNITLISTPAT_TWO_ONLY, "{0} {1}" },
2167 { "en", UATIMEUNITSTYLE_NARROW, UATIMEUNITLISTPAT_END_PIECE, "{0} {1}" },
2168 { "en", UATIMEUNITSTYLE_NARROW, UATIMEUNITLISTPAT_MIDDLE_PIECE, "{0} {1}" },
2169 { "en", UATIMEUNITSTYLE_NARROW, UATIMEUNITLISTPAT_START_PIECE, "{0} {1}" },
2170 { "en", UATIMEUNITSTYLE_SHORTER, UATIMEUNITLISTPAT_TWO_ONLY, "{0} {1}" },
2171 { "fr", UATIMEUNITSTYLE_FULL, UATIMEUNITLISTPAT_TWO_ONLY, "{0} et {1}" },
2172 { "fr", UATIMEUNITSTYLE_FULL, UATIMEUNITLISTPAT_END_PIECE, "{0} et {1}" },
2173 { "fr", UATIMEUNITSTYLE_FULL, UATIMEUNITLISTPAT_MIDDLE_PIECE, "{0}, {1}" },
2174 { "fr", UATIMEUNITSTYLE_FULL, UATIMEUNITLISTPAT_START_PIECE, "{0}, {1}" },
2175 { "fr", UATIMEUNITSTYLE_NARROW, UATIMEUNITLISTPAT_TWO_ONLY, "{0} {1}" },
2176 { "fr", UATIMEUNITSTYLE_NARROW, UATIMEUNITLISTPAT_END_PIECE, "{0} {1}" },
2177 { "fr", UATIMEUNITSTYLE_NARROW, UATIMEUNITLISTPAT_MIDDLE_PIECE, "{0} {1}" },
2178 { "fr", UATIMEUNITSTYLE_NARROW, UATIMEUNITLISTPAT_START_PIECE, "{0} {1}" },
2179 { "fr", UATIMEUNITSTYLE_SHORTER, UATIMEUNITLISTPAT_TWO_ONLY, "{0} {1}" },
2180 { NULL, 0, 0, NULL }
2181};
2182
2183enum {kUBufTimeUnitLen = 128, kBBufTimeUnitLen = 256 };
2184
2185static void TestTimeUnitFormat(void) { /* Apple-specific */
2186 const TimePatternItem* timePatItemPtr;
2187 const ListPatternItem* listPatItemPtr;
2188 UChar uActual[kUBufTimeUnitLen];
2189 UChar uExpect[kUBufTimeUnitLen];
2190
2191 for (timePatItemPtr = timePatternItems; timePatItemPtr->locale != NULL; timePatItemPtr++) {
2192 UErrorCode status = U_ZERO_ERROR;
2193 int32_t ulenActual = uatmufmt_getTimePattern(timePatItemPtr->locale, timePatItemPtr->patType, uActual, kUBufTimeUnitLen, &status);
2194 if ( U_FAILURE(status) ) {
2195 log_err("uatmufmt_getTimePattern for locale %s, patType %d: status %s\n", timePatItemPtr->locale, (int)timePatItemPtr->patType, u_errorName(status));
2196 } else {
2197 int32_t ulenExpect = u_unescape(timePatItemPtr->expect, uExpect, kUBufTimeUnitLen);
2198 if (ulenActual != ulenExpect || u_strncmp(uActual, uExpect, ulenExpect) != 0) {
2199 char bActual[kBBufTimeUnitLen];
2200 u_strToUTF8(bActual, kBBufTimeUnitLen, NULL, uActual, ulenActual, &status);
2201 log_err("uatmufmt_getTimePattern for locale %s, patType %d: unexpected result %s\n", timePatItemPtr->locale, (int)timePatItemPtr->patType, bActual);
2202 }
2203 }
2204 }
2205
2206 for (listPatItemPtr = listPatternItems; listPatItemPtr->locale != NULL; listPatItemPtr++) {
2207 UErrorCode status = U_ZERO_ERROR;
2208 int32_t ulenActual = uatmufmt_getListPattern(listPatItemPtr->locale, listPatItemPtr->width, listPatItemPtr->patType, uActual, kUBufTimeUnitLen, &status);
2209 if ( U_FAILURE(status) ) {
2210 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));
2211 } else {
2212 int32_t ulenExpect = u_unescape(listPatItemPtr->expect, uExpect, kUBufTimeUnitLen);
2213 if (ulenActual != ulenExpect || u_strncmp(uActual, uExpect, ulenExpect) != 0) {
2214 char bActual[kBBufTimeUnitLen];
2215 u_strToUTF8(bActual, kBBufTimeUnitLen, NULL, uActual, ulenActual, &status);
2216 log_err("uatmufmt_getListPattern for locale %s, width %d, patType %d: unexpected result %s\n", listPatItemPtr->locale, (int)listPatItemPtr->width, (int)listPatItemPtr->patType, bActual);
2217 }
2218 }
2219 }
2220
2221}
2222
2223typedef enum RemapTesttype {
2224 REMAP_TESTTYPE_FULL = UDAT_FULL, // 0
2225 REMAP_TESTTYPE_LONG = UDAT_LONG, // 1
2226 REMAP_TESTTYPE_MEDIUM = UDAT_MEDIUM, // 2
2227 REMAP_TESTTYPE_SHORT = UDAT_SHORT, // 3
2228 REMAP_TESTTYPE_LONG_DF = UDAT_LONG + 4, // 5 long time, full date
2229 REMAP_TESTTYPE_SHORT_DS = UDAT_SHORT + 16, // 3 short time, short date
2230 REMAP_TESTTYPE_SKELETON = -1,
2231 REMAP_TESTTYPE_PATTERN = -2,
2232} RemapTesttype;
2233
2234typedef struct {
2235 const char * pattern;
2236 RemapTesttype testtype;
2237 uint32_t options;
2238} RemapPatternTestItem;
2239
2240static const RemapPatternTestItem remapPatItems[] = {
2241 { "full", REMAP_TESTTYPE_FULL, 0 },
2242 { "full", REMAP_TESTTYPE_FULL, UADATPG_FORCE_24_HOUR_CYCLE },
2243 { "full", REMAP_TESTTYPE_FULL, UADATPG_FORCE_12_HOUR_CYCLE },
2244 { "long", REMAP_TESTTYPE_LONG, 0 },
2245 { "long", REMAP_TESTTYPE_LONG, UADATPG_FORCE_24_HOUR_CYCLE },
2246 { "long", REMAP_TESTTYPE_LONG, UADATPG_FORCE_12_HOUR_CYCLE },
2247 { "medium", REMAP_TESTTYPE_MEDIUM, 0 },
2248 { "medium", REMAP_TESTTYPE_MEDIUM, UADATPG_FORCE_24_HOUR_CYCLE },
2249 { "medium", REMAP_TESTTYPE_MEDIUM, UADATPG_FORCE_12_HOUR_CYCLE },
2250 { "short", REMAP_TESTTYPE_SHORT, 0 },
2251 { "short", REMAP_TESTTYPE_SHORT, UADATPG_FORCE_24_HOUR_CYCLE },
2252 { "short", REMAP_TESTTYPE_SHORT, UADATPG_FORCE_12_HOUR_CYCLE },
2253 { "long_df", REMAP_TESTTYPE_LONG_DF, 0 },
2254 { "long_df", REMAP_TESTTYPE_LONG_DF, UADATPG_FORCE_24_HOUR_CYCLE },
2255 { "long_df", REMAP_TESTTYPE_LONG_DF, UADATPG_FORCE_12_HOUR_CYCLE },
2256 { "short_ds", REMAP_TESTTYPE_SHORT_DS, 0 },
2257 { "short_ds", REMAP_TESTTYPE_SHORT_DS, UADATPG_FORCE_24_HOUR_CYCLE },
2258 { "short_ds", REMAP_TESTTYPE_SHORT_DS, UADATPG_FORCE_12_HOUR_CYCLE },
2259
2260 { "jmmss", REMAP_TESTTYPE_SKELETON, 0 },
2261 { "jmmss", REMAP_TESTTYPE_SKELETON, UADATPG_FORCE_24_HOUR_CYCLE },
2262 { "jmmss", REMAP_TESTTYPE_SKELETON, UADATPG_FORCE_12_HOUR_CYCLE },
2263 { "jjmmss", REMAP_TESTTYPE_SKELETON, 0 },
2264 { "jjmmss", REMAP_TESTTYPE_SKELETON, UADATPG_FORCE_24_HOUR_CYCLE },
2265 { "jjmmss", REMAP_TESTTYPE_SKELETON, UADATPG_FORCE_24_HOUR_CYCLE | UDATPG_MATCH_HOUR_FIELD_LENGTH },
2266 { "jjmmss", REMAP_TESTTYPE_SKELETON, UADATPG_FORCE_12_HOUR_CYCLE },
2267 { "jjmmss", REMAP_TESTTYPE_SKELETON, UADATPG_FORCE_12_HOUR_CYCLE | UDATPG_MATCH_HOUR_FIELD_LENGTH },
2268 { "Jmm", REMAP_TESTTYPE_SKELETON, 0 },
2269 { "Jmm", REMAP_TESTTYPE_SKELETON, UADATPG_FORCE_24_HOUR_CYCLE },
2270 { "Jmm", REMAP_TESTTYPE_SKELETON, UADATPG_FORCE_12_HOUR_CYCLE },
2271 { "jmsv", REMAP_TESTTYPE_SKELETON, 0 },
2272 { "jmsv", REMAP_TESTTYPE_SKELETON, UADATPG_FORCE_24_HOUR_CYCLE },
2273 { "jmsv", REMAP_TESTTYPE_SKELETON, UADATPG_FORCE_12_HOUR_CYCLE },
2274 { "jmsz", REMAP_TESTTYPE_SKELETON, 0 },
2275 { "jmsz", REMAP_TESTTYPE_SKELETON, UADATPG_FORCE_24_HOUR_CYCLE },
2276 { "jmsz", REMAP_TESTTYPE_SKELETON, UADATPG_FORCE_12_HOUR_CYCLE },
2277
2278 { "h:mm:ss a", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_12_HOUR_CYCLE }, // 12=hour patterns
2279 { "h:mm:ss a", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_24_HOUR_CYCLE },
2280 { "a'xx'h:mm:ss d MMM y", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_12_HOUR_CYCLE },
2281 { "a'xx'h:mm:ss d MMM y", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_24_HOUR_CYCLE },
2282 { "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_12_HOUR_CYCLE },
2283 { "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_24_HOUR_CYCLE },
2284 { "EEE, d MMM y 'aha' a'xx'h:mm:ss", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_12_HOUR_CYCLE },
2285 { "EEE, d MMM y 'aha' a'xx'h:mm:ss", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_24_HOUR_CYCLE },
2286 { "yyMMddhhmmss", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_12_HOUR_CYCLE },
2287 { "yyMMddhhmmss", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_24_HOUR_CYCLE },
2288
2289 { "H:mm:ss", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_12_HOUR_CYCLE }, // 24=hour patterns
2290 { "H:mm:ss", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_24_HOUR_CYCLE },
2291 { "H:mm:ss d MMM y", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_12_HOUR_CYCLE },
2292 { "H:mm:ss d MMM y", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_24_HOUR_CYCLE },
2293 { "EEE, d MMM y 'aha' H:mm:ss 'hrs'", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_12_HOUR_CYCLE },
2294 { "EEE, d MMM y 'aha' H:mm:ss 'hrs'", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_24_HOUR_CYCLE },
2295 { "EEE, d MMM y 'aha' H'h'mm'm'ss", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_12_HOUR_CYCLE },
2296 { "EEE, d MMM y 'aha' H'h'mm'm'ss", REMAP_TESTTYPE_PATTERN, UADATPG_FORCE_24_HOUR_CYCLE },
2297 { NULL, (RemapTesttype)0, 0 }
2298};
2299
2300static const char * remapResults_root[] = {
2301 "HH:mm:ss zzzz", // full
2302 "HH:mm:ss zzzz", // force24
2303 "h:mm:ss a zzzz", // force12
2304 "HH:mm:ss z", // long
2305 "HH:mm:ss z", // force24
2306 "h:mm:ss a z", // force12
2307 "HH:mm:ss", // medium
2308 "HH:mm:ss", // force24
2309 "h:mm:ss a", // force12
2310 "HH:mm", // short
2311 "HH:mm", // force24
2312 "h:mm a", // force12
2313 "y MMMM d, EEEE HH:mm:ss z", // long_df
2314 "y MMMM d, EEEE HH:mm:ss z", // force24
2315 "y MMMM d, EEEE h:mm:ss a z", // force12
2316 "y-MM-dd HH:mm", // short_ds
2317 "y-MM-dd HH:mm", // force24
2318 "y-MM-dd h:mm a", // force12
2319
2320 "HH:mm:ss", // jmmss
2321 "HH:mm:ss", // force24
2322 "h:mm:ss a", // force12
2323 "HH:mm:ss", // jjmmss
2324 "HH:mm:ss", // force24
2325 "HH:mm:ss", // force24 | match hour field length
2326 "h:mm:ss a", // force12
2327 "hh:mm:ss a", // force12 | match hour field length
2328 "HH:mm", // Jmm
2329 "HH:mm", // force24
2330 "hh:mm", // force12
2331 "HH:mm:ss v", // jmsv
2332 "HH:mm:ss v", // force24
2333 "h:mm:ss a v", // force12
2334 "HH:mm:ss z", // jmsz
2335 "HH:mm:ss z", // force24
2336 "h:mm:ss a z", // force12
2337
2338 "h:mm:ss a", // "h:mm:ss"
2339 "HH:mm:ss", //
2340 "a'xx'h:mm:ss d MMM y", // "a'xx'h:mm:ss d MMM y"
2341 "HH:mm:ss d MMM y", //
2342 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' h:mm:ss a 'hrs'"
2343 "EEE, d MMM y 'aha' HH:mm:ss 'hrs'", //
2344 "EEE, d MMM y 'aha' a'xx'h:mm:ss", // "EEE, d MMM y 'aha' a'xx'h:mm:ss"
2345 "EEE, d MMM y 'aha' HH:mm:ss", //
2346 "yyMMddhhmmss", // "yyMMddhhmmss"
2347 "yyMMddHHmmss", //
2348
2349 "h:mm:ss a", // "H:mm:ss"
2350 "H:mm:ss", //
2351 "h:mm:ss a d MMM y", // "H:mm:ss d MMM y"
2352 "H:mm:ss d MMM y", //
2353 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' H:mm:ss 'hrs'"
2354 "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
2355 "EEE, d MMM y 'aha' h'h'mm'm'ss a", // "EEE, d MMM y 'aha' H'h'mm'm'ss"
2356 "EEE, d MMM y 'aha' H'h'mm'm'ss", //
2357 NULL
2358};
2359
2360static const char * remapResults_en[] = {
2361 "h:mm:ss a zzzz", // full
2362 "HH:mm:ss zzzz", // force24
2363 "h:mm:ss a zzzz", // force12
2364 "h:mm:ss a z", // long
2365 "HH:mm:ss z", // force24
2366 "h:mm:ss a z", // force12
2367 "h:mm:ss a", // medium
2368 "HH:mm:ss", // force24
2369 "h:mm:ss a", // force12
2370 "h:mm a", // short
2371 "HH:mm", // force24
2372 "h:mm a", // force12
2373 "EEEE, MMMM d, y 'at' h:mm:ss a z", // long_df
2374 "EEEE, MMMM d, y 'at' HH:mm:ss z", // force24
2375 "EEEE, MMMM d, y 'at' h:mm:ss a z", // force12
2376 "M/d/yy, h:mm a", // short_ds
2377 "M/d/yy, HH:mm", // force24
2378 "M/d/yy, h:mm a", // force12
2379
2380 "h:mm:ss a", // jmmss
2381 "HH:mm:ss", // force24
2382 "h:mm:ss a", // force12
2383 "h:mm:ss a", // jjmmss
2384 "HH:mm:ss", // force24
2385 "HH:mm:ss", // force24 | match hour field length
2386 "h:mm:ss a", // force12
2387 "hh:mm:ss a", // force12 | match hour field length
2388 "hh:mm", // Jmm
2389 "HH:mm", // force24
2390 "hh:mm", // force12
2391 "h:mm:ss a v", // jmsv
2392 "HH:mm:ss v", // force24
2393 "h:mm:ss a v", // force12
2394 "h:mm:ss a z", // jmsz
2395 "HH:mm:ss z", // force24
2396 "h:mm:ss a z", // force12
2397
2398 "h:mm:ss a", // "h:mm:ss"
2399 "HH:mm:ss", //
2400 "a'xx'h:mm:ss d MMM y", // "a'xx'h:mm:ss d MMM y"
2401 "HH:mm:ss d MMM y", //
2402 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' h:mm:ss a 'hrs'"
2403 "EEE, d MMM y 'aha' HH:mm:ss 'hrs'", //
2404 "EEE, d MMM y 'aha' a'xx'h:mm:ss", // "EEE, d MMM y 'aha' a'xx'h:mm:ss"
2405 "EEE, d MMM y 'aha' HH:mm:ss", //
2406 "yyMMddhhmmss", // "yyMMddhhmmss"
2407 "yyMMddHHmmss", //
2408
2409 "h:mm:ss a", // "H:mm:ss"
2410 "H:mm:ss", //
2411 "h:mm:ss a d MMM y", // "H:mm:ss d MMM y"
2412 "H:mm:ss d MMM y", //
2413 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' H:mm:ss 'hrs'"
2414 "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
2415 "EEE, d MMM y 'aha' h'h'mm'm'ss a", // "EEE, d MMM y 'aha' H'h'mm'm'ss"
2416 "EEE, d MMM y 'aha' H'h'mm'm'ss", //
2417 NULL
2418};
2419
2420static const char * remapResults_ja[] = {
2421 "H\\u6642mm\\u5206ss\\u79D2 zzzz", // full
2422 "H\\u6642mm\\u5206ss\\u79D2 zzzz", // force24
2423 "aK:mm:ss zzzz", // force12
2424 "H:mm:ss z", // long
2425 "H:mm:ss z", // force24
2426 "aK:mm:ss z", // force12
2427 "H:mm:ss", // medium
2428 "H:mm:ss", // force24
2429 "aK:mm:ss", // force12
2430 "H:mm", // short
2431 "H:mm", // force24
2432 "aK:mm", // force12
2433 "y\\u5E74M\\u6708d\\u65E5EEEE H:mm:ss z", // long_df
2434 "y\\u5E74M\\u6708d\\u65E5EEEE H:mm:ss z", // force24
2435 "y\\u5E74M\\u6708d\\u65E5EEEE aK:mm:ss z", // force12
2436 "y/MM/dd H:mm", // short_ds
2437 "y/MM/dd H:mm", // force24
2438 "y/MM/dd aK:mm", // force12
2439
2440 "H:mm:ss", // jmmss
2441 "H:mm:ss", // force24
2442 "aK:mm:ss", // force12
2443 "H:mm:ss", // jjmmss
2444 "H:mm:ss", // force24
2445 "HH:mm:ss", // force24 | match hour field length
2446 "aK:mm:ss", // force12
2447 "aKK:mm:ss", // force12 | match hour field length
2448 "H:mm", // Jmm
2449 "H:mm", // force24
2450 "h:mm", // force12
2451 "H:mm:ss v", // jmsv
2452 "H:mm:ss v", // force24
2453 "aK:mm:ss v", // force12
2454 "H:mm:ss z", // jmsz
2455 "H:mm:ss z", // force24
2456 "aK:mm:ss z", // force12
2457
2458 "h:mm:ss a", // "h:mm:ss"
2459 "H:mm:ss", //
2460 "a'xx'h:mm:ss d MMM y", // "a'xx'h:mm:ss d MMM y"
2461 "H:mm:ss d MMM y", //
2462 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' h:mm:ss a 'hrs'"
2463 "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
2464 "EEE, d MMM y 'aha' a'xx'h:mm:ss", // "EEE, d MMM y 'aha' a'xx'h:mm:ss"
2465 "EEE, d MMM y 'aha' H:mm:ss", //
2466 "yyMMddhhmmss", // "yyMMddhhmmss"
2467 "yyMMddHHmmss", //
2468
2469 "aK:mm:ss", // "H:mm:ss"
2470 "H:mm:ss", //
2471 "aK:mm:ss d MMM y", // "H:mm:ss d MMM y"
2472 "H:mm:ss d MMM y", //
2473 "EEE, d MMM y 'aha' aK:mm:ss 'hrs'", // "EEE, d MMM y 'aha' H:mm:ss 'hrs'"
2474 "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
2475 "EEE, d MMM y 'aha' aK'h'mm'm'ss", // "EEE, d MMM y 'aha' H'h'mm'm'ss"
2476 "EEE, d MMM y 'aha' H'h'mm'm'ss", //
2477 NULL
2478};
2479
2480static const char * remapResults_ko[] = {
2481 "a h\\uC2DC m\\uBD84 s\\uCD08 zzzz", // full
2482 "H\\uC2DC m\\uBD84 s\\uCD08 zzzz", // force24
2483 "a h\\uC2DC m\\uBD84 s\\uCD08 zzzz", // force12
2484 "a h\\uC2DC m\\uBD84 s\\uCD08 z", // long
2485 "H\\uC2DC m\\uBD84 s\\uCD08 z", // force24
2486 "a h\\uC2DC m\\uBD84 s\\uCD08 z", // force12
2487 "a h:mm:ss", // medium
2488 "HH:mm:ss", // force24
2489 "a h:mm:ss", // force12
2490 "a h:mm", // short
2491 "HH:mm", // force24
2492 "a h:mm", // force12
2493 "y\\uB144 M\\uC6D4 d\\uC77C EEEE a h\\uC2DC m\\uBD84 s\\uCD08 z", // long_df
2494 "y\\uB144 M\\uC6D4 d\\uC77C EEEE H\\uC2DC m\\uBD84 s\\uCD08 z", // force24
2495 "y\\uB144 M\\uC6D4 d\\uC77C EEEE a h\\uC2DC m\\uBD84 s\\uCD08 z", // force12
2496 "y. M. d. a h:mm", // short_ds
2497 "y. M. d. HH:mm", // force24
2498 "y. M. d. a h:mm", // force12
2499
2500 "a h:mm:ss", // jmmss
2501 "HH:mm:ss", // force24
2502 "a h:mm:ss", // force12
2503 "a h:mm:ss", // jjmmss
2504 "HH:mm:ss", // force24
2505 "HH:mm:ss", // force24 | match hour field length
2506 "a h:mm:ss", // force12
2507 "a hh:mm:ss", // force12 | match hour field length
2508 "hh:mm", // Jmm
2509 "HH:mm", // force24
2510 "hh:mm", // force12
2511 "a h:mm:ss v", // jmsv
2512 "H\\uC2DC m\\uBD84 s\\uCD08 v", // force24
2513 "a h:mm:ss v", // force12
2514 "a h\\uC2DC m\\uBD84 s\\uCD08 z", // jmsz
2515 "H\\uC2DC m\\uBD84 s\\uCD08 z", // force24
2516 "a h\\uC2DC m\\uBD84 s\\uCD08 z", // force12
2517
2518 "h:mm:ss a", // "h:mm:ss"
2519 "HH:mm:ss", //
2520 "a'xx'h:mm:ss d MMM y", // "a'xx'h:mm:ss d MMM y"
2521 "HH:mm:ss d MMM y", //
2522 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' h:mm:ss a 'hrs'"
2523 "EEE, d MMM y 'aha' HH:mm:ss 'hrs'", //
2524 "EEE, d MMM y 'aha' a'xx'h:mm:ss", // "EEE, d MMM y 'aha' a'xx'h:mm:ss"
2525 "EEE, d MMM y 'aha' HH:mm:ss", //
2526 "yyMMddhhmmss", // "yyMMddhhmmss"
2527 "yyMMddHHmmss", //
2528
2529 "a h:mm:ss", // "H:mm:ss"
2530 "H:mm:ss", //
2531 "a h:mm:ss d MMM y", // "H:mm:ss d MMM y"
2532 "H:mm:ss d MMM y", //
2533 "EEE, d MMM y 'aha' a h:mm:ss 'hrs'", // "EEE, d MMM y 'aha' H:mm:ss 'hrs'"
2534 "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
2535 "EEE, d MMM y 'aha' a h'h'mm'm'ss", // "EEE, d MMM y 'aha' H'h'mm'm'ss"
2536 "EEE, d MMM y 'aha' H'h'mm'm'ss", //
2537 NULL
2538};
2539
2540static const char * remapResults_th[] = {
2541 "H \\u0E19\\u0E32\\u0E2C\\u0E34\\u0E01\\u0E32 mm \\u0E19\\u0E32\\u0E17\\u0E35 ss \\u0E27\\u0E34\\u0E19\\u0E32\\u0E17\\u0E35 zzzz", // full
2542 "H \\u0E19\\u0E32\\u0E2C\\u0E34\\u0E01\\u0E32 mm \\u0E19\\u0E32\\u0E17\\u0E35 ss \\u0E27\\u0E34\\u0E19\\u0E32\\u0E17\\u0E35 zzzz", // force24
2543 "h:mm:ss a zzzz", // force12
2544 "H \\u0E19\\u0E32\\u0E2C\\u0E34\\u0E01\\u0E32 mm \\u0E19\\u0E32\\u0E17\\u0E35 ss \\u0E27\\u0E34\\u0E19\\u0E32\\u0E17\\u0E35 z", // long
2545 "H \\u0E19\\u0E32\\u0E2C\\u0E34\\u0E01\\u0E32 mm \\u0E19\\u0E32\\u0E17\\u0E35 ss \\u0E27\\u0E34\\u0E19\\u0E32\\u0E17\\u0E35 z", // force24
2546 "h:mm:ss a z", // force12
2547 "HH:mm:ss", // medium
2548 "HH:mm:ss", // force24
2549 "h:mm:ss a", // force12
2550 "HH:mm", // short
2551 "HH:mm", // force24
2552 "h:mm a", // force12
2553 "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
2554 "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
2555 "EEEE\\u0E17\\u0E35\\u0E48 d MMMM G y h:mm:ss a z", // force12
2556 "d/M/yy HH:mm", // short_ds
2557 "d/M/yy HH:mm", // force24
2558 "d/M/yy h:mm a", // force12
2559
2560 "HH:mm:ss", // jmmss
2561 "HH:mm:ss", // force24
2562 "h:mm:ss a", // force12
2563 "HH:mm:ss", // 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 \\u0E19\\u0E32\\u0E2C\\u0E34\\u0E01\\u0E32 mm \\u0E19\\u0E32\\u0E17\\u0E35 ss \\u0E27\\u0E34\\u0E19\\u0E32\\u0E17\\u0E35 v", // jmsv
2572 "H \\u0E19\\u0E32\\u0E2C\\u0E34\\u0E01\\u0E32 mm \\u0E19\\u0E32\\u0E17\\u0E35 ss \\u0E27\\u0E34\\u0E19\\u0E32\\u0E17\\u0E35 v", // force24
2573 "h:mm:ss a v", // force12
2574 "H \\u0E19\\u0E32\\u0E2C\\u0E34\\u0E01\\u0E32 mm \\u0E19\\u0E32\\u0E17\\u0E35 ss \\u0E27\\u0E34\\u0E19\\u0E32\\u0E17\\u0E35 z", // jmsz
2575 "H \\u0E19\\u0E32\\u0E2C\\u0E34\\u0E01\\u0E32 mm \\u0E19\\u0E32\\u0E17\\u0E35 ss \\u0E27\\u0E34\\u0E19\\u0E32\\u0E17\\u0E35 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", //
2597 NULL
2598};
2599
2600static const char * remapResults_hi[] = {
2601 "a h:mm:ss zzzz", // full
2602 "HH:mm:ss zzzz", // force24
2603 "a h:mm:ss zzzz", // force12
2604 "a h:mm:ss z", // long
2605 "HH:mm:ss z", // force24
2606 "a h:mm:ss z", // force12
2607 "a h:mm:ss", // medium
2608 "HH:mm:ss", // force24
2609 "a h:mm:ss", // force12
2610 "a h:mm", // short
2611 "HH:mm", // force24
2612 "a h:mm", // force12
2613 "EEEE, d MMMM y, a h:mm:ss z", // long_df
2614 "EEEE, d MMMM y, HH:mm:ss z", // force24
2615 "EEEE, d MMMM y, a h:mm:ss z", // force12
2616 "d/M/yy, a h:mm", // short_ds
2617 "d/M/yy, HH:mm", // force24
2618 "d/M/yy, a h:mm", // force12
2619
2620 "a h:mm:ss", // jmmss
2621 "HH:mm:ss", // force24
2622 "a h:mm:ss", // force12
2623 "a h:mm:ss", // jjmmss
2624 "HH:mm:ss", // force24
2625 "HH:mm:ss", // force24 | match hour field length
2626 "a h:mm:ss", // force12
2627 "a hh:mm:ss", // force12 | match hour field length
2628 "hh:mm", // Jmm
2629 "HH:mm", // force24
2630 "hh:mm", // force12
2631 "a h:mm:ss v", // jmsv
2632 "HH:mm:ss v", // force24
2633 "a h:mm:ss v", // force12
2634 "a h:mm:ss z", // jmsz
2635 "HH:mm:ss z", // force24
2636 "a h:mm:ss z", // force12
2637
2638 "h:mm:ss a", // "h:mm:ss"
2639 "HH:mm:ss", //
2640 "a'xx'h:mm:ss d MMM y", // "a'xx'h:mm:ss d MMM y"
2641 "HH:mm:ss d MMM y", //
2642 "EEE, d MMM y 'aha' h:mm:ss a 'hrs'", // "EEE, d MMM y 'aha' h:mm:ss a 'hrs'"
2643 "EEE, d MMM y 'aha' HH:mm:ss 'hrs'", //
2644 "EEE, d MMM y 'aha' a'xx'h:mm:ss", // "EEE, d MMM y 'aha' a'xx'h:mm:ss"
2645 "EEE, d MMM y 'aha' HH:mm:ss", //
2646 "yyMMddhhmmss", // "yyMMddhhmmss"
2647 "yyMMddHHmmss", //
2648
2649 "a h:mm:ss", // "H:mm:ss"
2650 "H:mm:ss", //
2651 "a h:mm:ss d MMM y", // "H:mm:ss d MMM y"
2652 "H:mm:ss d MMM y", //
2653 "EEE, d MMM y 'aha' a h:mm:ss 'hrs'", // "EEE, d MMM y 'aha' H:mm:ss 'hrs'"
2654 "EEE, d MMM y 'aha' H:mm:ss 'hrs'", //
2655 "EEE, d MMM y 'aha' a h'h'mm'm'ss", // "EEE, d MMM y 'aha' H'h'mm'm'ss"
2656 "EEE, d MMM y 'aha' H'h'mm'm'ss", //
2657 NULL
2658};
2659
2660typedef struct {
2661 const char * locale;
2662 const char ** resultsPtr;
2663} RemapPatternLocaleResults;
2664
2665static const RemapPatternLocaleResults remapLocResults[] = {
2666 { "root", remapResults_root },
2667 { "en", remapResults_en },
2668 { "ja", remapResults_ja },
2669 { "ko", remapResults_ko },
2670 { "th", remapResults_th },
2671 { "hi", remapResults_hi },
2672 { NULL, NULL }
2673};
2674
2675enum { kUBufRemapMax = 64, kBBufRemapMax = 128 };
2676
2677static void TestRemapPatternWithOpts(void) { /* Apple-specific */
2678 const RemapPatternLocaleResults * locResPtr;
2679 for (locResPtr = remapLocResults; locResPtr->locale != NULL; locResPtr++) {
2680 UErrorCode status = U_ZERO_ERROR;
2681 UDateTimePatternGenerator* dtpg = udatpg_open(locResPtr->locale, &status);
2682 if ( U_FAILURE(status) ) {
2683 log_data_err("udatpg_open fails for locale %s, status %s (Are you missing data?)\n", locResPtr->locale, u_errorName(status));
2684 } else {
2685 const RemapPatternTestItem * testItemPtr = remapPatItems;
2686 const char ** expResultsPtr = locResPtr->resultsPtr;
2687 for (; testItemPtr->pattern != NULL && *expResultsPtr != NULL; testItemPtr++, expResultsPtr++) {
2688 UChar uskel[kUBufRemapMax];
2689 UChar upatn[kUBufRemapMax];
2690 UChar uget[kUBufRemapMax];
2691 UChar uexp[kUBufRemapMax];
2692 int32_t uelen, ulen = 0;
2693
2694 status = U_ZERO_ERROR;
2695 if (testItemPtr->testtype >= 0) {
2696 UDateFormatStyle timeStyle = (UDateFormatStyle)((int32_t)testItemPtr->testtype & 0x03);
2697 UDateFormatStyle dateStyle = (UDateFormatStyle)((((int32_t)testItemPtr->testtype >> 2) & 0x07) - 1);
2698 UDateFormat* dfmt = udat_open(timeStyle, dateStyle, locResPtr->locale, NULL, 0, NULL, 0, &status);
2699 if ( U_FAILURE(status) ) {
2700 log_data_err("udat_open fails for locale %s, status %s (Are you missing data?)\n", locResPtr->locale, u_errorName(status));
2701 continue;
2702 } else {
2703 ulen = udat_toPattern(dfmt, FALSE, upatn, kUBufRemapMax, &status);
2704 udat_close(dfmt);
2705 if ( U_FAILURE(status) ) {
2706 log_err("udat_toPattern fails for locale %s, status %s\n", locResPtr->locale, u_errorName(status));
2707 continue;
2708 }
2709 }
2710 } else if (testItemPtr->testtype == REMAP_TESTTYPE_SKELETON) {
2711 u_strFromUTF8(uskel, kUBufRemapMax, &ulen, testItemPtr->pattern, -1, &status);
2712 ulen = udatpg_getBestPatternWithOptions(dtpg, uskel, ulen, (UDateTimePatternMatchOptions)testItemPtr->options, upatn, kUBufRemapMax, &status);
2713 if ( U_FAILURE(status) ) {
2714 log_err("udatpg_getBestPatternWithOptions fails for locale %s, skeleton \"%s\": status %s\n", locResPtr->locale, testItemPtr->pattern, u_errorName(status));
2715 continue;
2716 }
2717 } else {
2718 ulen = u_unescape(testItemPtr->pattern, upatn, kUBufRemapMax);
2719 }
2720 uelen = u_unescape(*expResultsPtr, uexp, kUBufRemapMax);
2721 ulen = uadatpg_remapPatternWithOptions(dtpg, upatn, ulen, (UDateTimePatternMatchOptions)testItemPtr->options, uget, kUBufRemapMax, &status);
2722 if ( U_FAILURE(status) ) {
2723 log_err("uadatpg_remapPatternWithOptions fails for locale %s pattern \"%s\" opts %08X: status %s\n",
2724 locResPtr->locale, testItemPtr->pattern, testItemPtr->options, u_errorName(status));
2725 } else if (uelen != ulen || u_strncmp(uget, uexp, ulen) != 0) {
2726 char bebuf[kBBufRemapMax];
2727 char bbuf[kBBufRemapMax];
2728 UErrorCode tempStatus = U_ZERO_ERROR;
2729 u_strToUTF8(bebuf, kBBufRemapMax, NULL, uexp, uelen, &tempStatus);
2730 u_strToUTF8(bbuf, kBBufRemapMax, NULL, uget, ulen, &tempStatus);
2731 log_err("uadatpg_remapPatternWithOptions for locale %s pattern \"%s\" opts %08X: expect \"%s\", get \"%s\"\n",
2732 locResPtr->locale, testItemPtr->pattern, testItemPtr->options, bebuf, bbuf);
2733 }
2734 }
2735 udatpg_close(dtpg);
2736 }
2737 }
2738}
2739
2740#endif /* #if !UCONFIG_NO_FORMATTING */