summaryrefslogtreecommitdiffstats
path: root/src/corelib/time
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2021-09-24 14:12:04 +0200
committerEdward Welbourne <edward.welbourne@qt.io>2021-10-12 22:52:50 +0200
commitba23507960a80367d918468d9d7da39c92a09fbf (patch)
tree21881db6c9d5e0d95e3e3bb76d45cbff68f3d7b2 /src/corelib/time
parent22e330db482672b56fa8292b0649935de375e82e (diff)
Fix handling of time-zone gap in QTimeZonePrivate::dataForLocalTime()
This was handled correctly when the backend supplies transitions bracketing the time in question, but the fallback code tried to use the DST offset at the time with larger offset from UTC; this did not work when the gap was due to a change in standard time. Discovered by ANS1 parsing of a date-time with two-digit year, for which the date-time parser tried to use 1921-05-01T00:00 local time when filling in the fields it had parsed; but, when run in Europe/Helsinki, there is no such time due to the 20m 11s skipped when joining EET from the prior local solar mean time. Correct the calculation to use the actual change in offset from UTC, as used in the (far better tested) between-transitions branch of the code, rather than the DST offset after the transition. Add a test-case based on the ASN.1 certificate date whose parsing revealed the issue. Although it seems nothing in Coin can reproduce the issue, the reporter has verified that the test does indeed fail on the system where the bug was found and the fix does fix it. Fixes: QTBUG-96861 Pick-to: 6.2 Change-Id: I12b02bad01daca2073d1a356452cd573684aa688 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/time')
-rw-r--r--src/corelib/time/qtimezoneprivate.cpp6
1 files changed, 4 insertions, 2 deletions
diff --git a/src/corelib/time/qtimezoneprivate.cpp b/src/corelib/time/qtimezoneprivate.cpp
index 6829951c84..6b92d60f7f 100644
--- a/src/corelib/time/qtimezoneprivate.cpp
+++ b/src/corelib/time/qtimezoneprivate.cpp
@@ -416,8 +416,10 @@ QTimeZonePrivate::Data QTimeZonePrivate::dataForLocalTime(qint64 forLocalMSecs,
utcEpochMSecs = forStd;
} else {
// Invalid forLocalMSecs: in spring-forward gap.
- const int dstStep = daylightTimeOffset(early < late ? imminent : recent) * 1000;
- Q_ASSERT(dstStep); // There can't be a transition without it !
+ const int dstStep = (offsetInDst - offsetInStd) * 1000;
+ // That'll typically be the DST offset at imminent, but changes to
+ // standard time have zero DST offset both before and after.
+ Q_ASSERT(dstStep > 0); // There can't be a gap without it !
utcEpochMSecs = (hint > 0) ? forStd - dstStep : forDst + dstStep;
}
}