1 /* 2 ******************************************************************************* 3 * Copyright (C) 1996-2011, International Business Machines 4 * Corporation and others. All Rights Reserved. 5 ******************************************************************************* 6 */ 7 8 #include "unicode/utypes.h" 9 10 #if !UCONFIG_NO_FORMATTING 11 12 #include "unicode/udat.h" 13 14 #include "unicode/uloc.h" 15 #include "unicode/datefmt.h" 16 #include "unicode/timezone.h" 17 #include "unicode/smpdtfmt.h" 18 #include "unicode/fieldpos.h" 19 #include "unicode/parsepos.h" 20 #include "unicode/calendar.h" 21 #include "unicode/numfmt.h" 22 #include "unicode/dtfmtsym.h" 23 #include "unicode/ustring.h" 24 #include "cpputils.h" 25 #include "reldtfmt.h" 26 27 U_NAMESPACE_USE 28 29 /** 30 * Verify that fmt is a SimpleDateFormat. Invalid error if not. 31 * @param fmt the UDateFormat, definitely a DateFormat, maybe something else 32 * @param status error code, will be set to failure if there is a familure or the fmt is NULL. 33 */ 34 static void verifyIsSimpleDateFormat(const UDateFormat* fmt, UErrorCode *status) { 35 if(U_SUCCESS(*status) && 36 dynamic_cast<const SimpleDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))==NULL) { 37 *status = U_ILLEGAL_ARGUMENT_ERROR; 38 } 39 } 40 41 // This mirrors the correspondence between the 42 // SimpleDateFormat::fgPatternIndexToDateFormatField and 43 // SimpleDateFormat::fgPatternIndexToCalendarField arrays. 44 static UCalendarDateFields gDateFieldMapping[] = { 45 UCAL_ERA, // UDAT_ERA_FIELD = 0 46 UCAL_YEAR, // UDAT_YEAR_FIELD = 1 47 UCAL_MONTH, // UDAT_MONTH_FIELD = 2 48 UCAL_DATE, // UDAT_DATE_FIELD = 3 49 UCAL_HOUR_OF_DAY, // UDAT_HOUR_OF_DAY1_FIELD = 4 50 UCAL_HOUR_OF_DAY, // UDAT_HOUR_OF_DAY0_FIELD = 5 51 UCAL_MINUTE, // UDAT_MINUTE_FIELD = 6 52 UCAL_SECOND, // UDAT_SECOND_FIELD = 7 53 UCAL_MILLISECOND, // UDAT_FRACTIONAL_SECOND_FIELD = 8 54 UCAL_DAY_OF_WEEK, // UDAT_DAY_OF_WEEK_FIELD = 9 55 UCAL_DAY_OF_YEAR, // UDAT_DAY_OF_YEAR_FIELD = 10 56 UCAL_DAY_OF_WEEK_IN_MONTH, // UDAT_DAY_OF_WEEK_IN_MONTH_FIELD = 11 57 UCAL_WEEK_OF_YEAR, // UDAT_WEEK_OF_YEAR_FIELD = 12 58 UCAL_WEEK_OF_MONTH, // UDAT_WEEK_OF_MONTH_FIELD = 13 59 UCAL_AM_PM, // UDAT_AM_PM_FIELD = 14 60 UCAL_HOUR, // UDAT_HOUR1_FIELD = 15 61 UCAL_HOUR, // UDAT_HOUR0_FIELD = 16 62 UCAL_ZONE_OFFSET, // UDAT_TIMEZONE_FIELD = 17 63 UCAL_YEAR_WOY, // UDAT_YEAR_WOY_FIELD = 18 64 UCAL_DOW_LOCAL, // UDAT_DOW_LOCAL_FIELD = 19 65 UCAL_EXTENDED_YEAR, // UDAT_EXTENDED_YEAR_FIELD = 20 66 UCAL_JULIAN_DAY, // UDAT_JULIAN_DAY_FIELD = 21 67 UCAL_MILLISECONDS_IN_DAY, // UDAT_MILLISECONDS_IN_DAY_FIELD = 22 68 UCAL_ZONE_OFFSET, // UDAT_TIMEZONE_RFC_FIELD = 23 69 // UCAL_DST_OFFSET also 70 UCAL_ZONE_OFFSET, // UDAT_TIMEZONE_GENERIC_FIELD = 24 71 UCAL_DOW_LOCAL, // UDAT_STANDALONE_DAY_FIELD = 25 72 UCAL_MONTH, // UDAT_STANDALONE_MONTH_FIELD = 26 73 UCAL_MONTH, // UDAT_QUARTER_FIELD = 27 74 UCAL_MONTH, // UDAT_STANDALONE_QUARTER_FIELD = 28 75 UCAL_ZONE_OFFSET, // UDAT_TIMEZONE_SPECIAL_FIELD = 29 76 UCAL_FIELD_COUNT, // UDAT_FIELD_COUNT = 30 77 // UCAL_IS_LEAP_MONTH is not the target of a mapping 78 }; 79 80 U_CAPI UCalendarDateFields U_EXPORT2 81 udat_toCalendarDateField(UDateFormatField field) { 82 return gDateFieldMapping[field]; 83 } 84 85 U_CAPI UDateFormat* U_EXPORT2 86 udat_open(UDateFormatStyle timeStyle, 87 UDateFormatStyle dateStyle, 88 const char *locale, 89 const UChar *tzID, 90 int32_t tzIDLength, 91 const UChar *pattern, 92 int32_t patternLength, 93 UErrorCode *status) 94 { 95 DateFormat *fmt; 96 if(U_FAILURE(*status)) { 97 return 0; 98 } 99 if(timeStyle != UDAT_IGNORE) { 100 if(locale == 0) { 101 fmt = DateFormat::createDateTimeInstance((DateFormat::EStyle)dateStyle, 102 (DateFormat::EStyle)timeStyle); 103 } 104 else { 105 fmt = DateFormat::createDateTimeInstance((DateFormat::EStyle)dateStyle, 106 (DateFormat::EStyle)timeStyle, 107 Locale(locale)); 108 } 109 } 110 else { 111 UnicodeString pat((UBool)(patternLength == -1), pattern, patternLength); 112 113 if(locale == 0) { 114 fmt = new SimpleDateFormat(pat, *status); 115 } 116 else { 117 fmt = new SimpleDateFormat(pat, Locale(locale), *status); 118 } 119 } 120 121 if(fmt == 0) { 122 *status = U_MEMORY_ALLOCATION_ERROR; 123 return 0; 124 } 125 126 if(tzID != 0) { 127 TimeZone *zone = TimeZone::createTimeZone(UnicodeString((UBool)(tzIDLength == -1), tzID, tzIDLength)); 128 if(zone == 0) { 129 *status = U_MEMORY_ALLOCATION_ERROR; 130 delete fmt; 131 return 0; 132 } 133 fmt->adoptTimeZone(zone); 134 } 135 136 return (UDateFormat*)fmt; 137 } 138 139 140 U_CAPI void U_EXPORT2 141 udat_close(UDateFormat* format) 142 { 143 delete (DateFormat*)format; 144 } 145 146 U_CAPI UDateFormat* U_EXPORT2 147 udat_clone(const UDateFormat *fmt, 148 UErrorCode *status) 149 { 150 if(U_FAILURE(*status)) return 0; 151 152 Format *res = ((DateFormat*)fmt)->clone(); 153 154 if(res == 0) { 155 *status = U_MEMORY_ALLOCATION_ERROR; 156 return 0; 157 } 158 159 return (UDateFormat*) res; 160 } 161 162 U_CAPI int32_t U_EXPORT2 163 udat_format( const UDateFormat* format, 164 UDate dateToFormat, 165 UChar* result, 166 int32_t resultLength, 167 UFieldPosition* position, 168 UErrorCode* status) 169 { 170 if(U_FAILURE(*status)) return -1; 171 172 UnicodeString res; 173 if(!(result==NULL && resultLength==0)) { 174 // NULL destination for pure preflighting: empty dummy string 175 // otherwise, alias the destination buffer 176 res.setTo(result, 0, resultLength); 177 } 178 179 FieldPosition fp; 180 181 if(position != 0) 182 fp.setField(position->field); 183 184 ((DateFormat*)format)->format(dateToFormat, res, fp); 185 186 if(position != 0) { 187 position->beginIndex = fp.getBeginIndex(); 188 position->endIndex = fp.getEndIndex(); 189 } 190 191 return res.extract(result, resultLength, *status); 192 } 193 194 U_CAPI UDate U_EXPORT2 195 udat_parse( const UDateFormat* format, 196 const UChar* text, 197 int32_t textLength, 198 int32_t *parsePos, 199 UErrorCode *status) 200 { 201 if(U_FAILURE(*status)) return (UDate)0; 202 203 const UnicodeString src((UBool)(textLength == -1), text, textLength); 204 ParsePosition pp; 205 int32_t stackParsePos = 0; 206 UDate res; 207 208 if(parsePos == NULL) { 209 parsePos = &stackParsePos; 210 } 211 212 pp.setIndex(*parsePos); 213 214 res = ((DateFormat*)format)->parse(src, pp); 215 216 if(pp.getErrorIndex() == -1) 217 *parsePos = pp.getIndex(); 218 else { 219 *parsePos = pp.getErrorIndex(); 220 *status = U_PARSE_ERROR; 221 } 222 223 return res; 224 } 225 226 U_CAPI void U_EXPORT2 227 udat_parseCalendar(const UDateFormat* format, 228 UCalendar* calendar, 229 const UChar* text, 230 int32_t textLength, 231 int32_t *parsePos, 232 UErrorCode *status) 233 { 234 if(U_FAILURE(*status)) return; 235 236 const UnicodeString src((UBool)(textLength == -1), text, textLength); 237 ParsePosition pp; 238 239 if(parsePos != 0) 240 pp.setIndex(*parsePos); 241 242 ((DateFormat*)format)->parse(src, *(Calendar*)calendar, pp); 243 244 if(parsePos != 0) { 245 if(pp.getErrorIndex() == -1) 246 *parsePos = pp.getIndex(); 247 else { 248 *parsePos = pp.getErrorIndex(); 249 *status = U_PARSE_ERROR; 250 } 251 } 252 } 253 254 U_CAPI UBool U_EXPORT2 255 udat_isLenient(const UDateFormat* fmt) 256 { 257 return ((DateFormat*)fmt)->isLenient(); 258 } 259 260 U_CAPI void U_EXPORT2 261 udat_setLenient( UDateFormat* fmt, 262 UBool isLenient) 263 { 264 ((DateFormat*)fmt)->setLenient(isLenient); 265 } 266 267 U_CAPI const UCalendar* U_EXPORT2 268 udat_getCalendar(const UDateFormat* fmt) 269 { 270 return (const UCalendar*) ((DateFormat*)fmt)->getCalendar(); 271 } 272 273 U_CAPI void U_EXPORT2 274 udat_setCalendar(UDateFormat* fmt, 275 const UCalendar* calendarToSet) 276 { 277 ((DateFormat*)fmt)->setCalendar(*((Calendar*)calendarToSet)); 278 } 279 280 U_CAPI const UNumberFormat* U_EXPORT2 281 udat_getNumberFormat(const UDateFormat* fmt) 282 { 283 return (const UNumberFormat*) ((DateFormat*)fmt)->getNumberFormat(); 284 } 285 286 U_CAPI void U_EXPORT2 287 udat_setNumberFormat(UDateFormat* fmt, 288 const UNumberFormat* numberFormatToSet) 289 { 290 ((DateFormat*)fmt)->setNumberFormat(*((NumberFormat*)numberFormatToSet)); 291 } 292 293 U_CAPI const char* U_EXPORT2 294 udat_getAvailable(int32_t index) 295 { 296 return uloc_getAvailable(index); 297 } 298 299 U_CAPI int32_t U_EXPORT2 300 udat_countAvailable() 301 { 302 return uloc_countAvailable(); 303 } 304 305 U_CAPI UDate U_EXPORT2 306 udat_get2DigitYearStart( const UDateFormat *fmt, 307 UErrorCode *status) 308 { 309 verifyIsSimpleDateFormat(fmt, status); 310 if(U_FAILURE(*status)) return (UDate)0; 311 return ((SimpleDateFormat*)fmt)->get2DigitYearStart(*status); 312 } 313 314 U_CAPI void U_EXPORT2 315 udat_set2DigitYearStart( UDateFormat *fmt, 316 UDate d, 317 UErrorCode *status) 318 { 319 verifyIsSimpleDateFormat(fmt, status); 320 if(U_FAILURE(*status)) return; 321 ((SimpleDateFormat*)fmt)->set2DigitYearStart(d, *status); 322 } 323 324 U_CAPI int32_t U_EXPORT2 325 udat_toPattern( const UDateFormat *fmt, 326 UBool localized, 327 UChar *result, 328 int32_t resultLength, 329 UErrorCode *status) 330 { 331 if(U_FAILURE(*status)) return -1; 332 333 UnicodeString res; 334 if(!(result==NULL && resultLength==0)) { 335 // NULL destination for pure preflighting: empty dummy string 336 // otherwise, alias the destination buffer 337 res.setTo(result, 0, resultLength); 338 } 339 340 const DateFormat *df=reinterpret_cast<const DateFormat *>(fmt); 341 const SimpleDateFormat *sdtfmt=dynamic_cast<const SimpleDateFormat *>(df); 342 const RelativeDateFormat *reldtfmt; 343 if (sdtfmt!=NULL) { 344 if(localized) 345 sdtfmt->toLocalizedPattern(res, *status); 346 else 347 sdtfmt->toPattern(res); 348 } else if (!localized && (reldtfmt=dynamic_cast<const RelativeDateFormat *>(df))!=NULL) { 349 reldtfmt->toPattern(res, *status); 350 } else { 351 *status = U_ILLEGAL_ARGUMENT_ERROR; 352 return -1; 353 } 354 355 return res.extract(result, resultLength, *status); 356 } 357 358 // TODO: should this take an UErrorCode? 359 // A: Yes. Of course. 360 U_CAPI void U_EXPORT2 361 udat_applyPattern( UDateFormat *format, 362 UBool localized, 363 const UChar *pattern, 364 int32_t patternLength) 365 { 366 const UnicodeString pat((UBool)(patternLength == -1), pattern, patternLength); 367 UErrorCode status = U_ZERO_ERROR; 368 369 verifyIsSimpleDateFormat(format, &status); 370 if(U_FAILURE(status)) { 371 return; 372 } 373 374 if(localized) 375 ((SimpleDateFormat*)format)->applyLocalizedPattern(pat, status); 376 else 377 ((SimpleDateFormat*)format)->applyPattern(pat); 378 } 379 380 U_CAPI int32_t U_EXPORT2 381 udat_getSymbols(const UDateFormat *fmt, 382 UDateFormatSymbolType type, 383 int32_t index, 384 UChar *result, 385 int32_t resultLength, 386 UErrorCode *status) 387 { 388 const DateFormatSymbols *syms; 389 const SimpleDateFormat* sdtfmt; 390 const RelativeDateFormat* rdtfmt; 391 if ((sdtfmt = dynamic_cast<const SimpleDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))) != NULL) { 392 syms = sdtfmt->getDateFormatSymbols(); 393 } else if ((rdtfmt = dynamic_cast<const RelativeDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))) != NULL) { 394 syms = rdtfmt->getDateFormatSymbols(); 395 } else { 396 return -1; 397 } 398 int32_t count; 399 const UnicodeString *res = NULL; 400 401 switch(type) { 402 case UDAT_ERAS: 403 res = syms->getEras(count); 404 break; 405 406 case UDAT_ERA_NAMES: 407 res = syms->getEraNames(count); 408 break; 409 410 case UDAT_MONTHS: 411 res = syms->getMonths(count); 412 break; 413 414 case UDAT_SHORT_MONTHS: 415 res = syms->getShortMonths(count); 416 break; 417 418 case UDAT_WEEKDAYS: 419 res = syms->getWeekdays(count); 420 break; 421 422 case UDAT_SHORT_WEEKDAYS: 423 res = syms->getShortWeekdays(count); 424 break; 425 426 case UDAT_AM_PMS: 427 res = syms->getAmPmStrings(count); 428 break; 429 430 case UDAT_LOCALIZED_CHARS: 431 { 432 UnicodeString res1; 433 if(!(result==NULL && resultLength==0)) { 434 // NULL destination for pure preflighting: empty dummy string 435 // otherwise, alias the destination buffer 436 res1.setTo(result, 0, resultLength); 437 } 438 syms->getLocalPatternChars(res1); 439 return res1.extract(result, resultLength, *status); 440 } 441 442 case UDAT_NARROW_MONTHS: 443 res = syms->getMonths(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW); 444 break; 445 446 case UDAT_NARROW_WEEKDAYS: 447 res = syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW); 448 break; 449 450 case UDAT_STANDALONE_MONTHS: 451 res = syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE); 452 break; 453 454 case UDAT_STANDALONE_SHORT_MONTHS: 455 res = syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED); 456 break; 457 458 case UDAT_STANDALONE_NARROW_MONTHS: 459 res = syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW); 460 break; 461 462 case UDAT_STANDALONE_WEEKDAYS: 463 res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE); 464 break; 465 466 case UDAT_STANDALONE_SHORT_WEEKDAYS: 467 res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED); 468 break; 469 470 case UDAT_STANDALONE_NARROW_WEEKDAYS: 471 res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW); 472 break; 473 474 case UDAT_QUARTERS: 475 res = syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE); 476 break; 477 478 case UDAT_SHORT_QUARTERS: 479 res = syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED); 480 break; 481 482 case UDAT_STANDALONE_QUARTERS: 483 res = syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE); 484 break; 485 486 case UDAT_STANDALONE_SHORT_QUARTERS: 487 res = syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED); 488 break; 489 490 } 491 492 if(index < count) { 493 return res[index].extract(result, resultLength, *status); 494 } 495 return 0; 496 } 497 498 // TODO: also needs an errorCode. 499 U_CAPI int32_t U_EXPORT2 500 udat_countSymbols( const UDateFormat *fmt, 501 UDateFormatSymbolType type) 502 { 503 const DateFormatSymbols *syms; 504 const SimpleDateFormat* sdtfmt; 505 const RelativeDateFormat* rdtfmt; 506 if ((sdtfmt = dynamic_cast<const SimpleDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))) != NULL) { 507 syms = sdtfmt->getDateFormatSymbols(); 508 } else if ((rdtfmt = dynamic_cast<const RelativeDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))) != NULL) { 509 syms = rdtfmt->getDateFormatSymbols(); 510 } else { 511 return 0; 512 } 513 int32_t count = 0; 514 515 switch(type) { 516 case UDAT_ERAS: 517 syms->getEras(count); 518 break; 519 520 case UDAT_MONTHS: 521 syms->getMonths(count); 522 break; 523 524 case UDAT_SHORT_MONTHS: 525 syms->getShortMonths(count); 526 break; 527 528 case UDAT_WEEKDAYS: 529 syms->getWeekdays(count); 530 break; 531 532 case UDAT_SHORT_WEEKDAYS: 533 syms->getShortWeekdays(count); 534 break; 535 536 case UDAT_AM_PMS: 537 syms->getAmPmStrings(count); 538 break; 539 540 case UDAT_LOCALIZED_CHARS: 541 count = 1; 542 break; 543 544 case UDAT_ERA_NAMES: 545 syms->getEraNames(count); 546 break; 547 548 case UDAT_NARROW_MONTHS: 549 syms->getMonths(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW); 550 break; 551 552 case UDAT_NARROW_WEEKDAYS: 553 syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW); 554 break; 555 556 case UDAT_STANDALONE_MONTHS: 557 syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE); 558 break; 559 560 case UDAT_STANDALONE_SHORT_MONTHS: 561 syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED); 562 break; 563 564 case UDAT_STANDALONE_NARROW_MONTHS: 565 syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW); 566 break; 567 568 case UDAT_STANDALONE_WEEKDAYS: 569 syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE); 570 break; 571 572 case UDAT_STANDALONE_SHORT_WEEKDAYS: 573 syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED); 574 break; 575 576 case UDAT_STANDALONE_NARROW_WEEKDAYS: 577 syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW); 578 break; 579 580 case UDAT_QUARTERS: 581 syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE); 582 break; 583 584 case UDAT_SHORT_QUARTERS: 585 syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED); 586 break; 587 588 case UDAT_STANDALONE_QUARTERS: 589 syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE); 590 break; 591 592 case UDAT_STANDALONE_SHORT_QUARTERS: 593 syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED); 594 break; 595 596 } 597 598 return count; 599 } 600 601 U_NAMESPACE_BEGIN 602 603 /* 604 * This DateFormatSymbolsSingleSetter class is a friend of DateFormatSymbols 605 * solely for the purpose of avoiding to clone the array of strings 606 * just to modify one of them and then setting all of them back. 607 * For example, the old code looked like this: 608 * case UDAT_MONTHS: 609 * res = syms->getMonths(count); 610 * array = new UnicodeString[count]; 611 * if(array == 0) { 612 * *status = U_MEMORY_ALLOCATION_ERROR; 613 * return; 614 * } 615 * uprv_arrayCopy(res, array, count); 616 * if(index < count) 617 * array[index] = val; 618 * syms->setMonths(array, count); 619 * break; 620 * 621 * Even worse, the old code actually cloned the entire DateFormatSymbols object, 622 * cloned one value array, changed one value, and then made the SimpleDateFormat 623 * replace its DateFormatSymbols object with the new one. 624 * 625 * markus 2002-oct-14 626 */ 627 class DateFormatSymbolsSingleSetter /* not : public UObject because all methods are static */ { 628 public: 629 static void 630 setSymbol(UnicodeString *array, int32_t count, int32_t index, 631 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 632 { 633 if(array!=NULL) { 634 if(index>=count) { 635 errorCode=U_INDEX_OUTOFBOUNDS_ERROR; 636 } else if(value==NULL) { 637 errorCode=U_ILLEGAL_ARGUMENT_ERROR; 638 } else { 639 array[index].setTo(value, valueLength); 640 } 641 } 642 } 643 644 static void 645 setEra(DateFormatSymbols *syms, int32_t index, 646 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 647 { 648 setSymbol(syms->fEras, syms->fErasCount, index, value, valueLength, errorCode); 649 } 650 651 static void 652 setEraName(DateFormatSymbols *syms, int32_t index, 653 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 654 { 655 setSymbol(syms->fEraNames, syms->fEraNamesCount, index, value, valueLength, errorCode); 656 } 657 658 static void 659 setMonth(DateFormatSymbols *syms, int32_t index, 660 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 661 { 662 setSymbol(syms->fMonths, syms->fMonthsCount, index, value, valueLength, errorCode); 663 } 664 665 static void 666 setShortMonth(DateFormatSymbols *syms, int32_t index, 667 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 668 { 669 setSymbol(syms->fShortMonths, syms->fShortMonthsCount, index, value, valueLength, errorCode); 670 } 671 672 static void 673 setNarrowMonth(DateFormatSymbols *syms, int32_t index, 674 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 675 { 676 setSymbol(syms->fNarrowMonths, syms->fNarrowMonthsCount, index, value, valueLength, errorCode); 677 } 678 679 static void 680 setStandaloneMonth(DateFormatSymbols *syms, int32_t index, 681 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 682 { 683 setSymbol(syms->fStandaloneMonths, syms->fStandaloneMonthsCount, index, value, valueLength, errorCode); 684 } 685 686 static void 687 setStandaloneShortMonth(DateFormatSymbols *syms, int32_t index, 688 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 689 { 690 setSymbol(syms->fStandaloneShortMonths, syms->fStandaloneShortMonthsCount, index, value, valueLength, errorCode); 691 } 692 693 static void 694 setStandaloneNarrowMonth(DateFormatSymbols *syms, int32_t index, 695 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 696 { 697 setSymbol(syms->fStandaloneNarrowMonths, syms->fStandaloneNarrowMonthsCount, index, value, valueLength, errorCode); 698 } 699 700 static void 701 setWeekday(DateFormatSymbols *syms, int32_t index, 702 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 703 { 704 setSymbol(syms->fWeekdays, syms->fWeekdaysCount, index, value, valueLength, errorCode); 705 } 706 707 static void 708 setShortWeekday(DateFormatSymbols *syms, int32_t index, 709 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 710 { 711 setSymbol(syms->fShortWeekdays, syms->fShortWeekdaysCount, index, value, valueLength, errorCode); 712 } 713 714 static void 715 setNarrowWeekday(DateFormatSymbols *syms, int32_t index, 716 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 717 { 718 setSymbol(syms->fNarrowWeekdays, syms->fNarrowWeekdaysCount, index, value, valueLength, errorCode); 719 } 720 721 static void 722 setStandaloneWeekday(DateFormatSymbols *syms, int32_t index, 723 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 724 { 725 setSymbol(syms->fStandaloneWeekdays, syms->fStandaloneWeekdaysCount, index, value, valueLength, errorCode); 726 } 727 728 static void 729 setStandaloneShortWeekday(DateFormatSymbols *syms, int32_t index, 730 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 731 { 732 setSymbol(syms->fStandaloneShortWeekdays, syms->fStandaloneShortWeekdaysCount, index, value, valueLength, errorCode); 733 } 734 735 static void 736 setStandaloneNarrowWeekday(DateFormatSymbols *syms, int32_t index, 737 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 738 { 739 setSymbol(syms->fStandaloneNarrowWeekdays, syms->fStandaloneNarrowWeekdaysCount, index, value, valueLength, errorCode); 740 } 741 742 static void 743 setQuarter(DateFormatSymbols *syms, int32_t index, 744 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 745 { 746 setSymbol(syms->fQuarters, syms->fQuartersCount, index, value, valueLength, errorCode); 747 } 748 749 static void 750 setShortQuarter(DateFormatSymbols *syms, int32_t index, 751 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 752 { 753 setSymbol(syms->fShortQuarters, syms->fShortQuartersCount, index, value, valueLength, errorCode); 754 } 755 756 static void 757 setStandaloneQuarter(DateFormatSymbols *syms, int32_t index, 758 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 759 { 760 setSymbol(syms->fStandaloneQuarters, syms->fStandaloneQuartersCount, index, value, valueLength, errorCode); 761 } 762 763 static void 764 setStandaloneShortQuarter(DateFormatSymbols *syms, int32_t index, 765 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 766 { 767 setSymbol(syms->fStandaloneShortQuarters, syms->fStandaloneShortQuartersCount, index, value, valueLength, errorCode); 768 } 769 770 static void 771 setAmPm(DateFormatSymbols *syms, int32_t index, 772 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 773 { 774 setSymbol(syms->fAmPms, syms->fAmPmsCount, index, value, valueLength, errorCode); 775 } 776 777 static void 778 setLocalPatternChars(DateFormatSymbols *syms, 779 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 780 { 781 setSymbol(&syms->fLocalPatternChars, 1, 0, value, valueLength, errorCode); 782 } 783 }; 784 785 U_NAMESPACE_END 786 787 U_CAPI void U_EXPORT2 788 udat_setSymbols( UDateFormat *format, 789 UDateFormatSymbolType type, 790 int32_t index, 791 UChar *value, 792 int32_t valueLength, 793 UErrorCode *status) 794 { 795 verifyIsSimpleDateFormat(format, status); 796 if(U_FAILURE(*status)) return; 797 798 DateFormatSymbols *syms = (DateFormatSymbols *)((SimpleDateFormat *)format)->getDateFormatSymbols(); 799 800 switch(type) { 801 case UDAT_ERAS: 802 DateFormatSymbolsSingleSetter::setEra(syms, index, value, valueLength, *status); 803 break; 804 805 case UDAT_ERA_NAMES: 806 DateFormatSymbolsSingleSetter::setEraName(syms, index, value, valueLength, *status); 807 break; 808 809 case UDAT_MONTHS: 810 DateFormatSymbolsSingleSetter::setMonth(syms, index, value, valueLength, *status); 811 break; 812 813 case UDAT_SHORT_MONTHS: 814 DateFormatSymbolsSingleSetter::setShortMonth(syms, index, value, valueLength, *status); 815 break; 816 817 case UDAT_NARROW_MONTHS: 818 DateFormatSymbolsSingleSetter::setNarrowMonth(syms, index, value, valueLength, *status); 819 break; 820 821 case UDAT_STANDALONE_MONTHS: 822 DateFormatSymbolsSingleSetter::setStandaloneMonth(syms, index, value, valueLength, *status); 823 break; 824 825 case UDAT_STANDALONE_SHORT_MONTHS: 826 DateFormatSymbolsSingleSetter::setStandaloneShortMonth(syms, index, value, valueLength, *status); 827 break; 828 829 case UDAT_STANDALONE_NARROW_MONTHS: 830 DateFormatSymbolsSingleSetter::setStandaloneNarrowMonth(syms, index, value, valueLength, *status); 831 break; 832 833 case UDAT_WEEKDAYS: 834 DateFormatSymbolsSingleSetter::setWeekday(syms, index, value, valueLength, *status); 835 break; 836 837 case UDAT_SHORT_WEEKDAYS: 838 DateFormatSymbolsSingleSetter::setShortWeekday(syms, index, value, valueLength, *status); 839 break; 840 841 case UDAT_NARROW_WEEKDAYS: 842 DateFormatSymbolsSingleSetter::setNarrowWeekday(syms, index, value, valueLength, *status); 843 break; 844 845 case UDAT_STANDALONE_WEEKDAYS: 846 DateFormatSymbolsSingleSetter::setStandaloneWeekday(syms, index, value, valueLength, *status); 847 break; 848 849 case UDAT_STANDALONE_SHORT_WEEKDAYS: 850 DateFormatSymbolsSingleSetter::setStandaloneShortWeekday(syms, index, value, valueLength, *status); 851 break; 852 853 case UDAT_STANDALONE_NARROW_WEEKDAYS: 854 DateFormatSymbolsSingleSetter::setStandaloneNarrowWeekday(syms, index, value, valueLength, *status); 855 break; 856 857 case UDAT_QUARTERS: 858 DateFormatSymbolsSingleSetter::setQuarter(syms, index, value, valueLength, *status); 859 break; 860 861 case UDAT_SHORT_QUARTERS: 862 DateFormatSymbolsSingleSetter::setShortQuarter(syms, index, value, valueLength, *status); 863 break; 864 865 case UDAT_STANDALONE_QUARTERS: 866 DateFormatSymbolsSingleSetter::setStandaloneQuarter(syms, index, value, valueLength, *status); 867 break; 868 869 case UDAT_STANDALONE_SHORT_QUARTERS: 870 DateFormatSymbolsSingleSetter::setStandaloneShortQuarter(syms, index, value, valueLength, *status); 871 break; 872 873 case UDAT_AM_PMS: 874 DateFormatSymbolsSingleSetter::setAmPm(syms, index, value, valueLength, *status); 875 break; 876 877 case UDAT_LOCALIZED_CHARS: 878 DateFormatSymbolsSingleSetter::setLocalPatternChars(syms, value, valueLength, *status); 879 break; 880 881 default: 882 *status = U_UNSUPPORTED_ERROR; 883 break; 884 885 } 886 } 887 888 U_CAPI const char* U_EXPORT2 889 udat_getLocaleByType(const UDateFormat *fmt, 890 ULocDataLocaleType type, 891 UErrorCode* status) 892 { 893 if (fmt == NULL) { 894 if (U_SUCCESS(*status)) { 895 *status = U_ILLEGAL_ARGUMENT_ERROR; 896 } 897 return NULL; 898 } 899 return ((Format*)fmt)->getLocaleID(type, *status); 900 } 901 902 /** 903 * Verify that fmt is a RelativeDateFormat. Invalid error if not. 904 * @param fmt the UDateFormat, definitely a DateFormat, maybe something else 905 * @param status error code, will be set to failure if there is a familure or the fmt is NULL. 906 */ 907 static void verifyIsRelativeDateFormat(const UDateFormat* fmt, UErrorCode *status) { 908 if(U_SUCCESS(*status) && 909 dynamic_cast<const RelativeDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))==NULL) { 910 *status = U_ILLEGAL_ARGUMENT_ERROR; 911 } 912 } 913 914 915 U_CAPI int32_t U_EXPORT2 916 udat_toPatternRelativeDate(const UDateFormat *fmt, 917 UChar *result, 918 int32_t resultLength, 919 UErrorCode *status) 920 { 921 verifyIsRelativeDateFormat(fmt, status); 922 if(U_FAILURE(*status)) return -1; 923 924 UnicodeString datePattern; 925 if(!(result==NULL && resultLength==0)) { 926 // NULL destination for pure preflighting: empty dummy string 927 // otherwise, alias the destination buffer 928 datePattern.setTo(result, 0, resultLength); 929 } 930 ((RelativeDateFormat*)fmt)->toPatternDate(datePattern, *status); 931 return datePattern.extract(result, resultLength, *status); 932 } 933 934 U_CAPI int32_t U_EXPORT2 935 udat_toPatternRelativeTime(const UDateFormat *fmt, 936 UChar *result, 937 int32_t resultLength, 938 UErrorCode *status) 939 { 940 verifyIsRelativeDateFormat(fmt, status); 941 if(U_FAILURE(*status)) return -1; 942 943 UnicodeString timePattern; 944 if(!(result==NULL && resultLength==0)) { 945 // NULL destination for pure preflighting: empty dummy string 946 // otherwise, alias the destination buffer 947 timePattern.setTo(result, 0, resultLength); 948 } 949 ((RelativeDateFormat*)fmt)->toPatternTime(timePattern, *status); 950 return timePattern.extract(result, resultLength, *status); 951 } 952 953 U_CAPI void U_EXPORT2 954 udat_applyPatternRelative(UDateFormat *format, 955 const UChar *datePattern, 956 int32_t datePatternLength, 957 const UChar *timePattern, 958 int32_t timePatternLength, 959 UErrorCode *status) 960 { 961 verifyIsRelativeDateFormat(format, status); 962 if(U_FAILURE(*status)) return; 963 const UnicodeString datePat((UBool)(datePatternLength == -1), datePattern, datePatternLength); 964 const UnicodeString timePat((UBool)(timePatternLength == -1), timePattern, timePatternLength); 965 ((RelativeDateFormat*)format)->applyPatterns(datePat, timePat, *status); 966 } 967 968 #endif /* #if !UCONFIG_NO_FORMATTING */ 969