OLD | NEW |
(Empty) | |
| 1 /* |
| 2 ******************************************************************************* |
| 3 * Copyright (C) 1996-2010, 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 th
e fmt is NULL. |
| 33 */ |
| 34 static void verifyIsSimpleDateFormat(const UDateFormat* fmt, UErrorCode *status)
{ |
| 35 if(U_SUCCESS(*status) && |
| 36 dynamic_cast<const SimpleDateFormat*>(reinterpret_cast<const DateFormat*>
(fmt))==NULL) { |
| 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)dateSty
le, |
| 102 (DateFormat::EStyle)timeStyle); |
| 103 } |
| 104 else { |
| 105 fmt = DateFormat::createDateTimeInstance((DateFormat::EStyle)dateSty
le, |
| 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)(tzIDLeng
th == -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 const DateFormat *df=reinterpret_cast<const DateFormat *>(fmt); |
| 341 const SimpleDateFormat *sdtfmt=dynamic_cast<const SimpleDateFormat *>(df); |
| 342 const RelativeDateFormat *reldtfmt; |
| 343 if (sdtfmt!=NULL) { |
| 344 if(localized) |
| 345 sdtfmt->toLocalizedPattern(res, *status); |
| 346 else |
| 347 sdtfmt->toPattern(res); |
| 348 } else if (!localized && (reldtfmt=dynamic_cast<const RelativeDateFormat *>(
df))!=NULL) { |
| 349 reldtfmt->toPattern(res, *status); |
| 350 } else { |
| 351 *status = U_ILLEGAL_ARGUMENT_ERROR; |
| 352 return -1; |
| 353 } |
| 354 |
| 355 return res.extract(result, resultLength, *status); |
| 356 } |
| 357 |
| 358 // TODO: should this take an UErrorCode? |
| 359 // A: Yes. Of course. |
| 360 U_CAPI void U_EXPORT2 |
| 361 udat_applyPattern( UDateFormat *format, |
| 362 UBool localized, |
| 363 const UChar *pattern, |
| 364 int32_t patternLength) |
| 365 { |
| 366 const UnicodeString pat((UBool)(patternLength == -1), pattern, patternLength
); |
| 367 UErrorCode status = U_ZERO_ERROR; |
| 368 |
| 369 verifyIsSimpleDateFormat(format, &status); |
| 370 if(U_FAILURE(status)) { |
| 371 return; |
| 372 } |
| 373 |
| 374 if(localized) |
| 375 ((SimpleDateFormat*)format)->applyLocalizedPattern(pat, status); |
| 376 else |
| 377 ((SimpleDateFormat*)format)->applyPattern(pat); |
| 378 } |
| 379 |
| 380 U_CAPI int32_t U_EXPORT2 |
| 381 udat_getSymbols(const UDateFormat *fmt, |
| 382 UDateFormatSymbolType type, |
| 383 int32_t index, |
| 384 UChar *result, |
| 385 int32_t resultLength, |
| 386 UErrorCode *status) |
| 387 { |
| 388 verifyIsSimpleDateFormat(fmt, status); |
| 389 if(U_FAILURE(*status)) return -1; |
| 390 |
| 391 const DateFormatSymbols *syms = |
| 392 ((SimpleDateFormat*)fmt)->getDateFormatSymbols(); |
| 393 int32_t count; |
| 394 const UnicodeString *res = NULL; |
| 395 |
| 396 switch(type) { |
| 397 case UDAT_ERAS: |
| 398 res = syms->getEras(count); |
| 399 break; |
| 400 |
| 401 case UDAT_ERA_NAMES: |
| 402 res = syms->getEraNames(count); |
| 403 break; |
| 404 |
| 405 case UDAT_MONTHS: |
| 406 res = syms->getMonths(count); |
| 407 break; |
| 408 |
| 409 case UDAT_SHORT_MONTHS: |
| 410 res = syms->getShortMonths(count); |
| 411 break; |
| 412 |
| 413 case UDAT_WEEKDAYS: |
| 414 res = syms->getWeekdays(count); |
| 415 break; |
| 416 |
| 417 case UDAT_SHORT_WEEKDAYS: |
| 418 res = syms->getShortWeekdays(count); |
| 419 break; |
| 420 |
| 421 case UDAT_AM_PMS: |
| 422 res = syms->getAmPmStrings(count); |
| 423 break; |
| 424 |
| 425 case UDAT_LOCALIZED_CHARS: |
| 426 { |
| 427 UnicodeString res1; |
| 428 if(!(result==NULL && resultLength==0)) { |
| 429 // NULL destination for pure preflighting: empty dummy string |
| 430 // otherwise, alias the destination buffer |
| 431 res1.setTo(result, 0, resultLength); |
| 432 } |
| 433 syms->getLocalPatternChars(res1); |
| 434 return res1.extract(result, resultLength, *status); |
| 435 } |
| 436 |
| 437 case UDAT_NARROW_MONTHS: |
| 438 res = syms->getMonths(count, DateFormatSymbols::FORMAT, DateFormatSymbol
s::NARROW); |
| 439 break; |
| 440 |
| 441 case UDAT_NARROW_WEEKDAYS: |
| 442 res = syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymb
ols::NARROW); |
| 443 break; |
| 444 |
| 445 case UDAT_STANDALONE_MONTHS: |
| 446 res = syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSy
mbols::WIDE); |
| 447 break; |
| 448 |
| 449 case UDAT_STANDALONE_SHORT_MONTHS: |
| 450 res = syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSy
mbols::ABBREVIATED); |
| 451 break; |
| 452 |
| 453 case UDAT_STANDALONE_NARROW_MONTHS: |
| 454 res = syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSy
mbols::NARROW); |
| 455 break; |
| 456 |
| 457 case UDAT_STANDALONE_WEEKDAYS: |
| 458 res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormat
Symbols::WIDE); |
| 459 break; |
| 460 |
| 461 case UDAT_STANDALONE_SHORT_WEEKDAYS: |
| 462 res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormat
Symbols::ABBREVIATED); |
| 463 break; |
| 464 |
| 465 case UDAT_STANDALONE_NARROW_WEEKDAYS: |
| 466 res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormat
Symbols::NARROW); |
| 467 break; |
| 468 |
| 469 case UDAT_QUARTERS: |
| 470 res = syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymb
ols::WIDE); |
| 471 break; |
| 472 |
| 473 case UDAT_SHORT_QUARTERS: |
| 474 res = syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymb
ols::ABBREVIATED); |
| 475 break; |
| 476 |
| 477 case UDAT_STANDALONE_QUARTERS: |
| 478 res = syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormat
Symbols::WIDE); |
| 479 break; |
| 480 |
| 481 case UDAT_STANDALONE_SHORT_QUARTERS: |
| 482 res = syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormat
Symbols::ABBREVIATED); |
| 483 break; |
| 484 |
| 485 } |
| 486 |
| 487 if(index < count) { |
| 488 return res[index].extract(result, resultLength, *status); |
| 489 } |
| 490 return 0; |
| 491 } |
| 492 |
| 493 // TODO: also needs an errorCode. |
| 494 U_CAPI int32_t U_EXPORT2 |
| 495 udat_countSymbols( const UDateFormat *fmt, |
| 496 UDateFormatSymbolType type) |
| 497 { |
| 498 UErrorCode status = U_ZERO_ERROR; |
| 499 |
| 500 verifyIsSimpleDateFormat(fmt, &status); |
| 501 if(U_FAILURE(status)) { |
| 502 return 0; |
| 503 } |
| 504 |
| 505 const DateFormatSymbols *syms = |
| 506 ((SimpleDateFormat*)fmt)->getDateFormatSymbols(); |
| 507 int32_t count = 0; |
| 508 |
| 509 switch(type) { |
| 510 case UDAT_ERAS: |
| 511 syms->getEras(count); |
| 512 break; |
| 513 |
| 514 case UDAT_MONTHS: |
| 515 syms->getMonths(count); |
| 516 break; |
| 517 |
| 518 case UDAT_SHORT_MONTHS: |
| 519 syms->getShortMonths(count); |
| 520 break; |
| 521 |
| 522 case UDAT_WEEKDAYS: |
| 523 syms->getWeekdays(count); |
| 524 break; |
| 525 |
| 526 case UDAT_SHORT_WEEKDAYS: |
| 527 syms->getShortWeekdays(count); |
| 528 break; |
| 529 |
| 530 case UDAT_AM_PMS: |
| 531 syms->getAmPmStrings(count); |
| 532 break; |
| 533 |
| 534 case UDAT_LOCALIZED_CHARS: |
| 535 count = 1; |
| 536 break; |
| 537 |
| 538 case UDAT_ERA_NAMES: |
| 539 syms->getEraNames(count); |
| 540 break; |
| 541 |
| 542 case UDAT_NARROW_MONTHS: |
| 543 syms->getMonths(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NAR
ROW); |
| 544 break; |
| 545 |
| 546 case UDAT_NARROW_WEEKDAYS: |
| 547 syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::N
ARROW); |
| 548 break; |
| 549 |
| 550 case UDAT_STANDALONE_MONTHS: |
| 551 syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols:
:WIDE); |
| 552 break; |
| 553 |
| 554 case UDAT_STANDALONE_SHORT_MONTHS: |
| 555 syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols:
:ABBREVIATED); |
| 556 break; |
| 557 |
| 558 case UDAT_STANDALONE_NARROW_MONTHS: |
| 559 syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols:
:NARROW); |
| 560 break; |
| 561 |
| 562 case UDAT_STANDALONE_WEEKDAYS: |
| 563 syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbol
s::WIDE); |
| 564 break; |
| 565 |
| 566 case UDAT_STANDALONE_SHORT_WEEKDAYS: |
| 567 syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbol
s::ABBREVIATED); |
| 568 break; |
| 569 |
| 570 case UDAT_STANDALONE_NARROW_WEEKDAYS: |
| 571 syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbol
s::NARROW); |
| 572 break; |
| 573 |
| 574 case UDAT_QUARTERS: |
| 575 syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::W
IDE); |
| 576 break; |
| 577 |
| 578 case UDAT_SHORT_QUARTERS: |
| 579 syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::A
BBREVIATED); |
| 580 break; |
| 581 |
| 582 case UDAT_STANDALONE_QUARTERS: |
| 583 syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbol
s::WIDE); |
| 584 break; |
| 585 |
| 586 case UDAT_STANDALONE_SHORT_QUARTERS: |
| 587 syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbol
s::ABBREVIATED); |
| 588 break; |
| 589 |
| 590 } |
| 591 |
| 592 return count; |
| 593 } |
| 594 |
| 595 U_NAMESPACE_BEGIN |
| 596 |
| 597 /* |
| 598 * This DateFormatSymbolsSingleSetter class is a friend of DateFormatSymbols |
| 599 * solely for the purpose of avoiding to clone the array of strings |
| 600 * just to modify one of them and then setting all of them back. |
| 601 * For example, the old code looked like this: |
| 602 * case UDAT_MONTHS: |
| 603 * res = syms->getMonths(count); |
| 604 * array = new UnicodeString[count]; |
| 605 * if(array == 0) { |
| 606 * *status = U_MEMORY_ALLOCATION_ERROR; |
| 607 * return; |
| 608 * } |
| 609 * uprv_arrayCopy(res, array, count); |
| 610 * if(index < count) |
| 611 * array[index] = val; |
| 612 * syms->setMonths(array, count); |
| 613 * break; |
| 614 * |
| 615 * Even worse, the old code actually cloned the entire DateFormatSymbols object, |
| 616 * cloned one value array, changed one value, and then made the SimpleDateFormat |
| 617 * replace its DateFormatSymbols object with the new one. |
| 618 * |
| 619 * markus 2002-oct-14 |
| 620 */ |
| 621 class DateFormatSymbolsSingleSetter /* not : public UObject because all methods
are static */ { |
| 622 public: |
| 623 static void |
| 624 setSymbol(UnicodeString *array, int32_t count, int32_t index, |
| 625 const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
| 626 { |
| 627 if(array!=NULL) { |
| 628 if(index>=count) { |
| 629 errorCode=U_INDEX_OUTOFBOUNDS_ERROR; |
| 630 } else if(value==NULL) { |
| 631 errorCode=U_ILLEGAL_ARGUMENT_ERROR; |
| 632 } else { |
| 633 array[index].setTo(value, valueLength); |
| 634 } |
| 635 } |
| 636 } |
| 637 |
| 638 static void |
| 639 setEra(DateFormatSymbols *syms, int32_t index, |
| 640 const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
| 641 { |
| 642 setSymbol(syms->fEras, syms->fErasCount, index, value, valueLength, erro
rCode); |
| 643 } |
| 644 |
| 645 static void |
| 646 setEraName(DateFormatSymbols *syms, int32_t index, |
| 647 const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
| 648 { |
| 649 setSymbol(syms->fEraNames, syms->fEraNamesCount, index, value, valueLeng
th, errorCode); |
| 650 } |
| 651 |
| 652 static void |
| 653 setMonth(DateFormatSymbols *syms, int32_t index, |
| 654 const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
| 655 { |
| 656 setSymbol(syms->fMonths, syms->fMonthsCount, index, value, valueLength,
errorCode); |
| 657 } |
| 658 |
| 659 static void |
| 660 setShortMonth(DateFormatSymbols *syms, int32_t index, |
| 661 const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
| 662 { |
| 663 setSymbol(syms->fShortMonths, syms->fShortMonthsCount, index, value, val
ueLength, errorCode); |
| 664 } |
| 665 |
| 666 static void |
| 667 setNarrowMonth(DateFormatSymbols *syms, int32_t index, |
| 668 const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
| 669 { |
| 670 setSymbol(syms->fNarrowMonths, syms->fNarrowMonthsCount, index, value, v
alueLength, errorCode); |
| 671 } |
| 672 |
| 673 static void |
| 674 setStandaloneMonth(DateFormatSymbols *syms, int32_t index, |
| 675 const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
| 676 { |
| 677 setSymbol(syms->fStandaloneMonths, syms->fStandaloneMonthsCount, index,
value, valueLength, errorCode); |
| 678 } |
| 679 |
| 680 static void |
| 681 setStandaloneShortMonth(DateFormatSymbols *syms, int32_t index, |
| 682 const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
| 683 { |
| 684 setSymbol(syms->fStandaloneShortMonths, syms->fStandaloneShortMonthsCoun
t, index, value, valueLength, errorCode); |
| 685 } |
| 686 |
| 687 static void |
| 688 setStandaloneNarrowMonth(DateFormatSymbols *syms, int32_t index, |
| 689 const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
| 690 { |
| 691 setSymbol(syms->fStandaloneNarrowMonths, syms->fStandaloneNarrowMonthsCo
unt, index, value, valueLength, errorCode); |
| 692 } |
| 693 |
| 694 static void |
| 695 setWeekday(DateFormatSymbols *syms, int32_t index, |
| 696 const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
| 697 { |
| 698 setSymbol(syms->fWeekdays, syms->fWeekdaysCount, index, value, valueLeng
th, errorCode); |
| 699 } |
| 700 |
| 701 static void |
| 702 setShortWeekday(DateFormatSymbols *syms, int32_t index, |
| 703 const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
| 704 { |
| 705 setSymbol(syms->fShortWeekdays, syms->fShortWeekdaysCount, index, value,
valueLength, errorCode); |
| 706 } |
| 707 |
| 708 static void |
| 709 setNarrowWeekday(DateFormatSymbols *syms, int32_t index, |
| 710 const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
| 711 { |
| 712 setSymbol(syms->fNarrowWeekdays, syms->fNarrowWeekdaysCount, index, valu
e, valueLength, errorCode); |
| 713 } |
| 714 |
| 715 static void |
| 716 setStandaloneWeekday(DateFormatSymbols *syms, int32_t index, |
| 717 const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
| 718 { |
| 719 setSymbol(syms->fStandaloneWeekdays, syms->fStandaloneWeekdaysCount, ind
ex, value, valueLength, errorCode); |
| 720 } |
| 721 |
| 722 static void |
| 723 setStandaloneShortWeekday(DateFormatSymbols *syms, int32_t index, |
| 724 const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
| 725 { |
| 726 setSymbol(syms->fStandaloneShortWeekdays, syms->fStandaloneShortWeekdays
Count, index, value, valueLength, errorCode); |
| 727 } |
| 728 |
| 729 static void |
| 730 setStandaloneNarrowWeekday(DateFormatSymbols *syms, int32_t index, |
| 731 const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
| 732 { |
| 733 setSymbol(syms->fStandaloneNarrowWeekdays, syms->fStandaloneNarrowWeekda
ysCount, index, value, valueLength, errorCode); |
| 734 } |
| 735 |
| 736 static void |
| 737 setQuarter(DateFormatSymbols *syms, int32_t index, |
| 738 const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
| 739 { |
| 740 setSymbol(syms->fQuarters, syms->fQuartersCount, index, value, valueLeng
th, errorCode); |
| 741 } |
| 742 |
| 743 static void |
| 744 setShortQuarter(DateFormatSymbols *syms, int32_t index, |
| 745 const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
| 746 { |
| 747 setSymbol(syms->fShortQuarters, syms->fShortQuartersCount, index, value,
valueLength, errorCode); |
| 748 } |
| 749 |
| 750 static void |
| 751 setStandaloneQuarter(DateFormatSymbols *syms, int32_t index, |
| 752 const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
| 753 { |
| 754 setSymbol(syms->fStandaloneQuarters, syms->fStandaloneQuartersCount, ind
ex, value, valueLength, errorCode); |
| 755 } |
| 756 |
| 757 static void |
| 758 setStandaloneShortQuarter(DateFormatSymbols *syms, int32_t index, |
| 759 const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
| 760 { |
| 761 setSymbol(syms->fStandaloneShortQuarters, syms->fStandaloneShortQuarters
Count, index, value, valueLength, errorCode); |
| 762 } |
| 763 |
| 764 static void |
| 765 setAmPm(DateFormatSymbols *syms, int32_t index, |
| 766 const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
| 767 { |
| 768 setSymbol(syms->fAmPms, syms->fAmPmsCount, index, value, valueLength, er
rorCode); |
| 769 } |
| 770 |
| 771 static void |
| 772 setLocalPatternChars(DateFormatSymbols *syms, |
| 773 const UChar *value, int32_t valueLength, UErrorCode &errorCode) |
| 774 { |
| 775 setSymbol(&syms->fLocalPatternChars, 1, 0, value, valueLength, errorCode
); |
| 776 } |
| 777 }; |
| 778 |
| 779 U_NAMESPACE_END |
| 780 |
| 781 U_CAPI void U_EXPORT2 |
| 782 udat_setSymbols( UDateFormat *format, |
| 783 UDateFormatSymbolType type, |
| 784 int32_t index, |
| 785 UChar *value, |
| 786 int32_t valueLength, |
| 787 UErrorCode *status) |
| 788 { |
| 789 verifyIsSimpleDateFormat(format, status); |
| 790 if(U_FAILURE(*status)) return; |
| 791 |
| 792 DateFormatSymbols *syms = (DateFormatSymbols *)((SimpleDateFormat *)format)-
>getDateFormatSymbols(); |
| 793 |
| 794 switch(type) { |
| 795 case UDAT_ERAS: |
| 796 DateFormatSymbolsSingleSetter::setEra(syms, index, value, valueLength, *
status); |
| 797 break; |
| 798 |
| 799 case UDAT_ERA_NAMES: |
| 800 DateFormatSymbolsSingleSetter::setEraName(syms, index, value, valueLengt
h, *status); |
| 801 break; |
| 802 |
| 803 case UDAT_MONTHS: |
| 804 DateFormatSymbolsSingleSetter::setMonth(syms, index, value, valueLength,
*status); |
| 805 break; |
| 806 |
| 807 case UDAT_SHORT_MONTHS: |
| 808 DateFormatSymbolsSingleSetter::setShortMonth(syms, index, value, valueLe
ngth, *status); |
| 809 break; |
| 810 |
| 811 case UDAT_NARROW_MONTHS: |
| 812 DateFormatSymbolsSingleSetter::setNarrowMonth(syms, index, value, valueL
ength, *status); |
| 813 break; |
| 814 |
| 815 case UDAT_STANDALONE_MONTHS: |
| 816 DateFormatSymbolsSingleSetter::setStandaloneMonth(syms, index, value, va
lueLength, *status); |
| 817 break; |
| 818 |
| 819 case UDAT_STANDALONE_SHORT_MONTHS: |
| 820 DateFormatSymbolsSingleSetter::setStandaloneShortMonth(syms, index, valu
e, valueLength, *status); |
| 821 break; |
| 822 |
| 823 case UDAT_STANDALONE_NARROW_MONTHS: |
| 824 DateFormatSymbolsSingleSetter::setStandaloneNarrowMonth(syms, index, val
ue, valueLength, *status); |
| 825 break; |
| 826 |
| 827 case UDAT_WEEKDAYS: |
| 828 DateFormatSymbolsSingleSetter::setWeekday(syms, index, value, valueLengt
h, *status); |
| 829 break; |
| 830 |
| 831 case UDAT_SHORT_WEEKDAYS: |
| 832 DateFormatSymbolsSingleSetter::setShortWeekday(syms, index, value, value
Length, *status); |
| 833 break; |
| 834 |
| 835 case UDAT_NARROW_WEEKDAYS: |
| 836 DateFormatSymbolsSingleSetter::setNarrowWeekday(syms, index, value, valu
eLength, *status); |
| 837 break; |
| 838 |
| 839 case UDAT_STANDALONE_WEEKDAYS: |
| 840 DateFormatSymbolsSingleSetter::setStandaloneWeekday(syms, index, value,
valueLength, *status); |
| 841 break; |
| 842 |
| 843 case UDAT_STANDALONE_SHORT_WEEKDAYS: |
| 844 DateFormatSymbolsSingleSetter::setStandaloneShortWeekday(syms, index, va
lue, valueLength, *status); |
| 845 break; |
| 846 |
| 847 case UDAT_STANDALONE_NARROW_WEEKDAYS: |
| 848 DateFormatSymbolsSingleSetter::setStandaloneNarrowWeekday(syms, index, v
alue, valueLength, *status); |
| 849 break; |
| 850 |
| 851 case UDAT_QUARTERS: |
| 852 DateFormatSymbolsSingleSetter::setQuarter(syms, index, value, valueLengt
h, *status); |
| 853 break; |
| 854 |
| 855 case UDAT_SHORT_QUARTERS: |
| 856 DateFormatSymbolsSingleSetter::setShortQuarter(syms, index, value, value
Length, *status); |
| 857 break; |
| 858 |
| 859 case UDAT_STANDALONE_QUARTERS: |
| 860 DateFormatSymbolsSingleSetter::setStandaloneQuarter(syms, index, value,
valueLength, *status); |
| 861 break; |
| 862 |
| 863 case UDAT_STANDALONE_SHORT_QUARTERS: |
| 864 DateFormatSymbolsSingleSetter::setStandaloneShortQuarter(syms, index, va
lue, valueLength, *status); |
| 865 break; |
| 866 |
| 867 case UDAT_AM_PMS: |
| 868 DateFormatSymbolsSingleSetter::setAmPm(syms, index, value, valueLength,
*status); |
| 869 break; |
| 870 |
| 871 case UDAT_LOCALIZED_CHARS: |
| 872 DateFormatSymbolsSingleSetter::setLocalPatternChars(syms, value, valueLe
ngth, *status); |
| 873 break; |
| 874 |
| 875 default: |
| 876 *status = U_UNSUPPORTED_ERROR; |
| 877 break; |
| 878 |
| 879 } |
| 880 } |
| 881 |
| 882 U_CAPI const char* U_EXPORT2 |
| 883 udat_getLocaleByType(const UDateFormat *fmt, |
| 884 ULocDataLocaleType type, |
| 885 UErrorCode* status) |
| 886 { |
| 887 if (fmt == NULL) { |
| 888 if (U_SUCCESS(*status)) { |
| 889 *status = U_ILLEGAL_ARGUMENT_ERROR; |
| 890 } |
| 891 return NULL; |
| 892 } |
| 893 return ((Format*)fmt)->getLocaleID(type, *status); |
| 894 } |
| 895 |
| 896 /** |
| 897 * Verify that fmt is a RelativeDateFormat. Invalid error if not. |
| 898 * @param fmt the UDateFormat, definitely a DateFormat, maybe something else |
| 899 * @param status error code, will be set to failure if there is a familure or th
e fmt is NULL. |
| 900 */ |
| 901 static void verifyIsRelativeDateFormat(const UDateFormat* fmt, UErrorCode *statu
s) { |
| 902 if(U_SUCCESS(*status) && |
| 903 dynamic_cast<const RelativeDateFormat*>(reinterpret_cast<const DateFormat
*>(fmt))==NULL) { |
| 904 *status = U_ILLEGAL_ARGUMENT_ERROR; |
| 905 } |
| 906 } |
| 907 |
| 908 |
| 909 U_CAPI int32_t U_EXPORT2 |
| 910 udat_toPatternRelativeDate(const UDateFormat *fmt, |
| 911 UChar *result, |
| 912 int32_t resultLength, |
| 913 UErrorCode *status) |
| 914 { |
| 915 verifyIsRelativeDateFormat(fmt, status); |
| 916 if(U_FAILURE(*status)) return -1; |
| 917 |
| 918 UnicodeString datePattern; |
| 919 if(!(result==NULL && resultLength==0)) { |
| 920 // NULL destination for pure preflighting: empty dummy string |
| 921 // otherwise, alias the destination buffer |
| 922 datePattern.setTo(result, 0, resultLength); |
| 923 } |
| 924 ((RelativeDateFormat*)fmt)->toPatternDate(datePattern, *status); |
| 925 return datePattern.extract(result, resultLength, *status); |
| 926 } |
| 927 |
| 928 U_CAPI int32_t U_EXPORT2 |
| 929 udat_toPatternRelativeTime(const UDateFormat *fmt, |
| 930 UChar *result, |
| 931 int32_t resultLength, |
| 932 UErrorCode *status) |
| 933 { |
| 934 verifyIsRelativeDateFormat(fmt, status); |
| 935 if(U_FAILURE(*status)) return -1; |
| 936 |
| 937 UnicodeString timePattern; |
| 938 if(!(result==NULL && resultLength==0)) { |
| 939 // NULL destination for pure preflighting: empty dummy string |
| 940 // otherwise, alias the destination buffer |
| 941 timePattern.setTo(result, 0, resultLength); |
| 942 } |
| 943 ((RelativeDateFormat*)fmt)->toPatternTime(timePattern, *status); |
| 944 return timePattern.extract(result, resultLength, *status); |
| 945 } |
| 946 |
| 947 U_CAPI void U_EXPORT2 |
| 948 udat_applyPatternRelative(UDateFormat *format, |
| 949 const UChar *datePattern, |
| 950 int32_t datePatternLength, |
| 951 const UChar *timePattern, |
| 952 int32_t timePatternLength, |
| 953 UErrorCode *status) |
| 954 { |
| 955 verifyIsRelativeDateFormat(format, status); |
| 956 if(U_FAILURE(*status)) return; |
| 957 const UnicodeString datePat((UBool)(datePatternLength == -1), datePattern, d
atePatternLength); |
| 958 const UnicodeString timePat((UBool)(timePatternLength == -1), timePattern, t
imePatternLength); |
| 959 ((RelativeDateFormat*)format)->applyPatterns(datePat, timePat, *status); |
| 960 } |
| 961 |
| 962 #endif /* #if !UCONFIG_NO_FORMATTING */ |
OLD | NEW |