]> git.saurik.com Git - apple/icu.git/blob - icuSources/test/cintltst/cdattst.c
ICU-491.11.2.tar.gz
[apple/icu.git] / icuSources / test / cintltst / cdattst.c
1 /********************************************************************
2 * COPYRIGHT:
3 * Copyright (c) 1997-2012, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ********************************************************************/
6 /********************************************************************************
7 *
8 * File CDATTST.C
9 *
10 * Modification History:
11 * Name Description
12 * Madhu Katragadda Creation
13 *********************************************************************************
14 */
15
16 /* C API TEST FOR DATE FORMAT */
17
18 #include "unicode/utypes.h"
19
20 #if !UCONFIG_NO_FORMATTING
21
22 #include "unicode/uloc.h"
23 #include "unicode/udat.h"
24 #include "unicode/udatpg.h"
25 #include "unicode/ucal.h"
26 #include "unicode/unum.h"
27 #include "unicode/ustring.h"
28 #include "cintltst.h"
29 #include "cdattst.h"
30 #include "cformtst.h"
31 #include "cmemory.h"
32
33 #include <math.h>
34
35 static void TestExtremeDates(void);
36 static void TestAllLocales(void);
37 static void TestRelativeCrash(void);
38 static void TestContext(void);
39
40 #define LEN(a) (sizeof(a)/sizeof(a[0]))
41
42 void addDateForTest(TestNode** root);
43
44 #define TESTCASE(x) addTest(root, &x, "tsformat/cdattst/" #x)
45
46 void addDateForTest(TestNode** root)
47 {
48 TESTCASE(TestDateFormat);
49 TESTCASE(TestRelativeDateFormat);
50 TESTCASE(TestSymbols);
51 TESTCASE(TestDateFormatCalendar);
52 TESTCASE(TestExtremeDates);
53 TESTCASE(TestAllLocales);
54 TESTCASE(TestRelativeCrash);
55 TESTCASE(TestContext);
56 }
57 /* Testing the DateFormat API */
58 static void TestDateFormat()
59 {
60 UDateFormat *def, *fr, *it, *de, *def1, *fr_pat;
61 UDateFormat *any;
62 UDateFormat *copy;
63 UErrorCode status = U_ZERO_ERROR;
64 UChar* result = NULL;
65 const UCalendar *cal;
66 const UNumberFormat *numformat1, *numformat2;
67 UChar temp[50];
68 int32_t numlocales;
69 UDate d1;
70 int i;
71 int32_t resultlength;
72 int32_t resultlengthneeded;
73 int32_t parsepos;
74 UDate d = 837039928046.0;
75 double num = -10456.37;
76 /*const char* str="yyyy.MM.dd G 'at' hh:mm:ss z";
77 const char t[]="2/3/76 2:50 AM";*/
78 /*Testing udat_open() to open a dateformat */
79
80 ctest_setTimeZone(NULL, &status);
81
82 log_verbose("\nTesting udat_open() with various parameters\n");
83 fr = udat_open(UDAT_FULL, UDAT_DEFAULT, "fr_FR", NULL,0, NULL, 0,&status);
84 if(U_FAILURE(status))
85 {
86 log_data_err("FAIL: error in creating the dateformat using full time style with french locale -> %s (Are you missing data?)\n",
87 myErrorName(status) );
88 return;
89 }
90 /* this is supposed to open default date format, but later on it treats it like it is "en_US"
91 - very bad if you try to run the tests on machine where default locale is NOT "en_US" */
92 /* def = udat_open(UDAT_SHORT, UDAT_SHORT, NULL, NULL, 0, &status); */
93 def = udat_open(UDAT_SHORT, UDAT_SHORT, "en_US", NULL, 0,NULL, 0, &status);
94 if(U_FAILURE(status))
95 {
96 log_err("FAIL: error in creating the dateformat using short date and time style\n %s\n",
97 myErrorName(status) );
98 return;
99 }
100 it = udat_open(UDAT_DEFAULT, UDAT_MEDIUM, "it_IT", NULL, 0, NULL, 0,&status);
101 if(U_FAILURE(status))
102 {
103 log_err("FAIL: error in creating the dateformat using medium date style with italian locale\n %s\n",
104 myErrorName(status) );
105 return;
106 }
107 de = udat_open(UDAT_LONG, UDAT_LONG, "de_DE", NULL, 0, NULL, 0,&status);
108 if(U_FAILURE(status))
109 {
110 log_err("FAIL: error in creating the dateformat using long time and date styles with german locale\n %s\n",
111 myErrorName(status));
112 return;
113 }
114 /*creating a default dateformat */
115 def1 = udat_open(UDAT_SHORT, UDAT_SHORT, NULL, NULL, 0,NULL, 0, &status);
116 if(U_FAILURE(status))
117 {
118 log_err("FAIL: error in creating the dateformat using short date and time style\n %s\n",
119 myErrorName(status) );
120 return;
121 }
122
123
124 /*Testing udat_getAvailable() and udat_countAvailable()*/
125 log_verbose("\nTesting getAvailableLocales and countAvailable()\n");
126 numlocales=udat_countAvailable();
127 /* use something sensible w/o hardcoding the count */
128 if(numlocales < 0)
129 log_data_err("FAIL: error in countAvailable\n");
130 log_verbose("The number of locales for which date/time formatting patterns are available is %d\n", numlocales);
131
132 for(i=0;i<numlocales;i++) {
133 UErrorCode subStatus = U_ZERO_ERROR;
134 log_verbose("Testing open of %s\n", udat_getAvailable(i));
135 any = udat_open(UDAT_SHORT, UDAT_SHORT, udat_getAvailable(i), NULL ,0, NULL, 0, &subStatus);
136 if(U_FAILURE(subStatus)) {
137 log_data_err("FAIL: date format %s (getAvailable(%d)) is not instantiable: %s\n", udat_getAvailable(i), i, u_errorName(subStatus));
138 }
139 udat_close(any);
140 }
141
142 /*Testing udat_clone()*/
143 log_verbose("\nTesting the udat_clone() function of date format\n");
144 copy=udat_clone(def, &status);
145 if(U_FAILURE(status)){
146 log_err("Error in creating the clone using udat_clone: %s\n", myErrorName(status) );
147 }
148 /*if(def != copy)
149 log_err("Error in udat_clone");*/ /*how should i check for equality???? */
150
151 /*Testing udat_format()*/
152 log_verbose("\nTesting the udat_format() function of date format\n");
153 u_uastrcpy(temp, "7/10/96 4:05 PM");
154 /*format using def */
155 resultlength=0;
156 resultlengthneeded=udat_format(def, d, NULL, resultlength, NULL, &status);
157 if(status==U_BUFFER_OVERFLOW_ERROR)
158 {
159 status=U_ZERO_ERROR;
160 resultlength=resultlengthneeded+1;
161 if(result != NULL) {
162 free(result);
163 result = NULL;
164 }
165 result=(UChar*)malloc(sizeof(UChar) * resultlength);
166 udat_format(def, d, result, resultlength, NULL, &status);
167 }
168 if(U_FAILURE(status) || !result)
169 {
170 log_err("FAIL: Error in formatting using udat_format(.....) %s\n", myErrorName(status) );
171 return;
172 }
173 else
174 log_verbose("PASS: formatting successful\n");
175 if(u_strcmp(result, temp)==0)
176 log_verbose("PASS: Date Format for US locale successful using udat_format()\n");
177 else {
178 char xbuf[2048];
179 char gbuf[2048];
180 u_austrcpy(xbuf, temp);
181 u_austrcpy(gbuf, result);
182 log_err("FAIL: Date Format for US locale failed using udat_format() - expected %s got %s\n", xbuf, gbuf);
183 }
184 /*format using fr */
185
186 u_unescape("10 juil. 1996 16:05:28 heure avanc\\u00E9e du Pacifique", temp, 50);
187 if(result != NULL) {
188 free(result);
189 result = NULL;
190 }
191 result=myDateFormat(fr, d);
192 if(u_strcmp(result, temp)==0)
193 log_verbose("PASS: Date Format for french locale successful using udat_format()\n");
194 else
195 log_data_err("FAIL: Date Format for french locale failed using udat_format().\n" );
196
197 /*format using it */
198 u_uastrcpy(temp, "10/lug/1996 16:05:28");
199
200 {
201 UChar *fmtted;
202 char g[100];
203 char x[100];
204
205 fmtted = myDateFormat(it,d);
206 u_austrcpy(g, fmtted);
207 u_austrcpy(x, temp);
208 if(u_strcmp(fmtted, temp)==0) {
209 log_verbose("PASS: Date Format for italian locale successful uisng udat_format() - wanted %s, got %s\n", x, g);
210 } else {
211 log_data_err("FAIL: Date Format for italian locale failed using udat_format() - wanted %s, got %s\n", x, g);
212 }
213 }
214
215 /*Testing parsing using udat_parse()*/
216 log_verbose("\nTesting parsing using udat_parse()\n");
217 u_uastrcpy(temp,"2/3/76 2:50 AM");
218 parsepos=0;
219 status=U_ZERO_ERROR;
220
221 d1=udat_parse(def, temp, u_strlen(temp), &parsepos, &status);
222 if(U_FAILURE(status))
223 {
224 log_err("FAIL: Error in parsing using udat_parse(.....) %s\n", myErrorName(status) );
225 }
226 else
227 log_verbose("PASS: parsing succesful\n");
228 /*format it back and check for equality */
229
230
231 if(u_strcmp(myDateFormat(def, d1),temp)!=0)
232 log_err("FAIL: error in parsing\n");
233
234 /*Testing parsing using udat_parse()*/
235 log_verbose("\nTesting parsing using udat_parse()\n");
236 u_uastrcpy(temp,"2/Don't parse this part");
237 status=U_ZERO_ERROR;
238
239 d1=udat_parse(def, temp, u_strlen(temp), NULL, &status);
240 if(status != U_PARSE_ERROR)
241 {
242 log_err("FAIL: udat_parse(\"bad string\") passed when it should have failed\n");
243 }
244 else
245 log_verbose("PASS: parsing succesful\n");
246
247
248
249 /*Testing udat_openPattern() */
250 status=U_ZERO_ERROR;
251 log_verbose("\nTesting the udat_openPattern with a specified pattern\n");
252 /*for french locale */
253 fr_pat=udat_open(UDAT_IGNORE, UDAT_IGNORE,"fr_FR",NULL,0,temp, u_strlen(temp), &status);
254 if(U_FAILURE(status))
255 {
256 log_err("FAIL: Error in creating a date format using udat_openPattern \n %s\n",
257 myErrorName(status) );
258 }
259 else
260 log_verbose("PASS: creating dateformat using udat_openPattern() succesful\n");
261
262
263 /*Testing applyPattern and toPattern */
264 log_verbose("\nTesting applyPattern and toPattern()\n");
265 udat_applyPattern(def1, FALSE, temp, u_strlen(temp));
266 log_verbose("Extracting the pattern\n");
267
268 resultlength=0;
269 resultlengthneeded=udat_toPattern(def1, FALSE, NULL, resultlength, &status);
270 if(status==U_BUFFER_OVERFLOW_ERROR)
271 {
272 status=U_ZERO_ERROR;
273 resultlength=resultlengthneeded + 1;
274 result=(UChar*)malloc(sizeof(UChar) * resultlength);
275 udat_toPattern(def1, FALSE, result, resultlength, &status);
276 }
277 if(U_FAILURE(status))
278 {
279 log_err("FAIL: error in extracting the pattern from UNumberFormat\n %s\n",
280 myErrorName(status) );
281 }
282 if(u_strcmp(result, temp)!=0)
283 log_err("FAIL: Error in extracting the pattern\n");
284 else
285 log_verbose("PASS: applyPattern and toPattern work fine\n");
286
287 if(result != NULL) {
288 free(result);
289 result = NULL;
290 }
291
292
293 /*Testing getter and setter functions*/
294 /*isLenient and setLenient()*/
295 log_verbose("\nTesting the isLenient and setLenient properties\n");
296 udat_setLenient(fr, udat_isLenient(it));
297 if(udat_isLenient(fr) != udat_isLenient(it))
298 log_err("ERROR: setLenient() failed\n");
299 else
300 log_verbose("PASS: setLenient() successful\n");
301
302
303 /*Test get2DigitYearStart set2DigitYearStart */
304 log_verbose("\nTesting the get and set 2DigitYearStart properties\n");
305 d1= udat_get2DigitYearStart(fr_pat,&status);
306 if(U_FAILURE(status)) {
307 log_err("ERROR: udat_get2DigitYearStart failed %s\n", myErrorName(status) );
308 }
309 status = U_ZERO_ERROR;
310 udat_set2DigitYearStart(def1 ,d1, &status);
311 if(U_FAILURE(status)) {
312 log_err("ERROR: udat_set2DigitYearStart failed %s\n", myErrorName(status) );
313 }
314 if(udat_get2DigitYearStart(fr_pat, &status) != udat_get2DigitYearStart(def1, &status))
315 log_err("FAIL: error in set2DigitYearStart\n");
316 else
317 log_verbose("PASS: set2DigitYearStart successful\n");
318 /*try setting it to another value */
319 udat_set2DigitYearStart(de, 2000.0, &status);
320 if(U_FAILURE(status)){
321 log_verbose("ERROR: udat_set2DigitYearStart failed %s\n", myErrorName(status) );
322 }
323 if(udat_get2DigitYearStart(de, &status) != 2000)
324 log_err("FAIL: error in set2DigitYearStart\n");
325 else
326 log_verbose("PASS: set2DigitYearStart successful\n");
327
328
329
330 /*Test getNumberFormat() and setNumberFormat() */
331 log_verbose("\nTesting the get and set NumberFormat properties of date format\n");
332 numformat1=udat_getNumberFormat(fr_pat);
333 udat_setNumberFormat(def1, numformat1);
334 numformat2=udat_getNumberFormat(def1);
335 if(u_strcmp(myNumformat(numformat1, num), myNumformat(numformat2, num)) !=0)
336 log_err("FAIL: error in setNumberFormat or getNumberFormat()\n");
337 else
338 log_verbose("PASS:setNumberFormat and getNumberFormat succesful\n");
339
340 /*try setting the number format to another format */
341 numformat1=udat_getNumberFormat(def);
342 udat_setNumberFormat(def1, numformat1);
343 numformat2=udat_getNumberFormat(def1);
344 if(u_strcmp(myNumformat(numformat1, num), myNumformat(numformat2, num)) !=0)
345 log_err("FAIL: error in setNumberFormat or getNumberFormat()\n");
346 else
347 log_verbose("PASS: setNumberFormat and getNumberFormat succesful\n");
348
349
350
351 /*Test getCalendar and setCalendar*/
352 log_verbose("\nTesting the udat_getCalendar() and udat_setCalendar() properties\n");
353 cal=udat_getCalendar(fr_pat);
354
355
356 udat_setCalendar(def1, cal);
357 if(!ucal_equivalentTo(udat_getCalendar(fr_pat), udat_getCalendar(def1)))
358 log_err("FAIL: Error in setting and getting the calendar\n");
359 else
360 log_verbose("PASS: getting and setting calendar successful\n");
361
362 if(result!=NULL) {
363 free(result);
364 }
365
366 /*Closing the UDateForamt */
367 udat_close(def);
368 udat_close(fr);
369 udat_close(it);
370 udat_close(de);
371 udat_close(def1);
372 udat_close(fr_pat);
373 udat_close(copy);
374
375 ctest_resetTimeZone();
376 }
377
378 /*
379 Test combined relative date formatting (relative date + non-relative time).
380 This is a bit tricky since we can't have static test data for comparison, the
381 relative date formatting is relative to the time the tests are run. We generate
382 the data for comparison dynamically. However, the tests could fail if they are
383 run right at midnight Pacific time and the call to ucal_getNow() is before midnight
384 while the calls to udat_format are after midnight or span midnight.
385 */
386 static const UDate dayInterval = 24.0*60.0*60.0*1000.0;
387 static const UChar trdfZone[] = { 0x0055, 0x0053, 0x002F, 0x0050, 0x0061, 0x0063, 0x0069, 0x0066, 0x0069, 0x0063, 0 }; /* US/Pacific */
388 static const char trdfLocale[] = "en_US";
389 static const UChar minutesPatn[] = { 0x006D, 0x006D, 0 }; /* "mm" */
390 static const UChar monthLongPatn[] = { 0x004D, 0x004D, 0x004D, 0x004D, 0 }; /* "MMMM" */
391 static const UChar monthMediumPatn[] = { 0x004D, 0x004D, 0x004D, 0 }; /* "MMM" */
392 static const UChar monthShortPatn[] = { 0x004D, 0 }; /* "M" */
393 static const UDateFormatStyle dateStylesList[] = { UDAT_FULL, UDAT_LONG, UDAT_MEDIUM, UDAT_SHORT, UDAT_NONE };
394 static const UChar *monthPatnsList[] = { monthLongPatn, monthLongPatn, monthMediumPatn, monthShortPatn, NULL };
395 static const UChar newTimePatn[] = { 0x0048, 0x0048, 0x002C, 0x006D, 0x006D, 0 }; /* "HH,mm" */
396 static const UChar minutesStr[] = { 0x0034, 0x0039, 0 }; /* "49", minutes string to search for in output */
397 enum { kDateOrTimeOutMax = 96, kDateAndTimeOutMax = 192 };
398
399 static void TestRelativeDateFormat()
400 {
401 UDate today = 0.0;
402 const UDateFormatStyle * stylePtr;
403 const UChar ** monthPtnPtr;
404 UErrorCode status = U_ZERO_ERROR;
405 UCalendar * ucal = ucal_open(trdfZone, -1, trdfLocale, UCAL_GREGORIAN, &status);
406 if ( U_SUCCESS(status) ) {
407 int32_t year, month, day;
408 ucal_setMillis(ucal, ucal_getNow(), &status);
409 year = ucal_get(ucal, UCAL_YEAR, &status);
410 month = ucal_get(ucal, UCAL_MONTH, &status);
411 day = ucal_get(ucal, UCAL_DATE, &status);
412 ucal_setDateTime(ucal, year, month, day, 18, 49, 0, &status); /* set to today at 18:49:00 */
413 today = ucal_getMillis(ucal, &status);
414 ucal_close(ucal);
415 }
416 if ( U_FAILURE(status) || today == 0.0 ) {
417 log_data_err("Generate UDate for a specified time today fails, error %s - (Are you missing data?)\n", myErrorName(status) );
418 return;
419 }
420 for (stylePtr = dateStylesList, monthPtnPtr = monthPatnsList; *stylePtr != UDAT_NONE; ++stylePtr, ++monthPtnPtr) {
421 UDateFormat* fmtRelDateTime;
422 UDateFormat* fmtRelDate;
423 UDateFormat* fmtTime;
424 int32_t dayOffset, limit;
425 UFieldPosition fp;
426 UChar strDateTime[kDateAndTimeOutMax];
427 UChar strDate[kDateOrTimeOutMax];
428 UChar strTime[kDateOrTimeOutMax];
429 UChar * strPtr;
430 int32_t dtpatLen;
431
432 fmtRelDateTime = udat_open(UDAT_SHORT, *stylePtr | UDAT_RELATIVE, trdfLocale, trdfZone, -1, NULL, 0, &status);
433 if ( U_FAILURE(status) ) {
434 log_data_err("udat_open timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s (Are you missing data?)\n", *stylePtr, myErrorName(status) );
435 continue;
436 }
437 fmtRelDate = udat_open(UDAT_NONE, *stylePtr | UDAT_RELATIVE, trdfLocale, trdfZone, -1, NULL, 0, &status);
438 if ( U_FAILURE(status) ) {
439 log_err("udat_open timeStyle NONE dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
440 udat_close(fmtRelDateTime);
441 continue;
442 }
443 fmtTime = udat_open(UDAT_SHORT, UDAT_NONE, trdfLocale, trdfZone, -1, NULL, 0, &status);
444 if ( U_FAILURE(status) ) {
445 log_err("udat_open timeStyle SHORT dateStyle NONE fails, error %s\n", myErrorName(status) );
446 udat_close(fmtRelDateTime);
447 udat_close(fmtRelDate);
448 continue;
449 }
450
451 dtpatLen = udat_toPatternRelativeDate(fmtRelDateTime, strDate, kDateAndTimeOutMax, &status);
452 if ( U_FAILURE(status) ) {
453 log_err("udat_toPatternRelativeDate timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
454 status = U_ZERO_ERROR;
455 } else if ( u_strstr(strDate, *monthPtnPtr) == NULL || dtpatLen != u_strlen(strDate) ) {
456 log_err("udat_toPatternRelativeDate timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) date pattern incorrect\n", *stylePtr );
457 }
458 dtpatLen = udat_toPatternRelativeTime(fmtRelDateTime, strTime, kDateAndTimeOutMax, &status);
459 if ( U_FAILURE(status) ) {
460 log_err("udat_toPatternRelativeTime timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
461 status = U_ZERO_ERROR;
462 } else if ( u_strstr(strTime, minutesPatn) == NULL || dtpatLen != u_strlen(strTime) ) {
463 log_err("udat_toPatternRelativeTime timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) time pattern incorrect\n", *stylePtr );
464 }
465 dtpatLen = udat_toPattern(fmtRelDateTime, FALSE, strDateTime, kDateAndTimeOutMax, &status);
466 if ( U_FAILURE(status) ) {
467 log_err("udat_toPattern timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
468 status = U_ZERO_ERROR;
469 } else if ( u_strstr(strDateTime, strDate) == NULL || u_strstr(strDateTime, strTime) == NULL || dtpatLen != u_strlen(strDateTime) ) {
470 log_err("udat_toPattern timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) dateTime pattern incorrect\n", *stylePtr );
471 }
472 udat_applyPatternRelative(fmtRelDateTime, strDate, u_strlen(strDate), newTimePatn, u_strlen(newTimePatn), &status);
473 if ( U_FAILURE(status) ) {
474 log_err("udat_applyPatternRelative timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
475 status = U_ZERO_ERROR;
476 } else {
477 udat_toPattern(fmtRelDateTime, FALSE, strDateTime, kDateAndTimeOutMax, &status);
478 if ( U_FAILURE(status) ) {
479 log_err("udat_toPattern timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
480 status = U_ZERO_ERROR;
481 } else if ( u_strstr(strDateTime, newTimePatn) == NULL ) {
482 log_err("udat_applyPatternRelative timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) didn't update time pattern\n", *stylePtr );
483 }
484 }
485 udat_applyPatternRelative(fmtRelDateTime, strDate, u_strlen(strDate), strTime, u_strlen(strTime), &status); /* restore original */
486
487 fp.field = UDAT_MINUTE_FIELD;
488 for (dayOffset = -2, limit = 2; dayOffset <= limit; ++dayOffset) {
489 UDate dateToUse = today + (float)dayOffset*dayInterval;
490
491 udat_format(fmtRelDateTime, dateToUse, strDateTime, kDateAndTimeOutMax, &fp, &status);
492 if ( U_FAILURE(status) ) {
493 log_err("udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
494 status = U_ZERO_ERROR;
495 } else {
496 udat_format(fmtRelDate, dateToUse, strDate, kDateOrTimeOutMax, NULL, &status);
497 if ( U_FAILURE(status) ) {
498 log_err("udat_format timeStyle NONE dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
499 status = U_ZERO_ERROR;
500 } else if ( u_strstr(strDateTime, strDate) == NULL ) {
501 log_err("relative date string not found in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", *stylePtr );
502 }
503
504 udat_format(fmtTime, dateToUse, strTime, kDateOrTimeOutMax, NULL, &status);
505 if ( U_FAILURE(status) ) {
506 log_err("udat_format timeStyle SHORT dateStyle NONE fails, error %s\n", myErrorName(status) );
507 status = U_ZERO_ERROR;
508 } else if ( u_strstr(strDateTime, strTime) == NULL ) {
509 log_err("time string not found in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", *stylePtr );
510 }
511
512 strPtr = u_strstr(strDateTime, minutesStr);
513 if ( strPtr != NULL ) {
514 int32_t beginIndex = strPtr - strDateTime;
515 if ( fp.beginIndex != beginIndex ) {
516 log_err("UFieldPosition beginIndex %d, expected %d, in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", fp.beginIndex, beginIndex, *stylePtr );
517 }
518 } else {
519 log_err("minutes string not found in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", *stylePtr );
520 }
521 }
522 }
523
524 udat_close(fmtRelDateTime);
525 udat_close(fmtRelDate);
526 udat_close(fmtTime);
527 }
528 }
529
530 /*Testing udat_getSymbols() and udat_setSymbols() and udat_countSymbols()*/
531 static void TestSymbols()
532 {
533 UDateFormat *def, *fr;
534 UErrorCode status = U_ZERO_ERROR;
535 UChar *value=NULL;
536 UChar *result = NULL;
537 int32_t resultlength;
538 int32_t resultlengthout;
539 UChar *pattern;
540
541
542 /*creating a dateformat with french locale */
543 log_verbose("\ncreating a date format with french locale\n");
544 fr = udat_open(UDAT_FULL, UDAT_DEFAULT, "fr_FR", NULL, 0, NULL, 0, &status);
545 if(U_FAILURE(status))
546 {
547 log_data_err("error in creating the dateformat using full time style with french locale -> %s (Are you missing data?)\n",
548 myErrorName(status) );
549 return;
550 }
551 /*creating a default dateformat */
552 log_verbose("\ncreating a date format with default locale\n");
553 /* this is supposed to open default date format, but later on it treats it like it is "en_US"
554 - very bad if you try to run the tests on machine where default locale is NOT "en_US" */
555 /* def = udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,NULL, NULL, 0, &status); */
556 def = udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,"en_US", NULL, 0, NULL, 0, &status);
557 if(U_FAILURE(status))
558 {
559 log_err("error in creating the dateformat using short date and time style\n %s\n",
560 myErrorName(status) );
561 return;
562 }
563
564
565 /*Testing countSymbols, getSymbols and setSymbols*/
566 log_verbose("\nTesting countSymbols\n");
567 /*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 */
568 if(udat_countSymbols(def, UDAT_ERAS)!=2 || udat_countSymbols(def, UDAT_MONTHS)!=12 ||
569 udat_countSymbols(def, UDAT_SHORT_MONTHS)!=12 || udat_countSymbols(def, UDAT_WEEKDAYS)!=8 ||
570 udat_countSymbols(def, UDAT_SHORT_WEEKDAYS)!=8 || udat_countSymbols(def, UDAT_AM_PMS)!=2 ||
571 udat_countSymbols(def, UDAT_QUARTERS) != 4 || udat_countSymbols(def, UDAT_SHORT_QUARTERS) != 4 ||
572 udat_countSymbols(def, UDAT_LOCALIZED_CHARS)!=1)
573 {
574 log_err("FAIL: error in udat_countSymbols\n");
575 }
576 else
577 log_verbose("PASS: udat_countSymbols() successful\n");
578
579 /*testing getSymbols*/
580 log_verbose("\nTesting getSymbols\n");
581 pattern=(UChar*)malloc(sizeof(UChar) * 10);
582 u_uastrcpy(pattern, "jeudi");
583 resultlength=0;
584 resultlengthout=udat_getSymbols(fr, UDAT_WEEKDAYS, 5 , NULL, resultlength, &status);
585 if(status==U_BUFFER_OVERFLOW_ERROR)
586 {
587 status=U_ZERO_ERROR;
588 resultlength=resultlengthout+1;
589 if(result != NULL) {
590 free(result);
591 result = NULL;
592 }
593 result=(UChar*)malloc(sizeof(UChar) * resultlength);
594 udat_getSymbols(fr, UDAT_WEEKDAYS, 5, result, resultlength, &status);
595
596 }
597 if(U_FAILURE(status))
598 {
599 log_err("FAIL: Error in udat_getSymbols().... %s\n", myErrorName(status) );
600 }
601 else
602 log_verbose("PASS: getSymbols succesful\n");
603
604 if(u_strcmp(result, pattern)==0)
605 log_verbose("PASS: getSymbols retrieved the right value\n");
606 else
607 log_data_err("FAIL: getSymbols retrieved the wrong value\n");
608
609 /*run series of tests to test getsymbols regressively*/
610 log_verbose("\nTesting getSymbols() regressively\n");
611 VerifygetSymbols(fr, UDAT_WEEKDAYS, 1, "dimanche");
612 VerifygetSymbols(def, UDAT_WEEKDAYS, 1, "Sunday");
613 VerifygetSymbols(fr, UDAT_SHORT_WEEKDAYS, 7, "sam.");
614 VerifygetSymbols(def, UDAT_SHORT_WEEKDAYS, 7, "Sat");
615 VerifygetSymbols(def, UDAT_MONTHS, 11, "December");
616 VerifygetSymbols(def, UDAT_MONTHS, 0, "January");
617 VerifygetSymbols(fr, UDAT_ERAS, 0, "av. J.-C.");
618 VerifygetSymbols(def, UDAT_AM_PMS, 0, "AM");
619 VerifygetSymbols(def, UDAT_AM_PMS, 1, "PM");
620 VerifygetSymbols(fr, UDAT_SHORT_MONTHS, 0, "janv.");
621 VerifygetSymbols(def, UDAT_SHORT_MONTHS, 11, "Dec");
622 VerifygetSymbols(fr, UDAT_QUARTERS, 0, "1er trimestre");
623 VerifygetSymbols(def, UDAT_QUARTERS, 3, "4th quarter");
624 VerifygetSymbols(fr, UDAT_SHORT_QUARTERS, 1, "T2");
625 VerifygetSymbols(def, UDAT_SHORT_QUARTERS, 2, "Q3");
626 VerifygetSymbols(def,UDAT_LOCALIZED_CHARS, 0, "GyMdkHmsSEDFwWahKzYeugAZvcLQqVU");
627
628
629 if(result != NULL) {
630 free(result);
631 result = NULL;
632 }
633 free(pattern);
634
635 log_verbose("\nTesting setSymbols\n");
636 /*applying the pattern so that setSymbolss works */
637 resultlength=0;
638 resultlengthout=udat_toPattern(fr, FALSE, NULL, resultlength, &status);
639 if(status==U_BUFFER_OVERFLOW_ERROR)
640 {
641 status=U_ZERO_ERROR;
642 resultlength=resultlengthout + 1;
643 pattern=(UChar*)malloc(sizeof(UChar) * resultlength);
644 udat_toPattern(fr, FALSE, pattern, resultlength, &status);
645 }
646 if(U_FAILURE(status))
647 {
648 log_err("FAIL: error in extracting the pattern from UNumberFormat\n %s\n",
649 myErrorName(status) );
650 }
651
652 udat_applyPattern(def, FALSE, pattern, u_strlen(pattern));
653 resultlength=0;
654 resultlengthout=udat_toPattern(def, FALSE, NULL, resultlength,&status);
655 if(status==U_BUFFER_OVERFLOW_ERROR)
656 {
657 status=U_ZERO_ERROR;
658 resultlength=resultlengthout + 1;
659 if(result != NULL) {
660 free(result);
661 result = NULL;
662 }
663 result=(UChar*)malloc(sizeof(UChar) * resultlength);
664 udat_toPattern(fr, FALSE,result, resultlength, &status);
665 }
666 if(U_FAILURE(status))
667 {
668 log_err("FAIL: error in extracting the pattern from UNumberFormat\n %s\n",
669 myErrorName(status) );
670 }
671 if(u_strcmp(result, pattern)==0)
672 log_verbose("Pattern applied properly\n");
673 else
674 log_err("pattern could not be applied properly\n");
675
676 free(pattern);
677 /*testing set symbols */
678 resultlength=0;
679 resultlengthout=udat_getSymbols(fr, UDAT_MONTHS, 11 , NULL, resultlength, &status);
680 if(status==U_BUFFER_OVERFLOW_ERROR){
681 status=U_ZERO_ERROR;
682 resultlength=resultlengthout+1;
683 if(result != NULL) {
684 free(result);
685 result = NULL;
686 }
687 result=(UChar*)malloc(sizeof(UChar) * resultlength);
688 udat_getSymbols(fr, UDAT_MONTHS, 11, result, resultlength, &status);
689
690 }
691 if(U_FAILURE(status))
692 log_err("FAIL: error in getSymbols() %s\n", myErrorName(status) );
693 resultlength=resultlengthout+1;
694
695 udat_setSymbols(def, UDAT_MONTHS, 11, result, resultlength, &status);
696 if(U_FAILURE(status))
697 {
698 log_err("FAIL: Error in udat_setSymbols() : %s\n", myErrorName(status) );
699 }
700 else
701 log_verbose("PASS: SetSymbols successful\n");
702
703 resultlength=0;
704 resultlengthout=udat_getSymbols(def, UDAT_MONTHS, 11, NULL, resultlength, &status);
705 if(status==U_BUFFER_OVERFLOW_ERROR){
706 status=U_ZERO_ERROR;
707 resultlength=resultlengthout+1;
708 value=(UChar*)malloc(sizeof(UChar) * resultlength);
709 udat_getSymbols(def, UDAT_MONTHS, 11, value, resultlength, &status);
710 }
711 if(U_FAILURE(status))
712 log_err("FAIL: error in retrieving the value using getSymbols i.e roundtrip\n");
713
714 if(u_strcmp(result, value)!=0)
715 log_data_err("FAIL: Error in settting and getting symbols\n");
716 else
717 log_verbose("PASS: setSymbols successful\n");
718
719
720 /*run series of tests to test setSymbols regressively*/
721 log_verbose("\nTesting setSymbols regressively\n");
722 VerifysetSymbols(def, UDAT_ERAS, 0, "BeforeChrist");
723 VerifysetSymbols(def, UDAT_ERA_NAMES, 1, "AnnoDomini");
724 VerifysetSymbols(def, UDAT_WEEKDAYS, 1, "Sundayweek");
725 VerifysetSymbols(def, UDAT_SHORT_WEEKDAYS, 7, "Satweek");
726 VerifysetSymbols(def, UDAT_NARROW_WEEKDAYS, 4, "M");
727 VerifysetSymbols(def, UDAT_STANDALONE_WEEKDAYS, 1, "Sonntagweek");
728 VerifysetSymbols(def, UDAT_STANDALONE_SHORT_WEEKDAYS, 7, "Sams");
729 VerifysetSymbols(def, UDAT_STANDALONE_NARROW_WEEKDAYS, 4, "V");
730 VerifysetSymbols(fr, UDAT_MONTHS, 11, "december");
731 VerifysetSymbols(fr, UDAT_SHORT_MONTHS, 0, "Jan");
732 VerifysetSymbols(fr, UDAT_NARROW_MONTHS, 1, "R");
733 VerifysetSymbols(fr, UDAT_STANDALONE_MONTHS, 11, "dezember");
734 VerifysetSymbols(fr, UDAT_STANDALONE_SHORT_MONTHS, 7, "Aug");
735 VerifysetSymbols(fr, UDAT_STANDALONE_NARROW_MONTHS, 2, "M");
736 VerifysetSymbols(fr, UDAT_QUARTERS, 0, "1. Quart");
737 VerifysetSymbols(fr, UDAT_SHORT_QUARTERS, 1, "QQ2");
738 VerifysetSymbols(fr, UDAT_STANDALONE_QUARTERS, 2, "3rd Quar.");
739 VerifysetSymbols(fr, UDAT_STANDALONE_SHORT_QUARTERS, 3, "4QQ");
740
741
742 /*run series of tests to test get and setSymbols regressively*/
743 log_verbose("\nTesting get and set symbols regressively\n");
744 VerifygetsetSymbols(fr, def, UDAT_WEEKDAYS, 1);
745 VerifygetsetSymbols(fr, def, UDAT_WEEKDAYS, 7);
746 VerifygetsetSymbols(fr, def, UDAT_SHORT_WEEKDAYS, 1);
747 VerifygetsetSymbols(fr, def, UDAT_SHORT_WEEKDAYS, 7);
748 VerifygetsetSymbols(fr, def, UDAT_MONTHS, 0);
749 VerifygetsetSymbols(fr, def, UDAT_SHORT_MONTHS, 0);
750 VerifygetsetSymbols(fr, def, UDAT_ERAS,1);
751 VerifygetsetSymbols(fr, def, UDAT_LOCALIZED_CHARS, 0);
752 VerifygetsetSymbols(fr, def, UDAT_AM_PMS, 1);
753
754
755 /*closing*/
756
757 udat_close(fr);
758 udat_close(def);
759 if(result != NULL) {
760 free(result);
761 result = NULL;
762 }
763 free(value);
764
765 }
766
767 /**
768 * Test DateFormat(Calendar) API
769 */
770 static void TestDateFormatCalendar() {
771 UDateFormat *date=0, *time=0, *full=0;
772 UCalendar *cal=0;
773 UChar buf[256];
774 char cbuf[256];
775 int32_t pos;
776 UDate when;
777 UErrorCode ec = U_ZERO_ERROR;
778
779 ctest_setTimeZone(NULL, &ec);
780
781 /* Create a formatter for date fields. */
782 date = udat_open(UDAT_NONE, UDAT_SHORT, "en_US", NULL, 0, NULL, 0, &ec);
783 if (U_FAILURE(ec)) {
784 log_data_err("FAIL: udat_open(NONE, SHORT, en_US) failed with %s (Are you missing data?)\n",
785 u_errorName(ec));
786 goto FAIL;
787 }
788
789 /* Create a formatter for time fields. */
790 time = udat_open(UDAT_SHORT, UDAT_NONE, "en_US", NULL, 0, NULL, 0, &ec);
791 if (U_FAILURE(ec)) {
792 log_err("FAIL: udat_open(SHORT, NONE, en_US) failed with %s\n",
793 u_errorName(ec));
794 goto FAIL;
795 }
796
797 /* Create a full format for output */
798 full = udat_open(UDAT_FULL, UDAT_FULL, "en_US", NULL, 0, NULL, 0, &ec);
799 if (U_FAILURE(ec)) {
800 log_err("FAIL: udat_open(FULL, FULL, en_US) failed with %s\n",
801 u_errorName(ec));
802 goto FAIL;
803 }
804
805 /* Create a calendar */
806 cal = ucal_open(NULL, 0, "en_US", UCAL_GREGORIAN, &ec);
807 if (U_FAILURE(ec)) {
808 log_err("FAIL: ucal_open(en_US) failed with %s\n",
809 u_errorName(ec));
810 goto FAIL;
811 }
812
813 /* Parse the date */
814 ucal_clear(cal);
815 u_uastrcpy(buf, "4/5/2001");
816 pos = 0;
817 udat_parseCalendar(date, cal, buf, -1, &pos, &ec);
818 if (U_FAILURE(ec)) {
819 log_err("FAIL: udat_parseCalendar(4/5/2001) failed at %d with %s\n",
820 pos, u_errorName(ec));
821 goto FAIL;
822 }
823
824 /* Parse the time */
825 u_uastrcpy(buf, "5:45 PM");
826 pos = 0;
827 udat_parseCalendar(time, cal, buf, -1, &pos, &ec);
828 if (U_FAILURE(ec)) {
829 log_err("FAIL: udat_parseCalendar(17:45) failed at %d with %s\n",
830 pos, u_errorName(ec));
831 goto FAIL;
832 }
833
834 /* Check result */
835 when = ucal_getMillis(cal, &ec);
836 if (U_FAILURE(ec)) {
837 log_err("FAIL: ucal_getMillis() failed with %s\n", u_errorName(ec));
838 goto FAIL;
839 }
840 udat_format(full, when, buf, sizeof(buf), NULL, &ec);
841 if (U_FAILURE(ec)) {
842 log_err("FAIL: udat_format() failed with %s\n", u_errorName(ec));
843 goto FAIL;
844 }
845 u_austrcpy(cbuf, buf);
846 /* Thursday, April 5, 2001 5:45:00 PM PDT 986517900000 */
847 if (when == 986517900000.0) {
848 log_verbose("Ok: Parsed result: %s\n", cbuf);
849 } else {
850 log_err("FAIL: Parsed result: %s, exp 4/5/2001 5:45 PM\n", cbuf);
851 }
852
853 FAIL:
854 udat_close(date);
855 udat_close(time);
856 udat_close(full);
857 ucal_close(cal);
858
859 ctest_resetTimeZone();
860 }
861
862 /*INTERNAL FUNCTIONS USED*/
863 /* N.B.: use idx instead of index to avoid 'shadow' warnings in strict mode. */
864 static void VerifygetSymbols(UDateFormat* datfor, UDateFormatSymbolType type, int32_t idx, const char* expected)
865 {
866 UChar *pattern=NULL;
867 UErrorCode status = U_ZERO_ERROR;
868 UChar *result=NULL;
869 int32_t resultlength, resultlengthout;
870
871
872 pattern=(UChar*)malloc(sizeof(UChar) * (strlen(expected)+1));
873 u_uastrcpy(pattern, expected);
874 resultlength=0;
875 resultlengthout=udat_getSymbols(datfor, type, idx , NULL, resultlength, &status);
876 if(status==U_BUFFER_OVERFLOW_ERROR)
877 {
878 status=U_ZERO_ERROR;
879 resultlength=resultlengthout+1;
880 result=(UChar*)malloc(sizeof(UChar) * resultlength);
881 udat_getSymbols(datfor, type, idx, result, resultlength, &status);
882
883 }
884 if(U_FAILURE(status))
885 {
886 log_err("FAIL: Error in udat_getSymbols()... %s\n", myErrorName(status) );
887 return;
888 }
889 if(u_strcmp(result, pattern)==0)
890 log_verbose("PASS: getSymbols retrieved the right value\n");
891 else{
892 log_data_err("FAIL: getSymbols retrieved the wrong value\n Expected %s Got %s\n", austrdup(pattern),
893 austrdup(result) );
894 }
895 free(result);
896 free(pattern);
897 }
898
899 static void VerifysetSymbols(UDateFormat* datfor, UDateFormatSymbolType type, int32_t idx, const char* expected)
900 {
901 UChar *result=NULL;
902 UChar *value=NULL;
903 int32_t resultlength, resultlengthout;
904 UErrorCode status = U_ZERO_ERROR;
905
906 value=(UChar*)malloc(sizeof(UChar) * (strlen(expected) + 1));
907 u_uastrcpy(value, expected);
908 udat_setSymbols(datfor, type, idx, value, u_strlen(value), &status);
909 if(U_FAILURE(status))
910 {
911 log_err("FAIL: Error in udat_setSymbols() %s\n", myErrorName(status) );
912 return;
913 }
914
915 resultlength=0;
916 resultlengthout=udat_getSymbols(datfor, type, idx, NULL, resultlength, &status);
917 if(status==U_BUFFER_OVERFLOW_ERROR){
918 status=U_ZERO_ERROR;
919 resultlength=resultlengthout+1;
920 result=(UChar*)malloc(sizeof(UChar) * resultlength);
921 udat_getSymbols(datfor, type, idx, result, resultlength, &status);
922 }
923 if(U_FAILURE(status)){
924 log_err("FAIL: error in retrieving the value using getSymbols after setting it previously\n %s\n",
925 myErrorName(status) );
926 return;
927 }
928
929 if(u_strcmp(result, value)!=0){
930 log_err("FAIL:Error in setting and then getting symbols\n Expected %s Got %s\n", austrdup(value),
931 austrdup(result) );
932 }
933 else
934 log_verbose("PASS: setSymbols successful\n");
935
936 free(value);
937 free(result);
938 }
939
940
941 static void VerifygetsetSymbols(UDateFormat* from, UDateFormat* to, UDateFormatSymbolType type, int32_t idx)
942 {
943 UChar *result=NULL;
944 UChar *value=NULL;
945 int32_t resultlength, resultlengthout;
946 UErrorCode status = U_ZERO_ERROR;
947
948 resultlength=0;
949 resultlengthout=udat_getSymbols(from, type, idx , NULL, resultlength, &status);
950 if(status==U_BUFFER_OVERFLOW_ERROR){
951 status=U_ZERO_ERROR;
952 resultlength=resultlengthout+1;
953 result=(UChar*)malloc(sizeof(UChar) * resultlength);
954 udat_getSymbols(from, type, idx, result, resultlength, &status);
955 }
956 if(U_FAILURE(status)){
957 log_err("FAIL: error in getSymbols() %s\n", myErrorName(status) );
958 return;
959 }
960
961 resultlength=resultlengthout+1;
962 udat_setSymbols(to, type, idx, result, resultlength, &status);
963 if(U_FAILURE(status))
964 {
965 log_err("FAIL: Error in udat_setSymbols() : %s\n", myErrorName(status) );
966 return;
967 }
968
969 resultlength=0;
970 resultlengthout=udat_getSymbols(to, type, idx, NULL, resultlength, &status);
971 if(status==U_BUFFER_OVERFLOW_ERROR){
972 status=U_ZERO_ERROR;
973 resultlength=resultlengthout+1;
974 value=(UChar*)malloc(sizeof(UChar) * resultlength);
975 udat_getSymbols(to, type, idx, value, resultlength, &status);
976 }
977 if(U_FAILURE(status)){
978 log_err("FAIL: error in retrieving the value using getSymbols i.e roundtrip\n %s\n",
979 myErrorName(status) );
980 return;
981 }
982
983 if(u_strcmp(result, value)!=0){
984 log_data_err("FAIL:Error in setting and then getting symbols\n Expected %s Got %s\n", austrdup(result),
985 austrdup(value) );
986 }
987 else
988 log_verbose("PASS: setSymbols successful\n");
989
990 free(value);
991 free(result);
992 }
993
994
995 static UChar* myNumformat(const UNumberFormat* numfor, double d)
996 {
997 UChar *result2=NULL;
998 int32_t resultlength, resultlengthneeded;
999 UErrorCode status = U_ZERO_ERROR;
1000
1001 resultlength=0;
1002 resultlengthneeded=unum_formatDouble(numfor, d, NULL, resultlength, NULL, &status);
1003 if(status==U_BUFFER_OVERFLOW_ERROR)
1004 {
1005 status=U_ZERO_ERROR;
1006 resultlength=resultlengthneeded+1;
1007 /*result2=(UChar*)malloc(sizeof(UChar) * resultlength);*/ /* this leaks */
1008 result2=(UChar*)ctst_malloc(sizeof(UChar) * resultlength); /*this won't*/
1009 unum_formatDouble(numfor, d, result2, resultlength, NULL, &status);
1010 }
1011 if(U_FAILURE(status))
1012 {
1013 log_err("FAIL: Error in formatting using unum_format(.....) %s\n", myErrorName(status) );
1014 return 0;
1015 }
1016
1017 return result2;
1018 }
1019
1020 /**
1021 * The search depth for TestExtremeDates. The total number of
1022 * dates that will be tested is (2^EXTREME_DATES_DEPTH) - 1.
1023 */
1024 #define EXTREME_DATES_DEPTH 8
1025
1026 /**
1027 * Support for TestExtremeDates (below).
1028 *
1029 * Test a single date to see whether udat_format handles it properly.
1030 */
1031 static UBool _aux1ExtremeDates(UDateFormat* fmt, UDate date,
1032 UChar* buf, int32_t buflen, char* cbuf,
1033 UErrorCode* ec) {
1034 int32_t len = udat_format(fmt, date, buf, buflen, 0, ec);
1035 if (!assertSuccess("udat_format", ec)) return FALSE;
1036 u_austrncpy(cbuf, buf, buflen);
1037 if (len < 4) {
1038 log_err("FAIL: udat_format(%g) => \"%s\"\n", date, cbuf);
1039 } else {
1040 log_verbose("udat_format(%g) => \"%s\"\n", date, cbuf);
1041 }
1042 return TRUE;
1043 }
1044
1045 /**
1046 * Support for TestExtremeDates (below).
1047 *
1048 * Recursively test between 'small' and 'large', up to the depth
1049 * limit specified by EXTREME_DATES_DEPTH.
1050 */
1051 static UBool _aux2ExtremeDates(UDateFormat* fmt, UDate small, UDate large,
1052 UChar* buf, int32_t buflen, char* cbuf,
1053 int32_t count,
1054 UErrorCode* ec) {
1055 /* Logarithmic midpoint; see below */
1056 UDate mid = (UDate) exp((log(small) + log(large)) / 2);
1057 if (count == EXTREME_DATES_DEPTH) {
1058 return TRUE;
1059 }
1060 return
1061 _aux1ExtremeDates(fmt, mid, buf, buflen, cbuf, ec) &&
1062 _aux2ExtremeDates(fmt, small, mid, buf, buflen, cbuf, count+1, ec) &&
1063 _aux2ExtremeDates(fmt, mid, large, buf, buflen, cbuf, count+1, ec);
1064 }
1065
1066 /**
1067 * http://www.jtcsv.com/cgibin/icu-bugs?findid=3659
1068 *
1069 * For certain large dates, udat_format crashes on MacOS. This test
1070 * attempts to reproduce this problem by doing a recursive logarithmic*
1071 * binary search of a predefined interval (from 'small' to 'large').
1072 *
1073 * The limit of the search is given by EXTREME_DATES_DEPTH, above.
1074 *
1075 * *The search has to be logarithmic, not linear. A linear search of the
1076 * range 0..10^30, for example, will find 0.5*10^30, then 0.25*10^30 and
1077 * 0.75*10^30, etc. A logarithmic search will find 10^15, then 10^7.5
1078 * and 10^22.5, etc.
1079 */
1080 static void TestExtremeDates() {
1081 UDateFormat *fmt;
1082 UErrorCode ec;
1083 UChar buf[256];
1084 char cbuf[256];
1085 const double small = 1000; /* 1 sec */
1086 const double large = 1e+30; /* well beyond usable UDate range */
1087
1088 /* There is no need to test larger values from 1e+30 to 1e+300;
1089 the failures occur around 1e+27, and never above 1e+30. */
1090
1091 ec = U_ZERO_ERROR;
1092 fmt = udat_open(UDAT_LONG, UDAT_LONG, "en_US",
1093 0, 0, 0, 0, &ec);
1094 if (U_FAILURE(ec)) {
1095 log_data_err("FAIL: udat_open (%s) (Are you missing data?)\n", u_errorName(ec));
1096 return;
1097 }
1098
1099 _aux2ExtremeDates(fmt, small, large, buf, LEN(buf), cbuf, 0, &ec);
1100
1101 udat_close(fmt);
1102 }
1103
1104 static void TestAllLocales(void) {
1105 int32_t idx, dateIdx, timeIdx, localeCount;
1106 static const UDateFormatStyle style[] = {
1107 UDAT_FULL, UDAT_LONG, UDAT_MEDIUM, UDAT_SHORT
1108 };
1109 localeCount = uloc_countAvailable();
1110 for (idx = 0; idx < localeCount; idx++) {
1111 for (dateIdx = 0; dateIdx < (int32_t)(sizeof(style)/sizeof(style[0])); dateIdx++) {
1112 for (timeIdx = 0; timeIdx < (int32_t)(sizeof(style)/sizeof(style[0])); timeIdx++) {
1113 UErrorCode status = U_ZERO_ERROR;
1114 udat_close(udat_open(style[dateIdx], style[timeIdx],
1115 uloc_getAvailable(idx), NULL, 0, NULL, 0, &status));
1116 if (U_FAILURE(status)) {
1117 log_err("FAIL: udat_open(%s) failed with (%s) dateIdx=%d, timeIdx=%d\n",
1118 uloc_getAvailable(idx), u_errorName(status), dateIdx, timeIdx);
1119 }
1120 }
1121 }
1122 }
1123 }
1124
1125 static void TestRelativeCrash(void) {
1126 static const UChar tzName[] = { 0x0055, 0x0053, 0x002F, 0x0050, 0x0061, 0x0063, 0x0069, 0x0066, 0x0069, 0x0063, 0 };
1127 static const UDate aDate = -631152000000.0;
1128
1129 UErrorCode status = U_ZERO_ERROR;
1130 UErrorCode expectStatus = U_ILLEGAL_ARGUMENT_ERROR;
1131 UDateFormat icudf;
1132
1133 icudf = udat_open(UDAT_NONE, UDAT_SHORT_RELATIVE, "en", tzName, -1, NULL, 0, &status);
1134 if ( U_SUCCESS(status) ) {
1135 const char *what = "???";
1136 {
1137 UErrorCode subStatus = U_ZERO_ERROR;
1138 what = "udat_set2DigitYearStart";
1139 log_verbose("Trying %s on a relative date..\n", what);
1140 udat_set2DigitYearStart(icudf, aDate, &subStatus);
1141 if(subStatus == expectStatus) {
1142 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1143 } else {
1144 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
1145 }
1146 }
1147 {
1148 /* clone works polymorphically. try it anyways */
1149 UErrorCode subStatus = U_ZERO_ERROR;
1150 UDateFormat *oth;
1151 what = "clone";
1152 log_verbose("Trying %s on a relative date..\n", what);
1153 oth = udat_clone(icudf, &subStatus);
1154 if(subStatus == U_ZERO_ERROR) {
1155 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1156 udat_close(oth); /* ? */
1157 } else {
1158 log_err("FAIL: didn't crash on %s, but got %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
1159 }
1160 }
1161 {
1162 UErrorCode subStatus = U_ZERO_ERROR;
1163 what = "udat_get2DigitYearStart";
1164 log_verbose("Trying %s on a relative date..\n", what);
1165 udat_get2DigitYearStart(icudf, &subStatus);
1166 if(subStatus == expectStatus) {
1167 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1168 } else {
1169 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
1170 }
1171 }
1172 {
1173 /* Now udat_toPattern works for relative date formatters, unless localized is TRUE */
1174 UErrorCode subStatus = U_ZERO_ERROR;
1175 what = "udat_toPattern";
1176 log_verbose("Trying %s on a relative date..\n", what);
1177 udat_toPattern(icudf, TRUE,NULL,0, &subStatus);
1178 if(subStatus == expectStatus) {
1179 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1180 } else {
1181 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
1182 }
1183 }
1184 {
1185 UErrorCode subStatus = U_ZERO_ERROR;
1186 what = "udat_applyPattern";
1187 log_verbose("Trying %s on a relative date..\n", what);
1188 udat_applyPattern(icudf, FALSE,tzName,-1);
1189 subStatus = U_ILLEGAL_ARGUMENT_ERROR; /* what it should be, if this took an errorcode. */
1190 if(subStatus == expectStatus) {
1191 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1192 } else {
1193 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
1194 }
1195 }
1196 {
1197 UChar erabuf[32];
1198 UErrorCode subStatus = U_ZERO_ERROR;
1199 what = "udat_getSymbols";
1200 log_verbose("Trying %s on a relative date..\n", what);
1201 udat_getSymbols(icudf, UDAT_ERAS,0,erabuf,sizeof(erabuf)/sizeof(erabuf[0]), &subStatus);
1202 if(subStatus == U_ZERO_ERROR) {
1203 log_verbose("Success: %s returned %s.\n", what, u_errorName(subStatus));
1204 } else {
1205 log_err("FAIL: didn't crash on %s, but got %s instead of U_ZERO_ERROR.\n", what, u_errorName(subStatus));
1206 }
1207 }
1208 {
1209 UErrorCode subStatus = U_ZERO_ERROR;
1210 UChar symbolValue = 0x0041;
1211 what = "udat_setSymbols";
1212 log_verbose("Trying %s on a relative date..\n", what);
1213 udat_setSymbols(icudf, UDAT_ERAS,0,&symbolValue,1, &subStatus); /* bogus values */
1214 if(subStatus == expectStatus) {
1215 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1216 } else {
1217 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
1218 }
1219 }
1220 {
1221 UErrorCode subStatus = U_ZERO_ERROR;
1222 what = "udat_countSymbols";
1223 log_verbose("Trying %s on a relative date..\n", what);
1224 udat_countSymbols(icudf, UDAT_ERAS);
1225 subStatus = U_ILLEGAL_ARGUMENT_ERROR; /* should have an errorcode. */
1226 if(subStatus == expectStatus) {
1227 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus));
1228 } else {
1229 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus));
1230 }
1231 }
1232
1233 udat_close(icudf);
1234 } else {
1235 log_data_err("FAIL: err calling udat_open() ->%s (Are you missing data?)\n", u_errorName(status));
1236 }
1237 }
1238
1239 static const UChar skeleton_yMMMM[] = { 0x79,0x4D,0x4D,0x4D,0x4D,0 }; /* "yMMMM"; fr maps to "MMMM y", cs maps to "LLLL y" */
1240 static const UChar july2008_frDefault[] = { 0x6A,0x75,0x69,0x6C,0x6C,0x65,0x74,0x20,0x32,0x30,0x30,0x38,0 }; /* "juillet 2008" */
1241 static const UChar july2008_frTitle[] = { 0x4A,0x75,0x69,0x6C,0x6C,0x65,0x74,0x20,0x32,0x30,0x30,0x38,0 }; /* "Juillet 2008" sentence-begin, standalone */
1242 static const UChar july2008_csDefault[] = { 0x10D,0x65,0x72,0x76,0x65,0x6E,0x65,0x63,0x20,0x32,0x30,0x30,0x38,0 }; /* "c(hacek)ervenec 2008" */
1243 static const UChar july2008_csTitle[] = { 0x10C,0x65,0x72,0x76,0x65,0x6E,0x65,0x63,0x20,0x32,0x30,0x30,0x38,0 }; /* "C(hacek)ervenec 2008" sentence-begin, uiListOrMenu */
1244
1245 typedef struct {
1246 const char * locale;
1247 const UChar * skeleton;
1248 UDateFormatContextValue capitalizationContext;
1249 const UChar * expectedFormat;
1250 } TestContextItem;
1251
1252 static const TestContextItem textContextItems[] = {
1253 { "fr", skeleton_yMMMM, UDAT_CONTEXT_UNKNOWN, july2008_frDefault },
1254 #if !UCONFIG_NO_BREAK_ITERATION
1255 { "fr", skeleton_yMMMM, UDAT_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, july2008_frDefault },
1256 { "fr", skeleton_yMMMM, UDAT_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, july2008_frTitle },
1257 { "fr", skeleton_yMMMM, UDAT_CAPITALIZATION_FOR_UI_LIST_OR_MENU, july2008_frDefault },
1258 { "fr", skeleton_yMMMM, UDAT_CAPITALIZATION_FOR_STANDALONE, july2008_frTitle },
1259 #endif
1260 { "cs", skeleton_yMMMM, UDAT_CONTEXT_UNKNOWN, july2008_csDefault },
1261 #if !UCONFIG_NO_BREAK_ITERATION
1262 { "cs", skeleton_yMMMM, UDAT_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, july2008_csDefault },
1263 { "cs", skeleton_yMMMM, UDAT_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, july2008_csTitle },
1264 { "cs", skeleton_yMMMM, UDAT_CAPITALIZATION_FOR_UI_LIST_OR_MENU, july2008_csTitle },
1265 { "cs", skeleton_yMMMM, UDAT_CAPITALIZATION_FOR_STANDALONE, july2008_csDefault },
1266 #endif
1267 { NULL, NULL, 0, NULL }
1268 };
1269
1270 static const UDate july022008 = 1215000001979.0;
1271 enum { kUbufMax = 64, kBbufMax = 3*kUbufMax };
1272
1273 static void TestContext(void) {
1274 const TestContextItem* textContextItemPtr = textContextItems;
1275 for (; textContextItemPtr->locale != NULL; ++textContextItemPtr) {
1276 UErrorCode status = U_ZERO_ERROR;
1277 UDateFormat* udfmt = udat_open(UDAT_NONE, UDAT_MEDIUM, textContextItemPtr->locale, NULL, 0, NULL, 0, &status);
1278 if ( U_FAILURE(status) ) {
1279 log_data_err("FAIL: udat_open for locale %s, status %s\n", textContextItemPtr->locale, u_errorName(status) );
1280 } else {
1281 UDateTimePatternGenerator* udtpg = udatpg_open(textContextItemPtr->locale, &status);
1282 if ( U_FAILURE(status) ) {
1283 log_err("FAIL: udatpg_open for locale %s, status %s\n", textContextItemPtr->locale, u_errorName(status) );
1284 } else {
1285 UChar ubuf[kUbufMax];
1286 int32_t len = udatpg_getBestPattern(udtpg, textContextItemPtr->skeleton, -1, ubuf, kUbufMax, &status);
1287 if ( U_FAILURE(status) ) {
1288 log_err("FAIL: udatpg_getBestPattern for locale %s, status %s\n", textContextItemPtr->locale, u_errorName(status) );
1289 } else {
1290 udat_applyPattern(udfmt, FALSE, ubuf, len);
1291 udat_setDefaultContext(udfmt, UDAT_CAPITALIZATION, textContextItemPtr->capitalizationContext, &status);
1292 if ( U_FAILURE(status) ) {
1293 log_err("FAIL: udat_setDefaultContext for locale %s, capitalizationContext %d, status %s\n",
1294 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, u_errorName(status) );
1295 } else {
1296 int32_t getContext;
1297 len = udat_format(udfmt, july022008, ubuf, kUbufMax, NULL, &status);
1298 if ( U_FAILURE(status) ) {
1299 log_err("FAIL: udat_format for locale %s, capitalizationContext %d, status %s\n",
1300 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, u_errorName(status) );
1301 status = U_ZERO_ERROR;
1302 } else if (u_strncmp(ubuf, textContextItemPtr->expectedFormat, kUbufMax) != 0) {
1303 char bbuf1[kBbufMax];
1304 char bbuf2[kBbufMax];
1305 log_err("FAIL: udat_format for locale %s, capitalizationContext %d, expected %s, got %s\n",
1306 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext,
1307 u_austrncpy(bbuf1,textContextItemPtr->expectedFormat,kUbufMax), u_austrncpy(bbuf2,ubuf,kUbufMax) );
1308 }
1309 getContext = udat_getDefaultContext(udfmt, UDAT_CAPITALIZATION, &status);
1310 if ( U_FAILURE(status) ) {
1311 log_err("FAIL: udat_getDefaultContext for locale %s, capitalizationContext %d, status %s\n",
1312 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, u_errorName(status) );
1313 } else if (getContext != (int)textContextItemPtr->capitalizationContext) {
1314 log_err("FAIL: udat_getDefaultContext for locale %s, capitalizationContext %d, got context %d\n",
1315 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, getContext );
1316 }
1317 }
1318 }
1319 udatpg_close(udtpg);
1320 }
1321 udat_close(udfmt);
1322 }
1323 }
1324 }
1325
1326 #endif /* #if !UCONFIG_NO_FORMATTING */