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