summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2018-06-13 21:19:18 +0200
committerEdward Welbourne <edward.welbourne@qt.io>2020-10-09 01:09:42 +0200
commitcb0ecd6b6dfaea372d7973e4d78e661deb441540 (patch)
tree0c40156d09605f5901136d5727bf71278fd09267 /tests
parent83bff8951a6129cb9e6eaa0286328ae4953f0e8c (diff)
Check value is in range when setting a QDateTime
Previously, a QDate representing more than about 0.3 gigayears before or after the epoch would overflow the millisecond count and produce a "valid" date-time that didn't represent the date and time passed to its constructor. Changed to detect such overflow and produce an invalid date-time instead, if it happens. Corrected some tests that wrongly expected to be able to represent extreme date-time values with every time-spec. The (milli)seconds since epoch are from UTC's epoch, so converting to another offset, zone or local time may give a value outside the actual range. Added some tests for the actual exact bounds. Task-number: QTBUG-68855 Change-Id: I866a4974aeb54bba92dbe7eab0a440baf02124f0 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp42
1 files changed, 31 insertions, 11 deletions
diff --git a/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp
index 2e2b5fbf24..d66ee5c832 100644
--- a/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp
+++ b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp
@@ -755,17 +755,22 @@ void tst_QDateTime::fromMSecsSinceEpoch()
void tst_QDateTime::fromSecsSinceEpoch()
{
const qint64 maxSeconds = std::numeric_limits<qint64>::max() / 1000;
+ const QDateTime early = QDateTime::fromSecsSinceEpoch(-maxSeconds, Qt::UTC);
+ const QDateTime late = QDateTime::fromSecsSinceEpoch(maxSeconds, Qt::UTC);
- QVERIFY(QDateTime::fromSecsSinceEpoch(maxSeconds).isValid());
- QVERIFY(!QDateTime::fromSecsSinceEpoch(maxSeconds + 1).isValid());
- QVERIFY(QDateTime::fromSecsSinceEpoch(-maxSeconds).isValid());
- QVERIFY(!QDateTime::fromSecsSinceEpoch(-maxSeconds - 1).isValid());
-
- QVERIFY(QDateTime::fromSecsSinceEpoch(maxSeconds, Qt::UTC).isValid());
+ QVERIFY(late.isValid());
QVERIFY(!QDateTime::fromSecsSinceEpoch(maxSeconds + 1, Qt::UTC).isValid());
- QVERIFY(QDateTime::fromSecsSinceEpoch(-maxSeconds, Qt::UTC).isValid());
+ QVERIFY(early.isValid());
QVERIFY(!QDateTime::fromSecsSinceEpoch(-maxSeconds - 1, Qt::UTC).isValid());
+ // Local time: need to adjust for its zone offset
+ const qint64 last = maxSeconds - qMax(late.addYears(-1).toLocalTime().offsetFromUtc(), 0);
+ QVERIFY(QDateTime::fromSecsSinceEpoch(last).isValid());
+ QVERIFY(!QDateTime::fromSecsSinceEpoch(last + 1).isValid());
+ const qint64 first = -maxSeconds - qMin(early.addYears(1).toLocalTime().offsetFromUtc(), 0);
+ QVERIFY(QDateTime::fromSecsSinceEpoch(first).isValid());
+ QVERIFY(!QDateTime::fromSecsSinceEpoch(first - 1).isValid());
+
// Use an offset for which .toUTC()'s return would flip the validity:
QVERIFY(QDateTime::fromSecsSinceEpoch(maxSeconds, Qt::OffsetFromUTC, 7200).isValid());
QVERIFY(!QDateTime::fromSecsSinceEpoch(maxSeconds + 1, Qt::OffsetFromUTC, -7200).isValid());
@@ -775,10 +780,10 @@ void tst_QDateTime::fromSecsSinceEpoch()
#if QT_CONFIG(timezone)
// As for offset, use zones each side of UTC:
const QTimeZone west("UTC-02:00"), east("UTC+02:00");
- QVERIFY(QDateTime::fromSecsSinceEpoch(maxSeconds, east).isValid());
- QVERIFY(!QDateTime::fromSecsSinceEpoch(maxSeconds + 1, west).isValid());
- QVERIFY(QDateTime::fromSecsSinceEpoch(-maxSeconds, west).isValid());
- QVERIFY(!QDateTime::fromSecsSinceEpoch(-maxSeconds - 1, east).isValid());
+ QVERIFY(QDateTime::fromSecsSinceEpoch(maxSeconds, west).isValid());
+ QVERIFY(!QDateTime::fromSecsSinceEpoch(maxSeconds + 1, east).isValid());
+ QVERIFY(QDateTime::fromSecsSinceEpoch(-maxSeconds, east).isValid());
+ QVERIFY(!QDateTime::fromSecsSinceEpoch(-maxSeconds - 1, west).isValid());
#endif // timezone
}
@@ -3759,6 +3764,21 @@ void tst_QDateTime::range() const
int(QDateTime::YearRange::First));
QCOMPARE(QDateTime::fromMSecsSinceEpoch(Bounds::max() - 1, Qt::UTC).date().year(),
int(QDateTime::YearRange::Last));
+ constexpr qint64 millisPerDay = 24 * 3600 * 1000;
+ constexpr qint64 wholeDays = Bounds::max() / millisPerDay;
+ constexpr qint64 millisRemainder = Bounds::max() % millisPerDay;
+ QVERIFY(QDateTime(QDate(1970, 1, 1).addDays(wholeDays),
+ QTime::fromMSecsSinceStartOfDay(millisRemainder),
+ Qt::UTC).isValid());
+ QVERIFY(!QDateTime(QDate(1970, 1, 1).addDays(wholeDays),
+ QTime::fromMSecsSinceStartOfDay(millisRemainder + 1),
+ Qt::UTC).isValid());
+ QVERIFY(QDateTime(QDate(1970, 1, 1).addDays(-wholeDays - 1),
+ QTime::fromMSecsSinceStartOfDay(3600 * 24000 - millisRemainder - 1),
+ Qt::UTC).isValid());
+ QVERIFY(!QDateTime(QDate(1970, 1, 1).addDays(-wholeDays - 1),
+ QTime::fromMSecsSinceStartOfDay(3600 * 24000 - millisRemainder - 2),
+ Qt::UTC).isValid());
}
void tst_QDateTime::macTypes()