summaryrefslogtreecommitdiffstats
path: root/tests/auto
diff options
context:
space:
mode:
authorJohn Layt <jlayt@kde.org>2013-09-10 19:29:41 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-14 11:38:15 +0200
commit3a8b8edd0180594b84a97b974c188b39f17c9f49 (patch)
treea6a3377dbbff0ae75199440d0d493b0596ecb01f /tests/auto
parent6afbb462645f74b35fec95bf929b59a97e381438 (diff)
QDateTime - Add test case for Daylight Time Transitions
Test the Daylight Time transitions. QDateTime does not correctly deal with many of these scenarios so those tests are marked as QEXPECTFAIL. These bugs will be progressively addressed in coming commits. Change-Id: I01eba9d6143a792f081542cb198e221efcf28e98 Reviewed-by: Lars Knoll <lars.knoll@digia.com> Reviewed-by: Mitch Curtis <mitch.curtis@digia.com>
Diffstat (limited to 'tests/auto')
-rw-r--r--tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp377
1 files changed, 377 insertions, 0 deletions
diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
index bc489f6206..6c2fffb51d 100644
--- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
+++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
@@ -143,6 +143,8 @@ private slots:
void roundtripGermanLocale() const;
void utcOffsetLessThan() const;
+ void daylightTransitions() const;
+
private:
bool europeanTimeZone;
QDate defDate() const { return QDate(1900, 1, 1); }
@@ -2345,5 +2347,380 @@ void tst_QDateTime::utcOffsetLessThan() const
QVERIFY(!(dt2 < dt1));
}
+void tst_QDateTime::daylightTransitions() const
+{
+ if (europeanTimeZone) {
+ // CET transitions occur at 01:00:00 UTC on last Sunday in March and October
+ // 2011-03-27 02:00:00 CET became 03:00:00 CEST at msecs = 1301187600000
+ // 2011-10-30 03:00:00 CEST became 02:00:00 CET at msecs = 1319936400000
+ // 2012-03-25 02:00:00 CET became 03:00:00 CEST at msecs = 1332637200000
+ // 2012-10-28 03:00:00 CEST became 02:00:00 CET at msecs = 1351386000000
+ const qint64 daylight2011 = 1301187600000;
+ const qint64 standard2011 = 1319936400000;
+ const qint64 daylight2012 = 1332637200000;
+ const qint64 standard2012 = 1351386000000;
+ const qint64 msecsOneHour = 3600000;
+
+ // Test for correct behviour for StandardTime -> DaylightTime transition, i.e. missing hour
+
+ // Test setting date, time in missing hour will be invalid
+
+ QDateTime before(QDate(2012, 3, 25), QTime(1, 59, 59, 999));
+ QVERIFY(before.isValid());
+ QCOMPARE(before.date(), QDate(2012, 3, 25));
+ QCOMPARE(before.time(), QTime(1, 59, 59, 999));
+ QCOMPARE(before.toMSecsSinceEpoch(), daylight2012 - 1);
+
+ QDateTime missing(QDate(2012, 3, 25), QTime(2, 0, 0));
+ QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
+ QVERIFY(!missing.isValid());
+ QCOMPARE(missing.date(), QDate(2012, 3, 25));
+ QCOMPARE(missing.time(), QTime(2, 0, 0));
+
+ QDateTime after(QDate(2012, 3, 25), QTime(3, 0, 0));
+ QVERIFY(after.isValid());
+ QCOMPARE(after.date(), QDate(2012, 3, 25));
+ QCOMPARE(after.time(), QTime(3, 0, 0));
+ QCOMPARE(after.toMSecsSinceEpoch(), daylight2012);
+
+ // Test round-tripping of msecs
+
+ before.setMSecsSinceEpoch(daylight2012 - 1);
+ QVERIFY(before.isValid());
+ QCOMPARE(before.date(), QDate(2012, 3, 25));
+ QCOMPARE(before.time(), QTime(1, 59, 59, 999));
+ QCOMPARE(before.toMSecsSinceEpoch(), daylight2012 -1);
+
+ after.setMSecsSinceEpoch(daylight2012);
+ QVERIFY(after.isValid());
+ QCOMPARE(after.date(), QDate(2012, 3, 25));
+ QCOMPARE(after.time(), QTime(3, 0, 0));
+ QCOMPARE(after.toMSecsSinceEpoch(), daylight2012);
+
+ // Test changing time spec re-validates the date/time
+
+ QDateTime utc(QDate(2012, 3, 25), QTime(2, 00, 0), Qt::UTC);
+ QVERIFY(utc.isValid());
+ QCOMPARE(utc.date(), QDate(2012, 3, 25));
+ QCOMPARE(utc.time(), QTime(2, 0, 0));
+ utc.setTimeSpec(Qt::LocalTime);
+ QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
+ QVERIFY(!utc.isValid());
+ QCOMPARE(utc.date(), QDate(2012, 3, 25));
+ QCOMPARE(utc.time(), QTime(2, 0, 0));
+ utc.setTimeSpec(Qt::UTC);
+ QVERIFY(utc.isValid());
+ QCOMPARE(utc.date(), QDate(2012, 3, 25));
+ QCOMPARE(utc.time(), QTime(2, 0, 0));
+
+ // Test date maths, if result falls in missing hour then becomes next hour
+
+ QDateTime test(QDate(2011, 3, 25), QTime(2, 0, 0));
+ QVERIFY(test.isValid());
+ test = test.addYears(1);
+ QVERIFY(test.isValid());
+ QCOMPARE(test.date(), QDate(2012, 3, 25));
+ QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
+ QCOMPARE(test.time(), QTime(3, 0, 0));
+
+ test = QDateTime(QDate(2012, 2, 25), QTime(2, 0, 0));
+ QVERIFY(test.isValid());
+ test = test.addMonths(1);
+ QVERIFY(test.isValid());
+ QCOMPARE(test.date(), QDate(2012, 3, 25));
+ QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
+ QCOMPARE(test.time(), QTime(3, 0, 0));
+
+ test = QDateTime(QDate(2012, 3, 24), QTime(2, 0, 0));
+ QVERIFY(test.isValid());
+ test = test.addDays(1);
+ QVERIFY(test.isValid());
+ QCOMPARE(test.date(), QDate(2012, 3, 25));
+ QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
+ QCOMPARE(test.time(), QTime(3, 0, 0));
+
+ test = QDateTime(QDate(2012, 3, 25), QTime(1, 0, 0));
+ QVERIFY(test.isValid());
+ QCOMPARE(test.toMSecsSinceEpoch(), daylight2012 - msecsOneHour);
+ test = test.addMSecs(msecsOneHour);
+ QVERIFY(test.isValid());
+ QCOMPARE(test.date(), QDate(2012, 3, 25));
+ QCOMPARE(test.time(), QTime(3, 0, 0));
+ QCOMPARE(test.toMSecsSinceEpoch(), daylight2012);
+
+ // Test for correct behviour for DaylightTime -> StandardTime transition, i.e. second occurrence
+
+ // Test setting date and time in first and second occurrence will be valid
+
+ // 1 hour before transition is 2:00:00 FirstOccurrence
+ QDateTime hourBefore(QDate(2012, 10, 28), QTime(2, 0, 0));
+ QVERIFY(hourBefore.isValid());
+ QCOMPARE(hourBefore.date(), QDate(2012, 10, 28));
+ QCOMPARE(hourBefore.time(), QTime(2, 0, 0));
+#ifdef Q_OS_WIN
+ // Windows uses SecondOccurrence
+ QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
+#endif // Q_OS_WIN
+ QCOMPARE(hourBefore.toMSecsSinceEpoch(), standard2012 - msecsOneHour);
+
+ // 1 msec before transition is 2:59:59.999 FirstOccurrence
+ QDateTime msecBefore(QDate(2012, 10, 28), QTime(2, 59, 59, 999));
+ QVERIFY(msecBefore.isValid());
+ QCOMPARE(msecBefore.date(), QDate(2012, 10, 28));
+ QCOMPARE(msecBefore.time(), QTime(2, 59, 59, 999));
+#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
+ // Win and Mac uses SecondOccurrence here
+ QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
+#endif // Q_OS_MAC
+ QCOMPARE(msecBefore.toMSecsSinceEpoch(), standard2012 - 1);
+
+ // At transition is 2:00:00 SecondOccurrence
+ QDateTime atTran(QDate(2012, 10, 28), QTime(2, 0, 0));
+ QVERIFY(atTran.isValid());
+ QCOMPARE(atTran.date(), QDate(2012, 10, 28));
+ QCOMPARE(atTran.time(), QTime(2, 0, 0));
+#ifndef Q_OS_WIN
+ // Windows uses SecondOccurrence
+ QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
+#endif // Q_OS_WIN
+ QCOMPARE(atTran.toMSecsSinceEpoch(), standard2012);
+
+ // 59:59.999 after transition is 2:59:59.999 SecondOccurrence
+ QDateTime afterTran(QDate(2012, 10, 28), QTime(2, 59, 59, 999));
+ QVERIFY(afterTran.isValid());
+ QCOMPARE(afterTran.date(), QDate(2012, 10, 28));
+ QCOMPARE(afterTran.time(), QTime(2, 59, 59, 999));
+#if defined (Q_OS_UNIX) && !defined(Q_OS_MAC)
+ // Linux mktime bug uses last calculation
+ QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
+#endif // Q_OS_UNIX
+ QCOMPARE(afterTran.toMSecsSinceEpoch(), standard2012 + msecsOneHour - 1);
+
+ // 1 hour after transition is 3:00:00 FirstOccurrence
+ QDateTime hourAfter(QDate(2012, 10, 28), QTime(3, 0, 0));
+ QVERIFY(hourAfter.isValid());
+ QCOMPARE(hourAfter.date(), QDate(2012, 10, 28));
+ QCOMPARE(hourAfter.time(), QTime(3, 0, 0));
+ QCOMPARE(hourAfter.toMSecsSinceEpoch(), standard2012 + msecsOneHour);
+
+ // Test round-tripping of msecs
+
+ // 1 hour before transition is 2:00:00 FirstOccurrence
+ hourBefore.setMSecsSinceEpoch(standard2012 - msecsOneHour);
+ QVERIFY(hourBefore.isValid());
+ QCOMPARE(hourBefore.date(), QDate(2012, 10, 28));
+ QCOMPARE(hourBefore.time(), QTime(2, 0, 0));
+#ifndef Q_OS_MAC
+ // Linux mktime bug uses last calculation
+ QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
+#endif // Q_OS_MAC
+ QCOMPARE(hourBefore.toMSecsSinceEpoch(), standard2012 - msecsOneHour);
+
+ // 1 msec before transition is 2:59:59.999 FirstOccurrence
+ msecBefore.setMSecsSinceEpoch(standard2012 - 1);
+ QVERIFY(msecBefore.isValid());
+ QCOMPARE(msecBefore.date(), QDate(2012, 10, 28));
+ QCOMPARE(msecBefore.time(), QTime(2, 59, 59, 999));
+ QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
+ QCOMPARE(msecBefore.toMSecsSinceEpoch(), standard2012 - 1);
+
+ // At transition is 2:00:00 SecondOccurrence
+ atTran.setMSecsSinceEpoch(standard2012);
+ QVERIFY(atTran.isValid());
+ QCOMPARE(atTran.date(), QDate(2012, 10, 28));
+ QCOMPARE(atTran.time(), QTime(2, 0, 0));
+#ifdef Q_OS_MAC
+ // Mac defaults to FirstOccurrence here
+ QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
+#endif // Q_OS_MAC
+ QCOMPARE(atTran.toMSecsSinceEpoch(), standard2012);
+
+ // 59:59.999 after transition is 2:59:59.999 SecondOccurrence
+ afterTran.setMSecsSinceEpoch(standard2012 + msecsOneHour - 1);
+ QVERIFY(afterTran.isValid());
+ QCOMPARE(afterTran.date(), QDate(2012, 10, 28));
+ QCOMPARE(afterTran.time(), QTime(2, 59, 59, 999));
+ QCOMPARE(afterTran.toMSecsSinceEpoch(), standard2012 + msecsOneHour - 1);
+
+ // 1 hour after transition is 3:00:00 FirstOccurrence
+ hourAfter.setMSecsSinceEpoch(standard2012 + msecsOneHour);
+ QVERIFY(hourAfter.isValid());
+ QCOMPARE(hourAfter.date(), QDate(2012, 10, 28));
+ QCOMPARE(hourAfter.time(), QTime(3, 0, 0));
+ QCOMPARE(hourAfter.toMSecsSinceEpoch(), standard2012 + msecsOneHour);
+
+ // Test date maths, result is always FirstOccurrence
+
+ // Add year to get to tran FirstOccurrence
+ test = QDateTime(QDate(2011, 10, 28), QTime(2, 0, 0));
+ test = test.addYears(1);
+ QVERIFY(test.isValid());
+ QCOMPARE(test.date(), QDate(2012, 10, 28));
+ QCOMPARE(test.time(), QTime(2, 0, 0));
+#ifndef Q_OS_MAC
+ // Linux mktime bug uses last calculation
+ QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
+#endif // Q_OS_MAC
+ QCOMPARE(test.toMSecsSinceEpoch(), standard2012 - msecsOneHour);
+
+ // Add year to get to after tran FirstOccurrence
+ test = QDateTime(QDate(2011, 10, 28), QTime(3, 0, 0));
+ test = test.addYears(1);
+ QVERIFY(test.isValid());
+ QCOMPARE(test.date(), QDate(2012, 10, 28));
+ QCOMPARE(test.time(), QTime(3, 0, 0));
+ QCOMPARE(test.toMSecsSinceEpoch(), standard2012 + msecsOneHour);
+
+ // Add year to tran FirstOccurrence
+ test = QDateTime(QDate(2011, 10, 30), QTime(2, 0, 0));
+ test = test.addYears(1);
+ QVERIFY(test.isValid());
+ QCOMPARE(test.date(), QDate(2012, 10, 30));
+ QCOMPARE(test.time(), QTime(2, 0, 0));
+
+ // Add year to tran SecondOccurrence
+ test = QDateTime(QDate(2011, 10, 30), QTime(2, 0, 0)); // TODO SecondOccurrence
+ test = test.addYears(1);
+ QVERIFY(test.isValid());
+ QCOMPARE(test.date(), QDate(2012, 10, 30));
+ QCOMPARE(test.time(), QTime(2, 0, 0));
+
+ // Add year to after tran FirstOccurrence
+ test = QDateTime(QDate(2011, 10, 30), QTime(3, 0, 0));
+ test = test.addYears(1);
+ QVERIFY(test.isValid());
+ QCOMPARE(test.date(), QDate(2012, 10, 30));
+ QCOMPARE(test.time(), QTime(3, 0, 0));
+
+
+ // Add month to get to tran FirstOccurrence
+ test = QDateTime(QDate(2012, 9, 28), QTime(2, 0, 0));
+ test = test.addMonths(1);
+ QVERIFY(test.isValid());
+ QCOMPARE(test.date(), QDate(2012, 10, 28));
+ QCOMPARE(test.time(), QTime(2, 0, 0));
+#ifndef Q_OS_MAC
+ // Linux mktime bug uses last calculation
+ QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
+#endif // Q_OS_MAC
+ QCOMPARE(test.toMSecsSinceEpoch(), standard2012 - msecsOneHour);
+
+ // Add month to get to after tran FirstOccurrence
+ test = QDateTime(QDate(2012, 9, 28), QTime(3, 0, 0));
+ test = test.addMonths(1);
+ QVERIFY(test.isValid());
+ QCOMPARE(test.date(), QDate(2012, 10, 28));
+ QCOMPARE(test.time(), QTime(3, 0, 0));
+ QCOMPARE(test.toMSecsSinceEpoch(), standard2012 + msecsOneHour);
+
+ // Add month to tran FirstOccurrence
+ test = QDateTime(QDate(2011, 10, 30), QTime(2, 0, 0));
+ test = test.addMonths(1);
+ QVERIFY(test.isValid());
+ QCOMPARE(test.date(), QDate(2011, 11, 30));
+ QCOMPARE(test.time(), QTime(2, 0, 0));
+
+ // Add month to tran SecondOccurrence
+ test = QDateTime(QDate(2011, 10, 30), QTime(2, 0, 0)); // TODO SecondOccurrence
+ test = test.addMonths(1);
+ QVERIFY(test.isValid());
+ QCOMPARE(test.date(), QDate(2011, 11, 30));
+ QCOMPARE(test.time(), QTime(2, 0, 0));
+
+ // Add month to after tran FirstOccurrence
+ test = QDateTime(QDate(2011, 10, 30), QTime(3, 0, 0));
+ test = test.addMonths(1);
+ QVERIFY(test.isValid());
+ QCOMPARE(test.date(), QDate(2011, 11, 30));
+ QCOMPARE(test.time(), QTime(3, 0, 0));
+
+
+ // Add day to get to tran FirstOccurrence
+ test = QDateTime(QDate(2012, 10, 27), QTime(2, 0, 0));
+ test = test.addDays(1);
+ QVERIFY(test.isValid());
+ QCOMPARE(test.date(), QDate(2012, 10, 28));
+ QCOMPARE(test.time(), QTime(2, 0, 0));
+#ifndef Q_OS_MAC
+ // Linux mktime bug uses last calculation
+ QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
+#endif // Q_OS_MAC
+ QCOMPARE(test.toMSecsSinceEpoch(), standard2012 - msecsOneHour);
+
+ // Add day to get to after tran FirstOccurrence
+ test = QDateTime(QDate(2012, 10, 27), QTime(3, 0, 0));
+ test = test.addDays(1);
+ QVERIFY(test.isValid());
+ QCOMPARE(test.date(), QDate(2012, 10, 28));
+ QCOMPARE(test.time(), QTime(3, 0, 0));
+ QCOMPARE(test.toMSecsSinceEpoch(), standard2012 + msecsOneHour);
+
+ // Add day to tran FirstOccurrence
+ test = QDateTime(QDate(2011, 10, 30), QTime(2, 0, 0));
+ test = test.addDays(1);
+ QVERIFY(test.isValid());
+ QCOMPARE(test.date(), QDate(2011, 10, 31));
+ QCOMPARE(test.time(), QTime(2, 0, 0));
+
+ // Add day to tran SecondOccurrence
+ test = QDateTime(QDate(2011, 10, 30), QTime(2, 0, 0)); // TODO SecondOccurrence
+ test = test.addDays(1);
+ QVERIFY(test.isValid());
+ QCOMPARE(test.date(), QDate(2011, 10, 31));
+ QCOMPARE(test.time(), QTime(2, 0, 0));
+
+ // Add day to after tran FirstOccurrence
+ test = QDateTime(QDate(2011, 10, 30), QTime(3, 0, 0));
+ test = test.addDays(1);
+ QVERIFY(test.isValid());
+ QCOMPARE(test.date(), QDate(2011, 10, 31));
+ QCOMPARE(test.time(), QTime(3, 0, 0));
+
+
+ // Add hour to get to tran FirstOccurrence
+ test = QDateTime(QDate(2012, 10, 28), QTime(1, 0, 0));
+ test = test.addMSecs(msecsOneHour);
+ QVERIFY(test.isValid());
+ QCOMPARE(test.date(), QDate(2012, 10, 28));
+ QCOMPARE(test.time(), QTime(2, 0, 0));
+ QCOMPARE(test.toMSecsSinceEpoch(), standard2012 - msecsOneHour);
+
+ // Add hour to tran FirstOccurrence to get to tran SecondOccurrence
+ test = QDateTime(QDate(2012, 10, 28), QTime(2, 0, 0));
+ test = test.addMSecs(msecsOneHour);
+ QVERIFY(test.isValid());
+ QCOMPARE(test.date(), QDate(2012, 10, 28));
+#ifdef Q_OS_WIN
+ // Windows uses SecondOccurrence
+ QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
+#endif // Q_OS_WIN
+ QCOMPARE(test.time(), QTime(2, 0, 0));
+#ifdef Q_OS_WIN
+ // Windows uses SecondOccurrence
+ QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
+#endif // Q_OS_WIN
+ QCOMPARE(test.toMSecsSinceEpoch(), standard2012);
+
+ // Add hour to tran SecondOccurrence to get to after tran FirstOccurrence
+ test = QDateTime(QDate(2012, 10, 28), QTime(2, 0, 0)); // TODO SecondOccurrence
+ test = test.addMSecs(msecsOneHour);
+ QVERIFY(test.isValid());
+ QCOMPARE(test.date(), QDate(2012, 10, 28));
+#ifdef Q_OS_MAC
+ // Mac uses FirstOccurrence
+ QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
+#endif // Q_OS_MAC
+ QCOMPARE(test.time(), QTime(3, 0, 0));
+#ifdef Q_OS_MAC
+ // Mac uses FirstOccurrence
+ QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
+#endif // Q_OS_MAC
+ QCOMPARE(test.toMSecsSinceEpoch(), standard2012 + msecsOneHour);
+
+ } else {
+ QSKIP("You must test using Central European (CET/CEST) time zone, e.g. TZ=Europe/Oslo");
+ }
+}
+
QTEST_APPLESS_MAIN(tst_QDateTime)
#include "tst_qdatetime.moc"