summaryrefslogtreecommitdiffstats
path: root/src/corelib/time/qtimezoneprivate_tz.cpp
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2021-02-22 18:44:41 +0100
committerEdward Welbourne <edward.welbourne@qt.io>2021-03-18 15:31:06 +0100
commitb6544dc36caffa18e60db6adfcd8ea6ff6654960 (patch)
tree4978b38dc0096a08a2a7b5944cbf0881987c73ad /src/corelib/time/qtimezoneprivate_tz.cpp
parent9d3a7c72ad5308d016bf1315f6eaed0b51a72f65 (diff)
QTzTimeZonePrivate: provide correct data for before the first transition
We previously used the data for after the first transition; but the Olson database knows about local mean time for each zone, and it does get used by the system libraries, so systemZone will conflict with LocalTime once we use the time_t functions outside their 32-bit range (coming shortly). Record the pre-zone data during parsing and use it in the (fortunately only one) place that needs it. Discovered the issue in the course of debugging other issues while purging QDateTime of its wilful ignorance of pre-1970 DST. Change-Id: Icf957460fa3ccbaf5165e79f38ac68b450ecf98f Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/time/qtimezoneprivate_tz.cpp')
-rw-r--r--src/corelib/time/qtimezoneprivate_tz.cpp36
1 files changed, 22 insertions, 14 deletions
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<QTimeZonePrivate::Data> 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