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