ICU-8844 Clone fCalendar as necessary so it does not get modified by format or parse methods
X-SVN-Rev: 31017
This commit is contained in:
parent
8087532167
commit
3a8d6c31a9
@ -193,11 +193,15 @@ DateFormat::format(Calendar& /* unused cal */,
|
||||
UnicodeString&
|
||||
DateFormat::format(UDate date, UnicodeString& appendTo, FieldPosition& fieldPosition) const {
|
||||
if (fCalendar != NULL) {
|
||||
// Use our calendar instance
|
||||
UErrorCode ec = U_ZERO_ERROR;
|
||||
fCalendar->setTime(date, ec);
|
||||
if (U_SUCCESS(ec)) {
|
||||
return format(*fCalendar, appendTo, fieldPosition);
|
||||
// Use a clone of our calendar instance
|
||||
Calendar* calClone = fCalendar->clone();
|
||||
if (calClone != NULL) {
|
||||
UErrorCode ec = U_ZERO_ERROR;
|
||||
calClone->setTime(date, ec);
|
||||
if (U_SUCCESS(ec)) {
|
||||
format(*calClone, appendTo, fieldPosition);
|
||||
}
|
||||
delete calClone;
|
||||
}
|
||||
}
|
||||
return appendTo;
|
||||
@ -209,9 +213,13 @@ UnicodeString&
|
||||
DateFormat::format(UDate date, UnicodeString& appendTo, FieldPositionIterator* posIter,
|
||||
UErrorCode& status) const {
|
||||
if (fCalendar != NULL) {
|
||||
fCalendar->setTime(date, status);
|
||||
if (U_SUCCESS(status)) {
|
||||
return format(*fCalendar, appendTo, posIter, status);
|
||||
Calendar* calClone = fCalendar->clone();
|
||||
if (calClone != NULL) {
|
||||
calClone->setTime(date, status);
|
||||
if (U_SUCCESS(status)) {
|
||||
format(*calClone, appendTo, posIter, status);
|
||||
}
|
||||
delete calClone;
|
||||
}
|
||||
}
|
||||
return appendTo;
|
||||
@ -236,28 +244,25 @@ DateFormat::parse(const UnicodeString& text,
|
||||
{
|
||||
UDate d = 0; // Error return UDate is 0 (the epoch)
|
||||
if (fCalendar != NULL) {
|
||||
int32_t start = pos.getIndex();
|
||||
|
||||
// Parse may update TimeZone used by the calendar.
|
||||
TimeZone *tzsav = (TimeZone*)fCalendar->getTimeZone().clone();
|
||||
|
||||
fCalendar->clear();
|
||||
parse(text, *fCalendar, pos);
|
||||
if (pos.getIndex() != start) {
|
||||
UErrorCode ec = U_ZERO_ERROR;
|
||||
d = fCalendar->getTime(ec);
|
||||
if (U_FAILURE(ec)) {
|
||||
// We arrive here if fCalendar is non-lenient and there
|
||||
// is an out-of-range field. We don't know which field
|
||||
// was illegal so we set the error index to the start.
|
||||
pos.setIndex(start);
|
||||
pos.setErrorIndex(start);
|
||||
d = 0;
|
||||
Calendar* calClone = fCalendar->clone();
|
||||
if (calClone != NULL) {
|
||||
int32_t start = pos.getIndex();
|
||||
calClone->clear();
|
||||
parse(text, *calClone, pos);
|
||||
if (pos.getIndex() != start) {
|
||||
UErrorCode ec = U_ZERO_ERROR;
|
||||
d = calClone->getTime(ec);
|
||||
if (U_FAILURE(ec)) {
|
||||
// We arrive here if fCalendar => calClone is non-lenient and
|
||||
// there is an out-of-range field. We don't know which field
|
||||
// was illegal so we set the error index to the start.
|
||||
pos.setIndex(start);
|
||||
pos.setErrorIndex(start);
|
||||
d = 0;
|
||||
}
|
||||
}
|
||||
delete calClone;
|
||||
}
|
||||
|
||||
// Restore TimeZone
|
||||
fCalendar->adoptTimeZone(tzsav);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
@ -830,17 +830,25 @@ UnicodeString&
|
||||
SimpleDateFormat::_format(Calendar& cal, UnicodeString& appendTo, FieldPositionHandler& handler,
|
||||
UErrorCode& status) const
|
||||
{
|
||||
Calendar *workCal = &cal;
|
||||
TimeZone *backupTZ = NULL;
|
||||
if ( U_FAILURE(status) ) {
|
||||
return appendTo;
|
||||
}
|
||||
Calendar* workCal = &cal;
|
||||
Calendar* calClone = NULL;
|
||||
if (&cal != fCalendar && uprv_strcmp(cal.getType(), fCalendar->getType()) != 0) {
|
||||
// Different calendar type
|
||||
// We use the time and time zone from the input calendar, but
|
||||
// do not use the input calendar for field calculation.
|
||||
UDate t = cal.getTime(status);
|
||||
fCalendar->setTime(t, status);
|
||||
backupTZ = fCalendar->getTimeZone().clone();
|
||||
fCalendar->setTimeZone(cal.getTimeZone());
|
||||
workCal = fCalendar;
|
||||
calClone = fCalendar->clone();
|
||||
if (calClone != NULL) {
|
||||
UDate t = cal.getTime(status);
|
||||
calClone->setTime(t, status);
|
||||
calClone->setTimeZone(cal.getTimeZone());
|
||||
workCal = calClone;
|
||||
} else {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return appendTo;
|
||||
}
|
||||
}
|
||||
|
||||
UBool inQuote = FALSE;
|
||||
@ -885,9 +893,8 @@ SimpleDateFormat::_format(Calendar& cal, UnicodeString& appendTo, FieldPositionH
|
||||
subFormat(appendTo, prevCh, count, handler, *workCal, status);
|
||||
}
|
||||
|
||||
if (backupTZ != NULL) {
|
||||
// Restore the original time zone
|
||||
fCalendar->adoptTimeZone(backupTZ);
|
||||
if (calClone != NULL) {
|
||||
delete calClone;
|
||||
}
|
||||
|
||||
return appendTo;
|
||||
@ -1875,19 +1882,24 @@ SimpleDateFormat::parse(const UnicodeString& text, Calendar& cal, ParsePosition&
|
||||
|
||||
const UnicodeString numericFormatChars(NUMERIC_FORMAT_CHARS);
|
||||
|
||||
TimeZone *backupTZ = NULL;
|
||||
Calendar* calClone = NULL;
|
||||
Calendar *workCal = &cal;
|
||||
if (&cal != fCalendar && uprv_strcmp(cal.getType(), fCalendar->getType()) != 0) {
|
||||
// Different calendar type
|
||||
// We use the time/zone from the input calendar, but
|
||||
// do not use the input calendar for field calculation.
|
||||
fCalendar->setTime(cal.getTime(status),status);
|
||||
if (U_FAILURE(status)) {
|
||||
calClone = fCalendar->clone();
|
||||
if (calClone != NULL) {
|
||||
calClone->setTime(cal.getTime(status),status);
|
||||
if (U_FAILURE(status)) {
|
||||
goto ExitParse;
|
||||
}
|
||||
calClone->setTimeZone(cal.getTimeZone());
|
||||
workCal = calClone;
|
||||
} else {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
goto ExitParse;
|
||||
}
|
||||
backupTZ = fCalendar->getTimeZone().clone();
|
||||
fCalendar->setTimeZone(cal.getTimeZone());
|
||||
workCal = fCalendar;
|
||||
}
|
||||
|
||||
for (int32_t i=0; i<fPattern.length(); ++i) {
|
||||
@ -2187,9 +2199,8 @@ ExitParse:
|
||||
cal.setTime(workCal->getTime(status), status);
|
||||
}
|
||||
|
||||
// Restore the original time zone if required
|
||||
if (backupTZ != NULL) {
|
||||
fCalendar->adoptTimeZone(backupTZ);
|
||||
if (calClone != NULL) {
|
||||
delete calClone;
|
||||
}
|
||||
|
||||
// If any Calendar calls failed, we pretend that we
|
||||
|
Loading…
Reference in New Issue
Block a user