path: root/src/corelib/tools/qtimezoneprivate.cpp
diff options
authorEdward Welbourne <>2018-08-17 11:19:32 +0200
committerTony Sarajärvi <>2018-08-20 06:04:25 +0000
commitfe9a37ac4865f397533f36d1216dce6ebbacc80b (patch)
treec5be4793d348cd2d619933ce6a869626ff311c74 /src/corelib/tools/qtimezoneprivate.cpp
parent346c15102b14c58b8aaeed2c1586cd3100200e28 (diff)
QTimeZonePrivate::dataForLocalTime(): cope with negative DST offsets
The tz database's latest update now records the cases where summer time is deemed standard and winter-time is deemed DST. (This doesn't change what the offsets are, just how they're described.) The resulting negative DST offsets mess up the algorithm for converting local time to UTC, causing tst_QTimeZone::transitionEachZone() to fail for Europe/Dublin in the hour before its transition; so refine the algorithm to cope with the new case. Task-number: QTBUG-69980 Change-Id: I24003872fffb03b2903161859158d0ce998b3073 Reviewed-by: Thiago Macieira <>
Diffstat (limited to 'src/corelib/tools/qtimezoneprivate.cpp')
1 files changed, 7 insertions, 5 deletions
diff --git a/src/corelib/tools/qtimezoneprivate.cpp b/src/corelib/tools/qtimezoneprivate.cpp
index 2b6c2ea6a5..44ecf9a6c9 100644
--- a/src/corelib/tools/qtimezoneprivate.cpp
+++ b/src/corelib/tools/qtimezoneprivate.cpp
@@ -357,10 +357,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 +369,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++) {