ICU-10858 Fix missing fTimeZoneFormat assignment in SimpleDateFormat::operator= (#963)

This commit is contained in:
Campion 2020-01-14 12:07:24 -05:00 committed by pedberg-icu
parent c163f7dc29
commit b525045209
3 changed files with 51 additions and 7 deletions

View file

@ -583,11 +583,14 @@ SimpleDateFormat& SimpleDateFormat::operator=(const SimpleDateFormat& other)
fHasMinute = other.fHasMinute;
fHasSecond = other.fHasSecond;
// TimeZoneFormat in ICU4C only depends on a locale for now
if (fLocale != other.fLocale) {
delete fTimeZoneFormat;
fTimeZoneFormat = NULL; // forces lazy instantiation with the other locale
fLocale = other.fLocale;
fLocale = other.fLocale;
// TimeZoneFormat can now be set independently via setter.
// If it is NULL, it will be lazily initialized from locale
delete fTimeZoneFormat;
fTimeZoneFormat = NULL;
if (other.fTimeZoneFormat) {
fTimeZoneFormat = new TimeZoneFormat(*other.fTimeZoneFormat);
}
#if !UCONFIG_NO_BREAK_ITERATION

View file

@ -63,8 +63,9 @@ DateFormatRegressionTest::runIndexedTest( int32_t index, UBool exec, const char*
CASE(30,TestT10334)
CASE(31,TestT10619)
CASE(32,TestT10855)
CASE(33,TestT10906)
CASE(34,TestT13380)
CASE(33,TestT10858)
CASE(34,TestT10906)
CASE(35,TestT13380)
default: name = ""; break;
}
}
@ -1762,6 +1763,45 @@ void DateFormatRegressionTest::TestT13380(void) {
}
}
void DateFormatRegressionTest::TestT10858(void) {
// test for assignment operator on instances with the same locale but different TimeZoneFormat
UErrorCode status = U_ZERO_ERROR;
UnicodeString pattern("VVVV");
Locale loc("en_US");
// Make two identical Formats
SimpleDateFormat fmt_rhs(pattern, loc, status);
SimpleDateFormat fmt_lhs(pattern, loc, status);
// Setup a custom TimeZoneFormat
TimeZoneFormat* tzFmt = TimeZoneFormat::createInstance(Locale("de_DE"), status);
tzFmt->setGMTPattern(UnicodeString("UTC{0}"), status);
tzFmt->setGMTZeroFormat(UnicodeString("UTC"), status);
// Set custom TimeZoneFormat in fmt1 before assignment. Use
// adoptTimeZoneFormat instead of setTimeZoneFormat to delegate
// cleanup of tzFmt to SimpleDateFormat
fmt_rhs.adoptTimeZoneFormat(tzFmt);
// Make sure TimeZoneFormat is DIFFERENT between fmt_lhs & fmt_rhs at this point.
// Direct comparison with TimeZoneFormat::operator== does not suffice as it only
// checks for 'semantically equal' rather than 'identical' -- compare results of
// SimpleDateFormat::format() instead
UnicodeString res_rhs; fmt_rhs.format(0.0, res_rhs);
UnicodeString res_lhs_pre_assign; fmt_lhs.format(0.0, res_lhs_pre_assign);
if (res_lhs_pre_assign == res_rhs) {
errln(UnicodeString("Error: adoptTimeZoneFormat failed to set custom TimeZoneFormat into 'fmt_rhs'"));
}
// Invoke assignment operator and make sure formatted outputs from both objects are
// now identical (i.e. TimeZoneFormat, among other members, is correctly copied to LHS)
fmt_lhs = fmt_rhs;
UnicodeString res_lhs_post_assign; fmt_lhs.format(0.0, res_lhs_post_assign);
if (res_lhs_post_assign != res_rhs) {
errln(UnicodeString("Error: assigned instance did not take up TimeZoneFormat from original"));
}
}
#endif /* #if !UCONFIG_NO_FORMATTING */
//eof

View file

@ -59,6 +59,7 @@ public:
void TestT10334(void);
void TestT10619(void);
void TestT10855(void);
void TestT10858(void);
void TestT10906(void);
void TestT13380(void);
};