File indexing completed on 2024-11-24 04:42:17

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