ICU-10858 Fix missing fTimeZoneFormat assignment in SimpleDateFormat::operator= (#963)
diff --git a/icu4c/source/i18n/smpdtfmt.cpp b/icu4c/source/i18n/smpdtfmt.cpp
index 6246e8f..d704642 100644
--- a/icu4c/source/i18n/smpdtfmt.cpp
+++ b/icu4c/source/i18n/smpdtfmt.cpp
@@ -583,11 +583,14 @@
     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
diff --git a/icu4c/source/test/intltest/dtfmrgts.cpp b/icu4c/source/test/intltest/dtfmrgts.cpp
index 7b772f1..b72f0df 100644
--- a/icu4c/source/test/intltest/dtfmrgts.cpp
+++ b/icu4c/source/test/intltest/dtfmrgts.cpp
@@ -63,8 +63,9 @@
         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::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
diff --git a/icu4c/source/test/intltest/dtfmrgts.h b/icu4c/source/test/intltest/dtfmrgts.h
index 305487d..ecad431 100644
--- a/icu4c/source/test/intltest/dtfmrgts.h
+++ b/icu4c/source/test/intltest/dtfmrgts.h
@@ -59,6 +59,7 @@
     void TestT10334(void);
     void TestT10619(void);
     void TestT10855(void);
+    void TestT10858(void);
     void TestT10906(void);
     void TestT13380(void);
  };