File indexing completed on 2024-04-14 14:19:40

0001 /* This file is part of the KDE libraries
0002    Copyright (c) 2005,2006,2010,2011 David Jarvie <djarvie@kde.org>
0003 
0004    This library is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU Library General Public
0006    License as published by the Free Software Foundation; either
0007    version 2 of the License, or (at your option) any later version.
0008 
0009    This library is distributed in the hope that it will be useful,
0010    but WITHOUT ANY WARRANTY; without even the implied warranty of
0011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012    Library General Public License for more details.
0013 
0014    You should have received a copy of the GNU Library General Public License
0015    along with this library; see the file COPYING.LIB.  If not, write to
0016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017    Boston, MA 02110-1301, USA.
0018 */
0019 
0020 #include "kdatetimetest.h"
0021 
0022 #include <cstdlib>
0023 #include <QTest>
0024 #include <QDir>
0025 #include <klocale.h>
0026 #include <kcalendarsystem.h>
0027 #include <ksystemtimezone.h>
0028 #include <ktzfiletimezone.h>
0029 #include <kdatetime.h>
0030 #include <kconfiggroup.h>
0031 #include <QDBusConnection>
0032 #include <QDBusConnectionInterface>
0033 #include <QDBusInterface>
0034 #include <QDBusReply>
0035 #include <QTimer>
0036 #include <QSignalSpy>
0037 
0038 //TODO: test new methods
0039 
0040 QTEST_MAIN(KDateTimeTest)
0041 
0042 extern KDELIBS4SUPPORT_EXPORT int KDateTime_utcCacheHit;
0043 extern KDELIBS4SUPPORT_EXPORT int KDateTime_zoneCacheHit;
0044 
0045 void KDateTimeTest::initTestCase()
0046 {
0047     cleanupTestCase();
0048 
0049     mDataDir = QDir::homePath() + "/.kde-unit-test/kdatetimetest";
0050     QVERIFY(QDir().mkpath(mDataDir));
0051     QFile f;
0052     f.setFileName(mDataDir + QLatin1String("/zone.tab"));
0053     f.open(QIODevice::WriteOnly);
0054     QTextStream fStream(&f);
0055     fStream << "DE      +5230+01322     Europe/Berlin\n"
0056             "EG +3003+03115 Africa/Cairo\n"
0057             "FR +4852+00220 Europe/Paris\n"
0058             "GB +512830-0001845 Europe/London   Great Britain\n"
0059             "US +340308-1181434 America/Los_Angeles Pacific Time\n";
0060     f.close();
0061     QDir dir(mDataDir);
0062     QVERIFY(dir.mkdir("Africa"));
0063     QVERIFY(QFile::copy(QFINDTESTDATA("Cairo"), mDataDir + QLatin1String("/Africa/Cairo")));
0064     QVERIFY(dir.mkdir("America"));
0065     QVERIFY(QFile::copy(QFINDTESTDATA("Los_Angeles"), mDataDir + QLatin1String("/America/Los_Angeles")));
0066     QVERIFY(dir.mkdir("Europe"));
0067     QVERIFY(QFile::copy(QFINDTESTDATA("Berlin"), mDataDir + QLatin1String("/Europe/Berlin")));
0068     QVERIFY(QFile::copy(QFINDTESTDATA("London"), mDataDir + QLatin1String("/Europe/London")));
0069     QVERIFY(QFile::copy(QFINDTESTDATA("Paris"), mDataDir + QLatin1String("/Europe/Paris")));
0070 
0071     KConfig config("ktimezonedrc");
0072     KConfigGroup group(&config, "TimeZones");
0073     group.writeEntry("ZoneinfoDir", mDataDir);
0074     group.writeEntry("Zonetab", QString(mDataDir + QString::fromLatin1("/zone.tab")));
0075     group.writeEntry("LocalZone", QString::fromLatin1("America/Los_Angeles"));
0076     config.sync();
0077 }
0078 
0079 void KDateTimeTest::cleanupTestCase()
0080 {
0081     removeDir(QLatin1String("kdatetimetest/Africa"));
0082     removeDir(QLatin1String("kdatetimetest/America"));
0083     removeDir(QLatin1String("kdatetimetest/Europe"));
0084     removeDir(QLatin1String("kdatetimetest"));
0085     QFile::remove(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QLatin1Char('/') + "ktimezonedrc");
0086 }
0087 
0088 void KDateTimeTest::removeDir(const QString &subdir)
0089 {
0090     QDir local(QDir::homePath() + QLatin1String("/.kde-unit-test/") + subdir);
0091     foreach (const QString &file, local.entryList(QDir::Files))
0092         if (!local.remove(file)) {
0093             qWarning("%s: removing failed", qPrintable(file));
0094         }
0095     QCOMPARE((int)local.entryList(QDir::Files).count(), 0);
0096     local.cdUp();
0097     QString subd = subdir;
0098     subd.remove(QRegExp("^.*/"));
0099     local.rmpath(subd);
0100 }
0101 
0102 ////////////////////////////////////////////////////////////////////////
0103 // KDateTime::Spec constructors and basic property information methods,
0104 // and the static convenience instances/methods.
0105 ////////////////////////////////////////////////////////////////////////
0106 
0107 void KDateTimeTest::specConstructors()
0108 {
0109     KTimeZone london = KSystemTimeZones::zone("Europe/London");
0110     KTimeZone losAngeles = KSystemTimeZones::zone("America/Los_Angeles");
0111 
0112     QByteArray originalZone = qgetenv("TZ");   // save the original local time zone
0113     qputenv("TZ", ":Europe/London");
0114     ::tzset();
0115 
0116     // Ensure that local time is different from UTC and different from 'london'
0117     qputenv("TZ", ":America/Los_Angeles");
0118     ::tzset();
0119 
0120     // Default constructor
0121     KDateTime::Spec invalid;
0122     QVERIFY(!invalid.isValid());
0123     QCOMPARE(invalid.type(), KDateTime::Invalid);
0124     QVERIFY(!invalid.isLocalZone());
0125     QVERIFY(!invalid.isUtc());
0126     QVERIFY(!invalid.isOffsetFromUtc());
0127     QVERIFY(!invalid.isClockTime());
0128     QCOMPARE(invalid.utcOffset(), 0);
0129     QVERIFY(!invalid.timeZone().isValid());
0130 
0131     // Time zone
0132     KDateTime::Spec tz(london);
0133     QVERIFY(tz.isValid());
0134     QCOMPARE(tz.type(), KDateTime::TimeZone);
0135     QVERIFY(!tz.isUtc());
0136     QVERIFY(!tz.isOffsetFromUtc());
0137     QVERIFY(!tz.isLocalZone());
0138     QVERIFY(!tz.isClockTime());
0139     QCOMPARE(tz.utcOffset(), 0);
0140     QCOMPARE(tz.timeZone(), london);
0141 
0142     KDateTime::Spec tzLocal(losAngeles);
0143     QVERIFY(tzLocal.isValid());
0144     QCOMPARE(tzLocal.type(), KDateTime::TimeZone);
0145     QCOMPARE(tzLocal, KDateTime::Spec(KDateTime::LocalZone));
0146     QVERIFY(!tzLocal.isUtc());
0147     QVERIFY(!tzLocal.isOffsetFromUtc());
0148     QVERIFY(tzLocal.isLocalZone());
0149     QVERIFY(!tzLocal.isClockTime());
0150     QCOMPARE(tzLocal.utcOffset(), 0);
0151     QCOMPARE(tzLocal.timeZone(), losAngeles);
0152 
0153     // ... copy constructor
0154     KDateTime::Spec tzCopy(tz);
0155     QVERIFY(tzCopy.isValid());
0156     QCOMPARE(tzCopy.type(), KDateTime::TimeZone);
0157     QVERIFY(!tzCopy.isUtc());
0158     QVERIFY(!tzCopy.isOffsetFromUtc());
0159     QVERIFY(!tzCopy.isLocalZone());
0160     QVERIFY(!tzCopy.isClockTime());
0161     QCOMPARE(tzCopy.utcOffset(), 0);
0162     QCOMPARE(tzCopy.timeZone(), london);
0163 
0164     // Local time zone
0165     KDateTime::Spec local(KDateTime::LocalZone);
0166     QVERIFY(local.isValid());
0167     QCOMPARE(local.type(), KDateTime::TimeZone);
0168     QCOMPARE(local, KDateTime::Spec(KDateTime::LocalZone));
0169     QVERIFY(!local.isUtc());
0170     QVERIFY(!local.isOffsetFromUtc());
0171     QVERIFY(local.isLocalZone());
0172     QVERIFY(!local.isClockTime());
0173     QCOMPARE(local.utcOffset(), 0);
0174     QCOMPARE(local.timeZone(), KSystemTimeZones::local());
0175 
0176     KDateTime::Spec localx(KDateTime::Spec(KDateTime::LocalZone, 2 * 3600));
0177     QVERIFY(localx.isValid());
0178     QCOMPARE(localx.type(), KDateTime::TimeZone);
0179     QCOMPARE(localx, KDateTime::Spec(KDateTime::LocalZone));
0180     QVERIFY(!localx.isUtc());
0181     QVERIFY(!localx.isOffsetFromUtc());
0182     QVERIFY(localx.isLocalZone());
0183     QVERIFY(!localx.isClockTime());
0184     QCOMPARE(localx.utcOffset(), 0);
0185     QCOMPARE(localx.timeZone(), KSystemTimeZones::local());
0186 
0187     KDateTime::Spec local2 = KDateTime::Spec::LocalZone();
0188     QVERIFY(local2.isValid());
0189     QCOMPARE(local2.type(), KDateTime::TimeZone);
0190     QCOMPARE(local2, KDateTime::Spec(KDateTime::LocalZone));
0191     QVERIFY(!local2.isUtc());
0192     QVERIFY(!local2.isOffsetFromUtc());
0193     QVERIFY(local2.isLocalZone());
0194     QVERIFY(!local2.isClockTime());
0195     QCOMPARE(local2.utcOffset(), 0);
0196     QCOMPARE(local2.timeZone(), KSystemTimeZones::local());
0197 
0198     // ... copy constructor
0199     KDateTime::Spec localCopy(local);
0200     QVERIFY(localCopy.isValid());
0201     QCOMPARE(localCopy.type(), KDateTime::TimeZone);
0202     QCOMPARE(localCopy, KDateTime::Spec(KDateTime::LocalZone));
0203     QVERIFY(!localCopy.isUtc());
0204     QVERIFY(!localCopy.isOffsetFromUtc());
0205     QVERIFY(localCopy.isLocalZone());
0206     QVERIFY(!localCopy.isClockTime());
0207     QCOMPARE(localCopy.utcOffset(), 0);
0208     QCOMPARE(localCopy.timeZone(), losAngeles);
0209 
0210     // UTC
0211     KDateTime::Spec utc(KDateTime::UTC);
0212     QVERIFY(utc.isValid());
0213     QCOMPARE(utc.type(), KDateTime::UTC);
0214     QVERIFY(utc.isUtc());
0215     QVERIFY(!utc.isOffsetFromUtc());
0216     QVERIFY(!utc.isLocalZone());
0217     QVERIFY(!utc.isClockTime());
0218     QCOMPARE(utc.utcOffset(), 0);
0219     QCOMPARE(utc.timeZone(), KTimeZone::utc());
0220 
0221     KDateTime::Spec utcx(KDateTime::UTC, 2 * 3600);
0222     QVERIFY(utcx.isValid());
0223     QCOMPARE(utcx.type(), KDateTime::UTC);
0224     QVERIFY(utcx.isUtc());
0225     QVERIFY(!utcx.isOffsetFromUtc());
0226     QVERIFY(!utcx.isLocalZone());
0227     QVERIFY(!utcx.isClockTime());
0228     QCOMPARE(utcx.utcOffset(), 0);
0229     QCOMPARE(utcx.timeZone(), KTimeZone::utc());
0230 
0231     const KDateTime::Spec &utc2 = KDateTime::Spec::UTC();
0232     QVERIFY(utc2.isValid());
0233     QCOMPARE(utc2.type(), KDateTime::UTC);
0234     QVERIFY(utc2.isUtc());
0235     QVERIFY(!utc2.isOffsetFromUtc());
0236     QVERIFY(!utc2.isLocalZone());
0237     QVERIFY(!utc2.isClockTime());
0238     QCOMPARE(utc2.utcOffset(), 0);
0239     QCOMPARE(utc2.timeZone(), KTimeZone::utc());
0240 
0241     // ... copy constructor
0242     KDateTime::Spec utcCopy(utc);
0243     QVERIFY(utcCopy.isValid());
0244     QCOMPARE(utcCopy.type(), KDateTime::UTC);
0245     QVERIFY(utcCopy.isUtc());
0246     QVERIFY(!utcCopy.isOffsetFromUtc());
0247     QVERIFY(!utcCopy.isLocalZone());
0248     QVERIFY(!utcCopy.isClockTime());
0249     QCOMPARE(utcCopy.utcOffset(), 0);
0250     QCOMPARE(utcCopy.timeZone(), KTimeZone::utc());
0251 
0252     // Offset from UTC
0253     KDateTime::Spec offset0(KDateTime::OffsetFromUTC);
0254     QVERIFY(offset0.isValid());
0255     QCOMPARE(offset0.type(), KDateTime::OffsetFromUTC);
0256     QVERIFY(offset0.isUtc());
0257     QVERIFY(offset0.isOffsetFromUtc());
0258     QVERIFY(!offset0.isLocalZone());
0259     QVERIFY(!offset0.isClockTime());
0260     QCOMPARE(offset0.utcOffset(), 0);
0261     QVERIFY(!offset0.timeZone().isValid());
0262 
0263     KDateTime::Spec offset(KDateTime::Spec(KDateTime::OffsetFromUTC, -2 * 3600));
0264     QVERIFY(offset.isValid());
0265     QCOMPARE(offset.type(), KDateTime::OffsetFromUTC);
0266     QVERIFY(!offset.isUtc());
0267     QVERIFY(offset.isOffsetFromUtc());
0268     QVERIFY(!offset.isLocalZone());
0269     QVERIFY(!offset.isClockTime());
0270     QCOMPARE(offset.utcOffset(), -2 * 3600);
0271     QVERIFY(!offset.timeZone().isValid());
0272 
0273     KDateTime::Spec offset2 = KDateTime::Spec::OffsetFromUTC(2 * 3600);
0274     QVERIFY(offset2.isValid());
0275     QCOMPARE(offset2.type(), KDateTime::OffsetFromUTC);
0276     QVERIFY(!offset2.isUtc());
0277     QVERIFY(offset2.isOffsetFromUtc());
0278     QVERIFY(!offset2.isLocalZone());
0279     QVERIFY(!offset2.isClockTime());
0280     QCOMPARE(offset2.utcOffset(), 2 * 3600);
0281     QVERIFY(!offset2.timeZone().isValid());
0282 
0283     // ... copy constructor
0284     KDateTime::Spec offsetCopy(offset);
0285     QVERIFY(offsetCopy.isValid());
0286     QCOMPARE(offsetCopy.type(), KDateTime::OffsetFromUTC);
0287     QVERIFY(!offsetCopy.isUtc());
0288     QVERIFY(offsetCopy.isOffsetFromUtc());
0289     QVERIFY(!offsetCopy.isLocalZone());
0290     QVERIFY(!offsetCopy.isClockTime());
0291     QCOMPARE(offsetCopy.utcOffset(), -2 * 3600);
0292     QVERIFY(!offsetCopy.timeZone().isValid());
0293 
0294     // Local clock time
0295     KDateTime::Spec clock(KDateTime::ClockTime);
0296     QVERIFY(clock.isValid());
0297     QCOMPARE(clock.type(), KDateTime::ClockTime);
0298     QVERIFY(!clock.isUtc());
0299     QVERIFY(!clock.isOffsetFromUtc());
0300     QVERIFY(!clock.isLocalZone());
0301     QVERIFY(clock.isClockTime());
0302     QCOMPARE(clock.utcOffset(), 0);
0303     QVERIFY(!clock.timeZone().isValid());
0304 
0305     KDateTime::Spec clockx(KDateTime::Spec(KDateTime::ClockTime, 2 * 3600));
0306     QVERIFY(clockx.isValid());
0307     QCOMPARE(clockx.type(), KDateTime::ClockTime);
0308     QVERIFY(!clockx.isUtc());
0309     QVERIFY(!clockx.isOffsetFromUtc());
0310     QVERIFY(!clockx.isLocalZone());
0311     QVERIFY(clockx.isClockTime());
0312     QCOMPARE(clockx.utcOffset(), 0);
0313     QVERIFY(!clockx.timeZone().isValid());
0314 
0315     KDateTime::Spec clock2 = KDateTime::Spec::ClockTime();
0316     QVERIFY(clock2.isValid());
0317     QCOMPARE(clock2.type(), KDateTime::ClockTime);
0318     QVERIFY(!clock2.isUtc());
0319     QVERIFY(!clock2.isOffsetFromUtc());
0320     QVERIFY(!clock2.isLocalZone());
0321     QVERIFY(clock2.isClockTime());
0322     QCOMPARE(clock2.utcOffset(), 0);
0323     QVERIFY(!clock2.timeZone().isValid());
0324 
0325     // ... copy constructor
0326     KDateTime::Spec clockCopy(clock);
0327     QVERIFY(clockCopy.isValid());
0328     QCOMPARE(clockCopy.type(), KDateTime::ClockTime);
0329     QVERIFY(!clockCopy.isUtc());
0330     QVERIFY(!clockCopy.isOffsetFromUtc());
0331     QVERIFY(!clockCopy.isLocalZone());
0332     QVERIFY(clockCopy.isClockTime());
0333     QCOMPARE(clockCopy.utcOffset(), 0);
0334     QVERIFY(!clockCopy.timeZone().isValid());
0335 
0336     // "valid but garbage" timezone spec
0337     KTzfileTimeZoneSource source("/invalid/tzinfo/dir");
0338     KDateTime dateTimeInvalidTz(QDate(2001, 02, 13), QTime(3, 45, 14), KTzfileTimeZone(&source, "Europe/London"));
0339     QVERIFY(!dateTimeInvalidTz.isNull());
0340     QVERIFY(!dateTimeInvalidTz.isValid());
0341     QCOMPARE(dateTimeInvalidTz.toString(KDateTime::ISODate), QLatin1String("2001-02-13T03:45:14+EINVAL"));
0342 
0343     // Restore the original local time zone
0344     if (originalZone.isEmpty()) {
0345         ::unsetenv("TZ");
0346     } else {
0347         qputenv("TZ", originalZone);
0348     }
0349     ::tzset();
0350 }
0351 
0352 ////////////////////////////////////////////////////////////////////////
0353 // KDateTime::Spec setType(), operator==(), etc.
0354 ////////////////////////////////////////////////////////////////////////
0355 
0356 void KDateTimeTest::specSet()
0357 {
0358     KTimeZone london = KSystemTimeZones::zone("Europe/London");
0359     KTimeZone losAngeles = KSystemTimeZones::zone("America/Los_Angeles");
0360 
0361     // Ensure that local time is different from UTC and different from 'london'
0362     QByteArray originalZone = qgetenv("TZ");   // save the original local time zone
0363     qputenv("TZ", ":America/Los_Angeles");
0364     ::tzset();
0365 
0366     KDateTime::Spec spec;
0367     QCOMPARE(spec.type(), KDateTime::Invalid);
0368 
0369     spec.setType(KDateTime::OffsetFromUTC, 7200);
0370     QCOMPARE(spec.type(), KDateTime::OffsetFromUTC);
0371     QVERIFY(spec.equivalentTo(KDateTime::Spec::OffsetFromUTC(7200)));
0372     QVERIFY(!spec.equivalentTo(KDateTime::Spec::OffsetFromUTC(0)));
0373     QVERIFY(spec == KDateTime::Spec::OffsetFromUTC(7200));
0374     QVERIFY(!(spec != KDateTime::Spec::OffsetFromUTC(7200)));
0375     QVERIFY(spec != KDateTime::Spec::OffsetFromUTC(-7200));
0376     QVERIFY(spec != KDateTime::Spec(london));
0377 
0378     spec.setType(KDateTime::OffsetFromUTC, 0);
0379     QCOMPARE(spec.type(), KDateTime::OffsetFromUTC);
0380     QVERIFY(spec.equivalentTo(KDateTime::Spec::OffsetFromUTC(0)));
0381     QVERIFY(spec.equivalentTo(KDateTime::Spec::UTC()));
0382     QVERIFY(!spec.equivalentTo(KDateTime::Spec::OffsetFromUTC(7200)));
0383     QVERIFY(spec == KDateTime::Spec::OffsetFromUTC(0));
0384     QVERIFY(!(spec != KDateTime::Spec::OffsetFromUTC(0)));
0385     QVERIFY(spec != KDateTime::Spec::OffsetFromUTC(-7200));
0386     QVERIFY(spec != KDateTime::Spec(london));
0387 
0388     spec.setType(london);
0389     QCOMPARE(spec.type(), KDateTime::TimeZone);
0390     QVERIFY(spec.equivalentTo(KDateTime::Spec(london)));
0391     QVERIFY(spec == KDateTime::Spec(london));
0392     QVERIFY(!(spec != KDateTime::Spec(london)));
0393     QVERIFY(spec != KDateTime::Spec::OffsetFromUTC(0));
0394     QVERIFY(!spec.equivalentTo(KDateTime::Spec::OffsetFromUTC(0)));
0395 
0396     spec.setType(KDateTime::LocalZone);
0397     QCOMPARE(spec.type(), KDateTime::TimeZone);
0398     QVERIFY(spec.equivalentTo(KDateTime::Spec::LocalZone()));
0399     QVERIFY(spec == KDateTime::Spec::LocalZone());
0400     QVERIFY(!(spec != KDateTime::Spec::LocalZone()));
0401     QVERIFY(spec.equivalentTo(KDateTime::Spec(losAngeles)));
0402     QVERIFY(spec == KDateTime::Spec(losAngeles));
0403     QVERIFY(spec != KDateTime::Spec(london));
0404     QVERIFY(!spec.equivalentTo(KDateTime::Spec(london)));
0405 
0406     spec.setType(KDateTime::UTC);
0407     QCOMPARE(spec.type(), KDateTime::UTC);
0408     QVERIFY(spec.equivalentTo(KDateTime::Spec::UTC()));
0409     QVERIFY(spec == KDateTime::Spec::UTC());
0410     QVERIFY(!(spec != KDateTime::Spec::UTC()));
0411     QVERIFY(spec != KDateTime::Spec::LocalZone());
0412     QVERIFY(!spec.equivalentTo(KDateTime::Spec::LocalZone()));
0413     QVERIFY(spec.equivalentTo(KDateTime::Spec::OffsetFromUTC(0)));
0414 
0415     spec.setType(KDateTime::ClockTime);
0416     QCOMPARE(spec.type(), KDateTime::ClockTime);
0417     QVERIFY(spec.equivalentTo(KDateTime::Spec::ClockTime()));
0418     QVERIFY(spec == KDateTime::Spec::ClockTime());
0419     QVERIFY(!(spec != KDateTime::Spec::ClockTime()));
0420     QVERIFY(spec != KDateTime::Spec::UTC());
0421     QVERIFY(!spec.equivalentTo(KDateTime::Spec::UTC()));
0422 
0423     // Restore the original local time zone
0424     if (originalZone.isEmpty()) {
0425         ::unsetenv("TZ");
0426     } else {
0427         qputenv("TZ", originalZone);
0428     }
0429     ::tzset();
0430 }
0431 
0432 //////////////////////////////////////////////////////
0433 // Constructors and basic property information methods
0434 //////////////////////////////////////////////////////
0435 
0436 void KDateTimeTest::constructors()
0437 {
0438     QDate d(2001, 2, 13);
0439     QTime t(3, 45, 14);
0440     QDateTime dtLocal(d, t, Qt::LocalTime);
0441     QDateTime dtUTC(d, t, Qt::UTC);
0442     QDateTime dtLocal2(QDate(2016,03,27), QTime(1,0,0));  //Europe/London daylight savings change time
0443     KTimeZone london = KSystemTimeZones::zone("Europe/London");
0444 
0445     QByteArray originalZone = qgetenv("TZ");   // save the original local time zone
0446     qputenv("TZ", ":Europe/London");
0447     ::tzset();
0448     QDateTime dtUTCtoLondon = dtUTC.toLocalTime();
0449 
0450     // Ensure that local time is different from UTC and different from 'london'
0451     qputenv("TZ", ":America/Los_Angeles");
0452     ::tzset();
0453 
0454     // Default constructor
0455     KDateTime deflt;
0456     QVERIFY(deflt.isNull());
0457     QVERIFY(!deflt.isValid());
0458 
0459     // No time zone or timeSpec explicitly specified
0460     KDateTime datetimeL(dtLocal);
0461     QVERIFY(!datetimeL.isNull());
0462     QVERIFY(datetimeL.isValid());
0463     QVERIFY(!datetimeL.isDateOnly());
0464     QCOMPARE(datetimeL.timeType(), KDateTime::TimeZone);
0465     QCOMPARE(datetimeL.timeSpec(), KDateTime::Spec::LocalZone());
0466     QVERIFY(datetimeL.isLocalZone());
0467     QVERIFY(!datetimeL.isUtc());
0468     QVERIFY(!datetimeL.isOffsetFromUtc());
0469     QVERIFY(!datetimeL.isClockTime());
0470     QCOMPARE(datetimeL.utcOffset(), -8 * 3600);
0471     QCOMPARE(datetimeL.timeZone(), KSystemTimeZones::local());
0472     QCOMPARE(datetimeL.dateTime(), dtLocal);
0473 
0474     KDateTime datetimeU(dtUTC);
0475     QVERIFY(!datetimeU.isNull());
0476     QVERIFY(datetimeU.isValid());
0477     QVERIFY(!datetimeU.isDateOnly());
0478     QCOMPARE(datetimeU.timeType(), KDateTime::UTC);
0479     QVERIFY(!datetimeU.isLocalZone());
0480     QVERIFY(datetimeU.isUtc());
0481     QVERIFY(!datetimeU.isOffsetFromUtc());
0482     QVERIFY(!datetimeU.isClockTime());
0483     QCOMPARE(datetimeU.utcOffset(), 0);
0484     QCOMPARE(datetimeU.timeZone(), KTimeZone::utc());
0485     QCOMPARE(datetimeU.dateTime(), dtUTC);
0486 
0487     // Time zone
0488     KDateTime dateTz(d, london);
0489     QVERIFY(!dateTz.isNull());
0490     QVERIFY(dateTz.isValid());
0491     QVERIFY(dateTz.isDateOnly());
0492     QCOMPARE(dateTz.timeType(), KDateTime::TimeZone);
0493     QVERIFY(!dateTz.isUtc());
0494     QVERIFY(!dateTz.isOffsetFromUtc());
0495     QVERIFY(!dateTz.isLocalZone());
0496     QVERIFY(!dateTz.isClockTime());
0497     QCOMPARE(dateTz.utcOffset(), 0);
0498     QCOMPARE(dateTz.timeZone(), london);
0499     QCOMPARE(dateTz.dateTime(), QDateTime(d, QTime(0, 0, 0), Qt::LocalTime));
0500     QCOMPARE(dateTz.date(), d);
0501 
0502     KDateTime dateTimeTz(d, QTime(3, 45, 14), london);
0503     QVERIFY(!dateTimeTz.isNull());
0504     QVERIFY(dateTimeTz.isValid());
0505     QVERIFY(!dateTimeTz.isDateOnly());
0506     QCOMPARE(dateTimeTz.timeType(), KDateTime::TimeZone);
0507     QVERIFY(!dateTimeTz.isUtc());
0508     QVERIFY(!dateTimeTz.isOffsetFromUtc());
0509     QVERIFY(!dateTimeTz.isLocalZone());
0510     QVERIFY(!dateTimeTz.isClockTime());
0511     QCOMPARE(dateTimeTz.utcOffset(), 0);
0512     QCOMPARE(dateTimeTz.timeZone(), london);
0513     QCOMPARE(dateTimeTz.dateTime(), QDateTime(d, QTime(3, 45, 14), Qt::LocalTime));
0514     QCOMPARE(dateTimeTz.time(), QTime(3, 45, 14));
0515 
0516     KDateTime datetimeTz(dtLocal, london);
0517     QVERIFY(!datetimeTz.isNull());
0518     QVERIFY(datetimeTz.isValid());
0519     QVERIFY(!dateTimeTz.isDateOnly());
0520     QCOMPARE(datetimeTz.timeType(), KDateTime::TimeZone);
0521     QVERIFY(!datetimeTz.isUtc());
0522     QVERIFY(!datetimeTz.isOffsetFromUtc());
0523     QVERIFY(!datetimeTz.isLocalZone());
0524     QVERIFY(!datetimeTz.isClockTime());
0525     QCOMPARE(datetimeTz.utcOffset(), 0);
0526     QCOMPARE(datetimeTz.timeZone(), london);
0527     QCOMPARE(datetimeTz.dateTime(), dtLocal);
0528 
0529     KDateTime datetimeTz2(dtUTC, london);
0530     QVERIFY(!datetimeTz2.isNull());
0531     QVERIFY(datetimeTz2.isValid());
0532     QVERIFY(!dateTimeTz.isDateOnly());
0533     QCOMPARE(datetimeTz2.timeType(), KDateTime::TimeZone);
0534     QVERIFY(!datetimeTz2.isUtc());
0535     QVERIFY(!datetimeTz2.isOffsetFromUtc());
0536     QVERIFY(!datetimeTz2.isLocalZone());
0537     QVERIFY(!datetimeTz2.isClockTime());
0538     QCOMPARE(datetimeTz2.utcOffset(), 0);
0539     QCOMPARE(datetimeTz2.timeZone(), london);
0540     QCOMPARE(datetimeTz2.dateTime(), dtUTCtoLondon);
0541 
0542     // ... copy constructor
0543     KDateTime datetimeTzCopy(datetimeTz);
0544     QVERIFY(!datetimeTzCopy.isNull());
0545     QVERIFY(datetimeTzCopy.isValid());
0546     QVERIFY(!dateTimeTz.isDateOnly());
0547     QCOMPARE(datetimeTzCopy.timeType(), KDateTime::TimeZone);
0548     QVERIFY(!datetimeTzCopy.isUtc());
0549     QVERIFY(!datetimeTzCopy.isOffsetFromUtc());
0550     QVERIFY(!datetimeTzCopy.isLocalZone());
0551     QVERIFY(!datetimeTzCopy.isClockTime());
0552     QCOMPARE(datetimeTzCopy.utcOffset(), 0);
0553     QCOMPARE(datetimeTzCopy.timeZone(), datetimeTz.timeZone());
0554     QCOMPARE(datetimeTzCopy.dateTime(), datetimeTz.dateTime());
0555 
0556     // UTC
0557     KDateTime date_UTC(d, KDateTime::Spec::UTC());
0558     QVERIFY(!date_UTC.isNull());
0559     QVERIFY(date_UTC.isValid());
0560     QVERIFY(date_UTC.isDateOnly());
0561     QCOMPARE(date_UTC.timeType(), KDateTime::UTC);
0562     QVERIFY(date_UTC.isUtc());
0563     QVERIFY(!date_UTC.isOffsetFromUtc());
0564     QVERIFY(!date_UTC.isLocalZone());
0565     QVERIFY(!date_UTC.isClockTime());
0566     QCOMPARE(date_UTC.utcOffset(), 0);
0567     QCOMPARE(date_UTC.timeZone(), KTimeZone::utc());
0568     QCOMPARE(date_UTC.dateTime(), QDateTime(d, QTime(0, 0, 0), Qt::UTC));
0569 
0570     KDateTime dateTime_UTC(d, t, KDateTime::UTC);
0571     QVERIFY(!dateTime_UTC.isNull());
0572     QVERIFY(dateTime_UTC.isValid());
0573     QVERIFY(!dateTime_UTC.isDateOnly());
0574     QCOMPARE(dateTime_UTC.timeType(), KDateTime::UTC);
0575     QVERIFY(dateTime_UTC.isUtc());
0576     QVERIFY(!dateTime_UTC.isOffsetFromUtc());
0577     QVERIFY(!dateTime_UTC.isLocalZone());
0578     QVERIFY(!dateTime_UTC.isClockTime());
0579     QCOMPARE(dateTime_UTC.utcOffset(), 0);
0580     QCOMPARE(dateTime_UTC.timeZone(), KTimeZone::utc());
0581     QCOMPARE(dateTime_UTC.dateTime(), QDateTime(d, t, Qt::UTC));
0582 
0583     KDateTime datetime_UTC(dtLocal, KDateTime::UTC);
0584     QVERIFY(!datetime_UTC.isNull());
0585     QVERIFY(datetime_UTC.isValid());
0586     QVERIFY(!datetime_UTC.isDateOnly());
0587     QCOMPARE(datetime_UTC.timeType(), KDateTime::UTC);
0588     QVERIFY(datetime_UTC.isUtc());
0589     QVERIFY(!datetime_UTC.isOffsetFromUtc());
0590     QVERIFY(!datetime_UTC.isLocalZone());
0591     QVERIFY(!datetime_UTC.isClockTime());
0592     QCOMPARE(datetime_UTC.utcOffset(), 0);
0593     QCOMPARE(datetime_UTC.timeZone(), KTimeZone::utc());
0594     QCOMPARE(datetime_UTC.dateTime(), dtLocal.toUTC());
0595 
0596     KDateTime datetime_UTC2(dtUTC, KDateTime::UTC);
0597     QVERIFY(!datetime_UTC2.isNull());
0598     QVERIFY(datetime_UTC2.isValid());
0599     QVERIFY(!datetime_UTC2.isDateOnly());
0600     QCOMPARE(datetime_UTC2.timeType(), KDateTime::UTC);
0601     QVERIFY(datetime_UTC2.isUtc());
0602     QVERIFY(!datetime_UTC2.isOffsetFromUtc());
0603     QVERIFY(!datetime_UTC2.isLocalZone());
0604     QVERIFY(!datetime_UTC2.isClockTime());
0605     QCOMPARE(datetime_UTC2.utcOffset(), 0);
0606     QCOMPARE(datetime_UTC2.timeZone(), KTimeZone::utc());
0607     QCOMPARE(datetime_UTC2.dateTime(), dtUTC);
0608     QCOMPARE(datetime_UTC2.date(), dtUTC.date());
0609     QCOMPARE(datetime_UTC2.time(), dtUTC.time());
0610 
0611     // ... copy constructor
0612     KDateTime datetime_UTCCopy(datetime_UTC);
0613     QVERIFY(!datetime_UTCCopy.isNull());
0614     QVERIFY(datetime_UTCCopy.isValid());
0615     QVERIFY(!datetime_UTCCopy.isDateOnly());
0616     QCOMPARE(datetime_UTCCopy.timeType(), KDateTime::UTC);
0617     QVERIFY(datetime_UTCCopy.isUtc());
0618     QVERIFY(!datetime_UTCCopy.isOffsetFromUtc());
0619     QVERIFY(!datetime_UTCCopy.isLocalZone());
0620     QVERIFY(!datetime_UTCCopy.isClockTime());
0621     QCOMPARE(datetime_UTCCopy.utcOffset(), 0);
0622     QCOMPARE(datetime_UTCCopy.timeZone(), datetime_UTC.timeZone());
0623     QCOMPARE(datetime_UTCCopy.dateTime(), datetime_UTC.dateTime());
0624 
0625     // Offset from UTC
0626     KDateTime date_OffsetFromUTC(d, KDateTime::Spec::OffsetFromUTC(-2 * 3600));
0627     QVERIFY(!date_OffsetFromUTC.isNull());
0628     QVERIFY(date_OffsetFromUTC.isValid());
0629     QVERIFY(date_OffsetFromUTC.isDateOnly());
0630     QCOMPARE(date_OffsetFromUTC.timeType(), KDateTime::OffsetFromUTC);
0631     QVERIFY(!date_OffsetFromUTC.isUtc());
0632     QVERIFY(date_OffsetFromUTC.isOffsetFromUtc());
0633     QVERIFY(!date_OffsetFromUTC.isLocalZone());
0634     QVERIFY(!date_OffsetFromUTC.isClockTime());
0635     QCOMPARE(date_OffsetFromUTC.utcOffset(), -2 * 3600);
0636     QVERIFY(!date_OffsetFromUTC.timeZone().isValid());
0637     QCOMPARE(date_OffsetFromUTC.dateTime(), QDateTime(d, QTime(0, 0, 0), Qt::LocalTime));
0638 
0639     KDateTime dateTime_OffsetFromUTC(d, t, KDateTime::Spec::OffsetFromUTC(2 * 3600));
0640     QVERIFY(!dateTime_OffsetFromUTC.isNull());
0641     QVERIFY(dateTime_OffsetFromUTC.isValid());
0642     QVERIFY(!dateTime_OffsetFromUTC.isDateOnly());
0643     QCOMPARE(dateTime_OffsetFromUTC.timeType(), KDateTime::OffsetFromUTC);
0644     QVERIFY(!dateTime_OffsetFromUTC.isUtc());
0645     QVERIFY(dateTime_OffsetFromUTC.isOffsetFromUtc());
0646     QVERIFY(!dateTime_OffsetFromUTC.isLocalZone());
0647     QVERIFY(!dateTime_OffsetFromUTC.isClockTime());
0648     QCOMPARE(dateTime_OffsetFromUTC.utcOffset(), 2 * 3600);
0649     QVERIFY(!dateTime_OffsetFromUTC.timeZone().isValid());
0650     QCOMPARE(dateTime_OffsetFromUTC.dateTime(), QDateTime(d, t, Qt::LocalTime));
0651 
0652     KDateTime datetime_OffsetFromUTC(dtLocal, KDateTime::Spec::OffsetFromUTC(-2 * 3600));
0653     QVERIFY(!datetime_OffsetFromUTC.isNull());
0654     QVERIFY(datetime_OffsetFromUTC.isValid());
0655     QVERIFY(!datetime_OffsetFromUTC.isDateOnly());
0656     QCOMPARE(datetime_OffsetFromUTC.timeType(), KDateTime::OffsetFromUTC);
0657     QVERIFY(!datetime_OffsetFromUTC.isUtc());
0658     QVERIFY(datetime_OffsetFromUTC.isOffsetFromUtc());
0659     QVERIFY(!datetime_OffsetFromUTC.isLocalZone());
0660     QVERIFY(!datetime_OffsetFromUTC.isClockTime());
0661     QCOMPARE(datetime_OffsetFromUTC.utcOffset(), -2 * 3600);
0662     QVERIFY(!datetime_OffsetFromUTC.timeZone().isValid());
0663     QCOMPARE(datetime_OffsetFromUTC.dateTime(), dtLocal);
0664     QCOMPARE(datetime_OffsetFromUTC.date(), dtLocal.date());
0665     QCOMPARE(datetime_OffsetFromUTC.time(), dtLocal.time());
0666 
0667     KDateTime datetime_OffsetFromUTC2(dtUTC, KDateTime::Spec::OffsetFromUTC(2 * 3600));
0668     QVERIFY(!datetime_OffsetFromUTC2.isNull());
0669     QVERIFY(datetime_OffsetFromUTC2.isValid());
0670     QVERIFY(!datetime_OffsetFromUTC2.isDateOnly());
0671     QCOMPARE(datetime_OffsetFromUTC2.timeType(), KDateTime::OffsetFromUTC);
0672     QVERIFY(!datetime_OffsetFromUTC2.isUtc());
0673     QVERIFY(datetime_OffsetFromUTC2.isOffsetFromUtc());
0674     QVERIFY(!datetime_OffsetFromUTC2.isLocalZone());
0675     QVERIFY(!datetime_OffsetFromUTC2.isClockTime());
0676     QCOMPARE(datetime_OffsetFromUTC2.utcOffset(), 2 * 3600);
0677     QVERIFY(!datetime_OffsetFromUTC2.timeZone().isValid());
0678     QDateTime dtof = dtUTC.addSecs(2 * 3600);
0679     dtof.setTimeSpec(Qt::LocalTime);
0680     QCOMPARE(datetime_OffsetFromUTC2.dateTime(), dtof);
0681 
0682     // ... copy constructor
0683     KDateTime datetime_OffsetFromUTCCopy(datetime_OffsetFromUTC);
0684     QVERIFY(!datetime_OffsetFromUTCCopy.isNull());
0685     QVERIFY(datetime_OffsetFromUTCCopy.isValid());
0686     QVERIFY(!datetime_OffsetFromUTCCopy.isDateOnly());
0687     QCOMPARE(datetime_OffsetFromUTCCopy.timeType(), KDateTime::OffsetFromUTC);
0688     QVERIFY(!datetime_OffsetFromUTCCopy.isUtc());
0689     QVERIFY(datetime_OffsetFromUTCCopy.isOffsetFromUtc());
0690     QVERIFY(!datetime_OffsetFromUTCCopy.isLocalZone());
0691     QVERIFY(!datetime_OffsetFromUTCCopy.isClockTime());
0692     QCOMPARE(datetime_OffsetFromUTCCopy.utcOffset(), -2 * 3600);
0693     QVERIFY(!datetime_OffsetFromUTCCopy.timeZone().isValid());
0694     QCOMPARE(datetime_OffsetFromUTCCopy.dateTime(), datetime_OffsetFromUTC.dateTime());
0695 
0696     // Local time zone
0697     KDateTime date_LocalZone(d, KDateTime::Spec::LocalZone());
0698     QVERIFY(!date_LocalZone.isNull());
0699     QVERIFY(date_LocalZone.isValid());
0700     QVERIFY(date_LocalZone.isDateOnly());
0701     QCOMPARE(date_LocalZone.timeType(), KDateTime::TimeZone);
0702     QCOMPARE(date_LocalZone.timeSpec(), KDateTime::Spec::LocalZone());
0703     QVERIFY(!date_LocalZone.isUtc());
0704     QVERIFY(!date_LocalZone.isOffsetFromUtc());
0705     QVERIFY(date_LocalZone.isLocalZone());
0706     QVERIFY(!date_LocalZone.isClockTime());
0707     QCOMPARE(date_LocalZone.utcOffset(), -8 * 3600);
0708     QCOMPARE(date_LocalZone.timeZone(), KSystemTimeZones::local());
0709     QCOMPARE(date_LocalZone.dateTime(), QDateTime(d, QTime(0, 0, 0), Qt::LocalTime));
0710 
0711     KDateTime dateTime_LocalZone(d, t, KDateTime::LocalZone);
0712     QVERIFY(!dateTime_LocalZone.isNull());
0713     QVERIFY(dateTime_LocalZone.isValid());
0714     QVERIFY(!dateTime_LocalZone.isDateOnly());
0715     QCOMPARE(dateTime_LocalZone.timeType(), KDateTime::TimeZone);
0716     QCOMPARE(dateTime_LocalZone.timeSpec(), KDateTime::Spec::LocalZone());
0717     QVERIFY(!dateTime_LocalZone.isUtc());
0718     QVERIFY(!dateTime_LocalZone.isOffsetFromUtc());
0719     QVERIFY(dateTime_LocalZone.isLocalZone());
0720     QVERIFY(!dateTime_LocalZone.isClockTime());
0721     QCOMPARE(dateTime_LocalZone.utcOffset(), -8 * 3600);
0722     QCOMPARE(dateTime_LocalZone.timeZone(), KSystemTimeZones::local());
0723     QCOMPARE(dateTime_LocalZone.dateTime(), QDateTime(d, t, Qt::LocalTime));
0724 
0725     KDateTime datetime_LocalZone(dtLocal, KDateTime::LocalZone);
0726     QVERIFY(!datetime_LocalZone.isNull());
0727     QVERIFY(datetime_LocalZone.isValid());
0728     QVERIFY(!datetime_LocalZone.isDateOnly());
0729     QCOMPARE(datetime_LocalZone.timeType(), KDateTime::TimeZone);
0730     QCOMPARE(datetime_LocalZone.timeSpec(), KDateTime::Spec::LocalZone());
0731     QVERIFY(!datetime_LocalZone.isUtc());
0732     QVERIFY(!datetime_LocalZone.isOffsetFromUtc());
0733     QVERIFY(datetime_LocalZone.isLocalZone());
0734     QVERIFY(!datetime_LocalZone.isClockTime());
0735     QCOMPARE(datetime_LocalZone.utcOffset(), -8 * 3600);
0736     QCOMPARE(datetime_LocalZone.timeZone(), KSystemTimeZones::local());
0737     QCOMPARE(datetime_LocalZone.dateTime(), dtLocal);
0738     QCOMPARE(datetime_LocalZone.date(), dtLocal.date());
0739     QCOMPARE(datetime_LocalZone.time(), dtLocal.time());
0740 
0741     KDateTime datetime_LocalZone2(dtUTC, KDateTime::LocalZone);
0742     QVERIFY(!datetime_LocalZone2.isNull());
0743     QVERIFY(datetime_LocalZone2.isValid());
0744     QVERIFY(!datetime_LocalZone2.isDateOnly());
0745     QCOMPARE(datetime_LocalZone2.timeType(), KDateTime::TimeZone);
0746     QCOMPARE(datetime_LocalZone2.timeSpec(), KDateTime::Spec::LocalZone());
0747     QVERIFY(!datetime_LocalZone2.isUtc());
0748     QVERIFY(!datetime_LocalZone2.isOffsetFromUtc());
0749     QVERIFY(datetime_LocalZone2.isLocalZone());
0750     QVERIFY(!datetime_LocalZone2.isClockTime());
0751     QCOMPARE(datetime_LocalZone2.utcOffset(), -8 * 3600);
0752     QCOMPARE(datetime_LocalZone2.timeZone(), KSystemTimeZones::local());
0753     QCOMPARE(datetime_LocalZone2.dateTime(), dtUTC.toLocalTime());
0754 
0755     // ... copy constructor
0756     KDateTime datetime_LocalZoneCopy(datetime_LocalZone);
0757     QVERIFY(!datetime_LocalZoneCopy.isNull());
0758     QVERIFY(datetime_LocalZoneCopy.isValid());
0759     QVERIFY(!datetime_LocalZoneCopy.isDateOnly());
0760     QCOMPARE(datetime_LocalZoneCopy.timeType(), KDateTime::TimeZone);
0761     QCOMPARE(datetime_LocalZoneCopy.timeSpec(), KDateTime::Spec::LocalZone());
0762     QVERIFY(!datetime_LocalZoneCopy.isUtc());
0763     QVERIFY(!datetime_LocalZoneCopy.isOffsetFromUtc());
0764     QVERIFY(datetime_LocalZoneCopy.isLocalZone());
0765     QVERIFY(!datetime_LocalZoneCopy.isClockTime());
0766     QCOMPARE(datetime_LocalZoneCopy.utcOffset(), -8 * 3600);
0767     QCOMPARE(datetime_LocalZoneCopy.timeZone(), datetime_LocalZone.timeZone());
0768     QCOMPARE(datetime_LocalZoneCopy.dateTime(), datetime_LocalZone.dateTime());
0769 
0770     // Local clock time
0771     KDateTime date_ClockTime(d, KDateTime::Spec::ClockTime());
0772     QVERIFY(!date_ClockTime.isNull());
0773     QVERIFY(date_ClockTime.isValid());
0774     QVERIFY(date_ClockTime.isDateOnly());
0775     QCOMPARE(date_ClockTime.timeType(), KDateTime::ClockTime);
0776     QVERIFY(!date_ClockTime.isUtc());
0777     QVERIFY(!date_ClockTime.isOffsetFromUtc());
0778     QVERIFY(!date_ClockTime.isLocalZone());
0779     QVERIFY(date_ClockTime.isClockTime());
0780     QCOMPARE(date_ClockTime.utcOffset(), 0);
0781     QVERIFY(!date_ClockTime.timeZone().isValid());
0782     QCOMPARE(date_ClockTime.dateTime(), QDateTime(d, QTime(0, 0, 0), Qt::LocalTime));
0783 
0784     KDateTime dateTime_ClockTime(d, t, KDateTime::ClockTime);
0785     QVERIFY(!dateTime_ClockTime.isNull());
0786     QVERIFY(dateTime_ClockTime.isValid());
0787     QVERIFY(!dateTime_ClockTime.isDateOnly());
0788     QCOMPARE(dateTime_ClockTime.timeType(), KDateTime::ClockTime);
0789     QVERIFY(!dateTime_ClockTime.isUtc());
0790     QVERIFY(!dateTime_ClockTime.isOffsetFromUtc());
0791     QVERIFY(!dateTime_ClockTime.isLocalZone());
0792     QVERIFY(dateTime_ClockTime.isClockTime());
0793     QCOMPARE(dateTime_ClockTime.utcOffset(), 0);
0794     QVERIFY(!dateTime_ClockTime.timeZone().isValid());
0795     QCOMPARE(dateTime_ClockTime.dateTime(), QDateTime(d, t, Qt::LocalTime));
0796 
0797     KDateTime datetime_ClockTime(dtLocal, KDateTime::ClockTime);
0798     QVERIFY(!datetime_ClockTime.isNull());
0799     QVERIFY(datetime_ClockTime.isValid());
0800     QVERIFY(!datetime_ClockTime.isDateOnly());
0801     QCOMPARE(datetime_ClockTime.timeType(), KDateTime::ClockTime);
0802     QVERIFY(!datetime_ClockTime.isUtc());
0803     QVERIFY(!datetime_ClockTime.isOffsetFromUtc());
0804     QVERIFY(!datetime_ClockTime.isLocalZone());
0805     QVERIFY(datetime_ClockTime.isClockTime());
0806     QCOMPARE(datetime_ClockTime.utcOffset(), 0);
0807     QVERIFY(!datetime_ClockTime.timeZone().isValid());
0808     QCOMPARE(datetime_ClockTime.dateTime(), dtLocal);
0809     QCOMPARE(datetime_ClockTime.date(), dtLocal.date());
0810     QCOMPARE(datetime_ClockTime.time(), dtLocal.time());
0811 
0812     KDateTime datetime_ClockTime1(dtLocal2, KDateTime::ClockTime);
0813     QVERIFY(!datetime_ClockTime1.isNull());
0814     QVERIFY(datetime_ClockTime1.isValid());
0815     QVERIFY(!datetime_ClockTime1.isDateOnly());
0816     QCOMPARE(datetime_ClockTime1.timeType(), KDateTime::ClockTime);
0817     QVERIFY(!datetime_ClockTime1.isUtc());
0818     QVERIFY(!datetime_ClockTime1.isOffsetFromUtc());
0819     QVERIFY(!datetime_ClockTime1.isLocalZone());
0820     QVERIFY(datetime_ClockTime1.isClockTime());
0821     QCOMPARE(datetime_ClockTime1.utcOffset(), 0);
0822     QVERIFY(!datetime_ClockTime1.timeZone().isValid());
0823     QCOMPARE(datetime_ClockTime1.dateTime(), dtLocal2);
0824     QCOMPARE(datetime_ClockTime1.date(), dtLocal2.date());
0825     QCOMPARE(datetime_ClockTime1.time(), dtLocal2.time());
0826 
0827     KDateTime datetime_ClockTime2(dtUTC, KDateTime::ClockTime);
0828     QVERIFY(!datetime_ClockTime2.isNull());
0829     QVERIFY(datetime_ClockTime2.isValid());
0830     QVERIFY(!datetime_ClockTime2.isDateOnly());
0831     QCOMPARE(datetime_ClockTime2.timeType(), KDateTime::ClockTime);
0832     QVERIFY(!datetime_ClockTime2.isUtc());
0833     QVERIFY(!datetime_ClockTime2.isOffsetFromUtc());
0834     QVERIFY(!datetime_ClockTime2.isLocalZone());
0835     QVERIFY(datetime_ClockTime2.isClockTime());
0836     QCOMPARE(datetime_ClockTime2.utcOffset(), 0);
0837     QVERIFY(!datetime_ClockTime2.timeZone().isValid());
0838     QCOMPARE(datetime_ClockTime2.dateTime(), dtUTC.toLocalTime());
0839 
0840     // ... copy constructor
0841     KDateTime datetime_ClockTimeCopy(datetime_ClockTime);
0842     QVERIFY(!datetime_ClockTimeCopy.isNull());
0843     QVERIFY(datetime_ClockTimeCopy.isValid());
0844     QVERIFY(!datetime_ClockTimeCopy.isDateOnly());
0845     QCOMPARE(datetime_ClockTimeCopy.timeType(), KDateTime::ClockTime);
0846     QVERIFY(!datetime_ClockTimeCopy.isUtc());
0847     QVERIFY(!datetime_ClockTimeCopy.isOffsetFromUtc());
0848     QVERIFY(!datetime_ClockTimeCopy.isLocalZone());
0849     QVERIFY(datetime_ClockTimeCopy.isClockTime());
0850     QCOMPARE(datetime_ClockTimeCopy.utcOffset(), 0);
0851     QVERIFY(!datetime_ClockTimeCopy.timeZone().isValid());
0852     QCOMPARE(datetime_ClockTimeCopy.dateTime(), datetime_ClockTime.dateTime());
0853 
0854     // Invalid time zone specification for a constructor
0855     KDateTime date_TimeZone(d, KDateTime::Spec(KDateTime::TimeZone));
0856     QVERIFY(!date_TimeZone.isValid());
0857     KDateTime dateTime_TimeZone(d, t, KDateTime::Spec(KDateTime::TimeZone));
0858     QVERIFY(!dateTime_TimeZone.isValid());
0859     KDateTime datetime_TimeZone(dtLocal, KDateTime::Spec(KDateTime::TimeZone));
0860     QVERIFY(!datetime_TimeZone.isValid());
0861     KDateTime datetime_Invalid(dtLocal, KDateTime::Spec(KDateTime::Invalid));
0862     QVERIFY(!datetime_Invalid.isValid());
0863 
0864     // Restore the original local time zone
0865     if (originalZone.isEmpty()) {
0866         ::unsetenv("TZ");
0867     } else {
0868         qputenv("TZ", originalZone);
0869     }
0870     ::tzset();
0871 }
0872 
0873 ///////////////////////////////////
0874 // Time conversion and operator==()
0875 ///////////////////////////////////
0876 
0877 void KDateTimeTest::toUtc()
0878 {
0879     KTimeZone london = KSystemTimeZones::zone("Europe/London");
0880 
0881     // Ensure that local time is different from UTC and different from 'london'
0882     QByteArray originalZone = qgetenv("TZ");   // save the original local time zone
0883     qputenv("TZ", ":America/Los_Angeles");
0884     ::tzset();
0885 
0886     // Zone -> UTC
0887     KDateTime londonWinter(QDate(2005, 1, 1), QTime(0, 0, 0), london);
0888     KDateTime utcWinter = londonWinter.toUtc();
0889     QVERIFY(utcWinter.isUtc());
0890     QCOMPARE(utcWinter.dateTime(), QDateTime(QDate(2005, 1, 1), QTime(0, 0, 0), Qt::UTC));
0891     QVERIFY(londonWinter == utcWinter);
0892     KDateTime londonSummer(QDate(2005, 6, 1), QTime(0, 0, 0), london);
0893     KDateTime utcSummer = londonSummer.toUtc();
0894     QVERIFY(utcSummer.isUtc());
0895     QCOMPARE(utcSummer.dateTime(), QDateTime(QDate(2005, 5, 31), QTime(23, 0, 0), Qt::UTC));
0896     QVERIFY(londonSummer == utcSummer);
0897     QVERIFY(!(londonSummer == utcWinter));
0898     QVERIFY(!(londonWinter == utcSummer));
0899 
0900     // UTC offset -> UTC
0901     KDateTime offset(QDate(2005, 6, 6), QTime(1, 2, 30), KDateTime::Spec::OffsetFromUTC(-5400)); // -0130
0902     KDateTime utcOffset = offset.toUtc();
0903     QVERIFY(utcOffset.isUtc());
0904     QCOMPARE(utcOffset.dateTime(), QDateTime(QDate(2005, 6, 6), QTime(2, 32, 30), Qt::UTC));
0905     QVERIFY(offset == utcOffset);
0906     QVERIFY(!(offset == utcSummer));
0907 
0908     // Clock time -> UTC
0909     KDateTime clock(QDate(2005, 6, 6), QTime(1, 2, 30), KDateTime::ClockTime);
0910     KDateTime utcClock = clock.toUtc();
0911     QVERIFY(utcClock.isUtc());
0912     QCOMPARE(utcClock.dateTime(), QDateTime(QDate(2005, 6, 6), QTime(8, 2, 30), Qt::UTC));
0913     QVERIFY(clock == utcClock);
0914     QVERIFY(!(clock == utcOffset));
0915 
0916     // UTC -> UTC
0917     KDateTime utc(QDate(2005, 6, 6), QTime(1, 2, 30), KDateTime::UTC);
0918     KDateTime utcUtc = utc.toUtc();
0919     QVERIFY(utcUtc.isUtc());
0920     QCOMPARE(utcUtc.dateTime(), QDateTime(QDate(2005, 6, 6), QTime(1, 2, 30), Qt::UTC));
0921     QVERIFY(utc == utcUtc);
0922     QVERIFY(!(utc == utcClock));
0923 
0924     // ** Date only ** //
0925 
0926     // Zone -> UTC
0927     londonSummer.setDateOnly(true);
0928     utcSummer = londonSummer.toUtc();
0929     QVERIFY(utcSummer.isDateOnly());
0930     QCOMPARE(utcSummer.dateTime(), QDateTime(QDate(2005, 6, 1), QTime(0, 0, 0), Qt::UTC));
0931     QVERIFY(utcSummer != londonSummer);
0932     QVERIFY(!(utcSummer == londonSummer));
0933     londonWinter.setDateOnly(true);
0934     utcWinter = londonWinter.toUtc();
0935     QVERIFY(utcWinter == londonWinter);
0936     QVERIFY(!(utcWinter != londonWinter));
0937 
0938     // UTC offset -> UTC
0939     offset.setDateOnly(true);
0940     utcOffset = offset.toUtc();
0941     QVERIFY(utcOffset.isDateOnly());
0942     QCOMPARE(utcOffset.dateTime(), QDateTime(QDate(2005, 6, 6), QTime(0, 0, 0), Qt::UTC));
0943     QVERIFY(offset != utcOffset);
0944     QVERIFY(!(offset == utcOffset));
0945     KDateTime utcOffset1(QDate(2005, 6, 6), KDateTime::Spec::OffsetFromUTC(0));
0946     QVERIFY(utcOffset1 == utcOffset1.toUtc());
0947 
0948     // Clock time -> UTC
0949     clock.setDateOnly(true);
0950     utcClock = clock.toUtc();
0951     QVERIFY(utcClock.isDateOnly());
0952     QCOMPARE(utcClock.dateTime(), QDateTime(QDate(2005, 6, 6), QTime(0, 0, 0), Qt::UTC));
0953     QVERIFY(clock != utcClock);
0954     QVERIFY(!(clock == utcClock));
0955 
0956     // UTC -> UTC
0957     utc.setDateOnly(true);
0958     utcUtc = utc.toUtc();
0959     QVERIFY(utcUtc.isDateOnly());
0960     QCOMPARE(utcUtc.dateTime(), QDateTime(QDate(2005, 6, 6), QTime(0, 0, 0), Qt::UTC));
0961     QVERIFY(utc == utcUtc);
0962     QVERIFY(!(utc != utcUtc));
0963 
0964     // Restore the original local time zone
0965     if (originalZone.isEmpty()) {
0966         ::unsetenv("TZ");
0967     } else {
0968         qputenv("TZ", originalZone);
0969     }
0970     ::tzset();
0971 }
0972 
0973 void KDateTimeTest::toOffsetFromUtc()
0974 {
0975     KTimeZone london = KSystemTimeZones::zone("Europe/London");
0976 
0977     // Ensure that local time is different from UTC and different from 'london'
0978     QByteArray originalZone = qgetenv("TZ");   // save the original local time zone
0979     qputenv("TZ", ":America/Los_Angeles");
0980     ::tzset();
0981 
0982     // ***** toOffsetFromUtc(void) *****
0983 
0984     // Zone -> UTC offset
0985     KDateTime londonWinter(QDate(2005, 1, 1), QTime(2, 0, 0), london);
0986     KDateTime offsetWinter = londonWinter.toOffsetFromUtc();
0987     QVERIFY(offsetWinter.isOffsetFromUtc());
0988     QCOMPARE(offsetWinter.utcOffset(), 0);
0989     QCOMPARE(offsetWinter.dateTime(), QDateTime(QDate(2005, 1, 1), QTime(2, 0, 0), Qt::LocalTime));
0990     QVERIFY(londonWinter == offsetWinter);
0991     KDateTime londonSummer(QDate(2005, 6, 1), QTime(14, 0, 0), london);
0992     KDateTime offsetSummer = londonSummer.toOffsetFromUtc();
0993     QVERIFY(offsetSummer.isOffsetFromUtc());
0994     QCOMPARE(offsetSummer.utcOffset(), 3600);
0995     QCOMPARE(offsetSummer.dateTime(), QDateTime(QDate(2005, 6, 1), QTime(14, 0, 0), Qt::LocalTime));
0996     QVERIFY(londonSummer == offsetSummer);
0997     QVERIFY(!(londonSummer == offsetWinter));
0998     QVERIFY(!(londonWinter == offsetSummer));
0999 
1000     // UTC offset -> UTC offset
1001     KDateTime offset(QDate(2005, 6, 6), QTime(11, 2, 30), KDateTime::Spec::OffsetFromUTC(-5400)); // -0130
1002     KDateTime offsetOffset = offset.toOffsetFromUtc();
1003     QVERIFY(offsetOffset.isOffsetFromUtc());
1004     QCOMPARE(offsetOffset.utcOffset(), -5400);
1005     QCOMPARE(offsetOffset.dateTime(), QDateTime(QDate(2005, 6, 6), QTime(11, 2, 30), Qt::LocalTime));
1006     QVERIFY(offset == offsetOffset);
1007     QVERIFY(!(offset == offsetSummer));
1008 
1009     // Clock time -> UTC offset
1010     KDateTime clock(QDate(2005, 6, 6), QTime(1, 2, 30), KDateTime::ClockTime);
1011     KDateTime offsetClock = clock.toOffsetFromUtc();
1012     QVERIFY(offsetClock.isOffsetFromUtc());
1013     QCOMPARE(offsetClock.utcOffset(), -7 * 3600);
1014     QCOMPARE(offsetClock.dateTime(), QDateTime(QDate(2005, 6, 6), QTime(1, 2, 30), Qt::LocalTime));
1015     QVERIFY(clock == offsetClock);
1016     QVERIFY(!(clock == offsetOffset));
1017 
1018     // UTC -> UTC offset
1019     KDateTime utc(QDate(2005, 6, 6), QTime(11, 2, 30), KDateTime::UTC);
1020     KDateTime offsetUtc = utc.toOffsetFromUtc();
1021     QVERIFY(offsetUtc.isOffsetFromUtc());
1022     QCOMPARE(offsetUtc.utcOffset(), 0);
1023     QCOMPARE(offsetUtc.dateTime(), QDateTime(QDate(2005, 6, 6), QTime(11, 2, 30), Qt::LocalTime));
1024     QVERIFY(utc == offsetUtc);
1025     QVERIFY(!(utc == offsetClock));
1026 
1027     // ** Date only ** //
1028 
1029     // Zone -> UTC offset
1030     londonSummer.setDateOnly(true);
1031     offsetSummer = londonSummer.toOffsetFromUtc();
1032     QVERIFY(offsetSummer.isDateOnly());
1033     QVERIFY(offsetSummer.isOffsetFromUtc());
1034     QCOMPARE(offsetSummer.utcOffset(), 3600);
1035     QCOMPARE(offsetSummer.dateTime(), QDateTime(QDate(2005, 6, 1), QTime(0, 0, 0), Qt::LocalTime));
1036     QVERIFY(offsetSummer == londonSummer);
1037     QVERIFY(!(offsetSummer != londonSummer));
1038     londonWinter.setDateOnly(true);
1039     offsetWinter = londonWinter.toUtc();
1040     QVERIFY(offsetWinter == londonWinter);
1041     QVERIFY(!(offsetWinter != londonWinter));
1042 
1043     // UTC offset -> UTC offset
1044     offset.setDateOnly(true);
1045     offsetOffset = offset.toOffsetFromUtc();
1046     QVERIFY(offsetOffset.isDateOnly());
1047     QVERIFY(offsetOffset.isOffsetFromUtc());
1048     QCOMPARE(offsetOffset.utcOffset(), -5400);
1049     QCOMPARE(offsetOffset.dateTime(), QDateTime(QDate(2005, 6, 6), QTime(0, 0, 0), Qt::LocalTime));
1050     QVERIFY(offset == offsetOffset);
1051     QVERIFY(!(offset != offsetOffset));
1052 
1053     // Clock time -> UTC offset
1054     clock.setDateOnly(true);
1055     offsetClock = clock.toOffsetFromUtc();
1056     QVERIFY(offsetClock.isDateOnly());
1057     QVERIFY(offsetClock.isOffsetFromUtc());
1058     QCOMPARE(offsetClock.utcOffset(), -7 * 3600);
1059     QCOMPARE(offsetClock.dateTime(), QDateTime(QDate(2005, 6, 6), QTime(0, 0, 0), Qt::LocalTime));
1060     QVERIFY(clock == offsetClock);
1061     QVERIFY(!(clock != offsetClock));
1062 
1063     // UTC -> UTC offset
1064     utc.setDateOnly(true);
1065     offsetUtc = utc.toOffsetFromUtc();
1066     QVERIFY(offsetUtc.isDateOnly());
1067     QVERIFY(offsetUtc.isOffsetFromUtc());
1068     QCOMPARE(offsetUtc.utcOffset(), 0);
1069     QCOMPARE(offsetUtc.dateTime(), QDateTime(QDate(2005, 6, 6), QTime(0, 0, 0), Qt::LocalTime));
1070     QVERIFY(utc == offsetUtc);
1071     QVERIFY(!(utc != offsetUtc));
1072 
1073     // ***** toOffsetFromUtc(int utcOffset) *****
1074 
1075     // Zone -> UTC offset
1076     KDateTime londonWinter2(QDate(2005, 1, 1), QTime(2, 0, 0), london);
1077     offsetWinter = londonWinter2.toOffsetFromUtc(5400);    // +1H30M
1078     QVERIFY(offsetWinter.isOffsetFromUtc());
1079     QCOMPARE(offsetWinter.utcOffset(), 5400);
1080     QCOMPARE(offsetWinter.dateTime(), QDateTime(QDate(2005, 1, 1), QTime(3, 30, 0), Qt::LocalTime));
1081     QVERIFY(londonWinter2 == offsetWinter);
1082     KDateTime londonSummer2(QDate(2005, 6, 1), QTime(14, 0, 0), london);
1083     offsetSummer = londonSummer2.toOffsetFromUtc(5400);
1084     QVERIFY(offsetSummer.isOffsetFromUtc());
1085     QCOMPARE(offsetSummer.utcOffset(), 5400);
1086     QCOMPARE(offsetSummer.dateTime(), QDateTime(QDate(2005, 6, 1), QTime(14, 30, 0), Qt::LocalTime));
1087     QVERIFY(londonSummer2 == offsetSummer);
1088     QVERIFY(!(londonSummer2 == offsetWinter));
1089     QVERIFY(!(londonWinter2 == offsetSummer));
1090 
1091     // UTC offset -> UTC offset
1092     KDateTime offset2(QDate(2005, 6, 6), QTime(11, 2, 30), KDateTime::Spec::OffsetFromUTC(-5400)); // -0130
1093     offsetOffset = offset2.toOffsetFromUtc(3600);
1094     QVERIFY(offsetOffset.isOffsetFromUtc());
1095     QCOMPARE(offsetOffset.utcOffset(), 3600);
1096     QCOMPARE(offsetOffset.dateTime(), QDateTime(QDate(2005, 6, 6), QTime(13, 32, 30), Qt::LocalTime));
1097     QVERIFY(offset2 == offsetOffset);
1098     QVERIFY(!(offset2 == offsetSummer));
1099 
1100     // Clock time -> UTC offset
1101     KDateTime clock2(QDate(2005, 6, 6), QTime(1, 2, 30), KDateTime::ClockTime);
1102     offsetClock = clock2.toOffsetFromUtc(0);
1103     QVERIFY(offsetClock.isOffsetFromUtc());
1104     QCOMPARE(offsetClock.utcOffset(), 0);
1105     QCOMPARE(offsetClock.dateTime(), QDateTime(QDate(2005, 6, 6), QTime(8, 2, 30), Qt::LocalTime));
1106     QVERIFY(clock2 == offsetClock);
1107     QVERIFY(!(clock2 == offsetOffset));
1108 
1109     // UTC -> UTC offset
1110     KDateTime utc2(QDate(2005, 6, 6), QTime(11, 2, 30), KDateTime::UTC);
1111     offsetUtc = utc2.toOffsetFromUtc(-3600);
1112     QVERIFY(offsetUtc.isOffsetFromUtc());
1113     QCOMPARE(offsetUtc.utcOffset(), -3600);
1114     QCOMPARE(offsetUtc.dateTime(), QDateTime(QDate(2005, 6, 6), QTime(10, 2, 30), Qt::LocalTime));
1115     QVERIFY(utc2 == offsetUtc);
1116     QVERIFY(!(utc2 == offsetClock));
1117 
1118     // ** Date only ** //
1119 
1120     // Zone -> UTC offset
1121     londonSummer2.setDateOnly(true);
1122     offsetSummer = londonSummer2.toOffsetFromUtc(5400);
1123     QVERIFY(offsetSummer.isDateOnly());
1124     QVERIFY(offsetSummer.isOffsetFromUtc());
1125     QCOMPARE(offsetSummer.utcOffset(), 5400);
1126     QCOMPARE(offsetSummer.dateTime(), QDateTime(QDate(2005, 6, 1), QTime(0, 0, 0), Qt::LocalTime));
1127     QVERIFY(londonSummer2 != offsetSummer);
1128     QVERIFY(!(londonSummer2 == offsetSummer));
1129     QVERIFY(londonSummer2 == KDateTime(QDate(2005, 6, 1), KDateTime::Spec::OffsetFromUTC(3600)));
1130 
1131     // UTC offset -> UTC offset
1132     offset2.setDateOnly(true);
1133     offsetOffset = offset2.toOffsetFromUtc(-3600);
1134     QVERIFY(offsetOffset.isDateOnly());
1135     QVERIFY(offsetOffset.isOffsetFromUtc());
1136     QCOMPARE(offsetOffset.utcOffset(), -3600);
1137     QCOMPARE(offsetOffset.dateTime(), QDateTime(QDate(2005, 6, 6), QTime(0, 0, 0), Qt::LocalTime));
1138     QVERIFY(offset2 != offsetOffset);
1139     QVERIFY(!(offset2 == offsetOffset));
1140 
1141     // Clock time -> UTC offset
1142     clock2.setDateOnly(true);
1143     offsetClock = clock2.toOffsetFromUtc(6 * 3600);
1144     QVERIFY(offsetClock.isDateOnly());
1145     QVERIFY(offsetClock.isOffsetFromUtc());
1146     QCOMPARE(offsetClock.utcOffset(), 6 * 3600);
1147     QCOMPARE(offsetClock.dateTime(), QDateTime(QDate(2005, 6, 6), QTime(0, 0, 0), Qt::LocalTime));
1148     QVERIFY(clock2 != offsetClock);
1149     QVERIFY(!(clock2 == offsetClock));
1150     QVERIFY(clock == KDateTime(QDate(2005, 6, 6), KDateTime::Spec::OffsetFromUTC(-7 * 3600)));
1151 
1152     // UTC -> UTC offset
1153     utc2.setDateOnly(true);
1154     offsetUtc = utc2.toOffsetFromUtc(1800);
1155     QVERIFY(offsetUtc.isDateOnly());
1156     QVERIFY(offsetUtc.isOffsetFromUtc());
1157     QCOMPARE(offsetUtc.utcOffset(), 1800);
1158     QCOMPARE(offsetUtc.dateTime(), QDateTime(QDate(2005, 6, 6), QTime(0, 0, 0), Qt::LocalTime));
1159     QVERIFY(utc2 != offsetUtc);
1160     QVERIFY(!(utc2 == offsetUtc));
1161     QVERIFY(utc2 == KDateTime(QDate(2005, 6, 6), KDateTime::Spec::OffsetFromUTC(0)));
1162 
1163     // Restore the original local time zone
1164     if (originalZone.isEmpty()) {
1165         ::unsetenv("TZ");
1166     } else {
1167         qputenv("TZ", originalZone);
1168     }
1169     ::tzset();
1170 }
1171 
1172 void KDateTimeTest::toLocalZone()
1173 {
1174     KTimeZone london = KSystemTimeZones::zone("Europe/London");
1175 
1176     // Ensure that local time is different from UTC and different from 'london'
1177     QByteArray originalZone = qgetenv("TZ");   // save the original local time zone
1178     qputenv("TZ", ":America/Los_Angeles");
1179     ::tzset();
1180 
1181     // Zone -> LocalZone
1182     KDateTime londonWinter(QDate(2005, 1, 1), QTime(0, 0, 0), london);
1183     KDateTime locWinter = londonWinter.toLocalZone();
1184     QVERIFY(locWinter.isLocalZone());
1185     QCOMPARE(locWinter.dateTime(), QDateTime(QDate(2004, 12, 31), QTime(16, 0, 0), Qt::LocalTime));
1186     QVERIFY(londonWinter == locWinter);
1187     KDateTime londonSummer(QDate(2005, 6, 1), QTime(0, 0, 0), london);
1188     KDateTime locSummer = londonSummer.toLocalZone();
1189     QVERIFY(locSummer.isLocalZone());
1190     QCOMPARE(locSummer.dateTime(), QDateTime(QDate(2005, 5, 31), QTime(16, 0, 0), Qt::LocalTime));
1191     QVERIFY(londonSummer == locSummer);
1192     QVERIFY(!(londonSummer == locWinter));
1193     QVERIFY(!(londonWinter == locSummer));
1194 
1195     // UTC offset -> LocalZone
1196     KDateTime offset(QDate(2005, 6, 6), QTime(11, 2, 30), KDateTime::Spec::OffsetFromUTC(-5400)); // -0130
1197     KDateTime locOffset = offset.toLocalZone();
1198     QVERIFY(locOffset.isLocalZone());
1199     QCOMPARE(locOffset.dateTime(), QDateTime(QDate(2005, 6, 6), QTime(5, 32, 30), Qt::LocalTime));
1200     QVERIFY(offset == locOffset);
1201     QVERIFY(!(offset == locSummer));
1202 
1203     // Clock time -> LocalZone
1204     KDateTime clock(QDate(2005, 6, 6), QTime(1, 2, 30), KDateTime::ClockTime);
1205     KDateTime locClock = clock.toLocalZone();
1206     QVERIFY(locClock.isLocalZone());
1207     QCOMPARE(locClock.dateTime(), QDateTime(QDate(2005, 6, 6), QTime(1, 2, 30), Qt::LocalTime));
1208     QVERIFY(clock == locClock);
1209     QVERIFY(!(clock == locOffset));
1210 
1211     // UTC -> LocalZone
1212     KDateTime utc(QDate(2005, 6, 6), QTime(11, 2, 30), KDateTime::UTC);
1213     KDateTime locUtc = utc.toLocalZone();
1214     QVERIFY(locUtc.isLocalZone());
1215     QCOMPARE(locUtc.dateTime(), QDateTime(QDate(2005, 6, 6), QTime(4, 2, 30), Qt::LocalTime));
1216     QVERIFY(utc == locUtc);
1217     QVERIFY(!(utc == locClock));
1218 
1219     // ** Date only ** //
1220 
1221     // Zone -> LocalZone
1222     londonSummer.setDateOnly(true);
1223     locSummer = londonSummer.toLocalZone();
1224     QVERIFY(locSummer.isDateOnly());
1225     QCOMPARE(locSummer.dateTime(), QDateTime(QDate(2005, 6, 1), QTime(0, 0, 0), Qt::LocalTime));
1226     QVERIFY(londonSummer != locSummer);
1227     QVERIFY(!(londonSummer == locSummer));
1228 
1229     // UTC offset -> LocalZone
1230     offset.setDateOnly(true);
1231     locOffset = offset.toLocalZone();
1232     QVERIFY(locOffset.isDateOnly());
1233     QCOMPARE(locOffset.dateTime(), QDateTime(QDate(2005, 6, 6), QTime(0, 0, 0), Qt::LocalTime));
1234     QVERIFY(offset != locOffset);
1235     QVERIFY(!(offset == locOffset));
1236     QVERIFY(locOffset == KDateTime(QDate(2005, 6, 6), KDateTime::Spec::OffsetFromUTC(-7 * 3600)));
1237 
1238     // Clock time -> LocalZone
1239     clock.setDateOnly(true);
1240     locClock = clock.toLocalZone();
1241     QVERIFY(locClock.isDateOnly());
1242     QCOMPARE(locClock.dateTime(), QDateTime(QDate(2005, 6, 6), QTime(0, 0, 0), Qt::LocalTime));
1243     QVERIFY(clock == locClock);
1244     QVERIFY(!(clock != locClock));
1245 
1246     // UTC -> LocalZone
1247     utc.setDateOnly(true);
1248     locUtc = utc.toLocalZone();
1249     QVERIFY(locUtc.isDateOnly());
1250     QCOMPARE(locUtc.dateTime(), QDateTime(QDate(2005, 6, 6), QTime(0, 0, 0), Qt::LocalTime));
1251     QVERIFY(utc != locUtc);
1252     QVERIFY(!(utc == locUtc));
1253 
1254     // Restore the original local time zone
1255     if (originalZone.isEmpty()) {
1256         ::unsetenv("TZ");
1257     } else {
1258         qputenv("TZ", originalZone);
1259     }
1260     ::tzset();
1261 }
1262 
1263 void KDateTimeTest::toClockTime()
1264 {
1265     KTimeZone london = KSystemTimeZones::zone("Europe/London");
1266 
1267     // Ensure that local time is different from UTC and different from 'london'
1268     QByteArray originalZone = qgetenv("TZ");   // save the original local time zone
1269     qputenv("TZ", ":America/Los_Angeles");
1270     ::tzset();
1271 
1272     // Zone -> ClockTime
1273     KDateTime londonWinter(QDate(2005, 1, 1), QTime(0, 0, 0), london);
1274     KDateTime locWinter = londonWinter.toClockTime();
1275     QVERIFY(locWinter.isClockTime());
1276     QCOMPARE(locWinter.dateTime(), QDateTime(QDate(2004, 12, 31), QTime(16, 0, 0), Qt::LocalTime));
1277     QVERIFY(londonWinter == locWinter);
1278     KDateTime londonSummer(QDate(2005, 6, 1), QTime(0, 0, 0), london);
1279     KDateTime locSummer = londonSummer.toClockTime();
1280     QVERIFY(locSummer.isClockTime());
1281     QCOMPARE(locSummer.dateTime(), QDateTime(QDate(2005, 5, 31), QTime(16, 0, 0), Qt::LocalTime));
1282     QVERIFY(londonSummer == locSummer);
1283     QVERIFY(!(londonSummer == locWinter));
1284     QVERIFY(!(londonWinter == locSummer));
1285 
1286     // UTC offset -> ClockTime
1287     KDateTime offset(QDate(2005, 6, 6), QTime(11, 2, 30), KDateTime::Spec::OffsetFromUTC(-5400)); // -0130
1288     KDateTime locOffset = offset.toClockTime();
1289     QVERIFY(locOffset.isClockTime());
1290     QCOMPARE(locOffset.dateTime(), QDateTime(QDate(2005, 6, 6), QTime(5, 32, 30), Qt::LocalTime));
1291     QVERIFY(offset == locOffset);
1292     QVERIFY(!(offset == locSummer));
1293 
1294     // Clock time -> ClockTime
1295     KDateTime clock(QDate(2005, 6, 6), QTime(1, 2, 30), KDateTime::ClockTime);
1296     KDateTime locClock = clock.toClockTime();
1297     QVERIFY(locClock.isClockTime());
1298     QCOMPARE(locClock.dateTime(), QDateTime(QDate(2005, 6, 6), QTime(1, 2, 30), Qt::LocalTime));
1299     QVERIFY(clock == locClock);
1300     QVERIFY(!(clock == locOffset));
1301 
1302     // UTC -> ClockTime
1303     KDateTime utc(QDate(2005, 6, 6), QTime(11, 2, 30), KDateTime::UTC);
1304     KDateTime locUtc = utc.toClockTime();
1305     QVERIFY(locUtc.isClockTime());
1306     QCOMPARE(locUtc.dateTime(), QDateTime(QDate(2005, 6, 6), QTime(4, 2, 30), Qt::LocalTime));
1307     QVERIFY(utc == locUtc);
1308     QVERIFY(!(utc == locClock));
1309 
1310     // ** Date only ** //
1311 
1312     // Zone -> ClockTime
1313     londonSummer.setDateOnly(true);
1314     locSummer = londonSummer.toClockTime();
1315     QVERIFY(locSummer.isDateOnly());
1316     QCOMPARE(locSummer.dateTime(), QDateTime(QDate(2005, 6, 1), QTime(0, 0, 0), Qt::LocalTime));
1317     QVERIFY(londonSummer != locSummer);
1318     QVERIFY(!(londonSummer == locSummer));
1319 
1320     // UTC offset -> ClockTime
1321     offset.setDateOnly(true);
1322     locOffset = offset.toClockTime();
1323     QVERIFY(locOffset.isDateOnly());
1324     QCOMPARE(locOffset.dateTime(), QDateTime(QDate(2005, 6, 6), QTime(0, 0, 0), Qt::LocalTime));
1325     QVERIFY(offset != locOffset);
1326     QVERIFY(!(offset == locOffset));
1327     QVERIFY(locOffset == KDateTime(QDate(2005, 6, 6), KDateTime::Spec::OffsetFromUTC(-7 * 3600)));
1328 
1329     // Clock time -> ClockTime
1330     clock.setDateOnly(true);
1331     locClock = clock.toClockTime();
1332     QVERIFY(locClock.isDateOnly());
1333     QCOMPARE(locClock.dateTime(), QDateTime(QDate(2005, 6, 6), QTime(0, 0, 0), Qt::LocalTime));
1334     QVERIFY(clock == locClock);
1335     QVERIFY(!(clock != locClock));
1336 
1337     // UTC -> ClockTime
1338     utc.setDateOnly(true);
1339     locUtc = utc.toClockTime();
1340     QVERIFY(locUtc.isDateOnly());
1341     QCOMPARE(locUtc.dateTime(), QDateTime(QDate(2005, 6, 6), QTime(0, 0, 0), Qt::LocalTime));
1342     QVERIFY(utc != locUtc);
1343     QVERIFY(!(utc == locUtc));
1344 
1345     // Restore the original local time zone
1346     if (originalZone.isEmpty()) {
1347         ::unsetenv("TZ");
1348     } else {
1349         qputenv("TZ", originalZone);
1350     }
1351     ::tzset();
1352 }
1353 
1354 void KDateTimeTest::toZone()
1355 {
1356     QEventLoop loop;
1357     QTimer timer;
1358     timer.setSingleShot(true);
1359     QObject::connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
1360     QSignalSpy timeoutSpy(&timer, SIGNAL(timeout()));
1361 
1362     // This test relies on kded running, and on kdebase/runtime being installed
1363     if (!QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.kded5")) {
1364         QSKIP("kded not running");
1365     }
1366     QDBusInterface ktimezoned("org.kde.kded5", "/modules/ktimezoned", "org.kde.kded5.KTimeZoned");
1367     if (!ktimezoned.isValid()) {
1368         // Need to load the KDED time zones module
1369         QDBusInterface kded("org.kde.kded5", "/kded", "org.kde.kded5");
1370         QDBusReply<bool> reply = kded.call("loadModule", "ktimezoned");
1371         if (!reply.isValid() || !reply) {
1372             QSKIP("Could not load ktimezoned kded module");
1373         }
1374     }
1375 
1376     KTimeZone london = KSystemTimeZones::zone("Europe/London");
1377     KTimeZone losAngeles = KSystemTimeZones::zone("America/Los_Angeles");
1378 
1379     // Ensure that local time is different from UTC and different from 'london'
1380     KConfig config("ktimezonedrc");
1381     KConfigGroup group(&config, "TimeZones");
1382     group.writeEntry("LocalZone", QString::fromLatin1("Europe/London"));
1383     config.sync();
1384     QDBusMessage message = QDBusMessage::createSignal("/Daemon", "org.kde.KTimeZoned", "timeZoneChanged");
1385     QDBusConnection::sessionBus().send(message);
1386     timer.start(1000);
1387     loop.exec();
1388 
1389     // Zone -> Zone
1390     KDateTime londonWinter(QDate(2005, 1, 1), QTime(0, 0, 0), london);
1391     KDateTime locWinter = londonWinter.toZone(losAngeles);
1392     QCOMPARE(locWinter.timeZone(), losAngeles);
1393     QCOMPARE(locWinter.dateTime(), QDateTime(QDate(2004, 12, 31), QTime(16, 0, 0), Qt::LocalTime));
1394     QVERIFY(londonWinter == locWinter);
1395     KDateTime londonSummer(QDate(2005, 6, 1), QTime(0, 0, 0), london);
1396     KDateTime locSummer = londonSummer.toZone(losAngeles);
1397     QCOMPARE(locWinter.timeZone(), losAngeles);
1398     QCOMPARE(locSummer.dateTime(), QDateTime(QDate(2005, 5, 31), QTime(16, 0, 0), Qt::LocalTime));
1399     QVERIFY(londonSummer == locSummer);
1400     QVERIFY(!(londonSummer == locWinter));
1401     QVERIFY(!(londonWinter == locSummer));
1402 
1403     // UTC offset -> Zone
1404     KDateTime offset(QDate(2005, 6, 6), QTime(11, 2, 30), KDateTime::Spec::OffsetFromUTC(-5400)); // -0130
1405     KDateTime locOffset = offset.toZone(losAngeles);
1406     QCOMPARE(locOffset.timeZone(), losAngeles);
1407     QCOMPARE(locOffset.dateTime(), QDateTime(QDate(2005, 6, 6), QTime(5, 32, 30), Qt::LocalTime));
1408     QVERIFY(offset == locOffset);
1409     QVERIFY(!(offset == locSummer));
1410 
1411     // Clock time -> Zone
1412     KDateTime clock(QDate(2005, 6, 6), QTime(11, 2, 30), KDateTime::ClockTime);
1413     KDateTime locClock = clock.toZone(losAngeles);
1414     QCOMPARE(locClock.timeZone(), losAngeles);
1415     QCOMPARE(locClock.dateTime(), QDateTime(QDate(2005, 6, 6), QTime(3, 2, 30), Qt::LocalTime));
1416     QVERIFY(clock == locClock);
1417     QVERIFY(!(clock == locOffset));
1418 
1419     // UTC -> Zone
1420     KDateTime utc(QDate(2005, 6, 6), QTime(11, 2, 30), KDateTime::UTC);
1421     KDateTime locUtc = utc.toZone(losAngeles);
1422     QCOMPARE(locUtc.timeZone(), losAngeles);
1423     QCOMPARE(locUtc.dateTime(), QDateTime(QDate(2005, 6, 6), QTime(4, 2, 30), Qt::LocalTime));
1424     QVERIFY(utc == locUtc);
1425     QVERIFY(!(utc == locClock));
1426 
1427     // ** Date only ** //
1428 
1429     // Zone -> Zone
1430     londonSummer.setDateOnly(true);
1431     locSummer = londonSummer.toZone(losAngeles);
1432     QVERIFY(locSummer.isDateOnly());
1433     QCOMPARE(locSummer.dateTime(), QDateTime(QDate(2005, 6, 1), QTime(0, 0, 0), Qt::LocalTime));
1434     QVERIFY(londonSummer != locSummer);
1435     QVERIFY(!(londonSummer == locSummer));
1436 
1437     // UTC offset -> Zone
1438     offset.setDateOnly(true);
1439     locOffset = offset.toZone(losAngeles);
1440     QVERIFY(locOffset.isDateOnly());
1441     QCOMPARE(locOffset.dateTime(), QDateTime(QDate(2005, 6, 6), QTime(0, 0, 0), Qt::LocalTime));
1442     QVERIFY(offset != locOffset);
1443     QVERIFY(!(offset == locOffset));
1444 
1445     // Clock time -> Zone
1446     clock.setDateOnly(true);
1447     locClock = clock.toZone(losAngeles);
1448     QVERIFY(locClock.isDateOnly());
1449     QCOMPARE(locClock.dateTime(), QDateTime(QDate(2005, 6, 6), QTime(0, 0, 0), Qt::LocalTime));
1450     QVERIFY(clock != locClock);
1451     QVERIFY(!(clock == locClock));
1452 
1453     // UTC -> Zone
1454     utc.setDateOnly(true);
1455     locUtc = utc.toZone(losAngeles);
1456     QVERIFY(locUtc.isDateOnly());
1457     QCOMPARE(locUtc.dateTime(), QDateTime(QDate(2005, 6, 6), QTime(0, 0, 0), Qt::LocalTime));
1458     QVERIFY(utc != locUtc);
1459     QVERIFY(!(utc == locUtc));
1460 
1461     // Restore the original local time zone
1462     group.writeEntry("LocalZone", QString::fromLatin1("America/Los_Angeles"));
1463     config.sync();
1464     QDBusConnection::sessionBus().send(message);
1465     timer.start(1000);
1466     loop.exec();
1467 }
1468 
1469 void KDateTimeTest::toTimeSpec()
1470 {
1471     KTimeZone london = KSystemTimeZones::zone("Europe/London");
1472     KTimeZone cairo  = KSystemTimeZones::zone("Africa/Cairo");
1473 
1474     // Ensure that local time is different from UTC and different from 'london'
1475     QByteArray originalZone = qgetenv("TZ");   // save the original local time zone
1476     qputenv("TZ", ":America/Los_Angeles");
1477     ::tzset();
1478 
1479     KDateTime::Spec utcSpec(KDateTime::UTC);
1480     KDateTime::Spec cairoSpec(cairo);
1481     KDateTime::Spec offset1200Spec(KDateTime::OffsetFromUTC, 1200);
1482     KDateTime::Spec clockSpec(KDateTime::ClockTime);
1483 
1484     KDateTime utc1(QDate(2004, 3, 1), QTime(3, 45, 2), KDateTime::UTC);
1485     KDateTime zone1(QDate(2004, 3, 1), QTime(3, 45, 2), cairo);
1486     KDateTime offset1(QDate(2004, 3, 1), QTime(3, 45, 2), KDateTime::Spec::OffsetFromUTC(1200)); // +00:20
1487     KDateTime clock1(QDate(2004, 3, 1), QTime(3, 45, 2), KDateTime::ClockTime);
1488 
1489     KDateTime utc(QDate(2005, 6, 6), QTime(1, 2, 30), KDateTime::UTC);
1490     KDateTime zone(QDate(2005, 7, 1), QTime(2, 0, 0), london);
1491     KDateTime offset(QDate(2005, 6, 6), QTime(1, 2, 30), KDateTime::Spec::OffsetFromUTC(-5400)); // -01:30
1492     KDateTime clock(QDate(2005, 6, 6), QTime(1, 2, 30), KDateTime::ClockTime);
1493 
1494     // To UTC
1495     KDateTime utcZone = zone.toTimeSpec(utcSpec);
1496     QVERIFY(utcZone.isUtc());
1497     QVERIFY(utcZone == KDateTime(QDate(2005, 7, 1), QTime(1, 0, 0), KDateTime::UTC));
1498     QVERIFY(zone.timeSpec() != utcSpec);
1499     QVERIFY(utcZone.timeSpec() == utcSpec);
1500 
1501     KDateTime utcOffset = offset.toTimeSpec(utcSpec);
1502     QVERIFY(utcOffset.isUtc());
1503     QVERIFY(utcOffset == KDateTime(QDate(2005, 6, 6), QTime(2, 32, 30), KDateTime::UTC));
1504     QVERIFY(offset.timeSpec() != utcSpec);
1505     QVERIFY(utcOffset.timeSpec() == utcSpec);
1506 
1507     KDateTime utcClock = clock.toTimeSpec(utcSpec);
1508     QVERIFY(utcClock.isUtc());
1509     QVERIFY(utcClock == KDateTime(QDate(2005, 6, 6), QTime(8, 2, 30), KDateTime::UTC));
1510     QVERIFY(clock.timeSpec() != utcSpec);
1511     QVERIFY(utcZone.timeSpec() == utcSpec);
1512 
1513     KDateTime utcUtc = utc.toTimeSpec(utcSpec);
1514     QVERIFY(utcUtc.isUtc());
1515     QVERIFY(utcUtc == KDateTime(QDate(2005, 6, 6), QTime(1, 2, 30), KDateTime::UTC));
1516     QVERIFY(utc.timeSpec() == utcSpec);
1517     QVERIFY(utcUtc.timeSpec() == utcSpec);
1518 
1519     // To Zone
1520     KDateTime zoneZone = zone.toTimeSpec(cairoSpec);
1521     QCOMPARE(zoneZone.timeZone(), cairo);
1522     QVERIFY(zoneZone == KDateTime(QDate(2005, 7, 1), QTime(4, 0, 0), cairo));
1523     QVERIFY(zone.timeSpec() != cairoSpec);
1524     QVERIFY(zoneZone.timeSpec() == cairoSpec);
1525 
1526     KDateTime zoneOffset = offset.toTimeSpec(cairoSpec);
1527     QCOMPARE(zoneOffset.timeZone(), cairo);
1528     QVERIFY(zoneOffset == KDateTime(QDate(2005, 6, 6), QTime(5, 32, 30), cairo));
1529     QVERIFY(offset.timeSpec() != cairoSpec);
1530     QVERIFY(zoneOffset.timeSpec() == cairoSpec);
1531 
1532     KDateTime zoneClock = clock.toTimeSpec(cairoSpec);
1533     QCOMPARE(zoneClock.timeZone(), cairo);
1534     QVERIFY(zoneClock == KDateTime(QDate(2005, 6, 6), QTime(11, 2, 30), cairo));
1535     QVERIFY(clock.timeSpec() != cairoSpec);
1536     QVERIFY(zoneClock.timeSpec() == cairoSpec);
1537 
1538     KDateTime zoneUtc = utc.toTimeSpec(cairoSpec);
1539     QCOMPARE(zoneUtc.timeZone(), cairo);
1540     QVERIFY(zoneUtc == KDateTime(QDate(2005, 6, 6), QTime(4, 2, 30), cairo));
1541     QVERIFY(utc.timeSpec() != cairoSpec);
1542     QVERIFY(zoneUtc.timeSpec() == cairoSpec);
1543 
1544     // To UTC offset
1545     KDateTime offsetZone = zone.toTimeSpec(offset1200Spec);
1546     QVERIFY(offsetZone.isOffsetFromUtc());
1547     QCOMPARE(offsetZone.utcOffset(), 1200);
1548     QVERIFY(offsetZone == KDateTime(QDate(2005, 7, 1), QTime(1, 20, 0), KDateTime::Spec::OffsetFromUTC(1200)));
1549     QVERIFY(zone.timeSpec() != offset1200Spec);
1550     QVERIFY(offsetZone.timeSpec() == offset1200Spec);
1551 
1552     KDateTime offsetOffset = offset.toTimeSpec(offset1200Spec);
1553     QVERIFY(offsetOffset.isOffsetFromUtc());
1554     QCOMPARE(offsetZone.utcOffset(), 1200);
1555     QVERIFY(offsetOffset == KDateTime(QDate(2005, 6, 6), QTime(2, 52, 30), KDateTime::Spec::OffsetFromUTC(1200)));
1556     QVERIFY(offset.timeSpec() != offset1200Spec);
1557     QVERIFY(offsetOffset.timeSpec() == offset1200Spec);
1558 
1559     KDateTime offsetClock = clock.toTimeSpec(offset1200Spec);
1560     QVERIFY(offsetClock.isOffsetFromUtc());
1561     QCOMPARE(offsetZone.utcOffset(), 1200);
1562     QVERIFY(offsetClock == KDateTime(QDate(2005, 6, 6), QTime(8, 22, 30), KDateTime::Spec::OffsetFromUTC(1200)));
1563     QVERIFY(clock.timeSpec() != offset1200Spec);
1564     QVERIFY(offsetClock.timeSpec() == offset1200Spec);
1565 
1566     KDateTime offsetUtc = utc.toTimeSpec(offset1200Spec);
1567     QVERIFY(offsetUtc.isOffsetFromUtc());
1568     QCOMPARE(offsetZone.utcOffset(), 1200);
1569     QVERIFY(offsetUtc == KDateTime(QDate(2005, 6, 6), QTime(1, 22, 30), KDateTime::Spec::OffsetFromUTC(1200)));
1570     QVERIFY(utc.timeSpec() != offset1200Spec);
1571     QVERIFY(offsetUtc.timeSpec() == offset1200Spec);
1572 
1573     // To Clock time
1574     KDateTime clockZone = zone.toTimeSpec(clockSpec);
1575     QVERIFY(clockZone.isClockTime());
1576     QVERIFY(clockZone == KDateTime(QDate(2005, 6, 30), QTime(18, 0, 0), KDateTime::ClockTime));
1577     QVERIFY(zone.timeSpec() != clockSpec);
1578     QVERIFY(clockZone.timeSpec() == clockSpec);
1579 
1580     KDateTime clockOffset = offset.toTimeSpec(clockSpec);
1581     QVERIFY(clockOffset.isClockTime());
1582     QVERIFY(clockOffset == KDateTime(QDate(2005, 6, 5), QTime(19, 32, 30), KDateTime::ClockTime));
1583     QVERIFY(offset.timeSpec() != clockSpec);
1584     QVERIFY(clockOffset.timeSpec() == clockSpec);
1585 
1586     KDateTime clockClock = clock.toTimeSpec(clockSpec);
1587     QVERIFY(clockClock.isClockTime());
1588     QVERIFY(clockClock == KDateTime(QDate(2005, 6, 6), QTime(1, 2, 30), KDateTime::ClockTime));
1589     QVERIFY(clock.timeSpec() == clockSpec);
1590     QVERIFY(clockClock.timeSpec() == clockSpec);
1591 
1592     KDateTime clockUtc = utc.toTimeSpec(clockSpec);
1593     QVERIFY(clockUtc.isClockTime());
1594     QVERIFY(clockUtc == KDateTime(QDate(2005, 6, 5), QTime(18, 2, 30), KDateTime::ClockTime));
1595     QVERIFY(utc.timeSpec() != clockSpec);
1596     QVERIFY(clockUtc.timeSpec() == clockSpec);
1597 
1598     // ** Date only ** //
1599 
1600     KDateTime zoned(QDate(2005, 7, 1), london);
1601     KDateTime offsetd(QDate(2005, 6, 6), KDateTime::Spec::OffsetFromUTC(-5400)); // -01:30
1602     KDateTime clockd(QDate(2005, 6, 6), KDateTime::Spec(KDateTime::ClockTime));
1603     KDateTime utcd(QDate(2005, 6, 6), KDateTime::Spec(KDateTime::UTC));
1604 
1605     // To UTC
1606     utcZone = zoned.toTimeSpec(utcSpec);
1607     QVERIFY(utcZone.isUtc());
1608     QVERIFY(utcZone.isDateOnly());
1609     QVERIFY(utcZone == KDateTime(QDate(2005, 7, 1), KDateTime::Spec(KDateTime::UTC)));
1610     QVERIFY(utcZone != zoned);
1611 
1612     utcOffset = offsetd.toTimeSpec(utcSpec);
1613     QVERIFY(utcOffset.isUtc());
1614     QVERIFY(utcOffset.isDateOnly());
1615     QVERIFY(utcOffset == KDateTime(QDate(2005, 6, 6), KDateTime::Spec(KDateTime::UTC)));
1616     QVERIFY(utcOffset != offsetd);
1617 
1618     utcClock = clockd.toTimeSpec(utcSpec);
1619     QVERIFY(utcClock.isUtc());
1620     QVERIFY(utcClock.isDateOnly());
1621     QVERIFY(utcClock == KDateTime(QDate(2005, 6, 6), KDateTime::Spec(KDateTime::UTC)));
1622     QVERIFY(utcClock != clockd);
1623 
1624     utcUtc = utcd.toTimeSpec(utcSpec);
1625     QVERIFY(utcUtc.isUtc());
1626     QVERIFY(utcUtc.isDateOnly());
1627     QVERIFY(utcUtc == KDateTime(QDate(2005, 6, 6), KDateTime::Spec(KDateTime::UTC)));
1628     QVERIFY(utcUtc == utcd);
1629 
1630     // To Zone
1631     zoneZone = zoned.toTimeSpec(cairoSpec);
1632     QVERIFY(zoneZone.isDateOnly());
1633     QCOMPARE(zoneZone.timeZone(), cairo);
1634     QVERIFY(zoneZone == KDateTime(QDate(2005, 7, 1), cairo));
1635     QVERIFY(zoneZone != zoned);
1636 
1637     zoneOffset = offsetd.toTimeSpec(cairoSpec);
1638     QVERIFY(zoneOffset.isDateOnly());
1639     QCOMPARE(zoneOffset.timeZone(), cairo);
1640     QVERIFY(zoneOffset == KDateTime(QDate(2005, 6, 6), cairo));
1641     QVERIFY(zoneOffset != offsetd);
1642 
1643     zoneClock = clockd.toTimeSpec(cairoSpec);
1644     QVERIFY(zoneClock.isDateOnly());
1645     QCOMPARE(zoneClock.timeZone(), cairo);
1646     QVERIFY(zoneClock == KDateTime(QDate(2005, 6, 6), cairo));
1647     QVERIFY(zoneClock != clockd);
1648 
1649     zoneUtc = utcd.toTimeSpec(cairoSpec);
1650     QVERIFY(zoneUtc.isDateOnly());
1651     QCOMPARE(zoneUtc.timeZone(), cairo);
1652     QVERIFY(zoneUtc == KDateTime(QDate(2005, 6, 6), cairo));
1653     QVERIFY(zoneUtc != utcd);
1654 
1655     // To UTC offset
1656     offsetZone = zoned.toTimeSpec(offset1200Spec);
1657     QVERIFY(offsetZone.isOffsetFromUtc());
1658     QVERIFY(offsetZone.isDateOnly());
1659     QCOMPARE(offsetZone.utcOffset(), 1200);
1660     QVERIFY(offsetZone == KDateTime(QDate(2005, 7, 1), KDateTime::Spec::OffsetFromUTC(1200)));
1661     QVERIFY(offsetZone != zoned);
1662 
1663     offsetOffset = offsetd.toTimeSpec(offset1200Spec);
1664     QVERIFY(offsetOffset.isOffsetFromUtc());
1665     QVERIFY(offsetOffset.isDateOnly());
1666     QCOMPARE(offsetZone.utcOffset(), 1200);
1667     QVERIFY(offsetOffset == KDateTime(QDate(2005, 6, 6), KDateTime::Spec::OffsetFromUTC(1200)));
1668     QVERIFY(offsetOffset != offsetd);
1669 
1670     offsetClock = clockd.toTimeSpec(offset1200Spec);
1671     QVERIFY(offsetClock.isOffsetFromUtc());
1672     QVERIFY(offsetClock.isDateOnly());
1673     QCOMPARE(offsetZone.utcOffset(), 1200);
1674     QVERIFY(offsetClock == KDateTime(QDate(2005, 6, 6), KDateTime::Spec::OffsetFromUTC(1200)));
1675     QVERIFY(offsetClock != clockd);
1676 
1677     offsetUtc = utcd.toTimeSpec(offset1200Spec);
1678     QVERIFY(offsetUtc.isOffsetFromUtc());
1679     QVERIFY(offsetUtc.isDateOnly());
1680     QCOMPARE(offsetZone.utcOffset(), 1200);
1681     QVERIFY(offsetUtc == KDateTime(QDate(2005, 6, 6), KDateTime::Spec::OffsetFromUTC(1200)));
1682     QVERIFY(offsetUtc != utcd);
1683 
1684     // To Clock time
1685     clockZone = zoned.toTimeSpec(clockSpec);
1686     QVERIFY(clockZone.isClockTime());
1687     QVERIFY(clockZone.isDateOnly());
1688     QVERIFY(clockZone == KDateTime(QDate(2005, 7, 1), KDateTime::Spec(KDateTime::ClockTime)));
1689     QVERIFY(clockZone != zoned);
1690 
1691     clockOffset = offsetd.toTimeSpec(clockSpec);
1692     QVERIFY(clockOffset.isClockTime());
1693     QVERIFY(clockOffset.isDateOnly());
1694     QVERIFY(clockOffset == KDateTime(QDate(2005, 6, 6), KDateTime::Spec(KDateTime::ClockTime)));
1695     QVERIFY(clockOffset != offsetd);
1696 
1697     clockClock = clockd.toTimeSpec(clockSpec);
1698     QVERIFY(clockClock.isClockTime());
1699     QVERIFY(clockClock.isDateOnly());
1700     QVERIFY(clockClock == KDateTime(QDate(2005, 6, 6), KDateTime::Spec(KDateTime::ClockTime)));
1701     QVERIFY(clockClock == clockd);
1702 
1703     clockUtc = utcd.toTimeSpec(clockSpec);
1704     QVERIFY(clockUtc.isClockTime());
1705     QVERIFY(clockUtc.isDateOnly());
1706     QVERIFY(clockUtc == KDateTime(QDate(2005, 6, 6), KDateTime::Spec(KDateTime::ClockTime)));
1707     QVERIFY(clockUtc != utcd);
1708 
1709     // Restore the original local time zone
1710     if (originalZone.isEmpty()) {
1711         ::unsetenv("TZ");
1712     } else {
1713         qputenv("TZ", originalZone);
1714     }
1715     ::tzset();
1716 }
1717 
1718 ////////////////////////////////////////////////////////////////////////
1719 // Set methods: setDate(), setTime(), setDateTime(), setTimeSpec()
1720 ////////////////////////////////////////////////////////////////////////
1721 
1722 void KDateTimeTest::set()
1723 {
1724     KTimeZone london = KSystemTimeZones::zone("Europe/London");
1725 
1726     // Ensure that local time is different from UTC and different from 'london'
1727     QByteArray originalZone = qgetenv("TZ");   // save the original local time zone
1728     qputenv("TZ", ":America/Los_Angeles");
1729     ::tzset();
1730 
1731     // Zone
1732     KDateTime zoned(QDate(2005, 6, 1), london);
1733     zoned.setDate(QDate(2004, 5, 2));
1734     QVERIFY(zoned.isDateOnly());
1735     QCOMPARE(zoned.dateTime(), QDateTime(QDate(2004, 5, 2), QTime(0, 0, 0), Qt::LocalTime));
1736     zoned.setTime(QTime(12, 13, 14));
1737     QVERIFY(!zoned.isDateOnly());
1738     QCOMPARE(zoned.dateTime(), QDateTime(QDate(2004, 5, 2), QTime(12, 13, 14), Qt::LocalTime));
1739     zoned.setDate(QDate(2004, 5, 4));
1740     QVERIFY(!zoned.isDateOnly());
1741 
1742     zoned.setDateOnly(false);
1743     QVERIFY(!zoned.isDateOnly());
1744     QCOMPARE(zoned.dateTime(), QDateTime(QDate(2004, 5, 4), QTime(12, 13, 14), Qt::LocalTime));
1745     zoned.setDateOnly(true);
1746     QVERIFY(zoned.isDateOnly());
1747     QCOMPARE(zoned.dateTime(), QDateTime(QDate(2004, 5, 4), QTime(0, 0, 0), Qt::LocalTime));
1748     zoned.setDateOnly(false);
1749     QVERIFY(!zoned.isDateOnly());
1750     QCOMPARE(zoned.dateTime(), QDateTime(QDate(2004, 5, 4), QTime(0, 0, 0), Qt::LocalTime));
1751 
1752     KDateTime zone(QDate(2005, 6, 1), QTime(3, 40, 0), london);
1753     zone.setDate(QDate(2004, 5, 2));
1754     QCOMPARE(zone.dateTime(), QDateTime(QDate(2004, 5, 2), QTime(3, 40, 0), Qt::LocalTime));
1755     zone.setTime(QTime(12, 13, 14));
1756     QCOMPARE(zone.dateTime(), QDateTime(QDate(2004, 5, 2), QTime(12, 13, 14), Qt::LocalTime));
1757     zone.setDateTime(QDateTime(QDate(2003, 6, 10), QTime(5, 6, 7)));
1758     QCOMPARE(zone.dateTime(), QDateTime(QDate(2003, 6, 10), QTime(5, 6, 7), Qt::LocalTime));
1759     QCOMPARE(zone.utcOffset(), 3600);
1760     QCOMPARE(zone.toUtc().dateTime(), QDateTime(QDate(2003, 6, 10), QTime(4, 6, 7), Qt::UTC));
1761 
1762     // UTC offset
1763     KDateTime offsetd(QDate(2005, 6, 6), KDateTime::Spec::OffsetFromUTC(-5400)); // -0130
1764     offsetd.setDate(QDate(2004, 5, 2));
1765     QVERIFY(offsetd.isDateOnly());
1766     QCOMPARE(offsetd.dateTime(), QDateTime(QDate(2004, 5, 2), QTime(0, 0, 0), Qt::LocalTime));
1767     offsetd.setTime(QTime(12, 13, 14));
1768     QVERIFY(!offsetd.isDateOnly());
1769     QCOMPARE(offsetd.dateTime(), QDateTime(QDate(2004, 5, 2), QTime(12, 13, 14), Qt::LocalTime));
1770     offsetd.setDate(QDate(2004, 5, 4));
1771     QVERIFY(!offsetd.isDateOnly());
1772 
1773     offsetd.setDateOnly(false);
1774     QVERIFY(!offsetd.isDateOnly());
1775     QCOMPARE(offsetd.dateTime(), QDateTime(QDate(2004, 5, 4), QTime(12, 13, 14), Qt::LocalTime));
1776     offsetd.setDateOnly(true);
1777     QVERIFY(offsetd.isDateOnly());
1778     QCOMPARE(offsetd.dateTime(), QDateTime(QDate(2004, 5, 4), QTime(0, 0, 0), Qt::LocalTime));
1779     offsetd.setDateOnly(false);
1780     QVERIFY(!offsetd.isDateOnly());
1781     QCOMPARE(offsetd.dateTime(), QDateTime(QDate(2004, 5, 4), QTime(0, 0, 0), Qt::LocalTime));
1782 
1783     KDateTime offset(QDate(2005, 6, 6), QTime(1, 2, 30), KDateTime::Spec::OffsetFromUTC(-5400)); // -0130
1784     offset.setDate(QDate(2004, 5, 2));
1785     QCOMPARE(offset.dateTime(), QDateTime(QDate(2004, 5, 2), QTime(1, 2, 30), Qt::LocalTime));
1786     offset.setTime(QTime(12, 13, 14));
1787     QCOMPARE(offset.dateTime(), QDateTime(QDate(2004, 5, 2), QTime(12, 13, 14), Qt::LocalTime));
1788     offset.setDateTime(QDateTime(QDate(2003, 12, 10), QTime(5, 6, 7)));
1789     QCOMPARE(offset.dateTime(), QDateTime(QDate(2003, 12, 10), QTime(5, 6, 7), Qt::LocalTime));
1790     QCOMPARE(offset.utcOffset(), -5400);
1791     QCOMPARE(offset.toUtc().dateTime(), QDateTime(QDate(2003, 12, 10), QTime(6, 36, 7), Qt::UTC));
1792 
1793     // Clock time
1794     KDateTime clockd(QDate(2005, 6, 6), KDateTime::Spec(KDateTime::ClockTime));
1795     clockd.setDate(QDate(2004, 5, 2));
1796     QVERIFY(clockd.isDateOnly());
1797     QCOMPARE(clockd.dateTime(), QDateTime(QDate(2004, 5, 2), QTime(0, 0, 0), Qt::LocalTime));
1798     clockd.setTime(QTime(12, 13, 14));
1799     QVERIFY(!clockd.isDateOnly());
1800     QCOMPARE(clockd.dateTime(), QDateTime(QDate(2004, 5, 2), QTime(12, 13, 14), Qt::LocalTime));
1801     clockd.setDate(QDate(2004, 5, 4));
1802     QVERIFY(!clockd.isDateOnly());
1803 
1804     clockd.setDateOnly(false);
1805     QVERIFY(!clockd.isDateOnly());
1806     QCOMPARE(clockd.dateTime(), QDateTime(QDate(2004, 5, 4), QTime(12, 13, 14), Qt::LocalTime));
1807     clockd.setDateOnly(true);
1808     QVERIFY(clockd.isDateOnly());
1809     QCOMPARE(clockd.dateTime(), QDateTime(QDate(2004, 5, 4), QTime(0, 0, 0), Qt::LocalTime));
1810     clockd.setDateOnly(false);
1811     QVERIFY(!clockd.isDateOnly());
1812     QCOMPARE(clockd.dateTime(), QDateTime(QDate(2004, 5, 4), QTime(0, 0, 0), Qt::LocalTime));
1813 
1814     KDateTime clock(QDate(2005, 6, 6), QTime(1, 2, 30), KDateTime::ClockTime);
1815     clock.setDate(QDate(2004, 5, 2));
1816     QCOMPARE(clock.dateTime(), QDateTime(QDate(2004, 5, 2), QTime(1, 2, 30), Qt::LocalTime));
1817     clock.setTime(QTime(12, 13, 14));
1818     QCOMPARE(clock.dateTime(), QDateTime(QDate(2004, 5, 2), QTime(12, 13, 14), Qt::LocalTime));
1819     clock.setDateTime(QDateTime(QDate(2003, 12, 10), QTime(5, 6, 7)));
1820     QCOMPARE(clock.dateTime(), QDateTime(QDate(2003, 12, 10), QTime(5, 6, 7), Qt::LocalTime));
1821     QCOMPARE(clock.utcOffset(), 0);
1822     QCOMPARE(clock.toUtc().dateTime(), QDateTime(QDate(2003, 12, 10), QTime(13, 6, 7), Qt::UTC));
1823 
1824     // UTC
1825     KDateTime utcd(QDate(2005, 6, 6), KDateTime::Spec(KDateTime::UTC));
1826     utcd.setDate(QDate(2004, 5, 2));
1827     QVERIFY(utcd.isDateOnly());
1828     QCOMPARE(utcd.dateTime(), QDateTime(QDate(2004, 5, 2), QTime(0, 0, 0), Qt::UTC));
1829     utcd.setTime(QTime(12, 13, 14));
1830     QVERIFY(!utcd.isDateOnly());
1831     QCOMPARE(utcd.dateTime(), QDateTime(QDate(2004, 5, 2), QTime(12, 13, 14), Qt::UTC));
1832     utcd.setDate(QDate(2004, 5, 4));
1833     QVERIFY(!utcd.isDateOnly());
1834 
1835     utcd.setDateOnly(false);
1836     QVERIFY(!utcd.isDateOnly());
1837     QCOMPARE(utcd.dateTime(), QDateTime(QDate(2004, 5, 4), QTime(12, 13, 14), Qt::UTC));
1838     utcd.setDateOnly(true);
1839     QVERIFY(utcd.isDateOnly());
1840     QCOMPARE(utcd.dateTime(), QDateTime(QDate(2004, 5, 4), QTime(0, 0, 0), Qt::UTC));
1841     utcd.setDateOnly(false);
1842     QVERIFY(!utcd.isDateOnly());
1843     QCOMPARE(utcd.dateTime(), QDateTime(QDate(2004, 5, 4), QTime(0, 0, 0), Qt::UTC));
1844 
1845     KDateTime utc(QDate(2005, 6, 6), QTime(1, 2, 30), KDateTime::UTC);
1846     utc.setDate(QDate(2004, 5, 2));
1847     QCOMPARE(utc.dateTime(), QDateTime(QDate(2004, 5, 2), QTime(1, 2, 30), Qt::UTC));
1848     utc.setTime(QTime(12, 13, 14));
1849     QCOMPARE(utc.dateTime(), QDateTime(QDate(2004, 5, 2), QTime(12, 13, 14), Qt::UTC));
1850     utc.setDateTime(QDateTime(QDate(2003, 12, 10), QTime(5, 6, 7), Qt::UTC));
1851     QCOMPARE(utc.utcOffset(), 0);
1852     QCOMPARE(utc.dateTime(), QDateTime(QDate(2003, 12, 10), QTime(5, 6, 7), Qt::UTC));
1853 
1854     // setTimeSpec(SpecType)
1855     QCOMPARE(zone.dateTime(), QDateTime(QDate(2003, 6, 10), QTime(5, 6, 7), Qt::LocalTime));
1856     zone.setTimeSpec(KDateTime::Spec::OffsetFromUTC(7200));
1857     QVERIFY(zone.isOffsetFromUtc());
1858     QCOMPARE(zone.utcOffset(), 7200);
1859     QCOMPARE(zone.toUtc().dateTime(), QDateTime(QDate(2003, 6, 10), QTime(3, 6, 7), Qt::UTC));
1860     zone.setTimeSpec(KDateTime::LocalZone);
1861     QVERIFY(zone.isLocalZone());
1862     QCOMPARE(zone.utcOffset(), -7 * 3600);
1863     QCOMPARE(zone.toUtc().dateTime(), QDateTime(QDate(2003, 6, 10), QTime(12, 6, 7), Qt::UTC));
1864     zone.setTimeSpec(KDateTime::UTC);
1865     QVERIFY(zone.isUtc());
1866     QCOMPARE(zone.utcOffset(), 0);
1867     QCOMPARE(zone.dateTime(), QDateTime(QDate(2003, 6, 10), QTime(5, 6, 7), Qt::UTC));
1868     zone.setTimeSpec(KDateTime::ClockTime);
1869     QVERIFY(zone.isClockTime());
1870     QCOMPARE(zone.utcOffset(), 0);
1871     QCOMPARE(zone.toUtc().dateTime(), QDateTime(QDate(2003, 6, 10), QTime(12, 6, 7), Qt::UTC));
1872 
1873     // setTimeSpec(KDateTime::Spec)
1874     QCOMPARE(zone.dateTime(), QDateTime(QDate(2003, 6, 10), QTime(5, 6, 7), Qt::LocalTime));
1875     zone.setTimeSpec(offset.timeSpec());
1876     QVERIFY(zone.isOffsetFromUtc());
1877     QCOMPARE(zone.toUtc().dateTime(), QDateTime(QDate(2003, 6, 10), QTime(6, 36, 7), Qt::UTC));
1878     QVERIFY(zone.timeSpec() == offset.timeSpec());
1879     zone.setTimeSpec(KDateTime::LocalZone);
1880     QVERIFY(zone.isLocalZone());
1881     QCOMPARE(zone.toUtc().dateTime(), QDateTime(QDate(2003, 6, 10), QTime(12, 6, 7), Qt::UTC));
1882     zone.setTimeSpec(utc.timeSpec());
1883     QVERIFY(zone.isUtc());
1884     QCOMPARE(zone.dateTime(), QDateTime(QDate(2003, 6, 10), QTime(5, 6, 7), Qt::UTC));
1885     zone.setTimeSpec(clock.timeSpec());
1886     QVERIFY(zone.isClockTime());
1887     QCOMPARE(zone.toUtc().dateTime(), QDateTime(QDate(2003, 6, 10), QTime(12, 6, 7), Qt::UTC));
1888     zone.setTimeSpec(london);
1889     QCOMPARE(zone.timeZone(), london);
1890     QCOMPARE(zone.utcOffset(), 3600);
1891     QCOMPARE(zone.toUtc().dateTime(), QDateTime(QDate(2003, 6, 10), QTime(4, 6, 7), Qt::UTC));
1892 
1893     // time_t
1894     utcd = KDateTime(QDate(2005, 6, 6), QTime(12, 15, 20), KDateTime::UTC);
1895     QDateTime qtt = utcd.dateTime();
1896     uint secs = qtt.toTime_t();
1897     KDateTime tt;
1898     tt.setTime_t(static_cast<qint64>(secs));
1899     QVERIFY(tt.isUtc());
1900     QCOMPARE(tt.dateTime(), utcd.dateTime());
1901     QCOMPARE(tt.toTime_t(), secs);
1902 
1903     // Restore the original local time zone
1904     if (originalZone.isEmpty()) {
1905         ::unsetenv("TZ");
1906     } else {
1907         qputenv("TZ", originalZone);
1908     }
1909     ::tzset();
1910 }
1911 
1912 /////////////////////////////////////////////////////////
1913 // operator==()
1914 /////////////////////////////////////////////////////////
1915 
1916 void KDateTimeTest::equal()
1917 {
1918     KTimeZone london = KSystemTimeZones::zone("Europe/London");
1919     KTimeZone cairo  = KSystemTimeZones::zone("Africa/Cairo");
1920 
1921     // Ensure that local time is different from UTC and different from 'london'
1922     QByteArray originalZone = qgetenv("TZ");   // save the original local time zone
1923     qputenv("TZ", ":America/Los_Angeles");
1924     ::tzset();
1925 
1926     // Date/time values
1927     QVERIFY(!(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), cairo) == KDateTime(QDate(2004, 2, 28), QTime(3, 45, 3), cairo)));
1928     QVERIFY(!(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), cairo) == KDateTime(QDate(2004, 2, 29), QTime(3, 45, 3), cairo)));
1929     QVERIFY(!(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), cairo) == KDateTime(QDate(2004, 3, 1), QTime(3, 45, 3), cairo)));
1930     QVERIFY(!(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), cairo) == KDateTime(QDate(2004, 3, 2), QTime(3, 45, 3), cairo)));
1931     QVERIFY(!(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), cairo) == KDateTime(QDate(2004, 3, 3), QTime(3, 45, 3), cairo)));
1932     QVERIFY(!(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 3), cairo) == KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), cairo)));
1933     QVERIFY(KDateTime(QDate(2004, 3, 2), QTime(3, 45, 2), cairo) == KDateTime(QDate(2004, 3, 2), QTime(3, 45, 2), cairo));
1934     QVERIFY(!(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), cairo) == KDateTime(QDate(2004, 2, 28), QTime(3, 45, 3), london)));
1935     QVERIFY(!(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), cairo) == KDateTime(QDate(2004, 2, 29), QTime(3, 45, 3), london)));
1936     QVERIFY(!(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), cairo) == KDateTime(QDate(2004, 3, 1), QTime(3, 45, 3), london)));
1937     QVERIFY(!(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), cairo) == KDateTime(QDate(2004, 3, 2), QTime(3, 45, 3), london)));
1938     QVERIFY(!(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), cairo) == KDateTime(QDate(2004, 3, 3), QTime(3, 45, 3), london)));
1939     QVERIFY(!(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), cairo) == KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), KDateTime::UTC)));
1940     QVERIFY(!(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), KDateTime::UTC) == KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), cairo)));
1941     QVERIFY(KDateTime(QDate(2004, 3, 2), QTime(3, 45, 2), cairo) == KDateTime(QDate(2004, 3, 1), QTime(17, 45, 2), KDateTime::LocalZone));
1942 
1943     // Date/time : date-only
1944     QVERIFY(!(KDateTime(QDate(2004, 3, 1), QTime(0, 0, 0), cairo) == KDateTime(QDate(2004, 3, 1), cairo)));
1945     QVERIFY(!(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), cairo) == KDateTime(QDate(2004, 3, 1), cairo)));
1946     QVERIFY(!(KDateTime(QDate(2004, 3, 1), QTime(23, 59, 59, 999), cairo) == KDateTime(QDate(2004, 3, 1), cairo)));
1947     QVERIFY(!(KDateTime(QDate(2004, 3, 1), QTime(23, 59, 59, 999), cairo) == KDateTime(QDate(2004, 3, 2), cairo)));
1948     QVERIFY(!(KDateTime(QDate(2004, 3, 3), QTime(0, 0, 0), cairo) == KDateTime(QDate(2004, 3, 2), cairo)));
1949 
1950     QVERIFY(!(KDateTime(QDate(2004, 3, 1), QTime(0, 0, 0), cairo) == KDateTime(QDate(2004, 3, 1), london)));
1951     QVERIFY(!(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), cairo) == KDateTime(QDate(2004, 3, 1), london)));
1952     QVERIFY(!(KDateTime(QDate(2004, 3, 1), QTime(23, 59, 59, 999), cairo) == KDateTime(QDate(2004, 3, 1), london)));
1953     QVERIFY(!(KDateTime(QDate(2004, 3, 1), QTime(23, 59, 59, 999), cairo) == KDateTime(QDate(2004, 3, 2), london)));
1954     QVERIFY(!(KDateTime(QDate(2004, 3, 3), QTime(0, 0, 0), cairo) == KDateTime(QDate(2004, 3, 2), london)));
1955 
1956     QVERIFY(!(KDateTime(QDate(2004, 3, 2), QTime(9, 59, 59, 999), cairo) == KDateTime(QDate(2004, 3, 2), KDateTime::Spec(KDateTime::LocalZone))));
1957     QVERIFY(!(KDateTime(QDate(2004, 3, 2), QTime(10, 0, 0), cairo) == KDateTime(QDate(2004, 3, 2), KDateTime::Spec(KDateTime::LocalZone))));
1958     QVERIFY(!(KDateTime(QDate(2004, 3, 2), QTime(10, 0, 1), cairo) == KDateTime(QDate(2004, 3, 2), KDateTime::Spec(KDateTime::LocalZone))));
1959     QVERIFY(!(KDateTime(QDate(2004, 3, 3), QTime(9, 59, 59, 999), cairo) == KDateTime(QDate(2004, 3, 2), KDateTime::Spec(KDateTime::LocalZone))));
1960     QVERIFY(!(KDateTime(QDate(2004, 3, 3), QTime(10, 0, 0), cairo) == KDateTime(QDate(2004, 3, 2), KDateTime::Spec(KDateTime::LocalZone))));
1961 
1962     // Date-only : date/time
1963     QVERIFY(!(KDateTime(QDate(2004, 3, 1), cairo) == KDateTime(QDate(2004, 3, 1), QTime(0, 0, 0), cairo)));
1964     QVERIFY(!(KDateTime(QDate(2004, 3, 1), cairo) == KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), cairo)));
1965     QVERIFY(!(KDateTime(QDate(2004, 3, 1), cairo) == KDateTime(QDate(2004, 3, 1), QTime(23, 59, 59, 999), cairo)));
1966     QVERIFY(!(KDateTime(QDate(2004, 3, 2), cairo) == KDateTime(QDate(2004, 3, 1), QTime(23, 59, 59, 999), cairo)));
1967     QVERIFY(!(KDateTime(QDate(2004, 3, 2), cairo) == KDateTime(QDate(2004, 3, 3), QTime(0, 0, 0), cairo)));
1968 
1969     QVERIFY(!(KDateTime(QDate(2004, 3, 1), cairo) == KDateTime(QDate(2004, 3, 1), QTime(0, 0, 0), london)));
1970     QVERIFY(!(KDateTime(QDate(2004, 3, 1), cairo) == KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), london)));
1971     QVERIFY(!(KDateTime(QDate(2004, 3, 1), cairo) == KDateTime(QDate(2004, 3, 1), QTime(23, 59, 59, 999), london)));
1972     QVERIFY(!(KDateTime(QDate(2004, 3, 2), cairo) == KDateTime(QDate(2004, 3, 1), QTime(23, 59, 59, 999), london)));
1973     QVERIFY(!(KDateTime(QDate(2004, 3, 2), cairo) == KDateTime(QDate(2004, 3, 3), QTime(0, 0, 0), london)));
1974 
1975     QVERIFY(!(KDateTime(QDate(2004, 3, 2), KDateTime::Spec(KDateTime::LocalZone)) == KDateTime(QDate(2004, 3, 2), QTime(9, 59, 59, 999), cairo)));
1976     QVERIFY(!(KDateTime(QDate(2004, 3, 2), KDateTime::Spec(KDateTime::LocalZone)) == KDateTime(QDate(2004, 3, 2), QTime(10, 0, 0), cairo)));
1977     QVERIFY(!(KDateTime(QDate(2004, 3, 2), KDateTime::Spec(KDateTime::LocalZone)) == KDateTime(QDate(2004, 3, 3), QTime(9, 59, 59, 999), cairo)));
1978     QVERIFY(!(KDateTime(QDate(2004, 3, 2), KDateTime::Spec(KDateTime::LocalZone)) == KDateTime(QDate(2004, 3, 3), QTime(10, 0, 0), cairo)));
1979 
1980     // Date-only values
1981     QVERIFY(!(KDateTime(QDate(2004, 3, 1), cairo) == KDateTime(QDate(2004, 3, 2), cairo)));
1982     QVERIFY(!(KDateTime(QDate(2004, 3, 1), cairo) == KDateTime(QDate(2004, 3, 2), KDateTime::Spec::OffsetFromUTC(2 * 3600))));
1983     QVERIFY(!(KDateTime(QDate(2004, 3, 1), london) == KDateTime(QDate(2004, 3, 2), cairo)));
1984     QVERIFY(!(KDateTime(QDate(2004, 3, 1), cairo) == KDateTime(QDate(2004, 3, 2), KDateTime::Spec::OffsetFromUTC(3 * 3600))));
1985     QVERIFY(KDateTime(QDate(2004, 3, 1), cairo) == KDateTime(QDate(2004, 3, 1), cairo));
1986     QVERIFY(KDateTime(QDate(2004, 3, 1), cairo) == KDateTime(QDate(2004, 3, 1), KDateTime::Spec::OffsetFromUTC(2 * 3600)));
1987     QVERIFY(!(KDateTime(QDate(2004, 3, 2), cairo) == KDateTime(QDate(2004, 3, 1), london)));
1988     QVERIFY(!(KDateTime(QDate(2004, 3, 2), KDateTime::Spec::OffsetFromUTC(3 * 3600)) == KDateTime(QDate(2004, 3, 1), cairo)));
1989     QVERIFY(!(KDateTime(QDate(2004, 3, 2), cairo) == KDateTime(QDate(2004, 3, 1), cairo)));
1990     QVERIFY(!(KDateTime(QDate(2004, 3, 2), KDateTime::Spec::OffsetFromUTC(2 * 3600)) == KDateTime(QDate(2004, 3, 1), cairo)));
1991     // Compare days when daylight savings changes occur
1992     QVERIFY(KDateTime(QDate(2005, 3, 27), london) == KDateTime(QDate(2005, 3, 27), london));
1993     QVERIFY(!(KDateTime(QDate(2005, 3, 27), london) == KDateTime(QDate(2005, 3, 27), KDateTime::Spec::OffsetFromUTC(0))));
1994     QVERIFY(KDateTime(QDate(2005, 3, 27), KDateTime::Spec::OffsetFromUTC(0)) == KDateTime(QDate(2005, 3, 27), KDateTime::Spec::OffsetFromUTC(0)));
1995     QVERIFY(!(KDateTime(QDate(2005, 3, 27), KDateTime::Spec::OffsetFromUTC(0)) == KDateTime(QDate(2005, 3, 27), london)));
1996     QVERIFY(KDateTime(QDate(2005, 10, 30), KDateTime::Spec(KDateTime::UTC)) == KDateTime(QDate(2005, 10, 30), KDateTime::Spec(KDateTime::UTC)));
1997     QVERIFY(!(KDateTime(QDate(2005, 10, 30), london) == KDateTime(QDate(2005, 10, 30), KDateTime::Spec(KDateTime::UTC))));
1998     QVERIFY(!(KDateTime(QDate(2005, 10, 30), KDateTime::Spec(KDateTime::UTC)) == KDateTime(QDate(2005, 10, 30), london)));
1999 
2000     // Restore the original local time zone
2001     if (originalZone.isEmpty()) {
2002         ::unsetenv("TZ");
2003     } else {
2004         qputenv("TZ", originalZone);
2005     }
2006     ::tzset();
2007 }
2008 
2009 /////////////////////////////////////////////////////////
2010 // operator<()
2011 /////////////////////////////////////////////////////////
2012 
2013 void KDateTimeTest::lessThan()
2014 {
2015     KTimeZone london = KSystemTimeZones::zone("Europe/London");
2016     KTimeZone cairo  = KSystemTimeZones::zone("Africa/Cairo");
2017 
2018     // Ensure that local time is different from UTC and different from 'london'
2019     QByteArray originalZone = qgetenv("TZ");   // save the original local time zone
2020     qputenv("TZ", ":America/Los_Angeles");
2021     ::tzset();
2022 
2023     // Date/time values
2024     QVERIFY(!(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), cairo) < KDateTime(QDate(2004, 2, 28), QTime(3, 45, 3), cairo)));
2025     QVERIFY(!(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), cairo) < KDateTime(QDate(2004, 2, 29), QTime(3, 45, 3), cairo)));
2026     QVERIFY(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), cairo) < KDateTime(QDate(2004, 3, 1), QTime(3, 45, 3), cairo));
2027     QVERIFY(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), cairo) < KDateTime(QDate(2004, 3, 2), QTime(3, 45, 3), cairo));
2028     QVERIFY(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), cairo) < KDateTime(QDate(2004, 3, 3), QTime(3, 45, 3), cairo));
2029     QVERIFY(!(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 3), cairo) < KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), cairo)));
2030     QVERIFY(KDateTime(QDate(2004, 3, 2), QTime(3, 45, 1), cairo) < KDateTime(QDate(2004, 3, 2), QTime(3, 45, 2), cairo));
2031     QVERIFY(!(KDateTime(QDate(2004, 3, 2), QTime(3, 45, 2), cairo) < KDateTime(QDate(2004, 3, 2), QTime(3, 45, 2), cairo)));
2032     QVERIFY(!(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), cairo) < KDateTime(QDate(2004, 2, 28), QTime(3, 45, 3), london)));
2033     QVERIFY(!(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), cairo) < KDateTime(QDate(2004, 2, 29), QTime(3, 45, 3), london)));
2034     QVERIFY(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), cairo) < KDateTime(QDate(2004, 3, 1), QTime(3, 45, 3), london));
2035     QVERIFY(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), cairo) < KDateTime(QDate(2004, 3, 2), QTime(3, 45, 3), london));
2036     QVERIFY(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), cairo) < KDateTime(QDate(2004, 3, 3), QTime(3, 45, 3), london));
2037     QVERIFY(!(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), london) < KDateTime(QDate(2004, 2, 28), QTime(3, 45, 3), cairo)));
2038     QVERIFY(!(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), london) < KDateTime(QDate(2004, 2, 29), QTime(3, 45, 3), cairo)));
2039     QVERIFY(!(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), london) < KDateTime(QDate(2004, 3, 1), QTime(3, 45, 3), cairo)));
2040     QVERIFY(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), london) < KDateTime(QDate(2004, 3, 2), QTime(3, 45, 3), cairo));
2041     QVERIFY(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), london) < KDateTime(QDate(2004, 3, 3), QTime(3, 45, 3), cairo));
2042     QVERIFY(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), cairo) < KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), KDateTime::UTC));
2043     QVERIFY(!(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), KDateTime::UTC) < KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), cairo)));
2044     QVERIFY(!(KDateTime(QDate(2004, 3, 2), QTime(3, 45, 2), cairo) < KDateTime(QDate(2004, 3, 1), QTime(17, 45, 2), KDateTime::LocalZone)));
2045     QVERIFY(KDateTime(QDate(2004, 3, 2), QTime(3, 45, 2), cairo) < KDateTime(QDate(2004, 3, 1), QTime(17, 45, 3), KDateTime::LocalZone));
2046 
2047     // Date/time : date-only
2048     QVERIFY(KDateTime(QDate(2004, 2, 29), QTime(0, 0, 0), cairo) < KDateTime(QDate(2004, 3, 2), cairo));
2049     QVERIFY(KDateTime(QDate(2004, 3, 1), QTime(0, 0, 0), cairo) < KDateTime(QDate(2004, 3, 2), cairo));
2050     QVERIFY(KDateTime(QDate(2004, 3, 1), QTime(23, 59, 59, 999), cairo) < KDateTime(QDate(2004, 3, 2), cairo));
2051     QVERIFY(!(KDateTime(QDate(2004, 3, 2), QTime(0, 0, 0), cairo) < KDateTime(QDate(2004, 3, 2), cairo)));
2052     QVERIFY(!(KDateTime(QDate(2004, 3, 2), QTime(3, 45, 2), cairo) < KDateTime(QDate(2004, 3, 2), cairo)));
2053     QVERIFY(!(KDateTime(QDate(2004, 3, 2), QTime(23, 59, 59, 999), cairo) < KDateTime(QDate(2004, 3, 2), cairo)));
2054     QVERIFY(!(KDateTime(QDate(2004, 3, 3), QTime(0, 0, 0), cairo) < KDateTime(QDate(2004, 3, 2), cairo)));
2055     QVERIFY(!(KDateTime(QDate(2004, 3, 4), QTime(0, 0, 0), cairo) < KDateTime(QDate(2004, 3, 2), cairo)));
2056     QVERIFY(!(KDateTime(QDate(2004, 3, 5), QTime(0, 0, 0), cairo) < KDateTime(QDate(2004, 3, 2), cairo)));
2057 
2058     QVERIFY(KDateTime(QDate(2004, 2, 29), QTime(0, 0, 0), cairo) < KDateTime(QDate(2004, 3, 2), london));
2059     QVERIFY(KDateTime(QDate(2004, 3, 1), QTime(0, 0, 0), cairo) < KDateTime(QDate(2004, 3, 2), london));
2060     QVERIFY(KDateTime(QDate(2004, 3, 2), QTime(1, 59, 59, 999), cairo) < KDateTime(QDate(2004, 3, 2), london));
2061     QVERIFY(!(KDateTime(QDate(2004, 3, 2), QTime(2, 0, 0), cairo) < KDateTime(QDate(2004, 3, 2), london)));
2062     QVERIFY(!(KDateTime(QDate(2004, 3, 2), QTime(3, 45, 2), cairo) < KDateTime(QDate(2004, 3, 2), london)));
2063     QVERIFY(!(KDateTime(QDate(2004, 3, 2), QTime(23, 59, 59, 999), cairo) < KDateTime(QDate(2004, 3, 2), london)));
2064     QVERIFY(!(KDateTime(QDate(2004, 3, 3), QTime(0, 0, 0), cairo) < KDateTime(QDate(2004, 3, 2), london)));
2065     QVERIFY(!(KDateTime(QDate(2004, 3, 4), QTime(0, 0, 0), cairo) < KDateTime(QDate(2004, 3, 2), london)));
2066     QVERIFY(!(KDateTime(QDate(2004, 3, 5), QTime(0, 0, 0), cairo) < KDateTime(QDate(2004, 3, 2), london)));
2067 
2068     QVERIFY(KDateTime(QDate(2004, 3, 2), QTime(9, 59, 59, 999), cairo) < KDateTime(QDate(2004, 3, 2), KDateTime::Spec(KDateTime::LocalZone)));
2069     QVERIFY(!(KDateTime(QDate(2004, 3, 2), QTime(10, 0, 0), cairo) < KDateTime(QDate(2004, 3, 2), KDateTime::Spec(KDateTime::LocalZone))));
2070     QVERIFY(!(KDateTime(QDate(2004, 3, 2), QTime(10, 0, 1), cairo) < KDateTime(QDate(2004, 3, 2), KDateTime::Spec(KDateTime::LocalZone))));
2071     QVERIFY(!(KDateTime(QDate(2004, 3, 3), QTime(9, 59, 59, 999), cairo) < KDateTime(QDate(2004, 3, 2), KDateTime::Spec(KDateTime::LocalZone))));
2072     QVERIFY(!(KDateTime(QDate(2004, 3, 3), QTime(10, 0, 0), cairo) < KDateTime(QDate(2004, 3, 2), KDateTime::Spec(KDateTime::LocalZone))));
2073 
2074     // Date-only : date/time
2075     QVERIFY(KDateTime(QDate(2004, 2, 28), cairo) < KDateTime(QDate(2004, 3, 2), QTime(0, 0, 0), cairo));
2076     QVERIFY(KDateTime(QDate(2004, 2, 29), cairo) < KDateTime(QDate(2004, 3, 2), QTime(0, 0, 0), cairo));
2077     QVERIFY(KDateTime(QDate(2004, 3, 1), cairo) < KDateTime(QDate(2004, 3, 2), QTime(0, 0, 0), cairo));
2078     QVERIFY(!(KDateTime(QDate(2004, 3, 2), cairo) < KDateTime(QDate(2004, 3, 2), QTime(0, 0, 0), cairo)));
2079     QVERIFY(!(KDateTime(QDate(2004, 3, 2), cairo) < KDateTime(QDate(2004, 3, 2), QTime(3, 45, 2), cairo)));
2080     QVERIFY(!(KDateTime(QDate(2004, 3, 2), cairo) < KDateTime(QDate(2004, 3, 2), QTime(23, 59, 59, 999), cairo)));
2081     QVERIFY(!(KDateTime(QDate(2004, 3, 3), cairo) < KDateTime(QDate(2004, 3, 2), QTime(23, 59, 59, 999), cairo)));
2082     QVERIFY(!(KDateTime(QDate(2004, 3, 4), cairo) < KDateTime(QDate(2004, 3, 2), QTime(0, 0, 0), cairo)));
2083     QVERIFY(!(KDateTime(QDate(2004, 3, 5), cairo) < KDateTime(QDate(2004, 3, 2), QTime(0, 0, 0), cairo)));
2084 
2085     QVERIFY(KDateTime(QDate(2004, 2, 28), cairo) < KDateTime(QDate(2004, 3, 1), QTime(22, 0, 0), london));
2086     QVERIFY(KDateTime(QDate(2004, 2, 29), cairo) < KDateTime(QDate(2004, 3, 1), QTime(22, 0, 0), london));
2087     QVERIFY(KDateTime(QDate(2004, 3, 1), cairo) < KDateTime(QDate(2004, 3, 1), QTime(22, 0, 0), london));
2088     QVERIFY(!(KDateTime(QDate(2004, 3, 2), cairo) < KDateTime(QDate(2004, 3, 1), QTime(22, 0, 0), london)));
2089     QVERIFY(!(KDateTime(QDate(2004, 3, 2), cairo) < KDateTime(QDate(2004, 3, 2), QTime(3, 45, 2), london)));
2090     QVERIFY(!(KDateTime(QDate(2004, 3, 2), cairo) < KDateTime(QDate(2004, 3, 1), QTime(21, 59, 59, 999), london)));
2091     QVERIFY(!(KDateTime(QDate(2004, 3, 3), cairo) < KDateTime(QDate(2004, 3, 1), QTime(21, 59, 59, 999), london)));
2092     QVERIFY(!(KDateTime(QDate(2004, 3, 4), cairo) < KDateTime(QDate(2004, 3, 1), QTime(22, 0, 0), london)));
2093     QVERIFY(!(KDateTime(QDate(2004, 3, 5), cairo) < KDateTime(QDate(2004, 3, 1), QTime(22, 0, 0), london)));
2094 
2095     QVERIFY(KDateTime(QDate(2004, 2, 28), KDateTime::Spec(KDateTime::LocalZone)) < KDateTime(QDate(2004, 3, 2), QTime(9, 59, 59, 999), cairo));
2096     QVERIFY(KDateTime(QDate(2004, 2, 29), KDateTime::Spec(KDateTime::LocalZone)) < KDateTime(QDate(2004, 3, 2), QTime(9, 59, 59, 999), cairo));
2097     QVERIFY(!(KDateTime(QDate(2004, 3, 1), KDateTime::Spec(KDateTime::LocalZone)) < KDateTime(QDate(2004, 3, 2), QTime(9, 59, 59, 999), cairo)));
2098     QVERIFY(KDateTime(QDate(2004, 3, 1), KDateTime::Spec(KDateTime::LocalZone)) < KDateTime(QDate(2004, 3, 2), QTime(10, 0, 0), cairo));
2099     QVERIFY(!(KDateTime(QDate(2004, 3, 2), KDateTime::Spec(KDateTime::LocalZone)) < KDateTime(QDate(2004, 3, 2), QTime(9, 59, 59, 999), cairo)));
2100     QVERIFY(!(KDateTime(QDate(2004, 3, 3), KDateTime::Spec(KDateTime::LocalZone)) < KDateTime(QDate(2004, 3, 2), QTime(10, 0, 0), cairo)));
2101     QVERIFY(!(KDateTime(QDate(2004, 3, 6), KDateTime::Spec(KDateTime::LocalZone)) < KDateTime(QDate(2004, 3, 2), QTime(10, 0, 0), cairo)));
2102 
2103     // Date-only values
2104     QVERIFY(KDateTime(QDate(2004, 3, 1), cairo) < KDateTime(QDate(2004, 3, 2), cairo));
2105     QVERIFY(KDateTime(QDate(2004, 3, 1), cairo) < KDateTime(QDate(2004, 3, 2), KDateTime::Spec::OffsetFromUTC(2 * 3600)));
2106     QVERIFY(!(KDateTime(QDate(2004, 3, 1), london) < KDateTime(QDate(2004, 3, 2), cairo)));
2107     QVERIFY(!(KDateTime(QDate(2004, 3, 1), cairo) < KDateTime(QDate(2004, 3, 2), KDateTime::Spec::OffsetFromUTC(3 * 3600))));
2108     QVERIFY(KDateTime(QDate(2004, 3, 1), cairo) < KDateTime(QDate(2004, 3, 3), KDateTime::Spec::OffsetFromUTC(3 * 3600)));
2109     QVERIFY(KDateTime(QDate(2004, 3, 1), cairo) < KDateTime(QDate(2004, 3, 4), KDateTime::Spec::OffsetFromUTC(3 * 3600)));
2110     QVERIFY(!(KDateTime(QDate(2004, 3, 1), cairo) < KDateTime(QDate(2004, 3, 1), cairo)));
2111     QVERIFY(!(KDateTime(QDate(2004, 3, 1), cairo) < KDateTime(QDate(2004, 3, 1), KDateTime::Spec::OffsetFromUTC(2 * 3600))));
2112     QVERIFY(KDateTime(QDate(2004, 3, 1), cairo) < KDateTime(QDate(2004, 3, 5), london));
2113     QVERIFY(KDateTime(QDate(2004, 3, 1), cairo) < KDateTime(QDate(2004, 3, 2), london));
2114     QVERIFY(!(KDateTime(QDate(2004, 3, 2), cairo) < KDateTime(QDate(2004, 3, 1), london)));
2115     QVERIFY(!(KDateTime(QDate(2004, 3, 2), KDateTime::Spec::OffsetFromUTC(3 * 3600)) < KDateTime(QDate(2004, 3, 1), cairo)));
2116     QVERIFY(!(KDateTime(QDate(2004, 3, 2), cairo) < KDateTime(QDate(2004, 3, 1), cairo)));
2117     QVERIFY(!(KDateTime(QDate(2004, 3, 2), KDateTime::Spec::OffsetFromUTC(2 * 3600)) < KDateTime(QDate(2004, 3, 1), cairo)));
2118 
2119     // Restore the original local time zone
2120     if (originalZone.isEmpty()) {
2121         ::unsetenv("TZ");
2122     } else {
2123         qputenv("TZ", originalZone);
2124     }
2125     ::tzset();
2126 }
2127 
2128 /////////////////////////////////////////////////////////
2129 // compare()
2130 /////////////////////////////////////////////////////////
2131 
2132 void KDateTimeTest::compare()
2133 {
2134     KTimeZone london = KSystemTimeZones::zone("Europe/London");
2135     KTimeZone cairo  = KSystemTimeZones::zone("Africa/Cairo");
2136 
2137     // Ensure that local time is different from UTC and different from 'london'
2138     QByteArray originalZone = qgetenv("TZ");   // save the original local time zone
2139     qputenv("TZ", ":America/Los_Angeles");
2140     ::tzset();
2141 
2142     // Date/time values
2143     QCOMPARE(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), cairo).compare(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 3), cairo)), KDateTime::Before);
2144     QCOMPARE(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), cairo).compare(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), KDateTime::UTC)), KDateTime::Before);
2145     QCOMPARE(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), KDateTime::UTC).compare(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), cairo)), KDateTime::After);
2146     QCOMPARE(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 3), cairo).compare(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), cairo)), KDateTime::After);
2147     QCOMPARE(KDateTime(QDate(2004, 3, 2), QTime(3, 45, 2), cairo).compare(KDateTime(QDate(2004, 3, 1), QTime(17, 45, 2), KDateTime::LocalZone)), KDateTime::Equal);
2148     QCOMPARE(KDateTime(QDate(2004, 3, 2), QTime(3, 45, 2), cairo).compare(KDateTime(QDate(2004, 3, 2), QTime(3, 45, 2), cairo)), KDateTime::Equal);
2149 
2150     // Date/time : date-only
2151     QCOMPARE(KDateTime(QDate(2004, 3, 1), QTime(0, 0, 0), cairo).compare(KDateTime(QDate(2004, 3, 1), cairo)), KDateTime::AtStart);
2152     QCOMPARE(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), cairo).compare(KDateTime(QDate(2004, 3, 1), cairo)), KDateTime::Inside);
2153     QCOMPARE(KDateTime(QDate(2004, 3, 1), QTime(23, 59, 59, 999), cairo).compare(KDateTime(QDate(2004, 3, 1), cairo)), KDateTime::AtEnd);
2154     QCOMPARE(KDateTime(QDate(2004, 3, 1), QTime(23, 59, 59, 999), cairo).compare(KDateTime(QDate(2004, 3, 2), cairo)), KDateTime::Before);
2155     QCOMPARE(KDateTime(QDate(2004, 3, 3), QTime(0, 0, 0), cairo).compare(KDateTime(QDate(2004, 3, 2), cairo)), KDateTime::After);
2156 
2157     QCOMPARE(KDateTime(QDate(2004, 3, 2), QTime(9, 59, 59, 999), cairo).compare(KDateTime(QDate(2004, 3, 2), KDateTime::Spec(KDateTime::LocalZone))), KDateTime::Before);
2158     QCOMPARE(KDateTime(QDate(2004, 3, 2), QTime(10, 0, 0), cairo).compare(KDateTime(QDate(2004, 3, 2), KDateTime::Spec(KDateTime::LocalZone))), KDateTime::AtStart);
2159     QCOMPARE(KDateTime(QDate(2004, 3, 2), QTime(10, 0, 1), cairo).compare(KDateTime(QDate(2004, 3, 2), KDateTime::Spec(KDateTime::LocalZone))), KDateTime::Inside);
2160     QCOMPARE(KDateTime(QDate(2004, 3, 3), QTime(9, 59, 59, 999), cairo).compare(KDateTime(QDate(2004, 3, 2), KDateTime::Spec(KDateTime::LocalZone))), KDateTime::AtEnd);
2161     QCOMPARE(KDateTime(QDate(2004, 3, 3), QTime(10, 0, 0), cairo).compare(KDateTime(QDate(2004, 3, 2), KDateTime::Spec(KDateTime::LocalZone))), KDateTime::After);
2162 
2163     // Date-only : date/time
2164     QCOMPARE(KDateTime(QDate(2004, 3, 1), cairo).compare(KDateTime(QDate(2004, 3, 1), QTime(0, 0, 0), cairo)), KDateTime::StartsAt);
2165     QCOMPARE(KDateTime(QDate(2004, 3, 1), cairo).compare(KDateTime(QDate(2004, 3, 1), QTime(3, 45, 2), cairo)), KDateTime::Outside);
2166     QCOMPARE(KDateTime(QDate(2004, 3, 1), cairo).compare(KDateTime(QDate(2004, 3, 1), QTime(23, 59, 59, 999), cairo)), KDateTime::EndsAt);
2167     QCOMPARE(KDateTime(QDate(2004, 3, 2), cairo).compare(KDateTime(QDate(2004, 3, 1), QTime(23, 59, 59, 999), cairo)), KDateTime::After);
2168     QCOMPARE(KDateTime(QDate(2004, 3, 2), cairo).compare(KDateTime(QDate(2004, 3, 3), QTime(0, 0, 0), cairo)), KDateTime::Before);
2169 
2170     QCOMPARE(KDateTime(QDate(2004, 3, 2), KDateTime::Spec(KDateTime::LocalZone)).compare(KDateTime(QDate(2004, 3, 2), QTime(9, 59, 59, 999), cairo)), KDateTime::After);
2171     QCOMPARE(KDateTime(QDate(2004, 3, 2), KDateTime::Spec(KDateTime::LocalZone)).compare(KDateTime(QDate(2004, 3, 2), QTime(10, 0, 0), cairo)), KDateTime::StartsAt);
2172     QCOMPARE(KDateTime(QDate(2004, 3, 2), KDateTime::Spec(KDateTime::LocalZone)).compare(KDateTime(QDate(2004, 3, 3), QTime(9, 59, 59, 999), cairo)), KDateTime::EndsAt);
2173     QCOMPARE(KDateTime(QDate(2004, 3, 2), KDateTime::Spec(KDateTime::LocalZone)).compare(KDateTime(QDate(2004, 3, 3), QTime(10, 0, 0), cairo)), KDateTime::Before);
2174 
2175     // Date-only values
2176     QCOMPARE(KDateTime(QDate(2004, 3, 1), cairo).compare(KDateTime(QDate(2004, 3, 2), cairo)), KDateTime::Before);
2177     QCOMPARE(KDateTime(QDate(2004, 3, 1), cairo).compare(KDateTime(QDate(2004, 3, 2), KDateTime::Spec::OffsetFromUTC(2 * 3600))), KDateTime::Before);
2178     QCOMPARE(KDateTime(QDate(2004, 3, 1), london).compare(KDateTime(QDate(2004, 3, 2), cairo)), static_cast<KDateTime::Comparison>(KDateTime::Before | KDateTime::AtStart | KDateTime::Inside));
2179     QCOMPARE(KDateTime(QDate(2004, 3, 1), cairo).compare(KDateTime(QDate(2004, 3, 2), KDateTime::Spec::OffsetFromUTC(3 * 3600))), static_cast<KDateTime::Comparison>(KDateTime::Before | KDateTime::AtStart | KDateTime::Inside));
2180     QCOMPARE(KDateTime(QDate(2004, 3, 1), cairo).compare(KDateTime(QDate(2004, 3, 1), cairo)), KDateTime::Equal);
2181     QCOMPARE(KDateTime(QDate(2004, 3, 1), cairo).compare(KDateTime(QDate(2004, 3, 1), KDateTime::Spec::OffsetFromUTC(2 * 3600))), KDateTime::Equal);
2182     QCOMPARE(KDateTime(QDate(2004, 3, 2), cairo).compare(KDateTime(QDate(2004, 3, 1), london)), static_cast<KDateTime::Comparison>(KDateTime::Inside | KDateTime::AtEnd | KDateTime::After));
2183     QCOMPARE(KDateTime(QDate(2004, 3, 2), KDateTime::Spec::OffsetFromUTC(3 * 3600)).compare(KDateTime(QDate(2004, 3, 1), cairo)), static_cast<KDateTime::Comparison>(KDateTime::Inside | KDateTime::AtEnd | KDateTime::After));
2184     QCOMPARE(KDateTime(QDate(2004, 3, 2), cairo).compare(KDateTime(QDate(2004, 3, 1), cairo)), KDateTime::After);
2185     QCOMPARE(KDateTime(QDate(2004, 3, 2), KDateTime::Spec::OffsetFromUTC(2 * 3600)).compare(KDateTime(QDate(2004, 3, 1), cairo)), KDateTime::After);
2186     // Compare days when daylight savings changes occur
2187     QCOMPARE(KDateTime(QDate(2005, 3, 27), london).compare(KDateTime(QDate(2005, 3, 27), KDateTime::Spec::OffsetFromUTC(0))), static_cast<KDateTime::Comparison>(KDateTime::AtStart | KDateTime::Inside));
2188     QCOMPARE(KDateTime(QDate(2005, 3, 27), KDateTime::Spec::OffsetFromUTC(0)).compare(KDateTime(QDate(2005, 3, 27), london)), KDateTime::StartsAt);
2189     QCOMPARE(KDateTime(QDate(2005, 10, 30), london).compare(KDateTime(QDate(2005, 10, 30), KDateTime::Spec(KDateTime::UTC))), KDateTime::EndsAt);
2190     QCOMPARE(KDateTime(QDate(2005, 10, 30), KDateTime::Spec(KDateTime::UTC)).compare(KDateTime(QDate(2005, 10, 30), london)), static_cast<KDateTime::Comparison>(KDateTime::Inside | KDateTime::AtEnd));
2191 
2192     // Restore the original local time zone
2193     if (originalZone.isEmpty()) {
2194         ::unsetenv("TZ");
2195     } else {
2196         qputenv("TZ", originalZone);
2197     }
2198     ::tzset();
2199 }
2200 
2201 /////////////////////////////////////////////////////////
2202 // Addition and subtraction methods, and operator<() etc.
2203 /////////////////////////////////////////////////////////
2204 
2205 void KDateTimeTest::addSubtract()
2206 {
2207     KTimeZone london = KSystemTimeZones::zone("Europe/London");
2208     KTimeZone losAngeles = KSystemTimeZones::zone("America/Los_Angeles");
2209 
2210     // Ensure that local time is different from UTC and different from 'london'
2211     QByteArray originalZone = qgetenv("TZ");   // save the original local time zone
2212     qputenv("TZ", ":America/Los_Angeles");
2213     ::tzset();
2214 
2215     // UTC
2216     KDateTime utc1(QDate(2005, 7, 6), QTime(3, 40, 0), KDateTime::UTC);
2217     KDateTime utc2 = utc1.addSecs(184 * 86400);
2218     QVERIFY(utc2.isUtc());
2219     QCOMPARE(utc2.dateTime(), QDateTime(QDate(2006, 1, 6), QTime(3, 40, 0), Qt::UTC));
2220     KDateTime utc3 = utc1.addDays(184);
2221     QVERIFY(utc3.isUtc());
2222     QCOMPARE(utc2.dateTime(), utc3.dateTime());
2223     KDateTime utc4 = utc1.addMonths(6);
2224     QVERIFY(utc4.isUtc());
2225     QCOMPARE(utc2.dateTime(), utc4.dateTime());
2226     KDateTime utc5 = utc1.addYears(4);
2227     QVERIFY(utc5.isUtc());
2228     QCOMPARE(utc5.dateTime(), QDateTime(QDate(2009, 7, 6), QTime(3, 40, 0), Qt::UTC));
2229     QCOMPARE(utc1.secsTo(utc2), 184 * 86400);
2230     QCOMPARE(utc1.secsTo(utc3), 184 * 86400);
2231     QCOMPARE(utc1.daysTo(utc2), 184);
2232     QVERIFY(utc1 < utc2);
2233     QVERIFY(!(utc2 < utc1));
2234     QVERIFY(utc2 == utc3);
2235 
2236     // UTC offset
2237     KDateTime offset1(QDate(2005, 7, 6), QTime(3, 40, 0), KDateTime::Spec::OffsetFromUTC(-5400)); // -0130
2238     KDateTime offset2 = offset1.addSecs(184 * 86400);
2239     QVERIFY(offset2.isOffsetFromUtc());
2240     QCOMPARE(offset2.utcOffset(), -5400);
2241     QCOMPARE(offset2.dateTime(), QDateTime(QDate(2006, 1, 6), QTime(3, 40, 0), Qt::LocalTime));
2242     KDateTime offset3 = offset1.addDays(184);
2243     QVERIFY(offset3.isOffsetFromUtc());
2244     QCOMPARE(offset3.utcOffset(), -5400);
2245     QCOMPARE(offset2.dateTime(), offset3.dateTime());
2246     KDateTime offset4 = offset1.addMonths(6);
2247     QVERIFY(offset4.isOffsetFromUtc());
2248     QCOMPARE(offset4.utcOffset(), -5400);
2249     QCOMPARE(offset2.dateTime(), offset4.dateTime());
2250     KDateTime offset5 = offset1.addYears(4);
2251     QVERIFY(offset5.isOffsetFromUtc());
2252     QCOMPARE(offset5.utcOffset(), -5400);
2253     QCOMPARE(offset5.dateTime(), QDateTime(QDate(2009, 7, 6), QTime(3, 40, 0), Qt::LocalTime));
2254     QCOMPARE(offset1.secsTo(offset2), 184 * 86400);
2255     QCOMPARE(offset1.secsTo(offset3), 184 * 86400);
2256     QCOMPARE(offset1.daysTo(offset2), 184);
2257     QVERIFY(offset1 < offset2);
2258     QVERIFY(!(offset2 < offset1));
2259     QVERIFY(offset2 == offset3);
2260 
2261     // Zone
2262     KDateTime zone1(QDate(2005, 7, 6), QTime(3, 40, 0), london);
2263     KDateTime zone2 = zone1.addSecs(184 * 86400);
2264     QCOMPARE(zone2.timeZone(), london);
2265     QCOMPARE(zone2.dateTime(), QDateTime(QDate(2006, 1, 6), QTime(2, 40, 0), Qt::LocalTime));
2266     KDateTime zone3 = zone1.addDays(184);
2267     QCOMPARE(zone3.timeZone(), london);
2268     QCOMPARE(zone3.dateTime(), QDateTime(QDate(2006, 1, 6), QTime(3, 40, 0), Qt::LocalTime));
2269     KDateTime zone4 = zone1.addMonths(6);
2270     QCOMPARE(zone4.timeZone(), london);
2271     QCOMPARE(zone4.dateTime(), zone3.dateTime());
2272     KDateTime zone5 = zone1.addYears(4);
2273     QCOMPARE(zone5.timeZone(), london);
2274     QCOMPARE(zone5.dateTime(), QDateTime(QDate(2009, 7, 6), QTime(3, 40, 0), Qt::LocalTime));
2275     QCOMPARE(zone1.secsTo(zone2), 184 * 86400);
2276     QCOMPARE(zone1.secsTo(zone3), 184 * 86400 + 3600);
2277     QCOMPARE(zone1.daysTo(zone2), 184);
2278     QCOMPARE(zone1.daysTo(zone3), 184);
2279     QVERIFY(zone1 < zone2);
2280     QVERIFY(!(zone2 < zone1));
2281     QVERIFY(!(zone2 == zone3));
2282 
2283     // Local zone
2284     KDateTime local1(QDate(2005, 7, 6), QTime(3, 40, 0), KDateTime::LocalZone);
2285     KDateTime local2 = local1.addSecs(184 * 86400);
2286     QVERIFY(local2.isLocalZone());
2287     QCOMPARE(local2.timeZone(), losAngeles);
2288     QCOMPARE(local2.dateTime(), QDateTime(QDate(2006, 1, 6), QTime(2, 40, 0), Qt::LocalTime));
2289     KDateTime local3 = local1.addDays(184);
2290     QVERIFY(local3.isLocalZone());
2291     QCOMPARE(local3.dateTime(), QDateTime(QDate(2006, 1, 6), QTime(3, 40, 0), Qt::LocalTime));
2292     KDateTime local4 = local1.addMonths(6);
2293     QVERIFY(local4.isLocalZone());
2294     QCOMPARE(local4.dateTime(), local3.dateTime());
2295     KDateTime local5 = local1.addYears(4);
2296     QVERIFY(local5.isLocalZone());
2297     QCOMPARE(local5.dateTime(), QDateTime(QDate(2009, 7, 6), QTime(3, 40, 0), Qt::LocalTime));
2298     QCOMPARE(local1.secsTo(local2), 184 * 86400);
2299     QCOMPARE(local1.secsTo(local3), 184 * 86400 + 3600);
2300     QCOMPARE(local1.daysTo(local2), 184);
2301     QCOMPARE(local1.daysTo(local3), 184);
2302     QVERIFY(local1 < local2);
2303     QVERIFY(!(local2 < local1));
2304     QVERIFY(!(local2 == local3));
2305 
2306     // Clock time
2307     KDateTime clock1(QDate(2005, 7, 6), QTime(3, 40, 0), KDateTime::ClockTime);
2308     KDateTime clock2 = clock1.addSecs(184 * 86400);
2309     QVERIFY(clock2.isClockTime());
2310     QCOMPARE(clock2.dateTime(), QDateTime(QDate(2006, 1, 6), QTime(3, 40, 0), Qt::LocalTime));
2311     KDateTime clock3 = clock1.addDays(184);
2312     QVERIFY(clock3.isClockTime());
2313     QCOMPARE(clock2.dateTime(), clock3.dateTime());
2314     KDateTime clock4 = clock1.addMonths(6);
2315     QVERIFY(clock4.isClockTime());
2316     QCOMPARE(clock2.dateTime(), clock4.dateTime());
2317     KDateTime clock5 = clock1.addYears(4);
2318     QVERIFY(clock5.isClockTime());
2319     QCOMPARE(clock5.dateTime(), QDateTime(QDate(2009, 7, 6), QTime(3, 40, 0), Qt::LocalTime));
2320     QCOMPARE(clock1.secsTo(clock2), 184 * 86400);
2321     QCOMPARE(clock1.secsTo(clock3), 184 * 86400);
2322     QCOMPARE(clock1.daysTo(clock2), 184);
2323     QCOMPARE(clock1.daysTo(clock3), 184);
2324     QVERIFY(clock1 < clock2);
2325     QVERIFY(!(clock2 < clock1));
2326     QVERIFY(clock2 == clock3);
2327 
2328     // Mixed timeSpecs
2329     QCOMPARE(utc1.secsTo(offset1), 5400);
2330     QCOMPARE(utc1.secsTo(offset2), 184 * 86400 + 5400);
2331     QCOMPARE(offset2.secsTo(utc1), -(184 * 86400 + 5400));
2332     QVERIFY(utc1 < offset1);
2333     QVERIFY(utc1 <= offset1);
2334     QVERIFY(!(offset1 < utc1));
2335     QVERIFY(!(offset1 <= utc1));
2336     QCOMPARE(utc1.secsTo(zone1), -3600);
2337     QCOMPARE(utc1.secsTo(zone2), 184 * 86400 - 3600);
2338     QCOMPARE(zone2.secsTo(utc1), -(184 * 86400 - 3600));
2339     QVERIFY(utc1 > zone1);
2340     QVERIFY(utc1 >= zone1);
2341     QVERIFY(!(zone1 > utc1));
2342     QVERIFY(!(zone1 >= utc1));
2343     QCOMPARE(utc1.secsTo(local1), 7 * 3600);
2344     QCOMPARE(utc1.secsTo(local2), 184 * 86400 + 7 * 3600);
2345     QCOMPARE(local2.secsTo(utc1), -(184 * 86400 + 7 * 3600));
2346     QVERIFY(utc1 < local1);
2347     QVERIFY(utc1 <= local1);
2348     QVERIFY(!(local1 < utc1));
2349     QVERIFY(!(local1 <= utc1));
2350     QCOMPARE(utc1.secsTo(clock1), 7 * 3600);
2351     QCOMPARE(utc1.secsTo(clock2), 184 * 86400 + 8 * 3600);
2352     QCOMPARE(clock2.secsTo(utc1), -(184 * 86400 + 8 * 3600));
2353     QVERIFY(utc1 < clock1);
2354     QVERIFY(utc1 <= clock1);
2355     QVERIFY(!(clock1 < utc1));
2356     QVERIFY(!(clock1 <= utc1));
2357 
2358     QCOMPARE(offset1.secsTo(zone1), -9000);
2359     QCOMPARE(offset1.secsTo(zone2), 184 * 86400 - 9000);
2360     QCOMPARE(zone2.secsTo(offset1), -(184 * 86400 - 9000));
2361     QVERIFY(offset1 > zone1);
2362     QVERIFY(offset1 >= zone1);
2363     QVERIFY(!(zone1 > offset1));
2364     QVERIFY(!(zone1 >= offset1));
2365     QCOMPARE(offset1.secsTo(local1), 7 * 3600 - 5400);
2366     QCOMPARE(offset1.secsTo(local2), 184 * 86400 + 7 * 3600 - 5400);
2367     QCOMPARE(local2.secsTo(offset1), -(184 * 86400 + 7 * 3600 - 5400));
2368     QVERIFY(offset1 < local1);
2369     QVERIFY(offset1 <= local1);
2370     QVERIFY(!(local1 < offset1));
2371     QVERIFY(!(local1 <= offset1));
2372     QCOMPARE(offset1.secsTo(clock1), 7 * 3600 - 5400);
2373     QCOMPARE(offset1.secsTo(clock2), 184 * 86400 + 8 * 3600 - 5400);
2374     QCOMPARE(clock2.secsTo(offset1), -(184 * 86400 + 8 * 3600 - 5400));
2375     QVERIFY(offset1 < clock1);
2376     QVERIFY(offset1 <= clock1);
2377     QVERIFY(!(clock1 < offset1));
2378     QVERIFY(!(clock1 <= offset1));
2379 
2380     QCOMPARE(zone1.secsTo(local1), 8 * 3600);
2381     QCOMPARE(zone1.secsTo(local2), 184 * 86400 + 8 * 3600);
2382     QCOMPARE(local2.secsTo(zone1), -(184 * 86400 + 8 * 3600));
2383     QVERIFY(zone1 < local1);
2384     QVERIFY(zone1 <= local1);
2385     QVERIFY(!(local1 < zone1));
2386     QVERIFY(!(local1 <= zone1));
2387     QCOMPARE(zone1.secsTo(clock1), 8 * 3600);
2388     QCOMPARE(zone1.secsTo(clock2), 184 * 86400 + 9 * 3600);
2389     QCOMPARE(clock2.secsTo(zone1), -(184 * 86400 + 9 * 3600));
2390     QVERIFY(zone1 < clock1);
2391     QVERIFY(zone1 <= clock1);
2392     QVERIFY(!(clock1 < zone1));
2393     QVERIFY(!(clock1 <= zone1));
2394 
2395     QCOMPARE(local1.secsTo(clock1), 0);
2396     QCOMPARE(local1.secsTo(clock2), 184 * 86400 + 3600);
2397     QCOMPARE(clock2.secsTo(local1), -(184 * 86400 + 3600));
2398     QVERIFY(local1 == clock1);
2399     QVERIFY(local1 <= clock1);
2400     QVERIFY(local1 >= clock1);
2401     QVERIFY(!(local1 < clock1));
2402     QVERIFY(!(local1 > clock1));
2403 
2404     // Restore the original local time zone
2405     if (originalZone.isEmpty()) {
2406         ::unsetenv("TZ");
2407     } else {
2408         qputenv("TZ", originalZone);
2409     }
2410     ::tzset();
2411 }
2412 
2413 void KDateTimeTest::addMSecs()
2414 {
2415     KTimeZone london = KSystemTimeZones::zone("Europe/London");
2416     KTimeZone losAngeles = KSystemTimeZones::zone("America/Los_Angeles");
2417 
2418     // Ensure that local time is different from UTC and different from 'london'
2419     QByteArray originalZone = qgetenv("TZ");   // save the original local time zone
2420     qputenv("TZ", ":America/Los_Angeles");
2421     ::tzset();
2422 
2423     // UTC
2424     KDateTime utc1(QDate(2005, 7, 6), QTime(23, 59, 0, 100), KDateTime::UTC);
2425     KDateTime utc2 = utc1.addMSecs(59899);
2426     QVERIFY(utc2.isUtc());
2427     QCOMPARE(utc2.dateTime(), QDateTime(QDate(2005, 7, 6), QTime(23, 59, 59, 999), Qt::UTC));
2428     utc2 = utc1.addMSecs(59900);
2429     QVERIFY(utc2.isUtc());
2430     QCOMPARE(utc2.dateTime(), QDateTime(QDate(2005, 7, 7), QTime(0, 0, 0, 0), Qt::UTC));
2431     KDateTime utc1a(QDate(2005, 7, 6), QTime(0, 0, 5, 100), KDateTime::UTC);
2432     utc2 = utc1a.addMSecs(-5100);
2433     QVERIFY(utc2.isUtc());
2434     QCOMPARE(utc2.dateTime(), QDateTime(QDate(2005, 7, 6), QTime(0, 0, 0, 0), Qt::UTC));
2435     utc2 = utc1a.addMSecs(-5101);
2436     QVERIFY(utc2.isUtc());
2437     QCOMPARE(utc2.dateTime(), QDateTime(QDate(2005, 7, 5), QTime(23, 59, 59, 999), Qt::UTC));
2438 
2439     // UTC offset
2440     KDateTime offset1(QDate(2005, 7, 6), QTime(3, 40, 0, 100), KDateTime::Spec::OffsetFromUTC(-5400)); // -0130
2441     KDateTime offset2 = offset1.addMSecs(5899);
2442     QVERIFY(offset2.isOffsetFromUtc());
2443     QCOMPARE(offset2.utcOffset(), -5400);
2444     QCOMPARE(offset2.dateTime(), QDateTime(QDate(2005, 7, 6), QTime(3, 40, 5, 999), Qt::LocalTime));
2445     offset2 = offset1.addMSecs(5900);
2446     QVERIFY(offset2.isOffsetFromUtc());
2447     QCOMPARE(offset2.utcOffset(), -5400);
2448     QCOMPARE(offset2.dateTime(), QDateTime(QDate(2005, 7, 6), QTime(3, 40, 6, 0), Qt::LocalTime));
2449     offset2 = offset1.addMSecs(-5100);
2450     QVERIFY(offset2.isOffsetFromUtc());
2451     QCOMPARE(offset2.utcOffset(), -5400);
2452     QCOMPARE(offset2.dateTime(), QDateTime(QDate(2005, 7, 6), QTime(3, 39, 55, 0), Qt::LocalTime));
2453     offset2 = offset1.addMSecs(-5101);
2454     QVERIFY(offset2.isOffsetFromUtc());
2455     QCOMPARE(offset2.utcOffset(), -5400);
2456     QCOMPARE(offset2.dateTime(), QDateTime(QDate(2005, 7, 6), QTime(3, 39, 54, 999), Qt::LocalTime));
2457 
2458     // Zone
2459     KDateTime zone1(QDate(2002, 3, 31), QTime(0, 40, 0, 100), london); // time changes at 01:00 UTC
2460     KDateTime zone2 = zone1.addMSecs(3600 * 1000 + 899);
2461     QCOMPARE(zone2.timeZone(), london);
2462     QCOMPARE(zone2.dateTime(), QDateTime(QDate(2002, 3, 31), QTime(2, 40, 0, 999), Qt::LocalTime));
2463     zone2 = zone1.addMSecs(3600 * 1000 + 900);
2464     QCOMPARE(zone2.timeZone(), london);
2465     QCOMPARE(zone2.dateTime(), QDateTime(QDate(2002, 3, 31), QTime(2, 40, 1, 0), Qt::LocalTime));
2466     KDateTime zone1a(QDate(2002, 3, 31), QTime(2, 40, 0, 100), london); // time changes at 01:00 UTC
2467     zone2 = zone1a.addMSecs(-(3600 * 1000 + 100));
2468     QCOMPARE(zone2.timeZone(), london);
2469     QCOMPARE(zone2.dateTime(), QDateTime(QDate(2002, 3, 31), QTime(0, 40, 0, 0), Qt::LocalTime));
2470     zone2 = zone1a.addMSecs(-(3600 * 1000 + 101));
2471     QCOMPARE(zone2.timeZone(), london);
2472     QCOMPARE(zone2.dateTime(), QDateTime(QDate(2002, 3, 31), QTime(0, 39, 59, 999), Qt::LocalTime));
2473 
2474     // Local zone
2475     KDateTime local1(QDate(2002, 4, 7), QTime(1, 59, 0, 100), KDateTime::LocalZone); // time changes at 02:00 local
2476     KDateTime local2 = local1.addMSecs(59899);
2477     QVERIFY(local2.isLocalZone());
2478     QCOMPARE(local2.timeZone(), losAngeles);
2479     QCOMPARE(local2.dateTime(), QDateTime(QDate(2002, 4, 7), QTime(1, 59, 59, 999), Qt::LocalTime));
2480     local2 = local1.addMSecs(59900);
2481     QVERIFY(local2.isLocalZone());
2482     QCOMPARE(local2.timeZone(), losAngeles);
2483     QCOMPARE(local2.dateTime(), QDateTime(QDate(2002, 4, 7), QTime(3, 0, 0, 0), Qt::LocalTime));
2484     KDateTime local1a(QDate(2002, 4, 7), QTime(3, 0, 0, 100), KDateTime::LocalZone); // time changes at 02:00 local
2485     local2 = local1a.addMSecs(-100);
2486     QVERIFY(local2.isLocalZone());
2487     QCOMPARE(local2.timeZone(), losAngeles);
2488     QCOMPARE(local2.dateTime(), QDateTime(QDate(2002, 4, 7), QTime(3, 0, 0, 0), Qt::LocalTime));
2489     local2 = local1a.addMSecs(-101);
2490     QVERIFY(local2.isLocalZone());
2491     QCOMPARE(local2.timeZone(), losAngeles);
2492     QCOMPARE(local2.dateTime(), QDateTime(QDate(2002, 4, 7), QTime(1, 59, 59, 999), Qt::LocalTime));
2493 
2494     // Clock time
2495     KDateTime clock1(QDate(2002, 4, 7), QTime(1, 59, 0, 100), KDateTime::ClockTime);
2496     KDateTime clock2 = clock1.addMSecs(59899);
2497     QVERIFY(clock2.isClockTime());
2498     QCOMPARE(clock2.dateTime(), QDateTime(QDate(2002, 4, 7), QTime(1, 59, 59, 999), Qt::LocalTime));
2499     clock2 = clock1.addMSecs(59900);
2500     QVERIFY(clock2.isClockTime());
2501     QCOMPARE(clock2.dateTime(), QDateTime(QDate(2002, 4, 7), QTime(2, 0, 0, 0), Qt::LocalTime));
2502     KDateTime clock1a(QDate(2002, 4, 7), QTime(0, 0, 0, 100), KDateTime::ClockTime);
2503     clock2 = clock1a.addMSecs(-100);
2504     QVERIFY(clock2.isClockTime());
2505     QCOMPARE(clock2.dateTime(), QDateTime(QDate(2002, 4, 7), QTime(0, 0, 0, 0), Qt::LocalTime));
2506     clock2 = clock1a.addMSecs(-101);
2507     QVERIFY(clock2.isClockTime());
2508     QCOMPARE(clock2.dateTime(), QDateTime(QDate(2002, 4, 6), QTime(23, 59, 59, 999), Qt::LocalTime));
2509 
2510     // Restore the original local time zone
2511     if (originalZone.isEmpty()) {
2512         ::unsetenv("TZ");
2513     } else {
2514         qputenv("TZ", originalZone);
2515     }
2516     ::tzset();
2517 }
2518 
2519 void KDateTimeTest::addSubtractDate()
2520 {
2521     KTimeZone london = KSystemTimeZones::zone("Europe/London");
2522     KTimeZone losAngeles = KSystemTimeZones::zone("America/Los_Angeles");
2523 
2524     // Ensure that local time is different from UTC and different from 'london'
2525     QByteArray originalZone = qgetenv("TZ");   // save the original local time zone
2526     qputenv("TZ", ":America/Los_Angeles");
2527     ::tzset();
2528 
2529     // UTC
2530     KDateTime utc1(QDate(2005, 7, 6), KDateTime::Spec(KDateTime::UTC));
2531     KDateTime utc2 = utc1.addSecs(184 * 86400 + 100);
2532     QVERIFY(utc2.isUtc());
2533     QVERIFY(utc2.isDateOnly());
2534     QCOMPARE(utc2.dateTime(), QDateTime(QDate(2006, 1, 6), QTime(0, 0, 0), Qt::UTC));
2535     KDateTime utc3 = utc1.addDays(184);
2536     QVERIFY(utc3.isUtc());
2537     QVERIFY(utc3.isDateOnly());
2538     QCOMPARE(utc2.dateTime(), utc3.dateTime());
2539     KDateTime utc4 = utc1.addMonths(6);
2540     QVERIFY(utc4.isUtc());
2541     QVERIFY(utc4.isDateOnly());
2542     QCOMPARE(utc2.dateTime(), utc4.dateTime());
2543     KDateTime utc5 = utc1.addYears(4);
2544     QVERIFY(utc5.isUtc());
2545     QVERIFY(utc5.isDateOnly());
2546     QCOMPARE(utc5.dateTime(), QDateTime(QDate(2009, 7, 6), QTime(0, 0, 0), Qt::UTC));
2547     QCOMPARE(utc1.secsTo(utc2), 184 * 86400);
2548     QCOMPARE(utc1.secsTo(utc3), 184 * 86400);
2549     QCOMPARE(utc1.daysTo(utc2), 184);
2550     QVERIFY(utc1 < utc2);
2551     QVERIFY(!(utc2 < utc1));
2552     QVERIFY(utc2 == utc3);
2553 
2554     // UTC offset
2555     KDateTime offset1(QDate(2005, 7, 6), KDateTime::Spec::OffsetFromUTC(-5400)); // -0130
2556     KDateTime offset2 = offset1.addSecs(184 * 86400);
2557     QVERIFY(offset2.isDateOnly());
2558     QVERIFY(offset2.isOffsetFromUtc());
2559     QCOMPARE(offset2.utcOffset(), -5400);
2560     QCOMPARE(offset2.dateTime(), QDateTime(QDate(2006, 1, 6), QTime(0, 0, 0), Qt::LocalTime));
2561     KDateTime offset3 = offset1.addDays(184);
2562     QVERIFY(offset3.isDateOnly());
2563     QVERIFY(offset3.isOffsetFromUtc());
2564     QCOMPARE(offset3.utcOffset(), -5400);
2565     QCOMPARE(offset2.dateTime(), offset3.dateTime());
2566     KDateTime offset4 = offset1.addMonths(6);
2567     QVERIFY(offset4.isDateOnly());
2568     QVERIFY(offset4.isOffsetFromUtc());
2569     QCOMPARE(offset4.utcOffset(), -5400);
2570     QCOMPARE(offset2.dateTime(), offset4.dateTime());
2571     KDateTime offset5 = offset1.addYears(4);
2572     QVERIFY(offset5.isDateOnly());
2573     QVERIFY(offset5.isOffsetFromUtc());
2574     QCOMPARE(offset5.utcOffset(), -5400);
2575     QCOMPARE(offset5.dateTime(), QDateTime(QDate(2009, 7, 6), QTime(0, 0, 0), Qt::LocalTime));
2576     QCOMPARE(offset1.secsTo(offset2), 184 * 86400);
2577     QCOMPARE(offset1.secsTo(offset3), 184 * 86400);
2578     QCOMPARE(offset1.daysTo(offset2), 184);
2579     QVERIFY(offset1 < offset2);
2580     QVERIFY(!(offset2 < offset1));
2581     QVERIFY(offset2 == offset3);
2582 
2583     // Zone
2584     KDateTime zone1(QDate(2005, 7, 6), london);
2585     KDateTime zone2 = zone1.addSecs(184 * 86400);
2586     QVERIFY(zone2.isDateOnly());
2587     QCOMPARE(zone2.timeZone(), london);
2588     QCOMPARE(zone2.dateTime(), QDateTime(QDate(2006, 1, 6), QTime(0, 0, 0), Qt::LocalTime));
2589     KDateTime zone3 = zone1.addDays(184);
2590     QVERIFY(zone3.isDateOnly());
2591     QCOMPARE(zone3.timeZone(), london);
2592     QCOMPARE(zone3.dateTime(), QDateTime(QDate(2006, 1, 6), QTime(0, 0, 0), Qt::LocalTime));
2593     KDateTime zone4 = zone1.addMonths(6);
2594     QVERIFY(zone4.isDateOnly());
2595     QCOMPARE(zone4.timeZone(), london);
2596     QCOMPARE(zone4.dateTime(), zone3.dateTime());
2597     KDateTime zone5 = zone1.addYears(4);
2598     QVERIFY(zone5.isDateOnly());
2599     QCOMPARE(zone5.timeZone(), london);
2600     QCOMPARE(zone5.dateTime(), QDateTime(QDate(2009, 7, 6), QTime(0, 0, 0), Qt::LocalTime));
2601     QCOMPARE(zone1.secsTo(zone2), 184 * 86400);
2602     QCOMPARE(zone1.secsTo(zone3), 184 * 86400);
2603     QCOMPARE(zone1.daysTo(zone2), 184);
2604     QCOMPARE(zone1.daysTo(zone3), 184);
2605     QVERIFY(zone1 < zone2);
2606     QVERIFY(!(zone2 < zone1));
2607     QVERIFY(zone2 == zone3);
2608 
2609     // Local zone
2610     KDateTime local1(QDate(2005, 7, 6), KDateTime::Spec(KDateTime::LocalZone));
2611     KDateTime local2 = local1.addSecs(184 * 86400);
2612     QVERIFY(local2.isDateOnly());
2613     QVERIFY(local2.isLocalZone());
2614     QCOMPARE(local2.timeZone(), losAngeles);
2615     QCOMPARE(local2.dateTime(), QDateTime(QDate(2006, 1, 6), QTime(0, 0, 0), Qt::LocalTime));
2616     KDateTime local3 = local1.addDays(184);
2617     QVERIFY(local3.isDateOnly());
2618     QVERIFY(local3.isLocalZone());
2619     QCOMPARE(local3.dateTime(), QDateTime(QDate(2006, 1, 6), QTime(0, 0, 0), Qt::LocalTime));
2620     KDateTime local4 = local1.addMonths(6);
2621     QVERIFY(local4.isDateOnly());
2622     QVERIFY(local4.isLocalZone());
2623     QCOMPARE(local4.dateTime(), local3.dateTime());
2624     KDateTime local5 = local1.addYears(4);
2625     QVERIFY(local5.isDateOnly());
2626     QVERIFY(local5.isLocalZone());
2627     QCOMPARE(local5.dateTime(), QDateTime(QDate(2009, 7, 6), QTime(0, 0, 0), Qt::LocalTime));
2628     QCOMPARE(local1.secsTo(local2), 184 * 86400);
2629     QCOMPARE(local1.secsTo(local3), 184 * 86400);
2630     QCOMPARE(local1.daysTo(local2), 184);
2631     QCOMPARE(local1.daysTo(local3), 184);
2632     QVERIFY(local1 < local2);
2633     QVERIFY(!(local2 < local1));
2634     QVERIFY(local2 == local3);
2635 
2636     // Clock time
2637     KDateTime clock1(QDate(2005, 7, 6), KDateTime::Spec(KDateTime::ClockTime));
2638     KDateTime clock2 = clock1.addSecs(184 * 86400);
2639     QVERIFY(clock2.isDateOnly());
2640     QVERIFY(clock2.isClockTime());
2641     QCOMPARE(clock2.dateTime(), QDateTime(QDate(2006, 1, 6), QTime(0, 0, 0), Qt::LocalTime));
2642     KDateTime clock3 = clock1.addDays(184);
2643     QVERIFY(clock3.isDateOnly());
2644     QVERIFY(clock3.isClockTime());
2645     QCOMPARE(clock2.dateTime(), clock3.dateTime());
2646     KDateTime clock4 = clock1.addMonths(6);
2647     QVERIFY(clock4.isDateOnly());
2648     QVERIFY(clock4.isClockTime());
2649     QCOMPARE(clock2.dateTime(), clock4.dateTime());
2650     KDateTime clock5 = clock1.addYears(4);
2651     QVERIFY(clock5.isDateOnly());
2652     QVERIFY(clock5.isClockTime());
2653     QCOMPARE(clock5.dateTime(), QDateTime(QDate(2009, 7, 6), QTime(0, 0, 0), Qt::LocalTime));
2654     QCOMPARE(clock1.secsTo(clock2), 184 * 86400);
2655     QCOMPARE(clock1.secsTo(clock3), 184 * 86400);
2656     QCOMPARE(clock1.daysTo(clock2), 184);
2657     QCOMPARE(clock1.daysTo(clock3), 184);
2658     QVERIFY(clock1 < clock2);
2659     QVERIFY(!(clock2 < clock1));
2660     QVERIFY(clock2 == clock3);
2661 
2662     // Mixed timeSpecs
2663     QCOMPARE(utc1.secsTo(offset1), 0);
2664     QCOMPARE(utc1.secsTo(offset2), 184 * 86400);
2665     QCOMPARE(offset2.secsTo(utc1), -(184 * 86400));
2666     QVERIFY(!(utc1 < offset1));
2667     QVERIFY(utc1 <= offset1);
2668     QVERIFY(!(offset1 < utc1));
2669     QVERIFY(offset1 <= utc1);
2670     QCOMPARE(utc1.secsTo(zone1), 0);
2671     QCOMPARE(utc1.secsTo(zone2), 184 * 86400);
2672     QCOMPARE(zone2.secsTo(utc1), -(184 * 86400));
2673     QVERIFY(!(utc1 > zone1));
2674     QVERIFY(utc1 >= zone1);
2675     QVERIFY(!(zone1 > utc1));
2676     QVERIFY(zone1 >= utc1);
2677     QCOMPARE(utc1.secsTo(local1), 0);
2678     QCOMPARE(utc1.secsTo(local2), 184 * 86400);
2679     QCOMPARE(local2.secsTo(utc1), -(184 * 86400));
2680     QVERIFY(!(utc1 < local1));
2681     QVERIFY(utc1 <= local1);
2682     QVERIFY(!(local1 < utc1));
2683     QVERIFY(local1 <= utc1);
2684     QCOMPARE(utc1.secsTo(clock1), 0);
2685     QCOMPARE(utc1.secsTo(clock2), 184 * 86400);
2686     QCOMPARE(clock2.secsTo(utc1), -(184 * 86400));
2687     QVERIFY(!(utc1 < clock1));
2688     QVERIFY(utc1 <= clock1);
2689     QVERIFY(!(clock1 < utc1));
2690     QVERIFY(clock1 <= utc1);
2691 
2692     QCOMPARE(offset1.secsTo(zone1), 0);
2693     QCOMPARE(offset1.secsTo(zone2), 184 * 86400);
2694     QCOMPARE(zone2.secsTo(offset1), -(184 * 86400));
2695     QVERIFY(!(offset1 > zone1));
2696     QVERIFY(offset1 >= zone1);
2697     QVERIFY(!(zone1 > offset1));
2698     QVERIFY(zone1 >= offset1);
2699     QCOMPARE(offset1.secsTo(local1), 0);
2700     QCOMPARE(offset1.secsTo(local2), 184 * 86400);
2701     QCOMPARE(local2.secsTo(offset1), -(184 * 86400));
2702     QVERIFY(!(offset1 < local1));
2703     QVERIFY(offset1 <= local1);
2704     QVERIFY(!(local1 < offset1));
2705     QVERIFY(local1 <= offset1);
2706     QCOMPARE(offset1.secsTo(clock1), 0);
2707     QCOMPARE(offset1.secsTo(clock2), 184 * 86400);
2708     QCOMPARE(clock2.secsTo(offset1), -(184 * 86400));
2709     QVERIFY(!(offset1 < clock1));
2710     QVERIFY(offset1 <= clock1);
2711     QVERIFY(!(clock1 < offset1));
2712     QVERIFY(clock1 <= offset1);
2713 
2714     QCOMPARE(zone1.secsTo(local1), 0);
2715     QCOMPARE(zone1.secsTo(local2), 184 * 86400);
2716     QCOMPARE(local2.secsTo(zone1), -(184 * 86400));
2717     QVERIFY(!(zone1 < local1));
2718     QVERIFY(zone1 <= local1);
2719     QVERIFY(!(local1 < zone1));
2720     QVERIFY(local1 <= zone1);
2721     QCOMPARE(zone1.secsTo(clock1), 0);
2722     QCOMPARE(zone1.secsTo(clock2), 184 * 86400);
2723     QCOMPARE(clock2.secsTo(zone1), -(184 * 86400));
2724     QVERIFY(!(zone1 < clock1));
2725     QVERIFY(zone1 <= clock1);
2726     QVERIFY(!(clock1 < zone1));
2727     QVERIFY(clock1 <= zone1);
2728 
2729     QCOMPARE(local1.secsTo(clock1), 0);
2730     QCOMPARE(local1.secsTo(clock2), 184 * 86400);
2731     QCOMPARE(clock2.secsTo(local1), -(184 * 86400));
2732     QVERIFY(local1 == clock1);
2733     QVERIFY(local1 <= clock1);
2734     QVERIFY(local1 >= clock1);
2735     QVERIFY(!(local1 < clock1));
2736     QVERIFY(!(local1 > clock1));
2737 
2738     // Mixed date/time and date-only
2739 
2740     // UTC
2741     utc3.setTime(QTime(13, 14, 15));
2742     QVERIFY(!utc3.isDateOnly());
2743     QCOMPARE(utc3.time(), QTime(13, 14, 15));
2744     QCOMPARE(utc1.secsTo(utc3), 184 * 86400);
2745 
2746     KDateTime utc1t(QDate(2005, 7, 6), QTime(3, 40, 0), KDateTime::UTC);
2747     QCOMPARE(utc1t.secsTo(utc2), 184 * 86400);
2748 
2749     // UTC offset
2750     offset3.setTime(QTime(13, 14, 15));
2751     QVERIFY(!offset3.isDateOnly());
2752     QCOMPARE(offset3.time(), QTime(13, 14, 15));
2753     QCOMPARE(offset1.secsTo(offset3), 184 * 86400);
2754 
2755     KDateTime offset1t(QDate(2005, 7, 6), QTime(3, 40, 0), KDateTime::Spec::OffsetFromUTC(-5400)); // -0130
2756     QCOMPARE(offset1t.secsTo(offset2), 184 * 86400);
2757 
2758     KDateTime offset2t(QDate(2005, 7, 6), QTime(0, 40, 0), KDateTime::Spec::OffsetFromUTC(5400)); // +0130
2759 
2760     // Zone
2761     zone3.setTime(QTime(13, 14, 15));
2762     QVERIFY(!zone3.isDateOnly());
2763     QCOMPARE(zone3.time(), QTime(13, 14, 15));
2764     QCOMPARE(zone1.secsTo(zone3), 184 * 86400);
2765 
2766     KDateTime zone1t(QDate(2005, 7, 6), QTime(3, 40, 0), london);
2767     QCOMPARE(zone1t.secsTo(zone2), 184 * 86400);
2768 
2769     // Local zone
2770     local3.setTime(QTime(13, 14, 15));
2771     QVERIFY(!local3.isDateOnly());
2772     QCOMPARE(local3.time(), QTime(13, 14, 15));
2773     QCOMPARE(local1.secsTo(local3), 184 * 86400);
2774 
2775     KDateTime local1t(QDate(2005, 7, 6), QTime(3, 40, 0), KDateTime::LocalZone);
2776     QCOMPARE(local1t.secsTo(local2), 184 * 86400);
2777 
2778     KDateTime local2t(QDate(2005, 7, 5), QTime(23, 40, 0), KDateTime::LocalZone);
2779 
2780     // Clock time
2781     clock3.setTime(QTime(13, 14, 15));
2782     QVERIFY(!clock3.isDateOnly());
2783     QCOMPARE(clock3.time(), QTime(13, 14, 15));
2784     QCOMPARE(clock1.secsTo(clock3), 184 * 86400);
2785 
2786     KDateTime clock1t(QDate(2005, 7, 6), QTime(3, 40, 0), KDateTime::ClockTime);
2787     QCOMPARE(clock1t.secsTo(clock2), 184 * 86400);
2788 
2789     // Mixed timeSpecs
2790     QCOMPARE(utc1t.secsTo(offset1), 0);
2791     QVERIFY(utc1t != offset1);
2792     QVERIFY(offset1 != utc1t);
2793     QVERIFY(!(utc1t < offset1));
2794     QVERIFY(utc1t <= offset1);
2795     QVERIFY(!(offset1 < utc1t));
2796     QVERIFY(offset1 <= utc1t);
2797     QCOMPARE(utc1.secsTo(offset2t), -86400);
2798     QCOMPARE(offset2t.secsTo(utc1), 86400);
2799     QVERIFY(utc1 != offset2t);
2800     QVERIFY(offset2t != utc1);
2801     QVERIFY(utc1 > offset2t);
2802     QVERIFY(utc1 >= offset2t);
2803     QVERIFY(offset2t < utc1);
2804     QVERIFY(offset2t <= utc1);
2805     QCOMPARE(utc1t.secsTo(offset2), 184 * 86400);
2806     QCOMPARE(offset2.secsTo(utc1t), -(184 * 86400));
2807     QCOMPARE(utc1t.secsTo(zone1), 0);
2808     QVERIFY(utc1t != zone1);
2809     QVERIFY(zone1 != utc1t);
2810     QVERIFY(!(utc1t < zone1));
2811     QVERIFY(!(utc1t > zone1));
2812     QVERIFY(!(zone1 < utc1t));
2813     QVERIFY(!(zone1 > utc1t));
2814     QCOMPARE(utc1t.secsTo(zone2), 184 * 86400);
2815     QCOMPARE(zone2.secsTo(utc1t), -(184 * 86400));
2816     QVERIFY(utc1t != zone2);
2817     QVERIFY(zone2 != utc1t);
2818     QVERIFY(utc1t < zone2);
2819     QVERIFY(utc1t <= zone2);
2820     QVERIFY(!(zone2 < utc1t));
2821     QVERIFY(!(zone2 <= utc1t));
2822     QCOMPARE(utc1t.secsTo(local1), 86400);
2823     QCOMPARE(utc1t.secsTo(local2), 185 * 86400);
2824     QCOMPARE(local2.secsTo(utc1t), -(185 * 86400));
2825     QVERIFY(utc1t != local1);
2826     QVERIFY(local1 != utc1t);
2827     QVERIFY(utc1t < local1);
2828     QVERIFY(utc1t <= local1);
2829     QVERIFY(!(local1 < utc1t));
2830     QVERIFY(!(local1 <= utc1t));
2831     QCOMPARE(utc1.secsTo(local2t), 0);
2832     QCOMPARE(local2t.secsTo(utc1), 0);
2833     QVERIFY(utc1 != local2t);
2834     QVERIFY(local2t != utc1);
2835     QVERIFY(!(utc1 < local2t));
2836     QVERIFY(utc1 <= local2t);
2837     QVERIFY(!(local2t < utc1));
2838     QVERIFY(local2t <= utc1);
2839     QCOMPARE(utc1t.secsTo(clock1), 86400);
2840     QCOMPARE(utc1t.secsTo(clock2), 185 * 86400);
2841     QCOMPARE(clock2.secsTo(utc1t), -(185 * 86400));
2842     QVERIFY(utc1t != clock1);
2843     QVERIFY(clock1 != utc1t);
2844     QVERIFY(utc1t < clock1);
2845     QVERIFY(utc1t <= clock1);
2846     QVERIFY(!(clock1 < utc1t));
2847     QVERIFY(!(clock1 <= utc1t));
2848 
2849     QCOMPARE(offset1t.secsTo(zone1), 0);
2850     QCOMPARE(offset1t.secsTo(zone2), 184 * 86400);
2851     QCOMPARE(zone2.secsTo(offset1t), -(184 * 86400));
2852     QVERIFY(offset1t != zone1);
2853     QVERIFY(zone1 != offset1t);
2854     QVERIFY(!(offset1t > zone1));
2855     QVERIFY(offset1t >= zone1);
2856     QVERIFY(!(zone1 > offset1t));
2857     QVERIFY(zone1 >= offset1t);
2858     QCOMPARE(offset1t.secsTo(local1), 86400);
2859     QCOMPARE(offset1t.secsTo(local2), 185 * 86400);
2860     QCOMPARE(local2.secsTo(offset1t), -(185 * 86400));
2861     QVERIFY(offset1t != local1);
2862     QVERIFY(local1 != offset1t);
2863     QVERIFY(offset1t < local1);
2864     QVERIFY(offset1t <= local1);
2865     QVERIFY(!(local1 < offset1t));
2866     QVERIFY(!(local1 <= offset1t));
2867     QCOMPARE(offset1t.secsTo(clock1), 86400);
2868     QCOMPARE(offset1t.secsTo(clock2), 185 * 86400);
2869     QCOMPARE(clock2.secsTo(offset1t), -(185 * 86400));
2870     QVERIFY(offset1t != clock1);
2871     QVERIFY(clock1 != offset1t);
2872     QVERIFY(offset1t < clock1);
2873     QVERIFY(offset1t <= clock1);
2874     QVERIFY(!(clock1 < offset1t));
2875     QVERIFY(!(clock1 <= offset1t));
2876 
2877     QCOMPARE(zone1t.secsTo(local1), 86400);
2878     QCOMPARE(zone1t.secsTo(local2), 185 * 86400);
2879     QCOMPARE(local2.secsTo(zone1t), -(185 * 86400));
2880     QVERIFY(zone1t != local1);
2881     QVERIFY(local1 != zone1t);
2882     QVERIFY(zone1t < local1);
2883     QVERIFY(zone1t <= local1);
2884     QVERIFY(!(local1 < zone1t));
2885     QVERIFY(!(local1 <= zone1t));
2886     QCOMPARE(zone1t.secsTo(clock1), 86400);
2887     QCOMPARE(zone1t.secsTo(clock2), 185 * 86400);
2888     QCOMPARE(clock2.secsTo(zone1t), -(185 * 86400));
2889     QVERIFY(zone1t != clock1);
2890     QVERIFY(clock1 != zone1t);
2891     QVERIFY(zone1t < clock1);
2892     QVERIFY(zone1t <= clock1);
2893     QVERIFY(!(clock1 < zone1t));
2894     QVERIFY(!(clock1 <= zone1t));
2895 
2896     QCOMPARE(local1t.secsTo(clock1), 0);
2897     QCOMPARE(local1t.secsTo(clock2), 184 * 86400);
2898     QCOMPARE(clock2.secsTo(local1t), -(184 * 86400));
2899     QVERIFY(local1t != clock1);
2900     QVERIFY(local1t != clock1);
2901     QVERIFY(!(local1t < clock1));
2902     QVERIFY(local1t <= clock1);
2903     QVERIFY(!(local1t < clock1));
2904     QVERIFY(local1t <= clock1);
2905 
2906     // Restore the original local time zone
2907     if (originalZone.isEmpty()) {
2908         ::unsetenv("TZ");
2909     } else {
2910         qputenv("TZ", originalZone);
2911     }
2912     ::tzset();
2913 }
2914 
2915 ///////////////////////////////////////////
2916 // Tests around daylight saving time shifts
2917 ///////////////////////////////////////////
2918 
2919 void KDateTimeTest::dstShifts()
2920 {
2921     KTimeZone london = KSystemTimeZones::zone("Europe/London");
2922 
2923     // Ensure that local time is different from UTC and different from 'london'
2924     QByteArray originalZone = qgetenv("TZ");   // save the original local time zone
2925     qputenv("TZ", ":America/Los_Angeles");
2926     ::tzset();
2927 
2928     // Shift from DST to standard time for the UK in 2005 was at 2005-10-30 01:00 UTC.
2929     QDateTime qdt(QDate(2005, 10, 29), QTime(23, 59, 59), Qt::UTC);
2930     KDateTime dt(qdt, london);
2931     QVERIFY(!dt.isSecondOccurrence());
2932     QCOMPARE(dt.dateTime(), QDateTime(QDate(2005, 10, 30), QTime(0, 59, 59), Qt::LocalTime));
2933     dt = KDateTime(QDateTime(QDate(2005, 10, 30), QTime(0, 0, 0), Qt::UTC), london);
2934     QVERIFY(!dt.isSecondOccurrence());
2935     QCOMPARE(dt.dateTime(), QDateTime(QDate(2005, 10, 30), QTime(1, 0, 0), Qt::LocalTime));
2936     dt = KDateTime(QDateTime(QDate(2005, 10, 30), QTime(0, 59, 59), Qt::UTC), london);
2937     QVERIFY(!dt.isSecondOccurrence());
2938     QCOMPARE(dt.dateTime(), QDateTime(QDate(2005, 10, 30), QTime(1, 59, 59), Qt::LocalTime));
2939     dt = KDateTime(QDateTime(QDate(2005, 10, 30), QTime(1, 0, 0), Qt::UTC), london);
2940     QVERIFY(dt.isSecondOccurrence());
2941     QCOMPARE(dt.dateTime(), QDateTime(QDate(2005, 10, 30), QTime(1, 0, 0), Qt::LocalTime));
2942     dt = KDateTime(QDateTime(QDate(2005, 10, 30), QTime(1, 59, 59), Qt::UTC), london);
2943     QVERIFY(dt.isSecondOccurrence());
2944     QCOMPARE(dt.dateTime(), QDateTime(QDate(2005, 10, 30), QTime(1, 59, 59), Qt::LocalTime));
2945     dt = KDateTime(QDateTime(QDate(2005, 10, 30), QTime(2, 0, 0), Qt::UTC), london);
2946     QVERIFY(!dt.isSecondOccurrence());
2947     QCOMPARE(dt.dateTime(), QDateTime(QDate(2005, 10, 30), QTime(2, 0, 0), Qt::LocalTime));
2948 
2949     dt = KDateTime(QDateTime(QDate(2005, 10, 30), QTime(0, 59, 59), Qt::LocalTime), london);
2950     dt.setSecondOccurrence(true);   // this has no effect
2951     QCOMPARE(dt.toUtc().dateTime(), QDateTime(QDate(2005, 10, 29), QTime(23, 59, 59), Qt::UTC));
2952     dt = KDateTime(QDateTime(QDate(2005, 10, 30), QTime(1, 0, 0), Qt::LocalTime), london);
2953     QVERIFY(!dt.isSecondOccurrence());
2954     QCOMPARE(dt.toUtc().dateTime(), QDateTime(QDate(2005, 10, 30), QTime(0, 0, 0), Qt::UTC));
2955     dt = KDateTime(QDateTime(QDate(2005, 10, 30), QTime(1, 59, 59), Qt::LocalTime), london);
2956     QVERIFY(!dt.isSecondOccurrence());
2957     QCOMPARE(dt.toUtc().dateTime(), QDateTime(QDate(2005, 10, 30), QTime(0, 59, 59), Qt::UTC));
2958     dt = KDateTime(QDateTime(QDate(2005, 10, 30), QTime(1, 0, 0), Qt::LocalTime), london);
2959     dt.setSecondOccurrence(true);
2960     QCOMPARE(dt.toUtc().dateTime(), QDateTime(QDate(2005, 10, 30), QTime(1, 0, 0), Qt::UTC));
2961     QVERIFY(dt.isSecondOccurrence());
2962     dt = KDateTime(QDateTime(QDate(2005, 10, 30), QTime(1, 59, 59), Qt::LocalTime), london);
2963     dt.setSecondOccurrence(true);
2964     QCOMPARE(dt.toUtc().dateTime(), QDateTime(QDate(2005, 10, 30), QTime(1, 59, 59), Qt::UTC));
2965     QVERIFY(dt.isSecondOccurrence());
2966     dt = KDateTime(QDateTime(QDate(2005, 10, 30), QTime(2, 0, 0), Qt::LocalTime), london);
2967     dt.setSecondOccurrence(true);   // this has no effect
2968     QVERIFY(!dt.isSecondOccurrence());
2969     QCOMPARE(dt.toUtc().dateTime(), QDateTime(QDate(2005, 10, 30), QTime(2, 0, 0), Qt::UTC));
2970 
2971     dt = KDateTime(QDateTime(QDate(2005, 10, 30), QTime(0, 59, 59), Qt::LocalTime), london);
2972     KDateTime dt1 = dt.addSecs(1);   // local time 01:00:00
2973     QVERIFY(!dt1.isSecondOccurrence());
2974     dt1 = dt.addSecs(3600);   // local time 01:59:59
2975     QVERIFY(!dt1.isSecondOccurrence());
2976     dt1 = dt.addSecs(3601);   // local time 01:00:00
2977     QVERIFY(dt1.isSecondOccurrence());
2978     dt1 = dt.addSecs(7200);   // local time 01:59:59
2979     QVERIFY(dt1.isSecondOccurrence());
2980     dt1 = dt.addSecs(7201);   // local time 02:00:00
2981     QVERIFY(!dt1.isSecondOccurrence());
2982 
2983     QVERIFY(KDateTime(QDate(2005, 10, 29), london) == KDateTime(QDate(2005, 10, 29), KDateTime::Spec::OffsetFromUTC(3600)));
2984     QVERIFY(KDateTime(QDate(2005, 10, 30), london) != KDateTime(QDate(2005, 10, 30), KDateTime::Spec::OffsetFromUTC(3600)));
2985     QVERIFY(KDateTime(QDate(2005, 10, 30), london) != KDateTime(QDate(2005, 10, 30), KDateTime::Spec::OffsetFromUTC(0)));
2986     QVERIFY(KDateTime(QDate(2005, 10, 31), london) == KDateTime(QDate(2005, 10, 31), KDateTime::Spec::OffsetFromUTC(0)));
2987 
2988     // Restore the original local time zone
2989     if (originalZone.isEmpty()) {
2990         ::unsetenv("TZ");
2991     } else {
2992         qputenv("TZ", originalZone);
2993     }
2994     ::tzset();
2995 }
2996 
2997 ////////////////////
2998 // String conversion
2999 ////////////////////
3000 
3001 void KDateTimeTest::strings_iso8601()
3002 {
3003     KTimeZone london = KSystemTimeZones::zone("Europe/London");
3004     bool decpt = KLocale::global()->decimalSymbol() == QLatin1String(".");   // whether this locale uses '.' as decimal symbol
3005 
3006     // Ensure that local time is different from UTC and different from 'london'
3007     QByteArray originalZone = qgetenv("TZ");   // save the original local time zone
3008     qputenv("TZ", ":America/Los_Angeles");
3009     ::tzset();
3010 
3011     KDateTime dtlocal(QDate(1999, 12, 11), QTime(3, 45, 06, 12), KDateTime::LocalZone);
3012     QString s = dtlocal.toString(KDateTime::ISODate);
3013     if (decpt) {
3014         QCOMPARE(s, QString("1999-12-11T03:45:06.012-08:00"));
3015     } else {
3016         QCOMPARE(s, QString("1999-12-11T03:45:06,012-08:00"));
3017     }
3018     KDateTime dtlocal1 = KDateTime::fromString(s, KDateTime::ISODate);
3019     QCOMPARE(dtlocal1.dateTime().toUTC(), dtlocal.dateTime().toUTC());
3020     QCOMPARE(dtlocal1.timeType(), KDateTime::OffsetFromUTC);
3021     QCOMPARE(dtlocal1.utcOffset(), -8 * 3600);
3022     QVERIFY(dtlocal1 == dtlocal);
3023     dtlocal.setDateOnly(true);
3024     s = dtlocal.toString(KDateTime::ISODate);
3025     QCOMPARE(s, QString("1999-12-11T00:00:00-08:00"));
3026 
3027     KDateTime dtzone(QDate(1999, 6, 11), QTime(3, 45, 06, 12), london);
3028     s = dtzone.toString(KDateTime::ISODate);
3029     if (decpt) {
3030         QCOMPARE(s, QString("1999-06-11T03:45:06.012+01:00"));
3031     } else {
3032         QCOMPARE(s, QString("1999-06-11T03:45:06,012+01:00"));
3033     }
3034     KDateTime dtzone1 = KDateTime::fromString(s, KDateTime::ISODate);
3035     QCOMPARE(dtzone1.dateTime().toUTC(), dtzone.dateTime().toUTC());
3036     QCOMPARE(dtzone1.timeType(), KDateTime::OffsetFromUTC);
3037     QCOMPARE(dtzone1.utcOffset(), 3600);
3038     QVERIFY(dtzone1 == dtzone);
3039     dtzone.setDateOnly(true);
3040     s = dtzone.toString(KDateTime::ISODate);
3041     QCOMPARE(s, QString("1999-06-11T00:00:00+01:00"));
3042 
3043     KDateTime dtclock(QDate(1999, 12, 11), QTime(3, 45, 06), KDateTime::ClockTime);
3044     s = dtclock.toString(KDateTime::ISODate);
3045     QCOMPARE(s, QString("1999-12-11T03:45:06"));
3046     KDateTime dtclock1 = KDateTime::fromString(s, KDateTime::ISODate);
3047     QCOMPARE(dtclock1.dateTime(), dtclock.dateTime());
3048     QCOMPARE(dtclock1.timeType(), KDateTime::ClockTime);
3049     QVERIFY(dtclock1 == dtclock);
3050     dtclock.setDateOnly(true);
3051     s = dtclock.toString(KDateTime::ISODate);
3052     QCOMPARE(s, QString("1999-12-11"));
3053     dtclock1 = KDateTime::fromString(s, KDateTime::ISODate);
3054     QVERIFY(dtclock1.isDateOnly());
3055     QCOMPARE(dtclock1.timeType(), KDateTime::ClockTime);
3056     QCOMPARE(dtclock1.date(), QDate(1999, 12, 11));
3057 
3058     KDateTime dtutc(QDate(1999, 12, 11), QTime(3, 45, 00), KDateTime::UTC);
3059     s = dtutc.toString(KDateTime::ISODate);
3060     QCOMPARE(s, QString("1999-12-11T03:45:00Z"));
3061     KDateTime dtutc1 = KDateTime::fromString(s, KDateTime::ISODate);
3062     QCOMPARE(dtutc1.dateTime(), dtutc.dateTime());
3063     QCOMPARE(dtutc1.timeType(), KDateTime::UTC);
3064     QVERIFY(dtutc1 == dtutc);
3065     dtutc.setDateOnly(true);
3066     s = dtutc.toString(KDateTime::ISODate);
3067     QCOMPARE(s, QString("1999-12-11T00:00:00Z"));
3068 
3069     // Check signed years
3070     KDateTime dtneg(QDate(-1999, 12, 11), QTime(3, 45, 06), KDateTime::ClockTime);
3071     s = dtneg.toString(KDateTime::ISODate);
3072     QCOMPARE(s, QString("-1999-12-11T03:45:06"));
3073     KDateTime dtneg1 = KDateTime::fromString(s, KDateTime::ISODate);
3074     QCOMPARE(dtneg1.dateTime(), dtneg.dateTime());
3075     QCOMPARE(dtneg1.timeType(), KDateTime::ClockTime);
3076     QVERIFY(dtneg1 == dtneg);
3077     KDateTime dtneg2 = KDateTime::fromString(QString("-19991211T034506"), KDateTime::ISODate);
3078     QVERIFY(dtneg2 == dtneg);
3079 
3080     dtneg.setDateOnly(true);
3081     s = dtneg.toString(KDateTime::ISODate);
3082     QCOMPARE(s, QString("-1999-12-11"));
3083     dtneg1 = KDateTime::fromString(s, KDateTime::ISODate);
3084     QVERIFY(dtneg1.isDateOnly());
3085     QCOMPARE(dtneg1.timeType(), KDateTime::ClockTime);
3086     QCOMPARE(dtneg1.date(), QDate(-1999, 12, 11));
3087     dtneg2 = KDateTime::fromString(QString("-19991211"), KDateTime::ISODate);
3088     QVERIFY(dtneg2 == dtneg1);
3089 
3090     s = QString("+1999-12-11T03:45:06");
3091     KDateTime dtpos = KDateTime::fromString(s, KDateTime::ISODate);
3092     QCOMPARE(dtpos.dateTime(), QDateTime(QDate(1999, 12, 11), QTime(3, 45, 06)));
3093     QCOMPARE(dtpos.timeType(), KDateTime::ClockTime);
3094     KDateTime dtpos2 = KDateTime::fromString(QString("+19991211T034506"), KDateTime::ISODate);
3095     QVERIFY(dtpos2 == dtpos);
3096 
3097     dtpos.setDateOnly(true);
3098     s = QString("+1999-12-11");
3099     dtpos = KDateTime::fromString(s, KDateTime::ISODate);
3100     QVERIFY(dtpos.isDateOnly());
3101     QCOMPARE(dtpos.timeType(), KDateTime::ClockTime);
3102     QCOMPARE(dtpos.date(), QDate(1999, 12, 11));
3103     dtpos2 = KDateTime::fromString(QString("+19991211"), KDateTime::ISODate);
3104     QVERIFY(dtpos2 == dtpos);
3105 
3106     // Check years with >4 digits
3107     KDateTime dtbig(QDate(123456, 12, 11), QTime(3, 45, 06), KDateTime::ClockTime);
3108     s = dtbig.toString(KDateTime::ISODate);
3109     QCOMPARE(s, QString("123456-12-11T03:45:06"));
3110     KDateTime dtbig1 = KDateTime::fromString(s, KDateTime::ISODate);
3111     QCOMPARE(dtbig1.dateTime(), dtbig.dateTime());
3112     QCOMPARE(dtbig1.timeType(), KDateTime::ClockTime);
3113     QVERIFY(dtbig1 == dtbig);
3114     KDateTime dtbig2 = KDateTime::fromString(QString("1234561211T034506"), KDateTime::ISODate);
3115     QVERIFY(dtbig2 == dtbig);
3116 
3117     dtbig.setDateOnly(true);
3118     s = dtbig.toString(KDateTime::ISODate);
3119     QCOMPARE(s, QString("123456-12-11"));
3120     dtbig1 = KDateTime::fromString(s, KDateTime::ISODate);
3121     QVERIFY(dtbig1.isDateOnly());
3122     QCOMPARE(dtbig1.timeType(), KDateTime::ClockTime);
3123     QCOMPARE(dtbig1.date(), QDate(123456, 12, 11));
3124     dtbig2 = KDateTime::fromString(QString("1234561211"), KDateTime::ISODate);
3125     QVERIFY(dtbig2 == dtbig1);
3126 
3127     // Check basic format strings
3128     bool negZero = true;
3129     KDateTime dt = KDateTime::fromString(QString("20000301T1213"), KDateTime::ISODate, &negZero);
3130     QVERIFY(dt.timeType() == KDateTime::ClockTime);
3131     QVERIFY(!dt.isDateOnly());
3132     QVERIFY(!negZero);
3133     QCOMPARE(dt.dateTime(), QDateTime(QDate(2000, 3, 1), QTime(12, 13, 0), Qt::LocalTime));
3134     dt = KDateTime::fromString(QString("20000301"), KDateTime::ISODate, &negZero);
3135     QVERIFY(dt.timeType() == KDateTime::ClockTime);
3136     QVERIFY(dt.isDateOnly());
3137     QVERIFY(!negZero);
3138     QCOMPARE(dt.date(), QDate(2000, 3, 1));
3139     KDateTime::setFromStringDefault(KDateTime::UTC);
3140     dt = KDateTime::fromString(QString("20000301T1213"), KDateTime::ISODate);
3141     QVERIFY(dt.timeType() == KDateTime::UTC);
3142     QCOMPARE(dt.dateTime(), QDateTime(QDate(2000, 3, 1), QTime(12, 13, 0), Qt::UTC));
3143     KDateTime::setFromStringDefault(KDateTime::LocalZone);
3144     dt = KDateTime::fromString(QString("20000301T1213"), KDateTime::ISODate);
3145     QVERIFY(dt.timeSpec() == KDateTime::Spec::LocalZone());
3146     QCOMPARE(dt.dateTime(), QDateTime(QDate(2000, 3, 1), QTime(12, 13, 0), Qt::LocalTime));
3147     KDateTime::setFromStringDefault(london);
3148     dt = KDateTime::fromString(QString("20000301T1213"), KDateTime::ISODate);
3149     QVERIFY(dt.timeType() == KDateTime::TimeZone);
3150     QCOMPARE(dt.dateTime(), QDateTime(QDate(2000, 3, 1), QTime(12, 13, 0), Qt::LocalTime));
3151     KDateTime::setFromStringDefault(KDateTime::Spec::OffsetFromUTC(5000));  // = +01:23:20
3152     dt = KDateTime::fromString(QString("20000601T1213"), KDateTime::ISODate);
3153     QVERIFY(dt.timeType() == KDateTime::OffsetFromUTC);
3154     QCOMPARE(dt.utcOffset(), 5000);
3155     QCOMPARE(dt.toUtc().dateTime(), QDateTime(QDate(2000, 6, 1), QTime(10, 49, 40), Qt::UTC));
3156     KDateTime::setFromStringDefault(KDateTime::ClockTime);
3157     dt = KDateTime::fromString(QString("6543210301T1213"), KDateTime::ISODate, &negZero);
3158     QVERIFY(dt.timeType() == KDateTime::ClockTime);
3159     QVERIFY(!dt.isDateOnly());
3160     QVERIFY(!negZero);
3161     QCOMPARE(dt.dateTime(), QDateTime(QDate(654321, 3, 1), QTime(12, 13, 0), Qt::LocalTime));
3162     dt = KDateTime::fromString(QString("6543210301"), KDateTime::ISODate, &negZero);
3163     QVERIFY(dt.isDateOnly());
3164     QVERIFY(!negZero);
3165     QCOMPARE(dt.date(), QDate(654321, 3, 1));
3166     dt = KDateTime::fromString(QString("-47120301T1213"), KDateTime::ISODate, &negZero);
3167     QVERIFY(dt.timeType() == KDateTime::ClockTime);
3168     QVERIFY(!dt.isDateOnly());
3169     QVERIFY(!negZero);
3170     QCOMPARE(dt.dateTime(), QDateTime(QDate(-4712, 3, 1), QTime(12, 13, 0), Qt::LocalTime));
3171     dt = KDateTime::fromString(QString("-47120301"), KDateTime::ISODate, &negZero);
3172     QVERIFY(dt.isDateOnly());
3173     QVERIFY(!negZero);
3174     QCOMPARE(dt.date(), QDate(-4712, 3, 1));
3175 
3176     // Check strings containing day-of-the-year
3177     dt = KDateTime::fromString(QString("1999-060T19:20:21.06-11:20"), KDateTime::ISODate);
3178     QVERIFY(dt.timeType() == KDateTime::OffsetFromUTC);
3179     QCOMPARE(dt.utcOffset(), -11 * 3600 - 20 * 60);
3180     QCOMPARE(dt.dateTime(), QDateTime(QDate(1999, 3, 1), QTime(19, 20, 21, 60), Qt::LocalTime));
3181     dt = KDateTime::fromString(QString("1999-060T19:20:21,06-11:20"), KDateTime::ISODate);
3182     QVERIFY(dt.timeType() == KDateTime::OffsetFromUTC);
3183     QCOMPARE(dt.utcOffset(), -11 * 3600 - 20 * 60);
3184     QCOMPARE(dt.dateTime(), QDateTime(QDate(1999, 3, 1), QTime(19, 20, 21, 60), Qt::LocalTime));
3185     dt = KDateTime::fromString(QString("1999060T192021.06-1120"), KDateTime::ISODate);
3186     QVERIFY(dt.timeType() == KDateTime::OffsetFromUTC);
3187     QCOMPARE(dt.utcOffset(), -11 * 3600 - 20 * 60);
3188     QCOMPARE(dt.dateTime(), QDateTime(QDate(1999, 3, 1), QTime(19, 20, 21, 60), Qt::LocalTime));
3189     dt = KDateTime::fromString(QString("1999-060"), KDateTime::ISODate);
3190     QVERIFY(dt.timeType() == KDateTime::ClockTime);
3191     QVERIFY(dt.isDateOnly());
3192     QCOMPARE(dt.date(), QDate(1999, 3, 1));
3193 
3194     // Check 24:00:00
3195     dt = KDateTime::fromString(QString("1999-06-11T24:00:00+03:00"), KDateTime::ISODate);
3196     QCOMPARE(dt.dateTime(), QDateTime(QDate(1999, 6, 12), QTime(0, 0, 0), Qt::LocalTime));
3197     dt = KDateTime::fromString(QString("1999-06-11T24:00:01+03:00"), KDateTime::ISODate);
3198     QVERIFY(!dt.isValid());
3199 
3200     // Check leap second
3201     dt = KDateTime::fromString(QString("1999-06-11T23:59:60Z"), KDateTime::ISODate);
3202     QCOMPARE(dt.dateTime(), QDateTime(QDate(1999, 6, 11), QTime(23, 59, 59), Qt::UTC));
3203     dt = KDateTime::fromString(QString("1999-06-11T13:59:60Z"), KDateTime::ISODate);
3204     QVERIFY(!dt.isValid());
3205     dt = KDateTime::fromString(QString("1999-06-11T13:59:60-10:00"), KDateTime::ISODate);
3206     QCOMPARE(dt.dateTime(), QDateTime(QDate(1999, 6, 11), QTime(13, 59, 59), Qt::LocalTime));
3207     dt = KDateTime::fromString(QString("1999-06-11T23:59:60-10:00"), KDateTime::ISODate);
3208     QVERIFY(!dt.isValid());
3209 
3210     // Check negZero
3211     dt = KDateTime::fromString(QString("1999-060T19:20:21.06-00:00"), KDateTime::ISODate, &negZero);
3212     QVERIFY(negZero);
3213     dt = KDateTime::fromString(QString("1999-060T19:20:21.06+00:00"), KDateTime::ISODate, &negZero);
3214     QVERIFY(!negZero);
3215 
3216     // Restore the original local time zone
3217     if (originalZone.isEmpty()) {
3218         ::unsetenv("TZ");
3219     } else {
3220         qputenv("TZ", originalZone);
3221     }
3222     ::tzset();
3223 }
3224 
3225 void KDateTimeTest::strings_rfc2822()
3226 {
3227     KTimeZone london = KSystemTimeZones::zone("Europe/London");
3228 
3229     // Ensure that local time is different from UTC and different from 'london'
3230     QByteArray originalZone = qgetenv("TZ");   // save the original local time zone
3231     qputenv("TZ", ":America/Los_Angeles");
3232     ::tzset();
3233 
3234     bool negZero = true;
3235     KDateTime dtlocal(QDate(1999, 12, 11), QTime(3, 45, 06), KDateTime::LocalZone);
3236     QString s = dtlocal.toString(KDateTime::RFCDate);
3237     QCOMPARE(s, QString("11 Dec 1999 03:45:06 -0800"));
3238     KDateTime dtlocal1 = KDateTime::fromString(s, KDateTime::RFCDate, &negZero);
3239     QCOMPARE(dtlocal1.dateTime().toUTC(), dtlocal.dateTime().toUTC());
3240     QCOMPARE(dtlocal1.timeType(), KDateTime::OffsetFromUTC);
3241     QCOMPARE(dtlocal1.utcOffset(), -8 * 3600);
3242     QVERIFY(dtlocal1 == dtlocal);
3243     QVERIFY(!negZero);
3244     KDateTime dtlocal2 = KDateTime::fromString(s, KDateTime::RFCDateDay);
3245     QVERIFY(!dtlocal2.isValid());
3246     s = dtlocal.toString(KDateTime::RFCDateDay);
3247     QCOMPARE(s, QString("Sat, 11 Dec 1999 03:45:06 -0800"));
3248     dtlocal2 = KDateTime::fromString(s, KDateTime::RFCDate);
3249     QVERIFY(dtlocal1 == dtlocal2);
3250     QCOMPARE(dtlocal1.dateTime(), dtlocal2.dateTime());
3251     dtlocal2 = KDateTime::fromString(s, KDateTime::RFCDateDay);
3252     QVERIFY(dtlocal1 == dtlocal2);
3253     dtlocal2 = KDateTime::fromString(QString("Saturday, 11-Dec-99 03:45:06 -0800"), KDateTime::RFCDate);
3254     QVERIFY(dtlocal1 == dtlocal2);
3255     dtlocal2 = KDateTime::fromString(QString("11 Dec 1999 03:45:06 PST"), KDateTime::RFCDate, &negZero);
3256     QVERIFY(dtlocal1 == dtlocal2);
3257     QVERIFY(!negZero);
3258     dtlocal.setDateOnly(true);
3259     s = dtlocal.toString(KDateTime::RFCDate);
3260     QCOMPARE(s, QString("11 Dec 1999 00:00 -0800"));
3261     s = dtlocal.toString(KDateTime::RFCDateDay);
3262     QCOMPARE(s, QString("Sat, 11 Dec 1999 00:00 -0800"));
3263 
3264     KDateTime dtzone(QDate(1999, 6, 11), QTime(3, 45, 06), london);
3265     s = dtzone.toString(KDateTime::RFCDate);
3266     QCOMPARE(s, QString("11 Jun 1999 03:45:06 +0100"));
3267     KDateTime dtzone1 = KDateTime::fromString(s, KDateTime::RFCDate);
3268     QCOMPARE(dtzone1.dateTime().toUTC(), dtzone.dateTime().toUTC());
3269     QCOMPARE(dtzone1.timeType(), KDateTime::OffsetFromUTC);
3270     QCOMPARE(dtzone1.utcOffset(), 3600);
3271     QVERIFY(dtzone1 == dtzone);
3272     KDateTime dtzone2 = KDateTime::fromString(s, KDateTime::RFCDateDay);
3273     QVERIFY(!dtzone2.isValid());
3274     s = dtzone.toString(KDateTime::RFCDateDay);
3275     QCOMPARE(s, QString("Fri, 11 Jun 1999 03:45:06 +0100"));
3276     dtzone2 = KDateTime::fromString(s, KDateTime::RFCDate);
3277     QVERIFY(dtzone1 == dtzone2);
3278     QCOMPARE(dtzone1.dateTime(), dtzone2.dateTime());
3279     dtzone2 = KDateTime::fromString(s, KDateTime::RFCDateDay, &negZero);
3280     QVERIFY(dtzone1 == dtzone2);
3281     QVERIFY(!negZero);
3282     dtzone2 = KDateTime::fromString(QString("Friday, 11-Jun-99 03:45:06 +0100"), KDateTime::RFCDateDay);
3283     QVERIFY(dtzone1 == dtzone2);
3284     dtzone.setDateOnly(true);
3285     s = dtzone.toString(KDateTime::RFCDate);
3286     QCOMPARE(s, QString("11 Jun 1999 00:00 +0100"));
3287     s = dtzone.toString(KDateTime::RFCDateDay);
3288     QCOMPARE(s, QString("Fri, 11 Jun 1999 00:00 +0100"));
3289 
3290     KDateTime dtclock(QDate(1999, 12, 11), QTime(3, 45, 06), KDateTime::ClockTime);
3291     s = dtclock.toString(KDateTime::RFCDate);
3292     QCOMPARE(s, QString("11 Dec 1999 03:45:06 -0800"));
3293     KDateTime dtclock1 = KDateTime::fromString(s, KDateTime::RFCDate, &negZero);
3294     QCOMPARE(dtclock1.dateTime(), dtclock.dateTime());
3295     QCOMPARE(dtclock1.timeType(), KDateTime::OffsetFromUTC);
3296     QCOMPARE(dtclock1.utcOffset(), -8 * 3600);
3297     QVERIFY(dtclock1 == dtclock);
3298     QVERIFY(!negZero);
3299     KDateTime dtclock2 = KDateTime::fromString(s, KDateTime::RFCDateDay);
3300     QVERIFY(!dtclock2.isValid());
3301     s = dtclock.toString(KDateTime::RFCDateDay);
3302     QCOMPARE(s, QString("Sat, 11 Dec 1999 03:45:06 -0800"));
3303     dtclock2 = KDateTime::fromString(s, KDateTime::RFCDate);
3304     QVERIFY(dtclock1 == dtclock2);
3305     QCOMPARE(dtclock1.dateTime(), dtclock2.dateTime());
3306     dtclock2 = KDateTime::fromString(s, KDateTime::RFCDateDay);
3307     QVERIFY(dtclock1 == dtclock2);
3308     dtclock2 = KDateTime::fromString(QString("Saturday, 11-Dec-99 03:45:06 -0800"), KDateTime::RFCDateDay);
3309     QVERIFY(dtclock1 == dtclock2);
3310     dtclock.setDateOnly(true);
3311     s = dtclock.toString(KDateTime::RFCDate);
3312     QCOMPARE(s, QString("11 Dec 1999 00:00 -0800"));
3313     s = dtclock.toString(KDateTime::RFCDateDay);
3314     QCOMPARE(s, QString("Sat, 11 Dec 1999 00:00 -0800"));
3315 
3316     KDateTime dtutc(QDate(1999, 12, 11), QTime(3, 45, 00), KDateTime::UTC);
3317     s = dtutc.toString(KDateTime::RFCDate);
3318     QCOMPARE(s, QString("11 Dec 1999 03:45 +0000"));
3319     KDateTime dtutc1 = KDateTime::fromString(s, KDateTime::RFCDate, &negZero);
3320     QCOMPARE(dtutc1.dateTime(), dtutc.dateTime());
3321     QCOMPARE(dtutc1.timeType(), KDateTime::UTC);
3322     QVERIFY(dtutc1 == dtutc);
3323     QVERIFY(!negZero);
3324     KDateTime dtutc2 = KDateTime::fromString(s, KDateTime::RFCDateDay);
3325     QVERIFY(!dtutc2.isValid());
3326     s = dtutc.toString(KDateTime::RFCDateDay);
3327     QCOMPARE(s, QString("Sat, 11 Dec 1999 03:45 +0000"));
3328     dtutc2 = KDateTime::fromString(s, KDateTime::RFCDate);
3329     QVERIFY(dtutc1 == dtutc2);
3330     QCOMPARE(dtutc1.dateTime(), dtutc2.dateTime());
3331     dtutc2 = KDateTime::fromString(s, KDateTime::RFCDateDay);
3332     QVERIFY(dtutc1 == dtutc2);
3333     dtutc2 = KDateTime::fromString(QString("Saturday, 11-Dec-99 03:45 +0000"), KDateTime::RFCDate);
3334     QVERIFY(dtutc1 == dtutc2);
3335     dtutc.setDateOnly(true);
3336     s = dtutc.toString(KDateTime::RFCDate);
3337     QCOMPARE(s, QString("11 Dec 1999 00:00 +0000"));
3338     s = dtutc.toString(KDateTime::RFCDateDay);
3339     QCOMPARE(s, QString("Sat, 11 Dec 1999 00:00 +0000"));
3340 
3341     // Check '-0000' and unknown/invalid time zone names
3342     dtutc2 = KDateTime::fromString(QString("11 Dec 1999 03:45 -0000"), KDateTime::RFCDate, &negZero);
3343     QVERIFY(dtutc1 == dtutc2);
3344     QVERIFY(negZero);
3345     dtutc2 = KDateTime::fromString(QString("11 Dec 1999 03:45 B"), KDateTime::RFCDate, &negZero);
3346     QVERIFY(dtutc1 == dtutc2);
3347     QVERIFY(negZero);
3348     dtutc2 = KDateTime::fromString(QString("11 Dec 1999 03:45 BCDE"), KDateTime::RFCDate, &negZero);
3349     QVERIFY(dtutc1 == dtutc2);
3350     QVERIFY(negZero);
3351 
3352     // Check named time offsets
3353     KDateTime dtzname = KDateTime::fromString(QString("11 Dec 1999 03:45:06 UT"), KDateTime::RFCDate, &negZero);
3354     QVERIFY(dtzname.timeType() == KDateTime::UTC);
3355     QCOMPARE(dtzname.dateTime(), QDateTime(QDate(1999, 12, 11), QTime(3, 45, 6), Qt::UTC));
3356     QVERIFY(!negZero);
3357     dtzname = KDateTime::fromString(QString("11 Dec 1999 03:45:06 GMT"), KDateTime::RFCDate, &negZero);
3358     QVERIFY(dtzname.timeType() == KDateTime::UTC);
3359     QCOMPARE(dtzname.dateTime(), QDateTime(QDate(1999, 12, 11), QTime(3, 45, 6), Qt::UTC));
3360     QVERIFY(!negZero);
3361     dtzname = KDateTime::fromString(QString("11 Dec 1999 03:45:06 EDT"), KDateTime::RFCDate, &negZero);
3362     QVERIFY(dtzname.timeType() == KDateTime::OffsetFromUTC);
3363     QCOMPARE(dtzname.utcOffset(), -4 * 3600);
3364     QCOMPARE(dtzname.dateTime(), QDateTime(QDate(1999, 12, 11), QTime(3, 45, 6), Qt::LocalTime));
3365     QVERIFY(!negZero);
3366     dtzname = KDateTime::fromString(QString("11 Dec 1999 03:45:06 EST"), KDateTime::RFCDate, &negZero);
3367     QVERIFY(dtzname.timeType() == KDateTime::OffsetFromUTC);
3368     QCOMPARE(dtzname.utcOffset(), -5 * 3600);
3369     QCOMPARE(dtzname.dateTime(), QDateTime(QDate(1999, 12, 11), QTime(3, 45, 6), Qt::LocalTime));
3370     QVERIFY(!negZero);
3371     dtzname = KDateTime::fromString(QString("11 Dec 1999 03:45:06 CDT"), KDateTime::RFCDate, &negZero);
3372     QVERIFY(dtzname.timeType() == KDateTime::OffsetFromUTC);
3373     QCOMPARE(dtzname.utcOffset(), -5 * 3600);
3374     QCOMPARE(dtzname.dateTime(), QDateTime(QDate(1999, 12, 11), QTime(3, 45, 6), Qt::LocalTime));
3375     QVERIFY(!negZero);
3376     dtzname = KDateTime::fromString(QString("11 Dec 1999 03:45:06 CST"), KDateTime::RFCDate, &negZero);
3377     QVERIFY(dtzname.timeType() == KDateTime::OffsetFromUTC);
3378     QCOMPARE(dtzname.utcOffset(), -6 * 3600);
3379     QCOMPARE(dtzname.dateTime(), QDateTime(QDate(1999, 12, 11), QTime(3, 45, 6), Qt::LocalTime));
3380     QVERIFY(!negZero);
3381     dtzname = KDateTime::fromString(QString("11 Dec 1999 03:45:06 MDT"), KDateTime::RFCDate, &negZero);
3382     QVERIFY(dtzname.timeType() == KDateTime::OffsetFromUTC);
3383     QCOMPARE(dtzname.utcOffset(), -6 * 3600);
3384     QCOMPARE(dtzname.dateTime(), QDateTime(QDate(1999, 12, 11), QTime(3, 45, 6), Qt::LocalTime));
3385     QVERIFY(!negZero);
3386     dtzname = KDateTime::fromString(QString("11 Dec 1999 03:45:06 MST"), KDateTime::RFCDate, &negZero);
3387     QVERIFY(dtzname.timeType() == KDateTime::OffsetFromUTC);
3388     QCOMPARE(dtzname.utcOffset(), -7 * 3600);
3389     QCOMPARE(dtzname.dateTime(), QDateTime(QDate(1999, 12, 11), QTime(3, 45, 6), Qt::LocalTime));
3390     QVERIFY(!negZero);
3391     dtzname = KDateTime::fromString(QString("11 Dec 1999 03:45:06 PDT"), KDateTime::RFCDate, &negZero);
3392     QVERIFY(dtzname.timeType() == KDateTime::OffsetFromUTC);
3393     QCOMPARE(dtzname.utcOffset(), -7 * 3600);
3394     QCOMPARE(dtzname.dateTime(), QDateTime(QDate(1999, 12, 11), QTime(3, 45, 6), Qt::LocalTime));
3395     QVERIFY(!negZero);
3396     dtzname = KDateTime::fromString(QString("11 Dec 1999 03:45:06 PST"), KDateTime::RFCDate, &negZero);
3397     QVERIFY(dtzname.timeType() == KDateTime::OffsetFromUTC);
3398     QCOMPARE(dtzname.utcOffset(), -8 * 3600);
3399     QCOMPARE(dtzname.dateTime(), QDateTime(QDate(1999, 12, 11), QTime(3, 45, 6), Qt::LocalTime));
3400     QVERIFY(!negZero);
3401 
3402     // Check leap second
3403     KDateTime dt = KDateTime::fromString(QString("11 Dec 1999 23:59:60 -0000"), KDateTime::RFCDate);
3404     QCOMPARE(dt.dateTime(), QDateTime(QDate(1999, 12, 11), QTime(23, 59, 59), Qt::UTC));
3405     dt = KDateTime::fromString(QString("11 Dec 1999 13:59:60 -0000"), KDateTime::RFCDate);
3406     QVERIFY(!dt.isValid());
3407     dt = KDateTime::fromString(QString("11 Jun 1999 13:59:60 -1000"), KDateTime::RFCDate);
3408     QCOMPARE(dt.dateTime(), QDateTime(QDate(1999, 6, 11), QTime(13, 59, 59), Qt::LocalTime));
3409     dt = KDateTime::fromString(QString("11 Dec 1999 23:59:60 -1000"), KDateTime::RFCDate);
3410     QVERIFY(!dt.isValid());
3411 
3412     // Check erroneous strings:
3413     dtutc2 = KDateTime::fromString(QString("11 Dec 1999 23:59:60 -00:00"), KDateTime::RFCDate);
3414     QVERIFY(!dtutc2.isValid());     // colon in UTC offset
3415     dtutc2 = KDateTime::fromString(QString("Sun, 11 Dec 1999 03:45 +0000"), KDateTime::RFCDate);
3416     QVERIFY(!dtutc2.isValid());     // wrong weekday
3417     dtutc2 = KDateTime::fromString(QString("Satu, 11 Dec 1999 03:45 +0000"), KDateTime::RFCDate);
3418     QVERIFY(!dtutc2.isValid());     // bad weekday
3419     dtutc2 = KDateTime::fromString(QString("11 Dece 1999 03:45 +0000"), KDateTime::RFCDate);
3420     QVERIFY(!dtutc2.isValid());     // bad month
3421     dtutc2 = KDateTime::fromString(QString("11-Dec 1999 03:45 +0000"), KDateTime::RFCDate);
3422     QVERIFY(!dtutc2.isValid());     // only one hyphen in date
3423 
3424     // Restore the original local time zone
3425     if (originalZone.isEmpty()) {
3426         ::unsetenv("TZ");
3427     } else {
3428         qputenv("TZ", originalZone);
3429     }
3430     ::tzset();
3431 }
3432 
3433 void KDateTimeTest::strings_rfc3339()
3434 {
3435     KTimeZone london = KSystemTimeZones::zone("Europe/London");
3436 
3437     // Ensure that local time is different from UTC and different from 'london'
3438     QByteArray originalZone = qgetenv("TZ");   // save the original local time zone
3439     qputenv("TZ", ":America/Los_Angeles");
3440     ::tzset();
3441 
3442     bool negZero = true;
3443     KDateTime dtlocal(QDate(1999, 2, 9), QTime(3, 45, 06), KDateTime::LocalZone);
3444     QString s = dtlocal.toString(KDateTime::RFC3339Date);
3445     QCOMPARE(s, QString("1999-02-09T03:45:06-08:00"));
3446     KDateTime dtlocal1 = KDateTime::fromString(s, KDateTime::RFC3339Date, &negZero);
3447     QCOMPARE(dtlocal1.dateTime().toUTC(), dtlocal.dateTime().toUTC());
3448     QCOMPARE(dtlocal1.timeType(), KDateTime::OffsetFromUTC);
3449     QCOMPARE(dtlocal1.utcOffset(), -8 * 3600);
3450     QVERIFY(dtlocal1 == dtlocal);
3451     QVERIFY(!negZero);
3452     dtlocal.setDateOnly(true);
3453     s = dtlocal.toString(KDateTime::RFC3339Date);
3454     QCOMPARE(s, QString("1999-02-09T00:00:00-08:00"));
3455 
3456     KDateTime dtzone(QDate(1999, 6, 9), QTime(3, 45, 06), london);
3457     s = dtzone.toString(KDateTime::RFC3339Date);
3458     QCOMPARE(s, QString("1999-06-09T03:45:06+01:00"));
3459     KDateTime dtzone1 = KDateTime::fromString(s, KDateTime::RFC3339Date);
3460     QCOMPARE(dtzone1.dateTime().toUTC(), dtzone.dateTime().toUTC());
3461     QCOMPARE(dtzone1.timeType(), KDateTime::OffsetFromUTC);
3462     QCOMPARE(dtzone1.utcOffset(), 3600);
3463     QVERIFY(dtzone1 == dtzone);
3464     dtzone.setDateOnly(true);
3465     s = dtzone.toString(KDateTime::RFC3339Date);
3466     QCOMPARE(s, QString("1999-06-09T00:00:00+01:00"));
3467 
3468     KDateTime dtclock(QDate(1999, 2, 9), QTime(3, 5, 06), KDateTime::ClockTime);
3469     s = dtclock.toString(KDateTime::RFC3339Date);
3470     QCOMPARE(s, QString("1999-02-09T03:05:06-08:00"));
3471     KDateTime dtclock1 = KDateTime::fromString(s, KDateTime::RFC3339Date, &negZero);
3472     QCOMPARE(dtclock1.dateTime(), dtclock.dateTime());
3473     QCOMPARE(dtclock1.timeType(), KDateTime::OffsetFromUTC);
3474     QCOMPARE(dtclock1.utcOffset(), -8 * 3600);
3475     QVERIFY(dtclock1 == dtclock);
3476     QVERIFY(!negZero);
3477     KDateTime dtclock2 = KDateTime::fromString(QString("1999-02-09t03:05:06-08:00"), KDateTime::RFC3339Date, &negZero);
3478     QVERIFY(dtclock1 == dtclock2);
3479     dtclock.setDateOnly(true);
3480     s = dtclock.toString(KDateTime::RFC3339Date);
3481     QCOMPARE(s, QString("1999-02-09T00:00:00-08:00"));
3482 
3483     KDateTime dtutc(QDate(1999, 2, 9), QTime(3, 45, 00), KDateTime::UTC);
3484     s = dtutc.toString(KDateTime::RFC3339Date);
3485     QCOMPARE(s, QString("1999-02-09T03:45:00Z"));
3486     KDateTime dtutc1 = KDateTime::fromString(s, KDateTime::RFC3339Date, &negZero);
3487     QCOMPARE(dtutc1.dateTime(), dtutc.dateTime());
3488     QCOMPARE(dtutc1.timeType(), KDateTime::UTC);
3489     QVERIFY(dtutc1 == dtutc);
3490     QVERIFY(!negZero);
3491     KDateTime dtutc2 = KDateTime::fromString(QString("1999-02-09t03:45:00z"), KDateTime::RFC3339Date, &negZero);
3492     QVERIFY(dtutc1 == dtutc2);
3493     dtutc.setDateOnly(true);
3494     s = dtutc.toString(KDateTime::RFC3339Date);
3495     QCOMPARE(s, QString("1999-02-09T00:00:00Z"));
3496 
3497     // Check '-00:00' (specifies unknown local offset)
3498     dtutc2 = KDateTime::fromString(QString("1999-02-09T03:45:00-00:00"), KDateTime::RFC3339Date, &negZero);
3499     QVERIFY(dtutc1 == dtutc2);
3500     QVERIFY(negZero);
3501     dtutc2 = KDateTime::fromString(QString("1999-02-09T03:45:00+00:00"), KDateTime::RFC3339Date, &negZero);
3502     QVERIFY(dtutc1 == dtutc2);
3503     QVERIFY(!negZero);
3504 
3505     // Check leap second
3506     KDateTime dt = KDateTime::fromString(QString("1999-02-09T23:59:60z"), KDateTime::RFC3339Date);
3507     QCOMPARE(dt.dateTime(), QDateTime(QDate(1999, 2, 9), QTime(23, 59, 59), Qt::UTC));
3508     dt = KDateTime::fromString(QString("1999-02-09T23:59:60+00:00"), KDateTime::RFC3339Date);
3509     QCOMPARE(dt.toUtc().dateTime(), QDateTime(QDate(1999, 2, 9), QTime(23, 59, 59), Qt::UTC));
3510     dt = KDateTime::fromString(QString("1999-02-09T13:59:60-00:00"), KDateTime::RFC3339Date);
3511     QVERIFY(!dt.isValid());
3512     dt = KDateTime::fromString(QString("1999-06-11T13:59:60-10:00"), KDateTime::RFC3339Date);
3513     QCOMPARE(dt.toUtc().dateTime(), QDateTime(QDate(1999, 6, 11), QTime(23, 59, 59), Qt::UTC));
3514     dt = KDateTime::fromString(QString("1999-12-11T23:59:60-10:00"), KDateTime::RFC3339Date);
3515     QVERIFY(!dt.isValid());
3516 
3517     // Check erroneous strings:
3518     dtutc2 = KDateTime::fromString(QString("1999-02-09 03:45:00"), KDateTime::RFC3339Date, &negZero);
3519     QVERIFY(!dtutc2.isValid());
3520     dtutc2 = KDateTime::fromString(QString("1999-02-09T03:45:00B"), KDateTime::RFC3339Date, &negZero);
3521     QVERIFY(!dtutc2.isValid());
3522     dtutc2 = KDateTime::fromString(QString("1999-02-09T23:59:60-0000"), KDateTime::RFC3339Date);
3523     QVERIFY(!dtutc2.isValid());     // no colon in UTC offset
3524     dtutc2 = KDateTime::fromString(QString("19990-12-10T03:45:01+00:00"), KDateTime::RFC3339Date);
3525     QVERIFY(!dtutc2.isValid());     // bad year
3526     dtutc2 = KDateTime::fromString(QString("1999-13-10T03:45:01+00:00"), KDateTime::RFC3339Date);
3527     QVERIFY(!dtutc2.isValid());     // bad month
3528     dtutc2 = KDateTime::fromString(QString("1999-10-32T03:45:01+00:00"), KDateTime::RFC3339Date);
3529     QVERIFY(!dtutc2.isValid());     // bad day
3530     dtutc2 = KDateTime::fromString(QString("1999-1209T03:45:00+00:00"), KDateTime::RFC3339Date);
3531     QVERIFY(!dtutc2.isValid());     // only one hyphen in date
3532     dtutc2 = KDateTime::fromString(QString("1999-12T03:45:00+00:00"), KDateTime::RFC3339Date);
3533     QVERIFY(!dtutc2.isValid());     // no day of month
3534 
3535     // Restore the original local time zone
3536     if (originalZone.isEmpty()) {
3537         ::unsetenv("TZ");
3538     } else {
3539         qputenv("TZ", originalZone);
3540     }
3541     ::tzset();
3542 }
3543 
3544 void KDateTimeTest::strings_qttextdate()
3545 {
3546     KTimeZone london = KSystemTimeZones::zone("Europe/London");
3547 
3548     // Ensure that local time is different from UTC and different from 'london'
3549     QByteArray originalZone = qgetenv("TZ");   // save the original local time zone
3550     qputenv("TZ", ":America/Los_Angeles");
3551     ::tzset();
3552 
3553     bool negZero = true;
3554     KDateTime dtlocal(QDate(1999, 12, 11), QTime(3, 45, 06), KDateTime::LocalZone);
3555     QString s = dtlocal.toString(KDateTime::QtTextDate);
3556     QCOMPARE(s, QString("Sat Dec 11 03:45:06 1999 -0800"));
3557     KDateTime dtlocal1 = KDateTime::fromString(s, KDateTime::QtTextDate, &negZero);
3558     QCOMPARE(dtlocal1.dateTime().toUTC(), dtlocal.dateTime().toUTC());
3559     QCOMPARE(dtlocal1.timeType(), KDateTime::OffsetFromUTC);
3560     QCOMPARE(dtlocal1.utcOffset(), -8 * 3600);
3561     QVERIFY(dtlocal1 == dtlocal);
3562     QVERIFY(!dtlocal1.isDateOnly());
3563     QVERIFY(!negZero);
3564     dtlocal.setDateOnly(true);
3565     s = dtlocal.toString(KDateTime::QtTextDate);
3566     QCOMPARE(s, QString("Sat Dec 11 1999 -0800"));
3567     dtlocal1 = KDateTime::fromString(s, KDateTime::QtTextDate, &negZero);
3568     QVERIFY(dtlocal1.isDateOnly());
3569     QCOMPARE(dtlocal1.date(), QDate(1999, 12, 11));
3570     QCOMPARE(dtlocal1.timeType(), KDateTime::OffsetFromUTC);
3571     QCOMPARE(dtlocal1.utcOffset(), -8 * 3600);
3572 
3573     KDateTime dtzone(QDate(1999, 6, 11), QTime(3, 45, 06), london);
3574     s = dtzone.toString(KDateTime::QtTextDate);
3575     QCOMPARE(s, QString("Fri Jun 11 03:45:06 1999 +0100"));
3576     KDateTime dtzone1 = KDateTime::fromString(s, KDateTime::QtTextDate);
3577     QCOMPARE(dtzone1.dateTime().toUTC(), dtzone.dateTime().toUTC());
3578     QCOMPARE(dtzone1.timeType(), KDateTime::OffsetFromUTC);
3579     QCOMPARE(dtzone1.utcOffset(), 3600);
3580     QVERIFY(!dtzone1.isDateOnly());
3581     QVERIFY(dtzone1 == dtzone);
3582     KDateTime dtzone2 = KDateTime::fromString(s, KDateTime::QtTextDate, &negZero);
3583     QVERIFY(dtzone1 == dtzone2);
3584     QVERIFY(!negZero);
3585     dtzone.setDateOnly(true);
3586     s = dtzone.toString(KDateTime::QtTextDate);
3587     QCOMPARE(s, QString("Fri Jun 11 1999 +0100"));
3588     dtzone1 = KDateTime::fromString(s, KDateTime::QtTextDate, &negZero);
3589     QVERIFY(dtzone1.isDateOnly());
3590     QCOMPARE(dtzone1.date(), QDate(1999, 6, 11));
3591     QCOMPARE(dtzone1.timeType(), KDateTime::OffsetFromUTC);
3592     QCOMPARE(dtzone1.utcOffset(), 3600);
3593 
3594     KDateTime dtclock(QDate(1999, 12, 11), QTime(3, 45, 06), KDateTime::ClockTime);
3595     s = dtclock.toString(KDateTime::QtTextDate);
3596     QCOMPARE(s, QString("Sat Dec 11 03:45:06 1999"));
3597     KDateTime dtclock1 = KDateTime::fromString(s, KDateTime::QtTextDate, &negZero);
3598     QCOMPARE(dtclock1.dateTime(), dtclock.dateTime());
3599     QCOMPARE(dtclock1.timeType(), KDateTime::ClockTime);
3600     QVERIFY(dtclock1 == dtclock);
3601     QVERIFY(!dtclock1.isDateOnly());
3602     QVERIFY(!negZero);
3603     dtclock.setDateOnly(true);
3604     s = dtclock.toString(KDateTime::QtTextDate);
3605     QCOMPARE(s, QString("Sat Dec 11 1999"));
3606     dtclock1 = KDateTime::fromString(s, KDateTime::QtTextDate, &negZero);
3607     QVERIFY(dtclock1.isDateOnly());
3608     QCOMPARE(dtclock1.date(), QDate(1999, 12, 11));
3609     QCOMPARE(dtclock1.timeType(), KDateTime::ClockTime);
3610 
3611     KDateTime dtutc(QDate(1999, 12, 11), QTime(3, 45, 00), KDateTime::UTC);
3612     s = dtutc.toString(KDateTime::QtTextDate);
3613     QCOMPARE(s, QString("Sat Dec 11 03:45:00 1999 GMT +0000"));
3614     KDateTime dtutc1 = KDateTime::fromString(s, KDateTime::QtTextDate, &negZero);
3615     QCOMPARE(dtutc1.dateTime(), dtutc.dateTime());
3616     QCOMPARE(dtutc1.timeType(), KDateTime::UTC);
3617     QVERIFY(dtutc1 == dtutc);
3618     QVERIFY(!dtutc1.isDateOnly());
3619     QVERIFY(!negZero);
3620     dtutc.setDateOnly(true);
3621     s = dtutc.toString(KDateTime::QtTextDate);
3622     QCOMPARE(s, QString("Sat Dec 11 1999 +0000"));
3623     dtutc1 = KDateTime::fromString(s, KDateTime::QtTextDate, &negZero);
3624     QVERIFY(dtutc1.isDateOnly());
3625     QCOMPARE(dtutc1.date(), QDate(1999, 12, 11));
3626     QCOMPARE(dtutc1.timeType(), KDateTime::UTC);
3627 
3628     // Check '-0000'
3629     KDateTime dtutc2 = KDateTime::fromString(QString("Sat Dec 11 03:45:00 1999 -0000"), KDateTime::QtTextDate, &negZero);
3630     QVERIFY(dtutc1 != dtutc2);
3631     QVERIFY(negZero);
3632 
3633     // Check erroneous strings
3634     dtutc2 = KDateTime::fromString(QString("Sat Dec 11 03:45:00 1999 GMT"), KDateTime::QtTextDate, &negZero);
3635     QVERIFY(!dtutc2.isValid());
3636     dtutc2 = KDateTime::fromString(QString("Sun Dec 11 03:45:00 1999 +0000"), KDateTime::QtTextDate);
3637     QVERIFY(dtutc2.isValid());     // wrong weekday: accepted by Qt!!
3638     dtutc2 = KDateTime::fromString(QString("Satu, Dec 11 03:45:00 1999 +0000"), KDateTime::QtTextDate);
3639     QVERIFY(dtutc2.isValid());     // bad weekday, accepted by Qt (since 4.3)
3640     dtutc2 = KDateTime::fromString(QString("Sat Dece 11 03:45:00 1999 +0000"), KDateTime::QtTextDate);
3641     QVERIFY(!dtutc2.isValid());     // bad month, not accepted by Qt anymore (since 4.3)
3642 
3643     // Restore the original local time zone
3644     if (originalZone.isEmpty()) {
3645         ::unsetenv("TZ");
3646     } else {
3647         qputenv("TZ", originalZone);
3648     }
3649     ::tzset();
3650 }
3651 
3652 void KDateTimeTest::strings_format()
3653 {
3654     KCalendarSystem *calendar = KCalendarSystem::create(KLocale::GregorianCalendar, KLocale::global());
3655     KTimeZone london = KSystemTimeZones::zone("Europe/London");
3656     KTimeZone paris  = KSystemTimeZones::zone("Europe/Paris");
3657     KTimeZone berlin = KSystemTimeZones::zone("Europe/Berlin");
3658     KTimeZone cairo  = KSystemTimeZones::zone("Africa/Cairo");
3659     KTimeZones zones;
3660     zones.add(london);
3661     zones.add(paris);
3662     zones.add(berlin);
3663     zones.add(cairo);
3664 
3665     // Ensure that local time is different from UTC and different from 'london'
3666     QByteArray originalZone = qgetenv("TZ");   // save the original local time zone
3667     qputenv("TZ", ":America/Los_Angeles");
3668     ::tzset();
3669 
3670     // toString()
3671     QString all = QLatin1String("%Y.%y.%m.%:m.%B.%b.%d.%e.%A.%a-%H.%k.%I.%l.%M.%S?%:s?%P.%p.%:u.%z.%Z.%:Z.%:A.%:a.%:B.%:b/%:S.%:z.%%.");
3672     KDateTime dt(QDate(1999, 2, 3), QTime(6, 5, 0), KDateTime::LocalZone);
3673     QString s = dt.toString(all);
3674     QCOMPARE(s, QString::fromLatin1("1999.99.02.2.%1.%2.03.3.%3.%4-06.6.06.6.05.00?000?am.AM.-08.-0800.PST.America/Los_Angeles.Wednesday.Wed.February.Feb/.-08:00.%.")
3675              .arg(calendar->monthName(2, 1999, KCalendarSystem::LongName))
3676              .arg(calendar->monthName(2, 1999, KCalendarSystem::ShortName))
3677              .arg(calendar->weekDayName(3, KCalendarSystem::LongDayName))
3678              .arg(calendar->weekDayName(3, KCalendarSystem::ShortDayName)));
3679 
3680     KDateTime dtzone(QDate(1970, 4, 30), QTime(12, 45, 16, 25), london);
3681     s = dtzone.toString(all);
3682     QCOMPARE(s, QString::fromLatin1("1970.70.04.4.%1.%2.30.30.%3.%4-12.12.12.12.45.16?025?pm.PM.+01.+0100.BST.Europe/London.Thursday.Thu.April.Apr/:16.+01:00.%.")
3683              .arg(calendar->monthName(4, 2000, KCalendarSystem::LongName))
3684              .arg(calendar->monthName(4, 2000, KCalendarSystem::ShortName))
3685              .arg(calendar->weekDayName(4, KCalendarSystem::LongDayName))
3686              .arg(calendar->weekDayName(4, KCalendarSystem::ShortDayName)));
3687 
3688     KDateTime dtclock(QDate(2005, 9, 5), QTime(0, 0, 06, 1), KDateTime::ClockTime);
3689     s = dtclock.toString(all);
3690     QCOMPARE(s, QString::fromLatin1("2005.05.09.9.%1.%2.05.5.%3.%4-00.0.12.12.00.06?001?am.AM.....Monday.Mon.September.Sep/:06..%.")
3691              .arg(calendar->monthName(9, 2000, KCalendarSystem::LongName))
3692              .arg(calendar->monthName(9, 2000, KCalendarSystem::ShortName))
3693              .arg(calendar->weekDayName(1, KCalendarSystem::LongDayName))
3694              .arg(calendar->weekDayName(1, KCalendarSystem::ShortDayName)));
3695 
3696     KDateTime dtutc(QDate(2000, 12, 31), QTime(13, 45, 16, 100), KDateTime::UTC);
3697     s = dtutc.toString(all);
3698     QCOMPARE(s, QString::fromLatin1("2000.00.12.12.%1.%2.31.31.%3.%4-13.13.01.1.45.16?100?pm.PM.+00.+0000.UTC.UTC.Sunday.Sun.December.Dec/:16.+00:00.%.")
3699              .arg(calendar->monthName(12, 2000, KCalendarSystem::LongName))
3700              .arg(calendar->monthName(12, 2000, KCalendarSystem::ShortName))
3701              .arg(calendar->weekDayName(7, KCalendarSystem::LongDayName))
3702              .arg(calendar->weekDayName(7, KCalendarSystem::ShortDayName)));
3703 
3704     // fromString() without KTimeZones parameter
3705     dt = KDateTime::fromString(QLatin1String("2005/9/05/20:2,03"), QLatin1String("%Y/%:m/%d/%S:%k,%M"));
3706     QCOMPARE(dt.dateTime(), QDateTime(QDate(2005, 9, 5), QTime(2, 3, 20), Qt::LocalTime));
3707     QCOMPARE(dt.timeType(), KDateTime::ClockTime);
3708 
3709     dt = KDateTime::fromString(QString::fromLatin1("%1pm05ab%2t/052/20:2,03+10")
3710                                .arg(calendar->weekDayName(1, KCalendarSystem::LongDayName))
3711                                .arg(calendar->monthName(9, 1999, KCalendarSystem::LongName)),
3712                                QLatin1String("%a%p%yab%Bt/%e2/%S:%l,%M %z"));
3713     QCOMPARE(dt.dateTime(), QDateTime(QDate(2005, 9, 5), QTime(14, 3, 20), Qt::LocalTime));
3714     QCOMPARE(dt.timeType(), KDateTime::OffsetFromUTC);
3715     QCOMPARE(dt.utcOffset(), 10 * 3600);
3716     dt = KDateTime::fromString(QString::fromLatin1("%1pm05ab%2t/052/20:2,03+10")
3717                                .arg(calendar->weekDayName(1, KCalendarSystem::ShortDayName))
3718                                .arg(calendar->monthName(9, 1999, KCalendarSystem::ShortName)),
3719                                QLatin1String("%a%p%yab%Bt/%d2/%s:%l,%:M %z"));
3720     QCOMPARE(dt.dateTime(), QDateTime(QDate(2005, 9, 5), QTime(14, 3, 20), Qt::LocalTime));
3721     QCOMPARE(dt.timeType(), KDateTime::OffsetFromUTC);
3722     QCOMPARE(dt.utcOffset(), 10 * 3600);
3723     dt = KDateTime::fromString(QString::fromLatin1("monpm05absEpt/052/20:2,03+10"), QLatin1String("%a%p%yab%Bt/%d2/%S:%l,%M %z"));
3724     QCOMPARE(dt.dateTime(), QDateTime(QDate(2005, 9, 5), QTime(14, 3, 20), Qt::LocalTime));
3725     QCOMPARE(dt.timeType(), KDateTime::OffsetFromUTC);
3726     QCOMPARE(dt.utcOffset(), 10 * 3600);
3727     dt = KDateTime::fromString(QString::fromLatin1("monDAYpm05absEptemBert/052/20:2,03+10"), QLatin1String("%a%p%yab%Bt/%e2/%S:%l,%M %z"));
3728     QCOMPARE(dt.dateTime(), QDateTime(QDate(2005, 9, 5), QTime(14, 3, 20), Qt::LocalTime));
3729     QCOMPARE(dt.timeType(), KDateTime::OffsetFromUTC);
3730     QCOMPARE(dt.utcOffset(), 10 * 3600);
3731     dt = KDateTime::fromString(QString::fromLatin1("monDAYpm05abmzatemer/052/20:2,03+10"), QLatin1String("%a%p%yab%B/%e2/%S:%l,%M %z"));
3732     QVERIFY(!dt.isValid());    // invalid month name
3733     dt = KDateTime::fromString(QString::fromLatin1("monDApm05absep/052/20:2,03+10"), QLatin1String("%a%p%yab%B/%e2/%S:%l,%M %z"));
3734     QVERIFY(!dt.isValid());    // invalid day name
3735     dt = KDateTime::fromString(QLatin1String("mONdAYPM2005absEpt/052/20:02,03+1000"), QLatin1String("%:A%:p%Yab%Bt/%d2/%S:%I,%M %:u"));
3736     QCOMPARE(dt.dateTime(), QDateTime(QDate(2005, 9, 5), QTime(14, 3, 20), Qt::LocalTime));
3737     QCOMPARE(dt.utcOffset(), 10 * 3600);
3738     QCOMPARE(dt.timeType(), KDateTime::OffsetFromUTC);
3739     dtclock = KDateTime::fromString(QLatin1String("mONdAYPM2005abSept/052/20:02,03+100"), QLatin1String("%:A%:p%Yab%Bt/%e2/%S:%l,%M %:u"));
3740     QVERIFY(!dtclock.isValid());    // wrong number of digits in UTC offset
3741     dtclock = KDateTime::fromString(QLatin1String("mONdAYPM2005abSept/052/20:02,03+1"), QLatin1String("%:A%:p%Yab%Bt/%d2/%S:%I,%M %z"));
3742     QVERIFY(!dtclock.isValid());    // wrong number of digits in UTC offset
3743     dtclock = KDateTime::fromString(QLatin1String("mONdAYPM2005absEpt/052/20:13,03+1000"), QLatin1String("%:A%:p%Yab%Bt/%d2/%S:%I,%M %:u"));
3744     QVERIFY(!dtclock.isValid());    // hours out of range for am/pm
3745     dtclock = KDateTime::fromString(QLatin1String("mONdAYPM2005absEpt/052/20:00,03+1000"), QLatin1String("%:A%:p%Yab%Bt/%d2/%S:%I,%M %:u"));
3746     QVERIFY(!dtclock.isValid());    // hours out of range for am/pm
3747 
3748     // fromString() with KTimeZones parameter
3749     dt = KDateTime::fromString(QLatin1String("mon 2005/9/05/20:2,03"), QLatin1String("%:a %Y/%:m/%e/%S:%k,%M"), &zones);
3750     QCOMPARE(dt.dateTime(), QDateTime(QDate(2005, 9, 5), QTime(2, 3, 20), Qt::LocalTime));
3751     QCOMPARE(dt.timeType(), KDateTime::ClockTime);
3752     dt = KDateTime::fromString(QLatin1String("tue 2005/9/05/20:2,03"), QLatin1String("%:a %Y/%:m/%d/%S:%k,%M"), &zones);
3753     QVERIFY(!dt.isValid());    // wrong day-of-week
3754 
3755     dt = KDateTime::fromString(QLatin1String("pm2005absEpt/05monday/20:2,03+03:00"), QLatin1String("%p%Yab%Bt/%e%:A/%S:%l,%M %:z"), &zones);
3756     QCOMPARE(dt.dateTime(), QDateTime(QDate(2005, 9, 5), QTime(14, 3, 20), Qt::LocalTime));
3757     QCOMPARE(dt.timeType(), KDateTime::TimeZone);
3758     QCOMPARE(dt.utcOffset(), 3 * 3600);
3759     QCOMPARE(dt.timeZone(), cairo);
3760     dt = KDateTime::fromString(QLatin1String("pm2005absEpt/05sunday/20:2,03+03:00"), QLatin1String("%p%Yab%Bt/%d%A/%S:%l,%M %:z"), &zones);
3761     QVERIFY(!dt.isValid());    // wrong day-of-week
3762 
3763     dtutc = KDateTime::fromString(QLatin1String("2000-01-01T00:00:00.000+0000"), QLatin1String("%Y-%m-%dT%H:%M%:S%:s%z"));
3764     QVERIFY(dtutc.isValid());
3765 
3766     dt = KDateTime::fromString(QLatin1String("2000-01-01T05:00:00.000+0500"), QLatin1String("%Y-%m-%dT%H:%M%:S%:s%z"));
3767     QVERIFY(dt.isValid());
3768     QVERIFY(dtutc == dt);
3769 
3770     dt = KDateTime::fromString(QLatin1String("1999-12-31T20:30:00.000-0330"), QLatin1String("%Y-%m-%dT%H:%M%:S%:s%z"));
3771     QVERIFY(dt.isValid());
3772     QVERIFY(dtutc == dt);
3773 
3774     dt = KDateTime::fromString(QLatin1String("200509051430:01.3+0100"), QLatin1String("%Y%m%d%H%M%:S%:s%z"), &zones, true);
3775     QCOMPARE(dt.dateTime(), QDateTime(QDate(2005, 9, 5), QTime(14, 30, 01, 300), Qt::LocalTime));
3776     QCOMPARE(dt.timeType(), KDateTime::TimeZone);
3777     QCOMPARE(dt.timeZone(), london);
3778     QCOMPARE(dt.utcOffset(), 3600);
3779 
3780     dt = KDateTime::fromString(QLatin1String("200509051430:01.3+0500"), QLatin1String("%Y%m%d%H%M%:S%:s%z"), &zones, false);
3781     QCOMPARE(dt.dateTime(), QDateTime(QDate(2005, 9, 5), QTime(14, 30, 01, 300), Qt::LocalTime));
3782     QCOMPARE(dt.timeType(), KDateTime::OffsetFromUTC);
3783     QCOMPARE(dt.utcOffset(), 5 * 3600);
3784 
3785     dt = KDateTime::fromString(QLatin1String("200509051430:01.3+0200"), QLatin1String("%Y%m%d%H%M%:S%:s%z"), &zones, true);
3786     QCOMPARE(dt.dateTime(), QDateTime(QDate(2005, 9, 5), QTime(14, 30, 01, 300), Qt::LocalTime));
3787     QCOMPARE(dt.timeType(), KDateTime::OffsetFromUTC);
3788     QCOMPARE(dt.utcOffset(), 2 * 3600);
3789     dt = KDateTime::fromString(QLatin1String("200509051430:01.3+0200"), QLatin1String("%Y%m%d%H%M%:S%:s%z"), &zones, false);
3790     QVERIFY(!dt.isValid());    // matches paris and berlin
3791 
3792     dt = KDateTime::fromString(QLatin1String("2005September051430 CEST"), QLatin1String("%Y%:B%d%H%M%:S %Z"), &zones, true);
3793     QCOMPARE(dt.dateTime(), QDateTime(QDate(2005, 9, 5), QTime(14, 30, 0), Qt::LocalTime));
3794     QCOMPARE(dt.timeType(), KDateTime::OffsetFromUTC);
3795     QCOMPARE(dt.utcOffset(), 2 * 3600);
3796     dt = KDateTime::fromString(QLatin1String("2005September051430 CEST"), QLatin1String("%Y%:B%d%H%M%:S %Z"), &zones, false);
3797     QVERIFY(!dt.isValid());    // matches paris and berlin
3798 
3799     dt = KDateTime::fromString(QLatin1String("pm05absEptembeRt/   052/   20:12,03+0100"), QLatin1String("%:P%yab%:bt/  %e2/%t%S:%l,%M %z"), &zones);
3800     QCOMPARE(dt.dateTime(), QDateTime(QDate(2005, 9, 5), QTime(12, 3, 20), Qt::LocalTime));
3801     QCOMPARE(dt.timeType(), KDateTime::TimeZone);
3802     QCOMPARE(dt.utcOffset(), 3600);
3803     QCOMPARE(dt.timeZone(), london);
3804 
3805     dt = KDateTime::fromString(QLatin1String("2005absEpt/042sun/20.0123456:12Am,3Africa/Cairo%"), QLatin1String("%Yab%bt/%e2%a/%S%:s:%I%P,%:M %:Z%%"), &zones);
3806     QCOMPARE(dt.dateTime(), QDateTime(QDate(2005, 9, 4), QTime(0, 3, 20, 12), Qt::LocalTime));
3807     QCOMPARE(dt.timeType(), KDateTime::TimeZone);
3808     QCOMPARE(dt.timeZone(), cairo);
3809     QCOMPARE(dt.utcOffset(), 3 * 3600);
3810 
3811     // Test large and minimum date values
3812     dt = KDateTime(QDate(-2005, 9, 5), QTime(0, 0, 06, 1), KDateTime::ClockTime);
3813     s = dt.toString(QLatin1String("%Y"));
3814     QCOMPARE(s, QString::fromLatin1("-2005"));
3815 
3816     dt = KDateTime(QDate(-15, 9, 5), QTime(0, 0, 06, 1), KDateTime::ClockTime);
3817     s = dt.toString(QLatin1String("%Y"));
3818     QCOMPARE(s, QString::fromLatin1("-0015"));
3819 
3820     dt = KDateTime::fromString(QLatin1String("-471209051430:01.3+0500"), QLatin1String("%Y%m%d%H%M%:S%:s%z"));
3821     QCOMPARE(dt.dateTime(), QDateTime(QDate(-4712, 9, 5), QTime(14, 30, 1, 300), Qt::LocalTime));
3822     QCOMPARE(dt.utcOffset(), 5 * 3600);
3823     QVERIFY(dt.isValid());
3824 
3825     dt = KDateTime::fromString(QLatin1String("999909051430:01.3+0500"), QLatin1String("%Y%m%d%H%M%:S%:s%z"));
3826     QCOMPARE(dt.dateTime(), QDateTime(QDate(9999, 9, 5), QTime(14, 30, 1, 300), Qt::LocalTime));
3827     QCOMPARE(dt.utcOffset(), 5 * 3600);
3828     QVERIFY(dt.isValid());
3829 
3830     dt = KDateTime::fromString(QLatin1String("123456.09051430:01.3+0500"), QLatin1String("%:Y.%m%d%H%M%:S%:s%z"));
3831     QCOMPARE(dt.dateTime(), QDateTime(QDate(123456, 9, 5), QTime(14, 30, 1, 300), Qt::LocalTime));
3832     QCOMPARE(dt.utcOffset(), 5 * 3600);
3833     QVERIFY(dt.isValid());
3834     s = dt.toString(QLatin1String("%Y"));
3835     QCOMPARE(s, QString::fromLatin1("123456"));
3836 
3837     dt = KDateTime::fromString(QLatin1String("-471411231430:01.3+0500"), QLatin1String("%Y%m%d%H%M%:S%:s%z"));
3838     QVERIFY(dt.isValid());
3839     QVERIFY(dt.date().toJulianDay() == -1);
3840 
3841     // Restore the original local time zone
3842     if (originalZone.isEmpty()) {
3843         ::unsetenv("TZ");
3844     } else {
3845         qputenv("TZ", originalZone);
3846     }
3847     ::tzset();
3848 }
3849 
3850 #ifdef COMPILING_TESTS
3851 // This test requires a specially-modified kdecore, so use the same compile guard here
3852 // as used in kdecore/date/kdatetime.cpp
3853 void KDateTimeTest::cache()
3854 {
3855     KTimeZone london = KSystemTimeZones::zone("Europe/London");
3856     KTimeZone losAngeles = KSystemTimeZones::zone("America/Los_Angeles");
3857     KTimeZone cairo = KSystemTimeZones::zone("Africa/Cairo");
3858 
3859     QByteArray originalZone = qgetenv("TZ");   // save the original local time zone
3860     qputenv("TZ", ":Europe/London");
3861     ::tzset();
3862 
3863     // Ensure that local time is different from UTC and different from 'london'
3864     qputenv("TZ", ":America/Los_Angeles");
3865     ::tzset();
3866 
3867     int utcHit  = KDateTime_utcCacheHit;
3868     int zoneHit = KDateTime_zoneCacheHit;
3869     KDateTime local(QDate(2005, 6, 1), QTime(12, 0, 0), KDateTime::LocalZone);
3870     QCOMPARE(KDateTime_utcCacheHit, utcHit);
3871     QCOMPARE(KDateTime_zoneCacheHit, zoneHit);
3872     KDateTime dt1 = local.toZone(london);
3873     QCOMPARE(KDateTime_utcCacheHit, utcHit);
3874     QCOMPARE(KDateTime_zoneCacheHit, zoneHit);
3875     KDateTime cai = local.toZone(cairo);
3876     ++utcHit;
3877     QCOMPARE(KDateTime_utcCacheHit, utcHit);
3878     QCOMPARE(KDateTime_zoneCacheHit, zoneHit);
3879     KDateTime dt2a = local.toZone(london);
3880     ++utcHit;
3881     QCOMPARE(KDateTime_utcCacheHit, utcHit);
3882     QCOMPARE(KDateTime_zoneCacheHit, zoneHit);
3883     KDateTime dt2 = local.toZone(london);
3884     ++zoneHit;
3885     QCOMPARE(KDateTime_utcCacheHit, utcHit);
3886     QCOMPARE(KDateTime_zoneCacheHit, zoneHit);
3887     KDateTime dt3 = dt2;
3888     QCOMPARE(KDateTime_utcCacheHit, utcHit);
3889     QCOMPARE(KDateTime_zoneCacheHit, zoneHit);
3890     KDateTime dt4 = dt2.toZone(losAngeles);
3891     ++zoneHit;
3892     QCOMPARE(KDateTime_utcCacheHit, utcHit);
3893     QCOMPARE(KDateTime_zoneCacheHit, zoneHit);
3894     KDateTime dt4a = dt3.toZone(losAngeles);
3895     ++zoneHit;
3896     QCOMPARE(KDateTime_utcCacheHit, utcHit);
3897     QCOMPARE(KDateTime_zoneCacheHit, zoneHit);
3898     KDateTime dt5 = dt2.toZone(losAngeles);
3899     ++zoneHit;
3900     QCOMPARE(KDateTime_utcCacheHit, utcHit);
3901     QCOMPARE(KDateTime_zoneCacheHit, zoneHit);
3902     KDateTime dt5a = dt3.toZone(losAngeles);
3903     ++zoneHit;
3904     QCOMPARE(KDateTime_utcCacheHit, utcHit);
3905     QCOMPARE(KDateTime_zoneCacheHit, zoneHit);
3906     KDateTime dt6 = dt2.toZone(cairo);
3907     ++utcHit;
3908     QCOMPARE(KDateTime_utcCacheHit, utcHit);
3909     QCOMPARE(KDateTime_zoneCacheHit, zoneHit);
3910     KDateTime dt6a = dt3.toZone(cairo);
3911     ++zoneHit;
3912     QCOMPARE(KDateTime_utcCacheHit, utcHit);
3913     QCOMPARE(KDateTime_zoneCacheHit, zoneHit);
3914     dt3.detach();
3915     KDateTime dt7 = dt2.toZone(london);
3916     QCOMPARE(KDateTime_utcCacheHit, utcHit);
3917     QCOMPARE(KDateTime_zoneCacheHit, zoneHit);
3918     KDateTime dt7a = dt3.toZone(london);
3919     QCOMPARE(KDateTime_utcCacheHit, utcHit);
3920     QCOMPARE(KDateTime_zoneCacheHit, zoneHit);
3921 
3922     // Check that cached time zone conversions are cleared correctly
3923     KDateTime utc1(QDate(2005, 7, 6), QTime(3, 40, 0), KDateTime::UTC);
3924     KDateTime la1 = utc1.toTimeSpec(losAngeles);
3925     KDateTime utc2 = utc1.addDays(1);
3926     KDateTime la2 = utc2.toTimeSpec(losAngeles);
3927     QVERIFY(la1 != la2);
3928     QCOMPARE(la1.secsTo(la2), 86400);
3929 
3930     // Restore the original local time zone
3931     if (originalZone.isEmpty()) {
3932         ::unsetenv("TZ");
3933     } else {
3934         qputenv("TZ", originalZone);
3935     }
3936     ::tzset();
3937 }
3938 #endif /* COMPILING_TESTS */
3939 
3940 void KDateTimeTest::stream()
3941 {
3942     // Ensure that local time is different from UTC and different from 'london'
3943     QByteArray originalZone = qgetenv("TZ");   // save the original local time zone
3944     qputenv("TZ", ":America/Los_Angeles");
3945     ::tzset();
3946 
3947     // Ensure that the original contents of the KDateTime receiving a streamed value
3948     // don't affect the new contents.
3949     QByteArray data;
3950     QDataStream ds(&data, QIODevice::ReadWrite);
3951     KDateTime testdt, result;
3952 
3953     data.clear();
3954     testdt = KDateTime(QDate(2005, 6, 1), QTime(12, 0, 0), KDateTime::LocalZone);
3955     result = KDateTime::currentUtcDateTime();
3956     ds << testdt;
3957     ds.device()->seek(0);
3958     ds >> result;
3959     QCOMPARE(result, testdt);
3960 
3961     data.clear();
3962     testdt = KDateTime(QDate(2005, 6, 1), QTime(12, 0, 0), KDateTime::LocalZone);
3963     result = KDateTime::currentLocalDateTime();
3964     ds.device()->seek(0);
3965     ds << testdt;
3966     ds.device()->seek(0);
3967     ds >> result;
3968     QCOMPARE(result, testdt);
3969 
3970     data.clear();
3971     testdt = KDateTime(QDate(2006, 8, 30), QTime(7, 0, 0), KDateTime::UTC);
3972     result = KDateTime::currentUtcDateTime();
3973     ds.device()->seek(0);
3974     ds << testdt;
3975     ds.device()->seek(0);
3976     ds >> result;
3977     QCOMPARE(result, testdt);
3978 
3979     data.clear();
3980     testdt = KDateTime(QDate(2006, 8, 30), QTime(7, 0, 0), KDateTime::UTC);
3981     result = KDateTime::currentLocalDateTime();
3982     ds.device()->seek(0);
3983     ds << testdt;
3984     ds.device()->seek(0);
3985     ds >> result;
3986     QCOMPARE(result, testdt);
3987 
3988     // Restore the original local time zone
3989     if (originalZone.isEmpty()) {
3990         ::unsetenv("TZ");
3991     } else {
3992         qputenv("TZ", originalZone);
3993     }
3994     ::tzset();
3995 }
3996 
3997 void KDateTimeTest::misc()
3998 {
3999     // Ensure that local time is different from UTC and different from 'london'
4000     QByteArray originalZone = qgetenv("TZ");   // save the original local time zone
4001     qputenv("TZ", ":America/Los_Angeles");
4002     ::tzset();
4003 
4004     KDateTime local = KDateTime::currentLocalDateTime();
4005     KDateTime utc = KDateTime::currentUtcDateTime();
4006     QDateTime qcurrent = QDateTime::currentDateTime();
4007     // Because 3 calls to fetch the current time were made, they will differ slightly
4008     KDateTime localUtc = local.toUtc();
4009     int diff = localUtc.secsTo(utc);
4010     if (diff > 1  ||  diff < 0) {
4011         QCOMPARE(local.toUtc().dateTime(), utc.dateTime());
4012     }
4013     diff = local.dateTime().secsTo(qcurrent);
4014     if (diff > 1  ||  diff < 0) {
4015         QCOMPARE(local.dateTime(), qcurrent);
4016     }
4017 
4018     // Restore the original local time zone
4019     if (originalZone.isEmpty()) {
4020         ::unsetenv("TZ");
4021     } else {
4022         qputenv("TZ", originalZone);
4023     }
4024     ::tzset();
4025 }
4026 
4027 #include "moc_kdatetimetest.cpp"