diff options
author | Edward Welbourne <edward.welbourne@qt.io> | 2022-02-23 11:15:06 +0100 |
---|---|---|
committer | Edward Welbourne <edward.welbourne@qt.io> | 2022-03-04 23:26:12 +0100 |
commit | fe4c93652ce3e639ed7cab9da541432b35614642 (patch) | |
tree | 336fb890d8c024fdaa63d4f8e04ee1f2caf507c5 /src/corelib/time/qtimezoneprivate_win.cpp | |
parent | 8bf0fbca70035d18e3b2d15dde0b67cf1d5fd5a9 (diff) |
Improve handling of newYearOffset in qtimezoneprivate_win.cpp
In nextTransition() it wasn't being carried over from one rule to the
next, as intended. It needs to be defined at function level, set for
the first rule and updated for each new year tried. Also assert that
it does faithfully reflect the standard time in rules without
transitions.
In the process of fixing that, since it's computed from the
yearEndOffset() of a prior year, test whether that year is less than
the rule start rather than whether the present year is less than or
equal to it. As the prior year is immediately before the present year,
this makes no difference, but it clarifies the reasoning. Apply this
clarification also in data() and previousTransition() for consistency.
Pick-to: 6.3
Change-Id: I29c41e67784eaae13b83f6ae1ad16509e636c187
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/time/qtimezoneprivate_win.cpp')
-rw-r--r-- | src/corelib/time/qtimezoneprivate_win.cpp | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/src/corelib/time/qtimezoneprivate_win.cpp b/src/corelib/time/qtimezoneprivate_win.cpp index 5feceb7d55..672d3db984 100644 --- a/src/corelib/time/qtimezoneprivate_win.cpp +++ b/src/corelib/time/qtimezoneprivate_win.cpp @@ -665,7 +665,7 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::data(qint64 forMSecsSinceEpoch) cons int prior = year == 1 ? -1 : year - 1; // No year 0. const int endYear = qMax(rule.startYear, prior); while (year >= endYear) { - const int newYearOffset = (year <= rule.startYear && ruleIndex > 0) + const int newYearOffset = (prior < rule.startYear && ruleIndex > 0) ? yearEndOffset(m_tranRules.at(ruleIndex - 1), prior) : yearEndOffset(rule, prior); const TransitionTimePair pair(rule, year, newYearOffset); @@ -707,13 +707,20 @@ bool QWinTimeZonePrivate::hasTransitions() const QTimeZonePrivate::Data QWinTimeZonePrivate::nextTransition(qint64 afterMSecsSinceEpoch) const { int year = msecsToDate(afterMSecsSinceEpoch).year(); + int newYearOffset = invalidSeconds(); for (int ruleIndex = ruleIndexForYear(m_tranRules, year); ruleIndex < m_tranRules.count(); ++ruleIndex) { const QWinTransitionRule &rule = m_tranRules.at(ruleIndex); - // Initial guess: rule starts in standard time (unsound in southern hemisphere). - int newYearOffset = rule.standardTimeBias; // Does this rule's period include any transition at all ? if (rule.standardTimeRule.wMonth > 0 || rule.daylightTimeRule.wMonth > 0) { + int prior = year == 1 ? -1 : year - 1; // No year 0. + if (newYearOffset == invalidSeconds()) { + // First rule tried. (Will revise newYearOffset before any + // fall-back to a later rule.) + newYearOffset = (prior < rule.startYear && ruleIndex > 0) + ? yearEndOffset(m_tranRules.at(ruleIndex - 1), prior) + : yearEndOffset(rule, prior); + } if (year < rule.startYear) { // Either before first rule's start, or we fell off the end of // the rule for year because afterMSecsSinceEpoch is after any @@ -723,10 +730,6 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::nextTransition(qint64 afterMSecsSinc } const int endYear = ruleIndex + 1 < m_tranRules.count() ? qMin(m_tranRules.at(ruleIndex + 1).startYear, year + 2) : (year + 2); - int prior = year == 1 ? -1 : year - 1; // No year 0. - newYearOffset = (year <= rule.startYear && ruleIndex > 0) - ? yearEndOffset(m_tranRules.at(ruleIndex - 1), prior) - : yearEndOffset(rule, prior); while (year < endYear) { const TransitionTimePair pair(rule, year, newYearOffset); bool isDst = false; @@ -748,7 +751,15 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::nextTransition(qint64 afterMSecsSinc return pair.ruleToData(rule, this, isDst); } // Fell off end of rule, try next rule. - } // else: no transition during rule's period + } else { + // No transition during rule's period. If this is our first rule, + // record its standard time as newYearOffset for the next rule; + // otherwise, it should be consistent with what we have. + if (newYearOffset == invalidSeconds()) + newYearOffset = rule.standardTimeBias; + else + Q_ASSERT(newYearOffset == rule.standardTimeBias); + } } // Apparently no transition after the given time: return invalidData(); @@ -770,7 +781,7 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::previousTransition(qint64 beforeMSec int prior = year == 1 ? -1 : year - 1; // No year 0. const int endYear = qMax(rule.startYear, prior); while (year >= endYear) { - const int newYearOffset = (year <= rule.startYear && ruleIndex > 0) + const int newYearOffset = (prior < rule.startYear && ruleIndex > 0) ? yearEndOffset(m_tranRules.at(ruleIndex - 1), prior) : yearEndOffset(rule, prior); const TransitionTimePair pair(rule, year, newYearOffset); |