diff --git a/src/corelib/time/qtimezoneprivate_p.h b/src/corelib/time/qtimezoneprivate_p.h index 4fcf4cf32c..164a1b790f 100644 --- a/src/corelib/time/qtimezoneprivate_p.h +++ b/src/corelib/time/qtimezoneprivate_p.h @@ -300,6 +300,7 @@ struct QTzTimeZoneCacheEntry QList m_tranRules; QList m_abbreviations; QByteArray m_posixRule; + QTzTransitionRule m_preZoneRule; }; class Q_AUTOTEST_EXPORT QTzTimeZonePrivate final : public QTimeZonePrivate @@ -349,6 +350,7 @@ private: QList getPosixTransitions(qint64 msNear) const; Data dataForTzTransition(QTzTransitionTime tran) const; + Data dataFromRule(QTzTransitionRule rule, qint64 msecsSinceEpoch) const; #if QT_CONFIG(icu) mutable QSharedDataPointer m_icu; #endif diff --git a/src/corelib/time/qtimezoneprivate_tz.cpp b/src/corelib/time/qtimezoneprivate_tz.cpp index e758f1c12f..dd3dae78e9 100644 --- a/src/corelib/time/qtimezoneprivate_tz.cpp +++ b/src/corelib/time/qtimezoneprivate_tz.cpp @@ -768,12 +768,20 @@ QTzTimeZoneCacheEntry QTzTimeZoneCache::findEntry(const QByteArray &ianaId) ret.m_abbreviations.append(it.value()); abbrindList.append(it.key()); } + // Map tz_abbrind from map's keys (as initially read) to abbrindList's + // indices (used hereafter): for (int i = 0; i < typeList.size(); ++i) typeList[i].tz_abbrind = abbrindList.indexOf(typeList.at(i).tz_abbrind); + // TODO: is typeList[0] always the "before zones" data ? It seems to be ... + if (typeList.size()) + ret.m_preZoneRule = { typeList.at(0).tz_gmtoff, 0, typeList.at(0).tz_abbrind }; + else + ret.m_preZoneRule = { 0, 0, 0 }; + // Offsets are stored as total offset, want to know separate UTC and DST offsets // so find the first non-dst transition to use as base UTC Offset - int utcOffset = 0; + int utcOffset = ret.m_preZoneRule.stdOffset; for (const QTzTransition &tran : qAsConst(tranList)) { if (!typeList.at(tran.tz_typeind).tz_isdst) { utcOffset = typeList.at(tran.tz_typeind).tz_gmtoff; @@ -1026,14 +1034,14 @@ bool QTzTimeZonePrivate::isDaylightTime(qint64 atMSecsSinceEpoch) const QTimeZonePrivate::Data QTzTimeZonePrivate::dataForTzTransition(QTzTransitionTime tran) const { - QTimeZonePrivate::Data data; - data.atMSecsSinceEpoch = tran.atMSecsSinceEpoch; - QTzTransitionRule rule = cached_data.m_tranRules.at(tran.ruleIndex); - data.standardTimeOffset = rule.stdOffset; - data.daylightTimeOffset = rule.dstOffset; - data.offsetFromUtc = rule.stdOffset + rule.dstOffset; - data.abbreviation = QString::fromUtf8(cached_data.m_abbreviations.at(rule.abbreviationIndex)); - return data; + return dataFromRule(cached_data.m_tranRules.at(tran.ruleIndex), tran.atMSecsSinceEpoch); +} + +QTimeZonePrivate::Data QTzTimeZonePrivate::dataFromRule(QTzTransitionRule rule, + qint64 msecsSinceEpoch) const +{ + return { QString::fromUtf8(cached_data.m_abbreviations.at(rule.abbreviationIndex)), + msecsSinceEpoch, rule.stdOffset + rule.dstOffset, rule.stdOffset, rule.dstOffset }; } QList QTzTimeZonePrivate::getPosixTransitions(qint64 msNear) const @@ -1070,11 +1078,11 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::data(qint64 forMSecsSinceEpoch) const [forMSecsSinceEpoch] (const QTzTransitionTime &at) { return at.atMSecsSinceEpoch <= forMSecsSinceEpoch; }); - if (last > tranCache().cbegin()) - --last; - Data data = dataForTzTransition(*last); - data.atMSecsSinceEpoch = forMSecsSinceEpoch; - return data; + if (last == tranCache().cbegin()) + return dataFromRule(cached_data.m_preZoneRule, forMSecsSinceEpoch); + + --last; + return dataFromRule(cached_data.m_tranRules.at(last->ruleIndex), forMSecsSinceEpoch); } bool QTzTimeZonePrivate::hasTransitions() const