1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/icu/source/i18n/udat.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1071 @@ 1.4 +/* 1.5 +******************************************************************************* 1.6 +* Copyright (C) 1996-2013, International Business Machines 1.7 +* Corporation and others. All Rights Reserved. 1.8 +******************************************************************************* 1.9 +*/ 1.10 + 1.11 +#include "unicode/utypes.h" 1.12 + 1.13 +#if !UCONFIG_NO_FORMATTING 1.14 + 1.15 +#include "unicode/udat.h" 1.16 + 1.17 +#include "unicode/uloc.h" 1.18 +#include "unicode/datefmt.h" 1.19 +#include "unicode/timezone.h" 1.20 +#include "unicode/smpdtfmt.h" 1.21 +#include "unicode/fieldpos.h" 1.22 +#include "unicode/parsepos.h" 1.23 +#include "unicode/calendar.h" 1.24 +#include "unicode/numfmt.h" 1.25 +#include "unicode/dtfmtsym.h" 1.26 +#include "unicode/ustring.h" 1.27 +#include "unicode/udisplaycontext.h" 1.28 +#include "cpputils.h" 1.29 +#include "reldtfmt.h" 1.30 +#include "umutex.h" 1.31 + 1.32 +U_NAMESPACE_USE 1.33 + 1.34 +/** 1.35 + * Verify that fmt is a SimpleDateFormat. Invalid error if not. 1.36 + * @param fmt the UDateFormat, definitely a DateFormat, maybe something else 1.37 + * @param status error code, will be set to failure if there is a familure or the fmt is NULL. 1.38 + */ 1.39 +static void verifyIsSimpleDateFormat(const UDateFormat* fmt, UErrorCode *status) { 1.40 + if(U_SUCCESS(*status) && 1.41 + dynamic_cast<const SimpleDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))==NULL) { 1.42 + *status = U_ILLEGAL_ARGUMENT_ERROR; 1.43 + } 1.44 +} 1.45 + 1.46 +// This mirrors the correspondence between the 1.47 +// SimpleDateFormat::fgPatternIndexToDateFormatField and 1.48 +// SimpleDateFormat::fgPatternIndexToCalendarField arrays. 1.49 +static UCalendarDateFields gDateFieldMapping[] = { 1.50 + UCAL_ERA, // UDAT_ERA_FIELD = 0 1.51 + UCAL_YEAR, // UDAT_YEAR_FIELD = 1 1.52 + UCAL_MONTH, // UDAT_MONTH_FIELD = 2 1.53 + UCAL_DATE, // UDAT_DATE_FIELD = 3 1.54 + UCAL_HOUR_OF_DAY, // UDAT_HOUR_OF_DAY1_FIELD = 4 1.55 + UCAL_HOUR_OF_DAY, // UDAT_HOUR_OF_DAY0_FIELD = 5 1.56 + UCAL_MINUTE, // UDAT_MINUTE_FIELD = 6 1.57 + UCAL_SECOND, // UDAT_SECOND_FIELD = 7 1.58 + UCAL_MILLISECOND, // UDAT_FRACTIONAL_SECOND_FIELD = 8 1.59 + UCAL_DAY_OF_WEEK, // UDAT_DAY_OF_WEEK_FIELD = 9 1.60 + UCAL_DAY_OF_YEAR, // UDAT_DAY_OF_YEAR_FIELD = 10 1.61 + UCAL_DAY_OF_WEEK_IN_MONTH, // UDAT_DAY_OF_WEEK_IN_MONTH_FIELD = 11 1.62 + UCAL_WEEK_OF_YEAR, // UDAT_WEEK_OF_YEAR_FIELD = 12 1.63 + UCAL_WEEK_OF_MONTH, // UDAT_WEEK_OF_MONTH_FIELD = 13 1.64 + UCAL_AM_PM, // UDAT_AM_PM_FIELD = 14 1.65 + UCAL_HOUR, // UDAT_HOUR1_FIELD = 15 1.66 + UCAL_HOUR, // UDAT_HOUR0_FIELD = 16 1.67 + UCAL_ZONE_OFFSET, // UDAT_TIMEZONE_FIELD = 17 1.68 + UCAL_YEAR_WOY, // UDAT_YEAR_WOY_FIELD = 18 1.69 + UCAL_DOW_LOCAL, // UDAT_DOW_LOCAL_FIELD = 19 1.70 + UCAL_EXTENDED_YEAR, // UDAT_EXTENDED_YEAR_FIELD = 20 1.71 + UCAL_JULIAN_DAY, // UDAT_JULIAN_DAY_FIELD = 21 1.72 + UCAL_MILLISECONDS_IN_DAY, // UDAT_MILLISECONDS_IN_DAY_FIELD = 22 1.73 + UCAL_ZONE_OFFSET, // UDAT_TIMEZONE_RFC_FIELD = 23 1.74 + // UCAL_DST_OFFSET also 1.75 + UCAL_ZONE_OFFSET, // UDAT_TIMEZONE_GENERIC_FIELD = 24 1.76 + UCAL_DOW_LOCAL, // UDAT_STANDALONE_DAY_FIELD = 25 1.77 + UCAL_MONTH, // UDAT_STANDALONE_MONTH_FIELD = 26 1.78 + UCAL_MONTH, // UDAT_QUARTER_FIELD = 27 1.79 + UCAL_MONTH, // UDAT_STANDALONE_QUARTER_FIELD = 28 1.80 + UCAL_ZONE_OFFSET, // UDAT_TIMEZONE_SPECIAL_FIELD = 29 1.81 + UCAL_YEAR, // UDAT_YEAR_NAME_FIELD = 30 1.82 + UCAL_FIELD_COUNT, // UDAT_FIELD_COUNT = 31 1.83 + // UCAL_IS_LEAP_MONTH is not the target of a mapping 1.84 +}; 1.85 + 1.86 +U_CAPI UCalendarDateFields U_EXPORT2 1.87 +udat_toCalendarDateField(UDateFormatField field) { 1.88 + return gDateFieldMapping[field]; 1.89 +} 1.90 + 1.91 +/* For now- one opener. */ 1.92 +static UDateFormatOpener gOpener = NULL; 1.93 + 1.94 +U_INTERNAL void U_EXPORT2 1.95 +udat_registerOpener(UDateFormatOpener opener, UErrorCode *status) 1.96 +{ 1.97 + if(U_FAILURE(*status)) return; 1.98 + umtx_lock(NULL); 1.99 + if(gOpener==NULL) { 1.100 + gOpener = opener; 1.101 + } else { 1.102 + *status = U_ILLEGAL_ARGUMENT_ERROR; 1.103 + } 1.104 + umtx_unlock(NULL); 1.105 +} 1.106 + 1.107 +U_INTERNAL UDateFormatOpener U_EXPORT2 1.108 +udat_unregisterOpener(UDateFormatOpener opener, UErrorCode *status) 1.109 +{ 1.110 + if(U_FAILURE(*status)) return NULL; 1.111 + UDateFormatOpener oldOpener = NULL; 1.112 + umtx_lock(NULL); 1.113 + if(gOpener==NULL || gOpener!=opener) { 1.114 + *status = U_ILLEGAL_ARGUMENT_ERROR; 1.115 + } else { 1.116 + oldOpener=gOpener; 1.117 + gOpener=NULL; 1.118 + } 1.119 + umtx_unlock(NULL); 1.120 + return oldOpener; 1.121 +} 1.122 + 1.123 + 1.124 + 1.125 +U_CAPI UDateFormat* U_EXPORT2 1.126 +udat_open(UDateFormatStyle timeStyle, 1.127 + UDateFormatStyle dateStyle, 1.128 + const char *locale, 1.129 + const UChar *tzID, 1.130 + int32_t tzIDLength, 1.131 + const UChar *pattern, 1.132 + int32_t patternLength, 1.133 + UErrorCode *status) 1.134 +{ 1.135 + DateFormat *fmt; 1.136 + if(U_FAILURE(*status)) { 1.137 + return 0; 1.138 + } 1.139 + if(gOpener!=NULL) { // if it's registered 1.140 + fmt = (DateFormat*) (*gOpener)(timeStyle,dateStyle,locale,tzID,tzIDLength,pattern,patternLength,status); 1.141 + if(fmt!=NULL) { 1.142 + return (UDateFormat*)fmt; 1.143 + } // else fall through. 1.144 + } 1.145 + if(timeStyle != UDAT_PATTERN) { 1.146 + if(locale == 0) { 1.147 + fmt = DateFormat::createDateTimeInstance((DateFormat::EStyle)dateStyle, 1.148 + (DateFormat::EStyle)timeStyle); 1.149 + } 1.150 + else { 1.151 + fmt = DateFormat::createDateTimeInstance((DateFormat::EStyle)dateStyle, 1.152 + (DateFormat::EStyle)timeStyle, 1.153 + Locale(locale)); 1.154 + } 1.155 + } 1.156 + else { 1.157 + UnicodeString pat((UBool)(patternLength == -1), pattern, patternLength); 1.158 + 1.159 + if(locale == 0) { 1.160 + fmt = new SimpleDateFormat(pat, *status); 1.161 + } 1.162 + else { 1.163 + fmt = new SimpleDateFormat(pat, Locale(locale), *status); 1.164 + } 1.165 + } 1.166 + 1.167 + if(fmt == 0) { 1.168 + *status = U_MEMORY_ALLOCATION_ERROR; 1.169 + return 0; 1.170 + } 1.171 + 1.172 + if(tzID != 0) { 1.173 + TimeZone *zone = TimeZone::createTimeZone(UnicodeString((UBool)(tzIDLength == -1), tzID, tzIDLength)); 1.174 + if(zone == 0) { 1.175 + *status = U_MEMORY_ALLOCATION_ERROR; 1.176 + delete fmt; 1.177 + return 0; 1.178 + } 1.179 + fmt->adoptTimeZone(zone); 1.180 + } 1.181 + 1.182 + return (UDateFormat*)fmt; 1.183 +} 1.184 + 1.185 + 1.186 +U_CAPI void U_EXPORT2 1.187 +udat_close(UDateFormat* format) 1.188 +{ 1.189 + delete (DateFormat*)format; 1.190 +} 1.191 + 1.192 +U_CAPI UDateFormat* U_EXPORT2 1.193 +udat_clone(const UDateFormat *fmt, 1.194 + UErrorCode *status) 1.195 +{ 1.196 + if(U_FAILURE(*status)) return 0; 1.197 + 1.198 + Format *res = ((DateFormat*)fmt)->clone(); 1.199 + 1.200 + if(res == 0) { 1.201 + *status = U_MEMORY_ALLOCATION_ERROR; 1.202 + return 0; 1.203 + } 1.204 + 1.205 + return (UDateFormat*) res; 1.206 +} 1.207 + 1.208 +U_CAPI int32_t U_EXPORT2 1.209 +udat_format( const UDateFormat* format, 1.210 + UDate dateToFormat, 1.211 + UChar* result, 1.212 + int32_t resultLength, 1.213 + UFieldPosition* position, 1.214 + UErrorCode* status) 1.215 +{ 1.216 + if(U_FAILURE(*status)) return -1; 1.217 + 1.218 + UnicodeString res; 1.219 + if(!(result==NULL && resultLength==0)) { 1.220 + // NULL destination for pure preflighting: empty dummy string 1.221 + // otherwise, alias the destination buffer 1.222 + res.setTo(result, 0, resultLength); 1.223 + } 1.224 + 1.225 + FieldPosition fp; 1.226 + 1.227 + if(position != 0) 1.228 + fp.setField(position->field); 1.229 + 1.230 + ((DateFormat*)format)->format(dateToFormat, res, fp); 1.231 + 1.232 + if(position != 0) { 1.233 + position->beginIndex = fp.getBeginIndex(); 1.234 + position->endIndex = fp.getEndIndex(); 1.235 + } 1.236 + 1.237 + return res.extract(result, resultLength, *status); 1.238 +} 1.239 + 1.240 +U_CAPI UDate U_EXPORT2 1.241 +udat_parse( const UDateFormat* format, 1.242 + const UChar* text, 1.243 + int32_t textLength, 1.244 + int32_t *parsePos, 1.245 + UErrorCode *status) 1.246 +{ 1.247 + if(U_FAILURE(*status)) return (UDate)0; 1.248 + 1.249 + const UnicodeString src((UBool)(textLength == -1), text, textLength); 1.250 + ParsePosition pp; 1.251 + int32_t stackParsePos = 0; 1.252 + UDate res; 1.253 + 1.254 + if(parsePos == NULL) { 1.255 + parsePos = &stackParsePos; 1.256 + } 1.257 + 1.258 + pp.setIndex(*parsePos); 1.259 + 1.260 + res = ((DateFormat*)format)->parse(src, pp); 1.261 + 1.262 + if(pp.getErrorIndex() == -1) 1.263 + *parsePos = pp.getIndex(); 1.264 + else { 1.265 + *parsePos = pp.getErrorIndex(); 1.266 + *status = U_PARSE_ERROR; 1.267 + } 1.268 + 1.269 + return res; 1.270 +} 1.271 + 1.272 +U_CAPI void U_EXPORT2 1.273 +udat_parseCalendar(const UDateFormat* format, 1.274 + UCalendar* calendar, 1.275 + const UChar* text, 1.276 + int32_t textLength, 1.277 + int32_t *parsePos, 1.278 + UErrorCode *status) 1.279 +{ 1.280 + if(U_FAILURE(*status)) return; 1.281 + 1.282 + const UnicodeString src((UBool)(textLength == -1), text, textLength); 1.283 + ParsePosition pp; 1.284 + 1.285 + if(parsePos != 0) 1.286 + pp.setIndex(*parsePos); 1.287 + 1.288 + ((DateFormat*)format)->parse(src, *(Calendar*)calendar, pp); 1.289 + 1.290 + if(parsePos != 0) { 1.291 + if(pp.getErrorIndex() == -1) 1.292 + *parsePos = pp.getIndex(); 1.293 + else { 1.294 + *parsePos = pp.getErrorIndex(); 1.295 + *status = U_PARSE_ERROR; 1.296 + } 1.297 + } 1.298 +} 1.299 + 1.300 +U_CAPI UBool U_EXPORT2 1.301 +udat_isLenient(const UDateFormat* fmt) 1.302 +{ 1.303 + return ((DateFormat*)fmt)->isLenient(); 1.304 +} 1.305 + 1.306 +U_CAPI void U_EXPORT2 1.307 +udat_setLenient( UDateFormat* fmt, 1.308 + UBool isLenient) 1.309 +{ 1.310 + ((DateFormat*)fmt)->setLenient(isLenient); 1.311 +} 1.312 + 1.313 +U_CAPI const UCalendar* U_EXPORT2 1.314 +udat_getCalendar(const UDateFormat* fmt) 1.315 +{ 1.316 + return (const UCalendar*) ((DateFormat*)fmt)->getCalendar(); 1.317 +} 1.318 + 1.319 +U_CAPI void U_EXPORT2 1.320 +udat_setCalendar(UDateFormat* fmt, 1.321 + const UCalendar* calendarToSet) 1.322 +{ 1.323 + ((DateFormat*)fmt)->setCalendar(*((Calendar*)calendarToSet)); 1.324 +} 1.325 + 1.326 +U_CAPI const UNumberFormat* U_EXPORT2 1.327 +udat_getNumberFormat(const UDateFormat* fmt) 1.328 +{ 1.329 + return (const UNumberFormat*) ((DateFormat*)fmt)->getNumberFormat(); 1.330 +} 1.331 + 1.332 +U_CAPI void U_EXPORT2 1.333 +udat_setNumberFormat(UDateFormat* fmt, 1.334 + const UNumberFormat* numberFormatToSet) 1.335 +{ 1.336 + ((DateFormat*)fmt)->setNumberFormat(*((NumberFormat*)numberFormatToSet)); 1.337 +} 1.338 + 1.339 +U_CAPI const char* U_EXPORT2 1.340 +udat_getAvailable(int32_t index) 1.341 +{ 1.342 + return uloc_getAvailable(index); 1.343 +} 1.344 + 1.345 +U_CAPI int32_t U_EXPORT2 1.346 +udat_countAvailable() 1.347 +{ 1.348 + return uloc_countAvailable(); 1.349 +} 1.350 + 1.351 +U_CAPI UDate U_EXPORT2 1.352 +udat_get2DigitYearStart( const UDateFormat *fmt, 1.353 + UErrorCode *status) 1.354 +{ 1.355 + verifyIsSimpleDateFormat(fmt, status); 1.356 + if(U_FAILURE(*status)) return (UDate)0; 1.357 + return ((SimpleDateFormat*)fmt)->get2DigitYearStart(*status); 1.358 +} 1.359 + 1.360 +U_CAPI void U_EXPORT2 1.361 +udat_set2DigitYearStart( UDateFormat *fmt, 1.362 + UDate d, 1.363 + UErrorCode *status) 1.364 +{ 1.365 + verifyIsSimpleDateFormat(fmt, status); 1.366 + if(U_FAILURE(*status)) return; 1.367 + ((SimpleDateFormat*)fmt)->set2DigitYearStart(d, *status); 1.368 +} 1.369 + 1.370 +U_CAPI int32_t U_EXPORT2 1.371 +udat_toPattern( const UDateFormat *fmt, 1.372 + UBool localized, 1.373 + UChar *result, 1.374 + int32_t resultLength, 1.375 + UErrorCode *status) 1.376 +{ 1.377 + if(U_FAILURE(*status)) return -1; 1.378 + 1.379 + UnicodeString res; 1.380 + if(!(result==NULL && resultLength==0)) { 1.381 + // NULL destination for pure preflighting: empty dummy string 1.382 + // otherwise, alias the destination buffer 1.383 + res.setTo(result, 0, resultLength); 1.384 + } 1.385 + 1.386 + const DateFormat *df=reinterpret_cast<const DateFormat *>(fmt); 1.387 + const SimpleDateFormat *sdtfmt=dynamic_cast<const SimpleDateFormat *>(df); 1.388 + const RelativeDateFormat *reldtfmt; 1.389 + if (sdtfmt!=NULL) { 1.390 + if(localized) 1.391 + sdtfmt->toLocalizedPattern(res, *status); 1.392 + else 1.393 + sdtfmt->toPattern(res); 1.394 + } else if (!localized && (reldtfmt=dynamic_cast<const RelativeDateFormat *>(df))!=NULL) { 1.395 + reldtfmt->toPattern(res, *status); 1.396 + } else { 1.397 + *status = U_ILLEGAL_ARGUMENT_ERROR; 1.398 + return -1; 1.399 + } 1.400 + 1.401 + return res.extract(result, resultLength, *status); 1.402 +} 1.403 + 1.404 +// TODO: should this take an UErrorCode? 1.405 +// A: Yes. Of course. 1.406 +U_CAPI void U_EXPORT2 1.407 +udat_applyPattern( UDateFormat *format, 1.408 + UBool localized, 1.409 + const UChar *pattern, 1.410 + int32_t patternLength) 1.411 +{ 1.412 + const UnicodeString pat((UBool)(patternLength == -1), pattern, patternLength); 1.413 + UErrorCode status = U_ZERO_ERROR; 1.414 + 1.415 + verifyIsSimpleDateFormat(format, &status); 1.416 + if(U_FAILURE(status)) { 1.417 + return; 1.418 + } 1.419 + 1.420 + if(localized) 1.421 + ((SimpleDateFormat*)format)->applyLocalizedPattern(pat, status); 1.422 + else 1.423 + ((SimpleDateFormat*)format)->applyPattern(pat); 1.424 +} 1.425 + 1.426 +U_CAPI int32_t U_EXPORT2 1.427 +udat_getSymbols(const UDateFormat *fmt, 1.428 + UDateFormatSymbolType type, 1.429 + int32_t index, 1.430 + UChar *result, 1.431 + int32_t resultLength, 1.432 + UErrorCode *status) 1.433 +{ 1.434 + const DateFormatSymbols *syms; 1.435 + const SimpleDateFormat* sdtfmt; 1.436 + const RelativeDateFormat* rdtfmt; 1.437 + if ((sdtfmt = dynamic_cast<const SimpleDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))) != NULL) { 1.438 + syms = sdtfmt->getDateFormatSymbols(); 1.439 + } else if ((rdtfmt = dynamic_cast<const RelativeDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))) != NULL) { 1.440 + syms = rdtfmt->getDateFormatSymbols(); 1.441 + } else { 1.442 + return -1; 1.443 + } 1.444 + int32_t count; 1.445 + const UnicodeString *res = NULL; 1.446 + 1.447 + switch(type) { 1.448 + case UDAT_ERAS: 1.449 + res = syms->getEras(count); 1.450 + break; 1.451 + 1.452 + case UDAT_ERA_NAMES: 1.453 + res = syms->getEraNames(count); 1.454 + break; 1.455 + 1.456 + case UDAT_MONTHS: 1.457 + res = syms->getMonths(count); 1.458 + break; 1.459 + 1.460 + case UDAT_SHORT_MONTHS: 1.461 + res = syms->getShortMonths(count); 1.462 + break; 1.463 + 1.464 + case UDAT_WEEKDAYS: 1.465 + res = syms->getWeekdays(count); 1.466 + break; 1.467 + 1.468 + case UDAT_SHORT_WEEKDAYS: 1.469 + res = syms->getShortWeekdays(count); 1.470 + break; 1.471 + 1.472 + case UDAT_AM_PMS: 1.473 + res = syms->getAmPmStrings(count); 1.474 + break; 1.475 + 1.476 + case UDAT_LOCALIZED_CHARS: 1.477 + { 1.478 + UnicodeString res1; 1.479 + if(!(result==NULL && resultLength==0)) { 1.480 + // NULL destination for pure preflighting: empty dummy string 1.481 + // otherwise, alias the destination buffer 1.482 + res1.setTo(result, 0, resultLength); 1.483 + } 1.484 + syms->getLocalPatternChars(res1); 1.485 + return res1.extract(result, resultLength, *status); 1.486 + } 1.487 + 1.488 + case UDAT_NARROW_MONTHS: 1.489 + res = syms->getMonths(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW); 1.490 + break; 1.491 + 1.492 + case UDAT_SHORTER_WEEKDAYS: 1.493 + res = syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::SHORT); 1.494 + break; 1.495 + 1.496 + case UDAT_NARROW_WEEKDAYS: 1.497 + res = syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW); 1.498 + break; 1.499 + 1.500 + case UDAT_STANDALONE_MONTHS: 1.501 + res = syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE); 1.502 + break; 1.503 + 1.504 + case UDAT_STANDALONE_SHORT_MONTHS: 1.505 + res = syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED); 1.506 + break; 1.507 + 1.508 + case UDAT_STANDALONE_NARROW_MONTHS: 1.509 + res = syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW); 1.510 + break; 1.511 + 1.512 + case UDAT_STANDALONE_WEEKDAYS: 1.513 + res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE); 1.514 + break; 1.515 + 1.516 + case UDAT_STANDALONE_SHORT_WEEKDAYS: 1.517 + res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED); 1.518 + break; 1.519 + 1.520 + case UDAT_STANDALONE_SHORTER_WEEKDAYS: 1.521 + res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::SHORT); 1.522 + break; 1.523 + 1.524 + case UDAT_STANDALONE_NARROW_WEEKDAYS: 1.525 + res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW); 1.526 + break; 1.527 + 1.528 + case UDAT_QUARTERS: 1.529 + res = syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE); 1.530 + break; 1.531 + 1.532 + case UDAT_SHORT_QUARTERS: 1.533 + res = syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED); 1.534 + break; 1.535 + 1.536 + case UDAT_STANDALONE_QUARTERS: 1.537 + res = syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE); 1.538 + break; 1.539 + 1.540 + case UDAT_STANDALONE_SHORT_QUARTERS: 1.541 + res = syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED); 1.542 + break; 1.543 + 1.544 + } 1.545 + 1.546 + if(index < count) { 1.547 + return res[index].extract(result, resultLength, *status); 1.548 + } 1.549 + return 0; 1.550 +} 1.551 + 1.552 +// TODO: also needs an errorCode. 1.553 +U_CAPI int32_t U_EXPORT2 1.554 +udat_countSymbols( const UDateFormat *fmt, 1.555 + UDateFormatSymbolType type) 1.556 +{ 1.557 + const DateFormatSymbols *syms; 1.558 + const SimpleDateFormat* sdtfmt; 1.559 + const RelativeDateFormat* rdtfmt; 1.560 + if ((sdtfmt = dynamic_cast<const SimpleDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))) != NULL) { 1.561 + syms = sdtfmt->getDateFormatSymbols(); 1.562 + } else if ((rdtfmt = dynamic_cast<const RelativeDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))) != NULL) { 1.563 + syms = rdtfmt->getDateFormatSymbols(); 1.564 + } else { 1.565 + return 0; 1.566 + } 1.567 + int32_t count = 0; 1.568 + 1.569 + switch(type) { 1.570 + case UDAT_ERAS: 1.571 + syms->getEras(count); 1.572 + break; 1.573 + 1.574 + case UDAT_MONTHS: 1.575 + syms->getMonths(count); 1.576 + break; 1.577 + 1.578 + case UDAT_SHORT_MONTHS: 1.579 + syms->getShortMonths(count); 1.580 + break; 1.581 + 1.582 + case UDAT_WEEKDAYS: 1.583 + syms->getWeekdays(count); 1.584 + break; 1.585 + 1.586 + case UDAT_SHORT_WEEKDAYS: 1.587 + syms->getShortWeekdays(count); 1.588 + break; 1.589 + 1.590 + case UDAT_AM_PMS: 1.591 + syms->getAmPmStrings(count); 1.592 + break; 1.593 + 1.594 + case UDAT_LOCALIZED_CHARS: 1.595 + count = 1; 1.596 + break; 1.597 + 1.598 + case UDAT_ERA_NAMES: 1.599 + syms->getEraNames(count); 1.600 + break; 1.601 + 1.602 + case UDAT_NARROW_MONTHS: 1.603 + syms->getMonths(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW); 1.604 + break; 1.605 + 1.606 + case UDAT_SHORTER_WEEKDAYS: 1.607 + syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::SHORT); 1.608 + break; 1.609 + 1.610 + case UDAT_NARROW_WEEKDAYS: 1.611 + syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW); 1.612 + break; 1.613 + 1.614 + case UDAT_STANDALONE_MONTHS: 1.615 + syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE); 1.616 + break; 1.617 + 1.618 + case UDAT_STANDALONE_SHORT_MONTHS: 1.619 + syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED); 1.620 + break; 1.621 + 1.622 + case UDAT_STANDALONE_NARROW_MONTHS: 1.623 + syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW); 1.624 + break; 1.625 + 1.626 + case UDAT_STANDALONE_WEEKDAYS: 1.627 + syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE); 1.628 + break; 1.629 + 1.630 + case UDAT_STANDALONE_SHORT_WEEKDAYS: 1.631 + syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED); 1.632 + break; 1.633 + 1.634 + case UDAT_STANDALONE_SHORTER_WEEKDAYS: 1.635 + syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::SHORT); 1.636 + break; 1.637 + 1.638 + case UDAT_STANDALONE_NARROW_WEEKDAYS: 1.639 + syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW); 1.640 + break; 1.641 + 1.642 + case UDAT_QUARTERS: 1.643 + syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE); 1.644 + break; 1.645 + 1.646 + case UDAT_SHORT_QUARTERS: 1.647 + syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED); 1.648 + break; 1.649 + 1.650 + case UDAT_STANDALONE_QUARTERS: 1.651 + syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE); 1.652 + break; 1.653 + 1.654 + case UDAT_STANDALONE_SHORT_QUARTERS: 1.655 + syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED); 1.656 + break; 1.657 + 1.658 + } 1.659 + 1.660 + return count; 1.661 +} 1.662 + 1.663 +U_NAMESPACE_BEGIN 1.664 + 1.665 +/* 1.666 + * This DateFormatSymbolsSingleSetter class is a friend of DateFormatSymbols 1.667 + * solely for the purpose of avoiding to clone the array of strings 1.668 + * just to modify one of them and then setting all of them back. 1.669 + * For example, the old code looked like this: 1.670 + * case UDAT_MONTHS: 1.671 + * res = syms->getMonths(count); 1.672 + * array = new UnicodeString[count]; 1.673 + * if(array == 0) { 1.674 + * *status = U_MEMORY_ALLOCATION_ERROR; 1.675 + * return; 1.676 + * } 1.677 + * uprv_arrayCopy(res, array, count); 1.678 + * if(index < count) 1.679 + * array[index] = val; 1.680 + * syms->setMonths(array, count); 1.681 + * break; 1.682 + * 1.683 + * Even worse, the old code actually cloned the entire DateFormatSymbols object, 1.684 + * cloned one value array, changed one value, and then made the SimpleDateFormat 1.685 + * replace its DateFormatSymbols object with the new one. 1.686 + * 1.687 + * markus 2002-oct-14 1.688 + */ 1.689 +class DateFormatSymbolsSingleSetter /* not : public UObject because all methods are static */ { 1.690 +public: 1.691 + static void 1.692 + setSymbol(UnicodeString *array, int32_t count, int32_t index, 1.693 + const UChar *value, int32_t valueLength, UErrorCode &errorCode) 1.694 + { 1.695 + if(array!=NULL) { 1.696 + if(index>=count) { 1.697 + errorCode=U_INDEX_OUTOFBOUNDS_ERROR; 1.698 + } else if(value==NULL) { 1.699 + errorCode=U_ILLEGAL_ARGUMENT_ERROR; 1.700 + } else { 1.701 + array[index].setTo(value, valueLength); 1.702 + } 1.703 + } 1.704 + } 1.705 + 1.706 + static void 1.707 + setEra(DateFormatSymbols *syms, int32_t index, 1.708 + const UChar *value, int32_t valueLength, UErrorCode &errorCode) 1.709 + { 1.710 + setSymbol(syms->fEras, syms->fErasCount, index, value, valueLength, errorCode); 1.711 + } 1.712 + 1.713 + static void 1.714 + setEraName(DateFormatSymbols *syms, int32_t index, 1.715 + const UChar *value, int32_t valueLength, UErrorCode &errorCode) 1.716 + { 1.717 + setSymbol(syms->fEraNames, syms->fEraNamesCount, index, value, valueLength, errorCode); 1.718 + } 1.719 + 1.720 + static void 1.721 + setMonth(DateFormatSymbols *syms, int32_t index, 1.722 + const UChar *value, int32_t valueLength, UErrorCode &errorCode) 1.723 + { 1.724 + setSymbol(syms->fMonths, syms->fMonthsCount, index, value, valueLength, errorCode); 1.725 + } 1.726 + 1.727 + static void 1.728 + setShortMonth(DateFormatSymbols *syms, int32_t index, 1.729 + const UChar *value, int32_t valueLength, UErrorCode &errorCode) 1.730 + { 1.731 + setSymbol(syms->fShortMonths, syms->fShortMonthsCount, index, value, valueLength, errorCode); 1.732 + } 1.733 + 1.734 + static void 1.735 + setNarrowMonth(DateFormatSymbols *syms, int32_t index, 1.736 + const UChar *value, int32_t valueLength, UErrorCode &errorCode) 1.737 + { 1.738 + setSymbol(syms->fNarrowMonths, syms->fNarrowMonthsCount, index, value, valueLength, errorCode); 1.739 + } 1.740 + 1.741 + static void 1.742 + setStandaloneMonth(DateFormatSymbols *syms, int32_t index, 1.743 + const UChar *value, int32_t valueLength, UErrorCode &errorCode) 1.744 + { 1.745 + setSymbol(syms->fStandaloneMonths, syms->fStandaloneMonthsCount, index, value, valueLength, errorCode); 1.746 + } 1.747 + 1.748 + static void 1.749 + setStandaloneShortMonth(DateFormatSymbols *syms, int32_t index, 1.750 + const UChar *value, int32_t valueLength, UErrorCode &errorCode) 1.751 + { 1.752 + setSymbol(syms->fStandaloneShortMonths, syms->fStandaloneShortMonthsCount, index, value, valueLength, errorCode); 1.753 + } 1.754 + 1.755 + static void 1.756 + setStandaloneNarrowMonth(DateFormatSymbols *syms, int32_t index, 1.757 + const UChar *value, int32_t valueLength, UErrorCode &errorCode) 1.758 + { 1.759 + setSymbol(syms->fStandaloneNarrowMonths, syms->fStandaloneNarrowMonthsCount, index, value, valueLength, errorCode); 1.760 + } 1.761 + 1.762 + static void 1.763 + setWeekday(DateFormatSymbols *syms, int32_t index, 1.764 + const UChar *value, int32_t valueLength, UErrorCode &errorCode) 1.765 + { 1.766 + setSymbol(syms->fWeekdays, syms->fWeekdaysCount, index, value, valueLength, errorCode); 1.767 + } 1.768 + 1.769 + static void 1.770 + setShortWeekday(DateFormatSymbols *syms, int32_t index, 1.771 + const UChar *value, int32_t valueLength, UErrorCode &errorCode) 1.772 + { 1.773 + setSymbol(syms->fShortWeekdays, syms->fShortWeekdaysCount, index, value, valueLength, errorCode); 1.774 + } 1.775 + 1.776 + static void 1.777 + setShorterWeekday(DateFormatSymbols *syms, int32_t index, 1.778 + const UChar *value, int32_t valueLength, UErrorCode &errorCode) 1.779 + { 1.780 + setSymbol(syms->fShorterWeekdays, syms->fShorterWeekdaysCount, index, value, valueLength, errorCode); 1.781 + } 1.782 + 1.783 + static void 1.784 + setNarrowWeekday(DateFormatSymbols *syms, int32_t index, 1.785 + const UChar *value, int32_t valueLength, UErrorCode &errorCode) 1.786 + { 1.787 + setSymbol(syms->fNarrowWeekdays, syms->fNarrowWeekdaysCount, index, value, valueLength, errorCode); 1.788 + } 1.789 + 1.790 + static void 1.791 + setStandaloneWeekday(DateFormatSymbols *syms, int32_t index, 1.792 + const UChar *value, int32_t valueLength, UErrorCode &errorCode) 1.793 + { 1.794 + setSymbol(syms->fStandaloneWeekdays, syms->fStandaloneWeekdaysCount, index, value, valueLength, errorCode); 1.795 + } 1.796 + 1.797 + static void 1.798 + setStandaloneShortWeekday(DateFormatSymbols *syms, int32_t index, 1.799 + const UChar *value, int32_t valueLength, UErrorCode &errorCode) 1.800 + { 1.801 + setSymbol(syms->fStandaloneShortWeekdays, syms->fStandaloneShortWeekdaysCount, index, value, valueLength, errorCode); 1.802 + } 1.803 + 1.804 + static void 1.805 + setStandaloneShorterWeekday(DateFormatSymbols *syms, int32_t index, 1.806 + const UChar *value, int32_t valueLength, UErrorCode &errorCode) 1.807 + { 1.808 + setSymbol(syms->fStandaloneShorterWeekdays, syms->fStandaloneShorterWeekdaysCount, index, value, valueLength, errorCode); 1.809 + } 1.810 + 1.811 + static void 1.812 + setStandaloneNarrowWeekday(DateFormatSymbols *syms, int32_t index, 1.813 + const UChar *value, int32_t valueLength, UErrorCode &errorCode) 1.814 + { 1.815 + setSymbol(syms->fStandaloneNarrowWeekdays, syms->fStandaloneNarrowWeekdaysCount, index, value, valueLength, errorCode); 1.816 + } 1.817 + 1.818 + static void 1.819 + setQuarter(DateFormatSymbols *syms, int32_t index, 1.820 + const UChar *value, int32_t valueLength, UErrorCode &errorCode) 1.821 + { 1.822 + setSymbol(syms->fQuarters, syms->fQuartersCount, index, value, valueLength, errorCode); 1.823 + } 1.824 + 1.825 + static void 1.826 + setShortQuarter(DateFormatSymbols *syms, int32_t index, 1.827 + const UChar *value, int32_t valueLength, UErrorCode &errorCode) 1.828 + { 1.829 + setSymbol(syms->fShortQuarters, syms->fShortQuartersCount, index, value, valueLength, errorCode); 1.830 + } 1.831 + 1.832 + static void 1.833 + setStandaloneQuarter(DateFormatSymbols *syms, int32_t index, 1.834 + const UChar *value, int32_t valueLength, UErrorCode &errorCode) 1.835 + { 1.836 + setSymbol(syms->fStandaloneQuarters, syms->fStandaloneQuartersCount, index, value, valueLength, errorCode); 1.837 + } 1.838 + 1.839 + static void 1.840 + setStandaloneShortQuarter(DateFormatSymbols *syms, int32_t index, 1.841 + const UChar *value, int32_t valueLength, UErrorCode &errorCode) 1.842 + { 1.843 + setSymbol(syms->fStandaloneShortQuarters, syms->fStandaloneShortQuartersCount, index, value, valueLength, errorCode); 1.844 + } 1.845 + 1.846 + static void 1.847 + setAmPm(DateFormatSymbols *syms, int32_t index, 1.848 + const UChar *value, int32_t valueLength, UErrorCode &errorCode) 1.849 + { 1.850 + setSymbol(syms->fAmPms, syms->fAmPmsCount, index, value, valueLength, errorCode); 1.851 + } 1.852 + 1.853 + static void 1.854 + setLocalPatternChars(DateFormatSymbols *syms, 1.855 + const UChar *value, int32_t valueLength, UErrorCode &errorCode) 1.856 + { 1.857 + setSymbol(&syms->fLocalPatternChars, 1, 0, value, valueLength, errorCode); 1.858 + } 1.859 +}; 1.860 + 1.861 +U_NAMESPACE_END 1.862 + 1.863 +U_CAPI void U_EXPORT2 1.864 +udat_setSymbols( UDateFormat *format, 1.865 + UDateFormatSymbolType type, 1.866 + int32_t index, 1.867 + UChar *value, 1.868 + int32_t valueLength, 1.869 + UErrorCode *status) 1.870 +{ 1.871 + verifyIsSimpleDateFormat(format, status); 1.872 + if(U_FAILURE(*status)) return; 1.873 + 1.874 + DateFormatSymbols *syms = (DateFormatSymbols *)((SimpleDateFormat *)format)->getDateFormatSymbols(); 1.875 + 1.876 + switch(type) { 1.877 + case UDAT_ERAS: 1.878 + DateFormatSymbolsSingleSetter::setEra(syms, index, value, valueLength, *status); 1.879 + break; 1.880 + 1.881 + case UDAT_ERA_NAMES: 1.882 + DateFormatSymbolsSingleSetter::setEraName(syms, index, value, valueLength, *status); 1.883 + break; 1.884 + 1.885 + case UDAT_MONTHS: 1.886 + DateFormatSymbolsSingleSetter::setMonth(syms, index, value, valueLength, *status); 1.887 + break; 1.888 + 1.889 + case UDAT_SHORT_MONTHS: 1.890 + DateFormatSymbolsSingleSetter::setShortMonth(syms, index, value, valueLength, *status); 1.891 + break; 1.892 + 1.893 + case UDAT_NARROW_MONTHS: 1.894 + DateFormatSymbolsSingleSetter::setNarrowMonth(syms, index, value, valueLength, *status); 1.895 + break; 1.896 + 1.897 + case UDAT_STANDALONE_MONTHS: 1.898 + DateFormatSymbolsSingleSetter::setStandaloneMonth(syms, index, value, valueLength, *status); 1.899 + break; 1.900 + 1.901 + case UDAT_STANDALONE_SHORT_MONTHS: 1.902 + DateFormatSymbolsSingleSetter::setStandaloneShortMonth(syms, index, value, valueLength, *status); 1.903 + break; 1.904 + 1.905 + case UDAT_STANDALONE_NARROW_MONTHS: 1.906 + DateFormatSymbolsSingleSetter::setStandaloneNarrowMonth(syms, index, value, valueLength, *status); 1.907 + break; 1.908 + 1.909 + case UDAT_WEEKDAYS: 1.910 + DateFormatSymbolsSingleSetter::setWeekday(syms, index, value, valueLength, *status); 1.911 + break; 1.912 + 1.913 + case UDAT_SHORT_WEEKDAYS: 1.914 + DateFormatSymbolsSingleSetter::setShortWeekday(syms, index, value, valueLength, *status); 1.915 + break; 1.916 + 1.917 + case UDAT_SHORTER_WEEKDAYS: 1.918 + DateFormatSymbolsSingleSetter::setShorterWeekday(syms, index, value, valueLength, *status); 1.919 + break; 1.920 + 1.921 + case UDAT_NARROW_WEEKDAYS: 1.922 + DateFormatSymbolsSingleSetter::setNarrowWeekday(syms, index, value, valueLength, *status); 1.923 + break; 1.924 + 1.925 + case UDAT_STANDALONE_WEEKDAYS: 1.926 + DateFormatSymbolsSingleSetter::setStandaloneWeekday(syms, index, value, valueLength, *status); 1.927 + break; 1.928 + 1.929 + case UDAT_STANDALONE_SHORT_WEEKDAYS: 1.930 + DateFormatSymbolsSingleSetter::setStandaloneShortWeekday(syms, index, value, valueLength, *status); 1.931 + break; 1.932 + 1.933 + case UDAT_STANDALONE_SHORTER_WEEKDAYS: 1.934 + DateFormatSymbolsSingleSetter::setStandaloneShorterWeekday(syms, index, value, valueLength, *status); 1.935 + break; 1.936 + 1.937 + case UDAT_STANDALONE_NARROW_WEEKDAYS: 1.938 + DateFormatSymbolsSingleSetter::setStandaloneNarrowWeekday(syms, index, value, valueLength, *status); 1.939 + break; 1.940 + 1.941 + case UDAT_QUARTERS: 1.942 + DateFormatSymbolsSingleSetter::setQuarter(syms, index, value, valueLength, *status); 1.943 + break; 1.944 + 1.945 + case UDAT_SHORT_QUARTERS: 1.946 + DateFormatSymbolsSingleSetter::setShortQuarter(syms, index, value, valueLength, *status); 1.947 + break; 1.948 + 1.949 + case UDAT_STANDALONE_QUARTERS: 1.950 + DateFormatSymbolsSingleSetter::setStandaloneQuarter(syms, index, value, valueLength, *status); 1.951 + break; 1.952 + 1.953 + case UDAT_STANDALONE_SHORT_QUARTERS: 1.954 + DateFormatSymbolsSingleSetter::setStandaloneShortQuarter(syms, index, value, valueLength, *status); 1.955 + break; 1.956 + 1.957 + case UDAT_AM_PMS: 1.958 + DateFormatSymbolsSingleSetter::setAmPm(syms, index, value, valueLength, *status); 1.959 + break; 1.960 + 1.961 + case UDAT_LOCALIZED_CHARS: 1.962 + DateFormatSymbolsSingleSetter::setLocalPatternChars(syms, value, valueLength, *status); 1.963 + break; 1.964 + 1.965 + default: 1.966 + *status = U_UNSUPPORTED_ERROR; 1.967 + break; 1.968 + 1.969 + } 1.970 +} 1.971 + 1.972 +U_CAPI const char* U_EXPORT2 1.973 +udat_getLocaleByType(const UDateFormat *fmt, 1.974 + ULocDataLocaleType type, 1.975 + UErrorCode* status) 1.976 +{ 1.977 + if (fmt == NULL) { 1.978 + if (U_SUCCESS(*status)) { 1.979 + *status = U_ILLEGAL_ARGUMENT_ERROR; 1.980 + } 1.981 + return NULL; 1.982 + } 1.983 + return ((Format*)fmt)->getLocaleID(type, *status); 1.984 +} 1.985 + 1.986 + 1.987 +U_CAPI void U_EXPORT2 1.988 +udat_setContext(UDateFormat* fmt, UDisplayContext value, UErrorCode* status) 1.989 +{ 1.990 + verifyIsSimpleDateFormat(fmt, status); 1.991 + if (U_FAILURE(*status)) { 1.992 + return; 1.993 + } 1.994 + ((SimpleDateFormat*)fmt)->setContext(value, *status); 1.995 +} 1.996 + 1.997 +U_CAPI UDisplayContext U_EXPORT2 1.998 +udat_getContext(UDateFormat* fmt, UDisplayContextType type, UErrorCode* status) 1.999 +{ 1.1000 + verifyIsSimpleDateFormat(fmt, status); 1.1001 + if (U_FAILURE(*status)) { 1.1002 + return (UDisplayContext)0; 1.1003 + } 1.1004 + return ((SimpleDateFormat*)fmt)->getContext(type, *status); 1.1005 +} 1.1006 + 1.1007 + 1.1008 +/** 1.1009 + * Verify that fmt is a RelativeDateFormat. Invalid error if not. 1.1010 + * @param fmt the UDateFormat, definitely a DateFormat, maybe something else 1.1011 + * @param status error code, will be set to failure if there is a familure or the fmt is NULL. 1.1012 + */ 1.1013 +static void verifyIsRelativeDateFormat(const UDateFormat* fmt, UErrorCode *status) { 1.1014 + if(U_SUCCESS(*status) && 1.1015 + dynamic_cast<const RelativeDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))==NULL) { 1.1016 + *status = U_ILLEGAL_ARGUMENT_ERROR; 1.1017 + } 1.1018 +} 1.1019 + 1.1020 + 1.1021 +U_CAPI int32_t U_EXPORT2 1.1022 +udat_toPatternRelativeDate(const UDateFormat *fmt, 1.1023 + UChar *result, 1.1024 + int32_t resultLength, 1.1025 + UErrorCode *status) 1.1026 +{ 1.1027 + verifyIsRelativeDateFormat(fmt, status); 1.1028 + if(U_FAILURE(*status)) return -1; 1.1029 + 1.1030 + UnicodeString datePattern; 1.1031 + if(!(result==NULL && resultLength==0)) { 1.1032 + // NULL destination for pure preflighting: empty dummy string 1.1033 + // otherwise, alias the destination buffer 1.1034 + datePattern.setTo(result, 0, resultLength); 1.1035 + } 1.1036 + ((RelativeDateFormat*)fmt)->toPatternDate(datePattern, *status); 1.1037 + return datePattern.extract(result, resultLength, *status); 1.1038 +} 1.1039 + 1.1040 +U_CAPI int32_t U_EXPORT2 1.1041 +udat_toPatternRelativeTime(const UDateFormat *fmt, 1.1042 + UChar *result, 1.1043 + int32_t resultLength, 1.1044 + UErrorCode *status) 1.1045 +{ 1.1046 + verifyIsRelativeDateFormat(fmt, status); 1.1047 + if(U_FAILURE(*status)) return -1; 1.1048 + 1.1049 + UnicodeString timePattern; 1.1050 + if(!(result==NULL && resultLength==0)) { 1.1051 + // NULL destination for pure preflighting: empty dummy string 1.1052 + // otherwise, alias the destination buffer 1.1053 + timePattern.setTo(result, 0, resultLength); 1.1054 + } 1.1055 + ((RelativeDateFormat*)fmt)->toPatternTime(timePattern, *status); 1.1056 + return timePattern.extract(result, resultLength, *status); 1.1057 +} 1.1058 + 1.1059 +U_CAPI void U_EXPORT2 1.1060 +udat_applyPatternRelative(UDateFormat *format, 1.1061 + const UChar *datePattern, 1.1062 + int32_t datePatternLength, 1.1063 + const UChar *timePattern, 1.1064 + int32_t timePatternLength, 1.1065 + UErrorCode *status) 1.1066 +{ 1.1067 + verifyIsRelativeDateFormat(format, status); 1.1068 + if(U_FAILURE(*status)) return; 1.1069 + const UnicodeString datePat((UBool)(datePatternLength == -1), datePattern, datePatternLength); 1.1070 + const UnicodeString timePat((UBool)(timePatternLength == -1), timePattern, timePatternLength); 1.1071 + ((RelativeDateFormat*)format)->applyPatterns(datePat, timePat, *status); 1.1072 +} 1.1073 + 1.1074 +#endif /* #if !UCONFIG_NO_FORMATTING */