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