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