summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/time/qtimezone.cpp15
-rw-r--r--src/corelib/time/qtimezoneprivate_tz.cpp18
-rw-r--r--src/corelib/time/qtimezoneprivate_win.cpp8
3 files changed, 25 insertions, 16 deletions
diff --git a/src/corelib/time/qtimezone.cpp b/src/corelib/time/qtimezone.cpp
index 87d8ea75f1..0309e43e52 100644
--- a/src/corelib/time/qtimezone.cpp
+++ b/src/corelib/time/qtimezone.cpp
@@ -79,6 +79,7 @@ static QTimeZonePrivate *newBackendTimeZone()
// Create named time zone using appropriate backend
static QTimeZonePrivate *newBackendTimeZone(const QByteArray &ianaId)
{
+ Q_ASSERT(!ianaId.isEmpty());
#ifdef QT_NO_SYSTEMLOCALE
#if QT_CONFIG(icu)
return new QIcuTimeZonePrivate(ianaId);
@@ -339,7 +340,7 @@ QTimeZone::QTimeZone(const QByteArray &ianaId)
// If not a CLDR UTC offset ID then try creating it with the system backend.
// Relies on backend not creating valid TZ with invalid name.
if (!d->isValid())
- d = newBackendTimeZone(ianaId);
+ d = ianaId.isEmpty() ? newBackendTimeZone() : newBackendTimeZone(ianaId);
// Can also handle UTC with arbitrary (valid) offset, but only do so as
// fall-back, since either of the above may handle it more informatively.
if (!d->isValid()) {
@@ -795,7 +796,15 @@ QTimeZone::OffsetDataList QTimeZone::transitions(const QDateTime &fromDateTime,
QByteArray QTimeZone::systemTimeZoneId()
{
- return global_tz->backend->systemTimeZoneId();
+ const QByteArray sys = global_tz->backend->systemTimeZoneId();
+ if (!sys.isEmpty())
+ return sys;
+ // The system zone, despite the empty ID, may know its real ID anyway:
+ auto zone = systemTimeZone();
+ if (zone.isValid() && !zone.id().isEmpty())
+ return zone.id();
+ // If all else fails, guess UTC.
+ return QTimeZonePrivate::utcQByteArray();
}
/*!
@@ -807,7 +816,7 @@ QByteArray QTimeZone::systemTimeZoneId()
*/
QTimeZone QTimeZone::systemTimeZone()
{
- return QTimeZone(QTimeZone::systemTimeZoneId());
+ return QTimeZone(global_tz->backend->systemTimeZoneId());
}
/*!
diff --git a/src/corelib/time/qtimezoneprivate_tz.cpp b/src/corelib/time/qtimezoneprivate_tz.cpp
index c5c70b7364..b816b4ecff 100644
--- a/src/corelib/time/qtimezoneprivate_tz.cpp
+++ b/src/corelib/time/qtimezoneprivate_tz.cpp
@@ -641,7 +641,7 @@ QTzTimeZonePrivate::QTzTimeZonePrivate()
// Create a named time zone
QTzTimeZonePrivate::QTzTimeZonePrivate(const QByteArray &ianaId)
{
- init(ianaId.isEmpty() ? systemTimeZoneId() : ianaId);
+ init(ianaId);
}
QTzTimeZonePrivate::~QTzTimeZonePrivate()
@@ -854,9 +854,6 @@ QTzTimeZoneCacheEntry QTzTimeZoneCache::fetchEntry(const QByteArray &ianaId)
void QTzTimeZonePrivate::init(const QByteArray &ianaId)
{
- // System ID defaults to UTC, so is never empty; and our callers default to
- // the system ID if what they're given is empty.
- Q_ASSERT(!ianaId.isEmpty());
static QTzTimeZoneCache tzCache;
const auto &entry = tzCache.fetchEntry(ianaId);
if (entry.m_tranTimes.isEmpty() && entry.m_posixRule.isEmpty())
@@ -864,6 +861,15 @@ void QTzTimeZonePrivate::init(const QByteArray &ianaId)
cached_data = std::move(entry);
m_id = ianaId;
+ // Avoid empty ID, if we have an abbreviation to use instead
+ if (m_id.isEmpty()) { // We've read /etc/localtime's contents
+ for (const auto &abbr : cached_data.m_abbreviations) {
+ if (!abbr.isEmpty()) {
+ m_id = abbr;
+ break;
+ }
+ }
+ }
}
QLocale::Country QTzTimeZonePrivate::country() const
@@ -1261,10 +1267,6 @@ QByteArray QTzTimeZonePrivate::systemTimeZoneId() const
ianaId = reader.name();
}
- // Give up for now and return UTC
- if (ianaId.isEmpty())
- ianaId = utcQByteArray();
-
return ianaId;
}
diff --git a/src/corelib/time/qtimezoneprivate_win.cpp b/src/corelib/time/qtimezoneprivate_win.cpp
index 0aaf469ed9..4209bc707b 100644
--- a/src/corelib/time/qtimezoneprivate_win.cpp
+++ b/src/corelib/time/qtimezoneprivate_win.cpp
@@ -642,6 +642,8 @@ void QWinTimeZonePrivate::init(const QByteArray &ianaId)
m_id.clear();
m_windowsId.clear();
m_displayName.clear();
+ } else if (m_id.isEmpty()) {
+ m_id = m_standardName.toUtf8();
}
}
@@ -864,12 +866,8 @@ QByteArray QWinTimeZonePrivate::systemTimeZoneId() const
if (country != QLocale::AnyCountry)
ianaId = windowsIdToDefaultIanaId(windowsId, country);
// If we don't have a real country, or there wasn't a specific match, try the global default
- if (ianaId.isEmpty()) {
+ if (ianaId.isEmpty())
ianaId = windowsIdToDefaultIanaId(windowsId);
- // If no global default then probably an unknown Windows ID so return UTC
- if (ianaId.isEmpty())
- return utcQByteArray();
- }
return ianaId;
}