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