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