1// Copyright (C) 2016 and later: Unicode, Inc. and others. 2// License & terms of use: http://www.unicode.org/copyright.html 3/******************************************************************** 4 * COPYRIGHT: 5 * Copyright (c) 1997-2016, International Business Machines Corporation and 6 * others. All Rights Reserved. 7 ********************************************************************/ 8/******************************************************************************** 9* 10* File CDATTST.C 11* 12* Modification History: 13* Name Description 14* Madhu Katragadda Creation 15********************************************************************************* 16*/ 17 18/* C API TEST FOR DATE FORMAT */ 19 20#include "unicode/utypes.h" 21 22#if !UCONFIG_NO_FORMATTING 23 24#include "unicode/uloc.h" 25#include "unicode/udat.h" 26#include "unicode/udatpg.h" 27#include "unicode/ucal.h" 28#include "unicode/unum.h" 29#include "unicode/ustring.h" 30#include "unicode/ufieldpositer.h" 31#include "cintltst.h" 32#include "cdattst.h" 33#include "cformtst.h" 34#include "cmemory.h" 35 36#include <math.h> 37 38static void TestExtremeDates(void); 39static void TestAllLocales(void); 40static void TestRelativeCrash(void); 41static void TestContext(void); 42static void TestCalendarDateParse(void); 43static void TestParseErrorReturnValue(void); 44static void TestFormatForFields(void); 45 46void addDateForTest(TestNode** root); 47 48#define TESTCASE(x) addTest(root, &x, "tsformat/cdattst/" #x) 49 50void 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 */ 66static 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 \\u00E0 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/* 398Test combined relative date formatting (relative date + non-relative time). 399This is a bit tricky since we can't have static test data for comparison, the 400relative date formatting is relative to the time the tests are run. We generate 401the data for comparison dynamically. However, the tests could fail if they are 402run right at midnight Pacific time and the call to ucal_getNow() is before midnight 403while the calls to udat_format are after midnight or span midnight. 404*/ 405static const UDate dayInterval = 24.0*60.0*60.0*1000.0; 406static const UChar trdfZone[] = { 0x0055, 0x0053, 0x002F, 0x0050, 0x0061, 0x0063, 0x0069, 0x0066, 0x0069, 0x0063, 0 }; /* US/Pacific */ 407static const char trdfLocale[] = "en_US"; 408static const UChar minutesPatn[] = { 0x006D, 0x006D, 0 }; /* "mm" */ 409static const UChar monthLongPatn[] = { 0x004D, 0x004D, 0x004D, 0x004D, 0 }; /* "MMMM" */ 410static const UChar monthMediumPatn[] = { 0x004D, 0x004D, 0x004D, 0 }; /* "MMM" */ 411static const UChar monthShortPatn[] = { 0x004D, 0 }; /* "M" */ 412static const UDateFormatStyle dateStylesList[] = { UDAT_FULL, UDAT_LONG, UDAT_MEDIUM, UDAT_SHORT, UDAT_NONE }; 413static const UChar *monthPatnsList[] = { monthLongPatn, monthLongPatn, monthMediumPatn, monthShortPatn, NULL }; 414static const UChar newTimePatn[] = { 0x0048, 0x0048, 0x002C, 0x006D, 0x006D, 0 }; /* "HH,mm" */ 415static const UChar minutesStr[] = { 0x0034, 0x0039, 0 }; /* "49", minutes string to search for in output */ 416enum { kDateOrTimeOutMax = 96, kDateAndTimeOutMax = 192 }; 417 418static const UDate minutesTolerance = 2 * 60.0 * 1000.0; 419static const UDate daysTolerance = 2 * 24.0 * 60.0 * 60.0 * 1000.0; 420 421static 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()*/ 571static 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#if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR 682 VerifygetSymbols(def,UDAT_LOCALIZED_CHARS, 0, "GyMdkHmsSEDFwWahKzYeugAZvcLQqVUOXxrbB:"); 683#else 684 VerifygetSymbols(def,UDAT_LOCALIZED_CHARS, 0, "GyMdkHmsSEDFwWahKzYeugAZvcLQqVUOXxrbB"); 685#endif 686 687 688 if(result != NULL) { 689 free(result); 690 result = NULL; 691 } 692free(pattern); 693 694 log_verbose("\nTesting setSymbols\n"); 695 /*applying the pattern so that setSymbolss works */ 696 resultlength=0; 697 resultlengthout=udat_toPattern(fr, FALSE, NULL, resultlength, &status); 698 if(status==U_BUFFER_OVERFLOW_ERROR) 699 { 700 status=U_ZERO_ERROR; 701 resultlength=resultlengthout + 1; 702 pattern=(UChar*)malloc(sizeof(UChar) * resultlength); 703 udat_toPattern(fr, FALSE, pattern, resultlength, &status); 704 } 705 if(U_FAILURE(status)) 706 { 707 log_err("FAIL: error in extracting the pattern from UNumberFormat\n %s\n", 708 myErrorName(status) ); 709 } 710 711 udat_applyPattern(def, FALSE, pattern, u_strlen(pattern)); 712 resultlength=0; 713 resultlengthout=udat_toPattern(def, FALSE, NULL, resultlength,&status); 714 if(status==U_BUFFER_OVERFLOW_ERROR) 715 { 716 status=U_ZERO_ERROR; 717 resultlength=resultlengthout + 1; 718 if(result != NULL) { 719 free(result); 720 result = NULL; 721 } 722 result=(UChar*)malloc(sizeof(UChar) * resultlength); 723 udat_toPattern(fr, FALSE,result, resultlength, &status); 724 } 725 if(U_FAILURE(status)) 726 { 727 log_err("FAIL: error in extracting the pattern from UNumberFormat\n %s\n", 728 myErrorName(status) ); 729 } 730 if(u_strcmp(result, pattern)==0) 731 log_verbose("Pattern applied properly\n"); 732 else 733 log_err("pattern could not be applied properly\n"); 734 735free(pattern); 736 /*testing set symbols */ 737 resultlength=0; 738 resultlengthout=udat_getSymbols(fr, UDAT_MONTHS, 11 , NULL, resultlength, &status); 739 if(status==U_BUFFER_OVERFLOW_ERROR){ 740 status=U_ZERO_ERROR; 741 resultlength=resultlengthout+1; 742 if(result != NULL) { 743 free(result); 744 result = NULL; 745 } 746 result=(UChar*)malloc(sizeof(UChar) * resultlength); 747 udat_getSymbols(fr, UDAT_MONTHS, 11, result, resultlength, &status); 748 749 } 750 if(U_FAILURE(status)) 751 log_err("FAIL: error in getSymbols() %s\n", myErrorName(status) ); 752 resultlength=resultlengthout+1; 753 754 udat_setSymbols(def, UDAT_MONTHS, 11, result, resultlength, &status); 755 if(U_FAILURE(status)) 756 { 757 log_err("FAIL: Error in udat_setSymbols() : %s\n", myErrorName(status) ); 758 } 759 else 760 log_verbose("PASS: SetSymbols successful\n"); 761 762 resultlength=0; 763 resultlengthout=udat_getSymbols(def, UDAT_MONTHS, 11, NULL, resultlength, &status); 764 if(status==U_BUFFER_OVERFLOW_ERROR){ 765 status=U_ZERO_ERROR; 766 resultlength=resultlengthout+1; 767 value=(UChar*)malloc(sizeof(UChar) * resultlength); 768 udat_getSymbols(def, UDAT_MONTHS, 11, value, resultlength, &status); 769 } 770 if(U_FAILURE(status)) 771 log_err("FAIL: error in retrieving the value using getSymbols i.e roundtrip\n"); 772 773 if(u_strcmp(result, value)!=0) 774 log_data_err("FAIL: Error in settting and getting symbols\n"); 775 else 776 log_verbose("PASS: setSymbols successful\n"); 777 778 779 /*run series of tests to test setSymbols regressively*/ 780 log_verbose("\nTesting setSymbols regressively\n"); 781 VerifysetSymbols(def, UDAT_ERAS, 0, "BeforeChrist"); 782 VerifysetSymbols(def, UDAT_ERA_NAMES, 1, "AnnoDomini"); 783 VerifysetSymbols(def, UDAT_WEEKDAYS, 1, "Sundayweek"); 784 VerifysetSymbols(def, UDAT_SHORT_WEEKDAYS, 7, "Satweek"); 785 VerifysetSymbols(def, UDAT_NARROW_WEEKDAYS, 4, "M"); 786 VerifysetSymbols(def, UDAT_STANDALONE_WEEKDAYS, 1, "Sonntagweek"); 787 VerifysetSymbols(def, UDAT_STANDALONE_SHORT_WEEKDAYS, 7, "Sams"); 788 VerifysetSymbols(def, UDAT_STANDALONE_NARROW_WEEKDAYS, 4, "V"); 789 VerifysetSymbols(fr, UDAT_MONTHS, 11, "december"); 790 VerifysetSymbols(fr, UDAT_SHORT_MONTHS, 0, "Jan"); 791 VerifysetSymbols(fr, UDAT_NARROW_MONTHS, 1, "R"); 792 VerifysetSymbols(fr, UDAT_STANDALONE_MONTHS, 11, "dezember"); 793 VerifysetSymbols(fr, UDAT_STANDALONE_SHORT_MONTHS, 7, "Aug"); 794 VerifysetSymbols(fr, UDAT_STANDALONE_NARROW_MONTHS, 2, "M"); 795 VerifysetSymbols(fr, UDAT_QUARTERS, 0, "1. Quart"); 796 VerifysetSymbols(fr, UDAT_SHORT_QUARTERS, 1, "QQ2"); 797 VerifysetSymbols(fr, UDAT_STANDALONE_QUARTERS, 2, "3rd Quar."); 798 VerifysetSymbols(fr, UDAT_STANDALONE_SHORT_QUARTERS, 3, "4QQ"); 799 VerifysetSymbols(zhChiCal, UDAT_CYCLIC_YEARS_ABBREVIATED, 1, "yi-chou"); 800 VerifysetSymbols(zhChiCal, UDAT_ZODIAC_NAMES_ABBREVIATED, 1, "Ox"); 801 802 803 /*run series of tests to test get and setSymbols regressively*/ 804 log_verbose("\nTesting get and set symbols regressively\n"); 805 VerifygetsetSymbols(fr, def, UDAT_WEEKDAYS, 1); 806 VerifygetsetSymbols(fr, def, UDAT_WEEKDAYS, 7); 807 VerifygetsetSymbols(fr, def, UDAT_SHORT_WEEKDAYS, 1); 808 VerifygetsetSymbols(fr, def, UDAT_SHORT_WEEKDAYS, 7); 809 VerifygetsetSymbols(fr, def, UDAT_MONTHS, 0); 810 VerifygetsetSymbols(fr, def, UDAT_SHORT_MONTHS, 0); 811 VerifygetsetSymbols(fr, def, UDAT_ERAS,1); 812 VerifygetsetSymbols(fr, def, UDAT_LOCALIZED_CHARS, 0); 813 VerifygetsetSymbols(fr, def, UDAT_AM_PMS, 1); 814 815 816 /*closing*/ 817 818 udat_close(fr); 819 udat_close(def); 820 udat_close(zhChiCal); 821 if(result != NULL) { 822 free(result); 823 result = NULL; 824 } 825 free(value); 826 827} 828 829/** 830 * Test DateFormat(Calendar) API 831 */ 832static void TestDateFormatCalendar() { 833 UDateFormat *date=0, *time=0, *full=0; 834 UCalendar *cal=0; 835 UChar buf[256]; 836 char cbuf[256]; 837 int32_t pos; 838 UDate when; 839 UErrorCode ec = U_ZERO_ERROR; 840 UChar buf1[256]; 841 int32_t len1; 842 const char *expected; 843 UChar uExpected[32]; 844 845 ctest_setTimeZone(NULL, &ec); 846 847 /* Create a formatter for date fields. */ 848 date = udat_open(UDAT_NONE, UDAT_SHORT, "en_US", NULL, 0, NULL, 0, &ec); 849 if (U_FAILURE(ec)) { 850 log_data_err("FAIL: udat_open(NONE, SHORT, en_US) failed with %s (Are you missing data?)\n", 851 u_errorName(ec)); 852 goto FAIL; 853 } 854 855 /* Create a formatter for time fields. */ 856 time = udat_open(UDAT_SHORT, UDAT_NONE, "en_US", NULL, 0, NULL, 0, &ec); 857 if (U_FAILURE(ec)) { 858 log_err("FAIL: udat_open(SHORT, NONE, en_US) failed with %s\n", 859 u_errorName(ec)); 860 goto FAIL; 861 } 862 863 /* Create a full format for output */ 864 full = udat_open(UDAT_FULL, UDAT_FULL, "en_US", NULL, 0, NULL, 0, &ec); 865 if (U_FAILURE(ec)) { 866 log_err("FAIL: udat_open(FULL, FULL, en_US) failed with %s\n", 867 u_errorName(ec)); 868 goto FAIL; 869 } 870 871 /* Create a calendar */ 872 cal = ucal_open(NULL, 0, "en_US", UCAL_GREGORIAN, &ec); 873 if (U_FAILURE(ec)) { 874 log_err("FAIL: ucal_open(en_US) failed with %s\n", 875 u_errorName(ec)); 876 goto FAIL; 877 } 878 879 /* Parse the date */ 880 ucal_clear(cal); 881 u_uastrcpy(buf, "4/5/2001"); 882 pos = 0; 883 udat_parseCalendar(date, cal, buf, -1, &pos, &ec); 884 if (U_FAILURE(ec)) { 885 log_err("FAIL: udat_parseCalendar(4/5/2001) failed at %d with %s\n", 886 pos, u_errorName(ec)); 887 goto FAIL; 888 } 889 890 /* Check if formatCalendar matches the original date */ 891 len1 = udat_formatCalendar(date, cal, buf1, UPRV_LENGTHOF(buf1), NULL, &ec); 892 if (U_FAILURE(ec)) { 893 log_err("FAIL: udat_formatCalendar(4/5/2001) failed with %s\n", 894 u_errorName(ec)); 895 goto FAIL; 896 } 897 expected = "4/5/01"; 898 u_uastrcpy(uExpected, expected); 899 if (u_strlen(uExpected) != len1 || u_strncmp(uExpected, buf1, len1) != 0) { 900 log_err("FAIL: udat_formatCalendar(4/5/2001), expected: %s", expected); 901 } 902 903 /* Parse the time */ 904 u_uastrcpy(buf, "5:45 PM"); 905 pos = 0; 906 udat_parseCalendar(time, cal, buf, -1, &pos, &ec); 907 if (U_FAILURE(ec)) { 908 log_err("FAIL: udat_parseCalendar(17:45) failed at %d with %s\n", 909 pos, u_errorName(ec)); 910 goto FAIL; 911 } 912 913 /* Check if formatCalendar matches the original time */ 914 len1 = udat_formatCalendar(time, cal, buf1, UPRV_LENGTHOF(buf1), NULL, &ec); 915 if (U_FAILURE(ec)) { 916 log_err("FAIL: udat_formatCalendar(17:45) failed with %s\n", 917 u_errorName(ec)); 918 goto FAIL; 919 } 920 expected = "5:45 PM"; 921 u_uastrcpy(uExpected, expected); 922 if (u_strlen(uExpected) != len1 || u_strncmp(uExpected, buf1, len1) != 0) { 923 log_err("FAIL: udat_formatCalendar(17:45), expected: %s", expected); 924 } 925 926 /* Check result */ 927 when = ucal_getMillis(cal, &ec); 928 if (U_FAILURE(ec)) { 929 log_err("FAIL: ucal_getMillis() failed with %s\n", u_errorName(ec)); 930 goto FAIL; 931 } 932 udat_format(full, when, buf, sizeof(buf), NULL, &ec); 933 if (U_FAILURE(ec)) { 934 log_err("FAIL: udat_format() failed with %s\n", u_errorName(ec)); 935 goto FAIL; 936 } 937 u_austrcpy(cbuf, buf); 938 /* Thursday, April 5, 2001 5:45:00 PM PDT 986517900000 */ 939 if (when == 986517900000.0) { 940 log_verbose("Ok: Parsed result: %s\n", cbuf); 941 } else { 942 log_err("FAIL: Parsed result: %s, exp 4/5/2001 5:45 PM\n", cbuf); 943 } 944 945 FAIL: 946 udat_close(date); 947 udat_close(time); 948 udat_close(full); 949 ucal_close(cal); 950 951 ctest_resetTimeZone(); 952} 953 954 955 956/** 957 * Test parsing two digit year against "YY" vs. "YYYY" patterns 958 */ 959static void TestCalendarDateParse() { 960 961 int32_t result; 962 UErrorCode ec = U_ZERO_ERROR; 963 UDateFormat* simpleDateFormat = 0; 964 int32_t parsePos = 0; 965 int32_t twoDigitCenturyStart = 75; 966 int32_t currentTwoDigitYear = 0; 967 int32_t startCentury = 0; 968 UCalendar* tempCal = 0; 969 UCalendar* calendar = 0; 970 971 U_STRING_DECL(pattern, "yyyy", 4); 972 U_STRING_DECL(pattern2, "yy", 2); 973 U_STRING_DECL(text, "75", 2); 974 975 U_STRING_INIT(pattern, "yyyy", 4); 976 U_STRING_INIT(pattern2, "yy", 2); 977 U_STRING_INIT(text, "75", 2); 978 979 simpleDateFormat = udat_open(UDAT_FULL, UDAT_FULL, "en-GB", 0, 0, 0, 0, &ec); 980 if (U_FAILURE(ec)) { 981 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)); 982 return; 983 } 984 udat_applyPattern(simpleDateFormat, 0, pattern, u_strlen(pattern)); 985 udat_setLenient(simpleDateFormat, 0); 986 987 currentTwoDigitYear = getCurrentYear() % 100; 988 startCentury = getCurrentYear() - currentTwoDigitYear; 989 if (twoDigitCenturyStart > currentTwoDigitYear) { 990 startCentury -= 100; 991 } 992 tempCal = ucal_open(NULL, -1, NULL, UCAL_GREGORIAN, &ec); 993 ucal_setMillis(tempCal, 0, &ec); 994 ucal_setDateTime(tempCal, startCentury + twoDigitCenturyStart, UCAL_JANUARY, 1, 0, 0, 0, &ec); 995 udat_set2DigitYearStart(simpleDateFormat, ucal_getMillis(tempCal, &ec), &ec); 996 997 calendar = ucal_open(NULL, -1, NULL, UCAL_GREGORIAN, &ec); 998 ucal_setMillis(calendar, 0, &ec); 999 ucal_setDateTime(calendar, twoDigitCenturyStart, UCAL_JANUARY, 1, 0, 0, 0, &ec); 1000 1001 udat_parseCalendar(simpleDateFormat, calendar, text, u_strlen(text), &parsePos, &ec); 1002 1003 /* Check result */ 1004 result = ucal_get(calendar, UCAL_YEAR, &ec); 1005 if (U_FAILURE(ec)) { 1006 log_err("FAIL: ucal_get(UCAL_YEAR) failed with %s\n", u_errorName(ec)); 1007 goto FAIL; 1008 } 1009 1010 if (result != 75) { 1011 log_err("FAIL: parsed incorrect year: %d\n", result); 1012 goto FAIL; 1013 } 1014 1015 parsePos = 0; 1016 udat_applyPattern(simpleDateFormat, 0, pattern2, u_strlen(pattern2)); 1017 udat_parseCalendar(simpleDateFormat, calendar, text, u_strlen(text), &parsePos, &ec); 1018 1019 /* Check result */ 1020 result = ucal_get(calendar, UCAL_YEAR, &ec); 1021 if (U_FAILURE(ec)) { 1022 log_err("FAIL: ucal_get(UCAL_YEAR) failed with %s\n", u_errorName(ec)); 1023 goto FAIL; 1024 } 1025 1026 if (result != 1975) { 1027 log_err("FAIL: parsed incorrect year: %d\n", result); 1028 goto FAIL; 1029 } 1030 1031 FAIL: 1032 udat_close(simpleDateFormat); 1033 udat_close(tempCal); 1034 udat_close(calendar); 1035} 1036 1037 1038/*INTERNAL FUNCTIONS USED*/ 1039static int getCurrentYear() { 1040 static int currentYear = 0; 1041 if (currentYear == 0) { 1042 UErrorCode status = U_ZERO_ERROR; 1043 UCalendar *cal = ucal_open(NULL, -1, NULL, UCAL_GREGORIAN, &status); 1044 if (!U_FAILURE(status)) { 1045 /* Get the current year from the default UCalendar */ 1046 currentYear = ucal_get(cal, UCAL_YEAR, &status); 1047 ucal_close(cal); 1048 } 1049 } 1050 1051 return currentYear; 1052} 1053 1054/* N.B.: use idx instead of index to avoid 'shadow' warnings in strict mode. */ 1055static void VerifygetSymbols(UDateFormat* datfor, UDateFormatSymbolType type, int32_t idx, const char* expected) 1056{ 1057 UChar *pattern=NULL; 1058 UErrorCode status = U_ZERO_ERROR; 1059 UChar *result=NULL; 1060 int32_t resultlength, resultlengthout; 1061 int32_t patternSize = strlen(expected) + 1; 1062 1063 pattern=(UChar*)malloc(sizeof(UChar) * patternSize); 1064 u_unescape(expected, pattern, patternSize); 1065 resultlength=0; 1066 resultlengthout=udat_getSymbols(datfor, type, idx , NULL, resultlength, &status); 1067 if(status==U_BUFFER_OVERFLOW_ERROR) 1068 { 1069 status=U_ZERO_ERROR; 1070 resultlength=resultlengthout+1; 1071 result=(UChar*)malloc(sizeof(UChar) * resultlength); 1072 udat_getSymbols(datfor, type, idx, result, resultlength, &status); 1073 1074 } 1075 if(U_FAILURE(status)) 1076 { 1077 log_err("FAIL: Error in udat_getSymbols()... %s\n", myErrorName(status) ); 1078 return; 1079 } 1080 if(u_strcmp(result, pattern)==0) 1081 log_verbose("PASS: getSymbols retrieved the right value\n"); 1082 else{ 1083 log_data_err("FAIL: getSymbols retrieved the wrong value\n Expected %s Got %s\n", expected, 1084 aescstrdup(result,-1) ); 1085 } 1086 free(result); 1087 free(pattern); 1088} 1089 1090static void VerifysetSymbols(UDateFormat* datfor, UDateFormatSymbolType type, int32_t idx, const char* expected) 1091{ 1092 UChar *result=NULL; 1093 UChar *value=NULL; 1094 int32_t resultlength, resultlengthout; 1095 UErrorCode status = U_ZERO_ERROR; 1096 int32_t valueLen, valueSize = strlen(expected) + 1; 1097 1098 value=(UChar*)malloc(sizeof(UChar) * valueSize); 1099 valueLen = u_unescape(expected, value, valueSize); 1100 udat_setSymbols(datfor, type, idx, value, valueLen, &status); 1101 if(U_FAILURE(status)) 1102 { 1103 log_err("FAIL: Error in udat_setSymbols() %s\n", myErrorName(status) ); 1104 return; 1105 } 1106 1107 resultlength=0; 1108 resultlengthout=udat_getSymbols(datfor, type, idx, NULL, resultlength, &status); 1109 if(status==U_BUFFER_OVERFLOW_ERROR){ 1110 status=U_ZERO_ERROR; 1111 resultlength=resultlengthout+1; 1112 result=(UChar*)malloc(sizeof(UChar) * resultlength); 1113 udat_getSymbols(datfor, type, idx, result, resultlength, &status); 1114 } 1115 if(U_FAILURE(status)){ 1116 log_err("FAIL: error in retrieving the value using getSymbols after setting it previously\n %s\n", 1117 myErrorName(status) ); 1118 return; 1119 } 1120 1121 if(u_strcmp(result, value)!=0){ 1122 log_err("FAIL:Error in setting and then getting symbols\n Expected %s Got %s\n", expected, 1123 aescstrdup(result,-1) ); 1124 } 1125 else 1126 log_verbose("PASS: setSymbols successful\n"); 1127 1128 free(value); 1129 free(result); 1130} 1131 1132 1133static void VerifygetsetSymbols(UDateFormat* from, UDateFormat* to, UDateFormatSymbolType type, int32_t idx) 1134{ 1135 UChar *result=NULL; 1136 UChar *value=NULL; 1137 int32_t resultlength, resultlengthout; 1138 UErrorCode status = U_ZERO_ERROR; 1139 1140 resultlength=0; 1141 resultlengthout=udat_getSymbols(from, type, idx , NULL, resultlength, &status); 1142 if(status==U_BUFFER_OVERFLOW_ERROR){ 1143 status=U_ZERO_ERROR; 1144 resultlength=resultlengthout+1; 1145 result=(UChar*)malloc(sizeof(UChar) * resultlength); 1146 udat_getSymbols(from, type, idx, result, resultlength, &status); 1147 } 1148 if(U_FAILURE(status)){ 1149 log_err("FAIL: error in getSymbols() %s\n", myErrorName(status) ); 1150 return; 1151 } 1152 1153 resultlength=resultlengthout+1; 1154 udat_setSymbols(to, type, idx, result, resultlength, &status); 1155 if(U_FAILURE(status)) 1156 { 1157 log_err("FAIL: Error in udat_setSymbols() : %s\n", myErrorName(status) ); 1158 return; 1159 } 1160 1161 resultlength=0; 1162 resultlengthout=udat_getSymbols(to, type, idx, NULL, resultlength, &status); 1163 if(status==U_BUFFER_OVERFLOW_ERROR){ 1164 status=U_ZERO_ERROR; 1165 resultlength=resultlengthout+1; 1166 value=(UChar*)malloc(sizeof(UChar) * resultlength); 1167 udat_getSymbols(to, type, idx, value, resultlength, &status); 1168 } 1169 if(U_FAILURE(status)){ 1170 log_err("FAIL: error in retrieving the value using getSymbols i.e roundtrip\n %s\n", 1171 myErrorName(status) ); 1172 return; 1173 } 1174 1175 if(u_strcmp(result, value)!=0){ 1176 log_data_err("FAIL:Error in setting and then getting symbols\n Expected %s Got %s\n", austrdup(result), 1177 austrdup(value) ); 1178 } 1179 else 1180 log_verbose("PASS: setSymbols successful\n"); 1181 1182 free(value); 1183 free(result); 1184} 1185 1186 1187static UChar* myNumformat(const UNumberFormat* numfor, double d) 1188{ 1189 UChar *result2=NULL; 1190 int32_t resultlength, resultlengthneeded; 1191 UErrorCode status = U_ZERO_ERROR; 1192 1193 resultlength=0; 1194 resultlengthneeded=unum_formatDouble(numfor, d, NULL, resultlength, NULL, &status); 1195 if(status==U_BUFFER_OVERFLOW_ERROR) 1196 { 1197 status=U_ZERO_ERROR; 1198 resultlength=resultlengthneeded+1; 1199 /*result2=(UChar*)malloc(sizeof(UChar) * resultlength);*/ /* this leaks */ 1200 result2=(UChar*)ctst_malloc(sizeof(UChar) * resultlength); /*this won't*/ 1201 unum_formatDouble(numfor, d, result2, resultlength, NULL, &status); 1202 } 1203 if(U_FAILURE(status)) 1204 { 1205 log_err("FAIL: Error in formatting using unum_format(.....) %s\n", myErrorName(status) ); 1206 return 0; 1207 } 1208 1209 return result2; 1210} 1211 1212/** 1213 * The search depth for TestExtremeDates. The total number of 1214 * dates that will be tested is (2^EXTREME_DATES_DEPTH) - 1. 1215 */ 1216#define EXTREME_DATES_DEPTH 8 1217 1218/** 1219 * Support for TestExtremeDates (below). 1220 * 1221 * Test a single date to see whether udat_format handles it properly. 1222 */ 1223static UBool _aux1ExtremeDates(UDateFormat* fmt, UDate date, 1224 UChar* buf, int32_t buflen, char* cbuf, 1225 UErrorCode* ec) { 1226 int32_t len = udat_format(fmt, date, buf, buflen, 0, ec); 1227 if (!assertSuccess("udat_format", ec)) return FALSE; 1228 u_austrncpy(cbuf, buf, buflen); 1229 if (len < 4) { 1230 log_err("FAIL: udat_format(%g) => \"%s\"\n", date, cbuf); 1231 } else { 1232 log_verbose("udat_format(%g) => \"%s\"\n", date, cbuf); 1233 } 1234 return TRUE; 1235} 1236 1237/** 1238 * Support for TestExtremeDates (below). 1239 * 1240 * Recursively test between 'small' and 'large', up to the depth 1241 * limit specified by EXTREME_DATES_DEPTH. 1242 */ 1243static UBool _aux2ExtremeDates(UDateFormat* fmt, UDate small, UDate large, 1244 UChar* buf, int32_t buflen, char* cbuf, 1245 int32_t count, 1246 UErrorCode* ec) { 1247 /* Logarithmic midpoint; see below */ 1248 UDate mid = (UDate) exp((log(small) + log(large)) / 2); 1249 if (count == EXTREME_DATES_DEPTH) { 1250 return TRUE; 1251 } 1252 return 1253 _aux1ExtremeDates(fmt, mid, buf, buflen, cbuf, ec) && 1254 _aux2ExtremeDates(fmt, small, mid, buf, buflen, cbuf, count+1, ec) && 1255 _aux2ExtremeDates(fmt, mid, large, buf, buflen, cbuf, count+1, ec); 1256} 1257 1258/** 1259 * http://www.jtcsv.com/cgibin/icu-bugs?findid=3659 1260 * 1261 * For certain large dates, udat_format crashes on MacOS. This test 1262 * attempts to reproduce this problem by doing a recursive logarithmic* 1263 * binary search of a predefined interval (from 'small' to 'large'). 1264 * 1265 * The limit of the search is given by EXTREME_DATES_DEPTH, above. 1266 * 1267 * *The search has to be logarithmic, not linear. A linear search of the 1268 * range 0..10^30, for example, will find 0.5*10^30, then 0.25*10^30 and 1269 * 0.75*10^30, etc. A logarithmic search will find 10^15, then 10^7.5 1270 * and 10^22.5, etc. 1271 */ 1272static void TestExtremeDates() { 1273 UDateFormat *fmt; 1274 UErrorCode ec; 1275 UChar buf[256]; 1276 char cbuf[256]; 1277 const double small = 1000; /* 1 sec */ 1278 const double large = 1e+30; /* well beyond usable UDate range */ 1279 1280 /* There is no need to test larger values from 1e+30 to 1e+300; 1281 the failures occur around 1e+27, and never above 1e+30. */ 1282 1283 ec = U_ZERO_ERROR; 1284 fmt = udat_open(UDAT_LONG, UDAT_LONG, "en_US", 1285 0, 0, 0, 0, &ec); 1286 if (U_FAILURE(ec)) { 1287 log_data_err("FAIL: udat_open (%s) (Are you missing data?)\n", u_errorName(ec)); 1288 return; 1289 } 1290 1291 _aux2ExtremeDates(fmt, small, large, buf, UPRV_LENGTHOF(buf), cbuf, 0, &ec); 1292 1293 udat_close(fmt); 1294} 1295 1296static void TestAllLocales(void) { 1297 int32_t idx, dateIdx, timeIdx, localeCount; 1298 static const UDateFormatStyle style[] = { 1299 UDAT_FULL, UDAT_LONG, UDAT_MEDIUM, UDAT_SHORT 1300 }; 1301 localeCount = uloc_countAvailable(); 1302 for (idx = 0; idx < localeCount; idx++) { 1303 for (dateIdx = 0; dateIdx < UPRV_LENGTHOF(style); dateIdx++) { 1304 for (timeIdx = 0; timeIdx < UPRV_LENGTHOF(style); timeIdx++) { 1305 UErrorCode status = U_ZERO_ERROR; 1306 udat_close(udat_open(style[dateIdx], style[timeIdx], 1307 uloc_getAvailable(idx), NULL, 0, NULL, 0, &status)); 1308 if (U_FAILURE(status)) { 1309 log_err("FAIL: udat_open(%s) failed with (%s) dateIdx=%d, timeIdx=%d\n", 1310 uloc_getAvailable(idx), u_errorName(status), dateIdx, timeIdx); 1311 } 1312 } 1313 } 1314 } 1315} 1316 1317static void TestRelativeCrash(void) { 1318 static const UChar tzName[] = { 0x0055, 0x0053, 0x002F, 0x0050, 0x0061, 0x0063, 0x0069, 0x0066, 0x0069, 0x0063, 0 }; 1319 static const UDate aDate = -631152000000.0; 1320 1321 UErrorCode status = U_ZERO_ERROR; 1322 UErrorCode expectStatus = U_ILLEGAL_ARGUMENT_ERROR; 1323 UDateFormat icudf; 1324 1325 icudf = udat_open(UDAT_NONE, UDAT_SHORT_RELATIVE, "en", tzName, -1, NULL, 0, &status); 1326 if ( U_SUCCESS(status) ) { 1327 const char *what = "???"; 1328 { 1329 UErrorCode subStatus = U_ZERO_ERROR; 1330 what = "udat_set2DigitYearStart"; 1331 log_verbose("Trying %s on a relative date..\n", what); 1332 udat_set2DigitYearStart(icudf, aDate, &subStatus); 1333 if(subStatus == expectStatus) { 1334 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus)); 1335 } else { 1336 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus)); 1337 } 1338 } 1339 { 1340 /* clone works polymorphically. try it anyways */ 1341 UErrorCode subStatus = U_ZERO_ERROR; 1342 UDateFormat *oth; 1343 what = "clone"; 1344 log_verbose("Trying %s on a relative date..\n", what); 1345 oth = udat_clone(icudf, &subStatus); 1346 if(subStatus == U_ZERO_ERROR) { 1347 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus)); 1348 udat_close(oth); /* ? */ 1349 } else { 1350 log_err("FAIL: didn't crash on %s, but got %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus)); 1351 } 1352 } 1353 { 1354 UErrorCode subStatus = U_ZERO_ERROR; 1355 what = "udat_get2DigitYearStart"; 1356 log_verbose("Trying %s on a relative date..\n", what); 1357 udat_get2DigitYearStart(icudf, &subStatus); 1358 if(subStatus == expectStatus) { 1359 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus)); 1360 } else { 1361 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus)); 1362 } 1363 } 1364 { 1365 /* Now udat_toPattern works for relative date formatters, unless localized is TRUE */ 1366 UErrorCode subStatus = U_ZERO_ERROR; 1367 what = "udat_toPattern"; 1368 log_verbose("Trying %s on a relative date..\n", what); 1369 udat_toPattern(icudf, TRUE,NULL,0, &subStatus); 1370 if(subStatus == expectStatus) { 1371 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus)); 1372 } else { 1373 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus)); 1374 } 1375 } 1376 { 1377 UErrorCode subStatus = U_ZERO_ERROR; 1378 what = "udat_applyPattern"; 1379 log_verbose("Trying %s on a relative date..\n", what); 1380 udat_applyPattern(icudf, FALSE,tzName,-1); 1381 subStatus = U_ILLEGAL_ARGUMENT_ERROR; /* what it should be, if this took an errorcode. */ 1382 if(subStatus == expectStatus) { 1383 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus)); 1384 } else { 1385 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus)); 1386 } 1387 } 1388 { 1389 UChar erabuf[32]; 1390 UErrorCode subStatus = U_ZERO_ERROR; 1391 what = "udat_getSymbols"; 1392 log_verbose("Trying %s on a relative date..\n", what); 1393 udat_getSymbols(icudf, UDAT_ERAS,0,erabuf,UPRV_LENGTHOF(erabuf), &subStatus); 1394 if(subStatus == U_ZERO_ERROR) { 1395 log_verbose("Success: %s returned %s.\n", what, u_errorName(subStatus)); 1396 } else { 1397 log_err("FAIL: didn't crash on %s, but got %s instead of U_ZERO_ERROR.\n", what, u_errorName(subStatus)); 1398 } 1399 } 1400 { 1401 UErrorCode subStatus = U_ZERO_ERROR; 1402 UChar symbolValue = 0x0041; 1403 what = "udat_setSymbols"; 1404 log_verbose("Trying %s on a relative date..\n", what); 1405 udat_setSymbols(icudf, UDAT_ERAS,0,&symbolValue,1, &subStatus); /* bogus values */ 1406 if(subStatus == expectStatus) { 1407 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus)); 1408 } else { 1409 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus)); 1410 } 1411 } 1412 { 1413 UErrorCode subStatus = U_ZERO_ERROR; 1414 what = "udat_countSymbols"; 1415 log_verbose("Trying %s on a relative date..\n", what); 1416 udat_countSymbols(icudf, UDAT_ERAS); 1417 subStatus = U_ILLEGAL_ARGUMENT_ERROR; /* should have an errorcode. */ 1418 if(subStatus == expectStatus) { 1419 log_verbose("Success: did not crash on %s, but got %s.\n", what, u_errorName(subStatus)); 1420 } else { 1421 log_err("FAIL: didn't crash on %s, but got success %s instead of %s. \n", what, u_errorName(subStatus), u_errorName(expectStatus)); 1422 } 1423 } 1424 1425 udat_close(icudf); 1426 } else { 1427 log_data_err("FAIL: err calling udat_open() ->%s (Are you missing data?)\n", u_errorName(status)); 1428 } 1429} 1430 1431static const UChar skeleton_yMMMM[] = { 0x79,0x4D,0x4D,0x4D,0x4D,0 }; /* "yMMMM"; fr maps to "MMMM y", cs maps to "LLLL y" */ 1432static const UChar july2008_frDefault[] = { 0x6A,0x75,0x69,0x6C,0x6C,0x65,0x74,0x20,0x32,0x30,0x30,0x38,0 }; /* "juillet 2008" */ 1433static const UChar july2008_frTitle[] = { 0x4A,0x75,0x69,0x6C,0x6C,0x65,0x74,0x20,0x32,0x30,0x30,0x38,0 }; /* "Juillet 2008" sentence-begin, standalone */ 1434static const UChar july2008_csDefault[] = { 0x10D,0x65,0x72,0x76,0x65,0x6E,0x65,0x63,0x20,0x32,0x30,0x30,0x38,0 }; /* "c(hacek)ervenec 2008" */ 1435static 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 */ 1436 1437typedef struct { 1438 const char * locale; 1439 const UChar * skeleton; 1440 UDisplayContext capitalizationContext; 1441 const UChar * expectedFormat; 1442} TestContextItem; 1443 1444static const TestContextItem textContextItems[] = { 1445 { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_NONE, july2008_frDefault }, 1446#if !UCONFIG_NO_BREAK_ITERATION 1447 { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, july2008_frDefault }, 1448 { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, july2008_frTitle }, 1449 { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, july2008_frDefault }, 1450 { "fr", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_STANDALONE, july2008_frTitle }, 1451#endif 1452 { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_NONE, july2008_csDefault }, 1453#if !UCONFIG_NO_BREAK_ITERATION 1454 { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, july2008_csDefault }, 1455 { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, july2008_csTitle }, 1456 { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, july2008_csTitle }, 1457 { "cs", skeleton_yMMMM, UDISPCTX_CAPITALIZATION_FOR_STANDALONE, july2008_csDefault }, 1458#endif 1459 { NULL, NULL, (UDisplayContext)0, NULL } 1460}; 1461 1462static const UChar today_enDefault[] = { 0x74,0x6F,0x64,0x61,0x79,0 }; /* "today" */ 1463static const UChar today_enTitle[] = { 0x54,0x6F,0x64,0x61,0x79,0 }; /* "Today" sentence-begin, uiListOrMenu, standalone */ 1464static const UChar yesterday_enDefault[] = { 0x79,0x65,0x73,0x74,0x65,0x72,0x64,0x61,0x79,0 }; /* "yesterday" */ 1465static const UChar yesterday_enTitle[] = { 0x59,0x65,0x73,0x74,0x65,0x72,0x64,0x61,0x79,0 }; /* "Yesterday" sentence-begin, uiListOrMenu, standalone */ 1466static const UChar today_nbDefault[] = { 0x69,0x20,0x64,0x61,0x67,0 }; /* "i dag" */ 1467static const UChar today_nbTitle[] = { 0x49,0x20,0x64,0x61,0x67,0 }; /* "I dag" sentence-begin, standalone */ 1468static const UChar yesterday_nbDefault[] = { 0x69,0x20,0x67,0xE5,0x72,0 }; 1469static const UChar yesterday_nbTitle[] = { 0x49,0x20,0x67,0xE5,0x72,0 }; 1470 1471typedef struct { 1472 const char * locale; 1473 UDisplayContext capitalizationContext; 1474 const UChar * expectedFormatToday; 1475 const UChar * expectedFormatYesterday; 1476} TestRelativeContextItem; 1477 1478static const TestRelativeContextItem textContextRelativeItems[] = { 1479 { "en", UDISPCTX_CAPITALIZATION_NONE, today_enDefault, yesterday_enDefault }, 1480#if !UCONFIG_NO_BREAK_ITERATION 1481 { "en", UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, today_enDefault, yesterday_enDefault }, 1482 { "en", UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, today_enTitle, yesterday_enTitle }, 1483 { "en", UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, today_enTitle, yesterday_enTitle }, 1484 { "en", UDISPCTX_CAPITALIZATION_FOR_STANDALONE, today_enTitle, yesterday_enTitle }, 1485#endif 1486 { "nb", UDISPCTX_CAPITALIZATION_NONE, today_nbDefault, yesterday_nbDefault }, 1487#if !UCONFIG_NO_BREAK_ITERATION 1488 { "nb", UDISPCTX_CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, today_nbDefault, yesterday_nbDefault }, 1489 { "nb", UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, today_nbTitle, yesterday_nbTitle }, 1490 { "nb", UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU, today_nbDefault, yesterday_nbDefault }, 1491 { "nb", UDISPCTX_CAPITALIZATION_FOR_STANDALONE, today_nbTitle, yesterday_nbTitle }, 1492#endif 1493 { NULL, (UDisplayContext)0, NULL, NULL } 1494}; 1495 1496static const UChar zoneGMT[] = { 0x47,0x4D,0x54,0 }; /* "GMT" */ 1497static const UDate july022008 = 1215000000000.0; 1498enum { kUbufMax = 64, kBbufMax = 3*kUbufMax }; 1499 1500static void TestContext(void) { 1501 const TestContextItem* textContextItemPtr; 1502 const TestRelativeContextItem* textRelContextItemPtr; 1503 for (textContextItemPtr = textContextItems; textContextItemPtr->locale != NULL; ++textContextItemPtr) { 1504 UErrorCode status = U_ZERO_ERROR; 1505 UDateTimePatternGenerator* udtpg = udatpg_open(textContextItemPtr->locale, &status); 1506 if ( U_SUCCESS(status) ) { 1507 UChar ubuf[kUbufMax]; 1508 int32_t len = udatpg_getBestPattern(udtpg, textContextItemPtr->skeleton, -1, ubuf, kUbufMax, &status); 1509 if ( U_SUCCESS(status) ) { 1510 UDateFormat* udfmt = udat_open(UDAT_PATTERN, UDAT_PATTERN, textContextItemPtr->locale, zoneGMT, -1, ubuf, len, &status); 1511 if ( U_SUCCESS(status) ) { 1512 udat_setContext(udfmt, textContextItemPtr->capitalizationContext, &status); 1513 if ( U_SUCCESS(status) ) { 1514 UDisplayContext getContext; 1515 len = udat_format(udfmt, july022008, ubuf, kUbufMax, NULL, &status); 1516 if ( U_FAILURE(status) ) { 1517 log_err("FAIL: udat_format for locale %s, capitalizationContext %d, status %s\n", 1518 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, u_errorName(status) ); 1519 status = U_ZERO_ERROR; 1520 } else if (u_strncmp(ubuf, textContextItemPtr->expectedFormat, kUbufMax) != 0) { 1521 char bbuf1[kBbufMax]; 1522 char bbuf2[kBbufMax]; 1523 log_err("FAIL: udat_format for locale %s, capitalizationContext %d, expected %s, got %s\n", 1524 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, 1525 u_austrncpy(bbuf1,textContextItemPtr->expectedFormat,kUbufMax), u_austrncpy(bbuf2,ubuf,kUbufMax) ); 1526 } 1527 getContext = udat_getContext(udfmt, UDISPCTX_TYPE_CAPITALIZATION, &status); 1528 if ( U_FAILURE(status) ) { 1529 log_err("FAIL: udat_getContext for locale %s, capitalizationContext %d, status %s\n", 1530 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, u_errorName(status) ); 1531 } else if (getContext != textContextItemPtr->capitalizationContext) { 1532 log_err("FAIL: udat_getContext for locale %s, capitalizationContext %d, got context %d\n", 1533 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, (int)getContext ); 1534 } 1535 } else { 1536 log_err("FAIL: udat_setContext for locale %s, capitalizationContext %d, status %s\n", 1537 textContextItemPtr->locale, (int)textContextItemPtr->capitalizationContext, u_errorName(status) ); 1538 } 1539 udat_close(udfmt); 1540 } else { 1541 log_data_err("FAIL: udat_open for locale %s, status %s\n", textContextItemPtr->locale, u_errorName(status) ); 1542 } 1543 } else { 1544 log_err("FAIL: udatpg_getBestPattern for locale %s, status %s\n", textContextItemPtr->locale, u_errorName(status) ); 1545 } 1546 udatpg_close(udtpg); 1547 } else { 1548 log_data_err("FAIL: udatpg_open for locale %s, status %s\n", textContextItemPtr->locale, u_errorName(status) ); 1549 } 1550 } 1551 for (textRelContextItemPtr = textContextRelativeItems; textRelContextItemPtr->locale != NULL; ++textRelContextItemPtr) { 1552 UErrorCode status = U_ZERO_ERROR; 1553 UCalendar* ucal = ucal_open(zoneGMT, -1, "root", UCAL_GREGORIAN, &status); 1554 if ( U_SUCCESS(status) ) { 1555 UDateFormat* udfmt = udat_open(UDAT_NONE, UDAT_LONG_RELATIVE, textRelContextItemPtr->locale, zoneGMT, -1, NULL, 0, &status); 1556 if ( U_SUCCESS(status) ) { 1557 udat_setContext(udfmt, textRelContextItemPtr->capitalizationContext, &status); 1558 if ( U_SUCCESS(status) ) { 1559 UDate yesterday, today = ucal_getNow(); 1560 UChar ubuf[kUbufMax]; 1561 char bbuf1[kBbufMax]; 1562 char bbuf2[kBbufMax]; 1563 int32_t len = udat_format(udfmt, today, ubuf, kUbufMax, NULL, &status); 1564 (void)len; 1565 if ( U_FAILURE(status) ) { 1566 log_err("FAIL: udat_format today for locale %s, capitalizationContext %d, status %s\n", 1567 textRelContextItemPtr->locale, (int)textRelContextItemPtr->capitalizationContext, u_errorName(status) ); 1568 } else if (u_strncmp(ubuf, textRelContextItemPtr->expectedFormatToday, kUbufMax) != 0) { 1569 log_err("FAIL: udat_format today for locale %s, capitalizationContext %d, expected %s, got %s\n", 1570 textRelContextItemPtr->locale, (int)textRelContextItemPtr->capitalizationContext, 1571 u_austrncpy(bbuf1,textRelContextItemPtr->expectedFormatToday,kUbufMax), u_austrncpy(bbuf2,ubuf,kUbufMax) ); 1572 } 1573 status = U_ZERO_ERROR; 1574 ucal_setMillis(ucal, today, &status); 1575 ucal_add(ucal, UCAL_DATE, -1, &status); 1576 yesterday = ucal_getMillis(ucal, &status); 1577 if ( U_SUCCESS(status) ) { 1578 len = udat_format(udfmt, yesterday, ubuf, kUbufMax, NULL, &status); 1579 if ( U_FAILURE(status) ) { 1580 log_err("FAIL: udat_format yesterday for locale %s, capitalizationContext %d, status %s\n", 1581 textRelContextItemPtr->locale, (int)textRelContextItemPtr->capitalizationContext, u_errorName(status) ); 1582 } else if (u_strncmp(ubuf, textRelContextItemPtr->expectedFormatYesterday, kUbufMax) != 0) { 1583 log_err("FAIL: udat_format yesterday for locale %s, capitalizationContext %d, expected %s, got %s\n", 1584 textRelContextItemPtr->locale, (int)textRelContextItemPtr->capitalizationContext, 1585 u_austrncpy(bbuf1,textRelContextItemPtr->expectedFormatYesterday,kUbufMax), u_austrncpy(bbuf2,ubuf,kUbufMax) ); 1586 } 1587 } 1588 } else { 1589 log_err("FAIL: udat_setContext relative for locale %s, capitalizationContext %d, status %s\n", 1590 textRelContextItemPtr->locale, (int)textRelContextItemPtr->capitalizationContext, u_errorName(status) ); 1591 } 1592 udat_close(udfmt); 1593 } else { 1594 log_data_err("FAIL: udat_open relative for locale %s, status %s\n", textRelContextItemPtr->locale, u_errorName(status) ); 1595 } 1596 ucal_close(ucal); 1597 } else { 1598 log_data_err("FAIL: ucal_open for locale root, status %s\n", u_errorName(status) ); 1599 } 1600 } 1601} 1602 1603 1604// overrideNumberFormat[i][0] is to tell which field to set, 1605// overrideNumberFormat[i][1] is the expected result 1606static const char * overrideNumberFormat[][2] = { 1607 {"", "\\u521D\\u4E03 \\u521D\\u4E8C"}, 1608 {"d", "07 \\u521D\\u4E8C"}, 1609 {"do", "07 \\u521D\\u4E8C"}, 1610 {"Md", "\\u521D\\u4E03 \\u521D\\u4E8C"}, 1611 {"MdMMd", "\\u521D\\u4E03 \\u521D\\u4E8C"}, 1612 {"mixed", "\\u521D\\u4E03 \\u521D\\u4E8C"} 1613}; 1614 1615static void TestOverrideNumberFormat(void) { 1616 UErrorCode status = U_ZERO_ERROR; 1617 UChar pattern[50]; 1618 UChar expected[50]; 1619 UChar fields[50]; 1620 char bbuf1[kBbufMax]; 1621 char bbuf2[kBbufMax]; 1622 const char* localeString = "zh@numbers=hanidays"; 1623 UDateFormat* fmt; 1624 const UNumberFormat* getter_result; 1625 int32_t i; 1626 1627 u_uastrcpy(fields, "d"); 1628 u_uastrcpy(pattern,"MM d"); 1629 1630 fmt=udat_open(UDAT_PATTERN, UDAT_PATTERN, "en_US", zoneGMT, -1, pattern, u_strlen(pattern), &status); 1631 if (!assertSuccess("udat_open()", &status)) { 1632 return; 1633 } 1634 1635 // loop 5 times to check getter/setter 1636 for (i = 0; i < 5; i++){ 1637 UNumberFormat* overrideFmt; 1638 overrideFmt = unum_open(UNUM_DEFAULT, NULL, 0, localeString, NULL, &status); 1639 assertSuccess("unum_open()", &status); 1640 udat_adoptNumberFormatForFields(fmt, fields, overrideFmt, &status); 1641 overrideFmt = NULL; // no longer valid 1642 assertSuccess("udat_setNumberFormatForField()", &status); 1643 1644 getter_result = udat_getNumberFormatForField(fmt, 0x0064 /*'d'*/); 1645 if(getter_result == NULL) { 1646 log_err("FAIL: udat_getNumberFormatForField did not return a valid pointer\n"); 1647 } 1648 } 1649 { 1650 UNumberFormat* overrideFmt; 1651 overrideFmt = unum_open(UNUM_DEFAULT, NULL, 0, localeString, NULL, &status); 1652 assertSuccess("unum_open()", &status); 1653 udat_setNumberFormat(fmt, overrideFmt); // test the same override NF will not crash 1654 unum_close(overrideFmt); 1655 } 1656 udat_close(fmt); 1657 1658 for (i=0; i<UPRV_LENGTHOF(overrideNumberFormat); i++){ 1659 UChar ubuf[kUbufMax]; 1660 UDateFormat* fmt2; 1661 UNumberFormat* overrideFmt2; 1662 1663 fmt2 =udat_open(UDAT_PATTERN, UDAT_PATTERN,"en_US", zoneGMT, -1, pattern, u_strlen(pattern), &status); 1664 assertSuccess("udat_open() with en_US", &status); 1665 1666 overrideFmt2 = unum_open(UNUM_DEFAULT, NULL, 0, localeString, NULL, &status); 1667 assertSuccess("unum_open() in loop", &status); 1668 1669 u_uastrcpy(fields, overrideNumberFormat[i][0]); 1670 u_unescape(overrideNumberFormat[i][1], expected, UPRV_LENGTHOF(expected)); 1671 1672 if ( strcmp(overrideNumberFormat[i][0], "") == 0 ) { // use the one w/o field 1673 udat_adoptNumberFormat(fmt2, overrideFmt2); 1674 } else if ( strcmp(overrideNumberFormat[i][0], "mixed") == 0 ) { // set 1 field at first but then full override, both(M & d) should be override 1675 const char* singleLocale = "en@numbers=hebr"; 1676 UNumberFormat* singleOverrideFmt; 1677 u_uastrcpy(fields, "d"); 1678 1679 singleOverrideFmt = unum_open(UNUM_DEFAULT, NULL, 0, singleLocale, NULL, &status); 1680 assertSuccess("unum_open() in mixed", &status); 1681 1682 udat_adoptNumberFormatForFields(fmt2, fields, singleOverrideFmt, &status); 1683 assertSuccess("udat_setNumberFormatForField() in mixed", &status); 1684 1685 udat_adoptNumberFormat(fmt2, overrideFmt2); 1686 } else if ( strcmp(overrideNumberFormat[i][0], "do") == 0 ) { // o is an invalid field 1687 udat_adoptNumberFormatForFields(fmt2, fields, overrideFmt2, &status); 1688 if(status == U_INVALID_FORMAT_ERROR) { 1689 udat_close(fmt2); 1690 status = U_ZERO_ERROR; 1691 continue; 1692 } 1693 } else { 1694 udat_adoptNumberFormatForFields(fmt2, fields, overrideFmt2, &status); 1695 assertSuccess("udat_setNumberFormatForField() in loop", &status); 1696 } 1697 1698 udat_format(fmt2, july022008, ubuf, kUbufMax, NULL, &status); 1699 assertSuccess("udat_format() july022008", &status); 1700 1701 if (u_strncmp(ubuf, expected, kUbufMax) != 0) 1702 log_err("fail: udat_format for locale, expected %s, got %s\n", 1703 u_austrncpy(bbuf1,expected,kUbufMax), u_austrncpy(bbuf2,ubuf,kUbufMax) ); 1704 1705 udat_close(fmt2); 1706 } 1707} 1708 1709/* 1710 * Ticket #11523 1711 * udat_parse and udat_parseCalendar should have the same error code when given the same invalid input. 1712 */ 1713static void TestParseErrorReturnValue(void) { 1714 UErrorCode status = U_ZERO_ERROR; 1715 UErrorCode expectStatus = U_PARSE_ERROR; 1716 UDateFormat* df; 1717 UCalendar* cal; 1718 1719 df = udat_open(UDAT_DEFAULT, UDAT_DEFAULT, NULL, NULL, -1, NULL, -1, &status); 1720 if (!assertSuccessCheck("udat_open()", &status, TRUE)) { 1721 return; 1722 } 1723 1724 cal = ucal_open(NULL, 0, "en_US", UCAL_GREGORIAN, &status); 1725 if (!assertSuccess("ucal_open()", &status)) { 1726 return; 1727 } 1728 1729 udat_parse(df, NULL, -1, NULL, &status); 1730 if (status != expectStatus) { 1731 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)); 1732 } 1733 1734 status = U_ZERO_ERROR; 1735 udat_parseCalendar(df, cal, NULL, -1, NULL, &status); 1736 if (status != expectStatus) { 1737 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)); 1738 } 1739 1740 ucal_close(cal); 1741 udat_close(df); 1742} 1743 1744/* 1745 * Ticket #11553 1746 * Test new udat_formatForFields, udat_formatCalendarForFields (and UFieldPositionIterator) 1747 */ 1748static const char localeForFields[] = "en_US"; 1749/* zoneGMT[]defined above */ 1750static const UDate date2015Feb25 = 1424841000000.0; /* Wednesday, February 25, 2015 at 5:10:00 AM GMT */ 1751static const UChar patNoFields[] = { 0x0027, 0x0078, 0x0078, 0x0078, 0x0027, 0 }; /* "'xxx'" */ 1752 1753typedef struct { 1754 int32_t field; 1755 int32_t beginPos; 1756 int32_t endPos; 1757} FieldsData; 1758static const FieldsData expectedFields[] = { 1759 { UDAT_DAY_OF_WEEK_FIELD /* 9*/, 0, 9 }, 1760 { UDAT_MONTH_FIELD /* 2*/, 11, 19 }, 1761 { UDAT_DATE_FIELD /* 3*/, 20, 22 }, 1762 { UDAT_YEAR_FIELD /* 1*/, 24, 28 }, 1763 { UDAT_HOUR1_FIELD /*15*/, 32, 33 }, 1764#if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR 1765 { UDAT_TIME_SEPARATOR_FIELD /*35*/, 33, 34 }, 1766#endif 1767 { UDAT_MINUTE_FIELD /* 6*/, 34, 36 }, 1768#if UDAT_HAS_PATTERN_CHAR_FOR_TIME_SEPARATOR 1769 { UDAT_TIME_SEPARATOR_FIELD /*35*/, 36, 37 }, 1770#endif 1771 { UDAT_SECOND_FIELD /* 7*/, 37, 39 }, 1772 { UDAT_AM_PM_FIELD /*14*/, 40, 42 }, 1773 { UDAT_TIMEZONE_FIELD /*17*/, 43, 46 }, 1774 { -1, -1, -1 }, 1775}; 1776 1777enum {kUBufFieldsLen = 128, kBBufFieldsLen = 256 }; 1778 1779static void TestFormatForFields(void) { 1780 UErrorCode status = U_ZERO_ERROR; 1781 UFieldPositionIterator* fpositer = ufieldpositer_open(&status); 1782 if ( U_FAILURE(status) ) { 1783 log_err("ufieldpositer_open fails, status %s\n", u_errorName(status)); 1784 } else { 1785 UDateFormat* udfmt = udat_open(UDAT_LONG, UDAT_FULL, localeForFields, zoneGMT, -1, NULL, 0, &status); 1786 UCalendar* ucal = ucal_open(zoneGMT, -1, localeForFields, UCAL_DEFAULT, &status); 1787 if ( U_FAILURE(status) ) { 1788 log_data_err("udat_open or ucal_open fails for locale %s, status %s (Are you missing data?)\n", localeForFields, u_errorName(status)); 1789 } else { 1790 int32_t ulen, field, beginPos, endPos; 1791 UChar ubuf[kUBufFieldsLen]; 1792 const FieldsData * fptr; 1793 1794 status = U_ZERO_ERROR; 1795 ulen = udat_formatForFields(udfmt, date2015Feb25, ubuf, kUBufFieldsLen, fpositer, &status); 1796 if ( U_FAILURE(status) ) { 1797 log_err("udat_formatForFields fails, status %s\n", u_errorName(status)); 1798 } else { 1799 for (fptr = expectedFields; ; fptr++) { 1800 field = ufieldpositer_next(fpositer, &beginPos, &endPos); 1801 if (field != fptr->field || (field >= 0 && (beginPos != fptr->beginPos || endPos != fptr->endPos))) { 1802 if (fptr->field >= 0) { 1803 log_err("udat_formatForFields as \"%s\"; expect field %d range %d-%d, get field %d range %d-%d\n", 1804 aescstrdup(ubuf, ulen), fptr->field, fptr->beginPos, fptr->endPos, field, beginPos, endPos); 1805 } else { 1806 log_err("udat_formatForFields as \"%s\"; expect field < 0, get field %d range %d-%d\n", 1807 aescstrdup(ubuf, ulen), field, beginPos, endPos); 1808 } 1809 break; 1810 } 1811 if (field < 0) { 1812 break; 1813 } 1814 } 1815 } 1816 1817 ucal_setMillis(ucal, date2015Feb25, &status); 1818 status = U_ZERO_ERROR; 1819 ulen = udat_formatCalendarForFields(udfmt, ucal, ubuf, kUBufFieldsLen, fpositer, &status); 1820 if ( U_FAILURE(status) ) { 1821 log_err("udat_formatCalendarForFields fails, status %s\n", u_errorName(status)); 1822 } else { 1823 for (fptr = expectedFields; ; fptr++) { 1824 field = ufieldpositer_next(fpositer, &beginPos, &endPos); 1825 if (field != fptr->field || (field >= 0 && (beginPos != fptr->beginPos || endPos != fptr->endPos))) { 1826 if (fptr->field >= 0) { 1827 log_err("udat_formatFudat_formatCalendarForFieldsorFields as \"%s\"; expect field %d range %d-%d, get field %d range %d-%d\n", 1828 aescstrdup(ubuf, ulen), fptr->field, fptr->beginPos, fptr->endPos, field, beginPos, endPos); 1829 } else { 1830 log_err("udat_formatCalendarForFields as \"%s\"; expect field < 0, get field %d range %d-%d\n", 1831 aescstrdup(ubuf, ulen), field, beginPos, endPos); 1832 } 1833 break; 1834 } 1835 if (field < 0) { 1836 break; 1837 } 1838 } 1839 } 1840 1841 udat_applyPattern(udfmt, FALSE, patNoFields, -1); 1842 status = U_ZERO_ERROR; 1843 ulen = udat_formatForFields(udfmt, date2015Feb25, ubuf, kUBufFieldsLen, fpositer, &status); 1844 if ( U_FAILURE(status) ) { 1845 log_err("udat_formatForFields with no-field pattern fails, status %s\n", u_errorName(status)); 1846 } else { 1847 field = ufieldpositer_next(fpositer, &beginPos, &endPos); 1848 if (field >= 0) { 1849 log_err("udat_formatForFields with no-field pattern as \"%s\"; expect field < 0, get field %d range %d-%d\n", 1850 aescstrdup(ubuf, ulen), field, beginPos, endPos); 1851 } 1852 } 1853 1854 ucal_close(ucal); 1855 udat_close(udfmt); 1856 } 1857 ufieldpositer_close(fpositer); 1858 } 1859} 1860 1861#endif /* #if !UCONFIG_NO_FORMATTING */ 1862