/* This file is part of the KDE libraries Copyright (c) 2005-2007,2011-2012 David Jarvie This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "config-date.h" // for HAVE_TM_GMTOFF #include "ktimezonestest.h" #include "ktimezonestest_p.h" #include "ksystemtimezone.h" #include "qtest_kde.h" #include #include #include QTEST_KDEMAIN_CORE(KTimeZonesTest) TimeZoneTestData s_testData; void KTimeZonesTest::initTestCase() { s_testData.setupTimeZoneTest(); // see ktimezonestest_p.h mDataDir = s_testData.dataDir(); } void KTimeZonesTest::cleanupTestCase() { s_testData.cleanupTimeZoneTest(); } /////////////////// // KTimeZones tests /////////////////// void KTimeZonesTest::ktimezones() { KTimeZones timezones; KTimeZone zone1("Zone1"); QVERIFY(zone1.isValid()); KTimeZone zone2("Zone2"); QVERIFY(zone2.isValid()); QVERIFY(timezones.add(zone1)); QVERIFY(!timezones.add(zone1)); QVERIFY(timezones.add(zone2)); QCOMPARE(timezones.zones().count(), 2); KTimeZone tz = timezones.zone("Zone1"); QVERIFY((tz == zone1)); tz = timezones.zone("Zone99"); QVERIFY(!tz.isValid()); zone1 = timezones.remove(zone1); QVERIFY(zone1.isValid()); QCOMPARE(timezones.zones().count(), 1); QVERIFY(!timezones.remove(zone1).isValid()); QVERIFY(timezones.add(zone1)); QVERIFY(timezones.remove("Zone1").isValid()); QVERIFY(!timezones.remove("Zone1").isValid()); QVERIFY(timezones.remove("Zone2").isValid()); zone1 = KTimeZone("Zone10"); QVERIFY(timezones.add(zone1)); QCOMPARE(timezones.zones().count(), 1); timezones.clear(); QCOMPARE(timezones.zones().count(), 0); } ////////////////////////// // KTimeZone: ref counting ////////////////////////// void KTimeZonesTest::refcount() { KTimeZone *zone1 = new KTimeZone("Zone1"); QCOMPARE(zone1->name(), QString("Zone1")); KTimeZones timezones; timezones.add(*zone1); delete zone1; zone1 = 0; KTimeZone tz = timezones.zone("Zone1"); QVERIFY(tz.isValid()); QCOMPARE(tz.name(), QString("Zone1")); QCOMPARE(tz.type(), QByteArray("KTimeZone")); } /////////////////// // KTimeZone: UTC /////////////////// void KTimeZonesTest::utc() { KTimeZone utc = KTimeZone::utc(); QVERIFY(utc.isValid()); QCOMPARE(utc.name(), QString("UTC")); QCOMPARE(utc.offsetAtUtc(QDateTime(QDate(2005,1,1), QTime(), Qt::LocalTime)), 0); QCOMPARE(utc.offsetAtUtc(QDateTime(QDate(2005,1,1), QTime(), Qt::UTC)), 0); QCOMPARE(utc.offsetAtUtc(QDateTime(QDate(2005,2,1), QTime(), Qt::UTC)), 0); QCOMPARE(utc.offsetAtUtc(QDateTime(QDate(2005,7,1), QTime(), Qt::UTC)), 0); } ///////////////////////// // KSystemTimeZones tests ///////////////////////// void KTimeZonesTest::local() { KTimeZone local = KSystemTimeZones::local(); QVERIFY(local.isValid()); QCOMPARE(local.name(), QString::fromLatin1("Europe/Paris")); QCOMPARE(local.type(), QByteArray("KTimeZone")); } void KTimeZonesTest::zone() { KTimeZone utc = KSystemTimeZones::zone("UTC"); QVERIFY(utc.isValid()); KTimeZone losAngeles = KSystemTimeZones::zone("America/Los_Angeles"); QVERIFY(losAngeles.isValid()); KTimeZone london = KSystemTimeZones::zone("Europe/London"); QVERIFY(london.isValid()); QCOMPARE(london.countryCode(), QString("GB")); QCOMPARE(london.latitude(), float(51*3600 + 28*60 + 30)/3600.0f); QCOMPARE(london.longitude(), -float(0*3600 + 18*60 + 45)/3600.0f); QCOMPARE(london.comment(), QString("Great Britain")); QCOMPARE(losAngeles.longitude(), -float(118*3600 + 14*60 + 34)/3600.0f); } void KTimeZonesTest::zoneinfoDir() { QString zoneinfo = KSystemTimeZones::zoneinfoDir(); QCOMPARE(zoneinfo, mDataDir); } void KTimeZonesTest::zonetabChange() { QCOMPARE(KSystemTimeZones::zones().count(), 5); KTimeZone london = KSystemTimeZones::zone("Europe/London"); QVERIFY(london.isValid()); QCOMPARE(london.countryCode(), QString("GB")); QCOMPARE(london.latitude(), float(51*3600 + 28*60 + 30)/3600.0f); QCOMPARE(london.longitude(), -float(0*3600 + 18*60 + 45)/3600.0f); QCOMPARE(london.comment(), QString("Great Britain")); QVERIFY(!KSystemTimeZones::zone("Europe/Berlin").isValid()); QVERIFY(KSystemTimeZones::zone("Europe/Paris").isValid()); QVERIFY(KSystemTimeZones::zone("Europe/London").isValid()); QVERIFY(KSystemTimeZones::zone("Africa/Cairo").isValid()); QVERIFY(!KSystemTimeZones::zone("Asia/Dili").isValid()); QVERIFY(KSystemTimeZones::zone("America/Los_Angeles").isValid()); // Check that 'london' is automatically updated with the new zone.tab // contents, and that the new zones are added to KSystemTimeZones. s_testData.writeZoneTab(true); QTest::qWait(3000); QCOMPARE(KSystemTimeZones::zones().count(), 7); london = KSystemTimeZones::zone("Europe/London"); QVERIFY(london.isValid()); QCOMPARE(london.countryCode(), QString("XX")); QCOMPARE(london.latitude(), -float(51*3600 + 28*60 + 30)/3600.0f); QCOMPARE(london.longitude(), float(0*3600 + 18*60 + 45)/3600.0f); QCOMPARE(london.comment(), QString("Greater Britain")); QCOMPARE(KSystemTimeZones::zone("Europe/London"), london); QVERIFY(KSystemTimeZones::zone("Europe/Berlin").isValid()); QVERIFY(KSystemTimeZones::zone("Europe/Paris").isValid()); QVERIFY(KSystemTimeZones::zone("Europe/London").isValid()); QVERIFY(KSystemTimeZones::zone("Africa/Cairo").isValid()); QVERIFY(KSystemTimeZones::zone("Africa/Johannesburg").isValid()); QVERIFY(KSystemTimeZones::zone("Asia/Dili").isValid()); QVERIFY(KSystemTimeZones::zone("America/Los_Angeles").isValid()); // Check that 'london' is automatically updated with the new zone.tab // contents, and that the removed zones are deleted from KSystemTimeZones. s_testData.writeZoneTab(false); QTest::qWait(3000); london = KSystemTimeZones::zone("Europe/London"); QCOMPARE(KSystemTimeZones::zones().count(), 5); QVERIFY(london.isValid()); QCOMPARE(london.countryCode(), QString("GB")); QCOMPARE(london.latitude(), float(51*3600 + 28*60 + 30)/3600.0f); QCOMPARE(london.longitude(), -float(0*3600 + 18*60 + 45)/3600.0f); QCOMPARE(london.comment(), QString("Great Britain")); QCOMPARE(KSystemTimeZones::zone("Europe/London"), london); QVERIFY(!KSystemTimeZones::zone("Europe/Berlin").isValid()); QVERIFY(KSystemTimeZones::zone("Europe/Paris").isValid()); QVERIFY(KSystemTimeZones::zone("Europe/London").isValid()); QVERIFY(KSystemTimeZones::zone("Africa/Cairo").isValid()); QVERIFY(!KSystemTimeZones::zone("Asia/Dili").isValid()); QVERIFY(KSystemTimeZones::zone("America/Los_Angeles").isValid()); } //////////////////////// // KSystemTimeZone tests //////////////////////// void KTimeZonesTest::currentOffset() { const char *originalZone = ::getenv("TZ"); // save the original local time zone ::setenv("TZ", ":Europe/Paris", 1); ::tzset(); // Find the current offset of a time zone time_t now = time(0); tm *tnow = localtime(&now); #if defined(HAVE_TM_GMTOFF) int offset = tnow->tm_gmtoff; #else int offset = 0; #endif KTimeZone local = KSystemTimeZones::local(); QVERIFY(local.isValid()); QCOMPARE(local.currentOffset(Qt::UTC), offset); // Restore the original local time zone if (!originalZone) ::unsetenv("TZ"); else ::setenv("TZ", originalZone, 1); ::tzset(); } void KTimeZonesTest::offsetAtUtc() { // Find some offsets for Europe/London. KTimeZone losAngeles = KSystemTimeZones::zone("America/Los_Angeles"); QVERIFY(losAngeles.isValid()); KTimeZone london = KSystemTimeZones::zone("Europe/London"); QVERIFY(london.isValid()); QDateTime winter(QDate(2005,1,1), QTime(0,0,0), Qt::UTC); QDateTime summer(QDate(2005,6,1), QTime(0,0,0), Qt::UTC); QCOMPARE(london.offsetAtUtc(winter), 0); QCOMPARE(london.offsetAtUtc(summer), 3600);; QCOMPARE(losAngeles.offsetAtUtc(winter), -28800); QCOMPARE(losAngeles.offsetAtUtc(summer), -25200);; } void KTimeZonesTest::offsetAtZoneTime() { QDateTime Gmt1(QDate(2005,3,27), QTime(0,30,0), Qt::LocalTime); QDateTime GmtToBst1(QDate(2005,3,27), QTime(0,59,59), Qt::LocalTime); QDateTime GmtToBst2(QDate(2005,3,27), QTime(1,0,0), Qt::LocalTime); QDateTime GmtToBst3(QDate(2005,3,27), QTime(1,59,59), Qt::LocalTime); QDateTime GmtToBst4(QDate(2005,3,27), QTime(2,0,0), Qt::LocalTime); QDateTime Bst1(QDate(2005,4,27), QTime(2,30,0), Qt::LocalTime); QDateTime Bst2(QDate(2005,10,30), QTime(0,30,0), Qt::LocalTime); QDateTime BstToGmt1(QDate(2005,10,30), QTime(0,59,59), Qt::LocalTime); QDateTime BstToGmt2(QDate(2005,10,30), QTime(1,0,0), Qt::LocalTime); QDateTime BstToGmt3(QDate(2005,10,30), QTime(1,59,59), Qt::LocalTime); QDateTime BstToGmt4(QDate(2005,10,30), QTime(2,0,0), Qt::LocalTime); QDateTime Gmt2(QDate(2005,10,30), QTime(2,30,0), Qt::LocalTime); KTimeZone london = KSystemTimeZones::zone("Europe/London"); QVERIFY(london.isValid()); int offset2; QCOMPARE(london.offsetAtZoneTime(Gmt1, &offset2), 0); QCOMPARE(offset2, 0); QCOMPARE(london.offsetAtZoneTime(GmtToBst1, &offset2), 0); QCOMPARE(offset2, 0); QCOMPARE(london.offsetAtZoneTime(GmtToBst2, &offset2), KTimeZone::InvalidOffset); QCOMPARE(offset2, KTimeZone::InvalidOffset); QCOMPARE(london.offsetAtZoneTime(GmtToBst3, &offset2), KTimeZone::InvalidOffset); QCOMPARE(offset2, KTimeZone::InvalidOffset); QCOMPARE(london.offsetAtZoneTime(GmtToBst4, &offset2), 3600); QCOMPARE(offset2, 3600); QCOMPARE(london.offsetAtZoneTime(Bst1, &offset2), 3600); QCOMPARE(offset2, 3600); QCOMPARE(london.offsetAtZoneTime(Bst2, &offset2), 3600); QCOMPARE(offset2, 3600); QCOMPARE(london.offsetAtZoneTime(BstToGmt1, &offset2), 3600); QCOMPARE(offset2, 3600); QCOMPARE(london.offsetAtZoneTime(BstToGmt2, &offset2), 3600); QCOMPARE(offset2, 0); QCOMPARE(london.offsetAtZoneTime(BstToGmt3, &offset2), 3600); QCOMPARE(offset2, 0); QCOMPARE(london.offsetAtZoneTime(BstToGmt4, &offset2), 0); QCOMPARE(offset2, 0); QCOMPARE(london.offsetAtZoneTime(Gmt2, &offset2), 0); QCOMPARE(offset2, 0); KTimeZone johannesburg = KSystemTimeZones::zone("Africa/Johannesburg"); QVERIFY(johannesburg.isValid()); QDateTime recent(QDate(2013,5,10), QTime(13,0,0), Qt::LocalTime); QCOMPARE(johannesburg.offsetAtZoneTime(recent, &offset2), 7200); QCOMPARE(offset2, 7200); } void KTimeZonesTest::abbreviation() { // Fetch time zone abbreviations KTimeZone losAngeles = KSystemTimeZones::zone("America/Los_Angeles"); QVERIFY(losAngeles.isValid()); KTimeZone london = KSystemTimeZones::zone("Europe/London"); QVERIFY(london.isValid()); QDateTime winter(QDate(2005,1,1), QTime(0,0,0), Qt::UTC); QDateTime summer(QDate(2005,6,1), QTime(0,0,0), Qt::UTC); QString sResult = london.abbreviation(winter); QCOMPARE(london.abbreviation(winter), QByteArray("GMT")); QCOMPARE(london.abbreviation(summer), QByteArray("BST")); QCOMPARE(losAngeles.abbreviation(winter), QByteArray("PST")); QCOMPARE(losAngeles.abbreviation(summer), QByteArray("PDT")); } void KTimeZonesTest::timet() { QDateTime t1(QDate(1970,1,2), QTime(1,30,5), Qt::UTC); QDateTime t2(QDate(1969,12,30), QTime(22,29,55), Qt::UTC); time_t t1t = KTimeZone::toTime_t(t1); time_t t2t = KTimeZone::toTime_t(t2); QCOMPARE((int)t1t, 86400 + 3600 + 30*60 + 5); QCOMPARE((int)t2t, -(86400 + 3600 + 30*60 + 5)); QCOMPARE(KTimeZone::fromTime_t(t1t), t1); QCOMPARE(KTimeZone::fromTime_t(t2t), t2); } void KTimeZonesTest::toUtc() { // Convert to UTC. KTimeZone losAngeles = KSystemTimeZones::zone("America/Los_Angeles"); QVERIFY(losAngeles.isValid()); KTimeZone london = KSystemTimeZones::zone("Europe/London"); QVERIFY(london.isValid()); QDateTime winter(QDate(2005,1,1), QTime(0,0,0), Qt::UTC); QDateTime summer(QDate(2005,6,1), QTime(0,0,0), Qt::UTC); QDateTime winterLocal = winter; winterLocal.setTimeSpec(Qt::LocalTime); QDateTime summerLocal = summer; summerLocal.setTimeSpec(Qt::LocalTime); QCOMPARE(london.toUtc(winterLocal), winter); QCOMPARE(london.toUtc(summerLocal), summer.addSecs(-3600));; QCOMPARE(losAngeles.toUtc(winterLocal), winter.addSecs(8*3600)); QCOMPARE(losAngeles.toUtc(summerLocal), summer.addSecs(7*3600)); } void KTimeZonesTest::toZoneTime() { // Convert from UTC. KTimeZone losAngeles = KSystemTimeZones::zone("America/Los_Angeles"); QVERIFY(losAngeles.isValid()); KTimeZone london = KSystemTimeZones::zone("Europe/London"); QVERIFY(london.isValid()); QDateTime winter(QDate(2005,1,1), QTime(0,0,0), Qt::UTC); QDateTime summer(QDate(2005,6,1), QTime(0,0,0), Qt::UTC); QDateTime winterLocal = winter; winterLocal.setTimeSpec(Qt::LocalTime); QDateTime summerLocal = summer; summerLocal.setTimeSpec(Qt::LocalTime); QCOMPARE(london.toZoneTime(winter), winterLocal); QCOMPARE(london.toZoneTime(summer), summerLocal.addSecs(3600)); QCOMPARE(losAngeles.toZoneTime(winter), winterLocal.addSecs(-8*3600)); QCOMPARE(losAngeles.toZoneTime(summer), summerLocal.addSecs(-7*3600)); QDateTime prepre(QDate(2005,10,29), QTime(23,59,59), Qt::UTC); // before time shift (local time not repeated) QDateTime pre(QDate(2005,10,30), QTime(0,0,0), Qt::UTC); // before time shift (local time repeated afterwards) QDateTime before(QDate(2005,10,30), QTime(0,59,59), Qt::UTC); // before time shift (local time repeated afterwards) QDateTime at(QDate(2005,10,30), QTime(1,0,0), Qt::UTC); // at time shift (second occurrence of local time) QDateTime last(QDate(2005,10,30), QTime(1,59,59), Qt::UTC); // after time shift (second occurrence of local time) QDateTime after(QDate(2005,10,30), QTime(2,0,0), Qt::UTC); // after time shift (local time not repeated) bool second; QCOMPARE(london.toZoneTime(prepre, &second), QDateTime(QDate(2005,10,30), QTime(0,59,59), Qt::LocalTime)); QVERIFY(!second); QCOMPARE(london.toZoneTime(pre, &second), QDateTime(QDate(2005,10,30), QTime(1,0,0), Qt::LocalTime)); QVERIFY(!second); QCOMPARE(london.toZoneTime(before, &second), QDateTime(QDate(2005,10,30), QTime(1,59,59), Qt::LocalTime)); QVERIFY(!second); QCOMPARE(london.toZoneTime(at, &second), QDateTime(QDate(2005,10,30), QTime(1,0,0), Qt::LocalTime)); QVERIFY(second); QCOMPARE(london.toZoneTime(last, &second), QDateTime(QDate(2005,10,30), QTime(1,59,59), Qt::LocalTime)); QVERIFY(second); QCOMPARE(london.toZoneTime(after, &second), QDateTime(QDate(2005,10,30), QTime(2,0,0), Qt::LocalTime)); QVERIFY(!second); } void KTimeZonesTest::convert() { // Try time zone conversions. KTimeZone losAngeles = KSystemTimeZones::zone("America/Los_Angeles"); QVERIFY(losAngeles.isValid()); KTimeZone london = KSystemTimeZones::zone("Europe/London"); QVERIFY(london.isValid()); QDateTime bstBeforePdt(QDate(2005,3,28), QTime(0,0,0), Qt::LocalTime); QDateTime bstAfterPdt(QDate(2005,5,1), QTime(0,0,0), Qt::LocalTime); QDateTime gmtBeforePst(QDate(2005,10,30), QTime(4,0,0), Qt::LocalTime); QDateTime gmtAfterPst(QDate(2005,12,1), QTime(0,0,0), Qt::LocalTime); QDateTime bstBeforePdtResult(QDate(2005,3,27), QTime(15,0,0), Qt::LocalTime); QDateTime bstAfterPdtResult(QDate(2005,4,30), QTime(16,0,0), Qt::LocalTime); QDateTime gmtBeforePstResult(QDate(2005,10,29), QTime(21,0,0), Qt::LocalTime); QDateTime gmtAfterPstResult(QDate(2005,11,30), QTime(16,0,0), Qt::LocalTime); QCOMPARE(london.convert(losAngeles, bstBeforePdt), bstBeforePdtResult); QCOMPARE(london.convert(losAngeles, bstAfterPdt), bstAfterPdtResult); QCOMPARE(london.convert(losAngeles, gmtBeforePst), gmtBeforePstResult); QCOMPARE(london.convert(losAngeles, gmtAfterPst), gmtAfterPstResult); QCOMPARE(losAngeles.convert(losAngeles, bstBeforePdtResult), bstBeforePdtResult); } //////////////////////// // KTimeZone tests // Plus KSystemTimeZones::readZone() tests //////////////////////// void KTimeZonesTest::tzfile() { QDateTime winter(QDate(2005,1,1), QTime(0,0,0), Qt::UTC); QString zoneinfo = KSystemTimeZones::zoneinfoDir(); QVERIFY(!zoneinfo.isEmpty()); KTimeZoneSource tzsource(zoneinfo); KTimeZone *tzcairo = new KTimeZone(&tzsource, "Africa/Cairo"); delete tzcairo; tzcairo = new KTimeZone(&tzsource, "Africa/Cairo"); QCOMPARE(tzcairo->offsetAtUtc(winter), 7200); delete tzcairo; KTimeZone *johannesburg = new KTimeZone(&tzsource, "Africa/Johannesburg"); delete johannesburg; johannesburg = new KTimeZone(&tzsource, "Africa/Johannesburg"); QCOMPARE(johannesburg->offsetAtUtc(winter), 7200); delete johannesburg; } void KTimeZonesTest::tzfileDstShifts() { // Check time zone conversions against zdump output for zone KTimeZoneSource tzsource(KSystemTimeZones::zoneinfoDir()); KTimeZone berlin = KTimeZone(&tzsource, "Europe/Berlin"); KTimeZone losAngeles = KTimeZone(&tzsource, "America/Los_Angeles"); KTimeZone tz = berlin; for (int n = 0; n < 2; ++n, tz = losAngeles) { qDebug() << tz.name(); QVERIFY(tz.isValid()); QCOMPARE(tz.type(), QByteArray("KTimeZone")); QFile file(QString::fromLatin1(KDESRCDIR) + tz.name().remove(QRegExp("^.+/")) + QLatin1String(".zdump")); QVERIFY(file.open(QIODevice::ReadOnly)); QTextStream in(&file); QString line; while (!(line = in.readLine()).isNull()) { QStringList parts = line.split(" ", QString::SkipEmptyParts); QCOMPARE(parts[6], QString::fromLatin1("UTC")); QCOMPARE(parts[7], QString::fromLatin1("=")); QCOMPARE(parts[14].left(6), QString::fromLatin1("isdst=")); QCOMPARE(parts[15].left(7), QString::fromLatin1("gmtoff=")); QDateTime utc = QDateTime::fromString(static_cast(parts.mid(1, 5)).join(" ")); utc.setTimeSpec(Qt::UTC); QDateTime local = QDateTime::fromString(static_cast(parts.mid(8, 5)).join(" ")); local.setTimeSpec(Qt::LocalTime); QCOMPARE(tz.toZoneTime(utc), local); QCOMPARE(parts[13], QString::fromLatin1(tz.abbreviation(utc))); bool dst = (parts[14].right(1) != "0"); QCOMPARE(tz.isDstAtUtc(utc), dst); QCOMPARE(parts[15].mid(7).toInt(), tz.offsetAtUtc(utc)); } file.close(); } } void KTimeZonesTest::tzfileToZoneTime() { // Convert from UTC. KTimeZoneSource tzsource(KSystemTimeZones::zoneinfoDir()); KTimeZone london = KTimeZone(&tzsource, "Europe/London"); QVERIFY(london.isValid()); QCOMPARE(london.type(), QByteArray("KTimeZone")); QDateTime prepre(QDate(2005,10,29), QTime(23,59,59), Qt::UTC); // before time shift (local time not repeated) QDateTime pre(QDate(2005,10,30), QTime(0,0,0), Qt::UTC); // before time shift (local time repeated afterwards) QDateTime before(QDate(2005,10,30), QTime(0,59,59), Qt::UTC); // before time shift (local time repeated afterwards) QDateTime at(QDate(2005,10,30), QTime(1,0,0), Qt::UTC); // at time shift (second occurrence of local time) QDateTime last(QDate(2005,10,30), QTime(1,59,59), Qt::UTC); // after time shift (second occurrence of local time) QDateTime after(QDate(2005,10,30), QTime(2,0,0), Qt::UTC); // after time shift (local time not repeated) bool second; QCOMPARE(london.toZoneTime(prepre, &second), QDateTime(QDate(2005,10,30), QTime(0,59,59), Qt::LocalTime)); QVERIFY(!second); QCOMPARE(london.toZoneTime(pre, &second), QDateTime(QDate(2005,10,30), QTime(1,0,0), Qt::LocalTime)); QVERIFY(!second); QCOMPARE(london.toZoneTime(before, &second), QDateTime(QDate(2005,10,30), QTime(1,59,59), Qt::LocalTime)); QVERIFY(!second); QCOMPARE(london.toZoneTime(at, &second), QDateTime(QDate(2005,10,30), QTime(1,0,0), Qt::LocalTime)); QVERIFY(second); QCOMPARE(london.toZoneTime(last, &second), QDateTime(QDate(2005,10,30), QTime(1,59,59), Qt::LocalTime)); QVERIFY(second); QCOMPARE(london.toZoneTime(after, &second), QDateTime(QDate(2005,10,30), QTime(2,0,0), Qt::LocalTime)); QVERIFY(!second); KTimeZone sysLondon = KSystemTimeZones::readZone("Europe/London"); QVERIFY(sysLondon.isValid()); QCOMPARE(sysLondon.toZoneTime(prepre, &second), QDateTime(QDate(2005,10,30), QTime(0,59,59), Qt::LocalTime)); QVERIFY(!second); QCOMPARE(sysLondon.toZoneTime(pre, &second), QDateTime(QDate(2005,10,30), QTime(1,0,0), Qt::LocalTime)); QVERIFY(!second); QCOMPARE(sysLondon.toZoneTime(before, &second), QDateTime(QDate(2005,10,30), QTime(1,59,59), Qt::LocalTime)); QVERIFY(!second); QCOMPARE(sysLondon.toZoneTime(at, &second), QDateTime(QDate(2005,10,30), QTime(1,0,0), Qt::LocalTime)); QVERIFY(second); QCOMPARE(sysLondon.toZoneTime(last, &second), QDateTime(QDate(2005,10,30), QTime(1,59,59), Qt::LocalTime)); QVERIFY(second); QCOMPARE(sysLondon.toZoneTime(after, &second), QDateTime(QDate(2005,10,30), QTime(2,0,0), Qt::LocalTime)); QVERIFY(!second); } void KTimeZonesTest::tzfileOffsetAtUtc() { QDateTime a3Gmt(QDate(2004,12,27), QTime(0,30,0), Qt::UTC); QDateTime a2Gmt(QDate(2005,2,27), QTime(0,30,0), Qt::UTC); QDateTime aGmt(QDate(2005,3,27), QTime(0,30,0), Qt::UTC); QDateTime aBst(QDate(2005,3,27), QTime(1,30,0), Qt::UTC); QDateTime a2Bst(QDate(2005,7,27), QTime(2,30,0), Qt::UTC); QDateTime bBst(QDate(2005,10,29), QTime(23,30,0), Qt::UTC); QDateTime bBstBeforeGmt(QDate(2005,10,30), QTime(0,30,0), Qt::UTC); QDateTime bGmt(QDate(2005,10,30), QTime(2,30,0), Qt::UTC); KTimeZoneSource tzsource(KSystemTimeZones::zoneinfoDir()); KTimeZone london = KTimeZone(&tzsource, "Europe/London"); QVERIFY(london.isValid()); QCOMPARE(london.type(), QByteArray("KTimeZone")); QCOMPARE(london.offsetAtUtc(a3Gmt), 0); QCOMPARE(london.offsetAtUtc(a2Gmt), 0); // uses cache QCOMPARE(london.offsetAtUtc(aGmt), 0); // uses cache QCOMPARE(london.offsetAtUtc(aBst), 3600); QCOMPARE(london.offsetAtUtc(a2Bst), 3600); // uses cache QCOMPARE(london.offsetAtUtc(bBst), 3600); // uses cache QCOMPARE(london.offsetAtUtc(bBstBeforeGmt), 3600); // uses cache QCOMPARE(london.offsetAtUtc(bGmt), 0); QDateTime recent(QDate(2013,5,10), QTime(13,0,0), Qt::UTC); KTimeZone johannesburg = KTimeZone(&tzsource, "Africa/Johannesburg"); QVERIFY(johannesburg.isValid()); QCOMPARE(johannesburg.type(), QByteArray("KTimeZone")); QCOMPARE(johannesburg.offsetAtUtc(recent), 7200); } void KTimeZonesTest::tzfileOffsetAtZoneTime() { QDateTime Gmt0(QDate(2005,2,27), QTime(0,30,0), Qt::LocalTime); QDateTime Gmt1(QDate(2005,3,27), QTime(0,30,0), Qt::LocalTime); QDateTime GmtToBst1(QDate(2005,3,27), QTime(0,59,59), Qt::LocalTime); QDateTime GmtToBst2(QDate(2005,3,27), QTime(1,0,0), Qt::LocalTime); QDateTime GmtToBst3(QDate(2005,3,27), QTime(1,59,59), Qt::LocalTime); QDateTime GmtToBst4(QDate(2005,3,27), QTime(2,0,0), Qt::LocalTime); QDateTime Bst1(QDate(2005,4,27), QTime(2,30,0), Qt::LocalTime); QDateTime Bst2(QDate(2005,10,30), QTime(0,30,0), Qt::LocalTime); QDateTime BstToGmt1(QDate(2005,10,30), QTime(0,59,59), Qt::LocalTime); QDateTime BstToGmt2(QDate(2005,10,30), QTime(1,0,0), Qt::LocalTime); QDateTime BstToGmt3(QDate(2005,10,30), QTime(1,59,59), Qt::LocalTime); QDateTime BstToGmt4(QDate(2005,10,30), QTime(2,0,0), Qt::LocalTime); QDateTime Gmt2(QDate(2005,10,30), QTime(2,30,0), Qt::LocalTime); KTimeZoneSource tzsource(KSystemTimeZones::zoneinfoDir()); KTimeZone london = KTimeZone(&tzsource, "Europe/London"); QVERIFY(london.isValid()); int offset2; QCOMPARE(london.offsetAtZoneTime(Gmt0, &offset2), 0); QCOMPARE(offset2, 0); QCOMPARE(london.offsetAtZoneTime(Gmt1, &offset2), 0); // uses cache QCOMPARE(offset2, 0); QCOMPARE(london.offsetAtZoneTime(GmtToBst1, &offset2), 0); // uses cache QCOMPARE(offset2, 0); QCOMPARE(london.offsetAtZoneTime(GmtToBst2, &offset2), KTimeZone::InvalidOffset); QCOMPARE(offset2, KTimeZone::InvalidOffset); QCOMPARE(london.offsetAtZoneTime(GmtToBst3, &offset2), KTimeZone::InvalidOffset); QCOMPARE(offset2, KTimeZone::InvalidOffset); QCOMPARE(london.offsetAtZoneTime(GmtToBst4, &offset2), 3600); QCOMPARE(offset2, 3600); QCOMPARE(london.offsetAtZoneTime(Bst1, &offset2), 3600); QCOMPARE(offset2, 3600); QCOMPARE(london.offsetAtZoneTime(Bst2, &offset2), 3600); // uses cache QCOMPARE(offset2, 3600); QCOMPARE(london.offsetAtZoneTime(BstToGmt1, &offset2), 3600); // uses cache QCOMPARE(offset2, 3600); QCOMPARE(london.offsetAtZoneTime(BstToGmt2, &offset2), 3600); QCOMPARE(offset2, 0); QCOMPARE(london.offsetAtZoneTime(BstToGmt3, &offset2), 3600); QCOMPARE(offset2, 0); QCOMPARE(london.offsetAtZoneTime(BstToGmt4, &offset2), 0); QCOMPARE(offset2, 0); QCOMPARE(london.offsetAtZoneTime(Gmt2, &offset2), 0); // uses cache QCOMPARE(offset2, 0); KTimeZone sysLondon = KSystemTimeZones::readZone("Europe/London"); QVERIFY(sysLondon.isValid()); QCOMPARE(sysLondon.offsetAtZoneTime(Gmt0, &offset2), 0); QCOMPARE(offset2, 0); QCOMPARE(sysLondon.offsetAtZoneTime(Gmt1, &offset2), 0); // uses cache QCOMPARE(offset2, 0); QCOMPARE(sysLondon.offsetAtZoneTime(GmtToBst1, &offset2), 0); // uses cache QCOMPARE(offset2, 0); QCOMPARE(sysLondon.offsetAtZoneTime(GmtToBst2, &offset2), KTimeZone::InvalidOffset); QCOMPARE(offset2, KTimeZone::InvalidOffset); QCOMPARE(sysLondon.offsetAtZoneTime(GmtToBst3, &offset2), KTimeZone::InvalidOffset); QCOMPARE(offset2, KTimeZone::InvalidOffset); QCOMPARE(sysLondon.offsetAtZoneTime(GmtToBst4, &offset2), 3600); QCOMPARE(offset2, 3600); QCOMPARE(sysLondon.offsetAtZoneTime(Bst1, &offset2), 3600); QCOMPARE(offset2, 3600); QCOMPARE(sysLondon.offsetAtZoneTime(Bst2, &offset2), 3600); // uses cache QCOMPARE(offset2, 3600); QCOMPARE(sysLondon.offsetAtZoneTime(BstToGmt1, &offset2), 3600); // uses cache QCOMPARE(offset2, 3600); QCOMPARE(sysLondon.offsetAtZoneTime(BstToGmt2, &offset2), 3600); QCOMPARE(offset2, 0); QCOMPARE(sysLondon.offsetAtZoneTime(BstToGmt3, &offset2), 3600); QCOMPARE(offset2, 0); QCOMPARE(sysLondon.offsetAtZoneTime(BstToGmt4, &offset2), 0); QCOMPARE(offset2, 0); QCOMPARE(sysLondon.offsetAtZoneTime(Gmt2, &offset2), 0); // uses cache QCOMPARE(offset2, 0); KTimeZone johannesburg = KTimeZone(&tzsource, "Africa/Johannesburg"); QVERIFY(johannesburg.isValid()); QCOMPARE(johannesburg.type(), QByteArray("KTimeZone")); QDateTime recent(QDate(2013,5,10), QTime(13,0,0), Qt::LocalTime); QCOMPARE(johannesburg.offsetAtZoneTime(recent, &offset2), 7200); QCOMPARE(offset2, 7200); } void KTimeZonesTest::tzfileUtcOffsets() { KTimeZoneSource tzsource(KSystemTimeZones::zoneinfoDir()); KTimeZone london = KTimeZone(&tzsource, "Europe/London"); QVERIFY(london.isValid()); QList offsets = london.utcOffsets(); QCOMPARE(offsets.count(), 3); QCOMPARE(offsets[0], 0); // GMT QCOMPARE(offsets[1], 3600); // BST QCOMPARE(offsets[2], 7200); // DST KTimeZone sysLondon = KSystemTimeZones::readZone("Europe/London"); QVERIFY(sysLondon.isValid()); offsets = sysLondon.utcOffsets(); QCOMPARE(offsets.count(), 3); QCOMPARE(offsets[0], 0); // GMT QCOMPARE(offsets[1], 3600); // BST QCOMPARE(offsets[2], 7200); // DST } void KTimeZonesTest::tzfileAbbreviation() { KTimeZoneSource tzsource(KSystemTimeZones::zoneinfoDir()); KTimeZone london = KTimeZone(&tzsource, "Europe/London"); QVERIFY(london.isValid()); QDateTime winter(QDate(2005,1,1), QTime(0,0,0), Qt::UTC); QDateTime summer(QDate(2005,6,1), QTime(0,0,0), Qt::UTC); QDateTime standard(QDate(1970,4,30), QTime(12,45,16,25), Qt::UTC); QString sResult = london.abbreviation(winter); QCOMPARE(london.abbreviation(winter), QByteArray("GMT")); QCOMPARE(london.abbreviation(summer), QByteArray("BST")); QCOMPARE(london.abbreviation(standard), QByteArray("BST")); KTimeZone sysLondon = KSystemTimeZones::readZone("Europe/London"); QVERIFY(sysLondon.isValid()); sResult = sysLondon.abbreviation(winter); QCOMPARE(sysLondon.abbreviation(winter), QByteArray("GMT")); QCOMPARE(sysLondon.abbreviation(summer), QByteArray("BST")); QCOMPARE(sysLondon.abbreviation(standard), QByteArray("BST")); } void KTimeZonesTest::tzfileTransitions() { KTimeZoneSource tzsource(KSystemTimeZones::zoneinfoDir()); KTimeZone london = KTimeZone(&tzsource, "Europe/London"); QVERIFY(london.isValid()); QList all = london.transitions(); QVERIFY(!all.isEmpty()); QDateTime jan2003(QDate(2003,1,1),QTime(0,0,0),Qt::UTC); QDateTime jan2006(QDate(2006,1,1),QTime(0,0,0),Qt::UTC); int index2006 = london.transitionIndex(jan2006); if (index2006 >= 0) { QVERIFY(all[index2006].time() <= jan2006); QList some = london.transitions(QDateTime(), jan2006); QList check = all.mid(0, index2006+1); QCOMPARE(some.count(), check.count()); for (int i = 0; i < some.count(); ++i) { QCOMPARE(some[i].time(), check[i].time()); QCOMPARE(some[i].phase(), check[i].phase()); } if (all[index2006].time() < jan2006 && ++index2006 < all.count()) QVERIFY(all[index2006].time() > jan2006); some = london.transitions(jan2006); check = all.mid(index2006); for (int i = 0; i < some.count(); ++i) { QCOMPARE(some[i].time(), check[i].time()); QCOMPARE(some[i].phase(), check[i].phase()); } } index2006 = london.transitionIndex(jan2006); int index2003 = london.transitionIndex(jan2003); if (index2003 >= 0) { QVERIFY(all[index2003].time() <= jan2003); if (all[index2003].time() < jan2003 && ++index2003 < all.count()) QVERIFY(all[index2003].time() > jan2003); QList some = london.transitions(jan2003, jan2006); QList check = all.mid(index2003, index2006-index2003+1); QCOMPARE(some.count(), check.count()); for (int i = 0; i < some.count(); ++i) { QCOMPARE(some[i].time(), check[i].time()); QCOMPARE(some[i].phase(), check[i].phase()); } } } #include "moc_ktimezonestest.cpp"