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