1 /* 2 ******************************************************************************* 3 * Copyright (C) 1996-2010, 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 verifyIsSimpleDateFormat(fmt, status); 389 if(U_FAILURE(*status)) return -1; 390 391 const DateFormatSymbols *syms = 392 ((SimpleDateFormat*)fmt)->getDateFormatSymbols(); 393 int32_t count; 394 const UnicodeString *res = NULL; 395 396 switch(type) { 397 case UDAT_ERAS: 398 res = syms->getEras(count); 399 break; 400 401 case UDAT_ERA_NAMES: 402 res = syms->getEraNames(count); 403 break; 404 405 case UDAT_MONTHS: 406 res = syms->getMonths(count); 407 break; 408 409 case UDAT_SHORT_MONTHS: 410 res = syms->getShortMonths(count); 411 break; 412 413 case UDAT_WEEKDAYS: 414 res = syms->getWeekdays(count); 415 break; 416 417 case UDAT_SHORT_WEEKDAYS: 418 res = syms->getShortWeekdays(count); 419 break; 420 421 case UDAT_AM_PMS: 422 res = syms->getAmPmStrings(count); 423 break; 424 425 case UDAT_LOCALIZED_CHARS: 426 { 427 UnicodeString res1; 428 if(!(result==NULL && resultLength==0)) { 429 // NULL destination for pure preflighting: empty dummy string 430 // otherwise, alias the destination buffer 431 res1.setTo(result, 0, resultLength); 432 } 433 syms->getLocalPatternChars(res1); 434 return res1.extract(result, resultLength, *status); 435 } 436 437 case UDAT_NARROW_MONTHS: 438 res = syms->getMonths(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW); 439 break; 440 441 case UDAT_NARROW_WEEKDAYS: 442 res = syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW); 443 break; 444 445 case UDAT_STANDALONE_MONTHS: 446 res = syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE); 447 break; 448 449 case UDAT_STANDALONE_SHORT_MONTHS: 450 res = syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED); 451 break; 452 453 case UDAT_STANDALONE_NARROW_MONTHS: 454 res = syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW); 455 break; 456 457 case UDAT_STANDALONE_WEEKDAYS: 458 res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE); 459 break; 460 461 case UDAT_STANDALONE_SHORT_WEEKDAYS: 462 res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED); 463 break; 464 465 case UDAT_STANDALONE_NARROW_WEEKDAYS: 466 res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW); 467 break; 468 469 case UDAT_QUARTERS: 470 res = syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE); 471 break; 472 473 case UDAT_SHORT_QUARTERS: 474 res = syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED); 475 break; 476 477 case UDAT_STANDALONE_QUARTERS: 478 res = syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE); 479 break; 480 481 case UDAT_STANDALONE_SHORT_QUARTERS: 482 res = syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED); 483 break; 484 485 } 486 487 if(index < count) { 488 return res[index].extract(result, resultLength, *status); 489 } 490 return 0; 491 } 492 493 // TODO: also needs an errorCode. 494 U_CAPI int32_t U_EXPORT2 495 udat_countSymbols( const UDateFormat *fmt, 496 UDateFormatSymbolType type) 497 { 498 UErrorCode status = U_ZERO_ERROR; 499 500 verifyIsSimpleDateFormat(fmt, &status); 501 if(U_FAILURE(status)) { 502 return 0; 503 } 504 505 const DateFormatSymbols *syms = 506 ((SimpleDateFormat*)fmt)->getDateFormatSymbols(); 507 int32_t count = 0; 508 509 switch(type) { 510 case UDAT_ERAS: 511 syms->getEras(count); 512 break; 513 514 case UDAT_MONTHS: 515 syms->getMonths(count); 516 break; 517 518 case UDAT_SHORT_MONTHS: 519 syms->getShortMonths(count); 520 break; 521 522 case UDAT_WEEKDAYS: 523 syms->getWeekdays(count); 524 break; 525 526 case UDAT_SHORT_WEEKDAYS: 527 syms->getShortWeekdays(count); 528 break; 529 530 case UDAT_AM_PMS: 531 syms->getAmPmStrings(count); 532 break; 533 534 case UDAT_LOCALIZED_CHARS: 535 count = 1; 536 break; 537 538 case UDAT_ERA_NAMES: 539 syms->getEraNames(count); 540 break; 541 542 case UDAT_NARROW_MONTHS: 543 syms->getMonths(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW); 544 break; 545 546 case UDAT_NARROW_WEEKDAYS: 547 syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW); 548 break; 549 550 case UDAT_STANDALONE_MONTHS: 551 syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE); 552 break; 553 554 case UDAT_STANDALONE_SHORT_MONTHS: 555 syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED); 556 break; 557 558 case UDAT_STANDALONE_NARROW_MONTHS: 559 syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW); 560 break; 561 562 case UDAT_STANDALONE_WEEKDAYS: 563 syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE); 564 break; 565 566 case UDAT_STANDALONE_SHORT_WEEKDAYS: 567 syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED); 568 break; 569 570 case UDAT_STANDALONE_NARROW_WEEKDAYS: 571 syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW); 572 break; 573 574 case UDAT_QUARTERS: 575 syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE); 576 break; 577 578 case UDAT_SHORT_QUARTERS: 579 syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED); 580 break; 581 582 case UDAT_STANDALONE_QUARTERS: 583 syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE); 584 break; 585 586 case UDAT_STANDALONE_SHORT_QUARTERS: 587 syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED); 588 break; 589 590 } 591 592 return count; 593 } 594 595 U_NAMESPACE_BEGIN 596 597 /* 598 * This DateFormatSymbolsSingleSetter class is a friend of DateFormatSymbols 599 * solely for the purpose of avoiding to clone the array of strings 600 * just to modify one of them and then setting all of them back. 601 * For example, the old code looked like this: 602 * case UDAT_MONTHS: 603 * res = syms->getMonths(count); 604 * array = new UnicodeString[count]; 605 * if(array == 0) { 606 * *status = U_MEMORY_ALLOCATION_ERROR; 607 * return; 608 * } 609 * uprv_arrayCopy(res, array, count); 610 * if(index < count) 611 * array[index] = val; 612 * syms->setMonths(array, count); 613 * break; 614 * 615 * Even worse, the old code actually cloned the entire DateFormatSymbols object, 616 * cloned one value array, changed one value, and then made the SimpleDateFormat 617 * replace its DateFormatSymbols object with the new one. 618 * 619 * markus 2002-oct-14 620 */ 621 class DateFormatSymbolsSingleSetter /* not : public UObject because all methods are static */ { 622 public: 623 static void 624 setSymbol(UnicodeString *array, int32_t count, int32_t index, 625 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 626 { 627 if(array!=NULL) { 628 if(index>=count) { 629 errorCode=U_INDEX_OUTOFBOUNDS_ERROR; 630 } else if(value==NULL) { 631 errorCode=U_ILLEGAL_ARGUMENT_ERROR; 632 } else { 633 array[index].setTo(value, valueLength); 634 } 635 } 636 } 637 638 static void 639 setEra(DateFormatSymbols *syms, int32_t index, 640 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 641 { 642 setSymbol(syms->fEras, syms->fErasCount, index, value, valueLength, errorCode); 643 } 644 645 static void 646 setEraName(DateFormatSymbols *syms, int32_t index, 647 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 648 { 649 setSymbol(syms->fEraNames, syms->fEraNamesCount, index, value, valueLength, errorCode); 650 } 651 652 static void 653 setMonth(DateFormatSymbols *syms, int32_t index, 654 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 655 { 656 setSymbol(syms->fMonths, syms->fMonthsCount, index, value, valueLength, errorCode); 657 } 658 659 static void 660 setShortMonth(DateFormatSymbols *syms, int32_t index, 661 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 662 { 663 setSymbol(syms->fShortMonths, syms->fShortMonthsCount, index, value, valueLength, errorCode); 664 } 665 666 static void 667 setNarrowMonth(DateFormatSymbols *syms, int32_t index, 668 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 669 { 670 setSymbol(syms->fNarrowMonths, syms->fNarrowMonthsCount, index, value, valueLength, errorCode); 671 } 672 673 static void 674 setStandaloneMonth(DateFormatSymbols *syms, int32_t index, 675 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 676 { 677 setSymbol(syms->fStandaloneMonths, syms->fStandaloneMonthsCount, index, value, valueLength, errorCode); 678 } 679 680 static void 681 setStandaloneShortMonth(DateFormatSymbols *syms, int32_t index, 682 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 683 { 684 setSymbol(syms->fStandaloneShortMonths, syms->fStandaloneShortMonthsCount, index, value, valueLength, errorCode); 685 } 686 687 static void 688 setStandaloneNarrowMonth(DateFormatSymbols *syms, int32_t index, 689 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 690 { 691 setSymbol(syms->fStandaloneNarrowMonths, syms->fStandaloneNarrowMonthsCount, index, value, valueLength, errorCode); 692 } 693 694 static void 695 setWeekday(DateFormatSymbols *syms, int32_t index, 696 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 697 { 698 setSymbol(syms->fWeekdays, syms->fWeekdaysCount, index, value, valueLength, errorCode); 699 } 700 701 static void 702 setShortWeekday(DateFormatSymbols *syms, int32_t index, 703 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 704 { 705 setSymbol(syms->fShortWeekdays, syms->fShortWeekdaysCount, index, value, valueLength, errorCode); 706 } 707 708 static void 709 setNarrowWeekday(DateFormatSymbols *syms, int32_t index, 710 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 711 { 712 setSymbol(syms->fNarrowWeekdays, syms->fNarrowWeekdaysCount, index, value, valueLength, errorCode); 713 } 714 715 static void 716 setStandaloneWeekday(DateFormatSymbols *syms, int32_t index, 717 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 718 { 719 setSymbol(syms->fStandaloneWeekdays, syms->fStandaloneWeekdaysCount, index, value, valueLength, errorCode); 720 } 721 722 static void 723 setStandaloneShortWeekday(DateFormatSymbols *syms, int32_t index, 724 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 725 { 726 setSymbol(syms->fStandaloneShortWeekdays, syms->fStandaloneShortWeekdaysCount, index, value, valueLength, errorCode); 727 } 728 729 static void 730 setStandaloneNarrowWeekday(DateFormatSymbols *syms, int32_t index, 731 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 732 { 733 setSymbol(syms->fStandaloneNarrowWeekdays, syms->fStandaloneNarrowWeekdaysCount, index, value, valueLength, errorCode); 734 } 735 736 static void 737 setQuarter(DateFormatSymbols *syms, int32_t index, 738 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 739 { 740 setSymbol(syms->fQuarters, syms->fQuartersCount, index, value, valueLength, errorCode); 741 } 742 743 static void 744 setShortQuarter(DateFormatSymbols *syms, int32_t index, 745 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 746 { 747 setSymbol(syms->fShortQuarters, syms->fShortQuartersCount, index, value, valueLength, errorCode); 748 } 749 750 static void 751 setStandaloneQuarter(DateFormatSymbols *syms, int32_t index, 752 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 753 { 754 setSymbol(syms->fStandaloneQuarters, syms->fStandaloneQuartersCount, index, value, valueLength, errorCode); 755 } 756 757 static void 758 setStandaloneShortQuarter(DateFormatSymbols *syms, int32_t index, 759 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 760 { 761 setSymbol(syms->fStandaloneShortQuarters, syms->fStandaloneShortQuartersCount, index, value, valueLength, errorCode); 762 } 763 764 static void 765 setAmPm(DateFormatSymbols *syms, int32_t index, 766 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 767 { 768 setSymbol(syms->fAmPms, syms->fAmPmsCount, index, value, valueLength, errorCode); 769 } 770 771 static void 772 setLocalPatternChars(DateFormatSymbols *syms, 773 const UChar *value, int32_t valueLength, UErrorCode &errorCode) 774 { 775 setSymbol(&syms->fLocalPatternChars, 1, 0, value, valueLength, errorCode); 776 } 777 }; 778 779 U_NAMESPACE_END 780 781 U_CAPI void U_EXPORT2 782 udat_setSymbols( UDateFormat *format, 783 UDateFormatSymbolType type, 784 int32_t index, 785 UChar *value, 786 int32_t valueLength, 787 UErrorCode *status) 788 { 789 verifyIsSimpleDateFormat(format, status); 790 if(U_FAILURE(*status)) return; 791 792 DateFormatSymbols *syms = (DateFormatSymbols *)((SimpleDateFormat *)format)->getDateFormatSymbols(); 793 794 switch(type) { 795 case UDAT_ERAS: 796 DateFormatSymbolsSingleSetter::setEra(syms, index, value, valueLength, *status); 797 break; 798 799 case UDAT_ERA_NAMES: 800 DateFormatSymbolsSingleSetter::setEraName(syms, index, value, valueLength, *status); 801 break; 802 803 case UDAT_MONTHS: 804 DateFormatSymbolsSingleSetter::setMonth(syms, index, value, valueLength, *status); 805 break; 806 807 case UDAT_SHORT_MONTHS: 808 DateFormatSymbolsSingleSetter::setShortMonth(syms, index, value, valueLength, *status); 809 break; 810 811 case UDAT_NARROW_MONTHS: 812 DateFormatSymbolsSingleSetter::setNarrowMonth(syms, index, value, valueLength, *status); 813 break; 814 815 case UDAT_STANDALONE_MONTHS: 816 DateFormatSymbolsSingleSetter::setStandaloneMonth(syms, index, value, valueLength, *status); 817 break; 818 819 case UDAT_STANDALONE_SHORT_MONTHS: 820 DateFormatSymbolsSingleSetter::setStandaloneShortMonth(syms, index, value, valueLength, *status); 821 break; 822 823 case UDAT_STANDALONE_NARROW_MONTHS: 824 DateFormatSymbolsSingleSetter::setStandaloneNarrowMonth(syms, index, value, valueLength, *status); 825 break; 826 827 case UDAT_WEEKDAYS: 828 DateFormatSymbolsSingleSetter::setWeekday(syms, index, value, valueLength, *status); 829 break; 830 831 case UDAT_SHORT_WEEKDAYS: 832 DateFormatSymbolsSingleSetter::setShortWeekday(syms, index, value, valueLength, *status); 833 break; 834 835 case UDAT_NARROW_WEEKDAYS: 836 DateFormatSymbolsSingleSetter::setNarrowWeekday(syms, index, value, valueLength, *status); 837 break; 838 839 case UDAT_STANDALONE_WEEKDAYS: 840 DateFormatSymbolsSingleSetter::setStandaloneWeekday(syms, index, value, valueLength, *status); 841 break; 842 843 case UDAT_STANDALONE_SHORT_WEEKDAYS: 844 DateFormatSymbolsSingleSetter::setStandaloneShortWeekday(syms, index, value, valueLength, *status); 845 break; 846 847 case UDAT_STANDALONE_NARROW_WEEKDAYS: 848 DateFormatSymbolsSingleSetter::setStandaloneNarrowWeekday(syms, index, value, valueLength, *status); 849 break; 850 851 case UDAT_QUARTERS: 852 DateFormatSymbolsSingleSetter::setQuarter(syms, index, value, valueLength, *status); 853 break; 854 855 case UDAT_SHORT_QUARTERS: 856 DateFormatSymbolsSingleSetter::setShortQuarter(syms, index, value, valueLength, *status); 857 break; 858 859 case UDAT_STANDALONE_QUARTERS: 860 DateFormatSymbolsSingleSetter::setStandaloneQuarter(syms, index, value, valueLength, *status); 861 break; 862 863 case UDAT_STANDALONE_SHORT_QUARTERS: 864 DateFormatSymbolsSingleSetter::setStandaloneShortQuarter(syms, index, value, valueLength, *status); 865 break; 866 867 case UDAT_AM_PMS: 868 DateFormatSymbolsSingleSetter::setAmPm(syms, index, value, valueLength, *status); 869 break; 870 871 case UDAT_LOCALIZED_CHARS: 872 DateFormatSymbolsSingleSetter::setLocalPatternChars(syms, value, valueLength, *status); 873 break; 874 875 default: 876 *status = U_UNSUPPORTED_ERROR; 877 break; 878 879 } 880 } 881 882 U_CAPI const char* U_EXPORT2 883 udat_getLocaleByType(const UDateFormat *fmt, 884 ULocDataLocaleType type, 885 UErrorCode* status) 886 { 887 if (fmt == NULL) { 888 if (U_SUCCESS(*status)) { 889 *status = U_ILLEGAL_ARGUMENT_ERROR; 890 } 891 return NULL; 892 } 893 return ((Format*)fmt)->getLocaleID(type, *status); 894 } 895 896 /** 897 * Verify that fmt is a RelativeDateFormat. Invalid error if not. 898 * @param fmt the UDateFormat, definitely a DateFormat, maybe something else 899 * @param status error code, will be set to failure if there is a familure or the fmt is NULL. 900 */ 901 static void verifyIsRelativeDateFormat(const UDateFormat* fmt, UErrorCode *status) { 902 if(U_SUCCESS(*status) && 903 dynamic_cast<const RelativeDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))==NULL) { 904 *status = U_ILLEGAL_ARGUMENT_ERROR; 905 } 906 } 907 908 909 U_CAPI int32_t U_EXPORT2 910 udat_toPatternRelativeDate(const UDateFormat *fmt, 911 UChar *result, 912 int32_t resultLength, 913 UErrorCode *status) 914 { 915 verifyIsRelativeDateFormat(fmt, status); 916 if(U_FAILURE(*status)) return -1; 917 918 UnicodeString datePattern; 919 if(!(result==NULL && resultLength==0)) { 920 // NULL destination for pure preflighting: empty dummy string 921 // otherwise, alias the destination buffer 922 datePattern.setTo(result, 0, resultLength); 923 } 924 ((RelativeDateFormat*)fmt)->toPatternDate(datePattern, *status); 925 return datePattern.extract(result, resultLength, *status); 926 } 927 928 U_CAPI int32_t U_EXPORT2 929 udat_toPatternRelativeTime(const UDateFormat *fmt, 930 UChar *result, 931 int32_t resultLength, 932 UErrorCode *status) 933 { 934 verifyIsRelativeDateFormat(fmt, status); 935 if(U_FAILURE(*status)) return -1; 936 937 UnicodeString timePattern; 938 if(!(result==NULL && resultLength==0)) { 939 // NULL destination for pure preflighting: empty dummy string 940 // otherwise, alias the destination buffer 941 timePattern.setTo(result, 0, resultLength); 942 } 943 ((RelativeDateFormat*)fmt)->toPatternTime(timePattern, *status); 944 return timePattern.extract(result, resultLength, *status); 945 } 946 947 U_CAPI void U_EXPORT2 948 udat_applyPatternRelative(UDateFormat *format, 949 const UChar *datePattern, 950 int32_t datePatternLength, 951 const UChar *timePattern, 952 int32_t timePatternLength, 953 UErrorCode *status) 954 { 955 verifyIsRelativeDateFormat(format, status); 956 if(U_FAILURE(*status)) return; 957 const UnicodeString datePat((UBool)(datePatternLength == -1), datePattern, datePatternLength); 958 const UnicodeString timePat((UBool)(timePatternLength == -1), timePattern, timePatternLength); 959 ((RelativeDateFormat*)format)->applyPatterns(datePat, timePat, *status); 960 } 961 962 #endif /* #if !UCONFIG_NO_FORMATTING */ 963