summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qtimezoneprivate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/tools/qtimezoneprivate.cpp')
-rw-r--r--src/corelib/tools/qtimezoneprivate.cpp29
1 files changed, 15 insertions, 14 deletions
diff --git a/src/corelib/tools/qtimezoneprivate.cpp b/src/corelib/tools/qtimezoneprivate.cpp
index 2b6c2ea6a5..8bf7336a42 100644
--- a/src/corelib/tools/qtimezoneprivate.cpp
+++ b/src/corelib/tools/qtimezoneprivate.cpp
@@ -260,6 +260,8 @@ QTimeZonePrivate::Data QTimeZonePrivate::dataForLocalTime(qint64 forLocalMSecs,
const qint64 sixteenHoursInMSecs(16 * 3600 * 1000);
Q_STATIC_ASSERT(-sixteenHoursInMSecs / 1000 < QTimeZone::MinUtcOffsetSecs
&& sixteenHoursInMSecs / 1000 > QTimeZone::MaxUtcOffsetSecs);
+ const qint64 recent = forLocalMSecs - sixteenHoursInMSecs;
+ const qint64 imminent = forLocalMSecs + sixteenHoursInMSecs;
/*
Offsets are Local - UTC, positive to the east of Greenwich, negative to
the west; DST offset always exceeds standard offset, when DST applies.
@@ -327,7 +329,7 @@ QTimeZonePrivate::Data QTimeZonePrivate::dataForLocalTime(qint64 forLocalMSecs,
// Get a transition definitely before the local MSecs; usually all we need.
// Only around the transition times might we need another.
- Data tran = previousTransition(forLocalMSecs - sixteenHoursInMSecs);
+ Data tran = previousTransition(recent);
Q_ASSERT(forLocalMSecs < 0 || // Pre-epoch TZ info may be unavailable
forLocalMSecs - tran.offsetFromUtc * 1000 >= tran.atMSecsSinceEpoch);
Data nextTran = nextTransition(tran.atMSecsSinceEpoch);
@@ -343,8 +345,7 @@ QTimeZonePrivate::Data QTimeZonePrivate::dataForLocalTime(qint64 forLocalMSecs,
&& forLocalMSecs > nextTran.atMSecsSinceEpoch + nextTran.offsetFromUtc * 1000) {
Data newTran = nextTransition(nextTran.atMSecsSinceEpoch);
if (newTran.atMSecsSinceEpoch == invalidMSecs()
- || newTran.atMSecsSinceEpoch + newTran.offsetFromUtc * 1000
- > forLocalMSecs + sixteenHoursInMSecs) {
+ || newTran.atMSecsSinceEpoch + newTran.offsetFromUtc * 1000 > imminent) {
// Definitely not a relevant tansition: too far in the future.
break;
}
@@ -357,10 +358,10 @@ QTimeZonePrivate::Data QTimeZonePrivate::dataForLocalTime(qint64 forLocalMSecs,
/*
So now tran is definitely before and nextTran is either after or only
- slightly before. The one with the larger offset is in DST; the other in
- standard time. Our hint tells us which of those to use (defaulting to
- standard if no hint): try it first; if that fails, try the other; if both
- fail life's tricky.
+ slightly before. One is standard time; we interpret the other as DST
+ (although the transition might in fact by a change in standard offset). Our
+ hint tells us which of those to use (defaulting to standard if no hint): try
+ it first; if that fails, try the other; if both fail, life's tricky.
*/
Q_ASSERT(forLocalMSecs < 0
|| forLocalMSecs - tran.offsetFromUtc * 1000 > tran.atMSecsSinceEpoch);
@@ -369,7 +370,9 @@ QTimeZonePrivate::Data QTimeZonePrivate::dataForLocalTime(qint64 forLocalMSecs,
nextTran.atMSecsSinceEpoch = forLocalMSecs - nextTran.offsetFromUtc * 1000;
tran.atMSecsSinceEpoch = forLocalMSecs - tran.offsetFromUtc * 1000;
- const bool nextIsDst = tran.offsetFromUtc < nextTran.offsetFromUtc;
+ // If both or neither have zero DST, treat the one with lower offset as standard:
+ const bool nextIsDst = !nextTran.daylightTimeOffset == !tran.daylightTimeOffset
+ ? tran.offsetFromUtc < nextTran.offsetFromUtc : nextTran.daylightTimeOffset;
// If that agrees with hint > 0, our first guess is to use nextTran; else tran.
const bool nextFirst = nextIsDst == (hint > 0) && nextStart != invalidMSecs();
for (int i = 0; i < 2; i++) {
@@ -399,7 +402,7 @@ QTimeZonePrivate::Data QTimeZonePrivate::dataForLocalTime(qint64 forLocalMSecs,
0 < tran.atMSecsSinceEpoch - nextTran.atMSecsSinceEpoch
= (nextTran.offsetFromUtc - tran.offsetFromUtc) * 1000
*/
- int dstStep = nextTran.offsetFromUtc - tran.offsetFromUtc;
+ int dstStep = (nextTran.offsetFromUtc - tran.offsetFromUtc) * 1000;
Q_ASSERT(dstStep > 0); // How else could we get here ?
if (nextFirst) { // hint thought we needed nextTran, so use tran
tran.atMSecsSinceEpoch -= dstStep;
@@ -415,8 +418,8 @@ QTimeZonePrivate::Data QTimeZonePrivate::dataForLocalTime(qint64 forLocalMSecs,
/* Bracket and refine to discover offset. */
qint64 utcEpochMSecs;
- int early = offsetFromUtc(forLocalMSecs - sixteenHoursInMSecs);
- int late = offsetFromUtc(forLocalMSecs + sixteenHoursInMSecs);
+ int early = offsetFromUtc(recent);
+ int late = offsetFromUtc(imminent);
if (Q_LIKELY(early == late)) { // > 99% of the time
utcEpochMSecs = forLocalMSecs - early * 1000;
} else {
@@ -437,9 +440,7 @@ QTimeZonePrivate::Data QTimeZonePrivate::dataForLocalTime(qint64 forLocalMSecs,
utcEpochMSecs = forStd;
} else {
// Invalid forLocalMSecs: in spring-forward gap.
- const int dstStep = daylightTimeOffset(early < late ?
- forLocalMSecs + sixteenHoursInMSecs :
- forLocalMSecs - sixteenHoursInMSecs);
+ const int dstStep = daylightTimeOffset(early < late ? imminent : recent);
Q_ASSERT(dstStep); // There can't be a transition without it !
utcEpochMSecs = (hint > 0) ? forStd - dstStep : forDst + dstStep;
}