Update API docs comments to clarify what is returned in failure cases.
// 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
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].
// 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
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
// 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;
/**
* 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();
/**
* 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);
* @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;
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
* <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>
/**
* 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"
/**
* 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
*
*
* @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