QTimeZone - Fix dateForLocalTime() to check validity of next transition
The private method dateForLocalTime() was not checking that transitions were valid, resulting in infinite looping when a time zone didn't have any future transitions. Change-Id: I0e5d07063861778dd86056a80c36fdd9f9d36133 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
This commit is contained in:
parent
8e6258f059
commit
6ad97bfa73
@ -264,7 +264,8 @@ QTimeZonePrivate::Data QTimeZonePrivate::dataForLocalTime(qint64 forLocalMSecs)
|
||||
// If the local msecs is less than the real local time of the transition
|
||||
// then get the previous transition to use instead
|
||||
if (forLocalMSecs < tran.atMSecsSinceEpoch + (tran.offsetFromUtc * 1000)) {
|
||||
while (forLocalMSecs < tran.atMSecsSinceEpoch + (tran.offsetFromUtc * 1000)) {
|
||||
while (tran.atMSecsSinceEpoch != invalidMSecs()
|
||||
&& forLocalMSecs < tran.atMSecsSinceEpoch + (tran.offsetFromUtc * 1000)) {
|
||||
nextTran = tran;
|
||||
tran = previousTransition(tran.atMSecsSinceEpoch);
|
||||
}
|
||||
@ -272,7 +273,8 @@ QTimeZonePrivate::Data QTimeZonePrivate::dataForLocalTime(qint64 forLocalMSecs)
|
||||
// The zone msecs is after the transition, so check it is before the next tran
|
||||
// If not try use the next transition instead
|
||||
nextTran = nextTransition(tran.atMSecsSinceEpoch);
|
||||
while (forLocalMSecs >= nextTran.atMSecsSinceEpoch + (nextTran.offsetFromUtc * 1000)) {
|
||||
while (nextTran.atMSecsSinceEpoch != invalidMSecs()
|
||||
&& forLocalMSecs >= nextTran.atMSecsSinceEpoch + (nextTran.offsetFromUtc * 1000)) {
|
||||
tran = nextTran;
|
||||
nextTran = nextTransition(tran.atMSecsSinceEpoch);
|
||||
}
|
||||
@ -292,7 +294,8 @@ QTimeZonePrivate::Data QTimeZonePrivate::dataForLocalTime(qint64 forLocalMSecs)
|
||||
// then use the prev tran as we default to the FirstOccurrence
|
||||
// TODO Check if faster to just always get prev tran, or if faster using 6 hour check.
|
||||
Data dstTran = previousTransition(tran.atMSecsSinceEpoch);
|
||||
if (dstTran.daylightTimeOffset > 0 && diffPrevTran < (dstTran.daylightTimeOffset * 1000))
|
||||
if (dstTran.atMSecsSinceEpoch != invalidMSecs()
|
||||
&& dstTran.daylightTimeOffset > 0 && diffPrevTran < (dstTran.daylightTimeOffset * 1000))
|
||||
tran = dstTran;
|
||||
} else if (diffNextTran >= 0 && diffNextTran <= (nextTran.daylightTimeOffset * 1000)) {
|
||||
// If time falls within last hour of standard time then is actually the missing hour
|
||||
|
@ -2903,6 +2903,12 @@ void tst_QDateTime::timeZones() const
|
||||
// - Test 03:00:00 = 1 hour after tran
|
||||
hourAfterStd = QDateTime(QDate(2013, 10, 27), QTime(3, 0, 0), cet);
|
||||
QCOMPARE(hourAfterStd.toMSecsSinceEpoch(), dstToStdMSecs + 3600000);
|
||||
|
||||
// Test Time Zone that has transitions but no future transitions afer a given date
|
||||
QTimeZone sgt("Asia/Singapore");
|
||||
QDateTime future(QDate(2015, 1, 1), QTime(0, 0, 0), sgt);
|
||||
QVERIFY(future.isValid());
|
||||
QCOMPARE(future.offsetFromUtc(), 28800);
|
||||
}
|
||||
|
||||
void tst_QDateTime::invalid() const
|
||||
|
@ -409,6 +409,10 @@ void tst_QTimeZone::stressTest()
|
||||
qDebug() << "Stress test calculating transistions for" << testZone.id();
|
||||
testZone.transitions(lowDate1, highDate1);
|
||||
}
|
||||
testDate.setTimeZone(testZone);
|
||||
testDate.isValid();
|
||||
testDate.offsetFromUtc();
|
||||
testDate.timeZoneAbbreviation();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user