mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-06 22:15:31 +00:00
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.
This commit is contained in:
parent
3ebd817504
commit
1188394d74
4 changed files with 49 additions and 27 deletions
|
@ -1068,7 +1068,7 @@ uprv_tzname(int n)
|
|||
// 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
|
||||
|
|
|
@ -456,10 +456,11 @@ TimeZone::createTimeZone(const UnicodeString& ID)
|
|||
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 @@ TimeZone::detectHostTimeZone()
|
|||
|
||||
// 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::detectHostTimeZone()
|
|||
|
||||
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 @@ TimeZone::detectHostTimeZone()
|
|||
|
||||
// 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;
|
||||
|
|
|
@ -277,17 +277,25 @@ public:
|
|||
|
||||
/**
|
||||
* 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 @@ public:
|
|||
/**
|
||||
* 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 @@ public:
|
|||
* @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 @@ private:
|
|||
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
|
||||
|
|
|
@ -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 @@ ucal_openCountryTimeZones(const char* country, UErrorCode* ec);
|
|||
|
||||
/**
|
||||
* 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 @@ ucal_openCountryTimeZones(const char* country, UErrorCode* ec);
|
|||
*
|
||||
* @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
|
||||
|
|
Loading…
Add table
Reference in a new issue