ICU-13602 Check error status for lazily instantiated TiemZoneFormat in SimpleDateFormat.
X-SVN-Rev: 41413
This commit is contained in:
parent
2627d76fbe
commit
9cc7d14b62
@ -1695,100 +1695,101 @@ SimpleDateFormat::subFormat(UnicodeString &appendTo,
|
|||||||
UnicodeString zoneString(zsbuf, 0, UPRV_LENGTHOF(zsbuf));
|
UnicodeString zoneString(zsbuf, 0, UPRV_LENGTHOF(zsbuf));
|
||||||
const TimeZone& tz = cal.getTimeZone();
|
const TimeZone& tz = cal.getTimeZone();
|
||||||
UDate date = cal.getTime(status);
|
UDate date = cal.getTime(status);
|
||||||
|
const TimeZoneFormat *tzfmt = tzFormat(status);
|
||||||
if (U_SUCCESS(status)) {
|
if (U_SUCCESS(status)) {
|
||||||
if (patternCharIndex == UDAT_TIMEZONE_FIELD) {
|
if (patternCharIndex == UDAT_TIMEZONE_FIELD) {
|
||||||
if (count < 4) {
|
if (count < 4) {
|
||||||
// "z", "zz", "zzz"
|
// "z", "zz", "zzz"
|
||||||
tzFormat()->format(UTZFMT_STYLE_SPECIFIC_SHORT, tz, date, zoneString);
|
tzfmt->format(UTZFMT_STYLE_SPECIFIC_SHORT, tz, date, zoneString);
|
||||||
capContextUsageType = DateFormatSymbols::kCapContextUsageMetazoneShort;
|
capContextUsageType = DateFormatSymbols::kCapContextUsageMetazoneShort;
|
||||||
} else {
|
} else {
|
||||||
// "zzzz" or longer
|
// "zzzz" or longer
|
||||||
tzFormat()->format(UTZFMT_STYLE_SPECIFIC_LONG, tz, date, zoneString);
|
tzfmt->format(UTZFMT_STYLE_SPECIFIC_LONG, tz, date, zoneString);
|
||||||
capContextUsageType = DateFormatSymbols::kCapContextUsageMetazoneLong;
|
capContextUsageType = DateFormatSymbols::kCapContextUsageMetazoneLong;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (patternCharIndex == UDAT_TIMEZONE_RFC_FIELD) {
|
else if (patternCharIndex == UDAT_TIMEZONE_RFC_FIELD) {
|
||||||
if (count < 4) {
|
if (count < 4) {
|
||||||
// "Z"
|
// "Z"
|
||||||
tzFormat()->format(UTZFMT_STYLE_ISO_BASIC_LOCAL_FULL, tz, date, zoneString);
|
tzfmt->format(UTZFMT_STYLE_ISO_BASIC_LOCAL_FULL, tz, date, zoneString);
|
||||||
} else if (count == 5) {
|
} else if (count == 5) {
|
||||||
// "ZZZZZ"
|
// "ZZZZZ"
|
||||||
tzFormat()->format(UTZFMT_STYLE_ISO_EXTENDED_FULL, tz, date, zoneString);
|
tzfmt->format(UTZFMT_STYLE_ISO_EXTENDED_FULL, tz, date, zoneString);
|
||||||
} else {
|
} else {
|
||||||
// "ZZ", "ZZZ", "ZZZZ"
|
// "ZZ", "ZZZ", "ZZZZ"
|
||||||
tzFormat()->format(UTZFMT_STYLE_LOCALIZED_GMT, tz, date, zoneString);
|
tzfmt->format(UTZFMT_STYLE_LOCALIZED_GMT, tz, date, zoneString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (patternCharIndex == UDAT_TIMEZONE_GENERIC_FIELD) {
|
else if (patternCharIndex == UDAT_TIMEZONE_GENERIC_FIELD) {
|
||||||
if (count == 1) {
|
if (count == 1) {
|
||||||
// "v"
|
// "v"
|
||||||
tzFormat()->format(UTZFMT_STYLE_GENERIC_SHORT, tz, date, zoneString);
|
tzfmt->format(UTZFMT_STYLE_GENERIC_SHORT, tz, date, zoneString);
|
||||||
capContextUsageType = DateFormatSymbols::kCapContextUsageMetazoneShort;
|
capContextUsageType = DateFormatSymbols::kCapContextUsageMetazoneShort;
|
||||||
} else if (count == 4) {
|
} else if (count == 4) {
|
||||||
// "vvvv"
|
// "vvvv"
|
||||||
tzFormat()->format(UTZFMT_STYLE_GENERIC_LONG, tz, date, zoneString);
|
tzfmt->format(UTZFMT_STYLE_GENERIC_LONG, tz, date, zoneString);
|
||||||
capContextUsageType = DateFormatSymbols::kCapContextUsageMetazoneLong;
|
capContextUsageType = DateFormatSymbols::kCapContextUsageMetazoneLong;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (patternCharIndex == UDAT_TIMEZONE_SPECIAL_FIELD) {
|
else if (patternCharIndex == UDAT_TIMEZONE_SPECIAL_FIELD) {
|
||||||
if (count == 1) {
|
if (count == 1) {
|
||||||
// "V"
|
// "V"
|
||||||
tzFormat()->format(UTZFMT_STYLE_ZONE_ID_SHORT, tz, date, zoneString);
|
tzfmt->format(UTZFMT_STYLE_ZONE_ID_SHORT, tz, date, zoneString);
|
||||||
} else if (count == 2) {
|
} else if (count == 2) {
|
||||||
// "VV"
|
// "VV"
|
||||||
tzFormat()->format(UTZFMT_STYLE_ZONE_ID, tz, date, zoneString);
|
tzfmt->format(UTZFMT_STYLE_ZONE_ID, tz, date, zoneString);
|
||||||
} else if (count == 3) {
|
} else if (count == 3) {
|
||||||
// "VVV"
|
// "VVV"
|
||||||
tzFormat()->format(UTZFMT_STYLE_EXEMPLAR_LOCATION, tz, date, zoneString);
|
tzfmt->format(UTZFMT_STYLE_EXEMPLAR_LOCATION, tz, date, zoneString);
|
||||||
} else if (count == 4) {
|
} else if (count == 4) {
|
||||||
// "VVVV"
|
// "VVVV"
|
||||||
tzFormat()->format(UTZFMT_STYLE_GENERIC_LOCATION, tz, date, zoneString);
|
tzfmt->format(UTZFMT_STYLE_GENERIC_LOCATION, tz, date, zoneString);
|
||||||
capContextUsageType = DateFormatSymbols::kCapContextUsageZoneLong;
|
capContextUsageType = DateFormatSymbols::kCapContextUsageZoneLong;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (patternCharIndex == UDAT_TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD) {
|
else if (patternCharIndex == UDAT_TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD) {
|
||||||
if (count == 1) {
|
if (count == 1) {
|
||||||
// "O"
|
// "O"
|
||||||
tzFormat()->format(UTZFMT_STYLE_LOCALIZED_GMT_SHORT, tz, date, zoneString);
|
tzfmt->format(UTZFMT_STYLE_LOCALIZED_GMT_SHORT, tz, date, zoneString);
|
||||||
} else if (count == 4) {
|
} else if (count == 4) {
|
||||||
// "OOOO"
|
// "OOOO"
|
||||||
tzFormat()->format(UTZFMT_STYLE_LOCALIZED_GMT, tz, date, zoneString);
|
tzfmt->format(UTZFMT_STYLE_LOCALIZED_GMT, tz, date, zoneString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (patternCharIndex == UDAT_TIMEZONE_ISO_FIELD) {
|
else if (patternCharIndex == UDAT_TIMEZONE_ISO_FIELD) {
|
||||||
if (count == 1) {
|
if (count == 1) {
|
||||||
// "X"
|
// "X"
|
||||||
tzFormat()->format(UTZFMT_STYLE_ISO_BASIC_SHORT, tz, date, zoneString);
|
tzfmt->format(UTZFMT_STYLE_ISO_BASIC_SHORT, tz, date, zoneString);
|
||||||
} else if (count == 2) {
|
} else if (count == 2) {
|
||||||
// "XX"
|
// "XX"
|
||||||
tzFormat()->format(UTZFMT_STYLE_ISO_BASIC_FIXED, tz, date, zoneString);
|
tzfmt->format(UTZFMT_STYLE_ISO_BASIC_FIXED, tz, date, zoneString);
|
||||||
} else if (count == 3) {
|
} else if (count == 3) {
|
||||||
// "XXX"
|
// "XXX"
|
||||||
tzFormat()->format(UTZFMT_STYLE_ISO_EXTENDED_FIXED, tz, date, zoneString);
|
tzfmt->format(UTZFMT_STYLE_ISO_EXTENDED_FIXED, tz, date, zoneString);
|
||||||
} else if (count == 4) {
|
} else if (count == 4) {
|
||||||
// "XXXX"
|
// "XXXX"
|
||||||
tzFormat()->format(UTZFMT_STYLE_ISO_BASIC_FULL, tz, date, zoneString);
|
tzfmt->format(UTZFMT_STYLE_ISO_BASIC_FULL, tz, date, zoneString);
|
||||||
} else if (count == 5) {
|
} else if (count == 5) {
|
||||||
// "XXXXX"
|
// "XXXXX"
|
||||||
tzFormat()->format(UTZFMT_STYLE_ISO_EXTENDED_FULL, tz, date, zoneString);
|
tzfmt->format(UTZFMT_STYLE_ISO_EXTENDED_FULL, tz, date, zoneString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (patternCharIndex == UDAT_TIMEZONE_ISO_LOCAL_FIELD) {
|
else if (patternCharIndex == UDAT_TIMEZONE_ISO_LOCAL_FIELD) {
|
||||||
if (count == 1) {
|
if (count == 1) {
|
||||||
// "x"
|
// "x"
|
||||||
tzFormat()->format(UTZFMT_STYLE_ISO_BASIC_LOCAL_SHORT, tz, date, zoneString);
|
tzfmt->format(UTZFMT_STYLE_ISO_BASIC_LOCAL_SHORT, tz, date, zoneString);
|
||||||
} else if (count == 2) {
|
} else if (count == 2) {
|
||||||
// "xx"
|
// "xx"
|
||||||
tzFormat()->format(UTZFMT_STYLE_ISO_BASIC_LOCAL_FIXED, tz, date, zoneString);
|
tzfmt->format(UTZFMT_STYLE_ISO_BASIC_LOCAL_FIXED, tz, date, zoneString);
|
||||||
} else if (count == 3) {
|
} else if (count == 3) {
|
||||||
// "xxx"
|
// "xxx"
|
||||||
tzFormat()->format(UTZFMT_STYLE_ISO_EXTENDED_LOCAL_FIXED, tz, date, zoneString);
|
tzfmt->format(UTZFMT_STYLE_ISO_EXTENDED_LOCAL_FIXED, tz, date, zoneString);
|
||||||
} else if (count == 4) {
|
} else if (count == 4) {
|
||||||
// "xxxx"
|
// "xxxx"
|
||||||
tzFormat()->format(UTZFMT_STYLE_ISO_BASIC_LOCAL_FULL, tz, date, zoneString);
|
tzfmt->format(UTZFMT_STYLE_ISO_BASIC_LOCAL_FULL, tz, date, zoneString);
|
||||||
} else if (count == 5) {
|
} else if (count == 5) {
|
||||||
// "xxxxx"
|
// "xxxxx"
|
||||||
tzFormat()->format(UTZFMT_STYLE_ISO_EXTENDED_LOCAL_FULL, tz, date, zoneString);
|
tzfmt->format(UTZFMT_STYLE_ISO_EXTENDED_LOCAL_FULL, tz, date, zoneString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -3393,32 +3394,42 @@ int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, UC
|
|||||||
case UDAT_TIMEZONE_FIELD: // 'z'
|
case UDAT_TIMEZONE_FIELD: // 'z'
|
||||||
{
|
{
|
||||||
UTimeZoneFormatStyle style = (count < 4) ? UTZFMT_STYLE_SPECIFIC_SHORT : UTZFMT_STYLE_SPECIFIC_LONG;
|
UTimeZoneFormatStyle style = (count < 4) ? UTZFMT_STYLE_SPECIFIC_SHORT : UTZFMT_STYLE_SPECIFIC_LONG;
|
||||||
TimeZone *tz = tzFormat()->parse(style, text, pos, tzTimeType);
|
const TimeZoneFormat *tzfmt = tzFormat(status);
|
||||||
|
if (U_SUCCESS(status)) {
|
||||||
|
TimeZone *tz = tzfmt->parse(style, text, pos, tzTimeType);
|
||||||
if (tz != NULL) {
|
if (tz != NULL) {
|
||||||
cal.adoptTimeZone(tz);
|
cal.adoptTimeZone(tz);
|
||||||
return pos.getIndex();
|
return pos.getIndex();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return -start;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case UDAT_TIMEZONE_RFC_FIELD: // 'Z'
|
case UDAT_TIMEZONE_RFC_FIELD: // 'Z'
|
||||||
{
|
{
|
||||||
UTimeZoneFormatStyle style = (count < 4) ?
|
UTimeZoneFormatStyle style = (count < 4) ?
|
||||||
UTZFMT_STYLE_ISO_BASIC_LOCAL_FULL : ((count == 5) ? UTZFMT_STYLE_ISO_EXTENDED_FULL: UTZFMT_STYLE_LOCALIZED_GMT);
|
UTZFMT_STYLE_ISO_BASIC_LOCAL_FULL : ((count == 5) ? UTZFMT_STYLE_ISO_EXTENDED_FULL: UTZFMT_STYLE_LOCALIZED_GMT);
|
||||||
TimeZone *tz = tzFormat()->parse(style, text, pos, tzTimeType);
|
const TimeZoneFormat *tzfmt = tzFormat(status);
|
||||||
|
if (U_SUCCESS(status)) {
|
||||||
|
TimeZone *tz = tzfmt->parse(style, text, pos, tzTimeType);
|
||||||
if (tz != NULL) {
|
if (tz != NULL) {
|
||||||
cal.adoptTimeZone(tz);
|
cal.adoptTimeZone(tz);
|
||||||
return pos.getIndex();
|
return pos.getIndex();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return -start;
|
return -start;
|
||||||
}
|
}
|
||||||
case UDAT_TIMEZONE_GENERIC_FIELD: // 'v'
|
case UDAT_TIMEZONE_GENERIC_FIELD: // 'v'
|
||||||
{
|
{
|
||||||
UTimeZoneFormatStyle style = (count < 4) ? UTZFMT_STYLE_GENERIC_SHORT : UTZFMT_STYLE_GENERIC_LONG;
|
UTimeZoneFormatStyle style = (count < 4) ? UTZFMT_STYLE_GENERIC_SHORT : UTZFMT_STYLE_GENERIC_LONG;
|
||||||
TimeZone *tz = tzFormat()->parse(style, text, pos, tzTimeType);
|
const TimeZoneFormat *tzfmt = tzFormat(status);
|
||||||
|
if (U_SUCCESS(status)) {
|
||||||
|
TimeZone *tz = tzfmt->parse(style, text, pos, tzTimeType);
|
||||||
if (tz != NULL) {
|
if (tz != NULL) {
|
||||||
cal.adoptTimeZone(tz);
|
cal.adoptTimeZone(tz);
|
||||||
return pos.getIndex();
|
return pos.getIndex();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return -start;
|
return -start;
|
||||||
}
|
}
|
||||||
case UDAT_TIMEZONE_SPECIAL_FIELD: // 'V'
|
case UDAT_TIMEZONE_SPECIAL_FIELD: // 'V'
|
||||||
@ -3438,21 +3449,27 @@ int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, UC
|
|||||||
style = UTZFMT_STYLE_GENERIC_LOCATION;
|
style = UTZFMT_STYLE_GENERIC_LOCATION;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
TimeZone *tz = tzFormat()->parse(style, text, pos, tzTimeType);
|
const TimeZoneFormat *tzfmt = tzFormat(status);
|
||||||
|
if (U_SUCCESS(status)) {
|
||||||
|
TimeZone *tz = tzfmt->parse(style, text, pos, tzTimeType);
|
||||||
if (tz != NULL) {
|
if (tz != NULL) {
|
||||||
cal.adoptTimeZone(tz);
|
cal.adoptTimeZone(tz);
|
||||||
return pos.getIndex();
|
return pos.getIndex();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return -start;
|
return -start;
|
||||||
}
|
}
|
||||||
case UDAT_TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD: // 'O'
|
case UDAT_TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD: // 'O'
|
||||||
{
|
{
|
||||||
UTimeZoneFormatStyle style = (count < 4) ? UTZFMT_STYLE_LOCALIZED_GMT_SHORT : UTZFMT_STYLE_LOCALIZED_GMT;
|
UTimeZoneFormatStyle style = (count < 4) ? UTZFMT_STYLE_LOCALIZED_GMT_SHORT : UTZFMT_STYLE_LOCALIZED_GMT;
|
||||||
TimeZone *tz = tzFormat()->parse(style, text, pos, tzTimeType);
|
const TimeZoneFormat *tzfmt = tzFormat(status);
|
||||||
|
if (U_SUCCESS(status)) {
|
||||||
|
TimeZone *tz = tzfmt->parse(style, text, pos, tzTimeType);
|
||||||
if (tz != NULL) {
|
if (tz != NULL) {
|
||||||
cal.adoptTimeZone(tz);
|
cal.adoptTimeZone(tz);
|
||||||
return pos.getIndex();
|
return pos.getIndex();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return -start;
|
return -start;
|
||||||
}
|
}
|
||||||
case UDAT_TIMEZONE_ISO_FIELD: // 'X'
|
case UDAT_TIMEZONE_ISO_FIELD: // 'X'
|
||||||
@ -3475,11 +3492,14 @@ int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, UC
|
|||||||
style = UTZFMT_STYLE_ISO_EXTENDED_FULL;
|
style = UTZFMT_STYLE_ISO_EXTENDED_FULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
TimeZone *tz = tzFormat()->parse(style, text, pos, tzTimeType);
|
const TimeZoneFormat *tzfmt = tzFormat(status);
|
||||||
|
if (U_SUCCESS(status)) {
|
||||||
|
TimeZone *tz = tzfmt->parse(style, text, pos, tzTimeType);
|
||||||
if (tz != NULL) {
|
if (tz != NULL) {
|
||||||
cal.adoptTimeZone(tz);
|
cal.adoptTimeZone(tz);
|
||||||
return pos.getIndex();
|
return pos.getIndex();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return -start;
|
return -start;
|
||||||
}
|
}
|
||||||
case UDAT_TIMEZONE_ISO_LOCAL_FIELD: // 'x'
|
case UDAT_TIMEZONE_ISO_LOCAL_FIELD: // 'x'
|
||||||
@ -3502,11 +3522,14 @@ int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, UC
|
|||||||
style = UTZFMT_STYLE_ISO_EXTENDED_LOCAL_FULL;
|
style = UTZFMT_STYLE_ISO_EXTENDED_LOCAL_FULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
TimeZone *tz = tzFormat()->parse(style, text, pos, tzTimeType);
|
const TimeZoneFormat *tzfmt = tzFormat(status);
|
||||||
|
if (U_SUCCESS(status)) {
|
||||||
|
TimeZone *tz = tzfmt->parse(style, text, pos, tzTimeType);
|
||||||
if (tz != NULL) {
|
if (tz != NULL) {
|
||||||
cal.adoptTimeZone(tz);
|
cal.adoptTimeZone(tz);
|
||||||
return pos.getIndex();
|
return pos.getIndex();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return -start;
|
return -start;
|
||||||
}
|
}
|
||||||
// currently no pattern character is defined for UDAT_TIME_SEPARATOR_FIELD
|
// currently no pattern character is defined for UDAT_TIME_SEPARATOR_FIELD
|
||||||
@ -3856,7 +3879,13 @@ SimpleDateFormat::setDateFormatSymbols(const DateFormatSymbols& newFormatSymbols
|
|||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
const TimeZoneFormat*
|
const TimeZoneFormat*
|
||||||
SimpleDateFormat::getTimeZoneFormat(void) const {
|
SimpleDateFormat::getTimeZoneFormat(void) const {
|
||||||
return (const TimeZoneFormat*)tzFormat();
|
// TimeZoneFormat initialization might fail when out of memory.
|
||||||
|
// If we always initialize TimeZoneFormat instance, we can return
|
||||||
|
// such status there. For now, this implementation lazily instantiates
|
||||||
|
// a TimeZoneFormat for performance optimization reasons, but cannot
|
||||||
|
// propagate such error (probably just out of memory case) to the caller.
|
||||||
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
|
return (const TimeZoneFormat*)tzFormat(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
@ -4123,12 +4152,11 @@ SimpleDateFormat::skipUWhiteSpace(const UnicodeString& text, int32_t pos) const
|
|||||||
|
|
||||||
// Lazy TimeZoneFormat instantiation, semantically const.
|
// Lazy TimeZoneFormat instantiation, semantically const.
|
||||||
TimeZoneFormat *
|
TimeZoneFormat *
|
||||||
SimpleDateFormat::tzFormat() const {
|
SimpleDateFormat::tzFormat(UErrorCode &status) const {
|
||||||
if (fTimeZoneFormat == NULL) {
|
if (fTimeZoneFormat == NULL) {
|
||||||
umtx_lock(&LOCK);
|
umtx_lock(&LOCK);
|
||||||
{
|
{
|
||||||
if (fTimeZoneFormat == NULL) {
|
if (fTimeZoneFormat == NULL) {
|
||||||
UErrorCode status = U_ZERO_ERROR;
|
|
||||||
TimeZoneFormat *tzfmt = TimeZoneFormat::createInstance(fLocale, status);
|
TimeZoneFormat *tzfmt = TimeZoneFormat::createInstance(fLocale, status);
|
||||||
if (U_FAILURE(status)) {
|
if (U_FAILURE(status)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1518,7 +1518,7 @@ private:
|
|||||||
/**
|
/**
|
||||||
* Lazy TimeZoneFormat instantiation, semantically const
|
* Lazy TimeZoneFormat instantiation, semantically const
|
||||||
*/
|
*/
|
||||||
TimeZoneFormat *tzFormat() const;
|
TimeZoneFormat *tzFormat(UErrorCode &status) const;
|
||||||
|
|
||||||
const NumberFormat* getNumberFormatByIndex(UDateFormatField index) const;
|
const NumberFormat* getNumberFormatByIndex(UDateFormatField index) const;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user