QDateTime - Fix toTimeSpec() for invalid datetimes

Check if the datetime is valid before converting it to a different time
spec.  If it is invalid then just change the spec to keep behavior
consistent with 5.1.

Task-number: QTBUG-34020
Change-Id: I6630ec1d50f810a2178ab3222bd32af018085f81
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
John Layt 2013-10-15 17:36:36 +02:00 committed by The Qt Project
parent 24b817f20a
commit 6a63554bf8
2 changed files with 51 additions and 3 deletions

View File

@ -3921,7 +3921,16 @@ qint64 QDateTime::msecsTo(const QDateTime &other) const
QDateTime QDateTime::toTimeSpec(Qt::TimeSpec spec) const
{
return fromMSecsSinceEpoch(toMSecsSinceEpoch(), spec, 0);
if (d->m_spec == spec && (spec == Qt::UTC || spec == Qt::LocalTime))
return *this;
if (!isValid()) {
QDateTime ret = *this;
ret.setTimeSpec(spec);
return ret;
}
return fromMSecsSinceEpoch(d->toMSecsSinceEpoch(), spec, 0);
}
/*!
@ -3939,7 +3948,16 @@ QDateTime QDateTime::toTimeSpec(Qt::TimeSpec spec) const
QDateTime QDateTime::toOffsetFromUtc(int offsetSeconds) const
{
return fromMSecsSinceEpoch(toMSecsSinceEpoch(), Qt::OffsetFromUTC, offsetSeconds);
if (d->m_spec == Qt::OffsetFromUTC && d->m_offsetFromUtc == offsetSeconds)
return *this;
if (!isValid()) {
QDateTime ret = *this;
ret.setOffsetFromUtc(offsetSeconds);
return ret;
}
return fromMSecsSinceEpoch(d->toMSecsSinceEpoch(), Qt::OffsetFromUTC, offsetSeconds);
}
#ifndef QT_BOOTSTRAPPED
@ -3953,7 +3971,16 @@ QDateTime QDateTime::toOffsetFromUtc(int offsetSeconds) const
QDateTime QDateTime::toTimeZone(const QTimeZone &timeZone) const
{
return fromMSecsSinceEpoch(toMSecsSinceEpoch(), timeZone);
if (d->m_spec == Qt::TimeZone && d->m_timeZone == timeZone)
return *this;
if (!isValid()) {
QDateTime ret = *this;
ret.setTimeZone(timeZone);
return ret;
}
return fromMSecsSinceEpoch(d->toMSecsSinceEpoch(), timeZone);
}
#endif // QT_BOOTSTRAPPED

View File

@ -147,6 +147,8 @@ private slots:
void daylightTransitions() const;
void timeZones() const;
void invalid() const;
private:
bool europeanTimeZone;
QDate defDate() const { return QDate(1900, 1, 1); }
@ -2899,5 +2901,24 @@ void tst_QDateTime::timeZones() const
QCOMPARE(hourAfterStd.toMSecsSinceEpoch(), dstToStdMSecs + 3600000);
}
void tst_QDateTime::invalid() const
{
QDateTime invalidDate = QDateTime(QDate(0, 0, 0), QTime(-1, -1, -1));
QCOMPARE(invalidDate.isValid(), false);
QCOMPARE(invalidDate.timeSpec(), Qt::LocalTime);
QDateTime utcDate = invalidDate.toUTC();
QCOMPARE(utcDate.isValid(), false);
QCOMPARE(utcDate.timeSpec(), Qt::UTC);
QDateTime offsetDate = invalidDate.toOffsetFromUtc(3600);
QCOMPARE(offsetDate.isValid(), false);
QCOMPARE(offsetDate.timeSpec(), Qt::OffsetFromUTC);
QDateTime tzDate = invalidDate.toTimeZone(QTimeZone("Europe/Oslo"));
QCOMPARE(tzDate.isValid(), false);
QCOMPARE(tzDate.timeSpec(), Qt::TimeZone);
}
QTEST_APPLESS_MAIN(tst_QDateTime)
#include "tst_qdatetime.moc"