summaryrefslogtreecommitdiffstats
path: root/src/corelib/time/qtimezone.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/time/qtimezone.cpp')
-rw-r--r--src/corelib/time/qtimezone.cpp25
1 files changed, 19 insertions, 6 deletions
diff --git a/src/corelib/time/qtimezone.cpp b/src/corelib/time/qtimezone.cpp
index 0bba2afc61..87d8ea75f1 100644
--- a/src/corelib/time/qtimezone.cpp
+++ b/src/corelib/time/qtimezone.cpp
@@ -318,27 +318,40 @@ Q_GLOBAL_STATIC(QTimeZoneSingleton, global_tz);
*/
QTimeZone::QTimeZone() noexcept
- : d(0)
+ : d(nullptr)
{
}
/*!
Creates an instance of the requested time zone \a ianaId.
- The ID must be one of the available system IDs otherwise an invalid
- time zone will be returned.
+ The ID must be one of the available system IDs or a valid UTC-with-offset
+ ID, otherwise an invalid time zone will be returned.
\sa availableTimeZoneIds()
*/
QTimeZone::QTimeZone(const QByteArray &ianaId)
{
- // Try and see if it's a valid UTC offset ID, just as quick to try create as look-up
+ // Try and see if it's a CLDR UTC offset ID - just as quick by creating as
+ // by looking up.
d = new QUtcTimeZonePrivate(ianaId);
- // If not a valid UTC offset ID then try create it with the system backend
- // Relies on backend not creating valid tz with invalid name
+ // 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);
+ // 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()) {
+ qint64 offset = QUtcTimeZonePrivate::offsetFromUtcString(ianaId);
+ if (offset != QTimeZonePrivate::invalidSeconds()) {
+ // Should have abs(offset) < 24 * 60 * 60 = 86400.
+ qint32 seconds = qint32(offset);
+ Q_ASSERT(qint64(seconds) == offset);
+ // NB: this canonicalises the name, so it might not match ianaId
+ d = new QUtcTimeZonePrivate(seconds);
+ }
+ }
}
/*!