diff options
Diffstat (limited to 'src/corelib/tools/qtimezoneprivate.cpp')
-rw-r--r-- | src/corelib/tools/qtimezoneprivate.cpp | 29 |
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; } |