TimeZone* U_EXPORT2 TimeZone::createTimeZone(const UnicodeString& ID) { /* We first try to lookup the zone ID in our system list. If this * fails, we try to parse it as a custom string GMT[+-]hh:mm. If * all else fails, we return GMT, which is probably not what the * user wants, but at least is a functioning TimeZone object. * * We cannot return NULL, because that would break compatibility * with the JDK. */ TimeZone* result = createSystemTimeZone(ID); if (result == 0) { U_DEBUG_TZ_MSG(("failed to load system time zone with id - falling to custom")); result = createCustomTimeZone(ID); } if (result == 0) { U_DEBUG_TZ_MSG(("failed to load time zone with id - falling to GMT")); const TimeZone* temptz = getGMT(); if (temptz == NULL) { result = NULL; } else { result = temptz->clone(); } } return result; }
TimeZone* TimeZone::createTimeZone(const UnicodeString& ID) { /* We first try to lookup the zone ID in our system list. If this * fails, we try to parse it as a custom string GMT[+-]hh:mm. If * all else fails, we return GMT, which is probably not what the * user wants, but at least is a functioning TimeZone object. */ TimeZone* result = 0; if (haveZoneData()) { result = createSystemTimeZone(ID); } if (result == 0) { result = createCustomTimeZone(ID); } if (result == 0) { result = getGMT()->clone(); } return result; }
void TimeZone::initDefault() { // We access system timezone data through TPlatformUtilities, // including tzset(), timezone, and tzname[]. int32_t rawOffset = 0; const char *hostID; // First, try to create a system timezone, based // on the string ID in tzname[0]. { // NOTE: Local mutex here. TimeZone mutex below // mutexed to avoid threading issues in the platform functions. // Some of the locale/timezone OS functions may not be thread safe, // so the intent is that any setting from anywhere within ICU // happens while the ICU mutex is held. // The operating system might actually use ICU to implement timezones. // So we may have ICU calling ICU here, like on AIX. // In order to prevent a double lock of a non-reentrant mutex in a // different part of ICU, we use TZSET_LOCK to allow only one instance // of ICU to query these thread unsafe OS functions at any given time. Mutex lock(&TZSET_LOCK); ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONE, timeZone_cleanup); uprv_tzset(); // Initialize tz... system data // 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. hostID = uprv_tzname(0); // Invert sign because UNIX semantics are backwards rawOffset = uprv_timezone() * -U_MILLIS_PER_SECOND; } UBool initialized; UMTX_CHECK(&LOCK, (DEFAULT_ZONE != NULL), initialized); if (initialized) { /* Hrmph? Either a race condition happened, or tzset initialized ICU. */ return; } TimeZone* default_zone = 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); default_zone = createSystemTimeZone(hostStrID); #ifdef U_WINDOWS uprv_free(const_cast<char *>(hostID)); #endif int32_t hostIDLen = hostStrID.length(); if (default_zone != NULL && rawOffset != default_zone->getRawOffset() && (3 <= hostIDLen && hostIDLen <= 4)) { // Uh oh. This probably wasn't a good id. // It was probably an ambiguous abbreviation delete default_zone; default_zone = NULL; } // Construct a fixed standard zone with the host's ID // and raw offset. if (default_zone == NULL) { default_zone = new SimpleTimeZone(rawOffset, hostStrID); } // If we _still_ don't have a time zone, use GMT. if (default_zone == NULL) { const TimeZone* temptz = getGMT(); // If we can't use GMT, get out. if (temptz == NULL) { return; } default_zone = temptz->clone(); } // If DEFAULT_ZONE is still NULL, set it up. umtx_lock(&LOCK); if (DEFAULT_ZONE == NULL) { DEFAULT_ZONE = default_zone; default_zone = NULL; ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONE, timeZone_cleanup); } umtx_unlock(&LOCK); delete default_zone; }
/** * Initialize DEFAULT_ZONE from the system default time zone. The * caller should confirm that DEFAULT_ZONE is NULL before calling. * Upon return, DEFAULT_ZONE will not be NULL, unless operator new() * returns NULL. * * Must be called OUTSIDE mutex. */ void TimeZone::initDefault() { // We access system timezone data through TPlatformUtilities, // including tzset(), timezone, and tzname[]. int32_t rawOffset = 0; const char *hostID; // First, try to create a system timezone, based // on the string ID in tzname[0]. { // NOTE: Global mutex here; TimeZone mutex above // mutexed to avoid threading issues in the platform fcns. // Some of the locale/timezone OS functions may not be thread safe, // so the intent is that any setting from anywhere within ICU // happens with the ICU global mutex held. Mutex lock; uprv_tzset(); // Initialize tz... system data // 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. hostID = uprv_tzname(0); // Invert sign because UNIX semantics are backwards rawOffset = uprv_timezone() * -U_MILLIS_PER_SECOND; } TimeZone* default_zone = NULL; if (haveZoneData()) { default_zone = createSystemTimeZone(hostID); // If we couldn't get the time zone ID from the host, use // the default host timezone offset. Further refinements // to this include querying the host to determine if DST // is in use or not and possibly using the host locale to // select from multiple zones at a the same offset. We // don't do any of this now, but we could easily add this. if (default_zone == NULL) { // Use the designated default in the time zone list that has the // appropriate GMT offset, if there is one. const OffsetIndex* index = INDEX_BY_OFFSET; for (;;) { if (index->gmtOffset > rawOffset) { // Went past our desired offset; no match found break; } if (index->gmtOffset == rawOffset) { // Found our desired offset default_zone = createSystemTimeZone(ZONE_IDS[index->defaultZone]); break; } // Compute the position of the next entry. If the delta value // in this entry is zero, then there is no next entry. uint16_t delta = index->nextEntryDelta; if (delta == 0) { break; } index = (const OffsetIndex*)((int8_t*)index + delta); } } } // If we _still_ don't have a time zone, use GMT. This // can only happen if the raw offset returned by // uprv_timezone() does not correspond to any system zone. if (default_zone == NULL) { default_zone = getGMT()->clone(); } // If DEFAULT_ZONE is still NULL, set it up. umtx_lock(&LOCK); if (DEFAULT_ZONE == NULL) { DEFAULT_ZONE = default_zone; default_zone = NULL; } umtx_unlock(&LOCK); delete default_zone; }