ICU-13820 ICU4C should use "Etc/Unknown" zone when host TZ detection fails.
Update API docs comments to clarify what is returned in failure cases.
diff --git a/icu4c/source/common/putil.cpp b/icu4c/source/common/putil.cpp
index cdfaed9..9ed85c0 100644
--- a/icu4c/source/common/putil.cpp
+++ b/icu4c/source/common/putil.cpp
@@ -1068,7 +1068,7 @@
     // the other code path returns a pointer to a heap location.
     // If we don't have a name already, then tzname wouldn't be any
     // better, so just fall back.
-    return uprv_strdup("Etc/UTC");
+    return uprv_strdup("");
 #endif // !U_TZNAME
 
 #else
diff --git a/icu4c/source/i18n/timezone.cpp b/icu4c/source/i18n/timezone.cpp
index b8fe13a..f8711e4 100644
--- a/icu4c/source/i18n/timezone.cpp
+++ b/icu4c/source/i18n/timezone.cpp
@@ -456,10 +456,11 @@
 TimeZone* U_EXPORT2
 TimeZone::detectHostTimeZone()
 {
-    // We access system timezone data through TPlatformUtilities,
-    // including tzset(), timezone, and tzname[].
+    // We access system timezone data through uprv_tzset(), uprv_tzname(), and others,
+    // which have platform specific implementations in putil.cpp
     int32_t rawOffset = 0;
     const char *hostID;
+    UBool hostDetectionSucceeded = TRUE;
 
     // First, try to create a system timezone, based
     // on the string ID in tzname[0].
@@ -470,8 +471,7 @@
 
     // Get the timezone ID from the host.  This function should do
     // any required host-specific remapping; e.g., on Windows this
-    // function maps the Date and Time control panel setting to an
-    // ICU timezone ID.
+    // function maps the Windows Time Zone name to an ICU timezone ID.
     hostID = uprv_tzname(0);
 
     // Invert sign because UNIX semantics are backwards
@@ -479,10 +479,15 @@
 
     TimeZone* hostZone = NULL;
 
-    /* Make sure that the string is NULL terminated to prevent BoundsChecker/Purify warnings. */
     UnicodeString hostStrID(hostID, -1, US_INV);
-    hostStrID.append((UChar)0);
-    hostStrID.truncate(hostStrID.length()-1);
+
+    if (hostStrID.length() == 0) {
+        // The host time zone detection (or remapping) above has failed and
+        // we have no name at all. Fallback to using the Unknown zone.
+        hostStrID = UnicodeString(TRUE, UNKNOWN_ZONE_ID, UNKNOWN_ZONE_ID_LENGTH);
+        hostDetectionSucceeded = FALSE;
+    }
+
     hostZone = createSystemTimeZone(hostStrID);
 
 #if U_PLATFORM_USES_ONLY_WIN32_API
@@ -502,19 +507,19 @@
 
     // Construct a fixed standard zone with the host's ID
     // and raw offset.
-    if (hostZone == NULL) {
+    if (hostZone == NULL && hostDetectionSucceeded) {
         hostZone = new SimpleTimeZone(rawOffset, hostStrID);
     }
 
-    // If we _still_ don't have a time zone, use GMT.
+    // If we _still_ don't have a time zone, use the Unknown zone.
     //
     // Note: This is extremely unlikely situation. If
     // new SimpleTimeZone(...) above fails, the following
     // code may also fail.
     if (hostZone == NULL) {
-        const TimeZone* temptz = TimeZone::getGMT();
-        // GMT zone uses staticly allocated memory, so creation of it can never fail due to OOM.
-        hostZone = temptz->clone();
+        // Unknown zone uses static allocated memory, so it must always exist.
+        // However, clone() allocates memory and can fail.
+        hostZone = TimeZone::getUnknown().clone();
     }
 
     return hostZone;
diff --git a/icu4c/source/i18n/unicode/timezone.h b/icu4c/source/i18n/unicode/timezone.h
index bc15bbf..de558f9 100644
--- a/icu4c/source/i18n/unicode/timezone.h
+++ b/icu4c/source/i18n/unicode/timezone.h
@@ -277,17 +277,25 @@
 
     /**
      * Creates an instance of TimeZone detected from the current host
-     * system configuration. Note that ICU4C does not change the default
-     * time zone unless TimeZone::adoptDefault(TimeZone*) or
-     * TimeZone::setDefault(const TimeZone&) is explicitly called by a
+     * system configuration. If the host system detection routines fail,
+     * or if they specify a TimeZone or TimeZone offset which is not
+     * recognized, then the special TimeZone "Etc/Unknown" is returned.
+     * 
+     * Note that ICU4C does not change the default time zone unless
+     * `TimeZone::adoptDefault(TimeZone*)` or 
+     * `TimeZone::setDefault(const TimeZone&)` is explicitly called by a
      * user. This method does not update the current ICU's default,
      * and may return a different TimeZone from the one returned by
-     * TimeZone::createDefault().
+     * `TimeZone::createDefault()`.
      *
      * <p>This function is not thread safe.</p>
      *
      * @return  A new instance of TimeZone detected from the current host system
      *          configuration.
+     * @see adoptDefault
+     * @see setDefault
+     * @see createDefault
+     * @see getUnknown
      * @stable ICU 55
      */
     static TimeZone* U_EXPORT2 detectHostTimeZone();
@@ -295,13 +303,14 @@
     /**
      * Creates a new copy of the default TimeZone for this host. Unless the default time
      * zone has already been set using adoptDefault() or setDefault(), the default is
-     * determined by querying the system using methods in TPlatformUtilities. If the
-     * system routines fail, or if they specify a TimeZone or TimeZone offset which is not
-     * recognized, the TimeZone indicated by the ID kLastResortID is instantiated
-     * and made the default.
+     * determined by querying the host system configuration. If the host system detection
+     * routines fail, or if they specify a TimeZone or TimeZone offset which is not
+     * recognized, then the special TimeZone "Etc/Unknown" is instantiated and made the
+     * default.
      *
      * @return   A default TimeZone. Clients are responsible for deleting the time zone
      *           object returned.
+     * @see getUnknown
      * @stable ICU 2.0
      */
     static TimeZone* U_EXPORT2 createDefault(void);
@@ -676,7 +685,7 @@
      * @param locale the locale in which to supply the display name.
      * @param result the human-readable name of this time zone in the given locale
      *               or in the default locale if the given locale is not recognized.
-     * @return       A refence to 'result'.
+     * @return       A reference to 'result'.
      * @stable ICU 2.0
      */
     UnicodeString& getDisplayName(UBool inDaylight, EDisplayType style, const Locale& locale, UnicodeString& result) const;
@@ -926,7 +935,7 @@
         UErrorCode& status);
 
     /**
-     * Returns the normalized custome time zone ID for the given offset fields.
+     * Returns the normalized custom time zone ID for the given offset fields.
      * @param hour offset hours
      * @param min offset minutes
      * @param sec offset seconds
diff --git a/icu4c/source/i18n/unicode/ucal.h b/icu4c/source/i18n/unicode/ucal.h
index fb7c387..f31a257 100644
--- a/icu4c/source/i18n/unicode/ucal.h
+++ b/icu4c/source/i18n/unicode/ucal.h
@@ -105,7 +105,7 @@
  * <p>
  * <strong>Note:</strong> for some non-Gregorian calendars, different
  * fields may be necessary for complete disambiguation. For example, a full
- * specification of the historial Arabic astronomical calendar requires year,
+ * specification of the historical Arabic astronomical calendar requires year,
  * month, day-of-month <em>and</em> day-of-week in some cases.
  *
  * <p>
@@ -157,6 +157,7 @@
 
 /**
  * The time zone ID reserved for unknown time zone.
+ * It behaves like the GMT/UTC time zone but has the special ID "Etc/Unknown".
  * @stable ICU 4.8
  */
 #define UCAL_UNKNOWN_ZONE_ID "Etc/Unknown"
@@ -620,8 +621,13 @@
 
 /**
  * Return the default time zone. The default is determined initially
- * by querying the host operating system. It may be changed with
- * ucal_setDefaultTimeZone() or with the C++ TimeZone API.
+ * by querying the host operating system. If the host system detection
+ * routines fail, or if they specify a TimeZone or TimeZone offset
+ * which is not recognized, then the special TimeZone "Etc/Unknown"
+ * is returned.
+ * 
+ * The default may be changed with `ucal_setDefaultTimeZone()` or with
+ * the C++ TimeZone API, `TimeZone::adoptDefault(TimeZone*)`.
  *
  * @param result A buffer to receive the result, or NULL
  *
@@ -631,7 +637,9 @@
  *
  * @return The result string length, not including the terminating
  * null
- *
+ * 
+ * @see #UCAL_UNKNOWN_ZONE_ID
+ * 
  * @stable ICU 2.6
  */
 U_STABLE int32_t U_EXPORT2