summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorJohn Layt <jlayt@kde.org>2013-02-11 13:44:37 +0000
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-23 01:14:03 +0200
commit55f5b29d7975d7e642ec258e44ca23726e1dfa0d (patch)
treea962c946ed58690d67bba1982556f3cb97545969 /tests
parent8af776d4140c19baccb8e2767ed8b57cc79ccb06 (diff)
QDateTime - Add QTimeZone support
Add support to QDateTime for time zones using the new QTimeZone class. [ChangeLog][QtCore][QDateTime] Add support for a new Qt::TimeZone spec to be used with QTimeZone to define times in a specific time zone. Change-Id: I21bfa52a8ba8989b55bb74e025d1f2b2b623b2a7 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp200
-rw-r--r--tests/auto/corelib/tools/qlocale/tst_qlocale.cpp12
-rw-r--r--tests/benchmarks/corelib/tools/qdatetime/main.cpp91
3 files changed, 302 insertions, 1 deletions
diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
index b51fa0095c..a282fcabd3 100644
--- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
+++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
@@ -145,6 +145,7 @@ private slots:
void isDaylightTime() const;
void daylightTransitions() const;
+ void timeZones() const;
private:
bool europeanTimeZone;
@@ -547,6 +548,8 @@ void tst_QDateTime::setMSecsSinceEpoch()
dt.setMSecsSinceEpoch(msecs);
QCOMPARE(dt, utc);
+ QCOMPARE(dt.date(), utc.date());
+ QCOMPARE(dt.time(), utc.time());
QCOMPARE(dt.timeSpec(), Qt::UTC);
if (europeanTimeZone) {
@@ -561,6 +564,23 @@ void tst_QDateTime::setMSecsSinceEpoch()
if (msecs != std::numeric_limits<qint64>::max())
QCOMPARE(localDt, utc);
QCOMPARE(localDt.timeSpec(), Qt::LocalTime);
+
+ // Compare result for LocalTime to TimeZone
+ QTimeZone europe("Europe/Oslo");
+ QDateTime dt2;
+ dt2.setTimeZone(europe);
+ dt2.setMSecsSinceEpoch(msecs);
+ QCOMPARE(dt2.date(), european.date());
+#ifdef Q_OS_MAC
+ // NSTimeZone doesn't apply DST to high values
+ if (msecs < (Q_INT64_C(123456) << 32))
+#else
+ // Linux and Win are OK except when they overflow
+ if (msecs != std::numeric_limits<qint64>::max())
+#endif
+ QCOMPARE(dt2.time(), european.time());
+ QCOMPARE(dt2.timeSpec(), Qt::TimeZone);
+ QCOMPARE(dt2.timeZone(), europe);
}
QCOMPARE(dt.toMSecsSinceEpoch(), msecs);
@@ -2107,6 +2127,12 @@ void tst_QDateTime::offsetFromUtc()
} else {
QSKIP("You must test using Central European (CET/CEST) time zone, e.g. TZ=Europe/Oslo");
}
+
+ QDateTime dt5(QDate(2013, 1, 1), QTime(0, 0, 0), QTimeZone("Pacific/Auckland"));
+ QCOMPARE(dt5.offsetFromUtc(), 46800);
+
+ QDateTime dt6(QDate(2013, 6, 1), QTime(0, 0, 0), QTimeZone("Pacific/Auckland"));
+ QCOMPARE(dt6.offsetFromUtc(), 43200);
}
void tst_QDateTime::setOffsetFromUtc()
@@ -2232,6 +2258,17 @@ void tst_QDateTime::timeZoneAbbreviation()
} else {
QSKIP("You must test using Central European (CET/CEST) time zone, e.g. TZ=Europe/Oslo");
}
+
+ QDateTime dt5(QDate(2013, 1, 1), QTime(0, 0, 0), QTimeZone("Europe/Berlin"));
+#ifdef Q_OS_WIN
+ QEXPECT_FAIL("", "QTimeZone windows backend only returns long name", Continue);
+#endif
+ QCOMPARE(dt5.timeZoneAbbreviation(), QString("CET"));
+ QDateTime dt6(QDate(2013, 6, 1), QTime(0, 0, 0), QTimeZone("Europe/Berlin"));
+#ifdef Q_OS_WIN
+ QEXPECT_FAIL("", "QTimeZone windows backend only returns long name", Continue);
+#endif
+ QCOMPARE(dt6.timeZoneAbbreviation(), QString("CEST"));
}
void tst_QDateTime::getDate()
@@ -2717,5 +2754,168 @@ void tst_QDateTime::daylightTransitions() const
}
}
+void tst_QDateTime::timeZones() const
+{
+ QTimeZone nzTz = QTimeZone("Pacific/Auckland");
+
+ // During Standard Time NZ is +12:00
+ QDateTime utcStd(QDate(2012, 6, 1), QTime(0, 0, 0), Qt::UTC);
+ QDateTime nzStd(QDate(2012, 6, 1), QTime(12, 0, 0), nzTz);
+
+ QCOMPARE(nzStd.isValid(), true);
+ QCOMPARE(nzStd.timeSpec(), Qt::TimeZone);
+ QCOMPARE(nzStd.date(), QDate(2012, 6, 1));
+ QCOMPARE(nzStd.time(), QTime(12, 0, 0));
+ QVERIFY(nzStd.timeZone() == nzTz);
+ QCOMPARE(nzStd.timeZone().id(), QByteArray("Pacific/Auckland"));
+ QCOMPARE(nzStd.offsetFromUtc(), 43200);
+ QCOMPARE(nzStd.isDaylightTime(), false);
+ QCOMPARE(nzStd.toMSecsSinceEpoch(), utcStd.toMSecsSinceEpoch());
+
+ // During Daylight Time NZ is +13:00
+ QDateTime utcDst(QDate(2012, 1, 1), QTime(0, 0, 0), Qt::UTC);
+ QDateTime nzDst(QDate(2012, 1, 1), QTime(13, 0, 0), nzTz);
+
+ QCOMPARE(nzDst.isValid(), true);
+ QCOMPARE(nzDst.date(), QDate(2012, 1, 1));
+ QCOMPARE(nzDst.time(), QTime(13, 0, 0));
+ QCOMPARE(nzDst.offsetFromUtc(), 46800);
+ QCOMPARE(nzDst.isDaylightTime(), true);
+ QCOMPARE(nzDst.toMSecsSinceEpoch(), utcDst.toMSecsSinceEpoch());
+
+ QDateTime utc = nzStd.toUTC();
+ QCOMPARE(utc.date(), utcStd.date());
+ QCOMPARE(utc.time(), utcStd.time());
+
+ utc = nzDst.toUTC();
+ QCOMPARE(utc.date(), utcDst.date());
+ QCOMPARE(utc.time(), utcDst.time());
+
+ // Sydney is 2 hours behind New Zealand
+ QTimeZone ausTz = QTimeZone("Australia/Sydney");
+ QDateTime aus = nzStd.toTimeZone(ausTz);
+ QCOMPARE(aus.date(), QDate(2012, 6, 1));
+ QCOMPARE(aus.time(), QTime(10, 0, 0));
+
+ QDateTime dt1(QDate(2012, 6, 1), QTime(0, 0, 0), Qt::UTC);
+ QCOMPARE(dt1.timeSpec(), Qt::UTC);
+ dt1.setTimeZone(nzTz);
+ QCOMPARE(dt1.timeSpec(), Qt::TimeZone);
+ QCOMPARE(dt1.date(), QDate(2012, 6, 1));
+ QCOMPARE(dt1.time(), QTime(0, 0, 0));
+ QCOMPARE(dt1.timeZone(), nzTz);
+
+ QDateTime dt2 = QDateTime::fromTime_t(1338465600, nzTz);
+ QCOMPARE(dt2.date(), dt1.date());
+ QCOMPARE(dt2.time(), dt1.time());
+ QCOMPARE(dt2.timeSpec(), dt1.timeSpec());
+ QCOMPARE(dt2.timeZone(), dt1.timeZone());
+
+ QDateTime dt3 = QDateTime::fromMSecsSinceEpoch(1338465600000, nzTz);
+ QCOMPARE(dt3.date(), dt1.date());
+ QCOMPARE(dt3.time(), dt1.time());
+ QCOMPARE(dt3.timeSpec(), dt1.timeSpec());
+ QCOMPARE(dt3.timeZone(), dt1.timeZone());
+
+ // Check datastream serialises the time zone
+ QByteArray tmp;
+ {
+ QDataStream ds(&tmp, QIODevice::WriteOnly);
+ ds << dt1;
+ }
+ QDateTime dt4;
+ {
+ QDataStream ds(&tmp, QIODevice::ReadOnly);
+ ds >> dt4;
+ }
+ QCOMPARE(dt4, dt1);
+ QCOMPARE(dt4.timeSpec(), Qt::TimeZone);
+ QCOMPARE(dt4.timeZone(), nzTz);
+
+ // Check handling of transition times
+ QTimeZone cet("Europe/Oslo");
+
+ // Standard Time to Daylight Time 2013 on 2013-03-31 is 2:00 local time / 1:00 UTC
+ qint64 stdToDstMSecs = 1364691600000;
+
+ // Test MSecs to local
+ // - Test 1 msec before tran = 01:59:59.999
+ QDateTime beforeDst = QDateTime::fromMSecsSinceEpoch(stdToDstMSecs - 1, cet);
+ QCOMPARE(beforeDst.date(), QDate(2013, 3, 31));
+ QCOMPARE(beforeDst.time(), QTime(1, 59, 59, 999));
+ // - Test at tran = 03:00:00
+ QDateTime atDst = QDateTime::fromMSecsSinceEpoch(stdToDstMSecs, cet);
+ QCOMPARE(atDst.date(), QDate(2013, 3, 31));
+ QCOMPARE(atDst.time(), QTime(3, 0, 0));
+
+ // Test local to MSecs
+ // - Test 1 msec before tran = 01:59:59.999
+ beforeDst = QDateTime(QDate(2013, 3, 31), QTime(1, 59, 59, 999), cet);
+ QCOMPARE(beforeDst.toMSecsSinceEpoch(), stdToDstMSecs - 1);
+ // - Test at tran = 03:00:00
+ atDst = QDateTime(QDate(2013, 3, 31), QTime(3, 0, 0), cet);
+ QCOMPARE(atDst.toMSecsSinceEpoch(), stdToDstMSecs);
+ // - Test transition hole, setting 03:00:00 is valid
+ atDst = QDateTime(QDate(2013, 3, 31), QTime(3, 0, 0), cet);
+ QVERIFY(atDst.isValid());
+ QCOMPARE(atDst.date(), QDate(2013, 3, 31));
+ QCOMPARE(atDst.time(), QTime(3, 0, 0));
+ QCOMPARE(atDst.toMSecsSinceEpoch(), stdToDstMSecs);
+ // - Test transition hole, setting 02:00:00 is invalid
+ atDst = QDateTime(QDate(2013, 3, 31), QTime(2, 0, 0), cet);
+ QVERIFY(!atDst.isValid());
+ QCOMPARE(atDst.date(), QDate(2013, 3, 31));
+ QCOMPARE(atDst.time(), QTime(2, 0, 0));
+ // - Test transition hole, setting 02:59:59.999 is invalid
+ atDst = QDateTime(QDate(2013, 3, 31), QTime(2, 59, 59, 999), cet);
+ QVERIFY(!atDst.isValid());
+ QCOMPARE(atDst.date(), QDate(2013, 3, 31));
+ QCOMPARE(atDst.time(), QTime(2, 59, 59, 999));
+
+ // Standard Time to Daylight Time 2013 on 2013-10-27 is 3:00 local time / 1:00 UTC
+ qint64 dstToStdMSecs = 1382835600000;
+
+ // Test MSecs to local
+ // - Test 1 hour before tran = 02:00:00 local first occurrence
+ QDateTime hourBeforeStd = QDateTime::fromMSecsSinceEpoch(dstToStdMSecs - 3600000, cet);
+ QCOMPARE(hourBeforeStd.date(), QDate(2013, 10, 27));
+ QCOMPARE(hourBeforeStd.time(), QTime(2, 0, 0));
+ // - Test 1 msec before tran = 02:59:59.999 local first occurrence
+ QDateTime msecBeforeStd = QDateTime::fromMSecsSinceEpoch(dstToStdMSecs - 1, cet);
+ QCOMPARE(msecBeforeStd.date(), QDate(2013, 10, 27));
+ QCOMPARE(msecBeforeStd.time(), QTime(2, 59, 59, 999));
+ // - Test at tran = 03:00:00 local becomes 02:00:00 local second occurrence
+ QDateTime atStd = QDateTime::fromMSecsSinceEpoch(dstToStdMSecs, cet);
+ QCOMPARE(atStd.date(), QDate(2013, 10, 27));
+ QCOMPARE(atStd.time(), QTime(2, 0, 0));
+ // - Test 59 mins after tran = 02:59:59.999 local second occurrence
+ QDateTime afterStd = QDateTime::fromMSecsSinceEpoch(dstToStdMSecs + 3600000 -1, cet);
+ QCOMPARE(afterStd.date(), QDate(2013, 10, 27));
+ QCOMPARE(afterStd.time(), QTime(2, 59, 59, 999));
+ // - Test 1 hour after tran = 03:00:00 local
+ QDateTime hourAfterStd = QDateTime::fromMSecsSinceEpoch(dstToStdMSecs + 3600000, cet);
+ QCOMPARE(hourAfterStd.date(), QDate(2013, 10, 27));
+ QCOMPARE(hourAfterStd.time(), QTime(3, 00, 00));
+
+ // Test local to MSecs
+ // - Test first occurrence 02:00:00 = 1 hour before tran
+ hourBeforeStd = QDateTime(QDate(2013, 10, 27), QTime(2, 0, 0), cet);
+ QCOMPARE(hourBeforeStd.toMSecsSinceEpoch(), dstToStdMSecs - 3600000);
+ // - Test first occurrence 02:59:59.999 = 1 msec before tran
+ msecBeforeStd = QDateTime(QDate(2013, 10, 27), QTime(2, 59, 59, 999), cet);
+ QCOMPARE(msecBeforeStd.toMSecsSinceEpoch(), dstToStdMSecs - 1);
+ // - Test second occurrence 02:00:00 = at tran
+ atStd = QDateTime(QDate(2013, 10, 27), QTime(2, 0, 0), cet);
+ QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
+ QCOMPARE(atStd.toMSecsSinceEpoch(), dstToStdMSecs);
+ // - Test second occurrence 03:00:00 = 59 mins after tran
+ afterStd = QDateTime(QDate(2013, 10, 27), QTime(2, 59, 59, 999), cet);
+ QEXPECT_FAIL("", "QDateTime doesn't properly support Daylight Transitions", Continue);
+ QCOMPARE(afterStd.toMSecsSinceEpoch(), dstToStdMSecs + 3600000 - 1);
+ // - Test 03:00:00 = 1 hour after tran
+ hourAfterStd = QDateTime(QDate(2013, 10, 27), QTime(3, 0, 0), cet);
+ QCOMPARE(hourAfterStd.toMSecsSinceEpoch(), dstToStdMSecs + 3600000);
+}
+
QTEST_APPLESS_MAIN(tst_QDateTime)
#include "tst_qdatetime.moc"
diff --git a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp
index ea0e90a503..8411cfe29b 100644
--- a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp
+++ b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp
@@ -1303,6 +1303,18 @@ void tst_QLocale::formatTimeZone()
QSKIP("You must test using Central European (CET/CEST) time zone, e.g. TZ=Europe/Oslo");
}
+ QDateTime dt6(QDate(2013, 1, 1), QTime(0, 0, 0), QTimeZone("Europe/Berlin"));
+#ifdef Q_OS_WIN
+ QEXPECT_FAIL("", "QTimeZone windows backend only returns long name", Continue);
+#endif
+ QCOMPARE(enUS.toString(dt6, "t"), QString("CET"));
+
+ QDateTime dt7(QDate(2013, 6, 1), QTime(0, 0, 0), QTimeZone("Europe/Berlin"));
+#ifdef Q_OS_WIN
+ QEXPECT_FAIL("", "QTimeZone windows backend only returns long name", Continue);
+#endif
+ QCOMPARE(enUS.toString(dt7, "t"), QString("CEST"));
+
// Current datetime should return current abbreviation
QCOMPARE(enUS.toString(QDateTime::currentDateTime(), "t"),
QDateTime::currentDateTime().timeZoneAbbreviation());
diff --git a/tests/benchmarks/corelib/tools/qdatetime/main.cpp b/tests/benchmarks/corelib/tools/qdatetime/main.cpp
index 9da6611ec0..8550ef6cb2 100644
--- a/tests/benchmarks/corelib/tools/qdatetime/main.cpp
+++ b/tests/benchmarks/corelib/tools/qdatetime/main.cpp
@@ -39,7 +39,8 @@
**
****************************************************************************/
-#include <QLocale>
+#include <QDateTime>
+#include <QTimeZone>
#include <QTest>
#include <qdebug.h>
@@ -71,21 +72,27 @@ private Q_SLOTS:
void toMSecsSinceEpoch();
void toMSecsSinceEpoch1950();
void toMSecsSinceEpoch2050();
+ void toMSecsSinceEpochTz();
+ void toMSecsSinceEpoch1950Tz();
+ void toMSecsSinceEpoch2050Tz();
void toTime_t();
void setDate();
void setTime();
void setTimeSpec();
void setOffsetFromUtc();
void setMSecsSinceEpoch();
+ void setMSecsSinceEpochTz();
void setTime_t();
void toString();
void toStringTextFormat();
void toStringIsoFormat();
void addDays();
+ void addDaysTz();
void addMonths();
void addYears();
void addSecs();
void addMSecs();
+ void addMSecsTz();
void toTimeSpec();
void toOffsetFromUtc();
void daysTo();
@@ -106,6 +113,7 @@ private Q_SLOTS:
void fromTime_t();
void fromMSecsSinceEpoch();
void fromMSecsSinceEpochUtc();
+ void fromMSecsSinceEpochTz();
};
void tst_QDateTime::create()
@@ -228,6 +236,42 @@ void tst_QDateTime::toMSecsSinceEpoch2050()
}
}
+void tst_QDateTime::toMSecsSinceEpochTz()
+{
+ QTimeZone cet = QTimeZone("Europe/Oslo");
+ QList<QDateTime> list;
+ for (int jd = JULIAN_DAY_2010; jd < JULIAN_DAY_2020; ++jd)
+ list.append(QDateTime(QDate::fromJulianDay(jd), QTime::fromMSecsSinceStartOfDay(0), cet));
+ QBENCHMARK {
+ foreach (const QDateTime &test, list)
+ qint64 result = test.toMSecsSinceEpoch();
+ }
+}
+
+void tst_QDateTime::toMSecsSinceEpoch1950Tz()
+{
+ QTimeZone cet = QTimeZone("Europe/Oslo");
+ QList<QDateTime> list;
+ for (int jd = JULIAN_DAY_1950; jd < JULIAN_DAY_1960; ++jd)
+ list.append(QDateTime(QDate::fromJulianDay(jd), QTime::fromMSecsSinceStartOfDay(0), cet));
+ QBENCHMARK {
+ foreach (const QDateTime &test, list)
+ qint64 result = test.toMSecsSinceEpoch();
+ }
+}
+
+void tst_QDateTime::toMSecsSinceEpoch2050Tz()
+{
+ QTimeZone cet = QTimeZone("Europe/Oslo");
+ QList<QDateTime> list;
+ for (int jd = JULIAN_DAY_2050; jd < JULIAN_DAY_2060; ++jd)
+ list.append(QDateTime(QDate::fromJulianDay(jd), QTime::fromMSecsSinceStartOfDay(0), cet));
+ QBENCHMARK {
+ foreach (const QDateTime &test, list)
+ qint64 result = test.toMSecsSinceEpoch();
+ }
+}
+
void tst_QDateTime::toTime_t()
{
QList<QDateTime> list;
@@ -295,6 +339,18 @@ void tst_QDateTime::setMSecsSinceEpoch()
}
}
+void tst_QDateTime::setMSecsSinceEpochTz()
+{
+ QTimeZone cet = QTimeZone("Europe/Oslo");
+ QList<QDateTime> list;
+ for (int jd = JULIAN_DAY_2010; jd < JULIAN_DAY_2020; ++jd)
+ list.append(QDateTime(QDate::fromJulianDay(jd), QTime::fromMSecsSinceStartOfDay(0), cet));
+ QBENCHMARK {
+ foreach (QDateTime test, list)
+ test.setMSecsSinceEpoch((JULIAN_DAY_2010 + 180) * MSECS_PER_DAY);
+ }
+}
+
void tst_QDateTime::setTime_t()
{
time_t secs = time_t(JULIAN_DAY_2010 + 180) * SECS_PER_DAY;
@@ -351,6 +407,18 @@ void tst_QDateTime::addDays()
}
}
+void tst_QDateTime::addDaysTz()
+{
+ QTimeZone cet = QTimeZone("Europe/Oslo");
+ QList<QDateTime> list;
+ for (int jd = JULIAN_DAY_2010; jd < JULIAN_DAY_2020; ++jd)
+ list.append(QDateTime(QDate::fromJulianDay(jd), QTime::fromMSecsSinceStartOfDay(0), cet));
+ QBENCHMARK {
+ foreach (const QDateTime &test, list)
+ QDateTime result = test.addDays(1);
+ }
+}
+
void tst_QDateTime::addMonths()
{
QList<QDateTime> list;
@@ -395,6 +463,18 @@ void tst_QDateTime::addMSecs()
}
}
+void tst_QDateTime::addMSecsTz()
+{
+ QTimeZone cet = QTimeZone("Europe/Oslo");
+ QList<QDateTime> list;
+ for (int jd = JULIAN_DAY_2010; jd < JULIAN_DAY_2020; ++jd)
+ list.append(QDateTime(QDate::fromJulianDay(jd), QTime::fromMSecsSinceStartOfDay(0), cet));
+ QBENCHMARK {
+ foreach (const QDateTime &test, list)
+ QDateTime result = test.addMSecs(1);
+ }
+}
+
void tst_QDateTime::toTimeSpec()
{
QList<QDateTime> list;
@@ -601,6 +681,15 @@ void tst_QDateTime::fromMSecsSinceEpochUtc()
}
}
+void tst_QDateTime::fromMSecsSinceEpochTz()
+{
+ QTimeZone cet = QTimeZone("Europe/Oslo");
+ QBENCHMARK {
+ for (int jd = JULIAN_DAY_2010; jd < JULIAN_DAY_2020; ++jd)
+ QDateTime test = QDateTime::fromMSecsSinceEpoch(jd * MSECS_PER_DAY, cet);
+ }
+}
+
QTEST_MAIN(tst_QDateTime)
#include "main.moc"