summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2022-02-23 10:53:27 +0100
committerEdward Welbourne <edward.welbourne@qt.io>2022-03-10 13:42:35 +0100
commit47a2a235311df1546a440e4efb932a5cf56a63eb (patch)
tree42ee50b84b5571ae1ec6c8d558b2fb6d58d41d65
parent23302149f24548f1bf658f630def4cde8374af2b (diff)
Consistently treat times before first rule as in its standard time
In QWinTimeZonePrivate::previousTransition(), an initial no-transition first rule was interpreted as implying a transition to its standard time at "the start of time". Do the same for times before the start of the first rule even if it is a DST recurrence; and, in data(), treat times before the first rule as being in its standard time. In the process, restructure data() to do that early return first, instead of in an else clause, so as to dedent the other branch of its code and make clearer how it fits into its outer loop. Change-Id: I21482d904c33542bf04f6510b974c01817d7aa5f Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> (cherry picked from commit 8bf0fbca70035d18e3b2d15dde0b67cf1d5fd5a9) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/corelib/time/qtimezoneprivate_win.cpp76
1 files changed, 38 insertions, 38 deletions
diff --git a/src/corelib/time/qtimezoneprivate_win.cpp b/src/corelib/time/qtimezoneprivate_win.cpp
index d71508a806..5feceb7d55 100644
--- a/src/corelib/time/qtimezoneprivate_win.cpp
+++ b/src/corelib/time/qtimezoneprivate_win.cpp
@@ -655,43 +655,41 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::data(qint64 forMSecsSinceEpoch) cons
for (int ruleIndex = ruleIndexForYear(m_tranRules, year);
ruleIndex >= 0; --ruleIndex) {
const QWinTransitionRule &rule = m_tranRules.at(ruleIndex);
- // 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.
- const int endYear = qMax(rule.startYear, prior);
- while (year >= endYear) {
- const int newYearOffset = (year <= rule.startYear && ruleIndex > 0)
- ? yearEndOffset(m_tranRules.at(ruleIndex - 1), prior)
- : yearEndOffset(rule, prior);
- const TransitionTimePair pair(rule, year, newYearOffset);
- bool isDst = false;
- if (!ruleIndex && year < FIRST_DST_YEAR) {
- // We're before the invention of DST and have no earlier
- // rule that might give better data on this year, so just
- // extrapolate standard time (modulo fakery) backwards.
- } else if (pair.std != invalidMSecs() && pair.std <= forMSecsSinceEpoch) {
- isDst = pair.std < pair.dst && pair.dst <= forMSecsSinceEpoch;
- } else if (pair.dst != invalidMSecs() && pair.dst <= forMSecsSinceEpoch) {
- isDst = true;
- } else {
- year = prior; // Try an earlier year for this rule (once).
- prior = year == 1 ? -1 : year - 1; // No year 0.
- continue;
- }
- return ruleToData(rule, forMSecsSinceEpoch,
- isDst ? QTimeZone::DaylightTime : QTimeZone::StandardTime,
- pair.fakesDst);
- }
- // Fell off start of rule, try previous rule.
- } else {
- // No transition, no DST, use the year's standard time.
+ Q_ASSERT(ruleIndex == 0 || year >= rule.startYear);
+ if (year < rule.startYear
+ || !(rule.standardTimeRule.wMonth > 0 || rule.daylightTimeRule.wMonth > 0)) {
+ // No transition (or before first rule), no DST, use the rule's standard time.
return ruleToData(rule, forMSecsSinceEpoch, QTimeZone::StandardTime);
}
- if (year >= rule.startYear) {
- year = rule.startYear - 1; // Seek last transition in new rule.
- if (!year)
- --year;
+
+ 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)
+ ? yearEndOffset(m_tranRules.at(ruleIndex - 1), prior)
+ : yearEndOffset(rule, prior);
+ const TransitionTimePair pair(rule, year, newYearOffset);
+ bool isDst = false;
+ if (!ruleIndex && year < FIRST_DST_YEAR) {
+ // We're before the invention of DST and have no earlier
+ // rule that might give better data on this year, so just
+ // extrapolate standard time (modulo fakery) backwards.
+ } else if (pair.std != invalidMSecs() && pair.std <= forMSecsSinceEpoch) {
+ isDst = pair.std < pair.dst && pair.dst <= forMSecsSinceEpoch;
+ } else if (pair.dst != invalidMSecs() && pair.dst <= forMSecsSinceEpoch) {
+ isDst = true;
+ } else {
+ year = prior; // Try an earlier year for this rule (once).
+ prior = year == 1 ? -1 : year - 1; // No year 0.
+ continue;
+ }
+ return ruleToData(rule, forMSecsSinceEpoch,
+ isDst ? QTimeZone::DaylightTime : QTimeZone::StandardTime,
+ pair.fakesDst);
}
+ // We can only fall off the end of that loop if endYear is rule.startYear:
+ Q_ASSERT(year < rule.startYear);
+ // Fell off start of rule, try previous rule.
}
// We don't have relevant data :-(
return invalidData();
@@ -765,8 +763,10 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::previousTransition(qint64 beforeMSec
for (int ruleIndex = ruleIndexForYear(m_tranRules, year);
ruleIndex >= 0; --ruleIndex) {
const QWinTransitionRule &rule = m_tranRules.at(ruleIndex);
+ Q_ASSERT(ruleIndex == 0 || year >= rule.startYear);
// Does this rule's period include any transition at all ?
- if (rule.standardTimeRule.wMonth > 0 || rule.daylightTimeRule.wMonth > 0) {
+ if (year >= rule.startYear
+ && (rule.standardTimeRule.wMonth > 0 || rule.daylightTimeRule.wMonth > 0)) {
int prior = year == 1 ? -1 : year - 1; // No year 0.
const int endYear = qMax(rule.startYear, prior);
while (year >= endYear) {
@@ -788,9 +788,9 @@ QTimeZonePrivate::Data QWinTimeZonePrivate::previousTransition(qint64 beforeMSec
}
// Fell off start of rule, try previous rule.
} else if (ruleIndex == 0) {
- // Treat a no-transition first rule as a transition at the start of
- // time, so that a scan through all rules *does* see it as the first
- // rule:
+ // Describe time before the first transition in terms of a fictional
+ // transition at the start of time, so that a scan through all rules
+ // *does* see a first rule that supplies the offset for such times:
return ruleToData(rule, minMSecs(), QTimeZone::StandardTime, false);
} // else: no transition during rule's period
if (year >= rule.startYear) {