1 /******************************************************************** 2 * COPYRIGHT: 3 * Copyright (c) 1997-2015, 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 "unicode/ufieldpositer.h" 29 #include "cintltst.h" 30 #include "cdattst.h" 31 #include "cformtst.h" 32 #include "cmemory.h" 33 34 #include <math.h> 35 36 static void TestExtremeDates(void); 37 static void TestAllLocales(void); 38 static void TestRelativeCrash(void); 39 static void TestContext(void); 40 static void TestCalendarDateParse(void); 41 static void TestParseErrorReturnValue(void); 42 static void TestFormatForFields(void); 43 44 #define LEN(a) (sizeof(a)/sizeof(a[0])) 45 46 void addDateForTest(TestNode** root); 47 48 #define TESTCASE(x) addTest(root, &x, "tsformat/cdattst/" #x) 49 50 void addDateForTest(TestNode** root) 51 { 52 TESTCASE(TestDateFormat); 53 TESTCASE(TestRelativeDateFormat); 54 TESTCASE(TestSymbols); 55 TESTCASE(TestDateFormatCalendar); 56 TESTCASE(TestExtremeDates); 57 TESTCASE(TestAllLocales); 58 TESTCASE(TestRelativeCrash); 59 TESTCASE(TestContext); 60 TESTCASE(TestCalendarDateParse); 61 TESTCASE(TestOverrideNumberFormat); 62 TESTCASE(TestParseErrorReturnValue); 63 TESTCASE(TestFormatForFields); 64 } 65 /* Testing the DateFormat API */ 66 static void TestDateFormat() 67 { 68 UDateFormat *def, *fr, *it, *de, *def1, *fr_pat; 69 UDateFormat *any; 70 UDateFormat *copy; 71 UErrorCode status = U_ZERO_ERROR; 72 UChar* result = NULL; 73 const UCalendar *cal; 74 const UNumberFormat *numformat1, *numformat2; 75 UNumberFormat *adoptNF; 76 UChar temp[50]; 77 int32_t numlocales; 78 UDate d1; 79 int i; 80 int32_t resultlength; 81 int32_t resultlengthneeded; 82 int32_t parsepos; 83 UDate d = 837039928046.0; 84 double num = -10456.37; 85 /*const char* str="yyyy.MM.dd G 'at' hh:mm:ss z"; 86 const char t[]="2/3/76 2:50 AM";*/ 87 /*Testing udat_open() to open a dateformat */ 88 89 ctest_setTimeZone(NULL, &status); 90 91 log_verbose("\nTesting udat_open() with various parameters\n"); 92 fr = udat_open(UDAT_FULL, UDAT_DEFAULT, "fr_FR", NULL,0, NULL, 0,&status); 93 if(U_FAILURE(status)) 94 { 95 log_data_err("FAIL: error in creating the dateformat using full time style with french locale -> %s (Are you missing data?)\n", 96 myErrorName(status) ); 97 return; 98 } 99 /* this is supposed to open default date format, but later on it treats it like it is "en_US" 100 - very bad if you try to run the tests on machine where default locale is NOT "en_US" */ 101 /* def = udat_open(UDAT_SHORT, UDAT_SHORT, NULL, NULL, 0, &status); */ 102 def = udat_open(UDAT_SHORT, UDAT_SHORT, "en_US", NULL, 0,NULL, 0, &status); 103 if(U_FAILURE(status)) 104 { 105 log_err("FAIL: error in creating the dateformat using short date and time style\n %s\n", 106 myErrorName(status) ); 107 return; 108 } 109 it = udat_open(UDAT_DEFAULT, UDAT_MEDIUM, "it_IT", NULL, 0, NULL, 0,&status); 110 if(U_FAILURE(status)) 111 { 112 log_err("FAIL: error in creating the dateformat using medium date style with italian locale\n %s\n", 113 myErrorName(status) ); 114 return; 115 } 116 de = udat_open(UDAT_LONG, UDAT_LONG, "de_DE", NULL, 0, NULL, 0,&status); 117 if(U_FAILURE(status)) 118 { 119 log_err("FAIL: error in creating the dateformat using long time and date styles with german locale\n %s\n", 120 myErrorName(status)); 121 return; 122 } 123 /*creating a default dateformat */ 124 def1 = udat_open(UDAT_SHORT, UDAT_SHORT, NULL, NULL, 0,NULL, 0, &status); 125 if(U_FAILURE(status)) 126 { 127 log_err("FAIL: error in creating the dateformat using short date and time style\n %s\n", 128 myErrorName(status) ); 129 return; 130 } 131 132 133 /*Testing udat_getAvailable() and udat_countAvailable()*/ 134 log_verbose("\nTesting getAvailableLocales and countAvailable()\n"); 135 numlocales=udat_countAvailable(); 136 /* use something sensible w/o hardcoding the count */ 137 if(numlocales < 0) 138 log_data_err("FAIL: error in countAvailable\n"); 139 log_verbose("The number of locales for which date/time formatting patterns are available is %d\n", numlocales); 140 141 for(i=0;i<numlocales;i++) { 142 UErrorCode subStatus = U_ZERO_ERROR; 143 log_verbose("Testing open of %s\n", udat_getAvailable(i)); 144 any = udat_open(UDAT_SHORT, UDAT_SHORT, udat_getAvailable(i), NULL ,0, NULL, 0, &subStatus); 145 if(U_FAILURE(subStatus)) { 146 log_data_err("FAIL: date format %s (getAvailable(%d)) is not instantiable: %s\n", udat_getAvailable(i), i, u_errorName(subStatus)); 147 } 148 udat_close(any); 149 } 150 151 /*Testing udat_clone()*/ 152 log_verbose("\nTesting the udat_clone() function of date format\n"); 153 copy=udat_clone(def, &status); 154 if(U_FAILURE(status)){ 155 log_err("Error in creating the clone using udat_clone: %s\n", myErrorName(status) ); 156 } 157 /*if(def != copy) 158 log_err("Error in udat_clone");*/ /*how should i check for equality???? */ 159 160 /*Testing udat_format()*/ 161 log_verbose("\nTesting the udat_format() function of date format\n"); 162 u_uastrcpy(temp, "7/10/96, 4:05 PM"); 163 /*format using def */ 164 resultlength=0; 165 resultlengthneeded=udat_format(def, d, NULL, resultlength, NULL, &status); 166 if(status==U_BUFFER_OVERFLOW_ERROR) 167 { 168 status=U_ZERO_ERROR; 169 resultlength=resultlengthneeded+1; 170 if(result != NULL) { 171 free(result); 172 result = NULL; 173 } 174 result=(UChar*)malloc(sizeof(UChar) * resultlength); 175 udat_format(def, d, result, resultlength, NULL, &status); 176 } 177 if(U_FAILURE(status) || !result) 178 { 179 log_err("FAIL: Error in formatting using udat_format(.....) %s\n", myErrorName(status) ); 180 return; 181 } 182 else 183 log_verbose("PASS: formatting successful\n"); 184 if(u_strcmp(result, temp)==0) 185 log_verbose("PASS: Date Format for US locale successful using udat_format()\n"); 186 else { 187 char xbuf[2048]; 188 char gbuf[2048]; 189 u_austrcpy(xbuf, temp); 190 u_austrcpy(gbuf, result); 191 log_err("FAIL: Date Format for US locale failed using udat_format() - expected %s got %s\n", xbuf, gbuf); 192 } 193 /*format using fr */ 194 195 u_unescape("10 juil. 1996 16:05:28 heure d\\u2019\\u00E9t\\u00E9 du Pacifique", temp, 50); 196 if(result != NULL) { 197 free(result); 198 result = NULL; 199 } 200 result=myDateFormat(fr, d); 201 if(u_strcmp(result, temp)==0) 202 log_verbose("PASS: Date Format for french locale successful using udat_format()\n"); 203 else 204 log_data_err("FAIL: Date Format for french locale failed using udat_format().\n" ); 205 206 /*format using it */ 207 u_uastrcpy(temp, "10 lug 1996, 16:05:28"); 208 209 { 210 UChar *fmtted; 211 char g[100]; 212 char x[100]; 213 214 fmtted = myDateFormat(it,d); 215 u_austrcpy(g, fmtted); 216 u_austrcpy(x, temp); 217 if(u_strcmp(fmtted, temp)==0) { 218 log_verbose("PASS: Date Format for italian locale successful uisng udat_format() - wanted %s, got %s\n", x, g); 219 } else { 220 log_data_err("FAIL: Date Format for italian locale failed using udat_format() - wanted %s, got %s\n", x, g); 221 } 222 } 223 224 /*Testing parsing using udat_parse()*/ 225 log_verbose("\nTesting parsing using udat_parse()\n"); 226 u_uastrcpy(temp,"2/3/76, 2:50 AM"); 227 parsepos=0; 228 status=U_ZERO_ERROR; 229 230 d1=udat_parse(def, temp, u_strlen(temp), &parsepos, &status); 231 if(U_FAILURE(status)) 232 { 233 log_err("FAIL: Error in parsing using udat_parse(.....) %s\n", myErrorName(status) ); 234 } 235 else 236 log_verbose("PASS: parsing succesful\n"); 237 /*format it back and check for equality */ 238 239 240 if(u_strcmp(myDateFormat(def, d1),temp)!=0) 241 log_err("FAIL: error in parsing\n"); 242 243 /*Testing parsing using udat_parse()*/ 244 log_verbose("\nTesting parsing using udat_parse()\n"); 245 u_uastrcpy(temp,"2/Don't parse this part"); 246 status=U_ZERO_ERROR; 247 248 d1=udat_parse(def, temp, u_strlen(temp), NULL, &status); 249 if(status != U_PARSE_ERROR) 250 { 251 log_err("FAIL: udat_parse(\"bad string\") passed when it should have failed\n"); 252 } 253 else 254 log_verbose("PASS: parsing succesful\n"); 255 256 257 258 /*Testing udat_openPattern() */ 259 status=U_ZERO_ERROR; 260 log_verbose("\nTesting the udat_openPattern with a specified pattern\n"); 261 /*for french locale */ 262 fr_pat=udat_open(UDAT_PATTERN, UDAT_PATTERN,"fr_FR",NULL,0,temp, u_strlen(temp), &status); 263 if(U_FAILURE(status)) 264 { 265 log_err("FAIL: Error in creating a date format using udat_openPattern \n %s\n", 266 myErrorName(status) ); 267 } 268 else 269 log_verbose("PASS: creating dateformat using udat_openPattern() succesful\n"); 270 271 272 /*Testing applyPattern and toPattern */ 273 log_verbose("\nTesting applyPattern and toPattern()\n"); 274 udat_applyPattern(def1, FALSE, temp, u_strlen(temp)); 275 log_verbose("Extracting the pattern\n"); 276 277 resultlength=0; 278 resultlengthneeded=udat_toPattern(def1, FALSE, NULL, resultlength, &status); 279 if(status==U_BUFFER_OVERFLOW_ERROR) 280 { 281 status=U_ZERO_ERROR; 282 resultlength=resultlengthneeded + 1; 283 result=(UChar*)malloc(sizeof(UChar) * resultlength); 284 udat_toPattern(def1, FALSE, result, resultlength, &status); 285 } 286 if(U_FAILURE(status)) 287 { 288 log_err("FAIL: error in extracting the pattern from UNumberFormat\n %s\n", 289 myErrorName(status) ); 290 } 291 if(u_strcmp(result, temp)!=0) 292 log_err("FAIL: Error in extracting the pattern\n"); 293 else 294 log_verbose("PASS: applyPattern and toPattern work fine\n"); 295 296 if(result != NULL) { 297 free(result); 298 result = NULL; 299 } 300 301 302 /*Testing getter and setter functions*/ 303 /*isLenient and setLenient()*/ 304 log_verbose("\nTesting the isLenient and setLenient properties\n"); 305 udat_setLenient(fr, udat_isLenient(it)); 306 if(udat_isLenient(fr) != udat_isLenient(it)) 307 log_err("ERROR: setLenient() failed\n"); 308 else 309 log_verbose("PASS: setLenient() successful\n"); 310 311 312 /*Test get2DigitYearStart set2DigitYearStart */ 313 log_verbose("\nTesting the get and set 2DigitYearStart properties\n"); 314 d1= udat_get2DigitYearStart(fr_pat,&status); 315 if(U_FAILURE(status)) { 316 log_err("ERROR: udat_get2DigitYearStart failed %s\n", myErrorName(status) ); 317 } 318 status = U_ZERO_ERROR; 319 udat_set2DigitYearStart(def1 ,d1, &status); 320 if(U_FAILURE(status)) { 321 log_err("ERROR: udat_set2DigitYearStart failed %s\n", myErrorName(status) ); 322 } 323 if(udat_get2DigitYearStart(fr_pat, &status) != udat_get2DigitYearStart(def1, &status)) 324 log_err("FAIL: error in set2DigitYearStart\n"); 325 else 326 log_verbose("PASS: set2DigitYearStart successful\n"); 327 /*try setting it to another value */ 328 udat_set2DigitYearStart(de, 2000.0, &status); 329 if(U_FAILURE(status)){ 330 log_verbose("ERROR: udat_set2DigitYearStart failed %s\n", myErrorName(status) ); 331 } 332 if(udat_get2DigitYearStart(de, &status) != 2000) 333 log_err("FAIL: error in set2DigitYearStart\n"); 334 else 335 log_verbose("PASS: set2DigitYearStart successful\n"); 336 337 338 339 /*Test getNumberFormat() and setNumberFormat() */ 340 log_verbose("\nTesting the get and set NumberFormat properties of date format\n"); 341 numformat1=udat_getNumberFormat(fr_pat); 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 /*Test getNumberFormat() and adoptNumberFormat() */ 350 log_verbose("\nTesting the get and adopt NumberFormat properties of date format\n"); 351 adoptNF= unum_open(UNUM_DEFAULT, NULL, 0, NULL, NULL, &status); 352 udat_adoptNumberFormat(def1, adoptNF); 353 numformat2=udat_getNumberFormat(def1); 354 if(u_strcmp(myNumformat(adoptNF, num), myNumformat(numformat2, num)) !=0) 355 log_err("FAIL: error in adoptNumberFormat or getNumberFormat()\n"); 356 else 357 log_verbose("PASS:adoptNumberFormat and getNumberFormat succesful\n"); 358 359 /*try setting the number format to another format */ 360 numformat1=udat_getNumberFormat(def); 361 udat_setNumberFormat(def1, numformat1); 362 numformat2=udat_getNumberFormat(def1); 363 if(u_strcmp(myNumformat(numformat1, num), myNumformat(numformat2, num)) !=0) 364 log_err("FAIL: error in setNumberFormat or getNumberFormat()\n"); 365 else 366 log_verbose("PASS: setNumberFormat and getNumberFormat succesful\n"); 367 368 369 370 /*Test getCalendar and setCalendar*/ 371 log_verbose("\nTesting the udat_getCalendar() and udat_setCalendar() properties\n"); 372 cal=udat_getCalendar(fr_pat); 373 374 375 udat_setCalendar(def1, cal); 376 if(!ucal_equivalentTo(udat_getCalendar(fr_pat), udat_getCalendar(def1))) 377 log_err("FAIL: Error in setting and getting the calendar\n"); 378 else 379 log_verbose("PASS: getting and setting calendar successful\n"); 380 381 if(result!=NULL) { 382 free(result); 383 } 384 385 /*Closing the UDateForamt */ 386 udat_close(def); 387 udat_close(fr); 388 udat_close(it); 389 udat_close(de); 390 udat_close(def1); 391 udat_close(fr_pat); 392 udat_close(copy); 393 394 ctest_resetTimeZone(); 395 } 396 397 /* 398 Test combined relative date formatting (relative date + non-relative time). 399 This is a bit tricky since we can't have static test data for comparison, the 400 relative date formatting is relative to the time the tests are run. We generate 401 the data for comparison dynamically. However, the tests could fail if they are 402 run right at midnight Pacific time and the call to ucal_getNow() is before midnight 403 while the calls to udat_format are after midnight or span midnight. 404 */ 405 static const UDate dayInterval = 24.0*60.0*60.0*1000.0; 406 static const UChar trdfZone[] = { 0x0055, 0x0053, 0x002F, 0x0050, 0x0061, 0x0063, 0x0069, 0x0066, 0x0069, 0x0063, 0 }; /* US/Pacific */ 407 static const char trdfLocale[] = "en_US"; 408 static const UChar minutesPatn[] = { 0x006D, 0x006D, 0 }; /* "mm" */ 409 static const UChar monthLongPatn[] = { 0x004D, 0x004D, 0x004D, 0x004D, 0 }; /* "MMMM" */ 410 static const UChar monthMediumPatn[] = { 0x004D, 0x004D, 0x004D, 0 }; /* "MMM" */ 411 static const UChar monthShortPatn[] = { 0x004D, 0 }; /* "M" */ 412 static const UDateFormatStyle dateStylesList[] = { UDAT_FULL, UDAT_LONG, UDAT_MEDIUM, UDAT_SHORT, UDAT_NONE }; 413 static const UChar *monthPatnsList[] = { monthLongPatn, monthLongPatn, monthMediumPatn, monthShortPatn, NULL }; 414 static const UChar newTimePatn[] = { 0x0048, 0x0048, 0x002C, 0x006D, 0x006D, 0 }; /* "HH,mm" */ 415 static const UChar minutesStr[] = { 0x0034, 0x0039, 0 }; /* "49", minutes string to search for in output */ 416 enum { kDateOrTimeOutMax = 96, kDateAndTimeOutMax = 192 }; 417 418 static const UDate minutesTolerance = 2 * 60.0 * 1000.0; 419 static const UDate daysTolerance = 2 * 24.0 * 60.0 * 60.0 * 1000.0; 420 421 static void TestRelativeDateFormat() 422 { 423 UDate today = 0.0; 424 const UDateFormatStyle * stylePtr; 425 const UChar ** monthPtnPtr; 426 UErrorCode status = U_ZERO_ERROR; 427 UCalendar * ucal = ucal_open(trdfZone, -1, trdfLocale, UCAL_GREGORIAN, &status); 428 if ( U_SUCCESS(status) ) { 429 int32_t year, month, day; 430 ucal_setMillis(ucal, ucal_getNow(), &status); 431 year = ucal_get(ucal, UCAL_YEAR, &status); 432 month = ucal_get(ucal, UCAL_MONTH, &status); 433 day = ucal_get(ucal, UCAL_DATE, &status); 434 ucal_setDateTime(ucal, year, month, day, 18, 49, 0, &status); /* set to today at 18:49:00 */ 435 today = ucal_getMillis(ucal, &status); 436 ucal_close(ucal); 437 } 438 if ( U_FAILURE(status) || today == 0.0 ) { 439 log_data_err("Generate UDate for a specified time today fails, error %s - (Are you missing data?)\n", myErrorName(status) ); 440 return; 441 } 442 for (stylePtr = dateStylesList, monthPtnPtr = monthPatnsList; *stylePtr != UDAT_NONE; ++stylePtr, ++monthPtnPtr) { 443 UDateFormat* fmtRelDateTime; 444 UDateFormat* fmtRelDate; 445 UDateFormat* fmtTime; 446 int32_t dayOffset, limit; 447 UFieldPosition fp; 448 UChar strDateTime[kDateAndTimeOutMax]; 449 UChar strDate[kDateOrTimeOutMax]; 450 UChar strTime[kDateOrTimeOutMax]; 451 UChar * strPtr; 452 int32_t dtpatLen; 453 454 fmtRelDateTime = udat_open(UDAT_SHORT, *stylePtr | UDAT_RELATIVE, trdfLocale, trdfZone, -1, NULL, 0, &status); 455 if ( U_FAILURE(status) ) { 456 log_data_err("udat_open timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s (Are you missing data?)\n", *stylePtr, myErrorName(status) ); 457 continue; 458 } 459 fmtRelDate = udat_open(UDAT_NONE, *stylePtr | UDAT_RELATIVE, trdfLocale, trdfZone, -1, NULL, 0, &status); 460 if ( U_FAILURE(status) ) { 461 log_err("udat_open timeStyle NONE dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) ); 462 udat_close(fmtRelDateTime); 463 continue; 464 } 465 fmtTime = udat_open(UDAT_SHORT, UDAT_NONE, trdfLocale, trdfZone, -1, NULL, 0, &status); 466 if ( U_FAILURE(status) ) { 467 log_err("udat_open timeStyle SHORT dateStyle NONE fails, error %s\n", myErrorName(status) ); 468 udat_close(fmtRelDateTime); 469 udat_close(fmtRelDate); 470 continue; 471 } 472 473 dtpatLen = udat_toPatternRelativeDate(fmtRelDateTime, strDate, kDateAndTimeOutMax, &status); 474 if ( U_FAILURE(status) ) { 475 log_err("udat_toPatternRelativeDate timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) ); 476 status = U_ZERO_ERROR; 477 } else if ( u_strstr(strDate, *monthPtnPtr) == NULL || dtpatLen != u_strlen(strDate) ) { 478 log_err("udat_toPatternRelativeDate timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) date pattern incorrect\n", *stylePtr ); 479 } 480 dtpatLen = udat_toPatternRelativeTime(fmtRelDateTime, strTime, kDateAndTimeOutMax, &status); 481 if ( U_FAILURE(status) ) { 482 log_err("udat_toPatternRelativeTime timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) ); 483 status = U_ZERO_ERROR; 484 } else if ( u_strstr(strTime, minutesPatn) == NULL || dtpatLen != u_strlen(strTime) ) { 485 log_err("udat_toPatternRelativeTime timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) time pattern incorrect\n", *stylePtr ); 486 } 487 dtpatLen = udat_toPattern(fmtRelDateTime, FALSE, strDateTime, kDateAndTimeOutMax, &status); 488 if ( U_FAILURE(status) ) { 489 log_err("udat_toPattern timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) ); 490 status = U_ZERO_ERROR; 491 } else if ( u_strstr(strDateTime, strDate) == NULL || u_strstr(strDateTime, strTime) == NULL || dtpatLen != u_strlen(strDateTime) ) { 492 log_err("udat_toPattern timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) dateTime pattern incorrect\n", *stylePtr ); 493 } 494 udat_applyPatternRelative(fmtRelDateTime, strDate, u_strlen(strDate), newTimePatn, u_strlen(newTimePatn), &status); 495 if ( U_FAILURE(status) ) { 496 log_err("udat_applyPatternRelative timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) ); 497 status = U_ZERO_ERROR; 498 } else { 499 udat_toPattern(fmtRelDateTime, FALSE, strDateTime, kDateAndTimeOutMax, &status); 500 if ( U_FAILURE(status) ) { 501 log_err("udat_toPattern timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) ); 502 status = U_ZERO_ERROR; 503 } else if ( u_strstr(strDateTime, newTimePatn) == NULL ) { 504 log_err("udat_applyPatternRelative timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) didn't update time pattern\n", *stylePtr ); 505 } 506 } 507 udat_applyPatternRelative(fmtRelDateTime, strDate, u_strlen(strDate), strTime, u_strlen(strTime), &status); /* restore original */ 508 509 fp.field = UDAT_MINUTE_FIELD; 510 for (dayOffset = -2, limit = 2; dayOffset <= limit; ++dayOffset) { 511 UDate dateToUse = today + (float)dayOffset*dayInterval; 512 513 udat_format(fmtRelDateTime, dateToUse, strDateTime, kDateAndTimeOutMax, &fp, &status); 514 if ( U_FAILURE(status) ) { 515 log_err("udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) ); 516 status = U_ZERO_ERROR; 517 } else { 518 int32_t parsePos = 0; 519 UDate dateResult = udat_parse(fmtRelDateTime, strDateTime, -1, &parsePos, &status); 520 UDate dateDiff = (dateResult >= dateToUse)? dateResult - dateToUse: dateToUse - dateResult; 521 if ( U_FAILURE(status) || dateDiff > minutesTolerance ) { 522 log_err("udat_parse timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s, expect approx %.1f, got %.1f, parsePos %d\n", 523 *stylePtr, myErrorName(status), dateToUse, dateResult, parsePos ); 524 status = U_ZERO_ERROR; 525 } 526 527 udat_format(fmtRelDate, dateToUse, strDate, kDateOrTimeOutMax, NULL, &status); 528 if ( U_FAILURE(status) ) { 529 log_err("udat_format timeStyle NONE dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) ); 530 status = U_ZERO_ERROR; 531 } else if ( u_strstr(strDateTime, strDate) == NULL ) { 532 log_err("relative date string not found in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", *stylePtr ); 533 } else { 534 parsePos = 0; 535 dateResult = udat_parse(fmtRelDate, strDate, -1, &parsePos, &status); 536 dateDiff = (dateResult >= dateToUse)? dateResult - dateToUse: dateToUse - dateResult; 537 if ( U_FAILURE(status) || dateDiff > daysTolerance ) { 538 log_err("udat_parse timeStyle NONE dateStyle (%d | UDAT_RELATIVE) fails, error %s, expect approx %.1f, got %.1f, parsePos %d\n", 539 *stylePtr, myErrorName(status), dateToUse, dateResult, parsePos ); 540 status = U_ZERO_ERROR; 541 } 542 } 543 544 udat_format(fmtTime, dateToUse, strTime, kDateOrTimeOutMax, NULL, &status); 545 if ( U_FAILURE(status) ) { 546 log_err("udat_format timeStyle SHORT dateStyle NONE fails, error %s\n", myErrorName(status) ); 547 status = U_ZERO_ERROR; 548 } else if ( u_strstr(strDateTime, strTime) == NULL ) { 549 log_err("time string not found in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", *stylePtr ); 550 } 551 552 strPtr = u_strstr(strDateTime, minutesStr); 553 if ( strPtr != NULL ) { 554 int32_t beginIndex = strPtr - strDateTime; 555 if ( fp.beginIndex != beginIndex ) { 556 log_err("UFieldPosition beginIndex %d, expected %d, in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", fp.beginIndex, beginIndex, *stylePtr ); 557 } 558 } else { 559 log_err("minutes string not found in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", *stylePtr ); 560 } 561 } 562 } 563 564 udat_close(fmtRelDateTime); 565 udat_close(fmtRelDate); 566 udat_close(fmtTime); 567 } 568 } 569 570 /*Testing udat_getSymbols() and udat_setSymbols() and udat_countSymbols()*/ 571 static void TestSymbols() 572 { 573 UDateFormat *def, *fr, *zhChiCal; 574 UErrorCode status = U_ZERO_ERROR; 575 UChar *value=NULL; 576 UChar *result = NULL; 577 int32_t resultlength; 578 int32_t resultlengthout; 579 UChar *pattern; 580 581 582 /*creating a dateformat with french locale */ 583 log_verbose("\ncreating a date format with french locale\n"); 584 fr = udat_open(UDAT_FULL, UDAT_DEFAULT, "fr_FR", NULL, 0, NULL, 0, &status); 585 if(U_FAILURE(status)) 586 { 587 log_data_err("error in creating the dateformat using full time style with french locale -> %s (Are you missing data?)\n", 588 myErrorName(status) ); 589 return; 590 } 591 /*creating a default dateformat */ 592 log_verbose("\ncreating a date format with default locale\n"); 593 /* this is supposed to open default date format, but later on it treats it like it is "en_US" 594 - very bad if you try to run the tests on machine where default locale is NOT "en_US" */ 595 /* def = udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,NULL, NULL, 0, &status); */ 596 def = udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,"en_US", NULL, 0, NULL, 0, &status); 597 if(U_FAILURE(status)) 598 { 599 log_err("error in creating the dateformat using short date and time style\n %s\n", 600 myErrorName(status) ); 601 return; 602 } 603 /*creating a dateformat with zh locale */ 604 log_verbose("\ncreating a date format with zh locale for chinese calendar\n"); 605 zhChiCal = udat_open(UDAT_NONE, UDAT_FULL, "zh@calendar=chinese", NULL, 0, NULL, 0, &status); 606 if(U_FAILURE(status)) 607 { 608 log_data_err("error in creating the dateformat using full date, no time, locale zh@calendar=chinese -> %s (Are you missing data?)\n", 609 myErrorName(status) ); 610 return; 611 } 612 613 614 /*Testing countSymbols, getSymbols and setSymbols*/ 615 log_verbose("\nTesting countSymbols\n"); 616 /*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 */ 617 if(udat_countSymbols(def, UDAT_ERAS)!=2 || udat_countSymbols(def, UDAT_MONTHS)!=12 || 618 udat_countSymbols(def, UDAT_SHORT_MONTHS)!=12 || udat_countSymbols(def, UDAT_WEEKDAYS)!=8 || 619 udat_countSymbols(def, UDAT_SHORT_WEEKDAYS)!=8 || udat_countSymbols(def, UDAT_AM_PMS)!=2 || 620 udat_countSymbols(def, UDAT_QUARTERS) != 4 || udat_countSymbols(def, UDAT_SHORT_QUARTERS) != 4 || 621 udat_countSymbols(def, UDAT_LOCALIZED_CHARS)!=1 || udat_countSymbols(def, UDAT_SHORTER_WEEKDAYS)!=8 || 622 udat_countSymbols(zhChiCal, UDAT_CYCLIC_YEARS_NARROW)!=60 || udat_countSymbols(zhChiCal, UDAT_ZODIAC_NAMES_NARROW)!=12) 623 { 624 log_err("FAIL: error in udat_countSymbols\n"); 625 } 626 else 627 log_verbose("PASS: udat_countSymbols() successful\n"); 628 629 /*testing getSymbols*/ 630 log_verbose("\nTesting getSymbols\n"); 631 pattern=(UChar*)malloc(sizeof(UChar) * 10); 632 u_uastrcpy(pattern, "jeudi"); 633 resultlength=0; 634 resultlengthout=udat_getSymbols(fr, UDAT_WEEKDAYS, 5 , NULL, resultlength, &status); 635 if(status==U_BUFFER_OVERFLOW_ERROR) 636 { 637 status=U_ZERO_ERROR; 638 resultlength=resultlengthout+1; 639 if(result != NULL) { 640 free(result); 641 result = NULL; 642 } 643 result=(UChar*)malloc(sizeof(UChar) * resultlength); 644 udat_getSymbols(fr, UDAT_WEEKDAYS, 5, result, resultlength, &status); 645 646 } 647 if(U_FAILURE(status)) 648 { 649 log_err("FAIL: Error in udat_getSymbols().... %s\n", myErrorName(status) ); 650 } 651 else 652 log_verbose("PASS: getSymbols succesful\n"); 653 654 if(u_strcmp(result, pattern)==0) 655 log_verbose("PASS: getSymbols retrieved the right value\n"); 656 else 657 log_data_err("FAIL: getSymbols retrieved the wrong value\n"); 658 659 /*run series of tests to test getsymbols regressively*/ 660 log_verbose("\nTesting getSymbols() regressively\n"); 661 VerifygetSymbols(fr, UDAT_WEEKDAYS, 1, "dimanche"); 662 VerifygetSymbols(def, UDAT_WEEKDAYS, 1, "Sunday"); 663 VerifygetSymbols(fr, UDAT_SHORT_WEEKDAYS, 7, "sam."); 664 VerifygetSymbols(fr, UDAT_SHORTER_WEEKDAYS, 7, "sa"); 665 VerifygetSymbols(def, UDAT_SHORT_WEEKDAYS, 7, "Sat"); 666 VerifygetSymbols(def, UDAT_MONTHS, 11, "December"); 667 VerifygetSymbols(def, UDAT_MONTHS, 0, "January"); 668 VerifygetSymbols(fr, UDAT_ERAS, 0, "av. J.-C."); 669 VerifygetSymbols(def, UDAT_AM_PMS, 0, "AM"); 670 VerifygetSymbols(def, UDAT_AM_PMS, 1, "PM"); 671 VerifygetSymbols(fr, UDAT_SHORT_MONTHS, 0, "janv."); 672 VerifygetSymbols(def, UDAT_SHORT_MONTHS, 11, "Dec"); 673 VerifygetSymbols(fr, UDAT_QUARTERS, 0, "1er trimestre"); 674 VerifygetSymbols(def, UDAT_QUARTERS, 3, "4th quarter"); 675 VerifygetSymbols(fr, UDAT_SHORT_QUARTERS, 1, "T2"); 676 VerifygetSymbols(def, UDAT_SHORT_QUARTERS, 2, "Q3"); 677 VerifygetSymbols(zhChiCal, UDAT_CYCLIC_YEARS_ABBREVIATED, 0, "\\u7532\\u5B50"); 678 VerifygetSymbols(zhChiCal, UDAT_CYCLIC_YEARS_NARROW, 59, "\\u7678\\u4EA5"); 679 VerifygetSymbols(zhChiCal, UDAT_ZODIAC_NAMES_ABBREVIATED, 0, "\\u9F20"); 680 VerifygetSymbols(zhChiCal, UDAT_ZODIAC_NAMES_WIDE, 11, "\\u732A"); 681 VerifygetSymbols(def,UDAT_LOCALIZED_CHARS, 0, "GyMdkHmsSEDFwWahKzYeugAZvcLQqVUOXxr:"); 682 683 684 if(result != NULL) { 685 free(result); 686 result = NULL; 687 } 688 free(pattern); 689 690 log_verbose("\nTesting setSymbols\n"); 691 /*applying the pattern so that setSymbolss works */ 692 resultlength=0; 693 resultlengthout=udat_toPattern(fr, FALSE, NULL, resultlength, &status); 694 if(status==U_BUFFER_OVERFLOW_ERROR) 695 { 696 status=U_ZERO_ERROR; 697 resultlength=resultlengthout + 1; 698 pattern=(UChar*)malloc(sizeof(UChar) * resultlength); 699 udat_toPattern(fr, FALSE, pattern, resultlength, &status); 700 } 701 if(U_FAILURE(status)) 702 { 703 log_err("FAIL: error in extracting the pattern from UNumberFormat\n %s\n", 704 myErrorName(status) ); 705 } 706 707 udat_applyPattern(def, FALSE, pattern, u_strlen(pattern)); 708 resultlength=0; 709 resultlengthout=udat_toPattern(def, FALSE, NULL, resultlength,&status); 710 if(status==U_BUFFER_OVERFLOW_ERROR) 711 { 712 status=U_ZERO_ERROR; 713 resultlength=resultlengthout + 1; 714 if(result != NULL) { 715 free(result); 716 result = NULL; 717 } 718 result=(UChar*)malloc(sizeof(UChar) * resultlength); 719 udat_toPattern(fr, FALSE,result, resultlength, &status); 720 } 721 if(U_FAILURE(status)) 722 { 723 log_err("FAIL: error in extracting the pattern from UNumberFormat\n %s\n", 724 myErrorName(status) ); 725 } 726 if(u_strcmp(result, pattern)==0) 727 log_verbose("Pattern applied properly\n"); 728 else 729 log_err("pattern could not be applied properly\n"); 730 731 free(pattern); 732 /*testing set symbols */ 733 resultlength=0; 734 resultlengthout=udat_getSymbols(fr, UDAT_MONTHS, 11 , NULL, resultlength, &status); 735 if(status==U_BUFFER_OVERFLOW_ERROR){ 736 status=U_ZERO_ERROR; 737 resultlength=resultlengthout+1; 738 if(result != NULL) { 739 free(result); 740 result = NULL; 741 } 742 result=(UChar*)malloc(sizeof(UChar) * resultlength); 743 udat_getSymbols(fr, UDAT_MONTHS, 11, result, resultlength, &status); 744 745 } 746 if(U_FAILURE(status)) 747 log_err("FAIL: error in getSymbols() %s\n", myErrorName(status) ); 748 resultlength=resultlengthout+1; 749 750 udat_setSymbols(def, UDAT_MONTHS, 11, result, resultlength, &status); 751 if(U_FAILURE(status)) 752 { 753 log_err("FAIL: Error in udat_setSymbols() : %s\n", myErrorName(status) ); 754 } 755 else 756 log_verbose("PASS: SetSymbols successful\n"); 757 758 resultlength=0; 759 resultlengthout=udat_getSymbols(def, UDAT_MONTHS, 11, NULL, resultlength, &status); 760 if(status==U_BUFFER_OVERFLOW_ERROR){ 761 status=U_ZERO_ERROR; 762 resultlength=resultlengthout+1; 763 value=(UChar*)malloc(sizeof(UChar) * resultlength); 764 udat_getSymbols(def, UDAT_MONTHS, 11, value, resultlength, &status); 765 } 766 if(U_FAILURE(status)) 767 log_err("FAIL: error in retrieving the value using getSymbols i.e roundtrip\n"); 768 769 if(u_strcmp(result, value)!=0) 770 log_data_err("FAIL: Error in settting and getting symbols\n"); 771 else 772 log_verbose("PASS: setSymbols successful\n"); 773 774 775 /*run series of tests to test setSymbols regressively*/ 776 log_verbose("\nTesting setSymbols regressively\n"); 777 VerifysetSymbols(def, UDAT_ERAS, 0, "BeforeChrist"); 778 VerifysetSymbols(def, UDAT_ERA_NAMES, 1, "AnnoDomini"); 779 VerifysetSymbols(def, UDAT_WEEKDAYS, 1, "Sundayweek"); 780 VerifysetSymbols(def, UDAT_SHORT_WEEKDAYS, 7, "Satweek"); 781 VerifysetSymbols(def, UDAT_NARROW_WEEKDAYS, 4, "M"); 782 VerifysetSymbols(def, UDAT_STANDALONE_WEEKDAYS, 1, "Sonntagweek"); 783 VerifysetSymbols(def, UDAT_STANDALONE_SHORT_WEEKDAYS, 7, "Sams"); 784 VerifysetSymbols(def, UDAT_STANDALONE_NARROW_WEEKDAYS, 4, "V"); 785 VerifysetSymbols(fr, UDAT_MONTHS, 11, "december"); 786 VerifysetSymbols(fr, UDAT_SHORT_MONTHS, 0, "Jan"); 787 VerifysetSymbols(fr, UDAT_NARROW_MONTHS, 1, "R"); 788 VerifysetSymbols(fr, UDAT_STANDALONE_MONTHS, 11, "dezember"); 789 VerifysetSymbols(fr, UDAT_STANDALONE_SHORT_MONTHS, 7, "Aug"); 790 VerifysetSymbols(fr, UDAT_STANDALONE_NARROW_MONTHS, 2, "M"); 791 VerifysetSymbols(fr, UDAT_QUARTERS, 0, "1. Quart"); 792 VerifysetSymbols(fr, UDAT_SHORT_QUARTERS, 1, "QQ2"); 793 VerifysetSymbols(fr, UDAT_STANDALONE_QUARTERS, 2, "3rd Quar."); 794 VerifysetSymbols(fr, UDAT_STANDALONE_SHORT_QUARTERS, 3, "4QQ"); 795 VerifysetSymbols(zhChiCal, UDAT_CYCLIC_YEARS_ABBREVIATED, 1, "yi-chou"); 796 VerifysetSymbols(zhChiCal, UDAT_ZODIAC_NAMES_ABBREVIATED, 1, "Ox"); 797 798 799 /*run series of tests to test get and setSymbols regressively*/ 800 log_verbose("\nTesting get and set symbols regressively\n"); 801 VerifygetsetSymbols(fr, def, UDAT_WEEKDAYS, 1); 802 VerifygetsetSymbols(fr, def, UDAT_WEEKDAYS, 7); 803 VerifygetsetSymbols(fr, def, UDAT_SHORT_WEEKDAYS, 1); 804 VerifygetsetSymbols(fr, def, UDAT_SHORT_WEEKDAYS, 7); 805 VerifygetsetSymbols(fr, def, UDAT_MONTHS, 0); 806 VerifygetsetSymbols(fr, def, UDAT_SHORT_MONTHS, 0); 807 VerifygetsetSymbols(fr, def, UDAT_ERAS,1); 808 VerifygetsetSymbols(fr, def, UDAT_LOCALIZED_CHARS, 0); 809 VerifygetsetSymbols(fr, def, UDAT_AM_PMS, 1); 810 811 812 /*closing*/ 813 814 udat_close(fr); 815 udat_close(def); 816 udat_close(zhChiCal); 817 if(result != NULL) { 818 free(result); 819 result = NULL; 820 } 821 free(value); 822 823 } 824 825 /** 826 * Test DateFormat(Calendar) API 827 */ 828 static void TestDateFormatCalendar() { 829 UDateFormat *date=0, *time=0, *full=0; 830 UCalendar *cal=0; 831 UChar buf[256]; 832 char cbuf[256]; 833 int32_t pos; 834 UDate when; 835 UErrorCode ec = U_ZERO_ERROR; 836 UChar buf1[256]; 837 int32_t len1; 838 const char *expected; 839 UChar uExpected[32]; 840 841 ctest_setTimeZone(NULL, &ec); 842 843 /* Create a formatter for date fields. */ 844 date = udat_open(UDAT_NONE, UDAT_SHORT, "en_US", NULL, 0, NULL, 0, &ec); 845 if (U_FAILURE(ec)) { 846 log_data_err("FAIL: udat_open(NONE, SHORT, en_US) failed with %s (Are you missing data?)\n", 847 u_errorName(ec)); 848 goto FAIL; 849 } 850 851 /* Create a formatter for time fields. */ 852 time = udat_open(UDAT_SHORT, UDAT_NONE, "en_US", NULL, 0, NULL, 0, &ec); 853 if (U_FAILURE(ec)) { 854 log_err("FAIL: udat_open(SHORT, NONE, en_US) failed with %s\n", 855 u_errorName(ec)); 856 goto FAIL; 857 } 858 859 /* Create a full format for output */ 860 full = udat_open(UDAT_FULL, UDAT_FULL, "en_US", NULL, 0, NULL, 0, &ec); 861 if (U_FAILURE(ec)) { 862 log_err("FAIL: udat_open(FULL, FULL, en_US) failed with %s\n", 863 u_errorName(ec)); 864 goto FAIL; 865 } 866 867 /* Create a calendar */ 868 cal = ucal_open(NULL, 0, "en_US", UCAL_GREGORIAN, &ec); 869 if (U_FAILURE(ec)) { 870 log_err("FAIL: ucal_open(en_US) failed with %s\n", 871 u_errorName(ec)); 872 goto FAIL; 873 } 874 875 /* Parse the date */ 876 ucal_clear(cal); 877 u_uastrcpy(buf, "4/5/2001"); 878 pos = 0; 879 udat_parseCalendar(date, cal, buf, -1, &pos, &ec); 880 if (U_FAILURE(ec)) { 881 log_err("FAIL: udat_parseCalendar(4/5/2001) failed at %d with %s\n", 882 pos, u_errorName(ec)); 883 goto FAIL; 884 } 885 886 /* Check if formatCalendar matches the original date */ 887 len1 = udat_formatCalendar(date, cal, buf1, UPRV_LENGTHOF(buf1), NULL, &ec); 888 if (U_FAILURE(ec)) { 889 log_err("FAIL: udat_formatCalendar(4/5/2001) failed with %s\n", 890 u_errorName(ec)); 891 goto FAIL; 892 } 893 expected = "4/5/01"; 894 u_uastrcpy(uExpected, expected); 895 if (u_strlen(uExpected) != len1 || u_strncmp(uExpected, buf1, len1) != 0) { 896 log_err("FAIL: udat_formatCalendar(4/5/2001), expected: %s", expected); 897 } 898 899 /* Parse the time */ 900 u_uastrcpy(buf, "5:45 PM"); 901 pos = 0; 902 udat_parseCalendar(time, cal, buf, -1, &pos, &ec); 903 if (U_FAILURE(ec)) { 904 log_err("FAIL: udat_parseCalendar(17:45) failed at %d with %s\n", 905 pos, u_errorName(ec)); 906 goto FAIL; 907 } 908 909 /* Check if formatCalendar matches the original time */ 910 len1 = udat_formatCalendar(time, cal, buf1, UPRV_LENGTHOF(buf1), NULL, &ec); 911 if (U_FAILURE(ec)) { 912 log_err("FAIL: udat_formatCalendar(17:45) failed with %s\n", 913 u_errorName(ec)); 914 goto FAIL; 915 } 916 expected = "5:45 PM"; 917 u_uastrcpy(uExpected, expected); 918 if (u_strlen(uExpected) != len1 || u_strncmp(uExpected, buf1, len1) != 0) { 919 log_err("FAIL: udat_formatCalendar(17:45), expected: %s", expected); 920 } 921 922 /* Check result */ 923 when = ucal_getMillis(cal, &ec); 924 if (U_FAILURE(ec)) { 925 log_err("FAIL: ucal_getMillis() failed with %s\n", u_errorName(ec)); 926 goto FAIL; 927 } 928 udat_format(full, when, buf, sizeof(buf), NULL, &ec); 929 if (U_FAILURE(ec)) { 930 log_err("FAIL: udat_format() failed with %s\n", u_errorName(ec)); 931 goto FAIL; 932 } 933 u_austrcpy(cbuf, buf); 934 /* Thursday, April 5, 2001 5:45:00 PM PDT 986517900000 */ 935 if (when == 986517900000.0) { 936 log_verbose("Ok: Parsed result: %s\n", cbuf); 937 } else { 938 log_err("FAIL: Parsed result: %s, exp 4/5/2001 5:45 PM\n", cbuf); 939 } 940 941 FAIL: 942 udat_close(date); 943 udat_close(time); 944 udat_close(full); 945 ucal_close(cal); 946 947 ctest_resetTimeZone(); 948 } 949 950 951 952 /** 953 * Test parsing two digit year against "YY" vs. "YYYY" patterns 954 */ 955 static void TestCalendarDateParse() { 956 957 int32_t result; 958 UErrorCode ec = U_ZERO_ERROR; 959 UDateFormat* simpleDateFormat = 0; 960 int32_t parsePos = 0; 961 int32_t twoDigitCenturyStart = 75; 962 int32_t currentTwoDigitYear = 0; 963 int32_t startCentury = 0; 964 UCalendar* tempCal = 0; 965 UCalendar* calendar = 0; 966 967 U_STRING_DECL(pattern, "yyyy", 4); 968 U_STRING_DECL(pattern2, "yy", 2); 969 U_STRING_DECL(text, "75", 2); 970 971 U_STRING_INIT(pattern, "yyyy", 4); 972 U_STRING_INIT(pattern2, "yy", 2); 973 U_STRING_INIT(text, "75", 2); 974 975 simpleDateFormat = udat_open(UDAT_FULL, UDAT_FULL, "en-GB", 0, 0, 0, 0, &ec); 976 if (U_FAILURE(ec)) { 977 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)); 978 return; 979 } 980 udat_applyPattern(simpleDateFormat, 0, pattern, u_strlen(pattern)); 981 udat_setLenient(simpleDateFormat, 0); 982 983 currentTwoDigitYear = getCurrentYear() % 100; 984 startCentury = getCurrentYear() - currentTwoDigitYear; 985 if (twoDigitCenturyStart > currentTwoDigitYear) { 986 startCentury -= 100; 987 } 988 tempCal = ucal_open(NULL, -1, NULL, UCAL_GREGORIAN, &ec); 989 ucal_setMillis(tempCal, 0, &ec); 990 ucal_setDateTime(tempCal, startCentury + twoDigitCenturyStart, UCAL_JANUARY, 1, 0, 0, 0, &ec); 991 udat_set2DigitYearStart(simpleDateFormat, ucal_getMillis(tempCal, &ec), &ec); 992 993 calendar = ucal_open(NULL, -1, NULL, UCAL_GREGORIAN, &ec); 994 ucal_setMillis(calendar, 0, &ec); 995 ucal_setDateTime(calendar, twoDigitCenturyStart, UCAL_JANUARY, 1, 0, 0, 0, &ec); 996 997 udat_parseCalendar(simpleDateFormat, calendar, text, u_strlen(text), &parsePos, &ec); 998 999 /* Check result */ 1000 result = ucal_get(calendar, UCAL_YEAR, &ec); 1001 if (U_FAILURE(ec)) { 1002 log_err("FAIL: ucal_get(UCAL_YEAR) failed with %s\n", u_errorName(ec)); 1003 goto FAIL; 1004 } 1005 1006 if (result != 75) { 1007 log_err("FAIL: parsed incorrect year: %d\n", result); 1008 goto FAIL; 1009 } 1010 1011 parsePos = 0; 1012 udat_applyPattern(simpleDateFormat, 0, pattern2, u_strlen(pattern2)); 1013 udat_parseCalendar(simpleDateFormat, calendar, text, u_strlen(text), &parsePos, &ec); 1014 1015 /* Check result */ 1016 result = ucal_get(calendar, UCAL_YEAR, &ec); 1017 if (U_FAILURE(ec)) { 1018 log_err("FAIL: ucal_get(UCAL_YEAR) failed with %s\n", u_errorName(ec)); 1019 goto FAIL; 1020 } 1021 1022 if (result != 1975) { 1023 log_err("FAIL: parsed incorrect year: %d\n", result); 1024 goto FAIL; 1025 } 1026 1027 FAIL: 1028 udat_close(simpleDateFormat); 1029 udat_close(tempCal); 1030 udat_close(calendar); 1031 } 1032 1033 1034 /*INTERNAL FUNCTIONS USED*/ 1035 static int getCurrentYear() { 1036 static int currentYear = 0; 1037 if (currentYear == 0) { 1038 UErrorCode status = U_ZERO_ERROR; 1039 UCalendar *cal = ucal_open(NULL, -1, NULL, UCAL_GREGORIAN, &status); 1040 if (!U_FAILURE(status)) { 1041 /* Get the current year from the default UCalendar */ 1042 currentYear = ucal_get(cal, UCAL_YEAR, &status); 1043 ucal_close(cal); 1044 } 1045 } 1046 1047 return currentYear; 1048 } 1049 1050 /* N.B.: use idx instead of index to avoid 'shadow' warnings in strict mode. */ 1051 static void VerifygetSymbols(UDateFormat* datfor, UDateFormatSymbolType type, int32_t idx, const char* expected) 1052 { 1053 UChar *pattern=NULL; 1054 UErrorCode status = U_ZERO_ERROR; 1055 UChar *result=NULL; 1056 int32_t resultlength, resultlengthout; 1057 int32_t patternSize = strlen(expected) + 1; 1058 1059 pattern=(UChar*)malloc(sizeof(UChar) * patternSize); 1060 u_unescape(expected, pattern, patternSize); 1061 resultlength=0; 1062 resultlengthout=udat_getSymbols(datfor, type, idx , NULL, resultlength, &status); 1063 if(status==U_BUFFER_OVERFLOW_ERROR) 1064 { 1065 status=U_ZERO_ERROR; 1066 resultlength=resultlengthout+1; 1067 result=(UChar*)malloc(sizeof(UChar) * resultlength); 1068 udat_getSymbols(datfor, type, idx, result, resultlength, &status); 1069 1070 } 1071 if(U_FAILURE(status)) 1072 { 1073 log_err("FAIL: Error in udat_getSymbols()... %s\n", myErrorName(status) ); 1074 return; 1075 } 1076 if(u_strcmp(result, pattern)==0) 1077 log_verbose("PASS: getSymbols retrieved the right value\n"); 1078 else{ 1079 log_data_err("FAIL: getSymbols retrieved the wrong value\n Expected %s Got %s\n", expected, 1080 aescstrdup(result,-1) ); 1081 } 1082 free(result); 1083 free(pattern); 1084 } 1085 1086 static void VerifysetSymbols(UDateFormat* datfor, UDateFormatSymbolType type, int32_t idx, const char* expected) 1087 { 1088 UChar *result=NULL; 1089 UChar *value=NULL; 1090 int32_t resultlength, resultlengthout; 1091 UErrorCode status = U_ZERO_ERROR; 1092 int32_t valueLen, valueSize = strlen(expected) + 1; 1093 1094 value=(UChar*)malloc(sizeof(UChar) * valueSize); 1095 valueLen = u_unescape(expected, value, valueSize); 1096 udat_setSymbols(datfor, type, idx, value, valueLen, &status); 1097 if(U_FAILURE(status)) 1098 { 1099 log_err("FAIL: Error in udat_setSymbols() %s\n", myErrorName(status) ); 1100 return; 1101 } 1102 1103 resultlength=0; 1104 resultlengthout=udat_getSymbols(datfor, type, idx, NULL, resultlength, &status); 1105 if(status==U_BUFFER_OVERFLOW_ERROR){ 1106 status=U_ZERO_ERROR; 1107 resultlength=resultlengthout+1; 1108 result=(UChar*)malloc(sizeof(UChar) * resultlength); 1109 udat_getSymbols(datfor, type, idx, result, resultlength, &status); 1110 } 1111 if(U_FAILURE(status)){ 1112 log_err("FAIL: error in retrieving the value using getSymbols after setting it previously\n %s\n", 1113 myErrorName(status) ); 1114 return; 1115 } 1116 1117 if(u_strcmp(result, value)!=0){ 1118 log_err("FAIL:Error in setting and then getting symbols\n Expected %s Got %s\n", expected, 1119 aescstrdup(result,-1) ); 1120 } 1121 else 1122 log_verbose("PASS: setSymbols successful\n"); 1123 1124 free(value); 1125 free(result); 1126 } 1127 1128 1129 static void VerifygetsetSymbols(UDateFormat* from, UDateFormat* to, UDateFormatSymbolType type, int32_t idx) 1130 { 1131 UChar *result=NULL; 1132 UChar *value=NULL; 1133 int32_t resultlength, resultlengthout; 1134 UErrorCode status = U_ZERO_ERROR; 1135 1136 resultlength=0; 1137 resultlengthout=udat_getSymbols(from, type, idx , NULL, resultlength, &status); 1138 if(status==U_BUFFER_OVERFLOW_ERROR){ 1139 status=U_ZERO_ERROR; 1140 resultlength=resultlengthout+1; 1141 result=(UChar*)malloc(sizeof(UChar) * resultlength); 1142 udat_getSymbols(from, type, idx, result, resultlength, &status); 1143 } 1144 if(U_FAILURE(status)){ 1145 log_err("FAIL: error in getSymbols() %s\n", myErrorName(status) ); 1146 return; 1147 } 1148 1149 resultlength=resultlengthout+1; 1150 udat_setSymbols(to, type, idx, result, resultlength, &status); 1151 if(U_FAILURE(status)) 1152 { 1153 log_err("FAIL: Error in udat_setSymbols() : %s\n", myErrorName(status) ); 1154 return; 1155 } 1156 1157 resultlength=0; 1158 resultlengthout=udat_getSymbols(to, type, idx, NULL, resultlength, &status); 1159 if(status==U_BUFFER_OVERFLOW_ERROR){ 1160 status=U_ZERO_ERROR; 1161 resultlength=resultlengthout+1; 1162 value=(UChar*)malloc(sizeof(UChar) * resultlength); 1163 udat_getSymbols(to, type, idx, value, resultlength, &status); 1164 } 1165 if(U_FAILURE(status)){ 1166 log_err("FAIL: error in retrieving the value using getSymbols i.e roundtrip\n %s\n", 1167 myErrorName(status) ); 1168 return; 1169 } 1170 1171 if(u_strcmp(result, value)!=0){ 1172 log_data_err("FAIL:Error in setting and then getting symbols\n Expected %s Got %s\n", austrdup(result), 1173 austrdup(value) ); 1174 } 1175 else 1176 log_verbose("PASS: setSymbols successful\n"); 1177 1178 free(value); 1179 free(result); 1180 } 1181 1182 1183 static UChar* myNumformat(const UNumberFormat* numfor, double d) 1184 { 1185 UChar *result2=NULL; 1186 int32_t resultlength, resultlengthneeded; 1187 UErrorCode status = U_ZERO_ERROR; 1188 1189 resultlength=0; 1190 resultlengthneeded=unum_formatDouble(numfor, d, NULL, resultlength, NULL, &status); 1191 if(status==U_BUFFER_OVERFLOW_ERROR) 1192 { 1193 status=U_ZERO_ERROR; 1194 resultlength=resultlengthneeded+1; 1195 /*result2=(UChar*)malloc(sizeof(UChar) * resultlength);*/ /* this leaks */ 1196 result2=(UChar*)ctst_malloc(sizeof(UChar) * resultlength); /*this won't*/ 1197 unum_formatDouble(numfor, d, result2, resultlength, NULL, &status); 1198 } 1199 if(U_FAILURE(status)) 1200 { 1201 log_err("FAIL: Error in formatting using unum_format(.....) %s\n", myErrorName(status) ); 1202 return 0; 1203 } 1204 1205 return result2; 1206 } 1207 1208 /** 1209 * The search depth for TestExtremeDates. The total number of 1210 * dates that will be tested is (2^EXTREME_DATES_DEPTH) - 1. 1211 */ 1212 #define EXTREME_DATES_DEPTH 8 1213 1214 /** 1215 * Support for TestExtremeDates (below). 1216 * 1217 * Test a single date to see whether udat_format handles it properly. 1218 */ 1219 static UBool _aux1ExtremeDates(UDateFormat* fmt, UDate date, 1220 UChar* buf, int32_t buflen, char* cbuf, 1221 UErrorCode* ec) { 1222 int32_t len = udat_format(fmt, date, buf, buflen, 0, ec); 1223 if (!assertSuccess("udat_format", ec)) return FALSE; 1224 u_austrncpy(cbuf, buf, buflen); 1225 if (len < 4) { 1226 log_err("FAIL: udat_format(%g) => \"%s\"\n", date, cbuf); 1227 } else { 1228 log_verbose("udat_format(%g) => \"%s\"\n", date, cbuf); 1229 } 1230 return TRUE; 1231 } 1232 1233 /** 1234 * Support for TestExtremeDates (below). 1235 * 1236 * Recursively test between 'small' and 'large', up to the depth 1237 * limit specified by EXTREME_DATES_DEPTH. 1238 */ 1239 static UBool _aux2ExtremeDates(UDateFormat* fmt, UDate small, UDate large, 1240 UChar* buf, int32_t buflen, char* cbuf, 1241 int32_t count, 1242 UErrorCode* ec) { 1243 /* Logarithmic midpoint; see below */ 1244 UDate mid = (UDate) exp((log(small) + log(large)) / 2); 1245 if (count == EXTREME_DATES_DEPTH) { 1246 return TRUE; 1247 } 1248 return 1249 _aux1ExtremeDates(fmt, mid, buf, buflen, cbuf, ec) && 1250 _aux2ExtremeDates(fmt, small, mid, buf, buflen, cbuf, count+1, ec) && 1251 _aux2ExtremeDates(fmt, mid, large, buf, buflen, cbuf, count+1, ec); 1252 } 1253 1254 /** 1255 * http://www.jtcsv.com/cgibin/icu-bugs?findid=3659 1256 * 1257 * For certain large dates, udat_format crashes on MacOS. This test 1258 * attempts to reproduce this problem by doing a recursive logarithmic* 1259 * binary search of a predefined interval (from 'small' to 'large'). 1260 * 1261 * The limit of the search is given by EXTREME_DATES_DEPTH, above. 1262 * 1263 * *The search has to be logarithmic, not linear. A linear search of the 1264 * range 0..10^30, for example, will find 0.5*10^30, then 0.25*10^30 and 1265 * 0.75*10^30, etc. A logarithmic search will find 10^15, then 10^7.5 1266 * and 10^22.5, etc. 1267 */ 1268 static void TestExtremeDates() { 1269 UDateFormat *fmt; 1270 UErrorCode ec; 1271 UChar buf[256]; 1272 char cbuf[256]; 1273 const double small = 1000; /* 1 sec */ 1274 const double large = 1e+30; /* well beyond usable UDate range */ 1275 1276 /* There is no need to test larger values from 1e+30 to 1e+300; 1277 the failures occur around 1e+27, and never above 1e+30. */ 1278 1279 ec = U_ZERO_ERROR; 1280 fmt = udat_open(UDAT_LONG, UDAT_LONG, "en_US", 1281 0, 0, 0, 0, &ec); 1282 if (U_FAILURE(ec)) { 1283 log_data_err("FAIL: udat_open (%s) (Are you missing data?)\n", u_errorName(ec)); 1284 return; 1285 } 1286 1287 _aux2ExtremeDates(fmt, small, large, buf, LEN(buf), cbuf, 0, &ec); 1288 1289 udat_close(fmt); 1290 } 1291 1292 static void TestAllLocales(void) { 1293 int32_t idx, dateIdx, timeIdx, localeCount; 1294 static const UDateFormatStyle style[] = { 1295 UDAT_FULL, UDAT_LONG, UDAT_MEDIUM, UDAT_SHORT 1296 }; 1297 localeCount = uloc_countAvailable(); 1298 for (idx = 0; idx < localeCount; idx++) { 1299 for (dateIdx = 0; dateIdx < (int32_t)(sizeof(style)/sizeof(style[0])); dateIdx++) { 1300 for (timeIdx = 0; timeIdx < (int32_t)(sizeof(style)/sizeof(style[0])); timeIdx++) { 1301 UErrorCode status = U_ZERO_ERROR; 1302 udat_close(udat_open(style[dateIdx], style[timeIdx], 1303 uloc_getAvailable(idx), NULL, 0, NULL, 0, &status)); 1304 if (U_FAILURE(status)) { 1305 log_err("FAIL: udat_open(%s) failed with (%s) dateIdx=%d, timeIdx=%d\n", 1306 uloc_getAvailable(idx), u_errorName(status), dateIdx, timeIdx); 1307 } 1308 } 1309 } 1310 } 1311 } 1312 1313 static void TestRelativeCrash(void) { 1314 static const UChar tzName[] = { 0x0055, 0x0053, 0x002F, 0x0050, 0x0061, 0x0063, 0x0069, 0x0066, 0x0069, 0x0063, 0 }; 1315 static const UDate aDate = -631152000000.0; 1316 1317 UErrorCode status = U_ZERO_ERROR; 1318 UErrorCode expectStatus = U_ILLEGAL_ARGUMENT_ERROR; 1319 UDateFormat icudf; 1320 1321 icudf = udat_open(UDAT_NONE, UDAT_SHORT_RELATIVE, "en", tzName, -1, NULL, 0, &status); 1322 if ( U_SUCCESS(status) ) { 1323 const char *what = "???"; 1324 { 1325 UErrorCode subStatus = U_ZERO_ERROR; 1326 what = "udat_set2DigitYearStart"; 1327 log_verbose("Trying %s on a relative date..\n", what); 1328 udat_set2DigitYearStart(icudf, aDate, &subStatus); 1329 if(subStatus == expectStatus) { 1330 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus)); 1331 } else { 1332 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus)); 1333 } 1334 } 1335 { 1336 /* clone works polymorphically. try it anyways */ 1337 UErrorCode subStatus = U_ZERO_ERROR; 1338 UDateFormat *oth; 1339 what = "clone"; 1340 log_verbose("Trying %s on a relative date..\n", what); 1341 oth = udat_clone(icudf, &subStatus); 1342 if(subStatus == U_ZERO_ERROR) { 1343 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus)); 1344 udat_close(oth); /* ? */ 1345 } else { 1346 log_err("FAIL: didn't crash on %s, but got %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus)); 1347 } 1348 } 1349 { 1350 UErrorCode subStatus = U_ZERO_ERROR; 1351 what = "udat_get2DigitYearStart"; 1352 log_verbose("Trying %s on a relative date..\n", what); 1353 udat_get2DigitYearStart(icudf, &subStatus); 1354 if(subStatus == expectStatus) { 1355 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus)); 1356 } else { 1357 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus)); 1358 } 1359 } 1360 { 1361 /* Now udat_toPattern works for relative date formatters, unless localized is TRUE */ 1362 UErrorCode subStatus = U_ZERO_ERROR; 1363 what = "udat_toPattern"; 1364 log_verbose("Trying %s on a relative date..\n", what); 1365 udat_toPattern(icudf, TRUE,NULL,0, &subStatus); 1366 if(subStatus == expectStatus) { 1367 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus)); 1368 } else { 1369 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus)); 1370 } 1371 } 1372 { 1373 UErrorCode subStatus = U_ZERO_ERROR; 1374 what = "udat_applyPattern"; 1375 log_verbose("Trying %s on a relative date..\n", what); 1376 udat_applyPattern(icudf, FALSE,tzName,-1); 1377 subStatus = U_ILLEGAL_ARGUMENT_ERROR; /* what it should be, if this took an errorcode. */ 1378 if(subStatus == expectStatus) { 1379 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus)); 1380 } else { 1381 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus)); 1382 } 1383 } 1384 { 1385 UChar erabuf[32]; 1386 UErrorCode subStatus = U_ZERO_ERROR; 1387 what = "udat_getSymbols"; 1388 log_verbose("Trying %s on a relative date..\n", what); 1389 udat_getSymbols(icudf, UDAT_ERAS,0,erabuf,sizeof(erabuf)/sizeof(erabuf[0]), &subStatus); 1390 if(subStatus == U_ZERO_ERROR) { 1391 log_verbose("Success: %s returned %s.\n", what, u_errorName(subStatus)); 1392 } else { 1393 log_err("FAIL: didn't crash on %s, but got %s instead of U_ZERO_ERROR.\n", what, u_errorName(subStatus)); 1394 } 1395 } 1396 { 1397 UErrorCode subStatus = U_ZERO_ERROR; 1398 UChar symbolValue = 0x0041; 1399 what = "udat_setSymbols"; 1400 log_verbose("Trying %s on a relative date..\n", what); 1401 udat_setSymbols(icudf, UDAT_ERAS,0,&symbolValue,1, &subStatus); /* bogus values */ 1402 if(subStatus == expectStatus) { 1403 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus)); 1404 } else { 1405 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus)); 1406 } 1407 } 1408 { 1409 UErrorCode subStatus = U_ZERO_ERROR; 1410 what = "udat_countSymbols"; 1411 log_verbose("Trying %s on a relative date..\n", what); 1412 udat_countSymbols(icudf, UDAT_ERAS); 1413 subStatus = U_ILLEGAL_ARGUMENT_ERROR; /* should have an errorcode. */ 1414 if(subStatus == expectStatus) { 1415 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus)); 1416 } else { 1417 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus)); 1418 } 1419 } 1420 1421 udat_close(icudf); 1422 } else { 1423 log_data_err("FAIL: err calling udat_open() ->%s (Are you missing data?)\n", u_errorName(status)); 1424 } 1425 } 1426 1427 static const UChar skeleton_yMMMM[] = { 0x79,0x4D,0x4D,0x4D,0x4D,0 }; /* "yMMMM"; fr maps to "MMMM y", cs maps to "LLLL y" */ 1428 static const UChar july2008_frDefault[] = { 0x6A,0x75,0x69,0x6C,0x6C,0x65,0x74,0x20,0x32,0x30,0x30,0x38,0 }; /* "juillet 2008" */ 1429 static const UChar july2008_frTitle[] = { 0x4A,0x75,0x69,0x6C,0x6C,0x65,0x74,0x20,0x32,0x30,0x30,0x38,0 }; /* "Juillet 2008" sentence-begin, standalone */ 1430 static const UChar july2008_csDefault[] = { 0x10D,0x65,0x72,0x76,0x65,0x6E,0x65,0x63,0x20,0x32,0x30,0x30,0x38,0 }; /* "c(hacek)ervenec 2008" */ 1431 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 */ 1432 1433 typedef struct { 1434 const char * locale; 1435 const UChar * skeleton; 1436 UDisplayContext capitalizationContext; 1437 const UChar * expectedFormat; 1438 } TestContextItem; 1439 1440 static const TestContextItem textContextItems[] = { 1441 { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_NONE, july2008_frDefault }, 1442 #if !UCONFIG_NO_BREAK_ITERATION 1443 { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, july2008_frDefault }, 1444 { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, july2008_frTitle }, 1445 { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, july2008_frDefault }, 1446 { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_STANDALONE, july2008_frTitle }, 1447 #endif 1448 { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_NONE, july2008_csDefault }, 1449 #if !UCONFIG_NO_BREAK_ITERATION 1450 { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, july2008_csDefault }, 1451 { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, july2008_csTitle }, 1452 { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, july2008_csTitle }, 1453 { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_STANDALONE, july2008_csDefault }, 1454 #endif 1455 { NULL, NULL, (UDisplayContext)0, NULL } 1456 }; 1457 1458 static const UChar today_enDefault[] = { 0x74,0x6F,0x64,0x61,0x79,0 }; /* "today" */ 1459 static const UChar today_enTitle[] = { 0x54,0x6F,0x64,0x61,0x79,0 }; /* "Today" sentence-begin, uiListOrMenu, standalone */ 1460 static const UChar yesterday_enDefault[] = { 0x79,0x65,0x73,0x74,0x65,0x72,0x64,0x61,0x79,0 }; /* "yesterday" */ 1461 static const UChar yesterday_enTitle[] = { 0x59,0x65,0x73,0x74,0x65,0x72,0x64,0x61,0x79,0 }; /* "Yesterday" sentence-begin, uiListOrMenu, standalone */ 1462 static const UChar today_nbDefault[] = { 0x69,0x20,0x64,0x61,0x67,0 }; /* "i dag" */ 1463 static const UChar today_nbTitle[] = { 0x49,0x20,0x64,0x61,0x67,0 }; /* "I dag" sentence-begin, standalone */ 1464 static const UChar yesterday_nbDefault[] = { 0x69,0x20,0x67,0xE5,0x72,0 }; 1465 static const UChar yesterday_nbTitle[] = { 0x49,0x20,0x67,0xE5,0x72,0 }; 1466 1467 typedef struct { 1468 const char * locale; 1469 UDisplayContext capitalizationContext; 1470 const UChar * expectedFormatToday; 1471 const UChar * expectedFormatYesterday; 1472 } TestRelativeContextItem; 1473 1474 static const TestRelativeContextItem textContextRelativeItems[] = { 1475 { "en", UDISPCTX_CAPITALIZATION_NONE, today_enDefault, yesterday_enDefault }, 1476 #if !UCONFIG_NO_BREAK_ITERATION 1477 { "en", UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, today_enDefault, yesterday_enDefault }, 1478 { "en", UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, today_enTitle, yesterday_enTitle }, 1479 { "en", UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, today_enTitle, yesterday_enTitle }, 1480 { "en", UDISPCTX_CAPITALIZATION_FOR_STANDALONE, today_enTitle, yesterday_enTitle }, 1481 #endif 1482 { "nb", UDISPCTX_CAPITALIZATION_NONE, today_nbDefault, yesterday_nbDefault }, 1483 #if !UCONFIG_NO_BREAK_ITERATION 1484 { "nb", UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, today_nbDefault, yesterday_nbDefault }, 1485 { "nb", UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, today_nbTitle, yesterday_nbTitle }, 1486 { "nb", UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, today_nbDefault, yesterday_nbDefault }, 1487 { "nb", UDISPCTX_CAPITALIZATION_FOR_STANDALONE, today_nbTitle, yesterday_nbTitle }, 1488 #endif 1489 { NULL, (UDisplayContext)0, NULL, NULL } 1490 }; 1491 1492 static const UChar zoneGMT[] = { 0x47,0x4D,0x54,0 }; /* "GMT" */ 1493 static const UDate july022008 = 1215000000000.0; 1494 enum { kUbufMax = 64, kBbufMax = 3*kUbufMax }; 1495 1496 static void TestContext(void) { 1497 const TestContextItem* textContextItemPtr; 1498 const TestRelativeContextItem* textRelContextItemPtr; 1499 for (textContextItemPtr = textContextItems; textContextItemPtr->locale != NULL; ++textContextItemPtr) { 1500 UErrorCode status = U_ZERO_ERROR; 1501 UDateTimePatternGenerator* udtpg = udatpg_open(textContextItemPtr->locale, &status); 1502 if ( U_SUCCESS(status) ) { 1503 UChar ubuf[kUbufMax]; 1504 int32_t len = udatpg_getBestPattern(udtpg, textContextItemPtr->skeleton, -1, ubuf, kUbufMax, &status); 1505 if ( U_SUCCESS(status) ) { 1506 UDateFormat* udfmt = udat_open(UDAT_PATTERN, UDAT_PATTERN, textContextItemPtr->locale, zoneGMT, -1, ubuf, len, &status); 1507 if ( U_SUCCESS(status) ) { 1508 udat_setContext(udfmt, textContextItemPtr->capitalizationContext, &status); 1509 if ( U_SUCCESS(status) ) { 1510 UDisplayContext getContext; 1511 len = udat_format(udfmt, july022008, ubuf, kUbufMax, NULL, &status); 1512 if ( U_FAILURE(status) ) { 1513 log_err("FAIL: udat_format for locale %s, capitalizationContext %d, status %s\n", 1514 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, u_errorName(status) ); 1515 status = U_ZERO_ERROR; 1516 } else if (u_strncmp(ubuf, textContextItemPtr->expectedFormat, kUbufMax) != 0) { 1517 char bbuf1[kBbufMax]; 1518 char bbuf2[kBbufMax]; 1519 log_err("FAIL: udat_format for locale %s, capitalizationContext %d, expected %s, got %s\n", 1520 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, 1521 u_austrncpy(bbuf1,textContextItemPtr->expectedFormat,kUbufMax), u_austrncpy(bbuf2,ubuf,kUbufMax) ); 1522 } 1523 getContext = udat_getContext(udfmt, UDISPCTX_TYPE_CAPITALIZATION, &status); 1524 if ( U_FAILURE(status) ) { 1525 log_err("FAIL: udat_getContext for locale %s, capitalizationContext %d, status %s\n", 1526 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, u_errorName(status) ); 1527 } else if (getContext != textContextItemPtr->capitalizationContext) { 1528 log_err("FAIL: udat_getContext for locale %s, capitalizationContext %d, got context %d\n", 1529 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, (int)getContext ); 1530 } 1531 } else { 1532 log_err("FAIL: udat_setContext for locale %s, capitalizationContext %d, status %s\n", 1533 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, u_errorName(status) ); 1534 } 1535 udat_close(udfmt); 1536 } else { 1537 log_data_err("FAIL: udat_open for locale %s, status %s\n", textContextItemPtr->locale, u_errorName(status) ); 1538 } 1539 } else { 1540 log_err("FAIL: udatpg_getBestPattern for locale %s, status %s\n", textContextItemPtr->locale, u_errorName(status) ); 1541 } 1542 udatpg_close(udtpg); 1543 } else { 1544 log_data_err("FAIL: udatpg_open for locale %s, status %s\n", textContextItemPtr->locale, u_errorName(status) ); 1545 } 1546 } 1547 for (textRelContextItemPtr = textContextRelativeItems; textRelContextItemPtr->locale != NULL; ++textRelContextItemPtr) { 1548 UErrorCode status = U_ZERO_ERROR; 1549 UCalendar* ucal = ucal_open(zoneGMT, -1, "root", UCAL_GREGORIAN, &status); 1550 if ( U_SUCCESS(status) ) { 1551 UDateFormat* udfmt = udat_open(UDAT_NONE, UDAT_LONG_RELATIVE, textRelContextItemPtr->locale, zoneGMT, -1, NULL, 0, &status); 1552 if ( U_SUCCESS(status) ) { 1553 udat_setContext(udfmt, textRelContextItemPtr->capitalizationContext, &status); 1554 if ( U_SUCCESS(status) ) { 1555 UDate yesterday, today = ucal_getNow(); 1556 UChar ubuf[kUbufMax]; 1557 char bbuf1[kBbufMax]; 1558 char bbuf2[kBbufMax]; 1559 int32_t len = udat_format(udfmt, today, ubuf, kUbufMax, NULL, &status); 1560 (void)len; 1561 if ( U_FAILURE(status) ) { 1562 log_err("FAIL: udat_format today for locale %s, capitalizationContext %d, status %s\n", 1563 textRelContextItemPtr->locale, (int)textRelContextItemPtr->capitalizationContext, u_errorName(status) ); 1564 } else if (u_strncmp(ubuf, textRelContextItemPtr->expectedFormatToday, kUbufMax) != 0) { 1565 log_err("FAIL: udat_format today for locale %s, capitalizationContext %d, expected %s, got %s\n", 1566 textRelContextItemPtr->locale, (int)textRelContextItemPtr->capitalizationContext, 1567 u_austrncpy(bbuf1,textRelContextItemPtr->expectedFormatToday,kUbufMax), u_austrncpy(bbuf2,ubuf,kUbufMax) ); 1568 } 1569 status = U_ZERO_ERROR; 1570 ucal_setMillis(ucal, today, &status); 1571 ucal_add(ucal, UCAL_DATE, -1, &status); 1572 yesterday = ucal_getMillis(ucal, &status); 1573 if ( U_SUCCESS(status) ) { 1574 len = udat_format(udfmt, yesterday, ubuf, kUbufMax, NULL, &status); 1575 if ( U_FAILURE(status) ) { 1576 log_err("FAIL: udat_format yesterday for locale %s, capitalizationContext %d, status %s\n", 1577 textRelContextItemPtr->locale, (int)textRelContextItemPtr->capitalizationContext, u_errorName(status) ); 1578 } else if (u_strncmp(ubuf, textRelContextItemPtr->expectedFormatYesterday, kUbufMax) != 0) { 1579 log_err("FAIL: udat_format yesterday for locale %s, capitalizationContext %d, expected %s, got %s\n", 1580 textRelContextItemPtr->locale, (int)textRelContextItemPtr->capitalizationContext, 1581 u_austrncpy(bbuf1,textRelContextItemPtr->expectedFormatYesterday,kUbufMax), u_austrncpy(bbuf2,ubuf,kUbufMax) ); 1582 } 1583 } 1584 } else { 1585 log_err("FAIL: udat_setContext relative for locale %s, capitalizationContext %d, status %s\n", 1586 textRelContextItemPtr->locale, (int)textRelContextItemPtr->capitalizationContext, u_errorName(status) ); 1587 } 1588 udat_close(udfmt); 1589 } else { 1590 log_data_err("FAIL: udat_open relative for locale %s, status %s\n", textRelContextItemPtr->locale, u_errorName(status) ); 1591 } 1592 ucal_close(ucal); 1593 } else { 1594 log_data_err("FAIL: ucal_open for locale root, status %s\n", u_errorName(status) ); 1595 } 1596 } 1597 } 1598 1599 1600 // overrideNumberFormat[i][0] is to tell which field to set, 1601 // overrideNumberFormat[i][1] is the expected result 1602 static const char * overrideNumberFormat[][2] = { 1603 {"", "\\u521D\\u4E03 \\u521D\\u4E8C"}, 1604 {"d", "07 \\u521D\\u4E8C"}, 1605 {"do", "07 \\u521D\\u4E8C"}, 1606 {"Md", "\\u521D\\u4E03 \\u521D\\u4E8C"}, 1607 {"MdMMd", "\\u521D\\u4E03 \\u521D\\u4E8C"}, 1608 {"mixed", "\\u521D\\u4E03 \\u521D\\u4E8C"} 1609 }; 1610 1611 static void TestOverrideNumberFormat(void) { 1612 UErrorCode status = U_ZERO_ERROR; 1613 UChar pattern[50]; 1614 UChar expected[50]; 1615 UChar fields[50]; 1616 char bbuf1[kBbufMax]; 1617 char bbuf2[kBbufMax]; 1618 const char* localeString = "zh@numbers=hanidays"; 1619 UDateFormat* fmt; 1620 const UNumberFormat* getter_result; 1621 int32_t i; 1622 1623 u_uastrcpy(fields, "d"); 1624 u_uastrcpy(pattern,"MM d"); 1625 1626 fmt=udat_open(UDAT_PATTERN, UDAT_PATTERN, "en_US", zoneGMT, -1, pattern, u_strlen(pattern), &status); 1627 if (!assertSuccess("udat_open()", &status)) { 1628 return; 1629 } 1630 1631 // loop 5 times to check getter/setter 1632 for (i = 0; i < 5; i++){ 1633 UNumberFormat* overrideFmt; 1634 overrideFmt = unum_open(UNUM_DEFAULT, NULL, 0, localeString, NULL, &status); 1635 assertSuccess("unum_open()", &status); 1636 udat_adoptNumberFormatForFields(fmt, fields, overrideFmt, &status); 1637 overrideFmt = NULL; // no longer valid 1638 assertSuccess("udat_setNumberFormatForField()", &status); 1639 1640 getter_result = udat_getNumberFormatForField(fmt, 'd'); 1641 if(getter_result == NULL) { 1642 log_err("FAIL: udat_getNumberFormatForField did not return a valid pointer\n"); 1643 } 1644 } 1645 { 1646 UNumberFormat* overrideFmt; 1647 overrideFmt = unum_open(UNUM_DEFAULT, NULL, 0, localeString, NULL, &status); 1648 assertSuccess("unum_open()", &status); 1649 udat_setNumberFormat(fmt, overrideFmt); // test the same override NF will not crash 1650 unum_close(overrideFmt); 1651 } 1652 udat_close(fmt); 1653 1654 for (i=0; i<UPRV_LENGTHOF(overrideNumberFormat); i++){ 1655 UChar ubuf[kUbufMax]; 1656 UDateFormat* fmt2; 1657 UNumberFormat* overrideFmt2; 1658 1659 fmt2 =udat_open(UDAT_PATTERN, UDAT_PATTERN,"en_US", zoneGMT, -1, pattern, u_strlen(pattern), &status); 1660 assertSuccess("udat_open() with en_US", &status); 1661 1662 overrideFmt2 = unum_open(UNUM_DEFAULT, NULL, 0, localeString, NULL, &status); 1663 assertSuccess("unum_open() in loop", &status); 1664 1665 u_uastrcpy(fields, overrideNumberFormat[i][0]); 1666 u_unescape(overrideNumberFormat[i][1], expected, UPRV_LENGTHOF(expected)); 1667 1668 if ( strcmp(overrideNumberFormat[i][0], "") == 0 ) { // use the one w/o field 1669 udat_adoptNumberFormat(fmt2, overrideFmt2); 1670 } else if ( strcmp(overrideNumberFormat[i][0], "mixed") == 0 ) { // set 1 field at first but then full override, both(M & d) should be override 1671 const char* singleLocale = "en@numbers=hebr"; 1672 UNumberFormat* singleOverrideFmt; 1673 u_uastrcpy(fields, "d"); 1674 1675 singleOverrideFmt = unum_open(UNUM_DEFAULT, NULL, 0, singleLocale, NULL, &status); 1676 assertSuccess("unum_open() in mixed", &status); 1677 1678 udat_adoptNumberFormatForFields(fmt2, fields, singleOverrideFmt, &status); 1679 assertSuccess("udat_setNumberFormatForField() in mixed", &status); 1680 1681 udat_adoptNumberFormat(fmt2, overrideFmt2); 1682 } else if ( strcmp(overrideNumberFormat[i][0], "do") == 0 ) { // o is an invalid field 1683 udat_adoptNumberFormatForFields(fmt2, fields, overrideFmt2, &status); 1684 if(status == U_INVALID_FORMAT_ERROR) { 1685 udat_close(fmt2); 1686 status = U_ZERO_ERROR; 1687 continue; 1688 } 1689 } else { 1690 udat_adoptNumberFormatForFields(fmt2, fields, overrideFmt2, &status); 1691 assertSuccess("udat_setNumberFormatForField() in loop", &status); 1692 } 1693 1694 udat_format(fmt2, july022008, ubuf, kUbufMax, NULL, &status); 1695 assertSuccess("udat_format() july022008", &status); 1696 1697 if (u_strncmp(ubuf, expected, kUbufMax) != 0) 1698 log_err("fail: udat_format for locale, expected %s, got %s\n", 1699 u_austrncpy(bbuf1,expected,kUbufMax), u_austrncpy(bbuf2,ubuf,kUbufMax) ); 1700 1701 udat_close(fmt2); 1702 } 1703 } 1704 1705 /* 1706 * Ticket #11523 1707 * udat_parse and udat_parseCalendar should have the same error code when given the same invalid input. 1708 */ 1709 static void TestParseErrorReturnValue(void) { 1710 UErrorCode status = U_ZERO_ERROR; 1711 UErrorCode expectStatus = U_PARSE_ERROR; 1712 UDateFormat* df; 1713 UCalendar* cal; 1714 1715 df = udat_open(UDAT_DEFAULT, UDAT_DEFAULT, NULL, NULL, -1, NULL, -1, &status); 1716 if (!assertSuccessCheck("udat_open()", &status, TRUE)) { 1717 return; 1718 } 1719 1720 cal = ucal_open(NULL, 0, "en_US", UCAL_GREGORIAN, &status); 1721 if (!assertSuccess("ucal_open()", &status)) { 1722 return; 1723 } 1724 1725 udat_parse(df, NULL, -1, NULL, &status); 1726 if (status != expectStatus) { 1727 log_err("%s should have been returned by udat_parse when given an invalid input, instead got - %s\n", u_errorName(expectStatus), u_errorName(status)); 1728 } 1729 1730 status = U_ZERO_ERROR; 1731 udat_parseCalendar(df, cal, NULL, -1, NULL, &status); 1732 if (status != expectStatus) { 1733 log_err("%s should have been returned by udat_parseCalendar when given an invalid input, instead got - %s\n", u_errorName(expectStatus), u_errorName(status)); 1734 } 1735 1736 ucal_close(cal); 1737 udat_close(df); 1738 } 1739 1740 /* 1741 * Ticket #11553 1742 * Test new udat_formatForFields, udat_formatCalendarForFields (and UFieldPositionIterator) 1743 */ 1744 static const char localeForFields[] = "en_US"; 1745 /* zoneGMT[]defined above */ 1746 static const UDate date2015Feb25 = 1424841000000.0; /* Wednesday, February 25, 2015 at 5:10:00 AM GMT */ 1747 1748 typedef struct { 1749 int32_t field; 1750 int32_t beginPos; 1751 int32_t endPos; 1752 } FieldsData; 1753 static const FieldsData expectedFields[] = { 1754 { UDAT_DAY_OF_WEEK_FIELD /* 9*/, 0, 9 }, 1755 { UDAT_MONTH_FIELD /* 2*/, 11, 19 }, 1756 { UDAT_DATE_FIELD /* 3*/, 20, 22 }, 1757 { UDAT_YEAR_FIELD /* 1*/, 24, 28 }, 1758 { UDAT_HOUR1_FIELD /*15*/, 32, 33 }, 1759 { UDAT_TIME_SEPARATOR_FIELD /*35*/, 33, 34 }, 1760 { UDAT_MINUTE_FIELD /* 6*/, 34, 36 }, 1761 { UDAT_TIME_SEPARATOR_FIELD /*35*/, 36, 37 }, 1762 { UDAT_SECOND_FIELD /* 7*/, 37, 39 }, 1763 { UDAT_AM_PM_FIELD /*14*/, 40, 42 }, 1764 { UDAT_TIMEZONE_FIELD /*17*/, 43, 46 }, 1765 { -1, -1, -1 }, 1766 }; 1767 1768 enum {kUBufFieldsLen = 128, kBBufFieldsLen = 256 }; 1769 1770 static void TestFormatForFields(void) { 1771 UErrorCode status = U_ZERO_ERROR; 1772 UFieldPositionIterator* fpositer = ufieldpositer_open(&status); 1773 if ( U_FAILURE(status) ) { 1774 log_err("ufieldpositer_open fails, status %s\n", u_errorName(status)); 1775 } else { 1776 UDateFormat* udfmt = udat_open(UDAT_LONG, UDAT_FULL, localeForFields, zoneGMT, -1, NULL, 0, &status); 1777 UCalendar* ucal = ucal_open(zoneGMT, -1, localeForFields, UCAL_DEFAULT, &status); 1778 if ( U_FAILURE(status) ) { 1779 log_data_err("udat_open or ucal_open fails for locale %s, status %s (Are you missing data?)\n", localeForFields, u_errorName(status)); 1780 } else { 1781 int32_t ulen, field, beginPos, endPos; 1782 UChar ubuf[kUBufFieldsLen]; 1783 const FieldsData * fptr; 1784 1785 status = U_ZERO_ERROR; 1786 ulen = udat_formatForFields(udfmt, date2015Feb25, ubuf, kUBufFieldsLen, fpositer, &status); 1787 if ( U_FAILURE(status) ) { 1788 log_err("udat_formatForFields fails, status %s\n", u_errorName(status)); 1789 } else { 1790 for (fptr = expectedFields; ; fptr++) { 1791 field = ufieldpositer_next(fpositer, &beginPos, &endPos); 1792 if (field != fptr->field || (field >= 0 && (beginPos != fptr->beginPos || endPos != fptr->endPos))) { 1793 if (fptr->field >= 0) { 1794 log_err("udat_formatForFields as \"%s\"; expect field %d range %d-%d, get field %d range %d-%d\n", 1795 aescstrdup(ubuf, ulen), fptr->field, fptr->beginPos, fptr->endPos, field, beginPos, endPos); 1796 } else { 1797 log_err("udat_formatForFields as \"%s\"; expect field < 0, get field %d range %d-%d\n", 1798 aescstrdup(ubuf, ulen), field, beginPos, endPos); 1799 } 1800 break; 1801 } 1802 if (field < 0) { 1803 break; 1804 } 1805 } 1806 } 1807 1808 ucal_setMillis(ucal, date2015Feb25, &status); 1809 status = U_ZERO_ERROR; 1810 ulen = udat_formatCalendarForFields(udfmt, ucal, ubuf, kUBufFieldsLen, fpositer, &status); 1811 if ( U_FAILURE(status) ) { 1812 log_err("udat_formatCalendarForFields fails, status %s\n", u_errorName(status)); 1813 } else { 1814 for (fptr = expectedFields; ; fptr++) { 1815 field = ufieldpositer_next(fpositer, &beginPos, &endPos); 1816 if (field != fptr->field || (field >= 0 && (beginPos != fptr->beginPos || endPos != fptr->endPos))) { 1817 if (fptr->field >= 0) { 1818 log_err("udat_formatFudat_formatCalendarForFieldsorFields as \"%s\"; expect field %d range %d-%d, get field %d range %d-%d\n", 1819 aescstrdup(ubuf, ulen), fptr->field, fptr->beginPos, fptr->endPos, field, beginPos, endPos); 1820 } else { 1821 log_err("udat_formatCalendarForFields as \"%s\"; expect field < 0, get field %d range %d-%d\n", 1822 aescstrdup(ubuf, ulen), field, beginPos, endPos); 1823 } 1824 break; 1825 } 1826 if (field < 0) { 1827 break; 1828 } 1829 } 1830 } 1831 1832 ucal_close(ucal); 1833 udat_close(udfmt); 1834 } 1835 ufieldpositer_close(fpositer); 1836 } 1837 } 1838 1839 #endif /* #if !UCONFIG_NO_FORMATTING */ 1840