udat.cpp (46718B)
1 // © 2016 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html 3 /* 4 ******************************************************************************* 5 * Copyright (C) 1996-2015, International Business Machines 6 * Corporation and others. All Rights Reserved. 7 ******************************************************************************* 8 */ 9 10 #include "unicode/utypes.h" 11 12 #if !UCONFIG_NO_FORMATTING 13 14 #include "unicode/udat.h" 15 16 #include "unicode/uloc.h" 17 #include "unicode/datefmt.h" 18 #include "unicode/timezone.h" 19 #include "unicode/smpdtfmt.h" 20 #include "unicode/fieldpos.h" 21 #include "unicode/parsepos.h" 22 #include "unicode/calendar.h" 23 #include "unicode/numfmt.h" 24 #include "unicode/dtfmtsym.h" 25 #include "unicode/ustring.h" 26 #include "unicode/udisplaycontext.h" 27 #include "unicode/ufieldpositer.h" 28 #include "cpputils.h" 29 #include "reldtfmt.h" 30 #include "umutex.h" 31 32 U_NAMESPACE_USE 33 34 /** 35 * Verify that fmt is a SimpleDateFormat. Invalid error if not. 36 * @param fmt the UDateFormat, definitely a DateFormat, maybe something else 37 * @param status error code, will be set to failure if there is a failure or the fmt is nullptr. 38 */ 39 static void verifyIsSimpleDateFormat(const UDateFormat* fmt, UErrorCode *status) { 40 if(U_SUCCESS(*status) && 41 dynamic_cast<const SimpleDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))==nullptr) { 42 *status = U_ILLEGAL_ARGUMENT_ERROR; 43 } 44 } 45 46 // This mirrors the correspondence between the 47 // SimpleDateFormat::fgPatternIndexToDateFormatField and 48 // SimpleDateFormat::fgPatternIndexToCalendarField arrays. 49 static UCalendarDateFields gDateFieldMapping[] = { 50 UCAL_ERA, // UDAT_ERA_FIELD = 0 51 UCAL_YEAR, // UDAT_YEAR_FIELD = 1 52 UCAL_MONTH, // UDAT_MONTH_FIELD = 2 53 UCAL_DATE, // UDAT_DATE_FIELD = 3 54 UCAL_HOUR_OF_DAY, // UDAT_HOUR_OF_DAY1_FIELD = 4 55 UCAL_HOUR_OF_DAY, // UDAT_HOUR_OF_DAY0_FIELD = 5 56 UCAL_MINUTE, // UDAT_MINUTE_FIELD = 6 57 UCAL_SECOND, // UDAT_SECOND_FIELD = 7 58 UCAL_MILLISECOND, // UDAT_FRACTIONAL_SECOND_FIELD = 8 59 UCAL_DAY_OF_WEEK, // UDAT_DAY_OF_WEEK_FIELD = 9 60 UCAL_DAY_OF_YEAR, // UDAT_DAY_OF_YEAR_FIELD = 10 61 UCAL_DAY_OF_WEEK_IN_MONTH, // UDAT_DAY_OF_WEEK_IN_MONTH_FIELD = 11 62 UCAL_WEEK_OF_YEAR, // UDAT_WEEK_OF_YEAR_FIELD = 12 63 UCAL_WEEK_OF_MONTH, // UDAT_WEEK_OF_MONTH_FIELD = 13 64 UCAL_AM_PM, // UDAT_AM_PM_FIELD = 14 65 UCAL_HOUR, // UDAT_HOUR1_FIELD = 15 66 UCAL_HOUR, // UDAT_HOUR0_FIELD = 16 67 UCAL_ZONE_OFFSET, // UDAT_TIMEZONE_FIELD = 17 68 UCAL_YEAR_WOY, // UDAT_YEAR_WOY_FIELD = 18 69 UCAL_DOW_LOCAL, // UDAT_DOW_LOCAL_FIELD = 19 70 UCAL_EXTENDED_YEAR, // UDAT_EXTENDED_YEAR_FIELD = 20 71 UCAL_JULIAN_DAY, // UDAT_JULIAN_DAY_FIELD = 21 72 UCAL_MILLISECONDS_IN_DAY, // UDAT_MILLISECONDS_IN_DAY_FIELD = 22 73 UCAL_ZONE_OFFSET, // UDAT_TIMEZONE_RFC_FIELD = 23 (also UCAL_DST_OFFSET) 74 UCAL_ZONE_OFFSET, // UDAT_TIMEZONE_GENERIC_FIELD = 24 (also UCAL_DST_OFFSET) 75 UCAL_DOW_LOCAL, // UDAT_STANDALONE_DAY_FIELD = 25 76 UCAL_MONTH, // UDAT_STANDALONE_MONTH_FIELD = 26 77 UCAL_MONTH, // UDAT_QUARTER_FIELD = 27 78 UCAL_MONTH, // UDAT_STANDALONE_QUARTER_FIELD = 28 79 UCAL_ZONE_OFFSET, // UDAT_TIMEZONE_SPECIAL_FIELD = 29 (also UCAL_DST_OFFSET) 80 UCAL_YEAR, // UDAT_YEAR_NAME_FIELD = 30 81 UCAL_ZONE_OFFSET, // UDAT_TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD = 31 (also UCAL_DST_OFFSET) 82 UCAL_ZONE_OFFSET, // UDAT_TIMEZONE_ISO_FIELD = 32 (also UCAL_DST_OFFSET) 83 UCAL_ZONE_OFFSET, // UDAT_TIMEZONE_ISO_LOCAL_FIELD = 33 (also UCAL_DST_OFFSET) 84 UCAL_EXTENDED_YEAR, // UDAT_RELATED_YEAR_FIELD = 34 (not an exact match) 85 UCAL_FIELD_COUNT, // UDAT_AM_PM_MIDNIGHT_NOON_FIELD=35 (no match) 86 UCAL_FIELD_COUNT, // UDAT_FLEXIBLE_DAY_PERIOD_FIELD=36 (no match) 87 UCAL_FIELD_COUNT, // UDAT_TIME_SEPARATOR_FIELD = 37 (no match) 88 // UDAT_FIELD_COUNT = 38 as of ICU 67 89 // UCAL_IS_LEAP_MONTH is not the target of a mapping 90 }; 91 92 U_CAPI UCalendarDateFields U_EXPORT2 93 udat_toCalendarDateField(UDateFormatField field) UPRV_NO_SANITIZE_UNDEFINED { 94 static_assert(UDAT_FIELD_COUNT == UPRV_LENGTHOF(gDateFieldMapping), 95 "UDateFormatField and gDateFieldMapping should have the same number of entries and be kept in sync."); 96 return (field >= UDAT_ERA_FIELD && field < UPRV_LENGTHOF(gDateFieldMapping))? gDateFieldMapping[field]: UCAL_FIELD_COUNT; 97 } 98 99 /* For now- one opener. */ 100 static UDateFormatOpener gOpener = nullptr; 101 102 U_CAPI void U_EXPORT2 103 udat_registerOpener(UDateFormatOpener opener, UErrorCode *status) 104 { 105 if(U_FAILURE(*status)) return; 106 umtx_lock(nullptr); 107 if(gOpener==nullptr) { 108 gOpener = opener; 109 } else { 110 *status = U_ILLEGAL_ARGUMENT_ERROR; 111 } 112 umtx_unlock(nullptr); 113 } 114 115 U_CAPI UDateFormatOpener U_EXPORT2 116 udat_unregisterOpener(UDateFormatOpener opener, UErrorCode *status) 117 { 118 if(U_FAILURE(*status)) return nullptr; 119 UDateFormatOpener oldOpener = nullptr; 120 umtx_lock(nullptr); 121 if(gOpener==nullptr || gOpener!=opener) { 122 *status = U_ILLEGAL_ARGUMENT_ERROR; 123 } else { 124 oldOpener=gOpener; 125 gOpener=nullptr; 126 } 127 umtx_unlock(nullptr); 128 return oldOpener; 129 } 130 131 132 133 U_CAPI UDateFormat* U_EXPORT2 134 udat_open(UDateFormatStyle timeStyle, 135 UDateFormatStyle dateStyle, 136 const char *locale, 137 const char16_t *tzID, 138 int32_t tzIDLength, 139 const char16_t *pattern, 140 int32_t patternLength, 141 UErrorCode *status) 142 { 143 DateFormat *fmt; 144 if(U_FAILURE(*status)) { 145 return nullptr; 146 } 147 if(gOpener!=nullptr) { // if it's registered 148 fmt = (DateFormat*) (*gOpener)(timeStyle,dateStyle,locale,tzID,tzIDLength,pattern,patternLength,status); 149 if(fmt!=nullptr) { 150 return (UDateFormat*)fmt; 151 } // else fall through. 152 } 153 if(timeStyle != UDAT_PATTERN) { 154 if (locale == nullptr) { 155 fmt = DateFormat::createDateTimeInstance((DateFormat::EStyle)dateStyle, 156 (DateFormat::EStyle)timeStyle); 157 } 158 else { 159 fmt = DateFormat::createDateTimeInstance((DateFormat::EStyle)dateStyle, 160 (DateFormat::EStyle)timeStyle, 161 Locale(locale)); 162 } 163 } 164 else { 165 UnicodeString pat(patternLength == -1, pattern, patternLength); 166 167 if (locale == nullptr) { 168 fmt = new SimpleDateFormat(pat, *status); 169 } 170 else { 171 fmt = new SimpleDateFormat(pat, Locale(locale), *status); 172 } 173 } 174 175 if(fmt == nullptr) { 176 *status = U_MEMORY_ALLOCATION_ERROR; 177 return nullptr; 178 } 179 if (U_FAILURE(*status)) { 180 delete fmt; 181 return nullptr; 182 } 183 184 if (tzID != nullptr) { 185 TimeZone* zone = TimeZone::createTimeZone(UnicodeString(tzIDLength == -1, tzID, tzIDLength)); 186 if (zone == nullptr) { 187 *status = U_MEMORY_ALLOCATION_ERROR; 188 delete fmt; 189 return nullptr; 190 } 191 fmt->adoptTimeZone(zone); 192 } 193 194 return (UDateFormat*)fmt; 195 } 196 197 198 U_CAPI void U_EXPORT2 199 udat_close(UDateFormat* format) 200 { 201 if (format == nullptr) return; 202 delete (DateFormat*)format; 203 } 204 205 U_CAPI UDateFormat* U_EXPORT2 206 udat_clone(const UDateFormat *fmt, 207 UErrorCode *status) 208 { 209 if (U_FAILURE(*status)) return nullptr; 210 211 Format *res = ((DateFormat*)fmt)->clone(); 212 213 if (res == nullptr) { 214 *status = U_MEMORY_ALLOCATION_ERROR; 215 return nullptr; 216 } 217 218 return (UDateFormat*) res; 219 } 220 221 U_CAPI int32_t U_EXPORT2 222 udat_format( const UDateFormat* format, 223 UDate dateToFormat, 224 char16_t* result, 225 int32_t resultLength, 226 UFieldPosition* position, 227 UErrorCode* status) 228 { 229 if(U_FAILURE(*status)) { 230 return -1; 231 } 232 if (result == nullptr ? resultLength != 0 : resultLength < 0) { 233 *status = U_ILLEGAL_ARGUMENT_ERROR; 234 return -1; 235 } 236 237 UnicodeString res; 238 if (result != nullptr) { 239 // nullptr destination for pure preflighting: empty dummy string 240 // otherwise, alias the destination buffer 241 res.setTo(result, 0, resultLength); 242 } 243 244 FieldPosition fp; 245 246 if (position != nullptr) 247 fp.setField(position->field); 248 249 ((DateFormat*)format)->format(dateToFormat, res, fp); 250 251 if (position != nullptr) { 252 position->beginIndex = fp.getBeginIndex(); 253 position->endIndex = fp.getEndIndex(); 254 } 255 256 return res.extract(result, resultLength, *status); 257 } 258 259 U_CAPI int32_t U_EXPORT2 260 udat_formatCalendar(const UDateFormat* format, 261 UCalendar* calendar, 262 char16_t* result, 263 int32_t resultLength, 264 UFieldPosition* position, 265 UErrorCode* status) 266 { 267 if(U_FAILURE(*status)) { 268 return -1; 269 } 270 if (result == nullptr ? resultLength != 0 : resultLength < 0) { 271 *status = U_ILLEGAL_ARGUMENT_ERROR; 272 return -1; 273 } 274 275 UnicodeString res; 276 if (result != nullptr) { 277 // nullptr destination for pure preflighting: empty dummy string 278 // otherwise, alias the destination buffer 279 res.setTo(result, 0, resultLength); 280 } 281 282 FieldPosition fp; 283 284 if (position != nullptr) 285 fp.setField(position->field); 286 287 ((DateFormat*)format)->format(*(Calendar*)calendar, res, fp); 288 289 if (position != nullptr) { 290 position->beginIndex = fp.getBeginIndex(); 291 position->endIndex = fp.getEndIndex(); 292 } 293 294 return res.extract(result, resultLength, *status); 295 } 296 297 U_CAPI int32_t U_EXPORT2 298 udat_formatForFields( const UDateFormat* format, 299 UDate dateToFormat, 300 char16_t* result, 301 int32_t resultLength, 302 UFieldPositionIterator* fpositer, 303 UErrorCode* status) 304 { 305 if(U_FAILURE(*status)) { 306 return -1; 307 } 308 if (result == nullptr ? resultLength != 0 : resultLength < 0) { 309 *status = U_ILLEGAL_ARGUMENT_ERROR; 310 return -1; 311 } 312 313 UnicodeString res; 314 if (result != nullptr) { 315 // nullptr destination for pure preflighting: empty dummy string 316 // otherwise, alias the destination buffer 317 res.setTo(result, 0, resultLength); 318 } 319 320 ((DateFormat*)format)->format(dateToFormat, res, (FieldPositionIterator*)fpositer, *status); 321 322 return res.extract(result, resultLength, *status); 323 } 324 325 U_CAPI int32_t U_EXPORT2 326 udat_formatCalendarForFields(const UDateFormat* format, 327 UCalendar* calendar, 328 char16_t* result, 329 int32_t resultLength, 330 UFieldPositionIterator* fpositer, 331 UErrorCode* status) 332 { 333 if(U_FAILURE(*status)) { 334 return -1; 335 } 336 if (result == nullptr ? resultLength != 0 : resultLength < 0) { 337 *status = U_ILLEGAL_ARGUMENT_ERROR; 338 return -1; 339 } 340 341 UnicodeString res; 342 if (result != nullptr) { 343 // nullptr destination for pure preflighting: empty dummy string 344 // otherwise, alias the destination buffer 345 res.setTo(result, 0, resultLength); 346 } 347 348 ((DateFormat*)format)->format(*(Calendar*)calendar, res, (FieldPositionIterator*)fpositer, *status); 349 350 return res.extract(result, resultLength, *status); 351 } 352 353 U_CAPI UDate U_EXPORT2 354 udat_parse( const UDateFormat* format, 355 const char16_t* text, 356 int32_t textLength, 357 int32_t *parsePos, 358 UErrorCode *status) 359 { 360 if(U_FAILURE(*status)) return (UDate)0; 361 362 const UnicodeString src(textLength == -1, text, textLength); 363 ParsePosition pp; 364 int32_t stackParsePos = 0; 365 UDate res; 366 367 if(parsePos == nullptr) { 368 parsePos = &stackParsePos; 369 } 370 371 pp.setIndex(*parsePos); 372 373 res = ((DateFormat*)format)->parse(src, pp); 374 375 if(pp.getErrorIndex() == -1) 376 *parsePos = pp.getIndex(); 377 else { 378 *parsePos = pp.getErrorIndex(); 379 *status = U_PARSE_ERROR; 380 } 381 382 return res; 383 } 384 385 U_CAPI void U_EXPORT2 386 udat_parseCalendar(const UDateFormat* format, 387 UCalendar* calendar, 388 const char16_t* text, 389 int32_t textLength, 390 int32_t *parsePos, 391 UErrorCode *status) 392 { 393 if(U_FAILURE(*status)) return; 394 395 const UnicodeString src(textLength == -1, text, textLength); 396 ParsePosition pp; 397 int32_t stackParsePos = 0; 398 399 if(parsePos == nullptr) { 400 parsePos = &stackParsePos; 401 } 402 403 pp.setIndex(*parsePos); 404 405 ((DateFormat*)format)->parse(src, *(Calendar*)calendar, pp); 406 407 if(pp.getErrorIndex() == -1) 408 *parsePos = pp.getIndex(); 409 else { 410 *parsePos = pp.getErrorIndex(); 411 *status = U_PARSE_ERROR; 412 } 413 } 414 415 U_CAPI UBool U_EXPORT2 416 udat_isLenient(const UDateFormat* fmt) 417 { 418 return ((DateFormat*)fmt)->isLenient(); 419 } 420 421 U_CAPI void U_EXPORT2 422 udat_setLenient( UDateFormat* fmt, 423 UBool isLenient) 424 { 425 ((DateFormat*)fmt)->setLenient(isLenient); 426 } 427 428 U_CAPI UBool U_EXPORT2 429 udat_getBooleanAttribute(const UDateFormat* fmt, 430 UDateFormatBooleanAttribute attr, 431 UErrorCode* status) 432 { 433 if(U_FAILURE(*status)) return false; 434 return ((DateFormat*)fmt)->getBooleanAttribute(attr, *status); 435 //return false; 436 } 437 438 U_CAPI void U_EXPORT2 439 udat_setBooleanAttribute(UDateFormat *fmt, 440 UDateFormatBooleanAttribute attr, 441 UBool newValue, 442 UErrorCode* status) 443 { 444 if(U_FAILURE(*status)) return; 445 ((DateFormat*)fmt)->setBooleanAttribute(attr, newValue, *status); 446 } 447 448 U_CAPI const UCalendar* U_EXPORT2 449 udat_getCalendar(const UDateFormat* fmt) 450 { 451 return (const UCalendar*) ((DateFormat*)fmt)->getCalendar(); 452 } 453 454 U_CAPI void U_EXPORT2 455 udat_setCalendar(UDateFormat* fmt, 456 const UCalendar* calendarToSet) 457 { 458 ((DateFormat*)fmt)->setCalendar(*((Calendar*)calendarToSet)); 459 } 460 461 U_CAPI const UNumberFormat* U_EXPORT2 462 udat_getNumberFormatForField(const UDateFormat* fmt, char16_t field) 463 { 464 UErrorCode status = U_ZERO_ERROR; 465 verifyIsSimpleDateFormat(fmt, &status); 466 if (U_FAILURE(status)) return (const UNumberFormat*) ((DateFormat*)fmt)->getNumberFormat(); 467 return (const UNumberFormat*) ((SimpleDateFormat*)fmt)->getNumberFormatForField(field); 468 } 469 470 U_CAPI const UNumberFormat* U_EXPORT2 471 udat_getNumberFormat(const UDateFormat* fmt) 472 { 473 return (const UNumberFormat*) ((DateFormat*)fmt)->getNumberFormat(); 474 } 475 476 U_CAPI void U_EXPORT2 477 udat_adoptNumberFormatForFields( UDateFormat* fmt, 478 const char16_t* fields, 479 UNumberFormat* numberFormatToSet, 480 UErrorCode* status) 481 { 482 verifyIsSimpleDateFormat(fmt, status); 483 if (U_FAILURE(*status)) return; 484 485 if (fields!=nullptr) { 486 UnicodeString overrideFields(fields); 487 ((SimpleDateFormat*)fmt)->adoptNumberFormat(overrideFields, (NumberFormat*)numberFormatToSet, *status); 488 } 489 } 490 491 U_CAPI void U_EXPORT2 492 udat_setNumberFormat(UDateFormat* fmt, 493 const UNumberFormat* numberFormatToSet) 494 { 495 ((DateFormat*)fmt)->setNumberFormat(*((NumberFormat*)numberFormatToSet)); 496 } 497 498 U_CAPI void U_EXPORT2 499 udat_adoptNumberFormat( UDateFormat* fmt, 500 UNumberFormat* numberFormatToAdopt) 501 { 502 ((DateFormat*)fmt)->adoptNumberFormat((NumberFormat*)numberFormatToAdopt); 503 } 504 505 U_CAPI const char* U_EXPORT2 506 udat_getAvailable(int32_t index) 507 { 508 return uloc_getAvailable(index); 509 } 510 511 U_CAPI int32_t U_EXPORT2 512 udat_countAvailable() 513 { 514 return uloc_countAvailable(); 515 } 516 517 U_CAPI UDate U_EXPORT2 518 udat_get2DigitYearStart( const UDateFormat *fmt, 519 UErrorCode *status) 520 { 521 verifyIsSimpleDateFormat(fmt, status); 522 if(U_FAILURE(*status)) return (UDate)0; 523 return ((SimpleDateFormat*)fmt)->get2DigitYearStart(*status); 524 } 525 526 U_CAPI void U_EXPORT2 527 udat_set2DigitYearStart( UDateFormat *fmt, 528 UDate d, 529 UErrorCode *status) 530 { 531 verifyIsSimpleDateFormat(fmt, status); 532 if(U_FAILURE(*status)) return; 533 ((SimpleDateFormat*)fmt)->set2DigitYearStart(d, *status); 534 } 535 536 U_CAPI int32_t U_EXPORT2 537 udat_toPattern( const UDateFormat *fmt, 538 UBool localized, 539 char16_t *result, 540 int32_t resultLength, 541 UErrorCode *status) 542 { 543 if(U_FAILURE(*status)) { 544 return -1; 545 } 546 if (result == nullptr ? resultLength != 0 : resultLength < 0) { 547 *status = U_ILLEGAL_ARGUMENT_ERROR; 548 return -1; 549 } 550 551 UnicodeString res; 552 if (result != nullptr) { 553 // nullptr destination for pure preflighting: empty dummy string 554 // otherwise, alias the destination buffer 555 res.setTo(result, 0, resultLength); 556 } 557 558 const DateFormat *df=reinterpret_cast<const DateFormat *>(fmt); 559 const SimpleDateFormat *sdtfmt=dynamic_cast<const SimpleDateFormat *>(df); 560 const RelativeDateFormat *reldtfmt; 561 if (sdtfmt!=nullptr) { 562 if(localized) 563 sdtfmt->toLocalizedPattern(res, *status); 564 else 565 sdtfmt->toPattern(res); 566 } else if (!localized && (reldtfmt=dynamic_cast<const RelativeDateFormat *>(df))!=nullptr) { 567 reldtfmt->toPattern(res, *status); 568 } else { 569 *status = U_ILLEGAL_ARGUMENT_ERROR; 570 return -1; 571 } 572 573 return res.extract(result, resultLength, *status); 574 } 575 576 // TODO: should this take an UErrorCode? 577 // A: Yes. Of course. 578 U_CAPI void U_EXPORT2 579 udat_applyPattern( UDateFormat *format, 580 UBool localized, 581 const char16_t *pattern, 582 int32_t patternLength) 583 { 584 const UnicodeString pat(patternLength == -1, pattern, patternLength); 585 UErrorCode status = U_ZERO_ERROR; 586 587 verifyIsSimpleDateFormat(format, &status); 588 if(U_FAILURE(status)) { 589 return; 590 } 591 592 if(localized) 593 ((SimpleDateFormat*)format)->applyLocalizedPattern(pat, status); 594 else 595 ((SimpleDateFormat*)format)->applyPattern(pat); 596 } 597 598 U_CAPI int32_t U_EXPORT2 599 udat_getSymbols(const UDateFormat *fmt, 600 UDateFormatSymbolType type, 601 int32_t index, 602 char16_t *result, 603 int32_t resultLength, 604 UErrorCode *status) 605 { 606 const DateFormatSymbols *syms; 607 const SimpleDateFormat* sdtfmt; 608 const RelativeDateFormat* rdtfmt; 609 if ((sdtfmt = dynamic_cast<const SimpleDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))) != nullptr) { 610 syms = sdtfmt->getDateFormatSymbols(); 611 } else if ((rdtfmt = dynamic_cast<const RelativeDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))) != nullptr) { 612 syms = rdtfmt->getDateFormatSymbols(); 613 } else { 614 return -1; 615 } 616 int32_t count = 0; 617 const UnicodeString *res = nullptr; 618 619 switch(type) { 620 case UDAT_ERAS: 621 res = syms->getEras(count); 622 break; 623 624 case UDAT_ERA_NAMES: 625 res = syms->getEraNames(count); 626 break; 627 628 case UDAT_MONTHS: 629 res = syms->getMonths(count); 630 break; 631 632 case UDAT_SHORT_MONTHS: 633 res = syms->getShortMonths(count); 634 break; 635 636 case UDAT_WEEKDAYS: 637 res = syms->getWeekdays(count); 638 break; 639 640 case UDAT_SHORT_WEEKDAYS: 641 res = syms->getShortWeekdays(count); 642 break; 643 644 case UDAT_AM_PMS: 645 res = syms->getAmPmStrings(count); 646 break; 647 648 case UDAT_AM_PMS_NARROW: 649 res = syms->getAmPmStrings(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW); 650 break; 651 652 case UDAT_AM_PMS_WIDE: 653 res = syms->getAmPmStrings(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE); 654 break; 655 656 case UDAT_LOCALIZED_CHARS: 657 { 658 UnicodeString res1; 659 if(!(result==nullptr && resultLength==0)) { 660 // nullptr destination for pure preflighting: empty dummy string 661 // otherwise, alias the destination buffer 662 res1.setTo(result, 0, resultLength); 663 } 664 syms->getLocalPatternChars(res1); 665 return res1.extract(result, resultLength, *status); 666 } 667 668 case UDAT_NARROW_MONTHS: 669 res = syms->getMonths(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW); 670 break; 671 672 case UDAT_SHORTER_WEEKDAYS: 673 res = syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::SHORT); 674 break; 675 676 case UDAT_NARROW_WEEKDAYS: 677 res = syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW); 678 break; 679 680 case UDAT_STANDALONE_MONTHS: 681 res = syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE); 682 break; 683 684 case UDAT_STANDALONE_SHORT_MONTHS: 685 res = syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED); 686 break; 687 688 case UDAT_STANDALONE_NARROW_MONTHS: 689 res = syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW); 690 break; 691 692 case UDAT_STANDALONE_WEEKDAYS: 693 res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE); 694 break; 695 696 case UDAT_STANDALONE_SHORT_WEEKDAYS: 697 res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED); 698 break; 699 700 case UDAT_STANDALONE_SHORTER_WEEKDAYS: 701 res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::SHORT); 702 break; 703 704 case UDAT_STANDALONE_NARROW_WEEKDAYS: 705 res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW); 706 break; 707 708 case UDAT_QUARTERS: 709 res = syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE); 710 break; 711 712 case UDAT_SHORT_QUARTERS: 713 res = syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED); 714 break; 715 716 case UDAT_NARROW_QUARTERS: 717 res = syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW); 718 break; 719 720 case UDAT_STANDALONE_QUARTERS: 721 res = syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE); 722 break; 723 724 case UDAT_STANDALONE_SHORT_QUARTERS: 725 res = syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED); 726 break; 727 728 case UDAT_STANDALONE_NARROW_QUARTERS: 729 res = syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW); 730 break; 731 732 case UDAT_CYCLIC_YEARS_WIDE: 733 res = syms->getYearNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE); 734 break; 735 736 case UDAT_CYCLIC_YEARS_ABBREVIATED: 737 res = syms->getYearNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED); 738 break; 739 740 case UDAT_CYCLIC_YEARS_NARROW: 741 res = syms->getYearNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW); 742 break; 743 744 case UDAT_ZODIAC_NAMES_WIDE: 745 res = syms->getZodiacNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE); 746 break; 747 748 case UDAT_ZODIAC_NAMES_ABBREVIATED: 749 res = syms->getZodiacNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED); 750 break; 751 752 case UDAT_ZODIAC_NAMES_NARROW: 753 res = syms->getZodiacNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW); 754 break; 755 756 } 757 758 if(index < count) { 759 return res[index].extract(result, resultLength, *status); 760 } 761 return 0; 762 } 763 764 // TODO: also needs an errorCode. 765 U_CAPI int32_t U_EXPORT2 766 udat_countSymbols( const UDateFormat *fmt, 767 UDateFormatSymbolType type) 768 { 769 const DateFormatSymbols *syms; 770 const SimpleDateFormat* sdtfmt; 771 const RelativeDateFormat* rdtfmt; 772 if ((sdtfmt = dynamic_cast<const SimpleDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))) != nullptr) { 773 syms = sdtfmt->getDateFormatSymbols(); 774 } else if ((rdtfmt = dynamic_cast<const RelativeDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))) != nullptr) { 775 syms = rdtfmt->getDateFormatSymbols(); 776 } else { 777 return 0; 778 } 779 int32_t count = 0; 780 781 switch(type) { 782 case UDAT_ERAS: 783 syms->getEras(count); 784 break; 785 786 case UDAT_MONTHS: 787 syms->getMonths(count); 788 break; 789 790 case UDAT_SHORT_MONTHS: 791 syms->getShortMonths(count); 792 break; 793 794 case UDAT_WEEKDAYS: 795 syms->getWeekdays(count); 796 break; 797 798 case UDAT_SHORT_WEEKDAYS: 799 syms->getShortWeekdays(count); 800 break; 801 802 case UDAT_AM_PMS: 803 syms->getAmPmStrings(count); 804 break; 805 806 case UDAT_AM_PMS_NARROW: 807 syms->getAmPmStrings(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW); 808 break; 809 810 case UDAT_AM_PMS_WIDE: 811 syms->getAmPmStrings(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE); 812 break; 813 814 case UDAT_LOCALIZED_CHARS: 815 count = 1; 816 break; 817 818 case UDAT_ERA_NAMES: 819 syms->getEraNames(count); 820 break; 821 822 case UDAT_NARROW_MONTHS: 823 syms->getMonths(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW); 824 break; 825 826 case UDAT_SHORTER_WEEKDAYS: 827 syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::SHORT); 828 break; 829 830 case UDAT_NARROW_WEEKDAYS: 831 syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW); 832 break; 833 834 case UDAT_STANDALONE_MONTHS: 835 syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE); 836 break; 837 838 case UDAT_STANDALONE_SHORT_MONTHS: 839 syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED); 840 break; 841 842 case UDAT_STANDALONE_NARROW_MONTHS: 843 syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW); 844 break; 845 846 case UDAT_STANDALONE_WEEKDAYS: 847 syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE); 848 break; 849 850 case UDAT_STANDALONE_SHORT_WEEKDAYS: 851 syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED); 852 break; 853 854 case UDAT_STANDALONE_SHORTER_WEEKDAYS: 855 syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::SHORT); 856 break; 857 858 case UDAT_STANDALONE_NARROW_WEEKDAYS: 859 syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW); 860 break; 861 862 case UDAT_QUARTERS: 863 syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE); 864 break; 865 866 case UDAT_SHORT_QUARTERS: 867 syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED); 868 break; 869 870 case UDAT_NARROW_QUARTERS: 871 syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW); 872 break; 873 874 case UDAT_STANDALONE_QUARTERS: 875 syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE); 876 break; 877 878 case UDAT_STANDALONE_SHORT_QUARTERS: 879 syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED); 880 break; 881 882 case UDAT_STANDALONE_NARROW_QUARTERS: 883 syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW); 884 break; 885 886 case UDAT_CYCLIC_YEARS_WIDE: 887 syms->getYearNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE); 888 break; 889 890 case UDAT_CYCLIC_YEARS_ABBREVIATED: 891 syms->getYearNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED); 892 break; 893 894 case UDAT_CYCLIC_YEARS_NARROW: 895 syms->getYearNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW); 896 break; 897 898 case UDAT_ZODIAC_NAMES_WIDE: 899 syms->getZodiacNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE); 900 break; 901 902 case UDAT_ZODIAC_NAMES_ABBREVIATED: 903 syms->getZodiacNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED); 904 break; 905 906 case UDAT_ZODIAC_NAMES_NARROW: 907 syms->getZodiacNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW); 908 break; 909 910 } 911 912 return count; 913 } 914 915 U_NAMESPACE_BEGIN 916 917 /* 918 * This DateFormatSymbolsSingleSetter class is a friend of DateFormatSymbols 919 * solely for the purpose of avoiding to clone the array of strings 920 * just to modify one of them and then setting all of them back. 921 * For example, the old code looked like this: 922 * case UDAT_MONTHS: 923 * res = syms->getMonths(count); 924 * array = new UnicodeString[count]; 925 * if(array == 0) { 926 * *status = U_MEMORY_ALLOCATION_ERROR; 927 * return; 928 * } 929 * uprv_arrayCopy(res, array, count); 930 * if(index < count) 931 * array[index] = val; 932 * syms->setMonths(array, count); 933 * break; 934 * 935 * Even worse, the old code actually cloned the entire DateFormatSymbols object, 936 * cloned one value array, changed one value, and then made the SimpleDateFormat 937 * replace its DateFormatSymbols object with the new one. 938 * 939 * markus 2002-oct-14 940 */ 941 class DateFormatSymbolsSingleSetter /* not : public UObject because all methods are static */ { 942 public: 943 static void 944 setSymbol(UnicodeString *array, int32_t count, int32_t index, 945 const char16_t *value, int32_t valueLength, UErrorCode &errorCode) 946 { 947 if(array!=nullptr) { 948 if(index>=count) { 949 errorCode=U_INDEX_OUTOFBOUNDS_ERROR; 950 } else if(value==nullptr) { 951 errorCode=U_ILLEGAL_ARGUMENT_ERROR; 952 } else { 953 array[index].setTo(value, valueLength); 954 } 955 } 956 } 957 958 static void 959 setEra(DateFormatSymbols *syms, int32_t index, 960 const char16_t *value, int32_t valueLength, UErrorCode &errorCode) 961 { 962 setSymbol(syms->fEras, syms->fErasCount, index, value, valueLength, errorCode); 963 } 964 965 static void 966 setEraName(DateFormatSymbols *syms, int32_t index, 967 const char16_t *value, int32_t valueLength, UErrorCode &errorCode) 968 { 969 setSymbol(syms->fEraNames, syms->fEraNamesCount, index, value, valueLength, errorCode); 970 } 971 972 static void 973 setMonth(DateFormatSymbols *syms, int32_t index, 974 const char16_t *value, int32_t valueLength, UErrorCode &errorCode) 975 { 976 setSymbol(syms->fMonths, syms->fMonthsCount, index, value, valueLength, errorCode); 977 } 978 979 static void 980 setShortMonth(DateFormatSymbols *syms, int32_t index, 981 const char16_t *value, int32_t valueLength, UErrorCode &errorCode) 982 { 983 setSymbol(syms->fShortMonths, syms->fShortMonthsCount, index, value, valueLength, errorCode); 984 } 985 986 static void 987 setNarrowMonth(DateFormatSymbols *syms, int32_t index, 988 const char16_t *value, int32_t valueLength, UErrorCode &errorCode) 989 { 990 setSymbol(syms->fNarrowMonths, syms->fNarrowMonthsCount, index, value, valueLength, errorCode); 991 } 992 993 static void 994 setStandaloneMonth(DateFormatSymbols *syms, int32_t index, 995 const char16_t *value, int32_t valueLength, UErrorCode &errorCode) 996 { 997 setSymbol(syms->fStandaloneMonths, syms->fStandaloneMonthsCount, index, value, valueLength, errorCode); 998 } 999 1000 static void 1001 setStandaloneShortMonth(DateFormatSymbols *syms, int32_t index, 1002 const char16_t *value, int32_t valueLength, UErrorCode &errorCode) 1003 { 1004 setSymbol(syms->fStandaloneShortMonths, syms->fStandaloneShortMonthsCount, index, value, valueLength, errorCode); 1005 } 1006 1007 static void 1008 setStandaloneNarrowMonth(DateFormatSymbols *syms, int32_t index, 1009 const char16_t *value, int32_t valueLength, UErrorCode &errorCode) 1010 { 1011 setSymbol(syms->fStandaloneNarrowMonths, syms->fStandaloneNarrowMonthsCount, index, value, valueLength, errorCode); 1012 } 1013 1014 static void 1015 setWeekday(DateFormatSymbols *syms, int32_t index, 1016 const char16_t *value, int32_t valueLength, UErrorCode &errorCode) 1017 { 1018 setSymbol(syms->fWeekdays, syms->fWeekdaysCount, index, value, valueLength, errorCode); 1019 } 1020 1021 static void 1022 setShortWeekday(DateFormatSymbols *syms, int32_t index, 1023 const char16_t *value, int32_t valueLength, UErrorCode &errorCode) 1024 { 1025 setSymbol(syms->fShortWeekdays, syms->fShortWeekdaysCount, index, value, valueLength, errorCode); 1026 } 1027 1028 static void 1029 setShorterWeekday(DateFormatSymbols *syms, int32_t index, 1030 const char16_t *value, int32_t valueLength, UErrorCode &errorCode) 1031 { 1032 setSymbol(syms->fShorterWeekdays, syms->fShorterWeekdaysCount, index, value, valueLength, errorCode); 1033 } 1034 1035 static void 1036 setNarrowWeekday(DateFormatSymbols *syms, int32_t index, 1037 const char16_t *value, int32_t valueLength, UErrorCode &errorCode) 1038 { 1039 setSymbol(syms->fNarrowWeekdays, syms->fNarrowWeekdaysCount, index, value, valueLength, errorCode); 1040 } 1041 1042 static void 1043 setStandaloneWeekday(DateFormatSymbols *syms, int32_t index, 1044 const char16_t *value, int32_t valueLength, UErrorCode &errorCode) 1045 { 1046 setSymbol(syms->fStandaloneWeekdays, syms->fStandaloneWeekdaysCount, index, value, valueLength, errorCode); 1047 } 1048 1049 static void 1050 setStandaloneShortWeekday(DateFormatSymbols *syms, int32_t index, 1051 const char16_t *value, int32_t valueLength, UErrorCode &errorCode) 1052 { 1053 setSymbol(syms->fStandaloneShortWeekdays, syms->fStandaloneShortWeekdaysCount, index, value, valueLength, errorCode); 1054 } 1055 1056 static void 1057 setStandaloneShorterWeekday(DateFormatSymbols *syms, int32_t index, 1058 const char16_t *value, int32_t valueLength, UErrorCode &errorCode) 1059 { 1060 setSymbol(syms->fStandaloneShorterWeekdays, syms->fStandaloneShorterWeekdaysCount, index, value, valueLength, errorCode); 1061 } 1062 1063 static void 1064 setStandaloneNarrowWeekday(DateFormatSymbols *syms, int32_t index, 1065 const char16_t *value, int32_t valueLength, UErrorCode &errorCode) 1066 { 1067 setSymbol(syms->fStandaloneNarrowWeekdays, syms->fStandaloneNarrowWeekdaysCount, index, value, valueLength, errorCode); 1068 } 1069 1070 static void 1071 setQuarter(DateFormatSymbols *syms, int32_t index, 1072 const char16_t *value, int32_t valueLength, UErrorCode &errorCode) 1073 { 1074 setSymbol(syms->fQuarters, syms->fQuartersCount, index, value, valueLength, errorCode); 1075 } 1076 1077 static void 1078 setShortQuarter(DateFormatSymbols *syms, int32_t index, 1079 const char16_t *value, int32_t valueLength, UErrorCode &errorCode) 1080 { 1081 setSymbol(syms->fShortQuarters, syms->fShortQuartersCount, index, value, valueLength, errorCode); 1082 } 1083 1084 static void 1085 setNarrowQuarter(DateFormatSymbols *syms, int32_t index, 1086 const char16_t *value, int32_t valueLength, UErrorCode &errorCode) 1087 { 1088 setSymbol(syms->fNarrowQuarters, syms->fNarrowQuartersCount, index, value, valueLength, errorCode); 1089 } 1090 1091 static void 1092 setStandaloneQuarter(DateFormatSymbols *syms, int32_t index, 1093 const char16_t *value, int32_t valueLength, UErrorCode &errorCode) 1094 { 1095 setSymbol(syms->fStandaloneQuarters, syms->fStandaloneQuartersCount, index, value, valueLength, errorCode); 1096 } 1097 1098 static void 1099 setStandaloneShortQuarter(DateFormatSymbols *syms, int32_t index, 1100 const char16_t *value, int32_t valueLength, UErrorCode &errorCode) 1101 { 1102 setSymbol(syms->fStandaloneShortQuarters, syms->fStandaloneShortQuartersCount, index, value, valueLength, errorCode); 1103 } 1104 1105 static void 1106 setStandaloneNarrowQuarter(DateFormatSymbols *syms, int32_t index, 1107 const char16_t *value, int32_t valueLength, UErrorCode &errorCode) 1108 { 1109 setSymbol(syms->fStandaloneNarrowQuarters, syms->fStandaloneNarrowQuartersCount, index, value, valueLength, errorCode); 1110 } 1111 1112 static void 1113 setShortYearNames(DateFormatSymbols *syms, int32_t index, 1114 const char16_t *value, int32_t valueLength, UErrorCode &errorCode) 1115 { 1116 setSymbol(syms->fShortYearNames, syms->fShortYearNamesCount, index, value, valueLength, errorCode); 1117 } 1118 1119 static void 1120 setShortZodiacNames(DateFormatSymbols *syms, int32_t index, 1121 const char16_t *value, int32_t valueLength, UErrorCode &errorCode) 1122 { 1123 setSymbol(syms->fShortZodiacNames, syms->fShortZodiacNamesCount, index, value, valueLength, errorCode); 1124 } 1125 1126 static void 1127 setAmPm(DateFormatSymbols *syms, int32_t index, 1128 const char16_t *value, int32_t valueLength, UErrorCode &errorCode) 1129 { 1130 setSymbol(syms->fAmPms, syms->fAmPmsCount, index, value, valueLength, errorCode); 1131 } 1132 1133 static void 1134 setAmPmNarrow(DateFormatSymbols *syms, int32_t index, 1135 const char16_t *value, int32_t valueLength, UErrorCode &errorCode) 1136 { 1137 setSymbol(syms->fNarrowAmPms, syms->fNarrowAmPmsCount, index, value, valueLength, errorCode); 1138 } 1139 1140 static void 1141 setAmPmWide(DateFormatSymbols *syms, int32_t index, 1142 const char16_t *value, int32_t valueLength, UErrorCode &errorCode) 1143 { 1144 setSymbol(syms->fWideAmPms, syms->fWideAmPmsCount, index, value, valueLength, errorCode); 1145 } 1146 1147 static void 1148 setLocalPatternChars(DateFormatSymbols *syms, 1149 const char16_t *value, int32_t valueLength, UErrorCode &errorCode) 1150 { 1151 setSymbol(&syms->fLocalPatternChars, 1, 0, value, valueLength, errorCode); 1152 } 1153 }; 1154 1155 U_NAMESPACE_END 1156 1157 U_CAPI void U_EXPORT2 1158 udat_setSymbols( UDateFormat *format, 1159 UDateFormatSymbolType type, 1160 int32_t index, 1161 char16_t *value, 1162 int32_t valueLength, 1163 UErrorCode *status) 1164 { 1165 verifyIsSimpleDateFormat(format, status); 1166 if(U_FAILURE(*status)) return; 1167 1168 DateFormatSymbols *syms = (DateFormatSymbols *)((SimpleDateFormat *)format)->getDateFormatSymbols(); 1169 1170 switch(type) { 1171 case UDAT_ERAS: 1172 DateFormatSymbolsSingleSetter::setEra(syms, index, value, valueLength, *status); 1173 break; 1174 1175 case UDAT_ERA_NAMES: 1176 DateFormatSymbolsSingleSetter::setEraName(syms, index, value, valueLength, *status); 1177 break; 1178 1179 case UDAT_MONTHS: 1180 DateFormatSymbolsSingleSetter::setMonth(syms, index, value, valueLength, *status); 1181 break; 1182 1183 case UDAT_SHORT_MONTHS: 1184 DateFormatSymbolsSingleSetter::setShortMonth(syms, index, value, valueLength, *status); 1185 break; 1186 1187 case UDAT_NARROW_MONTHS: 1188 DateFormatSymbolsSingleSetter::setNarrowMonth(syms, index, value, valueLength, *status); 1189 break; 1190 1191 case UDAT_STANDALONE_MONTHS: 1192 DateFormatSymbolsSingleSetter::setStandaloneMonth(syms, index, value, valueLength, *status); 1193 break; 1194 1195 case UDAT_STANDALONE_SHORT_MONTHS: 1196 DateFormatSymbolsSingleSetter::setStandaloneShortMonth(syms, index, value, valueLength, *status); 1197 break; 1198 1199 case UDAT_STANDALONE_NARROW_MONTHS: 1200 DateFormatSymbolsSingleSetter::setStandaloneNarrowMonth(syms, index, value, valueLength, *status); 1201 break; 1202 1203 case UDAT_WEEKDAYS: 1204 DateFormatSymbolsSingleSetter::setWeekday(syms, index, value, valueLength, *status); 1205 break; 1206 1207 case UDAT_SHORT_WEEKDAYS: 1208 DateFormatSymbolsSingleSetter::setShortWeekday(syms, index, value, valueLength, *status); 1209 break; 1210 1211 case UDAT_SHORTER_WEEKDAYS: 1212 DateFormatSymbolsSingleSetter::setShorterWeekday(syms, index, value, valueLength, *status); 1213 break; 1214 1215 case UDAT_NARROW_WEEKDAYS: 1216 DateFormatSymbolsSingleSetter::setNarrowWeekday(syms, index, value, valueLength, *status); 1217 break; 1218 1219 case UDAT_STANDALONE_WEEKDAYS: 1220 DateFormatSymbolsSingleSetter::setStandaloneWeekday(syms, index, value, valueLength, *status); 1221 break; 1222 1223 case UDAT_STANDALONE_SHORT_WEEKDAYS: 1224 DateFormatSymbolsSingleSetter::setStandaloneShortWeekday(syms, index, value, valueLength, *status); 1225 break; 1226 1227 case UDAT_STANDALONE_SHORTER_WEEKDAYS: 1228 DateFormatSymbolsSingleSetter::setStandaloneShorterWeekday(syms, index, value, valueLength, *status); 1229 break; 1230 1231 case UDAT_STANDALONE_NARROW_WEEKDAYS: 1232 DateFormatSymbolsSingleSetter::setStandaloneNarrowWeekday(syms, index, value, valueLength, *status); 1233 break; 1234 1235 case UDAT_QUARTERS: 1236 DateFormatSymbolsSingleSetter::setQuarter(syms, index, value, valueLength, *status); 1237 break; 1238 1239 case UDAT_SHORT_QUARTERS: 1240 DateFormatSymbolsSingleSetter::setShortQuarter(syms, index, value, valueLength, *status); 1241 break; 1242 1243 case UDAT_NARROW_QUARTERS: 1244 DateFormatSymbolsSingleSetter::setNarrowQuarter(syms, index, value, valueLength, *status); 1245 break; 1246 1247 case UDAT_STANDALONE_QUARTERS: 1248 DateFormatSymbolsSingleSetter::setStandaloneQuarter(syms, index, value, valueLength, *status); 1249 break; 1250 1251 case UDAT_STANDALONE_SHORT_QUARTERS: 1252 DateFormatSymbolsSingleSetter::setStandaloneShortQuarter(syms, index, value, valueLength, *status); 1253 break; 1254 1255 case UDAT_STANDALONE_NARROW_QUARTERS: 1256 DateFormatSymbolsSingleSetter::setStandaloneNarrowQuarter(syms, index, value, valueLength, *status); 1257 break; 1258 1259 case UDAT_CYCLIC_YEARS_ABBREVIATED: 1260 DateFormatSymbolsSingleSetter::setShortYearNames(syms, index, value, valueLength, *status); 1261 break; 1262 1263 case UDAT_ZODIAC_NAMES_ABBREVIATED: 1264 DateFormatSymbolsSingleSetter::setShortZodiacNames(syms, index, value, valueLength, *status); 1265 break; 1266 1267 case UDAT_AM_PMS: 1268 DateFormatSymbolsSingleSetter::setAmPm(syms, index, value, valueLength, *status); 1269 break; 1270 1271 case UDAT_AM_PMS_NARROW: 1272 DateFormatSymbolsSingleSetter::setAmPmNarrow(syms, index, value, valueLength, *status); 1273 break; 1274 1275 case UDAT_AM_PMS_WIDE: 1276 DateFormatSymbolsSingleSetter::setAmPmWide(syms, index, value, valueLength, *status); 1277 break; 1278 1279 case UDAT_LOCALIZED_CHARS: 1280 DateFormatSymbolsSingleSetter::setLocalPatternChars(syms, value, valueLength, *status); 1281 break; 1282 1283 default: 1284 *status = U_UNSUPPORTED_ERROR; 1285 break; 1286 1287 } 1288 } 1289 1290 U_CAPI const char* U_EXPORT2 1291 udat_getLocaleByType(const UDateFormat *fmt, 1292 ULocDataLocaleType type, 1293 UErrorCode* status) 1294 { 1295 if (fmt == nullptr) { 1296 if (U_SUCCESS(*status)) { 1297 *status = U_ILLEGAL_ARGUMENT_ERROR; 1298 } 1299 return nullptr; 1300 } 1301 return ((Format*)fmt)->getLocaleID(type, *status); 1302 } 1303 1304 U_CAPI void U_EXPORT2 1305 udat_setContext(UDateFormat* fmt, UDisplayContext value, UErrorCode* status) 1306 { 1307 if (U_FAILURE(*status)) { 1308 return; 1309 } 1310 ((DateFormat*)fmt)->setContext(value, *status); 1311 } 1312 1313 U_CAPI UDisplayContext U_EXPORT2 1314 udat_getContext(const UDateFormat* fmt, UDisplayContextType type, UErrorCode* status) 1315 { 1316 if (U_FAILURE(*status)) { 1317 return (UDisplayContext)0; 1318 } 1319 return ((const DateFormat*)fmt)->getContext(type, *status); 1320 } 1321 1322 1323 /** 1324 * Verify that fmt is a RelativeDateFormat. Invalid error if not. 1325 * @param fmt the UDateFormat, definitely a DateFormat, maybe something else 1326 * @param status error code, will be set to failure if there is a failure or the fmt is nullptr. 1327 */ 1328 static void verifyIsRelativeDateFormat(const UDateFormat* fmt, UErrorCode *status) { 1329 if(U_SUCCESS(*status) && 1330 dynamic_cast<const RelativeDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))==nullptr) { 1331 *status = U_ILLEGAL_ARGUMENT_ERROR; 1332 } 1333 } 1334 1335 1336 U_CAPI int32_t U_EXPORT2 1337 udat_toPatternRelativeDate(const UDateFormat *fmt, 1338 char16_t *result, 1339 int32_t resultLength, 1340 UErrorCode *status) 1341 { 1342 verifyIsRelativeDateFormat(fmt, status); 1343 if(U_FAILURE(*status)) { 1344 return -1; 1345 } 1346 if (result == nullptr ? resultLength != 0 : resultLength < 0) { 1347 *status = U_ILLEGAL_ARGUMENT_ERROR; 1348 return -1; 1349 } 1350 1351 UnicodeString datePattern; 1352 if (result != nullptr) { 1353 // nullptr destination for pure preflighting: empty dummy string 1354 // otherwise, alias the destination buffer 1355 datePattern.setTo(result, 0, resultLength); 1356 } 1357 ((RelativeDateFormat*)fmt)->toPatternDate(datePattern, *status); 1358 return datePattern.extract(result, resultLength, *status); 1359 } 1360 1361 U_CAPI int32_t U_EXPORT2 1362 udat_toPatternRelativeTime(const UDateFormat *fmt, 1363 char16_t *result, 1364 int32_t resultLength, 1365 UErrorCode *status) 1366 { 1367 verifyIsRelativeDateFormat(fmt, status); 1368 if(U_FAILURE(*status)) { 1369 return -1; 1370 } 1371 if (result == nullptr ? resultLength != 0 : resultLength < 0) { 1372 *status = U_ILLEGAL_ARGUMENT_ERROR; 1373 return -1; 1374 } 1375 1376 UnicodeString timePattern; 1377 if (result != nullptr) { 1378 // nullptr destination for pure preflighting: empty dummy string 1379 // otherwise, alias the destination buffer 1380 timePattern.setTo(result, 0, resultLength); 1381 } 1382 ((RelativeDateFormat*)fmt)->toPatternTime(timePattern, *status); 1383 return timePattern.extract(result, resultLength, *status); 1384 } 1385 1386 U_CAPI void U_EXPORT2 1387 udat_applyPatternRelative(UDateFormat *format, 1388 const char16_t *datePattern, 1389 int32_t datePatternLength, 1390 const char16_t *timePattern, 1391 int32_t timePatternLength, 1392 UErrorCode *status) 1393 { 1394 verifyIsRelativeDateFormat(format, status); 1395 if(U_FAILURE(*status)) return; 1396 const UnicodeString datePat(datePatternLength == -1, datePattern, datePatternLength); 1397 const UnicodeString timePat(timePatternLength == -1, timePattern, timePatternLength); 1398 ((RelativeDateFormat*)format)->applyPatterns(datePat, timePat, *status); 1399 } 1400 1401 #endif /* #if !UCONFIG_NO_FORMATTING */