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