path: root/src/corelib/tools/qtimezone.cpp
diff options
authorChris Wilson <>2017-05-05 16:57:56 +0100
committerChris Wilson <>2017-06-08 08:34:31 +0000
commit147aa291620d9e2533bbea536a748a8f8a7ed14b (patch)
treecca4420b56f8580b87d3c348d1ef6cb444c4adb8 /src/corelib/tools/qtimezone.cpp
parent86a948fc0ff124d2ef03956ac507c923cbb262eb (diff)
Fix sending UTC-offset QTimeZones through QDataStream
QTimeZone("UTC") should be valid, as "UTC" appears in the list of availableTimeZoneIds(), and tst_QTimeZone::dataStreamTest() constructs timezones like this, which are considered valid. The internal representation of a QTimeZone("UTC") as created by QTimeZone::QTimeZone(const QByteArray &ianaId) is a QUtcTimeZonePrivate which isValid(), so the containing QTimeZone isValid() too. When QTimeZone is serialized into a QDataStream, it calls tz.d->serialize(ds) which is QUtcTimeZonePrivate::serialize. This writes QStringLiteral("OffsetFromUtc") followed by the IANA ID and the offset (etc.) to the datastream. When QTimeZone is deserialized it looks for this marker string, and if present, it passed all of the parameters to the QTimeZone constructor (not just the name). However, that constructor does not support standard IANA timezones (only custom ones), and when it detects that the supplied IANA ID is actually listed in availableTimeZoneIds(), it leaves the pointer to the QTimeZonePrivate uninitialized (NULL), which leaves the QTimeZone invalid (isValid() returns false). Thus, a valid timezone which was serialized and then deserialized has become invalid. This also affects serialization of QDateTimes with timezones. Fixed by calling the name-only constructor first, which works (only) for IANA standard timezones and leaves the QTimeZone invalid (isValid() returns false) otherwise. In which case, we can call the many-argument contructor to create a custom timezone with the same offset as the one which was originally serialized. [ChangeLog][QtCore][QTimeZone] Fixed sending IANA standard UTC-offset QTimeZones through QDataStream, which previously came out invalid after deserialization. Task-number: QTBUG-60595 Change-Id: Id9c47e8bda701faae4d800e012afb6db545b2fe9 Reviewed-by: Oswald Buddenhagen <> Reviewed-by: Edward Welbourne <>
Diffstat (limited to 'src/corelib/tools/qtimezone.cpp')
1 files changed, 7 insertions, 1 deletions
diff --git a/src/corelib/tools/qtimezone.cpp b/src/corelib/tools/qtimezone.cpp
index ec2f7c4af6..c4cd76c59c 100644
--- a/src/corelib/tools/qtimezone.cpp
+++ b/src/corelib/tools/qtimezone.cpp
@@ -961,7 +961,13 @@ QDataStream &operator>>(QDataStream &ds, QTimeZone &tz)
int country;
QString comment;
ds >> ianaId >> utcOffset >> name >> abbreviation >> country >> comment;
- tz = QTimeZone(ianaId.toUtf8(), utcOffset, name, abbreviation, (QLocale::Country) country, comment);
+ // Try creating as a system timezone, which succeeds (producing a valid
+ // zone) iff ianaId is valid; we can then ignore the other data.
+ tz = QTimeZone(ianaId.toUtf8());
+ // If not, then construct a custom timezone using all the saved values:
+ if (!tz.isValid())
+ tz = QTimeZone(ianaId.toUtf8(), utcOffset, name, abbreviation,
+ QLocale::Country(country), comment);
} else {
tz = QTimeZone(ianaId.toUtf8());