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