summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2019-05-27 17:47:22 +0200
committerEdward Welbourne <edward.welbourne@qt.io>2019-06-06 15:54:32 +0200
commit548513a4bd050d3df0a85fed6e2d1a00ce06d2ab (patch)
tree9e65f2701e013c1d1232082d5635c1b4e7817dd3 /tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp
parent29e3a4dfeaf5d4924eaa68824fb21998de687809 (diff)
Separate out the time, zone, date code from corelib/tools/
We'll be adding calendar code here as well, and tools/ was getting rather crowded, so it looks like time to move out a reasonably coherent sub-bundle of it all. Change-Id: I7e8030f38c31aa307f519dd918a43fc44baa6aa1 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp')
-rw-r--r--tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp1340
1 files changed, 0 insertions, 1340 deletions
diff --git a/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp b/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp
deleted file mode 100644
index 9904719f7c..0000000000
--- a/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp
+++ /dev/null
@@ -1,1340 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include <qtimezone.h>
-#include <private/qtimezoneprivate_p.h>
-#include <qlocale.h>
-
-#if defined(Q_OS_WIN) && !QT_CONFIG(icu)
-# define USING_WIN_TZ
-#endif
-
-class tst_QTimeZone : public QObject
-{
- Q_OBJECT
-
-public:
- tst_QTimeZone();
-
-private slots:
- // Public class default system tests
- void createTest();
- void nullTest();
- void dataStreamTest();
- void isTimeZoneIdAvailable();
- void availableTimeZoneIds();
- void specificTransition_data();
- void specificTransition();
- void transitionEachZone_data();
- void transitionEachZone();
- void checkOffset_data();
- void checkOffset();
- void stressTest();
- void windowsId();
- void isValidId_data();
- void isValidId();
- // Backend tests
- void utcTest();
- void icuTest();
- void tzTest();
- void macTest();
- void darwinTypes();
- void winTest();
-
-private:
- void printTimeZone(const QTimeZone &tz);
-#ifdef QT_BUILD_INTERNAL
- // Generic tests of privates, called by implementation-specific private tests:
- void testCetPrivate(const QTimeZonePrivate &tzp);
- void testEpochTranPrivate(const QTimeZonePrivate &tzp);
-#endif // QT_BUILD_INTERNAL
- const bool debug;
-};
-
-tst_QTimeZone::tst_QTimeZone()
- // Set to true to print debug output, test Display Names and run long stress tests
- : debug(false)
-{
-}
-
-void tst_QTimeZone::printTimeZone(const QTimeZone &tz)
-{
- QDateTime now = QDateTime::currentDateTime();
- QDateTime jan = QDateTime(QDate(2012, 1, 1), QTime(0, 0, 0), Qt::UTC);
- QDateTime jun = QDateTime(QDate(2012, 6, 1), QTime(0, 0, 0), Qt::UTC);
- qDebug() << "";
- qDebug() << "Time Zone = " << tz;
- qDebug() << "";
- qDebug() << "Is Valid = " << tz.isValid();
- qDebug() << "";
- qDebug() << "Zone ID = " << tz.id();
- qDebug() << "Country = " << QLocale::countryToString(tz.country());
- qDebug() << "Comment = " << tz.comment();
- qDebug() << "";
- qDebug() << "Locale = " << QLocale().name();
- qDebug() << "Name Long = " << tz.displayName(QTimeZone::StandardTime, QTimeZone::LongName);
- qDebug() << "Name Short = " << tz.displayName(QTimeZone::StandardTime, QTimeZone::ShortName);
- qDebug() << "Name Offset = " << tz.displayName(QTimeZone::StandardTime, QTimeZone::OffsetName);
- qDebug() << "Name Long DST = " << tz.displayName(QTimeZone::DaylightTime, QTimeZone::LongName);
- qDebug() << "Name Short DST = " << tz.displayName(QTimeZone::DaylightTime, QTimeZone::ShortName);
- qDebug() << "Name Offset DST = " << tz.displayName(QTimeZone::DaylightTime, QTimeZone::OffsetName);
- qDebug() << "Name Long Generic = " << tz.displayName(QTimeZone::GenericTime, QTimeZone::LongName);
- qDebug() << "Name Short Generic = " << tz.displayName(QTimeZone::GenericTime, QTimeZone::ShortName);
- qDebug() << "Name Offset Generic = " << tz.displayName(QTimeZone::GenericTime, QTimeZone::OffsetName);
- qDebug() << "";
- QLocale locale = QLocale(QStringLiteral("de_DE"));
- qDebug() << "Locale = " << locale.name();
- qDebug() << "Name Long = " << tz.displayName(QTimeZone::StandardTime, QTimeZone::LongName, locale);
- qDebug() << "Name Short = " << tz.displayName(QTimeZone::StandardTime, QTimeZone::ShortName, locale);
- qDebug() << "Name Offset = " << tz.displayName(QTimeZone::StandardTime, QTimeZone::OffsetName, locale);
- qDebug() << "Name Long DST = " << tz.displayName(QTimeZone::DaylightTime, QTimeZone::LongName,locale);
- qDebug() << "Name Short DST = " << tz.displayName(QTimeZone::DaylightTime, QTimeZone::ShortName, locale);
- qDebug() << "Name Offset DST = " << tz.displayName(QTimeZone::DaylightTime, QTimeZone::OffsetName, locale);
- qDebug() << "Name Long Generic = " << tz.displayName(QTimeZone::GenericTime, QTimeZone::LongName, locale);
- qDebug() << "Name Short Generic = " << tz.displayName(QTimeZone::GenericTime, QTimeZone::ShortName, locale);
- qDebug() << "Name Offset Generic = " << tz.displayName(QTimeZone::GenericTime, QTimeZone::OffsetName, locale);
- qDebug() << "";
- qDebug() << "Abbreviation Now = " << tz.abbreviation(now);
- qDebug() << "Abbreviation on 1 Jan = " << tz.abbreviation(jan);
- qDebug() << "Abbreviation on 1 June = " << tz.abbreviation(jun);
- qDebug() << "";
- qDebug() << "Offset on 1 January = " << tz.offsetFromUtc(jan);
- qDebug() << "Offset on 1 June = " << tz.offsetFromUtc(jun);
- qDebug() << "Offset Now = " << tz.offsetFromUtc(now);
- qDebug() << "";
- qDebug() << "UTC Offset Now = " << tz.standardTimeOffset(now);
- qDebug() << "UTC Offset on 1 January = " << tz.standardTimeOffset(jan);
- qDebug() << "UTC Offset on 1 June = " << tz.standardTimeOffset(jun);
- qDebug() << "";
- qDebug() << "DST Offset on 1 January = " << tz.daylightTimeOffset(jan);
- qDebug() << "DST Offset on 1 June = " << tz.daylightTimeOffset(jun);
- qDebug() << "DST Offset Now = " << tz.daylightTimeOffset(now);
- qDebug() << "";
- qDebug() << "Has DST = " << tz.hasDaylightTime();
- qDebug() << "Is DST Now = " << tz.isDaylightTime(now);
- qDebug() << "Is DST on 1 January = " << tz.isDaylightTime(jan);
- qDebug() << "Is DST on 1 June = " << tz.isDaylightTime(jun);
- qDebug() << "";
- qDebug() << "Has Transitions = " << tz.hasTransitions();
- qDebug() << "Transition after 1 Jan = " << tz.nextTransition(jan).atUtc;
- qDebug() << "Transition after 1 Jun = " << tz.nextTransition(jun).atUtc;
- qDebug() << "Transition before 1 Jan = " << tz.previousTransition(jan).atUtc;
- qDebug() << "Transition before 1 Jun = " << tz.previousTransition(jun).atUtc;
- qDebug() << "";
-}
-
-void tst_QTimeZone::createTest()
-{
- QTimeZone tz("Pacific/Auckland");
-
- if (debug)
- printTimeZone(tz);
-
- // If the tz is not valid then skip as is probably using the UTC backend which is tested later
- if (!tz.isValid())
- return;
-
- // Validity tests
- QCOMPARE(tz.isValid(), true);
-
- // Comparison tests
- QTimeZone tz2("Pacific/Auckland");
- QTimeZone tz3("Australia/Sydney");
- QCOMPARE((tz == tz2), true);
- QCOMPARE((tz != tz2), false);
- QCOMPARE((tz == tz3), false);
- QCOMPARE((tz != tz3), true);
-
- QCOMPARE(tz.country(), QLocale::NewZealand);
-
- QDateTime jan = QDateTime(QDate(2012, 1, 1), QTime(0, 0, 0), Qt::UTC);
- QDateTime jun = QDateTime(QDate(2012, 6, 1), QTime(0, 0, 0), Qt::UTC);
- QDateTime janPrev = QDateTime(QDate(2011, 1, 1), QTime(0, 0, 0), Qt::UTC);
-
- QCOMPARE(tz.offsetFromUtc(jan), 13 * 3600);
- QCOMPARE(tz.offsetFromUtc(jun), 12 * 3600);
-
- QCOMPARE(tz.standardTimeOffset(jan), 12 * 3600);
- QCOMPARE(tz.standardTimeOffset(jun), 12 * 3600);
-
- QCOMPARE(tz.daylightTimeOffset(jan), 3600);
- QCOMPARE(tz.daylightTimeOffset(jun), 0);
-
- QCOMPARE(tz.hasDaylightTime(), true);
- QCOMPARE(tz.isDaylightTime(jan), true);
- QCOMPARE(tz.isDaylightTime(jun), false);
-
- // Only test transitions if host system supports them
- if (tz.hasTransitions()) {
- QTimeZone::OffsetData tran = tz.nextTransition(jan);
- // 2012-04-01 03:00 NZDT, +13 -> +12
- QCOMPARE(tran.atUtc,
- QDateTime(QDate(2012, 4, 1), QTime(3, 0), Qt::OffsetFromUTC, 13 * 3600));
- QCOMPARE(tran.offsetFromUtc, 12 * 3600);
- QCOMPARE(tran.standardTimeOffset, 12 * 3600);
- QCOMPARE(tran.daylightTimeOffset, 0);
-
- tran = tz.nextTransition(jun);
- // 2012-09-30 02:00 NZST, +12 -> +13
- QCOMPARE(tran.atUtc,
- QDateTime(QDate(2012, 9, 30), QTime(2, 0), Qt::OffsetFromUTC, 12 * 3600));
- QCOMPARE(tran.offsetFromUtc, 13 * 3600);
- QCOMPARE(tran.standardTimeOffset, 12 * 3600);
- QCOMPARE(tran.daylightTimeOffset, 3600);
-
- tran = tz.previousTransition(jan);
- // 2011-09-25 02:00 NZST, +12 -> +13
- QCOMPARE(tran.atUtc,
- QDateTime(QDate(2011, 9, 25), QTime(2, 0), Qt::OffsetFromUTC, 12 * 3600));
- QCOMPARE(tran.offsetFromUtc, 13 * 3600);
- QCOMPARE(tran.standardTimeOffset, 12 * 3600);
- QCOMPARE(tran.daylightTimeOffset, 3600);
-
- tran = tz.previousTransition(jun);
- // 2012-04-01 03:00 NZDT, +13 -> +12 (again)
- QCOMPARE(tran.atUtc,
- QDateTime(QDate(2012, 4, 1), QTime(3, 0), Qt::OffsetFromUTC, 13 * 3600));
- QCOMPARE(tran.offsetFromUtc, 12 * 3600);
- QCOMPARE(tran.standardTimeOffset, 12 * 3600);
- QCOMPARE(tran.daylightTimeOffset, 0);
-
- QTimeZone::OffsetDataList expected;
- tran.atUtc = QDateTime(QDate(2011, 4, 3), QTime(2, 0), Qt::OffsetFromUTC, 13 * 3600);
- tran.offsetFromUtc = 13 * 3600;
- tran.standardTimeOffset = 12 * 3600;
- tran.daylightTimeOffset = 3600;
- expected << tran;
- tran.atUtc = QDateTime(QDate(2011, 9, 25), QTime(2, 0), Qt::OffsetFromUTC, 12 * 3600);
- tran.offsetFromUtc = 12 * 3600;
- tran.standardTimeOffset = 12 * 3600;
- tran.daylightTimeOffset = 0;
- expected << tran;
- QTimeZone::OffsetDataList result = tz.transitions(janPrev, jan);
- QCOMPARE(result.count(), expected.count());
- for (int i = 0; i > expected.count(); ++i) {
- QCOMPARE(result.at(i).atUtc, expected.at(i).atUtc);
- QCOMPARE(result.at(i).offsetFromUtc, expected.at(i).offsetFromUtc);
- QCOMPARE(result.at(i).standardTimeOffset, expected.at(i).standardTimeOffset);
- QCOMPARE(result.at(i).daylightTimeOffset, expected.at(i).daylightTimeOffset);
- }
- }
-}
-
-void tst_QTimeZone::nullTest()
-{
- QTimeZone nullTz1;
- QTimeZone nullTz2;
- QTimeZone utc("UTC");
-
- // Validity tests
- QCOMPARE(nullTz1.isValid(), false);
- QCOMPARE(nullTz2.isValid(), false);
- QCOMPARE(utc.isValid(), true);
-
- // Comparison tests
- QCOMPARE((nullTz1 == nullTz2), true);
- QCOMPARE((nullTz1 != nullTz2), false);
- QCOMPARE((nullTz1 == utc), false);
- QCOMPARE((nullTz1 != utc), true);
-
- // Assignment tests
- nullTz2 = utc;
- QCOMPARE(nullTz2.isValid(), true);
- utc = nullTz1;
- QCOMPARE(utc.isValid(), false);
-
- QCOMPARE(nullTz1.id(), QByteArray());
- QCOMPARE(nullTz1.country(), QLocale::AnyCountry);
- QCOMPARE(nullTz1.comment(), QString());
-
- QDateTime jan = QDateTime(QDate(2012, 1, 1), QTime(0, 0, 0), Qt::UTC);
- QDateTime jun = QDateTime(QDate(2012, 6, 1), QTime(0, 0, 0), Qt::UTC);
- QDateTime janPrev = QDateTime(QDate(2011, 1, 1), QTime(0, 0, 0), Qt::UTC);
-
- QCOMPARE(nullTz1.abbreviation(jan), QString());
- QCOMPARE(nullTz1.displayName(jan), QString());
- QCOMPARE(nullTz1.displayName(QTimeZone::StandardTime), QString());
-
- QCOMPARE(nullTz1.offsetFromUtc(jan), 0);
- QCOMPARE(nullTz1.offsetFromUtc(jun), 0);
-
- QCOMPARE(nullTz1.standardTimeOffset(jan), 0);
- QCOMPARE(nullTz1.standardTimeOffset(jun), 0);
-
- QCOMPARE(nullTz1.daylightTimeOffset(jan), 0);
- QCOMPARE(nullTz1.daylightTimeOffset(jun), 0);
-
- QCOMPARE(nullTz1.hasDaylightTime(), false);
- QCOMPARE(nullTz1.isDaylightTime(jan), false);
- QCOMPARE(nullTz1.isDaylightTime(jun), false);
-
- QTimeZone::OffsetData data = nullTz1.offsetData(jan);
- QCOMPARE(data.atUtc, QDateTime());
- QCOMPARE(data.offsetFromUtc, std::numeric_limits<int>::min());
- QCOMPARE(data.standardTimeOffset, std::numeric_limits<int>::min());
- QCOMPARE(data.daylightTimeOffset, std::numeric_limits<int>::min());
-
- QCOMPARE(nullTz1.hasTransitions(), false);
-
- data = nullTz1.nextTransition(jan);
- QCOMPARE(data.atUtc, QDateTime());
- QCOMPARE(data.offsetFromUtc, std::numeric_limits<int>::min());
- QCOMPARE(data.standardTimeOffset, std::numeric_limits<int>::min());
- QCOMPARE(data.daylightTimeOffset, std::numeric_limits<int>::min());
-
- data = nullTz1.previousTransition(jan);
- QCOMPARE(data.atUtc, QDateTime());
- QCOMPARE(data.offsetFromUtc, std::numeric_limits<int>::min());
- QCOMPARE(data.standardTimeOffset, std::numeric_limits<int>::min());
- QCOMPARE(data.daylightTimeOffset, std::numeric_limits<int>::min());
-}
-
-void tst_QTimeZone::dataStreamTest()
-{
- // Test the OffsetFromUtc backend serialization. First with a custom timezone:
- QTimeZone tz1("QST", 123456, "Qt Standard Time", "QST", QLocale::Norway, "Qt Testing");
- QByteArray tmp;
- {
- QDataStream ds(&tmp, QIODevice::WriteOnly);
- ds << tz1;
- }
- QTimeZone tz2("UTC");
- {
- QDataStream ds(&tmp, QIODevice::ReadOnly);
- ds >> tz2;
- }
- QCOMPARE(tz2.id(), QByteArray("QST"));
- QCOMPARE(tz2.comment(), QString("Qt Testing"));
- QCOMPARE(tz2.country(), QLocale::Norway);
- QCOMPARE(tz2.abbreviation(QDateTime::currentDateTime()), QString("QST"));
- QCOMPARE(tz2.displayName(QTimeZone::StandardTime, QTimeZone::LongName, QString()),
- QString("Qt Standard Time"));
- QCOMPARE(tz2.displayName(QTimeZone::DaylightTime, QTimeZone::LongName, QString()),
- QString("Qt Standard Time"));
- QCOMPARE(tz2.offsetFromUtc(QDateTime::currentDateTime()), 123456);
-
- // And then with a standard IANA timezone (QTBUG-60595):
- tz1 = QTimeZone("UTC");
- QCOMPARE(tz1.isValid(), true);
- {
- QDataStream ds(&tmp, QIODevice::WriteOnly);
- ds << tz1;
- }
- {
- QDataStream ds(&tmp, QIODevice::ReadOnly);
- ds >> tz2;
- }
- QCOMPARE(tz2.isValid(), true);
- QCOMPARE(tz2.id(), tz1.id());
-
- // Test the system backend serialization
- tz1 = QTimeZone("Pacific/Auckland");
-
- // If not valid then probably using the UTC system backend so skip
- if (!tz1.isValid())
- return;
-
- {
- QDataStream ds(&tmp, QIODevice::WriteOnly);
- ds << tz1;
- }
- tz2 = QTimeZone("UTC");
- {
- QDataStream ds(&tmp, QIODevice::ReadOnly);
- ds >> tz2;
- }
- QCOMPARE(tz2.id(), tz1.id());
-}
-
-void tst_QTimeZone::isTimeZoneIdAvailable()
-{
- QList<QByteArray> available = QTimeZone::availableTimeZoneIds();
- foreach (const QByteArray &id, available)
- QVERIFY(QTimeZone::isTimeZoneIdAvailable(id));
-
-#ifdef QT_BUILD_INTERNAL
- // a-z, A-Z, 0-9, '.', '-', '_' are valid chars
- // Can't start with '-'
- // Parts separated by '/', each part min 1 and max of 14 chars
- QCOMPARE(QTimeZonePrivate::isValidId("az"), true);
- QCOMPARE(QTimeZonePrivate::isValidId("AZ"), true);
- QCOMPARE(QTimeZonePrivate::isValidId("09"), true);
- QCOMPARE(QTimeZonePrivate::isValidId("a/z"), true);
- QCOMPARE(QTimeZonePrivate::isValidId("a.z"), true);
- QCOMPARE(QTimeZonePrivate::isValidId("a-z"), true);
- QCOMPARE(QTimeZonePrivate::isValidId("a_z"), true);
- QCOMPARE(QTimeZonePrivate::isValidId(".z"), true);
- QCOMPARE(QTimeZonePrivate::isValidId("_z"), true);
- QCOMPARE(QTimeZonePrivate::isValidId("12345678901234"), true);
- QCOMPARE(QTimeZonePrivate::isValidId("12345678901234/12345678901234"), true);
- QCOMPARE(QTimeZonePrivate::isValidId("a z"), false);
- QCOMPARE(QTimeZonePrivate::isValidId("a\\z"), false);
- QCOMPARE(QTimeZonePrivate::isValidId("a,z"), false);
- QCOMPARE(QTimeZonePrivate::isValidId("/z"), false);
- QCOMPARE(QTimeZonePrivate::isValidId("-z"), false);
- QCOMPARE(QTimeZonePrivate::isValidId("123456789012345"), false);
- QCOMPARE(QTimeZonePrivate::isValidId("123456789012345/12345678901234"), false);
- QCOMPARE(QTimeZonePrivate::isValidId("12345678901234/123456789012345"), false);
-#endif // QT_BUILD_INTERNAL
-}
-
-void tst_QTimeZone::specificTransition_data()
-{
- QTest::addColumn<QByteArray>("zone");
- QTest::addColumn<QDate>("start");
- QTest::addColumn<QDate>("stop");
- QTest::addColumn<int>("count");
- QTest::addColumn<QDateTime>("atUtc");
- // In minutes:
- QTest::addColumn<int>("offset");
- QTest::addColumn<int>("stdoff");
- QTest::addColumn<int>("dstoff");
-
- // Moscow ditched DST on 2010-10-31 but has since changed standard offset twice.
-#ifdef USING_WIN_TZ
- // Win7 is too old to know about this transition:
- if (QOperatingSystemVersion::current() > QOperatingSystemVersion::Windows7)
-#endif
- {
- QTest::newRow("Moscow/2014") // From original bug-report
- << QByteArray("Europe/Moscow")
- << QDate(2011, 4, 1) << QDate(2017, 12,31) << 1
- << QDateTime(QDate(2014, 10, 26), QTime(2, 0, 0),
- Qt::OffsetFromUTC, 4 * 3600).toUTC()
- << 3 * 3600 << 3 * 3600 << 0;
- }
- QTest::newRow("Moscow/2011") // Transition on 2011-03-27
- << QByteArray("Europe/Moscow")
- << QDate(2010, 11, 1) << QDate(2014, 10, 25) << 1
- << QDateTime(QDate(2011, 3, 27), QTime(2, 0, 0),
- Qt::OffsetFromUTC, 3 * 3600).toUTC()
- << 4 * 3600 << 4 * 3600 << 0;
-}
-
-void tst_QTimeZone::specificTransition()
-{
- // Regression test for QTBUG-42021 (on MS-Win)
- QFETCH(QByteArray, zone);
- QFETCH(QDate, start);
- QFETCH(QDate, stop);
- QFETCH(int, count);
- // No attempt to check abbreviations; to much cross-platform variation.
- QFETCH(QDateTime, atUtc);
- QFETCH(int, offset);
- QFETCH(int, stdoff);
- QFETCH(int, dstoff);
-
- QTimeZone timeZone(zone);
- if (!timeZone.isValid())
- QSKIP("Missing time-zone data");
- QTimeZone::OffsetDataList transits =
- timeZone.transitions(QDateTime(start, QTime(0, 0), timeZone),
- QDateTime(stop, QTime(23, 59), timeZone));
- QCOMPARE(transits.length(), count);
- const QTimeZone::OffsetData &transition = transits.at(0);
- QCOMPARE(transition.offsetFromUtc, offset);
- QCOMPARE(transition.standardTimeOffset, stdoff);
- QCOMPARE(transition.daylightTimeOffset, dstoff);
- QCOMPARE(transition.atUtc, atUtc);
-}
-
-void tst_QTimeZone::transitionEachZone_data()
-{
- QTest::addColumn<QByteArray>("zone");
- QTest::addColumn<qint64>("secs");
- QTest::addColumn<int>("start");
- QTest::addColumn<int>("stop");
-
- struct {
- qint64 baseSecs;
- int start, stop;
- int year;
- } table[] = {
- { 25666200, 3, 12, 1970 }, // 1970-10-25 01:30 UTC; North America
- { 1288488600, -4, 8, 2010 } // 2010-10-31 01:30 UTC; Europe, Russia
- };
-
- const auto zones = QTimeZone::availableTimeZoneIds();
- for (int k = sizeof(table) / sizeof(table[0]); k-- > 0; ) {
- for (const QByteArray &zone : zones) {
- const QString name = QString::asprintf("%s@%d", zone.constData(), table[k].year);
- QTest::newRow(name.toUtf8().constData())
- << zone
- << table[k].baseSecs
- << table[k].start
- << table[k].stop;
- }
- }
-}
-
-void tst_QTimeZone::transitionEachZone()
-{
- // Regression test: round-trip fromMsecs/toMSecs should be idempotent; but
- // various zones failed during fall-back transitions.
- QFETCH(QByteArray, zone);
- QFETCH(qint64, secs);
- QFETCH(int, start);
- QFETCH(int, stop);
- QTimeZone named(zone);
-
- for (int i = start; i < stop; i++) {
-#ifdef USING_WIN_TZ
- // See QTBUG-64985: MS's TZ APIs' misdescription of Europe/Samara leads
- // to mis-disambiguation of its fall-back here.
- if (zone == "Europe/Samara" && i == -3) {
- continue;
- }
-#endif
-#ifdef Q_OS_ANDROID
- if (zone == "America/Mazatlan" || zone == "Mexico/BajaSur")
- QSKIP("Crashes on Android, see QTBUG-69132");
-#endif
- qint64 here = secs + i * 3600;
- QDateTime when = QDateTime::fromMSecsSinceEpoch(here * 1000, named);
- qint64 stamp = when.toMSecsSinceEpoch();
- if (here * 1000 != stamp) // (The +1 is due to using *1*:30 as baseSecs.)
- qDebug() << "Failing for" << zone << "at half past" << (i + 1) << "UTC";
- QCOMPARE(stamp % 1000, 0);
- QCOMPARE(here - stamp / 1000, 0);
- }
-}
-
-void tst_QTimeZone::checkOffset_data()
-{
- QTest::addColumn<QByteArray>("zoneName");
- QTest::addColumn<QDateTime>("when");
- QTest::addColumn<int>("netOffset");
- QTest::addColumn<int>("stdOffset");
- QTest::addColumn<int>("dstOffset");
-
- struct {
- const char *zone, *nick;
- int year, month, day, hour, min, sec;
- int std, dst;
- } table[] = {
- // Zone with no transitions (QTBUG-74614, QTBUG-74666, when TZ backend uses minimal data)
- { "Etc/UTC", "epoch", 1970, 1, 1, 0, 0, 0, 0, 0 },
- { "Etc/UTC", "pre_int32", 1901, 12, 13, 20, 45, 51, 0, 0 },
- { "Etc/UTC", "post_int32", 2038, 1, 19, 3, 14, 9, 0, 0 },
- { "Etc/UTC", "post_uint32", 2106, 2, 7, 6, 28, 17, 0, 0 },
- { "Etc/UTC", "initial", -292275056, 5, 16, 16, 47, 5, 0, 0 },
- { "Etc/UTC", "final", 292278994, 8, 17, 7, 12, 55, 0, 0 },
- // Kiev: regression test for QTBUG-64122 (on MS):
- { "Europe/Kiev", "summer", 2017, 10, 27, 12, 0, 0, 2 * 3600, 3600 },
- { "Europe/Kiev", "winter", 2017, 10, 29, 12, 0, 0, 2 * 3600, 0 }
- };
- for (const auto &entry : table) {
- QTimeZone zone(entry.zone);
- if (zone.isValid()) {
- QTest::addRow("%s@%s", entry.zone, entry.nick)
- << QByteArray(entry.zone)
- << QDateTime(QDate(entry.year, entry.month, entry.day),
- QTime(entry.hour, entry.min, entry.sec), zone)
- << entry.dst + entry.std << entry.std << entry.dst;
- } else {
- qWarning("Skipping %s@%s test as zone is invalid", entry.zone, entry.nick);
- }
- }
-}
-
-void tst_QTimeZone::checkOffset()
-{
- QFETCH(QByteArray, zoneName);
- QFETCH(QDateTime, when);
- QFETCH(int, netOffset);
- QFETCH(int, stdOffset);
- QFETCH(int, dstOffset);
-
- QTimeZone zone(zoneName);
- QVERIFY(zone.isValid()); // It was when _data() added the row !
- QCOMPARE(zone.offsetFromUtc(when), netOffset);
- QCOMPARE(zone.standardTimeOffset(when), stdOffset);
- QCOMPARE(zone.daylightTimeOffset(when), dstOffset);
- QCOMPARE(zone.isDaylightTime(when), dstOffset != 0);
-}
-
-void tst_QTimeZone::availableTimeZoneIds()
-{
- if (debug) {
- qDebug() << "";
- qDebug() << "Available Time Zones" ;
- qDebug() << QTimeZone::availableTimeZoneIds();
- qDebug() << "";
- qDebug() << "Available Time Zones in the US";
- qDebug() << QTimeZone::availableTimeZoneIds(QLocale::UnitedStates);
- qDebug() << "";
- qDebug() << "Available Time Zones with UTC Offset 0";
- qDebug() << QTimeZone::availableTimeZoneIds(0);
- qDebug() << "";
- } else {
- //Just test the calls work, we cannot know what any test machine has available
- QList<QByteArray> listAll = QTimeZone::availableTimeZoneIds();
- QList<QByteArray> listUs = QTimeZone::availableTimeZoneIds(QLocale::UnitedStates);
- QList<QByteArray> listZero = QTimeZone::availableTimeZoneIds(0);
- }
-}
-
-void tst_QTimeZone::stressTest()
-{
- QList<QByteArray> idList = QTimeZone::availableTimeZoneIds();
- foreach (const QByteArray &id, idList) {
- QTimeZone testZone = QTimeZone(id);
- QCOMPARE(testZone.isValid(), true);
- QCOMPARE(testZone.id(), id);
- QDateTime testDate = QDateTime(QDate(2015, 1, 1), QTime(0, 0, 0), Qt::UTC);
- testZone.country();
- testZone.comment();
- testZone.displayName(testDate);
- testZone.displayName(QTimeZone::DaylightTime);
- testZone.displayName(QTimeZone::StandardTime);
- testZone.abbreviation(testDate);
- testZone.offsetFromUtc(testDate);
- testZone.standardTimeOffset(testDate);
- testZone.daylightTimeOffset(testDate);
- testZone.hasDaylightTime();
- testZone.isDaylightTime(testDate);
- testZone.offsetData(testDate);
- testZone.hasTransitions();
- testZone.nextTransition(testDate);
- testZone.previousTransition(testDate);
- // Dates known to be outside possible tz file pre-calculated rules range
- QDateTime lowDate1 = QDateTime(QDate(1800, 1, 1), QTime(0, 0, 0), Qt::UTC);
- QDateTime lowDate2 = QDateTime(QDate(1800, 6, 1), QTime(0, 0, 0), Qt::UTC);
- QDateTime highDate1 = QDateTime(QDate(2200, 1, 1), QTime(0, 0, 0), Qt::UTC);
- QDateTime highDate2 = QDateTime(QDate(2200, 6, 1), QTime(0, 0, 0), Qt::UTC);
- testZone.nextTransition(lowDate1);
- testZone.nextTransition(lowDate2);
- testZone.previousTransition(lowDate2);
- testZone.previousTransition(lowDate2);
- testZone.nextTransition(highDate1);
- testZone.nextTransition(highDate2);
- testZone.previousTransition(highDate1);
- testZone.previousTransition(highDate2);
- if (debug) {
- // This could take a long time, depending on platform and database
- qDebug() << "Stress test calculating transistions for" << testZone.id();
- testZone.transitions(lowDate1, highDate1);
- }
- testDate.setTimeZone(testZone);
- testDate.isValid();
- testDate.offsetFromUtc();
- testDate.timeZoneAbbreviation();
- }
-}
-
-void tst_QTimeZone::windowsId()
-{
-/*
- Current Windows zones for "Central Standard Time":
- Region IANA Id(s)
- Default "America/Chicago"
- Canada "America/Winnipeg America/Rainy_River America/Rankin_Inlet America/Resolute"
- Mexico "America/Matamoros"
- USA "America/Chicago America/Indiana/Knox America/Indiana/Tell_City America/Menominee"
- "America/North_Dakota/Beulah America/North_Dakota/Center"
- "America/North_Dakota/New_Salem"
- AnyCountry "CST6CDT"
-*/
- QCOMPARE(QTimeZone::ianaIdToWindowsId("America/Chicago"),
- QByteArray("Central Standard Time"));
- QCOMPARE(QTimeZone::ianaIdToWindowsId("America/Resolute"),
- QByteArray("Central Standard Time"));
-
- // Partials shouldn't match
- QCOMPARE(QTimeZone::ianaIdToWindowsId("America/Chi"), QByteArray());
- QCOMPARE(QTimeZone::ianaIdToWindowsId("InvalidZone"), QByteArray());
- QCOMPARE(QTimeZone::ianaIdToWindowsId(QByteArray()), QByteArray());
-
- // Check default value
- QCOMPARE(QTimeZone::windowsIdToDefaultIanaId("Central Standard Time"),
- QByteArray("America/Chicago"));
- QCOMPARE(QTimeZone::windowsIdToDefaultIanaId("Central Standard Time", QLocale::Canada),
- QByteArray("America/Winnipeg"));
- QCOMPARE(QTimeZone::windowsIdToDefaultIanaId("Central Standard Time", QLocale::AnyCountry),
- QByteArray("CST6CDT"));
- QCOMPARE(QTimeZone::windowsIdToDefaultIanaId(QByteArray()), QByteArray());
-
- // No country is sorted list of all zones
- QList<QByteArray> list;
- list << "America/Chicago" << "America/Indiana/Knox" << "America/Indiana/Tell_City"
- << "America/Matamoros" << "America/Menominee" << "America/North_Dakota/Beulah"
- << "America/North_Dakota/Center" << "America/North_Dakota/New_Salem"
- << "America/Rainy_River" << "America/Rankin_Inlet" << "America/Resolute"
- << "America/Winnipeg" << "CST6CDT";
- QCOMPARE(QTimeZone::windowsIdToIanaIds("Central Standard Time"), list);
-
- // Check country with no match returns empty list
- list.clear();
- QCOMPARE(QTimeZone::windowsIdToIanaIds("Central Standard Time", QLocale::NewZealand),
- list);
-
- // Check valid country returns list in preference order
- list.clear();
- list << "America/Winnipeg" << "America/Rainy_River" << "America/Rankin_Inlet"
- << "America/Resolute";
- QCOMPARE(QTimeZone::windowsIdToIanaIds("Central Standard Time", QLocale::Canada), list);
-
- list.clear();
- list << "America/Matamoros";
- QCOMPARE(QTimeZone::windowsIdToIanaIds("Central Standard Time", QLocale::Mexico), list);
-
- list.clear();
- list << "America/Chicago" << "America/Indiana/Knox" << "America/Indiana/Tell_City"
- << "America/Menominee" << "America/North_Dakota/Beulah" << "America/North_Dakota/Center"
- << "America/North_Dakota/New_Salem";
- QCOMPARE(QTimeZone::windowsIdToIanaIds("Central Standard Time", QLocale::UnitedStates),
- list);
-
- list.clear();
- list << "CST6CDT";
- QCOMPARE(QTimeZone::windowsIdToIanaIds("Central Standard Time", QLocale::AnyCountry),
- list);
-
- // Check no windowsId return empty
- list.clear();
- QCOMPARE(QTimeZone::windowsIdToIanaIds(QByteArray()), list);
- QCOMPARE(QTimeZone::windowsIdToIanaIds(QByteArray(), QLocale::AnyCountry), list);
-}
-
-void tst_QTimeZone::isValidId_data()
-{
-#ifdef QT_BUILD_INTERNAL
- QTest::addColumn<QByteArray>("input");
- QTest::addColumn<bool>("valid");
-
-#define TESTSET(name, section, valid) \
- QTest::newRow(name " front") << QByteArray(section "/xyz/xyz") << valid; \
- QTest::newRow(name " middle") << QByteArray("xyz/" section "/xyz") << valid; \
- QTest::newRow(name " back") << QByteArray("xyz/xyz/" section) << valid
-
- TESTSET("empty", "", false);
- TESTSET("minimal", "m", true);
- TESTSET("maximal", "12345678901234", true);
- TESTSET("too long", "123456789012345", false);
-
- TESTSET("bad hyphen", "-hyphen", false);
- TESTSET("good hyphen", "hy-phen", true);
-
- TESTSET("valid char _", "_", true);
- TESTSET("valid char .", ".", true);
- TESTSET("valid char :", ":", true);
- TESTSET("valid char +", "+", true);
- TESTSET("valid char A", "A", true);
- TESTSET("valid char Z", "Z", true);
- TESTSET("valid char a", "a", true);
- TESTSET("valid char z", "z", true);
- TESTSET("valid char 0", "0", true);
- TESTSET("valid char 9", "9", true);
-
- TESTSET("invalid char ^", "^", false);
- TESTSET("invalid char \"", "\"", false);
- TESTSET("invalid char $", "$", false);
- TESTSET("invalid char %", "%", false);
- TESTSET("invalid char &", "&", false);
- TESTSET("invalid char (", "(", false);
- TESTSET("invalid char )", ")", false);
- TESTSET("invalid char =", "=", false);
- TESTSET("invalid char ?", "?", false);
- TESTSET("invalid char ß", "ß", false);
- TESTSET("invalid char \\x01", "\x01", false);
- TESTSET("invalid char ' '", " ", false);
-
-#undef TESTSET
-#endif // QT_BUILD_INTERNAL
-}
-
-void tst_QTimeZone::isValidId()
-{
-#ifdef QT_BUILD_INTERNAL
- QFETCH(QByteArray, input);
- QFETCH(bool, valid);
-
- QCOMPARE(QTimeZonePrivate::isValidId(input), valid);
-#else
- QSKIP("This test requires a Qt -developer-build.");
-#endif
-}
-
-void tst_QTimeZone::utcTest()
-{
-#ifdef QT_BUILD_INTERNAL
- // Test default UTC constructor
- QUtcTimeZonePrivate tzp;
- QCOMPARE(tzp.isValid(), true);
- QCOMPARE(tzp.id(), QByteArray("UTC"));
- QCOMPARE(tzp.country(), QLocale::AnyCountry);
- QCOMPARE(tzp.abbreviation(0), QString("UTC"));
- QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::LongName, QString()), QString("UTC"));
- QCOMPARE(tzp.offsetFromUtc(0), 0);
- QCOMPARE(tzp.standardTimeOffset(0), 0);
- QCOMPARE(tzp.daylightTimeOffset(0), 0);
- QCOMPARE(tzp.hasDaylightTime(), false);
- QCOMPARE(tzp.hasTransitions(), false);
-
- // Test create from UTC Offset
- QDateTime now = QDateTime::currentDateTime();
- QTimeZone tz(36000);
- QCOMPARE(tz.isValid(), true);
- QCOMPARE(tz.id(), QByteArray("UTC+10:00"));
- QCOMPARE(tz.offsetFromUtc(now), 36000);
- QCOMPARE(tz.standardTimeOffset(now), 36000);
- QCOMPARE(tz.daylightTimeOffset(now), 0);
-
- // Test invalid UTC offset, must be in range -14 to +14 hours
- int min = -14*60*60;
- int max = 14*60*60;
- QCOMPARE(QTimeZone(min - 1).isValid(), false);
- QCOMPARE(QTimeZone(min).isValid(), true);
- QCOMPARE(QTimeZone(min + 1).isValid(), true);
- QCOMPARE(QTimeZone(max - 1).isValid(), true);
- QCOMPARE(QTimeZone(max).isValid(), true);
- QCOMPARE(QTimeZone(max + 1).isValid(), false);
-
- // Test create from standard name
- tz = QTimeZone("UTC+10:00");
- QCOMPARE(tz.isValid(), true);
- QCOMPARE(tz.id(), QByteArray("UTC+10:00"));
- QCOMPARE(tz.offsetFromUtc(now), 36000);
- QCOMPARE(tz.standardTimeOffset(now), 36000);
- QCOMPARE(tz.daylightTimeOffset(now), 0);
-
- // Test invalid UTC ID, must be in available list
- tz = QTimeZone("UTC+00:01");
- QCOMPARE(tz.isValid(), false);
-
- // Test create custom zone
- tz = QTimeZone("QST", 123456, "Qt Standard Time", "QST", QLocale::Norway, "Qt Testing");
- QCOMPARE(tz.isValid(), true);
- QCOMPARE(tz.id(), QByteArray("QST"));
- QCOMPARE(tz.comment(), QString("Qt Testing"));
- QCOMPARE(tz.country(), QLocale::Norway);
- QCOMPARE(tz.abbreviation(now), QString("QST"));
- QCOMPARE(tz.displayName(QTimeZone::StandardTime, QTimeZone::LongName, QString()),
- QString("Qt Standard Time"));
- QCOMPARE(tz.offsetFromUtc(now), 123456);
- QCOMPARE(tz.standardTimeOffset(now), 123456);
- QCOMPARE(tz.daylightTimeOffset(now), 0);
-#endif // QT_BUILD_INTERNAL
-}
-
-void tst_QTimeZone::icuTest()
-{
-#if defined(QT_BUILD_INTERNAL) && QT_CONFIG(icu)
- // Known datetimes
- qint64 std = QDateTime(QDate(2012, 1, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch();
- qint64 dst = QDateTime(QDate(2012, 6, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch();
-
- // Test default constructor
- QIcuTimeZonePrivate tzpd;
- QVERIFY(tzpd.isValid());
-
- // Test invalid constructor
- QIcuTimeZonePrivate tzpi("Gondwana/Erewhon");
- QCOMPARE(tzpi.isValid(), false);
-
- // Test named constructor
- QIcuTimeZonePrivate tzp("Europe/Berlin");
- QVERIFY(tzp.isValid());
-
- // Only test names in debug mode, names used can vary by ICU version installed
- if (debug) {
- // Test display names by type
- QLocale enUS("en_US");
- QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::LongName, enUS),
- QString("Central European Standard Time"));
- QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::ShortName, enUS),
- QString("GMT+01:00"));
- QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::OffsetName, enUS),
- QString("UTC+01:00"));
- QCOMPARE(tzp.displayName(QTimeZone::DaylightTime, QTimeZone::LongName, enUS),
- QString("Central European Summer Time"));
- QCOMPARE(tzp.displayName(QTimeZone::DaylightTime, QTimeZone::ShortName, enUS),
- QString("GMT+02:00"));
- QCOMPARE(tzp.displayName(QTimeZone::DaylightTime, QTimeZone::OffsetName, enUS),
- QString("UTC+02:00"));
- // ICU C api does not support Generic Time yet, C++ api does
- QCOMPARE(tzp.displayName(QTimeZone::GenericTime, QTimeZone::LongName, enUS),
- QString("Central European Standard Time"));
- QCOMPARE(tzp.displayName(QTimeZone::GenericTime, QTimeZone::ShortName, enUS),
- QString("GMT+01:00"));
- QCOMPARE(tzp.displayName(QTimeZone::GenericTime, QTimeZone::OffsetName, enUS),
- QString("UTC+01:00"));
-
- // Test Abbreviations
- QCOMPARE(tzp.abbreviation(std), QString("CET"));
- QCOMPARE(tzp.abbreviation(dst), QString("CEST"));
- }
-
- testCetPrivate(tzp);
- testEpochTranPrivate(QIcuTimeZonePrivate("America/Toronto"));
-#endif // icu
-}
-
-void tst_QTimeZone::tzTest()
-{
-#if defined QT_BUILD_INTERNAL && defined Q_OS_UNIX && !defined Q_OS_DARWIN && !defined Q_OS_ANDROID
- // Known datetimes
- qint64 std = QDateTime(QDate(2012, 1, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch();
- qint64 dst = QDateTime(QDate(2012, 6, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch();
-
- // Test default constructor
- QTzTimeZonePrivate tzpd;
- QVERIFY(tzpd.isValid());
-
- // Test invalid constructor
- QTzTimeZonePrivate tzpi("Gondwana/Erewhon");
- QCOMPARE(tzpi.isValid(), false);
-
- // Test named constructor
- QTzTimeZonePrivate tzp("Europe/Berlin");
- QVERIFY(tzp.isValid());
-
- // Test POSIX-format value for $TZ:
- QTzTimeZonePrivate tzposix("MET-1METDST-2,M3.5.0/02:00:00,M10.5.0/03:00:00");
- QVERIFY(tzposix.isValid());
-
- QTimeZone tzBrazil("BRT+3"); // parts of Northern Brazil, as a POSIX rule
- QVERIFY(tzBrazil.isValid());
- QCOMPARE(tzBrazil.offsetFromUtc(QDateTime(QDate(1111, 11, 11).startOfDay())), -10800);
-
- // Test display names by type, either ICU or abbreviation only
- QLocale enUS("en_US");
- // Only test names in debug mode, names used can vary by ICU version installed
- if (debug) {
-#if QT_CONFIG(icu)
- QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::LongName, enUS),
- QString("Central European Standard Time"));
- QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::ShortName, enUS),
- QString("GMT+01:00"));
- QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::OffsetName, enUS),
- QString("UTC+01:00"));
- QCOMPARE(tzp.displayName(QTimeZone::DaylightTime, QTimeZone::LongName, enUS),
- QString("Central European Summer Time"));
- QCOMPARE(tzp.displayName(QTimeZone::DaylightTime, QTimeZone::ShortName, enUS),
- QString("GMT+02:00"));
- QCOMPARE(tzp.displayName(QTimeZone::DaylightTime, QTimeZone::OffsetName, enUS),
- QString("UTC+02:00"));
- // ICU C api does not support Generic Time yet, C++ api does
- QCOMPARE(tzp.displayName(QTimeZone::GenericTime, QTimeZone::LongName, enUS),
- QString("Central European Standard Time"));
- QCOMPARE(tzp.displayName(QTimeZone::GenericTime, QTimeZone::ShortName, enUS),
- QString("GMT+01:00"));
- QCOMPARE(tzp.displayName(QTimeZone::GenericTime, QTimeZone::OffsetName, enUS),
- QString("UTC+01:00"));
-#else
- QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::LongName, enUS),
- QString("CET"));
- QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::ShortName, enUS),
- QString("CET"));
- QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::OffsetName, enUS),
- QString("CET"));
- QCOMPARE(tzp.displayName(QTimeZone::DaylightTime, QTimeZone::LongName, enUS),
- QString("CEST"));
- QCOMPARE(tzp.displayName(QTimeZone::DaylightTime, QTimeZone::ShortName, enUS),
- QString("CEST"));
- QCOMPARE(tzp.displayName(QTimeZone::DaylightTime, QTimeZone::OffsetName, enUS),
- QString("CEST"));
- QCOMPARE(tzp.displayName(QTimeZone::GenericTime, QTimeZone::LongName, enUS),
- QString("CET"));
- QCOMPARE(tzp.displayName(QTimeZone::GenericTime, QTimeZone::ShortName, enUS),
- QString("CET"));
- QCOMPARE(tzp.displayName(QTimeZone::GenericTime, QTimeZone::OffsetName, enUS),
- QString("CET"));
-#endif // icu
-
- // Test Abbreviations
- QCOMPARE(tzp.abbreviation(std), QString("CET"));
- QCOMPARE(tzp.abbreviation(dst), QString("CEST"));
- }
-
- testCetPrivate(tzp);
- testEpochTranPrivate(QTzTimeZonePrivate("America/Toronto"));
-
- // Test first and last transition rule
- // Warning: This could vary depending on age of TZ file!
-
- // Test low date uses first rule found
- // Note: Depending on the OS in question, the database may be carrying the
- // Local Mean Time. which for Berlin is 0:53:28
- QTimeZonePrivate::Data dat = tzp.data(-9999999999999);
- QCOMPARE(dat.atMSecsSinceEpoch, (qint64)-9999999999999);
- QCOMPARE(dat.daylightTimeOffset, 0);
- if (dat.abbreviation == "LMT") {
- QCOMPARE(dat.standardTimeOffset, 3208);
- } else {
- QCOMPARE(dat.standardTimeOffset, 3600);
-
- // Test previous to low value is invalid
- dat = tzp.previousTransition(-9999999999999);
- QCOMPARE(dat.atMSecsSinceEpoch, std::numeric_limits<qint64>::min());
- QCOMPARE(dat.standardTimeOffset, std::numeric_limits<int>::min());
- QCOMPARE(dat.daylightTimeOffset, std::numeric_limits<int>::min());
- }
-
- dat = tzp.nextTransition(-9999999999999);
- QCOMPARE(QDateTime::fromMSecsSinceEpoch(dat.atMSecsSinceEpoch, Qt::OffsetFromUTC, 3600),
- QDateTime(QDate(1893, 4, 1), QTime(0, 6, 32), Qt::OffsetFromUTC, 3600));
- QCOMPARE(dat.standardTimeOffset, 3600);
- QCOMPARE(dat.daylightTimeOffset, 0);
-
- // Known high datetimes
- qint64 stdHi = QDateTime(QDate(2100, 1, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch();
- qint64 dstHi = QDateTime(QDate(2100, 6, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch();
-
- // Tets high dates use the POSIX rule
- dat = tzp.data(stdHi);
- QCOMPARE(dat.atMSecsSinceEpoch - stdHi, (qint64)0);
- QCOMPARE(dat.offsetFromUtc, 3600);
- QCOMPARE(dat.standardTimeOffset, 3600);
- QCOMPARE(dat.daylightTimeOffset, 0);
-
- dat = tzp.data(dstHi);
- QCOMPARE(dat.atMSecsSinceEpoch - dstHi, (qint64)0);
- QCOMPARE(dat.offsetFromUtc, 7200);
- QCOMPARE(dat.standardTimeOffset, 3600);
- QCOMPARE(dat.daylightTimeOffset, 3600);
-
- dat = tzp.previousTransition(stdHi);
- QCOMPARE(QDateTime::fromMSecsSinceEpoch(dat.atMSecsSinceEpoch, Qt::OffsetFromUTC, 3600),
- QDateTime(QDate(2099, 10, 26), QTime(2, 0), Qt::OffsetFromUTC, 3600));
- QCOMPARE(dat.offsetFromUtc, 3600);
- QCOMPARE(dat.standardTimeOffset, 3600);
- QCOMPARE(dat.daylightTimeOffset, 0);
-
- dat = tzp.previousTransition(dstHi);
- QCOMPARE(QDateTime::fromMSecsSinceEpoch(dat.atMSecsSinceEpoch, Qt::OffsetFromUTC, 3600),
- QDateTime(QDate(2100, 3, 29), QTime(2, 0), Qt::OffsetFromUTC, 3600));
- QCOMPARE(dat.offsetFromUtc, 7200);
- QCOMPARE(dat.standardTimeOffset, 3600);
- QCOMPARE(dat.daylightTimeOffset, 3600);
-
- dat = tzp.nextTransition(stdHi);
- QCOMPARE(QDateTime::fromMSecsSinceEpoch(dat.atMSecsSinceEpoch, Qt::OffsetFromUTC, 3600),
- QDateTime(QDate(2100, 3, 29), QTime(2, 0), Qt::OffsetFromUTC, 3600));
- QCOMPARE(dat.offsetFromUtc, 7200);
- QCOMPARE(dat.standardTimeOffset, 3600);
- QCOMPARE(dat.daylightTimeOffset, 3600);
-
- dat = tzp.nextTransition(dstHi);
- QCOMPARE(QDateTime::fromMSecsSinceEpoch(dat.atMSecsSinceEpoch, Qt::OffsetFromUTC, 3600),
- QDateTime(QDate(2100, 10, 25), QTime(2, 0), Qt::OffsetFromUTC, 3600));
- QCOMPARE(dat.offsetFromUtc, 3600);
- QCOMPARE(dat.standardTimeOffset, 3600);
- QCOMPARE(dat.daylightTimeOffset, 0);
-
- // Test TZ timezone vs UTC timezone for fractionary negative offset
- QTzTimeZonePrivate tztz1("America/Caracas");
- QUtcTimeZonePrivate tzutc1("UTC-04:30");
- QVERIFY(tztz1.isValid());
- QVERIFY(tzutc1.isValid());
- QTzTimeZonePrivate::Data datatz1 = tztz1.data(std);
- QTzTimeZonePrivate::Data datautc1 = tzutc1.data(std);
- QCOMPARE(datatz1.offsetFromUtc, datautc1.offsetFromUtc);
-
- // Test TZ timezone vs UTC timezone for fractionary positive offset
- QTzTimeZonePrivate tztz2("Asia/Calcutta");
- QUtcTimeZonePrivate tzutc2("UTC+05:30");
- QVERIFY(tztz2.isValid());
- QVERIFY(tzutc2.isValid());
- QTzTimeZonePrivate::Data datatz2 = tztz2.data(std);
- QTzTimeZonePrivate::Data datautc2 = tzutc2.data(std);
- QCOMPARE(datatz2.offsetFromUtc, datautc2.offsetFromUtc);
-
- // Test a timezone with a name that isn't all letters
- QTzTimeZonePrivate tzBarnaul("Asia/Barnaul");
- if (tzBarnaul.isValid()) {
- QCOMPARE(tzBarnaul.data(std).abbreviation, QString("+07"));
-
- // first full day of the new rule (tzdata2016b)
- QDateTime dt(QDate(2016, 3, 28), QTime(0, 0, 0), Qt::UTC);
- QCOMPARE(tzBarnaul.data(dt.toMSecsSinceEpoch()).abbreviation, QString("+07"));
- }
-#endif // QT_BUILD_INTERNAL && Q_OS_UNIX && !Q_OS_DARWIN
-}
-
-void tst_QTimeZone::macTest()
-{
-#if defined(QT_BUILD_INTERNAL) && defined(Q_OS_DARWIN)
- // Known datetimes
- qint64 std = QDateTime(QDate(2012, 1, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch();
- qint64 dst = QDateTime(QDate(2012, 6, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch();
-
- // Test default constructor
- QMacTimeZonePrivate tzpd;
- QVERIFY(tzpd.isValid());
-
- // Test invalid constructor
- QMacTimeZonePrivate tzpi("Gondwana/Erewhon");
- QCOMPARE(tzpi.isValid(), false);
-
- // Test named constructor
- QMacTimeZonePrivate tzp("Europe/Berlin");
- QVERIFY(tzp.isValid());
-
- // Only test names in debug mode, names used can vary by version
- if (debug) {
- // Test display names by type
- QLocale enUS("en_US");
- QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::LongName, enUS),
- QString("Central European Standard Time"));
- QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::ShortName, enUS),
- QString("GMT+01:00"));
- QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::OffsetName, enUS),
- QString("UTC+01:00"));
- QCOMPARE(tzp.displayName(QTimeZone::DaylightTime, QTimeZone::LongName, enUS),
- QString("Central European Summer Time"));
- QCOMPARE(tzp.displayName(QTimeZone::DaylightTime, QTimeZone::ShortName, enUS),
- QString("GMT+02:00"));
- QCOMPARE(tzp.displayName(QTimeZone::DaylightTime, QTimeZone::OffsetName, enUS),
- QString("UTC+02:00"));
- // ICU C api does not support Generic Time yet, C++ api does
- QCOMPARE(tzp.displayName(QTimeZone::GenericTime, QTimeZone::LongName, enUS),
- QString("Central European Time"));
- QCOMPARE(tzp.displayName(QTimeZone::GenericTime, QTimeZone::ShortName, enUS),
- QString("Germany Time"));
- QCOMPARE(tzp.displayName(QTimeZone::GenericTime, QTimeZone::OffsetName, enUS),
- QString("UTC+01:00"));
-
- // Test Abbreviations
- QCOMPARE(tzp.abbreviation(std), QString("CET"));
- QCOMPARE(tzp.abbreviation(dst), QString("CEST"));
- }
-
- testCetPrivate(tzp);
- testEpochTranPrivate(QMacTimeZonePrivate("America/Toronto"));
-#endif // QT_BUILD_INTERNAL && Q_OS_DARWIN
-}
-
-void tst_QTimeZone::darwinTypes()
-{
-#ifndef Q_OS_DARWIN
- QSKIP("This is an Apple-only test");
-#else
- extern void tst_QTimeZone_darwinTypes(); // in tst_qtimezone_darwin.mm
- tst_QTimeZone_darwinTypes();
-#endif
-}
-
-void tst_QTimeZone::winTest()
-{
-#if defined(QT_BUILD_INTERNAL) && defined(USING_WIN_TZ)
- // Known datetimes
- qint64 std = QDateTime(QDate(2012, 1, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch();
- qint64 dst = QDateTime(QDate(2012, 6, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch();
-
- // Test default constructor
- QWinTimeZonePrivate tzpd;
- if (debug)
- qDebug() << "System ID = " << tzpd.id()
- << tzpd.displayName(QTimeZone::StandardTime, QTimeZone::LongName, QLocale())
- << tzpd.displayName(QTimeZone::GenericTime, QTimeZone::LongName, QLocale());
- QVERIFY(tzpd.isValid());
-
- // Test invalid constructor
- QWinTimeZonePrivate tzpi("Gondwana/Erewhon");
- QCOMPARE(tzpi.isValid(), false);
-
- // Test named constructor
- QWinTimeZonePrivate tzp("Europe/Berlin");
- QVERIFY(tzp.isValid());
-
- // Only test names in debug mode, names used can vary by version
- if (debug) {
- // Test display names by type
- QLocale enUS("en_US");
- QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::LongName, enUS),
- QString("W. Europe Standard Time"));
- QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::ShortName, enUS),
- QString("W. Europe Standard Time"));
- QCOMPARE(tzp.displayName(QTimeZone::StandardTime, QTimeZone::OffsetName, enUS),
- QString("UTC+01:00"));
- QCOMPARE(tzp.displayName(QTimeZone::DaylightTime, QTimeZone::LongName, enUS),
- QString("W. Europe Daylight Time"));
- QCOMPARE(tzp.displayName(QTimeZone::DaylightTime, QTimeZone::ShortName, enUS),
- QString("W. Europe Daylight Time"));
- QCOMPARE(tzp.displayName(QTimeZone::DaylightTime, QTimeZone::OffsetName, enUS),
- QString("UTC+02:00"));
- QCOMPARE(tzp.displayName(QTimeZone::GenericTime, QTimeZone::LongName, enUS),
- QString("(UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna"));
- QCOMPARE(tzp.displayName(QTimeZone::GenericTime, QTimeZone::ShortName, enUS),
- QString("(UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna"));
- QCOMPARE(tzp.displayName(QTimeZone::GenericTime, QTimeZone::OffsetName, enUS),
- QString("UTC+01:00"));
-
- // Test Abbreviations
- QCOMPARE(tzp.abbreviation(std), QString("W. Europe Standard Time"));
- QCOMPARE(tzp.abbreviation(dst), QString("W. Europe Daylight Time"));
- }
-
- testCetPrivate(tzp);
- testEpochTranPrivate(QWinTimeZonePrivate("America/Toronto"));
-#endif // QT_BUILD_INTERNAL && USING_WIN_TZ
-}
-
-#ifdef QT_BUILD_INTERNAL
-// Test each private produces the same basic results for CET
-void tst_QTimeZone::testCetPrivate(const QTimeZonePrivate &tzp)
-{
- // Known datetimes
- qint64 std = QDateTime(QDate(2012, 1, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch();
- qint64 dst = QDateTime(QDate(2012, 6, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch();
- qint64 prev = QDateTime(QDate(2011, 1, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch();
-
- QCOMPARE(tzp.offsetFromUtc(std), 3600);
- QCOMPARE(tzp.offsetFromUtc(dst), 7200);
-
- QCOMPARE(tzp.standardTimeOffset(std), 3600);
- QCOMPARE(tzp.standardTimeOffset(dst), 3600);
-
- QCOMPARE(tzp.daylightTimeOffset(std), 0);
- QCOMPARE(tzp.daylightTimeOffset(dst), 3600);
-
- QCOMPARE(tzp.hasDaylightTime(), true);
- QCOMPARE(tzp.isDaylightTime(std), false);
- QCOMPARE(tzp.isDaylightTime(dst), true);
-
- QTimeZonePrivate::Data dat = tzp.data(std);
- QCOMPARE(dat.atMSecsSinceEpoch, std);
- QCOMPARE(dat.offsetFromUtc, 3600);
- QCOMPARE(dat.standardTimeOffset, 3600);
- QCOMPARE(dat.daylightTimeOffset, 0);
- QCOMPARE(dat.abbreviation, tzp.abbreviation(std));
-
- dat = tzp.data(dst);
- QCOMPARE(dat.atMSecsSinceEpoch, dst);
- QCOMPARE(dat.offsetFromUtc, 7200);
- QCOMPARE(dat.standardTimeOffset, 3600);
- QCOMPARE(dat.daylightTimeOffset, 3600);
- QCOMPARE(dat.abbreviation, tzp.abbreviation(dst));
-
- // Only test transitions if host system supports them
- if (tzp.hasTransitions()) {
- QTimeZonePrivate::Data tran = tzp.nextTransition(std);
- // 2012-03-25 02:00 CET, +1 -> +2
- QCOMPARE(QDateTime::fromMSecsSinceEpoch(tran.atMSecsSinceEpoch, Qt::UTC),
- QDateTime(QDate(2012, 3, 25), QTime(2, 0), Qt::OffsetFromUTC, 3600));
- QCOMPARE(tran.offsetFromUtc, 7200);
- QCOMPARE(tran.standardTimeOffset, 3600);
- QCOMPARE(tran.daylightTimeOffset, 3600);
-
- tran = tzp.nextTransition(dst);
- // 2012-10-28 03:00 CEST, +2 -> +1
- QCOMPARE(QDateTime::fromMSecsSinceEpoch(tran.atMSecsSinceEpoch, Qt::UTC),
- QDateTime(QDate(2012, 10, 28), QTime(3, 0), Qt::OffsetFromUTC, 2 * 3600));
- QCOMPARE(tran.offsetFromUtc, 3600);
- QCOMPARE(tran.standardTimeOffset, 3600);
- QCOMPARE(tran.daylightTimeOffset, 0);
-
- tran = tzp.previousTransition(std);
- // 2011-10-30 03:00 CEST, +2 -> +1
- QCOMPARE(QDateTime::fromMSecsSinceEpoch(tran.atMSecsSinceEpoch, Qt::UTC),
- QDateTime(QDate(2011, 10, 30), QTime(3, 0), Qt::OffsetFromUTC, 2 * 3600));
- QCOMPARE(tran.offsetFromUtc, 3600);
- QCOMPARE(tran.standardTimeOffset, 3600);
- QCOMPARE(tran.daylightTimeOffset, 0);
-
- tran = tzp.previousTransition(dst);
- // 2012-03-25 02:00 CET, +1 -> +2 (again)
- QCOMPARE(QDateTime::fromMSecsSinceEpoch(tran.atMSecsSinceEpoch, Qt::UTC),
- QDateTime(QDate(2012, 3, 25), QTime(2, 0), Qt::OffsetFromUTC, 3600));
- QCOMPARE(tran.offsetFromUtc, 7200);
- QCOMPARE(tran.standardTimeOffset, 3600);
- QCOMPARE(tran.daylightTimeOffset, 3600);
-
- QTimeZonePrivate::DataList expected;
- // 2011-03-27 02:00 CET, +1 -> +2
- tran.atMSecsSinceEpoch = QDateTime(QDate(2011, 3, 27), QTime(2, 0),
- Qt::OffsetFromUTC, 3600).toMSecsSinceEpoch();
- tran.offsetFromUtc = 7200;
- tran.standardTimeOffset = 3600;
- tran.daylightTimeOffset = 3600;
- expected << tran;
- // 2011-10-30 03:00 CEST, +2 -> +1
- tran.atMSecsSinceEpoch = QDateTime(QDate(2011, 10, 30), QTime(3, 0),
- Qt::OffsetFromUTC, 2 * 3600).toMSecsSinceEpoch();
- tran.offsetFromUtc = 3600;
- tran.standardTimeOffset = 3600;
- tran.daylightTimeOffset = 0;
- expected << tran;
- QTimeZonePrivate::DataList result = tzp.transitions(prev, std);
- QCOMPARE(result.count(), expected.count());
- for (int i = 0; i < expected.count(); ++i) {
- QCOMPARE(QDateTime::fromMSecsSinceEpoch(result.at(i).atMSecsSinceEpoch,
- Qt::OffsetFromUTC, 3600),
- QDateTime::fromMSecsSinceEpoch(expected.at(i).atMSecsSinceEpoch,
- Qt::OffsetFromUTC, 3600));
- QCOMPARE(result.at(i).offsetFromUtc, expected.at(i).offsetFromUtc);
- QCOMPARE(result.at(i).standardTimeOffset, expected.at(i).standardTimeOffset);
- QCOMPARE(result.at(i).daylightTimeOffset, expected.at(i).daylightTimeOffset);
- }
- }
-}
-
-// Needs a zone with DST around the epoch; currently America/Toronto (EST5EDT)
-void tst_QTimeZone::testEpochTranPrivate(const QTimeZonePrivate &tzp)
-{
- if (!tzp.hasTransitions())
- return; // test only viable for transitions
-
- QTimeZonePrivate::Data tran = tzp.nextTransition(0); // i.e. first after epoch
- // 1970-04-26 02:00 EST, -5 -> -4
- const QDateTime after = QDateTime(QDate(1970, 4, 26), QTime(2, 0), Qt::OffsetFromUTC, -5 * 3600);
- const QDateTime found = QDateTime::fromMSecsSinceEpoch(tran.atMSecsSinceEpoch, Qt::UTC);
-#ifdef USING_WIN_TZ // MS gets the date wrong: 5th April instead of 26th.
- QCOMPARE(found.toOffsetFromUtc(-5 * 3600).time(), after.time());
-#else
- QCOMPARE(found, after);
-#endif
- QCOMPARE(tran.offsetFromUtc, -4 * 3600);
- QCOMPARE(tran.standardTimeOffset, -5 * 3600);
- QCOMPARE(tran.daylightTimeOffset, 3600);
-
- // Pre-epoch time-zones might not be supported at all:
- tran = tzp.nextTransition(QDateTime(QDate(1601, 1, 1), QTime(0, 0),
- Qt::UTC).toMSecsSinceEpoch());
- if (tran.atMSecsSinceEpoch != QTimeZonePrivate::invalidMSecs()
- // Toronto *did* have a transition before 1970 (DST since 1918):
- && tran.atMSecsSinceEpoch < 0) {
- // ... but, if they are, we should be able to search back to them:
- tran = tzp.previousTransition(0); // i.e. last before epoch
- // 1969-10-26 02:00 EDT, -4 -> -5
- QCOMPARE(QDateTime::fromMSecsSinceEpoch(tran.atMSecsSinceEpoch, Qt::UTC),
- QDateTime(QDate(1969, 10, 26), QTime(2, 0), Qt::OffsetFromUTC, -4 * 3600));
- QCOMPARE(tran.offsetFromUtc, -5 * 3600);
- QCOMPARE(tran.standardTimeOffset, -5 * 3600);
- QCOMPARE(tran.daylightTimeOffset, 0);
- } else {
- // Do not use QSKIP(): that would discard the rest of this sub-test's caller.
- qDebug() << "No support for pre-epoch time-zone transitions";
- }
-}
-#endif // QT_BUILD_INTERNAL
-
-QTEST_APPLESS_MAIN(tst_QTimeZone)
-#include "tst_qtimezone.moc"