1 /*
2    This file is part of kalarmcal library, which provides access to KAlarm
3    calendar data.
4 
5    SPDX-FileCopyrightText: 2005-2021 David Jarvie <djarvie@kde.org>
6 
7    SPDX-License-Identifier: LGPL-2.0-or-later
8 */
9 
10 #include "kadatetimetest.h"
11 #include <stdlib.h>
12 #include "kadatetime.h"
13 using KAlarmCal::KADateTime;
14 
15 
16 #include <QTest>
17 #include <QTimeZone>
18 #include <QLocale>
19 #include <QDBusConnection>
20 #include <QDBusConnectionInterface>
21 
22 //clazy:excludeall=non-pod-global-static
23 
24 //TODO: test new methods
25 
26 QTEST_GUILESS_MAIN(KADateTimeTest)
27 
28 
29 namespace KAlarmCal
30 {
31 extern KALARMCAL_EXPORT int KADateTime_utcCacheHit;
32 extern KALARMCAL_EXPORT int KADateTime_zoneCacheHit;
33 }
34 
35 ////////////////////////////////////////////////////////////////////////
36 // KADateTime::Spec constructors and basic property information methods,
37 // and the static convenience instances/methods.
38 ////////////////////////////////////////////////////////////////////////
39 
specConstructors()40 void KADateTimeTest::specConstructors()
41 {
42     QTimeZone london("Europe/London");
43     QTimeZone losAngeles("America/Los_Angeles");
44 
45     QByteArray originalZone = qgetenv("TZ");   // save the original local time zone
46     qputenv("TZ", ":Europe/London");
47     ::tzset();
48 
49     // Ensure that local time is different from UTC and different from 'london'
50     qputenv("TZ", ":America/Los_Angeles");
51     ::tzset();
52 
53     // Default constructor
54     KADateTime::Spec invalid;
55     QVERIFY(!invalid.isValid());
56     QCOMPARE(invalid.type(), KADateTime::Invalid);
57     QVERIFY(!invalid.isLocalZone());
58     QVERIFY(!invalid.isUtc());
59     QVERIFY(!invalid.isOffsetFromUtc());
60     QCOMPARE(invalid.utcOffset(), 0);
61     QVERIFY(!invalid.timeZone().isValid());
62 
63     // Time zone
64     KADateTime::Spec tz(london);
65     QVERIFY(tz.isValid());
66     QCOMPARE(tz.type(), KADateTime::TimeZone);
67     QVERIFY(!tz.isUtc());
68     QVERIFY(!tz.isOffsetFromUtc());
69     QVERIFY(!tz.isLocalZone());
70     QCOMPARE(tz.utcOffset(), 0);
71     QCOMPARE(tz.timeZone(), london);
72 
73     KADateTime::Spec tzLocal(losAngeles);
74     QVERIFY(tzLocal.isValid());
75     QCOMPARE(tzLocal.type(), KADateTime::TimeZone);
76     QVERIFY(!tzLocal.isUtc());
77     QVERIFY(!tzLocal.isOffsetFromUtc());
78     QVERIFY(!tzLocal.isLocalZone());
79     QCOMPARE(tzLocal.utcOffset(), 0);
80     QCOMPARE(tzLocal.timeZone(), losAngeles);
81 
82     // ... copy constructor
83     KADateTime::Spec tzCopy(tz);
84     QVERIFY(tzCopy.isValid());
85     QCOMPARE(tzCopy.type(), KADateTime::TimeZone);
86     QVERIFY(!tzCopy.isUtc());
87     QVERIFY(!tzCopy.isOffsetFromUtc());
88     QVERIFY(!tzCopy.isLocalZone());
89     QCOMPARE(tzCopy.utcOffset(), 0);
90     QCOMPARE(tzCopy.timeZone(), london);
91 
92     // Local time zone
93     KADateTime::Spec local(KADateTime::LocalZone);
94     QVERIFY(local.isValid());
95     QCOMPARE(local.type(), KADateTime::LocalZone);
96     QCOMPARE(local, KADateTime::Spec(KADateTime::LocalZone));
97     QVERIFY(!local.isUtc());
98     QVERIFY(!local.isOffsetFromUtc());
99     QVERIFY(local.isLocalZone());
100     QCOMPARE(local.utcOffset(), 0);
101     QCOMPARE(local.timeZone(), QTimeZone::systemTimeZone());
102 
103     KADateTime::Spec localx(KADateTime::Spec(KADateTime::LocalZone, 2 * 3600));
104     QVERIFY(localx.isValid());
105     QCOMPARE(localx.type(), KADateTime::LocalZone);
106     QCOMPARE(localx, KADateTime::Spec(KADateTime::LocalZone));
107     QVERIFY(!localx.isUtc());
108     QVERIFY(!localx.isOffsetFromUtc());
109     QVERIFY(localx.isLocalZone());
110     QCOMPARE(localx.utcOffset(), 0);
111     QCOMPARE(localx.timeZone(), QTimeZone::systemTimeZone());
112 
113     KADateTime::Spec local2 = KADateTime::Spec::LocalZone();
114     QVERIFY(local2.isValid());
115     QCOMPARE(local2.type(), KADateTime::LocalZone);
116     QCOMPARE(local2, KADateTime::Spec(KADateTime::LocalZone));
117     QVERIFY(!local2.isUtc());
118     QVERIFY(!local2.isOffsetFromUtc());
119     QVERIFY(local2.isLocalZone());
120     QCOMPARE(local2.utcOffset(), 0);
121     QCOMPARE(local2.timeZone(), QTimeZone::systemTimeZone());
122 
123     // ... copy constructor
124     KADateTime::Spec localCopy(local);
125     QVERIFY(localCopy.isValid());
126     QCOMPARE(localCopy.type(), KADateTime::LocalZone);
127     QCOMPARE(localCopy, KADateTime::Spec(KADateTime::LocalZone));
128     QVERIFY(!localCopy.isUtc());
129     QVERIFY(!localCopy.isOffsetFromUtc());
130     QVERIFY(localCopy.isLocalZone());
131     QCOMPARE(localCopy.utcOffset(), 0);
132     QCOMPARE(localCopy.timeZone(), losAngeles);
133 
134     // UTC
135     KADateTime::Spec utc(KADateTime::UTC);
136     QVERIFY(utc.isValid());
137     QCOMPARE(utc.type(), KADateTime::UTC);
138     QVERIFY(utc.isUtc());
139     QVERIFY(!utc.isOffsetFromUtc());
140     QVERIFY(!utc.isLocalZone());
141     QCOMPARE(utc.utcOffset(), 0);
142     QCOMPARE(utc.timeZone(), QTimeZone::utc());
143 
144     KADateTime::Spec utcx(KADateTime::UTC, 2 * 3600);
145     QVERIFY(utcx.isValid());
146     QCOMPARE(utcx.type(), KADateTime::UTC);
147     QVERIFY(utcx.isUtc());
148     QVERIFY(!utcx.isOffsetFromUtc());
149     QVERIFY(!utcx.isLocalZone());
150     QCOMPARE(utcx.utcOffset(), 0);
151     QCOMPARE(utcx.timeZone(), QTimeZone::utc());
152 
153     const KADateTime::Spec &utc2 = KADateTime::Spec::UTC();
154     QVERIFY(utc2.isValid());
155     QCOMPARE(utc2.type(), KADateTime::UTC);
156     QVERIFY(utc2.isUtc());
157     QVERIFY(!utc2.isOffsetFromUtc());
158     QVERIFY(!utc2.isLocalZone());
159     QCOMPARE(utc2.utcOffset(), 0);
160     QCOMPARE(utc2.timeZone(), QTimeZone::utc());
161 
162     // ... copy constructor
163     KADateTime::Spec utcCopy(utc);
164     QVERIFY(utcCopy.isValid());
165     QCOMPARE(utcCopy.type(), KADateTime::UTC);
166     QVERIFY(utcCopy.isUtc());
167     QVERIFY(!utcCopy.isOffsetFromUtc());
168     QVERIFY(!utcCopy.isLocalZone());
169     QCOMPARE(utcCopy.utcOffset(), 0);
170     QCOMPARE(utcCopy.timeZone(), QTimeZone::utc());
171 
172     // Offset from UTC
173     KADateTime::Spec offset0(KADateTime::OffsetFromUTC);
174     QVERIFY(offset0.isValid());
175     QCOMPARE(offset0.type(), KADateTime::OffsetFromUTC);
176     QVERIFY(offset0.isUtc());
177     QVERIFY(offset0.isOffsetFromUtc());
178     QVERIFY(!offset0.isLocalZone());
179     QCOMPARE(offset0.utcOffset(), 0);
180     QVERIFY(!offset0.timeZone().isValid());
181 
182     KADateTime::Spec offset(KADateTime::Spec(KADateTime::OffsetFromUTC, -2 * 3600));
183     QVERIFY(offset.isValid());
184     QCOMPARE(offset.type(), KADateTime::OffsetFromUTC);
185     QVERIFY(!offset.isUtc());
186     QVERIFY(offset.isOffsetFromUtc());
187     QVERIFY(!offset.isLocalZone());
188     QCOMPARE(offset.utcOffset(), -2 * 3600);
189     QVERIFY(!offset.timeZone().isValid());
190 
191     KADateTime::Spec offset2 = KADateTime::Spec::OffsetFromUTC(2 * 3600);
192     QVERIFY(offset2.isValid());
193     QCOMPARE(offset2.type(), KADateTime::OffsetFromUTC);
194     QVERIFY(!offset2.isUtc());
195     QVERIFY(offset2.isOffsetFromUtc());
196     QVERIFY(!offset2.isLocalZone());
197     QCOMPARE(offset2.utcOffset(), 2 * 3600);
198     QVERIFY(!offset2.timeZone().isValid());
199 
200     // ... copy constructor
201     KADateTime::Spec offsetCopy(offset);
202     QVERIFY(offsetCopy.isValid());
203     QCOMPARE(offsetCopy.type(), KADateTime::OffsetFromUTC);
204     QVERIFY(!offsetCopy.isUtc());
205     QVERIFY(offsetCopy.isOffsetFromUtc());
206     QVERIFY(!offsetCopy.isLocalZone());
207     QCOMPARE(offsetCopy.utcOffset(), -2 * 3600);
208     QVERIFY(!offsetCopy.timeZone().isValid());
209 
210     // Restore the original local time zone
211     if (originalZone.isEmpty()) {
212         unsetenv("TZ");
213     } else {
214         qputenv("TZ", originalZone);
215     }
216     ::tzset();
217 }
218 
219 ////////////////////////////////////////////////////////////////////////
220 // KADateTime::Spec setType(), operator==(), etc.
221 ////////////////////////////////////////////////////////////////////////
222 
specSet()223 void KADateTimeTest::specSet()
224 {
225     QTimeZone london("Europe/London");
226     QTimeZone losAngeles("America/Los_Angeles");
227 
228     // Ensure that local time is different from UTC and different from 'london'
229     QByteArray originalZone = qgetenv("TZ");   // save the original local time zone
230     qputenv("TZ", ":America/Los_Angeles");
231     ::tzset();
232 
233     KADateTime::Spec spec;
234     QCOMPARE(spec.type(), KADateTime::Invalid);
235 
236     spec.setType(KADateTime::OffsetFromUTC, 7200);
237     QCOMPARE(spec.type(), KADateTime::OffsetFromUTC);
238     QVERIFY(spec.equivalentTo(KADateTime::Spec::OffsetFromUTC(7200)));
239     QVERIFY(!spec.equivalentTo(KADateTime::Spec::OffsetFromUTC(0)));
240     QVERIFY(spec == KADateTime::Spec::OffsetFromUTC(7200));
241     QVERIFY(!(spec != KADateTime::Spec::OffsetFromUTC(7200)));
242     QVERIFY(spec != KADateTime::Spec::OffsetFromUTC(-7200));
243     QVERIFY(spec != KADateTime::Spec(london));
244 
245     spec.setType(KADateTime::OffsetFromUTC, 0);
246     QCOMPARE(spec.type(), KADateTime::OffsetFromUTC);
247     QVERIFY(spec.equivalentTo(KADateTime::Spec::OffsetFromUTC(0)));
248     QVERIFY(spec.equivalentTo(KADateTime::Spec::UTC()));
249     QVERIFY(!spec.equivalentTo(KADateTime::Spec::OffsetFromUTC(7200)));
250     QVERIFY(spec == KADateTime::Spec::OffsetFromUTC(0));
251     QVERIFY(!(spec != KADateTime::Spec::OffsetFromUTC(0)));
252     QVERIFY(spec != KADateTime::Spec::OffsetFromUTC(-7200));
253     QVERIFY(spec != KADateTime::Spec(london));
254 
255     spec.setType(london);
256     QCOMPARE(spec.type(), KADateTime::TimeZone);
257     QVERIFY(spec.equivalentTo(KADateTime::Spec(london)));
258     QVERIFY(spec == KADateTime::Spec(london));
259     QVERIFY(!(spec != KADateTime::Spec(london)));
260     QVERIFY(spec != KADateTime::Spec::OffsetFromUTC(0));
261     QVERIFY(!spec.equivalentTo(KADateTime::Spec::OffsetFromUTC(0)));
262 
263     spec.setType(KADateTime::LocalZone);
264     QCOMPARE(spec.type(), KADateTime::LocalZone);
265     QVERIFY(spec.equivalentTo(KADateTime::Spec::LocalZone()));
266     QVERIFY(spec == KADateTime::Spec::LocalZone());
267     QVERIFY(!(spec != KADateTime::Spec::LocalZone()));
268     QVERIFY(spec.equivalentTo(KADateTime::Spec(losAngeles)));
269     QVERIFY(spec != KADateTime::Spec(losAngeles));
270     QVERIFY(spec != KADateTime::Spec(london));
271     QVERIFY(!spec.equivalentTo(KADateTime::Spec(london)));
272 
273     spec.setType(KADateTime::UTC);
274     QCOMPARE(spec.type(), KADateTime::UTC);
275     QVERIFY(spec.equivalentTo(KADateTime::Spec::UTC()));
276     QVERIFY(spec == KADateTime::Spec::UTC());
277     QVERIFY(!(spec != KADateTime::Spec::UTC()));
278     QVERIFY(spec != KADateTime::Spec::LocalZone());
279     QVERIFY(!spec.equivalentTo(KADateTime::Spec::LocalZone()));
280     QVERIFY(spec.equivalentTo(KADateTime::Spec::OffsetFromUTC(0)));
281 
282     // Restore the original local time zone
283     if (originalZone.isEmpty()) {
284         unsetenv("TZ");
285     } else {
286         qputenv("TZ", originalZone);
287     }
288     ::tzset();
289 }
290 
291 //////////////////////////////////////////////////////
292 // Constructors and basic property information methods
293 //////////////////////////////////////////////////////
294 
constructors()295 void KADateTimeTest::constructors()
296 {
297     QDate d(2001, 2, 13);
298     QTime t(3, 45, 14);
299     QDateTime dtLocal(d, t, Qt::LocalTime);
300     QDateTime dtUTC(d, t, Qt::UTC);
301     QTimeZone london("Europe/London");
302 
303     QByteArray originalZone = qgetenv("TZ");   // save the original local time zone
304     qputenv("TZ", ":Europe/London");
305     ::tzset();
306     QDateTime dtUTCtoLondon = dtUTC.toLocalTime();
307 
308     // Ensure that local time is different from UTC and different from 'london'
309     qputenv("TZ", ":America/Los_Angeles");
310     ::tzset();
311 
312     // Default constructor
313     KADateTime deflt;
314     QVERIFY(deflt.isNull());
315     QVERIFY(!deflt.isValid());
316 
317     // No time zone or timeSpec explicitly specified
318     KADateTime datetimeL(dtLocal);
319     QVERIFY(!datetimeL.isNull());
320     QVERIFY(datetimeL.isValid());
321     QVERIFY(!datetimeL.isDateOnly());
322     QCOMPARE(datetimeL.timeType(), KADateTime::LocalZone);
323     QCOMPARE(datetimeL.timeSpec(), KADateTime::Spec::LocalZone());
324     QVERIFY(datetimeL.isLocalZone());
325     QVERIFY(!datetimeL.isUtc());
326     QVERIFY(!datetimeL.isOffsetFromUtc());
327     QCOMPARE(datetimeL.utcOffset(), -8 * 3600);
328     QCOMPARE(datetimeL.timeZone(), QTimeZone::systemTimeZone());
329     QCOMPARE(datetimeL.date(), dtLocal.date());
330     QCOMPARE(datetimeL.time(), dtLocal.time());
331     QCOMPARE(datetimeL.qDateTime(), dtLocal);
332 
333     KADateTime datetimeU(dtUTC);
334     QVERIFY(!datetimeU.isNull());
335     QVERIFY(datetimeU.isValid());
336     QVERIFY(!datetimeU.isDateOnly());
337     QCOMPARE(datetimeU.timeType(), KADateTime::UTC);
338     QVERIFY(!datetimeU.isLocalZone());
339     QVERIFY(datetimeU.isUtc());
340     QVERIFY(!datetimeU.isOffsetFromUtc());
341     QCOMPARE(datetimeU.utcOffset(), 0);
342     QCOMPARE(datetimeU.timeZone(), QTimeZone::utc());
343     QCOMPARE(datetimeU.date(), dtUTC.date());
344     QCOMPARE(datetimeU.time(), dtUTC.time());
345     QCOMPARE(datetimeU.qDateTime(), dtUTC);
346 
347     // Time zone
348     KADateTime dateTz(d, london);
349     QVERIFY(!dateTz.isNull());
350     QVERIFY(dateTz.isValid());
351     QVERIFY(dateTz.isDateOnly());
352     QCOMPARE(dateTz.timeType(), KADateTime::TimeZone);
353     QVERIFY(!dateTz.isUtc());
354     QVERIFY(!dateTz.isOffsetFromUtc());
355     QVERIFY(!dateTz.isLocalZone());
356     QCOMPARE(dateTz.utcOffset(), 0);
357     QCOMPARE(dateTz.timeZone(), london);
358     QCOMPARE(dateTz.date(), d);
359     QCOMPARE(dateTz.time(), QTime(0, 0, 0));
360     QCOMPARE(dateTz.qDateTime(), QDateTime(d, QTime(0, 0, 0), london));
361 
362     KADateTime dateTimeTz(d, QTime(3, 45, 14), london);
363     QVERIFY(!dateTimeTz.isNull());
364     QVERIFY(dateTimeTz.isValid());
365     QVERIFY(!dateTimeTz.isDateOnly());
366     QCOMPARE(dateTimeTz.timeType(), KADateTime::TimeZone);
367     QVERIFY(!dateTimeTz.isUtc());
368     QVERIFY(!dateTimeTz.isOffsetFromUtc());
369     QVERIFY(!dateTimeTz.isLocalZone());
370     QCOMPARE(dateTimeTz.utcOffset(), 0);
371     QCOMPARE(dateTimeTz.timeZone(), london);
372     QCOMPARE(dateTimeTz.date(), d);
373     QCOMPARE(dateTimeTz.time(), QTime(3, 45, 14));
374     QCOMPARE(dateTimeTz.qDateTime(), QDateTime(d, QTime(3, 45, 14), london));
375 
376     KADateTime datetimeTz(dtLocal, london);
377     QVERIFY(!datetimeTz.isNull());
378     QVERIFY(datetimeTz.isValid());
379     QVERIFY(!dateTimeTz.isDateOnly());
380     QCOMPARE(datetimeTz.timeType(), KADateTime::TimeZone);
381     QVERIFY(!datetimeTz.isUtc());
382     QVERIFY(!datetimeTz.isOffsetFromUtc());
383     QVERIFY(!datetimeTz.isLocalZone());
384     QCOMPARE(datetimeTz.utcOffset(), 0);
385     QCOMPARE(datetimeTz.timeZone(), london);
386     QCOMPARE(datetimeTz.date(), dtLocal.date());
387     QCOMPARE(datetimeTz.time(), QTime(11, 45, 14));
388     QCOMPARE(datetimeTz.qDateTime(), dtLocal.toTimeZone(london));
389 
390     KADateTime datetimeTz2(dtUTC, london);
391     QVERIFY(!datetimeTz2.isNull());
392     QVERIFY(datetimeTz2.isValid());
393     QVERIFY(!dateTimeTz.isDateOnly());
394     QCOMPARE(datetimeTz2.timeType(), KADateTime::TimeZone);
395     QVERIFY(!datetimeTz2.isUtc());
396     QVERIFY(!datetimeTz2.isOffsetFromUtc());
397     QVERIFY(!datetimeTz2.isLocalZone());
398     QCOMPARE(datetimeTz2.utcOffset(), 0);
399     QCOMPARE(datetimeTz2.timeZone(), london);
400     QCOMPARE(datetimeTz2.date(), dtUTCtoLondon.date());
401     QCOMPARE(datetimeTz2.time(), dtUTCtoLondon.time());
402     QCOMPARE(datetimeTz2.qDateTime(), dtUTC);
403 
404     // ... copy constructor
405     KADateTime datetimeTzCopy(datetimeTz);
406     QVERIFY(!datetimeTzCopy.isNull());
407     QVERIFY(datetimeTzCopy.isValid());
408     QVERIFY(!dateTimeTz.isDateOnly());
409     QCOMPARE(datetimeTzCopy.timeType(), KADateTime::TimeZone);
410     QVERIFY(!datetimeTzCopy.isUtc());
411     QVERIFY(!datetimeTzCopy.isOffsetFromUtc());
412     QVERIFY(!datetimeTzCopy.isLocalZone());
413     QCOMPARE(datetimeTzCopy.utcOffset(), 0);
414     QCOMPARE(datetimeTzCopy.timeZone(), datetimeTz.timeZone());
415     QCOMPARE(datetimeTzCopy.date(), datetimeTz.date());
416     QCOMPARE(datetimeTzCopy.time(), datetimeTz.time());
417     QCOMPARE(datetimeTzCopy.qDateTime(), datetimeTz.qDateTime());
418 
419     // UTC
420     KADateTime date_UTC(d, KADateTime::Spec::UTC());
421     QVERIFY(!date_UTC.isNull());
422     QVERIFY(date_UTC.isValid());
423     QVERIFY(date_UTC.isDateOnly());
424     QCOMPARE(date_UTC.timeType(), KADateTime::UTC);
425     QVERIFY(date_UTC.isUtc());
426     QVERIFY(!date_UTC.isOffsetFromUtc());
427     QVERIFY(!date_UTC.isLocalZone());
428     QCOMPARE(date_UTC.utcOffset(), 0);
429     QCOMPARE(date_UTC.timeZone(), QTimeZone::utc());
430     QCOMPARE(date_UTC.date(), d);
431     QCOMPARE(date_UTC.time(), QTime(0, 0, 0));
432     QCOMPARE(date_UTC.qDateTime(), QDateTime(d, QTime(0, 0, 0), Qt::UTC));
433 
434     KADateTime dateTime_UTC(d, t, KADateTime::UTC);
435     QVERIFY(!dateTime_UTC.isNull());
436     QVERIFY(dateTime_UTC.isValid());
437     QVERIFY(!dateTime_UTC.isDateOnly());
438     QCOMPARE(dateTime_UTC.timeType(), KADateTime::UTC);
439     QVERIFY(dateTime_UTC.isUtc());
440     QVERIFY(!dateTime_UTC.isOffsetFromUtc());
441     QVERIFY(!dateTime_UTC.isLocalZone());
442     QCOMPARE(dateTime_UTC.utcOffset(), 0);
443     QCOMPARE(dateTime_UTC.timeZone(), QTimeZone::utc());
444     QCOMPARE(dateTime_UTC.date(), d);
445     QCOMPARE(dateTime_UTC.time(), t);
446     QCOMPARE(dateTime_UTC.qDateTime(), QDateTime(d, t, Qt::UTC));
447 
448     KADateTime datetime_UTC(dtLocal, KADateTime::UTC);
449     QVERIFY(!datetime_UTC.isNull());
450     QVERIFY(datetime_UTC.isValid());
451     QVERIFY(!datetime_UTC.isDateOnly());
452     QCOMPARE(datetime_UTC.timeType(), KADateTime::UTC);
453     QVERIFY(datetime_UTC.isUtc());
454     QVERIFY(!datetime_UTC.isOffsetFromUtc());
455     QVERIFY(!datetime_UTC.isLocalZone());
456     QCOMPARE(datetime_UTC.utcOffset(), 0);
457     QCOMPARE(datetime_UTC.timeZone(), QTimeZone::utc());
458     {
459         QDateTime utc = dtLocal.toUTC();
460         QCOMPARE(datetime_UTC.date(), utc.date());
461         QCOMPARE(datetime_UTC.time(), utc.time());
462         QCOMPARE(datetime_UTC.qDateTime(), utc);
463     }
464 
465     KADateTime datetime_UTC2(dtUTC, KADateTime::UTC);
466     QVERIFY(!datetime_UTC2.isNull());
467     QVERIFY(datetime_UTC2.isValid());
468     QVERIFY(!datetime_UTC2.isDateOnly());
469     QCOMPARE(datetime_UTC2.timeType(), KADateTime::UTC);
470     QVERIFY(datetime_UTC2.isUtc());
471     QVERIFY(!datetime_UTC2.isOffsetFromUtc());
472     QVERIFY(!datetime_UTC2.isLocalZone());
473     QCOMPARE(datetime_UTC2.utcOffset(), 0);
474     QCOMPARE(datetime_UTC2.timeZone(), QTimeZone::utc());
475     QCOMPARE(datetime_UTC2.date(), dtUTC.date());
476     QCOMPARE(datetime_UTC2.time(), dtUTC.time());
477     QCOMPARE(datetime_UTC2.qDateTime(), dtUTC);
478 
479     // ... copy constructor
480     KADateTime datetime_UTCCopy(datetime_UTC);
481     QVERIFY(!datetime_UTCCopy.isNull());
482     QVERIFY(datetime_UTCCopy.isValid());
483     QVERIFY(!datetime_UTCCopy.isDateOnly());
484     QCOMPARE(datetime_UTCCopy.timeType(), KADateTime::UTC);
485     QVERIFY(datetime_UTCCopy.isUtc());
486     QVERIFY(!datetime_UTCCopy.isOffsetFromUtc());
487     QVERIFY(!datetime_UTCCopy.isLocalZone());
488     QCOMPARE(datetime_UTCCopy.utcOffset(), 0);
489     QCOMPARE(datetime_UTCCopy.timeZone(), datetime_UTC.timeZone());
490     QCOMPARE(datetime_UTCCopy.date(), datetime_UTC.date());
491     QCOMPARE(datetime_UTCCopy.time(), datetime_UTC.time());
492     QCOMPARE(datetime_UTCCopy.qDateTime(), datetime_UTC.qDateTime());
493 
494     // Offset from UTC
495     KADateTime date_OffsetFromUTC(d, KADateTime::Spec::OffsetFromUTC(-2 * 3600));
496     QVERIFY(!date_OffsetFromUTC.isNull());
497     QVERIFY(date_OffsetFromUTC.isValid());
498     QVERIFY(date_OffsetFromUTC.isDateOnly());
499     QCOMPARE(date_OffsetFromUTC.timeType(), KADateTime::OffsetFromUTC);
500     QVERIFY(!date_OffsetFromUTC.isUtc());
501     QVERIFY(date_OffsetFromUTC.isOffsetFromUtc());
502     QVERIFY(!date_OffsetFromUTC.isLocalZone());
503     QCOMPARE(date_OffsetFromUTC.utcOffset(), -2 * 3600);
504     QVERIFY(!date_OffsetFromUTC.timeZone().isValid());
505     QCOMPARE(date_OffsetFromUTC.date(), d);
506     QCOMPARE(date_OffsetFromUTC.time(), QTime(0, 0, 0));
507     QCOMPARE(date_OffsetFromUTC.qDateTime(), QDateTime(d, QTime(0, 0, 0), Qt::OffsetFromUTC, -2 * 3600));
508 
509     KADateTime dateTime_OffsetFromUTC(d, t, KADateTime::Spec::OffsetFromUTC(2 * 3600));
510     QVERIFY(!dateTime_OffsetFromUTC.isNull());
511     QVERIFY(dateTime_OffsetFromUTC.isValid());
512     QVERIFY(!dateTime_OffsetFromUTC.isDateOnly());
513     QCOMPARE(dateTime_OffsetFromUTC.timeType(), KADateTime::OffsetFromUTC);
514     QVERIFY(!dateTime_OffsetFromUTC.isUtc());
515     QVERIFY(dateTime_OffsetFromUTC.isOffsetFromUtc());
516     QVERIFY(!dateTime_OffsetFromUTC.isLocalZone());
517     QCOMPARE(dateTime_OffsetFromUTC.utcOffset(), 2 * 3600);
518     QVERIFY(!dateTime_OffsetFromUTC.timeZone().isValid());
519     QCOMPARE(dateTime_OffsetFromUTC.date(), d);
520     QCOMPARE(dateTime_OffsetFromUTC.time(), t);
521     QCOMPARE(dateTime_OffsetFromUTC.qDateTime(), QDateTime(d, t, Qt::OffsetFromUTC, 2 * 3600));
522 
523     KADateTime datetime_OffsetFromUTC(dtLocal, KADateTime::Spec::OffsetFromUTC(-2 * 3600));
524     QVERIFY(!datetime_OffsetFromUTC.isNull());
525     QVERIFY(datetime_OffsetFromUTC.isValid());
526     QVERIFY(!datetime_OffsetFromUTC.isDateOnly());
527     QCOMPARE(datetime_OffsetFromUTC.timeType(), KADateTime::OffsetFromUTC);
528     QVERIFY(!datetime_OffsetFromUTC.isUtc());
529     QVERIFY(datetime_OffsetFromUTC.isOffsetFromUtc());
530     QVERIFY(!datetime_OffsetFromUTC.isLocalZone());
531     QCOMPARE(datetime_OffsetFromUTC.utcOffset(), -2 * 3600);
532     QVERIFY(!datetime_OffsetFromUTC.timeZone().isValid());
533     QCOMPARE(datetime_OffsetFromUTC.date(), dtLocal.date());
534     QCOMPARE(datetime_OffsetFromUTC.time(), dtLocal.time().addSecs(6 * 3600));
535     QCOMPARE(datetime_OffsetFromUTC.qDateTime(), dtLocal.toOffsetFromUtc(-2 * 3600));
536 
537     KADateTime datetime_OffsetFromUTC2(dtUTC, KADateTime::Spec::OffsetFromUTC(2 * 3600));
538     QVERIFY(!datetime_OffsetFromUTC2.isNull());
539     QVERIFY(datetime_OffsetFromUTC2.isValid());
540     QVERIFY(!datetime_OffsetFromUTC2.isDateOnly());
541     QCOMPARE(datetime_OffsetFromUTC2.timeType(), KADateTime::OffsetFromUTC);
542     QVERIFY(!datetime_OffsetFromUTC2.isUtc());
543     QVERIFY(datetime_OffsetFromUTC2.isOffsetFromUtc());
544     QVERIFY(!datetime_OffsetFromUTC2.isLocalZone());
545     QCOMPARE(datetime_OffsetFromUTC2.utcOffset(), 2 * 3600);
546     QVERIFY(!datetime_OffsetFromUTC2.timeZone().isValid());
547     {
548         QDateTime dtof = dtUTC.addSecs(2 * 3600);
549         dtof.setTimeSpec(Qt::LocalTime);
550         QCOMPARE(datetime_OffsetFromUTC2.date(), dtof.date());
551         QCOMPARE(datetime_OffsetFromUTC2.time(), dtof.time());
552     }
553     QCOMPARE(datetime_OffsetFromUTC2.qDateTime(), dtUTC.toOffsetFromUtc(2 * 3600));
554 
555     // ... copy constructor
556     KADateTime datetime_OffsetFromUTCCopy(datetime_OffsetFromUTC);
557     QVERIFY(!datetime_OffsetFromUTCCopy.isNull());
558     QVERIFY(datetime_OffsetFromUTCCopy.isValid());
559     QVERIFY(!datetime_OffsetFromUTCCopy.isDateOnly());
560     QCOMPARE(datetime_OffsetFromUTCCopy.timeType(), KADateTime::OffsetFromUTC);
561     QVERIFY(!datetime_OffsetFromUTCCopy.isUtc());
562     QVERIFY(datetime_OffsetFromUTCCopy.isOffsetFromUtc());
563     QVERIFY(!datetime_OffsetFromUTCCopy.isLocalZone());
564     QCOMPARE(datetime_OffsetFromUTCCopy.utcOffset(), -2 * 3600);
565     QVERIFY(!datetime_OffsetFromUTCCopy.timeZone().isValid());
566     QCOMPARE(datetime_OffsetFromUTCCopy.date(), datetime_OffsetFromUTC.date());
567     QCOMPARE(datetime_OffsetFromUTCCopy.time(), datetime_OffsetFromUTC.time());
568     QCOMPARE(datetime_OffsetFromUTCCopy.qDateTime(), datetime_OffsetFromUTC.qDateTime());
569 
570     // Local time zone
571     KADateTime date_LocalZone(d, KADateTime::Spec::LocalZone());
572     QVERIFY(!date_LocalZone.isNull());
573     QVERIFY(date_LocalZone.isValid());
574     QVERIFY(date_LocalZone.isDateOnly());
575     QCOMPARE(date_LocalZone.timeType(), KADateTime::LocalZone);
576     QCOMPARE(date_LocalZone.timeSpec(), KADateTime::Spec::LocalZone());
577     QVERIFY(!date_LocalZone.isUtc());
578     QVERIFY(!date_LocalZone.isOffsetFromUtc());
579     QVERIFY(date_LocalZone.isLocalZone());
580     QCOMPARE(date_LocalZone.utcOffset(), -8 * 3600);
581     QCOMPARE(date_LocalZone.timeZone(), QTimeZone::systemTimeZone());
582     QCOMPARE(date_LocalZone.date(), d);
583     QCOMPARE(date_LocalZone.time(), QTime(0, 0, 0));
584     QCOMPARE(date_LocalZone.qDateTime(), QDateTime(d, QTime(0, 0, 0), Qt::LocalTime));
585 
586     KADateTime dateTime_LocalZone(d, t, KADateTime::LocalZone);
587     QVERIFY(!dateTime_LocalZone.isNull());
588     QVERIFY(dateTime_LocalZone.isValid());
589     QVERIFY(!dateTime_LocalZone.isDateOnly());
590     QCOMPARE(dateTime_LocalZone.timeType(), KADateTime::LocalZone);
591     QCOMPARE(dateTime_LocalZone.timeSpec(), KADateTime::Spec::LocalZone());
592     QVERIFY(!dateTime_LocalZone.isUtc());
593     QVERIFY(!dateTime_LocalZone.isOffsetFromUtc());
594     QVERIFY(dateTime_LocalZone.isLocalZone());
595     QCOMPARE(dateTime_LocalZone.utcOffset(), -8 * 3600);
596     QCOMPARE(dateTime_LocalZone.timeZone(), QTimeZone::systemTimeZone());
597     QCOMPARE(dateTime_LocalZone.date(), d);
598     QCOMPARE(dateTime_LocalZone.time(), t);
599     QCOMPARE(dateTime_LocalZone.qDateTime(), QDateTime(d, t, Qt::LocalTime));
600 
601     KADateTime datetime_LocalZone(dtLocal, KADateTime::LocalZone);
602     QVERIFY(!datetime_LocalZone.isNull());
603     QVERIFY(datetime_LocalZone.isValid());
604     QVERIFY(!datetime_LocalZone.isDateOnly());
605     QCOMPARE(datetime_LocalZone.timeType(), KADateTime::LocalZone);
606     QCOMPARE(datetime_LocalZone.timeSpec(), KADateTime::Spec::LocalZone());
607     QVERIFY(!datetime_LocalZone.isUtc());
608     QVERIFY(!datetime_LocalZone.isOffsetFromUtc());
609     QVERIFY(datetime_LocalZone.isLocalZone());
610     QCOMPARE(datetime_LocalZone.utcOffset(), -8 * 3600);
611     QCOMPARE(datetime_LocalZone.timeZone(), QTimeZone::systemTimeZone());
612     QCOMPARE(datetime_LocalZone.date(), dtLocal.date());
613     QCOMPARE(datetime_LocalZone.time(), dtLocal.time());
614     QCOMPARE(datetime_LocalZone.qDateTime(), dtLocal);
615 
616     KADateTime datetime_LocalZone2(dtUTC, KADateTime::LocalZone);
617     QVERIFY(!datetime_LocalZone2.isNull());
618     QVERIFY(datetime_LocalZone2.isValid());
619     QVERIFY(!datetime_LocalZone2.isDateOnly());
620     QCOMPARE(datetime_LocalZone2.timeType(), KADateTime::LocalZone);
621     QCOMPARE(datetime_LocalZone2.timeSpec(), KADateTime::Spec::LocalZone());
622     QVERIFY(!datetime_LocalZone2.isUtc());
623     QVERIFY(!datetime_LocalZone2.isOffsetFromUtc());
624     QVERIFY(datetime_LocalZone2.isLocalZone());
625     QCOMPARE(datetime_LocalZone2.utcOffset(), -8 * 3600);
626     QCOMPARE(datetime_LocalZone2.timeZone(), QTimeZone::systemTimeZone());
627     {
628         QDateTime local = dtUTC.toLocalTime();
629         QCOMPARE(datetime_LocalZone2.date(), local.date());
630         QCOMPARE(datetime_LocalZone2.time(), local.time());
631     }
632     QCOMPARE(datetime_LocalZone2.qDateTime(), dtUTC.toLocalTime());
633 
634     // ... copy constructor
635     KADateTime datetime_LocalZoneCopy(datetime_LocalZone);
636     QVERIFY(!datetime_LocalZoneCopy.isNull());
637     QVERIFY(datetime_LocalZoneCopy.isValid());
638     QVERIFY(!datetime_LocalZoneCopy.isDateOnly());
639     QCOMPARE(datetime_LocalZoneCopy.timeType(), KADateTime::LocalZone);
640     QCOMPARE(datetime_LocalZoneCopy.timeSpec(), KADateTime::Spec::LocalZone());
641     QVERIFY(!datetime_LocalZoneCopy.isUtc());
642     QVERIFY(!datetime_LocalZoneCopy.isOffsetFromUtc());
643     QVERIFY(datetime_LocalZoneCopy.isLocalZone());
644     QCOMPARE(datetime_LocalZoneCopy.utcOffset(), -8 * 3600);
645     QCOMPARE(datetime_LocalZoneCopy.timeZone(), datetime_LocalZone.timeZone());
646     QCOMPARE(datetime_LocalZoneCopy.date(), datetime_LocalZone.date());
647     QCOMPARE(datetime_LocalZoneCopy.time(), datetime_LocalZone.time());
648     QCOMPARE(datetime_LocalZoneCopy.qDateTime(), datetime_LocalZone.qDateTime());
649 
650     // Invalid time zone specification for a constructor
651     KADateTime date_TimeZone(d, KADateTime::Spec(KADateTime::TimeZone));
652     QVERIFY(!date_TimeZone.isValid());
653     KADateTime dateTime_TimeZone(d, t, KADateTime::Spec(KADateTime::TimeZone));
654     QVERIFY(!dateTime_TimeZone.isValid());
655     KADateTime datetime_TimeZone(dtLocal, KADateTime::Spec(KADateTime::TimeZone));
656     QVERIFY(!datetime_TimeZone.isValid());
657     KADateTime datetime_Invalid(dtLocal, KADateTime::Spec(KADateTime::Invalid));
658     QVERIFY(!datetime_Invalid.isValid());
659 
660     // Restore the original local time zone
661     if (originalZone.isEmpty()) {
662         unsetenv("TZ");
663     } else {
664         qputenv("TZ", originalZone);
665     }
666     ::tzset();
667 }
668 
669 ///////////////////////////////////
670 // Time conversion and operator==()
671 ///////////////////////////////////
672 
toUtc()673 void KADateTimeTest::toUtc()
674 {
675     QTimeZone london("Europe/London");
676 
677     // Ensure that local time is different from UTC and different from 'london'
678     QByteArray originalZone = qgetenv("TZ");   // save the original local time zone
679     qputenv("TZ", ":America/Los_Angeles");
680     ::tzset();
681 
682     // Zone -> UTC
683     KADateTime londonWinter(QDate(2005, 1, 1), QTime(0, 0, 0), london);
684     KADateTime utcWinter = londonWinter.toUtc();
685     QVERIFY(utcWinter.isUtc());
686     QCOMPARE(utcWinter.date(), QDate(2005, 1, 1));
687     QCOMPARE(utcWinter.time(), QTime(0, 0, 0));
688     QVERIFY(londonWinter == utcWinter);
689     KADateTime londonSummer(QDate(2005, 6, 1), QTime(0, 0, 0), london);
690     KADateTime utcSummer = londonSummer.toUtc();
691     QVERIFY(utcSummer.isUtc());
692     QCOMPARE(utcSummer.date(), QDate(2005, 5, 31));
693     QCOMPARE(utcSummer.time(), QTime(23, 0, 0));
694     QVERIFY(londonSummer == utcSummer);
695     QVERIFY(!(londonSummer == utcWinter));
696     QVERIFY(!(londonWinter == utcSummer));
697 
698     // UTC offset -> UTC
699     KADateTime offset(QDate(2005, 6, 6), QTime(1, 2, 30), KADateTime::Spec::OffsetFromUTC(-5400)); // -0130
700     KADateTime utcOffset = offset.toUtc();
701     QVERIFY(utcOffset.isUtc());
702     QCOMPARE(utcOffset.date(), QDate(2005, 6, 6));
703     QCOMPARE(utcOffset.time(), QTime(2, 32, 30));
704     QVERIFY(offset == utcOffset);
705     QVERIFY(!(offset == utcSummer));
706 
707     // Local time -> UTC
708     KADateTime localz(QDate(2005, 6, 6), QTime(1, 2, 30), KADateTime::LocalZone);
709     KADateTime utcLocalz = localz.toUtc();
710     QVERIFY(utcLocalz.isUtc());
711     QCOMPARE(utcLocalz.date(), QDate(2005, 6, 6));
712     QCOMPARE(utcLocalz.time(), QTime(8, 2, 30));
713     QVERIFY(localz == utcLocalz);
714     QVERIFY(!(localz == utcOffset));
715 
716     // UTC -> UTC
717     KADateTime utc(QDate(2005, 6, 6), QTime(1, 2, 30), KADateTime::UTC);
718     KADateTime utcUtc = utc.toUtc();
719     QVERIFY(utcUtc.isUtc());
720     QCOMPARE(utcUtc.date(), QDate(2005, 6, 6));
721     QCOMPARE(utcUtc.time(), QTime(1, 2, 30));
722     QVERIFY(utc == utcUtc);
723     QVERIFY(!(utc == utcLocalz));
724 
725     // ** Date only ** //
726 
727     // Zone -> UTC
728     londonSummer.setDateOnly(true);
729     utcSummer = londonSummer.toUtc();
730     QVERIFY(utcSummer.isDateOnly());
731     QCOMPARE(utcSummer.date(), QDate(2005, 6, 1));
732     QCOMPARE(utcSummer.time(), QTime(0, 0, 0));
733     QVERIFY(utcSummer != londonSummer);
734     QVERIFY(!(utcSummer == londonSummer));
735     londonWinter.setDateOnly(true);
736     utcWinter = londonWinter.toUtc();
737     QVERIFY(utcWinter == londonWinter);
738     QVERIFY(!(utcWinter != londonWinter));
739 
740     // UTC offset -> UTC
741     offset.setDateOnly(true);
742     utcOffset = offset.toUtc();
743     QVERIFY(utcOffset.isDateOnly());
744     QCOMPARE(utcOffset.date(), QDate(2005, 6, 6));
745     QCOMPARE(utcOffset.time(), QTime(0, 0, 0));
746     QVERIFY(offset != utcOffset);
747     QVERIFY(!(offset == utcOffset));
748     KADateTime utcOffset1(QDate(2005, 6, 6), KADateTime::Spec::OffsetFromUTC(0));
749     QVERIFY(utcOffset1 == utcOffset1.toUtc());
750 
751     // Local time -> UTC
752     localz.setDateOnly(true);
753     utcLocalz = localz.toUtc();
754     QVERIFY(utcLocalz.isDateOnly());
755     QCOMPARE(utcLocalz.date(), QDate(2005, 6, 6));
756     QCOMPARE(utcLocalz.time(), QTime(0, 0, 0));
757     QVERIFY(localz != utcLocalz);
758     QVERIFY(!(localz == utcLocalz));
759 
760     // UTC -> UTC
761     utc.setDateOnly(true);
762     utcUtc = utc.toUtc();
763     QVERIFY(utcUtc.isDateOnly());
764     QCOMPARE(utcUtc.date(), QDate(2005, 6, 6));
765     QCOMPARE(utcUtc.time(), QTime(0, 0, 0));
766     QVERIFY(utc == utcUtc);
767     QVERIFY(!(utc != utcUtc));
768 
769     // Restore the original local time zone
770     if (originalZone.isEmpty()) {
771         unsetenv("TZ");
772     } else {
773         qputenv("TZ", originalZone);
774     }
775     ::tzset();
776 }
777 
toOffsetFromUtc()778 void KADateTimeTest::toOffsetFromUtc()
779 {
780     QTimeZone london("Europe/London");
781 
782     // Ensure that local time is different from UTC and different from 'london'
783     QByteArray originalZone = qgetenv("TZ");   // save the original local time zone
784     qputenv("TZ", ":America/Los_Angeles");
785     ::tzset();
786 
787     // ***** toOffsetFromUtc(void) *****
788 
789     // Zone -> UTC offset
790     KADateTime londonWinter(QDate(2005, 1, 1), QTime(2, 0, 0), london);
791     KADateTime offsetWinter = londonWinter.toOffsetFromUtc();
792     QVERIFY(offsetWinter.isOffsetFromUtc());
793     QCOMPARE(offsetWinter.utcOffset(), 0);
794     QCOMPARE(offsetWinter.date(), QDate(2005, 1, 1));
795     QCOMPARE(offsetWinter.time(), QTime(2, 0, 0));
796     QVERIFY(londonWinter == offsetWinter);
797     KADateTime londonSummer(QDate(2005, 6, 1), QTime(14, 0, 0), london);
798     KADateTime offsetSummer = londonSummer.toOffsetFromUtc();
799     QVERIFY(offsetSummer.isOffsetFromUtc());
800     QCOMPARE(offsetSummer.utcOffset(), 3600);
801     QCOMPARE(offsetSummer.date(), QDate(2005, 6, 1));
802     QCOMPARE(offsetSummer.time(), QTime(14, 0, 0));
803     QVERIFY(londonSummer == offsetSummer);
804     QVERIFY(!(londonSummer == offsetWinter));
805     QVERIFY(!(londonWinter == offsetSummer));
806 
807     // UTC offset -> UTC offset
808     KADateTime offset(QDate(2005, 6, 6), QTime(11, 2, 30), KADateTime::Spec::OffsetFromUTC(-5400)); // -0130
809     KADateTime offsetOffset = offset.toOffsetFromUtc();
810     QVERIFY(offsetOffset.isOffsetFromUtc());
811     QCOMPARE(offsetOffset.utcOffset(), -5400);
812     QCOMPARE(offsetOffset.date(), QDate(2005, 6, 6));
813     QCOMPARE(offsetOffset.time(), QTime(11, 2, 30));
814     QVERIFY(offset == offsetOffset);
815     QVERIFY(!(offset == offsetSummer));
816 
817     // Local time -> UTC offset
818     KADateTime localz(QDate(2005, 6, 6), QTime(1, 2, 30), KADateTime::LocalZone);
819     KADateTime offsetLocalz = localz.toOffsetFromUtc();
820     QVERIFY(offsetLocalz.isOffsetFromUtc());
821     QCOMPARE(offsetLocalz.utcOffset(), -7 * 3600);
822     QCOMPARE(offsetLocalz.date(), QDate(2005, 6, 6));
823     QCOMPARE(offsetLocalz.time(), QTime(1, 2, 30));
824     QVERIFY(localz == offsetLocalz);
825     QVERIFY(!(localz == offsetOffset));
826 
827     // UTC -> UTC offset
828     KADateTime utc(QDate(2005, 6, 6), QTime(11, 2, 30), KADateTime::UTC);
829     KADateTime offsetUtc = utc.toOffsetFromUtc();
830     QVERIFY(offsetUtc.isOffsetFromUtc());
831     QCOMPARE(offsetUtc.utcOffset(), 0);
832     QCOMPARE(offsetUtc.date(), QDate(2005, 6, 6));
833     QCOMPARE(offsetUtc.time(), QTime(11, 2, 30));
834     QVERIFY(utc == offsetUtc);
835     QVERIFY(!(utc == offsetLocalz));
836 
837     // ** Date only ** //
838 
839     // Zone -> UTC offset
840     londonSummer.setDateOnly(true);
841     offsetSummer = londonSummer.toOffsetFromUtc();
842     QVERIFY(offsetSummer.isDateOnly());
843     QVERIFY(offsetSummer.isOffsetFromUtc());
844     QCOMPARE(offsetSummer.utcOffset(), 3600);
845     QCOMPARE(offsetSummer.date(), QDate(2005, 6, 1));
846     QCOMPARE(offsetSummer.time(), QTime(0, 0, 0));
847     QVERIFY(offsetSummer == londonSummer);
848     QVERIFY(!(offsetSummer != londonSummer));
849     londonWinter.setDateOnly(true);
850     offsetWinter = londonWinter.toUtc();
851     QVERIFY(offsetWinter == londonWinter);
852     QVERIFY(!(offsetWinter != londonWinter));
853 
854     // UTC offset -> UTC offset
855     offset.setDateOnly(true);
856     offsetOffset = offset.toOffsetFromUtc();
857     QVERIFY(offsetOffset.isDateOnly());
858     QVERIFY(offsetOffset.isOffsetFromUtc());
859     QCOMPARE(offsetOffset.utcOffset(), -5400);
860     QCOMPARE(offsetOffset.date(), QDate(2005, 6, 6));
861     QCOMPARE(offsetOffset.time(), QTime(0, 0, 0));
862     QVERIFY(offset == offsetOffset);
863     QVERIFY(!(offset != offsetOffset));
864 
865     // Local time -> UTC offset
866     localz.setDateOnly(true);
867     offsetLocalz = localz.toOffsetFromUtc();
868     QVERIFY(offsetLocalz.isDateOnly());
869     QVERIFY(offsetLocalz.isOffsetFromUtc());
870     QCOMPARE(offsetLocalz.utcOffset(), -7 * 3600);
871     QCOMPARE(offsetLocalz.date(), QDate(2005, 6, 6));
872     QCOMPARE(offsetLocalz.time(), QTime(0, 0, 0));
873     QVERIFY(localz == offsetLocalz);
874     QVERIFY(!(localz != offsetLocalz));
875 
876     // UTC -> UTC offset
877     utc.setDateOnly(true);
878     offsetUtc = utc.toOffsetFromUtc();
879     QVERIFY(offsetUtc.isDateOnly());
880     QVERIFY(offsetUtc.isOffsetFromUtc());
881     QCOMPARE(offsetUtc.utcOffset(), 0);
882     QCOMPARE(offsetUtc.date(), QDate(2005, 6, 6));
883     QCOMPARE(offsetUtc.time(), QTime(0, 0, 0));
884     QVERIFY(utc == offsetUtc);
885     QVERIFY(!(utc != offsetUtc));
886 
887     // ***** toOffsetFromUtc(int utcOffset) *****
888 
889     // Zone -> UTC offset
890     KADateTime londonWinter2(QDate(2005, 1, 1), QTime(2, 0, 0), london);
891     offsetWinter = londonWinter2.toOffsetFromUtc(5400);    // +1H30M
892     QVERIFY(offsetWinter.isOffsetFromUtc());
893     QCOMPARE(offsetWinter.utcOffset(), 5400);
894     QCOMPARE(offsetWinter.date(), QDate(2005, 1, 1));
895     QCOMPARE(offsetWinter.time(), QTime(3, 30, 0));
896     QVERIFY(londonWinter2 == offsetWinter);
897     KADateTime londonSummer2(QDate(2005, 6, 1), QTime(14, 0, 0), london);
898     offsetSummer = londonSummer2.toOffsetFromUtc(5400);
899     QVERIFY(offsetSummer.isOffsetFromUtc());
900     QCOMPARE(offsetSummer.utcOffset(), 5400);
901     QCOMPARE(offsetSummer.date(), QDate(2005, 6, 1));
902     QCOMPARE(offsetSummer.time(), QTime(14, 30, 0));
903     QVERIFY(londonSummer2 == offsetSummer);
904     QVERIFY(!(londonSummer2 == offsetWinter));
905     QVERIFY(!(londonWinter2 == offsetSummer));
906 
907     // UTC offset -> UTC offset
908     KADateTime offset2(QDate(2005, 6, 6), QTime(11, 2, 30), KADateTime::Spec::OffsetFromUTC(-5400)); // -0130
909     offsetOffset = offset2.toOffsetFromUtc(3600);
910     QVERIFY(offsetOffset.isOffsetFromUtc());
911     QCOMPARE(offsetOffset.utcOffset(), 3600);
912     QCOMPARE(offsetOffset.date(), QDate(2005, 6, 6));
913     QCOMPARE(offsetOffset.time(), QTime(13, 32, 30));
914     QVERIFY(offset2 == offsetOffset);
915     QVERIFY(!(offset2 == offsetSummer));
916 
917     // Local time -> UTC offset
918     KADateTime localz2(QDate(2005, 6, 6), QTime(1, 2, 30), KADateTime::LocalZone);
919     offsetLocalz = localz2.toOffsetFromUtc(0);
920     QVERIFY(offsetLocalz.isOffsetFromUtc());
921     QCOMPARE(offsetLocalz.utcOffset(), 0);
922     QCOMPARE(offsetLocalz.date(), QDate(2005, 6, 6));
923     QCOMPARE(offsetLocalz.time(), QTime(8, 2, 30));
924     QVERIFY(localz2 == offsetLocalz);
925     QVERIFY(!(localz2 == offsetOffset));
926 
927     // UTC -> UTC offset
928     KADateTime utc2(QDate(2005, 6, 6), QTime(11, 2, 30), KADateTime::UTC);
929     offsetUtc = utc2.toOffsetFromUtc(-3600);
930     QVERIFY(offsetUtc.isOffsetFromUtc());
931     QCOMPARE(offsetUtc.utcOffset(), -3600);
932     QCOMPARE(offsetUtc.date(), QDate(2005, 6, 6));
933     QCOMPARE(offsetUtc.time(), QTime(10, 2, 30));
934     QVERIFY(utc2 == offsetUtc);
935     QVERIFY(!(utc2 == offsetLocalz));
936 
937     // ** Date only ** //
938 
939     // Zone -> UTC offset
940     londonSummer2.setDateOnly(true);
941     offsetSummer = londonSummer2.toOffsetFromUtc(5400);
942     QVERIFY(offsetSummer.isDateOnly());
943     QVERIFY(offsetSummer.isOffsetFromUtc());
944     QCOMPARE(offsetSummer.utcOffset(), 5400);
945     QCOMPARE(offsetSummer.date(), QDate(2005, 6, 1));
946     QCOMPARE(offsetSummer.time(), QTime(0, 0, 0));
947     QVERIFY(londonSummer2 != offsetSummer);
948     QVERIFY(!(londonSummer2 == offsetSummer));
949     QVERIFY(londonSummer2 == KADateTime(QDate(2005, 6, 1), KADateTime::Spec::OffsetFromUTC(3600)));
950 
951     // UTC offset -> UTC offset
952     offset2.setDateOnly(true);
953     offsetOffset = offset2.toOffsetFromUtc(-3600);
954     QVERIFY(offsetOffset.isDateOnly());
955     QVERIFY(offsetOffset.isOffsetFromUtc());
956     QCOMPARE(offsetOffset.utcOffset(), -3600);
957     QCOMPARE(offsetOffset.date(), QDate(2005, 6, 6));
958     QCOMPARE(offsetOffset.time(), QTime(0, 0, 0));
959     QVERIFY(offset2 != offsetOffset);
960     QVERIFY(!(offset2 == offsetOffset));
961 
962     // Local time -> UTC offset
963     localz2.setDateOnly(true);
964     offsetLocalz = localz2.toOffsetFromUtc(6 * 3600);
965     QVERIFY(offsetLocalz.isDateOnly());
966     QVERIFY(offsetLocalz.isOffsetFromUtc());
967     QCOMPARE(offsetLocalz.utcOffset(), 6 * 3600);
968     QCOMPARE(offsetLocalz.date(), QDate(2005, 6, 6));
969     QCOMPARE(offsetLocalz.time(), QTime(0, 0, 0));
970     QVERIFY(localz2 != offsetLocalz);
971     QVERIFY(!(localz2 == offsetLocalz));
972     QVERIFY(localz == KADateTime(QDate(2005, 6, 6), KADateTime::Spec::OffsetFromUTC(-7 * 3600)));
973 
974     // UTC -> UTC offset
975     utc2.setDateOnly(true);
976     offsetUtc = utc2.toOffsetFromUtc(1800);
977     QVERIFY(offsetUtc.isDateOnly());
978     QVERIFY(offsetUtc.isOffsetFromUtc());
979     QCOMPARE(offsetUtc.utcOffset(), 1800);
980     QCOMPARE(offsetUtc.date(), QDate(2005, 6, 6));
981     QCOMPARE(offsetUtc.time(), QTime(0, 0, 0));
982     QVERIFY(utc2 != offsetUtc);
983     QVERIFY(!(utc2 == offsetUtc));
984     QVERIFY(utc2 == KADateTime(QDate(2005, 6, 6), KADateTime::Spec::OffsetFromUTC(0)));
985 
986     // Restore the original local time zone
987     if (originalZone.isEmpty()) {
988         unsetenv("TZ");
989     } else {
990         qputenv("TZ", originalZone);
991     }
992     ::tzset();
993 }
994 
toLocalZone()995 void KADateTimeTest::toLocalZone()
996 {
997     QTimeZone london("Europe/London");
998 
999     // 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 
toZone()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 
toTimeSpec()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 
set()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 
equal()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 
lessThan()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 
compare()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 
addSubtract()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 
addMSecs()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 
addSubtractDate()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 
dstShifts()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     QCOMPARE(dt.date(), QDate(2005, 10, 30));
2576     QCOMPARE(dt.time(), QTime(0, 59, 59));
2577     dt = KADateTime(QDateTime(QDate(2005, 10, 30), QTime(0, 0, 0), Qt::UTC), london);
2578     QVERIFY(!dt.isSecondOccurrence());
2579     QCOMPARE(dt.date(), QDate(2005, 10, 30));
2580     QCOMPARE(dt.time(), QTime(1, 0, 0));
2581     dt = KADateTime(QDateTime(QDate(2005, 10, 30), QTime(0, 59, 59), Qt::UTC), london);
2582     QVERIFY(!dt.isSecondOccurrence());
2583     QCOMPARE(dt.date(), QDate(2005, 10, 30));
2584     QCOMPARE(dt.time(), QTime(1, 59, 59));
2585     dt = KADateTime(QDateTime(QDate(2005, 10, 30), QTime(1, 0, 0), Qt::UTC), london);
2586     QVERIFY(dt.isSecondOccurrence());
2587     QCOMPARE(dt.date(), QDate(2005, 10, 30));
2588     QCOMPARE(dt.time(), QTime(1, 0, 0));
2589     dt = KADateTime(QDateTime(QDate(2005, 10, 30), QTime(1, 59, 59), Qt::UTC), london);
2590     QVERIFY(dt.isSecondOccurrence());
2591     QCOMPARE(dt.date(), QDate(2005, 10, 30));
2592     QCOMPARE(dt.time(), QTime(1, 59, 59));
2593     dt = KADateTime(QDateTime(QDate(2005, 10, 30), QTime(2, 0, 0), Qt::UTC), london);
2594     QVERIFY(!dt.isSecondOccurrence());
2595     QCOMPARE(dt.date(), QDate(2005, 10, 30));
2596     QCOMPARE(dt.time(), QTime(2, 0, 0));
2597 
2598     dt = KADateTime(QDate(2005, 10, 30), QTime(0, 59, 59), london);
2599     dt.setSecondOccurrence(true);   // this has no effect
2600     QCOMPARE(dt.toUtc().date(), QDate(2005, 10, 29));
2601     QCOMPARE(dt.toUtc().time(), QTime(23, 59, 59));
2602     dt = KADateTime(QDate(2005, 10, 30), QTime(1, 0, 0), london);
2603     QVERIFY(!dt.isSecondOccurrence());
2604     QCOMPARE(dt.toUtc().date(), QDate(2005, 10, 30));
2605     QCOMPARE(dt.toUtc().time(), QTime(0, 0, 0));
2606     dt = KADateTime(QDate(2005, 10, 30), QTime(1, 59, 59), london);
2607     QVERIFY(!dt.isSecondOccurrence());
2608     QCOMPARE(dt.toUtc().date(), QDate(2005, 10, 30));
2609     QCOMPARE(dt.toUtc().time(), QTime(0, 59, 59));
2610     dt = KADateTime(QDate(2005, 10, 30), QTime(1, 0, 0), london);
2611     dt.setSecondOccurrence(true);
2612     QCOMPARE(dt.toUtc().date(), QDate(2005, 10, 30));
2613     QCOMPARE(dt.toUtc().time(), QTime(1, 0, 0));
2614     QVERIFY(dt.isSecondOccurrence());
2615     dt = KADateTime(QDate(2005, 10, 30), QTime(1, 59, 59), london);
2616     dt.setSecondOccurrence(true);
2617     QCOMPARE(dt.toUtc().date(), QDate(2005, 10, 30));
2618     QCOMPARE(dt.toUtc().time(), QTime(1, 59, 59));
2619     QVERIFY(dt.isSecondOccurrence());
2620     dt = KADateTime(QDate(2005, 10, 30), QTime(2, 0, 0), london);
2621     dt.setSecondOccurrence(true);   // this has no effect
2622     QVERIFY(!dt.isSecondOccurrence());
2623     QCOMPARE(dt.toUtc().date(), QDate(2005, 10, 30));
2624     QCOMPARE(dt.toUtc().time(), QTime(2, 0, 0));
2625 
2626     dt = KADateTime(QDate(2005, 10, 30), QTime(0, 59, 59), london);
2627     KADateTime dt1 = dt.addSecs(1);   // local time 01:00:00
2628     QVERIFY(!dt1.isSecondOccurrence());
2629     dt1 = dt.addSecs(3600);   // local time 01:59:59
2630     QVERIFY(!dt1.isSecondOccurrence());
2631     dt1 = dt.addSecs(3601);   // local time 01:00:00
2632     QVERIFY(dt1.isSecondOccurrence());
2633     dt1 = dt.addSecs(7200);   // local time 01:59:59
2634     QVERIFY(dt1.isSecondOccurrence());
2635     dt1 = dt.addSecs(7201);   // local time 02:00:00
2636     QVERIFY(!dt1.isSecondOccurrence());
2637 
2638     QVERIFY(KADateTime(QDate(2005, 10, 29), london) == KADateTime(QDate(2005, 10, 29), KADateTime::Spec::OffsetFromUTC(3600)));
2639     QVERIFY(KADateTime(QDate(2005, 10, 30), london) != KADateTime(QDate(2005, 10, 30), KADateTime::Spec::OffsetFromUTC(3600)));
2640     QVERIFY(KADateTime(QDate(2005, 10, 30), london) != KADateTime(QDate(2005, 10, 30), KADateTime::Spec::OffsetFromUTC(0)));
2641     QVERIFY(KADateTime(QDate(2005, 10, 31), london) == KADateTime(QDate(2005, 10, 31), KADateTime::Spec::OffsetFromUTC(0)));
2642 
2643     // Restore the original local time zone
2644     if (originalZone.isEmpty()) {
2645         unsetenv("TZ");
2646     } else {
2647         qputenv("TZ", originalZone);
2648     }
2649     ::tzset();
2650 }
2651 
2652 ////////////////////
2653 // String conversion
2654 ////////////////////
2655 
strings_iso8601()2656 void KADateTimeTest::strings_iso8601()
2657 {
2658     QTimeZone london("Europe/London");
2659     bool decpt = QLocale().decimalPoint() == QLatin1Char('.');   // whether this locale uses '.' as decimal symbol
2660 
2661     // Ensure that local time is different from UTC and different from 'london'
2662     QByteArray originalZone = qgetenv("TZ");   // save the original local time zone
2663     qputenv("TZ", ":America/Los_Angeles");
2664     ::tzset();
2665 
2666     KADateTime dtlocal(QDate(1999, 12, 11), QTime(3, 45, 6, 12), KADateTime::LocalZone);
2667     QString s = dtlocal.toString(KADateTime::ISODate);
2668     if (decpt) {
2669         QCOMPARE(s, QStringLiteral("1999-12-11T03:45:06.012"));
2670     } else {
2671         QCOMPARE(s, QStringLiteral("1999-12-11T03:45:06,012"));
2672     }
2673     KADateTime dtlocal1 = KADateTime::fromString(s, KADateTime::ISODate);
2674     QCOMPARE(dtlocal1.qDateTime().toUTC(), dtlocal.qDateTime().toUTC());
2675     QCOMPARE(dtlocal1.timeType(), KADateTime::LocalZone);
2676     QCOMPARE(dtlocal1.utcOffset(), -8 * 3600);
2677     QVERIFY(dtlocal1 == dtlocal);
2678 
2679     s = dtlocal.toString(KADateTime::ISODateFull);
2680     if (decpt) {
2681         QCOMPARE(s, QStringLiteral("1999-12-11T03:45:06.012-08:00"));
2682     } else {
2683         QCOMPARE(s, QStringLiteral("1999-12-11T03:45:06,012-08:00"));
2684     }
2685     dtlocal1 = KADateTime::fromString(s, KADateTime::ISODate);
2686     QCOMPARE(dtlocal1.qDateTime().toUTC(), dtlocal.qDateTime().toUTC());
2687     QCOMPARE(dtlocal1.timeType(), KADateTime::OffsetFromUTC);
2688     QCOMPARE(dtlocal1.utcOffset(), -8 * 3600);
2689     QVERIFY(dtlocal1 == dtlocal);
2690 
2691     dtlocal.setDateOnly(true);
2692     s = dtlocal.toString(KADateTime::ISODate);
2693     QCOMPARE(s, QStringLiteral("1999-12-11"));
2694 
2695     KADateTime dtzone(QDate(1999, 6, 11), QTime(3, 45, 6, 12), london);
2696     s = dtzone.toString(KADateTime::ISODate);
2697     if (decpt) {
2698         QCOMPARE(s, QStringLiteral("1999-06-11T03:45:06.012+01:00"));
2699     } else {
2700         QCOMPARE(s, QStringLiteral("1999-06-11T03:45:06,012+01:00"));
2701     }
2702     KADateTime dtzone1 = KADateTime::fromString(s, KADateTime::ISODate);
2703     QCOMPARE(dtzone1.qDateTime().toUTC(), dtzone.qDateTime().toUTC());
2704     QCOMPARE(dtzone1.timeType(), KADateTime::OffsetFromUTC);
2705     QCOMPARE(dtzone1.utcOffset(), 3600);
2706     QVERIFY(dtzone1 == dtzone);
2707     dtzone.setDateOnly(true);
2708     s = dtzone.toString(KADateTime::ISODate);
2709     QCOMPARE(s, QStringLiteral("1999-06-11T00:00:00+01:00"));
2710 
2711     KADateTime dtutc(QDate(1999, 12, 11), QTime(3, 45, 0), KADateTime::UTC);
2712     s = dtutc.toString(KADateTime::ISODate);
2713     QCOMPARE(s, QStringLiteral("1999-12-11T03:45:00Z"));
2714     KADateTime dtutc1 = KADateTime::fromString(s, KADateTime::ISODate);
2715     QCOMPARE(dtutc1.date(), dtutc.date());
2716     QCOMPARE(dtutc1.time(), dtutc.time());
2717     QCOMPARE(dtutc1.timeType(), KADateTime::UTC);
2718     QVERIFY(dtutc1 == dtutc);
2719     dtutc.setDateOnly(true);
2720     s = dtutc.toString(KADateTime::ISODate);
2721     QCOMPARE(s, QStringLiteral("1999-12-11T00:00:00Z"));
2722 
2723     // Check signed years
2724     KADateTime dtneg(QDate(-1999, 12, 11), QTime(3, 45, 6), KADateTime::LocalZone);
2725     s = dtneg.toString(KADateTime::ISODate);
2726     QCOMPARE(s, QStringLiteral("-1999-12-11T03:45:06"));
2727     KADateTime dtneg1 = KADateTime::fromString(s, KADateTime::ISODate);
2728     QCOMPARE(dtneg1.date(), dtneg.date());
2729     QCOMPARE(dtneg1.time(), dtneg.time());
2730     QCOMPARE(dtneg1.timeType(), KADateTime::LocalZone);
2731     QVERIFY(dtneg1 == dtneg);
2732     KADateTime dtneg2 = KADateTime::fromString(QStringLiteral("-19991211T034506"), KADateTime::ISODate);
2733     QVERIFY(dtneg2 == dtneg);
2734 
2735     dtneg.setDateOnly(true);
2736     s = dtneg.toString(KADateTime::ISODate);
2737     QCOMPARE(s, QStringLiteral("-1999-12-11"));
2738     dtneg1 = KADateTime::fromString(s, KADateTime::ISODate);
2739     QVERIFY(dtneg1.isDateOnly());
2740     QCOMPARE(dtneg1.timeType(), KADateTime::LocalZone);
2741     QCOMPARE(dtneg1.date(), QDate(-1999, 12, 11));
2742     dtneg2 = KADateTime::fromString(QStringLiteral("-19991211"), KADateTime::ISODate);
2743     QVERIFY(dtneg2 == dtneg1);
2744 
2745     s = QStringLiteral("+1999-12-11T03:45:06");
2746     KADateTime dtpos = KADateTime::fromString(s, KADateTime::ISODate);
2747     QCOMPARE(dtpos.date(), QDate(1999, 12, 11));
2748     QCOMPARE(dtpos.time(), QTime(3, 45, 6));
2749     QCOMPARE(dtpos.timeType(), KADateTime::LocalZone);
2750     KADateTime dtpos2 = KADateTime::fromString(QStringLiteral("+19991211T034506"), KADateTime::ISODate);
2751     QVERIFY(dtpos2 == dtpos);
2752 
2753     dtpos.setDateOnly(true);
2754     s = QStringLiteral("+1999-12-11");
2755     dtpos = KADateTime::fromString(s, KADateTime::ISODate);
2756     QVERIFY(dtpos.isDateOnly());
2757     QCOMPARE(dtpos.timeType(), KADateTime::LocalZone);
2758     QCOMPARE(dtpos.date(), QDate(1999, 12, 11));
2759     dtpos2 = KADateTime::fromString(QStringLiteral("+19991211"), KADateTime::ISODate);
2760     QVERIFY(dtpos2 == dtpos);
2761 
2762     // Check years with >4 digits
2763     KADateTime dtbig(QDate(123456, 12, 11), QTime(3, 45, 06), KADateTime::LocalZone);
2764     s = dtbig.toString(KADateTime::ISODate);
2765     QCOMPARE(s, QStringLiteral("123456-12-11T03:45:06"));
2766     KADateTime dtbig1 = KADateTime::fromString(s, KADateTime::ISODate);
2767     QCOMPARE(dtbig1.date(), dtbig.date());
2768     QCOMPARE(dtbig1.time(), dtbig.time());
2769     QCOMPARE(dtbig1.timeType(), KADateTime::LocalZone);
2770     QVERIFY(dtbig1 == dtbig);
2771     KADateTime dtbig2 = KADateTime::fromString(QStringLiteral("1234561211T034506"), KADateTime::ISODate);
2772     QVERIFY(dtbig2 == dtbig);
2773 
2774     dtbig.setDateOnly(true);
2775     s = dtbig.toString(KADateTime::ISODate);
2776     QCOMPARE(s, QStringLiteral("123456-12-11"));
2777     dtbig1 = KADateTime::fromString(s, KADateTime::ISODate);
2778     QVERIFY(dtbig1.isDateOnly());
2779     QCOMPARE(dtbig1.timeType(), KADateTime::LocalZone);
2780     QCOMPARE(dtbig1.date(), QDate(123456, 12, 11));
2781     dtbig2 = KADateTime::fromString(QStringLiteral("1234561211"), KADateTime::ISODate);
2782     QVERIFY(dtbig2 == dtbig1);
2783 
2784     // Check basic format strings
2785     bool negZero = true;
2786     KADateTime dt = KADateTime::fromString(QStringLiteral("20000301T1213"), KADateTime::ISODate, &negZero);
2787     QVERIFY(dt.timeType() == KADateTime::LocalZone);
2788     QVERIFY(!dt.isDateOnly());
2789     QVERIFY(!negZero);
2790     QCOMPARE(dt.date(), QDate(2000, 3, 1));
2791     QCOMPARE(dt.time(), QTime(12, 13, 0));
2792     dt = KADateTime::fromString(QStringLiteral("20000301"), KADateTime::ISODate, &negZero);
2793     QVERIFY(dt.timeType() == KADateTime::LocalZone);
2794     QVERIFY(dt.isDateOnly());
2795     QVERIFY(!negZero);
2796     QCOMPARE(dt.date(), QDate(2000, 3, 1));
2797     KADateTime::setFromStringDefault(KADateTime::UTC);
2798     dt = KADateTime::fromString(QStringLiteral("20000301T1213"), KADateTime::ISODate);
2799     QVERIFY(dt.timeType() == KADateTime::UTC);
2800     QCOMPARE(dt.date(), QDate(2000, 3, 1));
2801     QCOMPARE(dt.time(), QTime(12, 13, 0));
2802     KADateTime::setFromStringDefault(KADateTime::LocalZone);
2803     dt = KADateTime::fromString(QStringLiteral("20000301T1213"), KADateTime::ISODate);
2804     QVERIFY(dt.timeSpec() == KADateTime::Spec::LocalZone());
2805     QCOMPARE(dt.date(), QDate(2000, 3, 1));
2806     QCOMPARE(dt.time(), QTime(12, 13, 0));
2807     KADateTime::setFromStringDefault(london);
2808     dt = KADateTime::fromString(QStringLiteral("20000301T1213"), KADateTime::ISODate);
2809     QVERIFY(dt.timeType() == KADateTime::TimeZone);
2810     QCOMPARE(dt.date(), QDate(2000, 3, 1));
2811     QCOMPARE(dt.time(), QTime(12, 13, 0));
2812     KADateTime::setFromStringDefault(KADateTime::Spec::OffsetFromUTC(5000));  // = +01:23:20
2813     dt = KADateTime::fromString(QStringLiteral("20000601T1213"), KADateTime::ISODate);
2814     QVERIFY(dt.timeType() == KADateTime::OffsetFromUTC);
2815     QCOMPARE(dt.utcOffset(), 5000);
2816     QCOMPARE(dt.toUtc().date(), QDate(2000, 6, 1));
2817     QCOMPARE(dt.toUtc().time(), QTime(10, 49, 40));
2818     KADateTime::setFromStringDefault(KADateTime::LocalZone);
2819     dt = KADateTime::fromString(QStringLiteral("6543210301T1213"), KADateTime::ISODate, &negZero);
2820     QVERIFY(dt.timeType() == KADateTime::LocalZone);
2821     QVERIFY(!dt.isDateOnly());
2822     QVERIFY(!negZero);
2823     QCOMPARE(dt.date(), QDate(654321, 3, 1));
2824     QCOMPARE(dt.time(), QTime(12, 13, 0));
2825     dt = KADateTime::fromString(QStringLiteral("6543210301"), KADateTime::ISODate, &negZero);
2826     QVERIFY(dt.isDateOnly());
2827     QVERIFY(!negZero);
2828     QCOMPARE(dt.date(), QDate(654321, 3, 1));
2829     dt = KADateTime::fromString(QStringLiteral("-47120301T1213"), KADateTime::ISODate, &negZero);
2830     QVERIFY(dt.timeType() == KADateTime::LocalZone);
2831     QVERIFY(!dt.isDateOnly());
2832     QVERIFY(!negZero);
2833     QCOMPARE(dt.date(), QDate(-4712, 3, 1));
2834     QCOMPARE(dt.time(), QTime(12, 13, 0));
2835     dt = KADateTime::fromString(QStringLiteral("-47120301"), KADateTime::ISODate, &negZero);
2836     QVERIFY(dt.isDateOnly());
2837     QVERIFY(!negZero);
2838     QCOMPARE(dt.date(), QDate(-4712, 3, 1));
2839 
2840     // Check strings containing day-of-the-year
2841     dt = KADateTime::fromString(QStringLiteral("1999-060T19:20:21.06-11:20"), KADateTime::ISODate);
2842     QVERIFY(dt.timeType() == KADateTime::OffsetFromUTC);
2843     QCOMPARE(dt.utcOffset(), -11 * 3600 - 20 * 60);
2844     QCOMPARE(dt.date(), QDate(1999, 3, 1));
2845     QCOMPARE(dt.time(), QTime(19, 20, 21, 60));
2846     dt = KADateTime::fromString(QStringLiteral("1999-060T19:20:21,06-11:20"), KADateTime::ISODate);
2847     QVERIFY(dt.timeType() == KADateTime::OffsetFromUTC);
2848     QCOMPARE(dt.utcOffset(), -11 * 3600 - 20 * 60);
2849     QCOMPARE(dt.date(), QDate(1999, 3, 1));
2850     QCOMPARE(dt.time(), QTime(19, 20, 21, 60));
2851     dt = KADateTime::fromString(QStringLiteral("1999060T192021.06-1120"), KADateTime::ISODate);
2852     QVERIFY(dt.timeType() == KADateTime::OffsetFromUTC);
2853     QCOMPARE(dt.utcOffset(), -11 * 3600 - 20 * 60);
2854     QCOMPARE(dt.date(), QDate(1999, 3, 1));
2855     QCOMPARE(dt.time(), QTime(19, 20, 21, 60));
2856     dt = KADateTime::fromString(QStringLiteral("1999-060"), KADateTime::ISODate);
2857     QVERIFY(dt.timeType() == KADateTime::LocalZone);
2858     QVERIFY(dt.isDateOnly());
2859     QCOMPARE(dt.date(), QDate(1999, 3, 1));
2860 
2861     // Check 24:00:00
2862     dt = KADateTime::fromString(QStringLiteral("1999-06-11T24:00:00+03:00"), KADateTime::ISODate);
2863     QCOMPARE(dt.date(), QDate(1999, 6, 12));
2864     QCOMPARE(dt.time(), QTime(0, 0, 0));
2865     dt = KADateTime::fromString(QStringLiteral("1999-06-11T24:00:01+03:00"), KADateTime::ISODate);
2866     QVERIFY(!dt.isValid());
2867 
2868     // Check leap second
2869     dt = KADateTime::fromString(QStringLiteral("1999-06-11T23:59:60Z"), KADateTime::ISODate);
2870     QCOMPARE(dt.date(), QDate(1999, 6, 11));
2871     QCOMPARE(dt.time(), QTime(23, 59, 59));
2872     dt = KADateTime::fromString(QStringLiteral("1999-06-11T13:59:60Z"), KADateTime::ISODate);
2873     QVERIFY(!dt.isValid());
2874     dt = KADateTime::fromString(QStringLiteral("1999-06-11T13:59:60-10:00"), KADateTime::ISODate);
2875     QCOMPARE(dt.date(), QDate(1999, 6, 11));
2876     QCOMPARE(dt.time(), QTime(13, 59, 59));
2877     dt = KADateTime::fromString(QStringLiteral("1999-06-11T23:59:60-10:00"), KADateTime::ISODate);
2878     QVERIFY(!dt.isValid());
2879 
2880     // Check negZero
2881     dt = KADateTime::fromString(QStringLiteral("1999-060T19:20:21.06-00:00"), KADateTime::ISODate, &negZero);
2882     QVERIFY(negZero);
2883     dt = KADateTime::fromString(QStringLiteral("1999-060T19:20:21.06+00:00"), KADateTime::ISODate, &negZero);
2884     QVERIFY(!negZero);
2885 
2886     // Restore the original local time zone
2887     if (originalZone.isEmpty()) {
2888         unsetenv("TZ");
2889     } else {
2890         qputenv("TZ", originalZone);
2891     }
2892     ::tzset();
2893 }
2894 
strings_rfc2822()2895 void KADateTimeTest::strings_rfc2822()
2896 {
2897     QTimeZone london("Europe/London");
2898 
2899     // Ensure that local time is different from UTC and different from 'london'
2900     QByteArray originalZone = qgetenv("TZ");   // save the original local time zone
2901     qputenv("TZ", ":America/Los_Angeles");
2902     ::tzset();
2903 
2904     bool negZero = true;
2905     KADateTime dtlocal(QDate(1999, 12, 11), QTime(3, 45, 6), KADateTime::LocalZone);
2906     QString s = dtlocal.toString(KADateTime::RFCDate);
2907     QCOMPARE(s, QStringLiteral("11 Dec 1999 03:45:06 -0800"));
2908     KADateTime dtlocal1 = KADateTime::fromString(s, KADateTime::RFCDate, &negZero);
2909     QCOMPARE(dtlocal1.qDateTime().toUTC(), dtlocal.qDateTime().toUTC());
2910     QCOMPARE(dtlocal1.timeType(), KADateTime::OffsetFromUTC);
2911     QCOMPARE(dtlocal1.utcOffset(), -8 * 3600);
2912     QVERIFY(dtlocal1 == dtlocal);
2913     QVERIFY(!negZero);
2914     KADateTime dtlocal2 = KADateTime::fromString(s, KADateTime::RFCDateDay);
2915     QVERIFY(!dtlocal2.isValid());
2916     s = dtlocal.toString(KADateTime::RFCDateDay);
2917     QCOMPARE(s, QStringLiteral("Sat, 11 Dec 1999 03:45:06 -0800"));
2918     dtlocal2 = KADateTime::fromString(s, KADateTime::RFCDate);
2919     QVERIFY(dtlocal1 == dtlocal2);
2920     QCOMPARE(dtlocal1.date(), dtlocal2.date());
2921     QCOMPARE(dtlocal1.time(), dtlocal2.time());
2922     dtlocal2 = KADateTime::fromString(s, KADateTime::RFCDateDay);
2923     QVERIFY(dtlocal1 == dtlocal2);
2924     dtlocal2 = KADateTime::fromString(QStringLiteral("Saturday, 11-Dec-99 03:45:06 -0800"), KADateTime::RFCDate);
2925     QVERIFY(dtlocal1 == dtlocal2);
2926     dtlocal2 = KADateTime::fromString(QStringLiteral("11 Dec 1999 03:45:06 PST"), KADateTime::RFCDate, &negZero);
2927     QVERIFY(dtlocal1 == dtlocal2);
2928     QVERIFY(!negZero);
2929     dtlocal.setDateOnly(true);
2930     s = dtlocal.toString(KADateTime::RFCDate);
2931     QCOMPARE(s, QStringLiteral("11 Dec 1999 00:00 -0800"));
2932     s = dtlocal.toString(KADateTime::RFCDateDay);
2933     QCOMPARE(s, QStringLiteral("Sat, 11 Dec 1999 00:00 -0800"));
2934 
2935     KADateTime dtzone(QDate(1999, 6, 11), QTime(3, 45, 6), london);
2936     s = dtzone.toString(KADateTime::RFCDate);
2937     QCOMPARE(s, QStringLiteral("11 Jun 1999 03:45:06 +0100"));
2938     KADateTime dtzone1 = KADateTime::fromString(s, KADateTime::RFCDate);
2939     QCOMPARE(dtzone1.qDateTime().toUTC(), dtzone.qDateTime().toUTC());
2940     QCOMPARE(dtzone1.timeType(), KADateTime::OffsetFromUTC);
2941     QCOMPARE(dtzone1.utcOffset(), 3600);
2942     QVERIFY(dtzone1 == dtzone);
2943     KADateTime dtzone2 = KADateTime::fromString(s, KADateTime::RFCDateDay);
2944     QVERIFY(!dtzone2.isValid());
2945     s = dtzone.toString(KADateTime::RFCDateDay);
2946     QCOMPARE(s, QStringLiteral("Fri, 11 Jun 1999 03:45:06 +0100"));
2947     dtzone2 = KADateTime::fromString(s, KADateTime::RFCDate);
2948     QVERIFY(dtzone1 == dtzone2);
2949     QCOMPARE(dtzone1.date(), dtzone2.date());
2950     QCOMPARE(dtzone1.time(), dtzone2.time());
2951     dtzone2 = KADateTime::fromString(s, KADateTime::RFCDateDay, &negZero);
2952     QVERIFY(dtzone1 == dtzone2);
2953     QVERIFY(!negZero);
2954     dtzone2 = KADateTime::fromString(QStringLiteral("Friday, 11-Jun-99 03:45:06 +0100"), KADateTime::RFCDateDay);
2955     QVERIFY(dtzone1 == dtzone2);
2956     dtzone.setDateOnly(true);
2957     s = dtzone.toString(KADateTime::RFCDate);
2958     QCOMPARE(s, QStringLiteral("11 Jun 1999 00:00 +0100"));
2959     s = dtzone.toString(KADateTime::RFCDateDay);
2960     QCOMPARE(s, QStringLiteral("Fri, 11 Jun 1999 00:00 +0100"));
2961 
2962     KADateTime dtutc(QDate(1999, 12, 11), QTime(3, 45, 00), KADateTime::UTC);
2963     s = dtutc.toString(KADateTime::RFCDate);
2964     QCOMPARE(s, QStringLiteral("11 Dec 1999 03:45 +0000"));
2965     KADateTime dtutc1 = KADateTime::fromString(s, KADateTime::RFCDate, &negZero);
2966     QCOMPARE(dtutc1.date(), dtutc.date());
2967     QCOMPARE(dtutc1.time(), dtutc.time());
2968     QCOMPARE(dtutc1.timeType(), KADateTime::UTC);
2969     QVERIFY(dtutc1 == dtutc);
2970     QVERIFY(!negZero);
2971     KADateTime dtutc2 = KADateTime::fromString(s, KADateTime::RFCDateDay);
2972     QVERIFY(!dtutc2.isValid());
2973     s = dtutc.toString(KADateTime::RFCDateDay);
2974     QCOMPARE(s, QStringLiteral("Sat, 11 Dec 1999 03:45 +0000"));
2975     dtutc2 = KADateTime::fromString(s, KADateTime::RFCDate);
2976     QVERIFY(dtutc1 == dtutc2);
2977     QCOMPARE(dtutc1.date(), dtutc2.date());
2978     QCOMPARE(dtutc1.time(), dtutc2.time());
2979     dtutc2 = KADateTime::fromString(s, KADateTime::RFCDateDay);
2980     QVERIFY(dtutc1 == dtutc2);
2981     dtutc2 = KADateTime::fromString(QStringLiteral("Saturday, 11-Dec-99 03:45 +0000"), KADateTime::RFCDate);
2982     QVERIFY(dtutc1 == dtutc2);
2983     dtutc.setDateOnly(true);
2984     s = dtutc.toString(KADateTime::RFCDate);
2985     QCOMPARE(s, QStringLiteral("11 Dec 1999 00:00 +0000"));
2986     s = dtutc.toString(KADateTime::RFCDateDay);
2987     QCOMPARE(s, QStringLiteral("Sat, 11 Dec 1999 00:00 +0000"));
2988 
2989     // Check '-0000' and unknown/invalid time zone names
2990     dtutc2 = KADateTime::fromString(QStringLiteral("11 Dec 1999 03:45 -0000"), KADateTime::RFCDate, &negZero);
2991     QVERIFY(dtutc1 == dtutc2);
2992     QVERIFY(negZero);
2993     dtutc2 = KADateTime::fromString(QStringLiteral("11 Dec 1999 03:45 B"), KADateTime::RFCDate, &negZero);
2994     QVERIFY(dtutc1 == dtutc2);
2995     QVERIFY(negZero);
2996     dtutc2 = KADateTime::fromString(QStringLiteral("11 Dec 1999 03:45 BCDE"), KADateTime::RFCDate, &negZero);
2997     QVERIFY(dtutc1 == dtutc2);
2998     QVERIFY(negZero);
2999 
3000     // Check named time offsets
3001     KADateTime dtzname = KADateTime::fromString(QStringLiteral("11 Dec 1999 03:45:06 UT"), KADateTime::RFCDate, &negZero);
3002     QVERIFY(dtzname.timeType() == KADateTime::UTC);
3003     QCOMPARE(dtzname.date(), QDate(1999, 12, 11));
3004     QCOMPARE(dtzname.time(), QTime(3, 45, 6));
3005     QVERIFY(!negZero);
3006     dtzname = KADateTime::fromString(QStringLiteral("11 Dec 1999 03:45:06 GMT"), KADateTime::RFCDate, &negZero);
3007     QVERIFY(dtzname.timeType() == KADateTime::UTC);
3008     QCOMPARE(dtzname.date(), QDate(1999, 12, 11));
3009     QCOMPARE(dtzname.time(), QTime(3, 45, 6));
3010     QVERIFY(!negZero);
3011     dtzname = KADateTime::fromString(QStringLiteral("11 Dec 1999 03:45:06 EDT"), KADateTime::RFCDate, &negZero);
3012     QVERIFY(dtzname.timeType() == KADateTime::OffsetFromUTC);
3013     QCOMPARE(dtzname.utcOffset(), -4 * 3600);
3014     QCOMPARE(dtzname.date(), QDate(1999, 12, 11));
3015     QCOMPARE(dtzname.time(), QTime(3, 45, 6));
3016     QVERIFY(!negZero);
3017     dtzname = KADateTime::fromString(QStringLiteral("11 Dec 1999 03:45:06 EST"), KADateTime::RFCDate, &negZero);
3018     QVERIFY(dtzname.timeType() == KADateTime::OffsetFromUTC);
3019     QCOMPARE(dtzname.utcOffset(), -5 * 3600);
3020     QCOMPARE(dtzname.date(), QDate(1999, 12, 11));
3021     QCOMPARE(dtzname.time(), QTime(3, 45, 6));
3022     QVERIFY(!negZero);
3023     dtzname = KADateTime::fromString(QStringLiteral("11 Dec 1999 03:45:06 CDT"), KADateTime::RFCDate, &negZero);
3024     QVERIFY(dtzname.timeType() == KADateTime::OffsetFromUTC);
3025     QCOMPARE(dtzname.utcOffset(), -5 * 3600);
3026     QCOMPARE(dtzname.date(), QDate(1999, 12, 11));
3027     QCOMPARE(dtzname.time(), QTime(3, 45, 6));
3028     QVERIFY(!negZero);
3029     dtzname = KADateTime::fromString(QStringLiteral("11 Dec 1999 03:45:06 CST"), KADateTime::RFCDate, &negZero);
3030     QVERIFY(dtzname.timeType() == KADateTime::OffsetFromUTC);
3031     QCOMPARE(dtzname.utcOffset(), -6 * 3600);
3032     QCOMPARE(dtzname.date(), QDate(1999, 12, 11));
3033     QCOMPARE(dtzname.time(), QTime(3, 45, 6));
3034     QVERIFY(!negZero);
3035     dtzname = KADateTime::fromString(QStringLiteral("11 Dec 1999 03:45:06 MDT"), KADateTime::RFCDate, &negZero);
3036     QVERIFY(dtzname.timeType() == KADateTime::OffsetFromUTC);
3037     QCOMPARE(dtzname.utcOffset(), -6 * 3600);
3038     QCOMPARE(dtzname.date(), QDate(1999, 12, 11));
3039     QCOMPARE(dtzname.time(), QTime(3, 45, 6));
3040     QVERIFY(!negZero);
3041     dtzname = KADateTime::fromString(QStringLiteral("11 Dec 1999 03:45:06 MST"), KADateTime::RFCDate, &negZero);
3042     QVERIFY(dtzname.timeType() == KADateTime::OffsetFromUTC);
3043     QCOMPARE(dtzname.utcOffset(), -7 * 3600);
3044     QCOMPARE(dtzname.date(), QDate(1999, 12, 11));
3045     QCOMPARE(dtzname.time(), QTime(3, 45, 6));
3046     QVERIFY(!negZero);
3047     dtzname = KADateTime::fromString(QStringLiteral("11 Dec 1999 03:45:06 PDT"), KADateTime::RFCDate, &negZero);
3048     QVERIFY(dtzname.timeType() == KADateTime::OffsetFromUTC);
3049     QCOMPARE(dtzname.utcOffset(), -7 * 3600);
3050     QCOMPARE(dtzname.date(), QDate(1999, 12, 11));
3051     QCOMPARE(dtzname.time(), QTime(3, 45, 6));
3052     QVERIFY(!negZero);
3053     dtzname = KADateTime::fromString(QStringLiteral("11 Dec 1999 03:45:06 PST"), KADateTime::RFCDate, &negZero);
3054     QVERIFY(dtzname.timeType() == KADateTime::OffsetFromUTC);
3055     QCOMPARE(dtzname.utcOffset(), -8 * 3600);
3056     QCOMPARE(dtzname.date(), QDate(1999, 12, 11));
3057     QCOMPARE(dtzname.time(), QTime(3, 45, 6));
3058     QVERIFY(!negZero);
3059 
3060     // Check leap second
3061     KADateTime dt = KADateTime::fromString(QStringLiteral("11 Dec 1999 23:59:60 -0000"), KADateTime::RFCDate);
3062     QCOMPARE(dt.date(), QDate(1999, 12, 11));
3063     QCOMPARE(dt.time(), QTime(23, 59, 59));
3064     dt = KADateTime::fromString(QStringLiteral("11 Dec 1999 13:59:60 -0000"), KADateTime::RFCDate);
3065     QVERIFY(!dt.isValid());
3066     dt = KADateTime::fromString(QStringLiteral("11 Jun 1999 13:59:60 -1000"), KADateTime::RFCDate);
3067     QCOMPARE(dt.date(), QDate(1999, 6, 11));
3068     QCOMPARE(dt.time(), QTime(13, 59, 59));
3069     dt = KADateTime::fromString(QStringLiteral("11 Dec 1999 23:59:60 -1000"), KADateTime::RFCDate);
3070     QVERIFY(!dt.isValid());
3071 
3072     // Check erroneous strings:
3073     dtutc2 = KADateTime::fromString(QStringLiteral("11 Dec 1999 23:59:60 -00:00"), KADateTime::RFCDate);
3074     QVERIFY(!dtutc2.isValid());     // colon in UTC offset
3075     dtutc2 = KADateTime::fromString(QStringLiteral("Sun, 11 Dec 1999 03:45 +0000"), KADateTime::RFCDate);
3076     QVERIFY(!dtutc2.isValid());     // wrong weekday
3077     dtutc2 = KADateTime::fromString(QStringLiteral("Satu, 11 Dec 1999 03:45 +0000"), KADateTime::RFCDate);
3078     QVERIFY(!dtutc2.isValid());     // bad weekday
3079     dtutc2 = KADateTime::fromString(QStringLiteral("11 Dece 1999 03:45 +0000"), KADateTime::RFCDate);
3080     QVERIFY(!dtutc2.isValid());     // bad month
3081     dtutc2 = KADateTime::fromString(QStringLiteral("11-Dec 1999 03:45 +0000"), KADateTime::RFCDate);
3082     QVERIFY(!dtutc2.isValid());     // only one hyphen in date
3083 
3084     // Restore the original local time zone
3085     if (originalZone.isEmpty()) {
3086         unsetenv("TZ");
3087     } else {
3088         qputenv("TZ", originalZone);
3089     }
3090     ::tzset();
3091 }
3092 
strings_rfc3339()3093 void KADateTimeTest::strings_rfc3339()
3094 {
3095     QTimeZone london("Europe/London");
3096 
3097     // Ensure that local time is different from UTC and different from 'london'
3098     QByteArray originalZone = qgetenv("TZ");   // save the original local time zone
3099     qputenv("TZ", ":America/Los_Angeles");
3100     ::tzset();
3101 
3102     bool negZero = true;
3103     KADateTime dtlocal(QDate(1999, 2, 9), QTime(3, 45, 6, 236), KADateTime::LocalZone);
3104     QString s = dtlocal.toString(KADateTime::RFC3339Date);
3105     QCOMPARE(s, QStringLiteral("1999-02-09T03:45:06.236-08:00"));
3106     KADateTime dtlocal1 = KADateTime::fromString(s, KADateTime::RFC3339Date, &negZero);
3107     QCOMPARE(dtlocal1.qDateTime().toUTC(), dtlocal.qDateTime().toUTC());
3108     QCOMPARE(dtlocal1.timeType(), KADateTime::OffsetFromUTC);
3109     QCOMPARE(dtlocal1.utcOffset(), -8 * 3600);
3110     QVERIFY(dtlocal1 == dtlocal);
3111     QVERIFY(!negZero);
3112     dtlocal.setDateOnly(true);
3113     s = dtlocal.toString(KADateTime::RFC3339Date);
3114     QCOMPARE(s, QStringLiteral("1999-02-09T00:00:00-08:00"));
3115 
3116     KADateTime dtzone(QDate(1999, 6, 9), QTime(3, 45, 06, 230), london);
3117     s = dtzone.toString(KADateTime::RFC3339Date);
3118     QCOMPARE(s, QStringLiteral("1999-06-09T03:45:06.23+01:00"));
3119     KADateTime dtzone1 = KADateTime::fromString(s, KADateTime::RFC3339Date);
3120     QCOMPARE(dtzone1.qDateTime().toUTC(), dtzone.qDateTime().toUTC());
3121     QCOMPARE(dtzone1.timeType(), KADateTime::OffsetFromUTC);
3122     QCOMPARE(dtzone1.utcOffset(), 3600);
3123     QVERIFY(dtzone1 == dtzone);
3124     dtzone.setDateOnly(true);
3125     s = dtzone.toString(KADateTime::RFC3339Date);
3126     QCOMPARE(s, QStringLiteral("1999-06-09T00:00:00+01:00"));
3127 
3128     KADateTime dtzone2(QDate(1999, 6, 9), QTime(3, 45, 06, 200), london);
3129     s = dtzone2.toString(KADateTime::RFC3339Date);
3130     QCOMPARE(s, QStringLiteral("1999-06-09T03:45:06.2+01:00"));
3131     KADateTime dtzone3 = KADateTime::fromString(s, KADateTime::RFC3339Date);
3132     QCOMPARE(dtzone3.qDateTime().toUTC(), dtzone2.qDateTime().toUTC());
3133 
3134     KADateTime dtutc(QDate(1999, 2, 9), QTime(3, 45, 00), KADateTime::UTC);
3135     s = dtutc.toString(KADateTime::RFC3339Date);
3136     QCOMPARE(s, QStringLiteral("1999-02-09T03:45:00Z"));
3137     KADateTime dtutc1 = KADateTime::fromString(s, KADateTime::RFC3339Date, &negZero);
3138     QCOMPARE(dtutc1.date(), dtutc.date());
3139     QCOMPARE(dtutc1.time(), dtutc.time());
3140     QCOMPARE(dtutc1.timeType(), KADateTime::UTC);
3141     QVERIFY(dtutc1 == dtutc);
3142     QVERIFY(!negZero);
3143     KADateTime dtutc2 = KADateTime::fromString(QStringLiteral("1999-02-09t03:45:00z"), KADateTime::RFC3339Date, &negZero);
3144     QVERIFY(dtutc1 == dtutc2);
3145     dtutc.setDateOnly(true);
3146     s = dtutc.toString(KADateTime::RFC3339Date);
3147     QCOMPARE(s, QStringLiteral("1999-02-09T00:00:00Z"));
3148 
3149     // Check '-00:00' (specifies unknown local offset)
3150     dtutc2 = KADateTime::fromString(QStringLiteral("1999-02-09T03:45:00-00:00"), KADateTime::RFC3339Date, &negZero);
3151     QVERIFY(dtutc1 == dtutc2);
3152     QVERIFY(negZero);
3153     dtutc2 = KADateTime::fromString(QStringLiteral("1999-02-09T03:45:00+00:00"), KADateTime::RFC3339Date, &negZero);
3154     QVERIFY(dtutc1 == dtutc2);
3155     QVERIFY(!negZero);
3156 
3157     // Check leap second
3158     KADateTime dt = KADateTime::fromString(QStringLiteral("1999-02-09T23:59:60z"), KADateTime::RFC3339Date);
3159     QCOMPARE(dt.date(), QDate(1999, 2, 9));
3160     QCOMPARE(dt.time(), QTime(23, 59, 59));
3161     dt = KADateTime::fromString(QStringLiteral("1999-02-09T23:59:60+00:00"), KADateTime::RFC3339Date);
3162     QCOMPARE(dt.toUtc().date(), QDate(1999, 2, 9));
3163     QCOMPARE(dt.toUtc().time(), QTime(23, 59, 59));
3164     dt = KADateTime::fromString(QStringLiteral("1999-02-09T13:59:60-00:00"), KADateTime::RFC3339Date);
3165     QVERIFY(!dt.isValid());
3166     dt = KADateTime::fromString(QStringLiteral("1999-06-11T13:59:60-10:00"), KADateTime::RFC3339Date);
3167     QCOMPARE(dt.toUtc().date(), QDate(1999, 6, 11));
3168     QCOMPARE(dt.toUtc().time(), QTime(23, 59, 59));
3169     dt = KADateTime::fromString(QStringLiteral("1999-12-11T23:59:60-10:00"), KADateTime::RFC3339Date);
3170     QVERIFY(!dt.isValid());
3171 
3172     // Check erroneous strings:
3173     dtutc2 = KADateTime::fromString(QStringLiteral("1999-02-09 03:45:00"), KADateTime::RFC3339Date, &negZero);
3174     QVERIFY(!dtutc2.isValid());
3175     dtutc2 = KADateTime::fromString(QStringLiteral("1999-02-09T03:45:00B"), KADateTime::RFC3339Date, &negZero);
3176     QVERIFY(!dtutc2.isValid());
3177     dtutc2 = KADateTime::fromString(QStringLiteral("1999-02-09T23:59:60-0000"), KADateTime::RFC3339Date);
3178     QVERIFY(!dtutc2.isValid());     // no colon in UTC offset
3179     dtutc2 = KADateTime::fromString(QStringLiteral("19990-12-10T03:45:01+00:00"), KADateTime::RFC3339Date);
3180     QVERIFY(!dtutc2.isValid());     // bad year
3181     dtutc2 = KADateTime::fromString(QStringLiteral("1999-13-10T03:45:01+00:00"), KADateTime::RFC3339Date);
3182     QVERIFY(!dtutc2.isValid());     // bad month
3183     dtutc2 = KADateTime::fromString(QStringLiteral("1999-10-32T03:45:01+00:00"), KADateTime::RFC3339Date);
3184     QVERIFY(!dtutc2.isValid());     // bad day
3185     dtutc2 = KADateTime::fromString(QStringLiteral("1999-1209T03:45:00+00:00"), KADateTime::RFC3339Date);
3186     QVERIFY(!dtutc2.isValid());     // only one hyphen in date
3187     dtutc2 = KADateTime::fromString(QStringLiteral("1999-12T03:45:00+00:00"), KADateTime::RFC3339Date);
3188     QVERIFY(!dtutc2.isValid());     // no day of month
3189 
3190     // Restore the original local time zone
3191     if (originalZone.isEmpty()) {
3192         unsetenv("TZ");
3193     } else {
3194         qputenv("TZ", originalZone);
3195     }
3196     ::tzset();
3197 }
3198 
strings_qttextdate()3199 void KADateTimeTest::strings_qttextdate()
3200 {
3201     QTimeZone london("Europe/London");
3202 
3203     // Ensure that local time is different from UTC and different from 'london'
3204     QByteArray originalZone = qgetenv("TZ");   // save the original local time zone
3205     qputenv("TZ", ":America/Los_Angeles");
3206     ::tzset();
3207 
3208     bool negZero = true;
3209     KADateTime dtlocal(QDate(1999, 12, 11), QTime(3, 45, 6), KADateTime::LocalZone);
3210     QString s = dtlocal.toString(KADateTime::QtTextDate);
3211     QCOMPARE(s, QStringLiteral("Sat Dec 11 03:45:06 1999"));
3212     KADateTime dtlocal1 = KADateTime::fromString(s, KADateTime::QtTextDate, &negZero);
3213     QCOMPARE(dtlocal1.qDateTime().toUTC(), dtlocal.qDateTime().toUTC());
3214     QCOMPARE(dtlocal1.timeType(), KADateTime::LocalZone);
3215     QCOMPARE(dtlocal1.utcOffset(), -8 * 3600);
3216     QVERIFY(dtlocal1 == dtlocal);
3217     QVERIFY(!dtlocal1.isDateOnly());
3218     QVERIFY(!negZero);
3219     dtlocal.setDateOnly(true);
3220     s = dtlocal.toString(KADateTime::QtTextDate);
3221     QCOMPARE(s, QStringLiteral("Sat Dec 11 1999"));
3222     dtlocal1 = KADateTime::fromString(s, KADateTime::QtTextDate, &negZero);
3223     QVERIFY(dtlocal1.isDateOnly());
3224     QCOMPARE(dtlocal1.date(), QDate(1999, 12, 11));
3225     QCOMPARE(dtlocal1.timeType(), KADateTime::LocalZone);
3226     QCOMPARE(dtlocal1.utcOffset(), -8 * 3600);
3227 
3228     KADateTime dtzone(QDate(1999, 6, 11), QTime(3, 45, 6), london);
3229     s = dtzone.toString(KADateTime::QtTextDate);
3230     QCOMPARE(s, QStringLiteral("Fri Jun 11 03:45:06 1999 +0100"));
3231     KADateTime dtzone1 = KADateTime::fromString(s, KADateTime::QtTextDate);
3232     QCOMPARE(dtzone1.qDateTime().toUTC(), dtzone.qDateTime().toUTC());
3233     QCOMPARE(dtzone1.timeType(), KADateTime::OffsetFromUTC);
3234     QCOMPARE(dtzone1.utcOffset(), 3600);
3235     QVERIFY(!dtzone1.isDateOnly());
3236     QVERIFY(dtzone1 == dtzone);
3237     KADateTime dtzone2 = KADateTime::fromString(s, KADateTime::QtTextDate, &negZero);
3238     QVERIFY(dtzone1 == dtzone2);
3239     QVERIFY(!negZero);
3240     dtzone.setDateOnly(true);
3241     s = dtzone.toString(KADateTime::QtTextDate);
3242     QCOMPARE(s, QStringLiteral("Fri Jun 11 1999 +0100"));
3243     dtzone1 = KADateTime::fromString(s, KADateTime::QtTextDate, &negZero);
3244     QVERIFY(dtzone1.isDateOnly());
3245     QCOMPARE(dtzone1.date(), QDate(1999, 6, 11));
3246     QCOMPARE(dtzone1.timeType(), KADateTime::OffsetFromUTC);
3247     QCOMPARE(dtzone1.utcOffset(), 3600);
3248 
3249     KADateTime dtutc(QDate(1999, 12, 11), QTime(3, 45, 0), KADateTime::UTC);
3250     s = dtutc.toString(KADateTime::QtTextDate);
3251     QCOMPARE(s, QStringLiteral("Sat Dec 11 03:45:00 1999 +0000"));
3252     KADateTime dtutc1 = KADateTime::fromString(s, KADateTime::QtTextDate, &negZero);
3253     QCOMPARE(dtutc1.date(), dtutc.date());
3254     QCOMPARE(dtutc1.time(), dtutc.time());
3255     QCOMPARE(dtutc1.timeType(), KADateTime::UTC);
3256     QVERIFY(dtutc1 == dtutc);
3257     QVERIFY(!dtutc1.isDateOnly());
3258     QVERIFY(!negZero);
3259     dtutc.setDateOnly(true);
3260     s = dtutc.toString(KADateTime::QtTextDate);
3261     QCOMPARE(s, QStringLiteral("Sat Dec 11 1999 +0000"));
3262     dtutc1 = KADateTime::fromString(s, KADateTime::QtTextDate, &negZero);
3263     QVERIFY(dtutc1.isDateOnly());
3264     QCOMPARE(dtutc1.date(), QDate(1999, 12, 11));
3265     QCOMPARE(dtutc1.timeType(), KADateTime::UTC);
3266 
3267     // Check '-0000'
3268     KADateTime dtutc2 = KADateTime::fromString(QStringLiteral("Sat Dec 11 03:45:00 1999 -0000"), KADateTime::QtTextDate, &negZero);
3269     QVERIFY(dtutc1 != dtutc2);
3270     QVERIFY(negZero);
3271 
3272     // Check erroneous strings
3273     dtutc2 = KADateTime::fromString(QStringLiteral("Sat Dec 11 03:45:00 1999 GMT"), KADateTime::QtTextDate, &negZero);
3274     QVERIFY(!dtutc2.isValid());
3275     dtutc2 = KADateTime::fromString(QStringLiteral("Sun Dec 11 03:45:00 1999 +0000"), KADateTime::QtTextDate);
3276     QVERIFY(dtutc2.isValid());     // wrong weekday: accepted by Qt!!
3277     dtutc2 = KADateTime::fromString(QStringLiteral("Satu, Dec 11 03:45:00 1999 +0000"), KADateTime::QtTextDate);
3278     QVERIFY(dtutc2.isValid());     // bad weekday, accepted by Qt (since 4.3)
3279     dtutc2 = KADateTime::fromString(QStringLiteral("Sat Dece 11 03:45:00 1999 +0000"), KADateTime::QtTextDate);
3280     QVERIFY(!dtutc2.isValid());     // bad month, not accepted by Qt anymore (since 4.3)
3281 
3282     // Restore the original local time zone
3283     if (originalZone.isEmpty()) {
3284         unsetenv("TZ");
3285     } else {
3286         qputenv("TZ", originalZone);
3287     }
3288     ::tzset();
3289 }
3290 
strings_format()3291 void KADateTimeTest::strings_format()
3292 {
3293     QTimeZone london("Europe/London");
3294     QTimeZone paris("Europe/Paris");
3295     QTimeZone berlin("Europe/Berlin");
3296     QTimeZone cairo("Africa/Cairo");
3297     QList<QTimeZone> zones;
3298     zones.append(london);
3299     zones.append(paris);
3300     zones.append(berlin);
3301     zones.append(cairo);
3302 
3303     // Ensure that local time is different from UTC and different from 'london'
3304     QByteArray originalZone = qgetenv("TZ");   // save the original local time zone
3305     qputenv("TZ", ":America/Los_Angeles");
3306     ::tzset();
3307 
3308     QLocale locale;
3309 
3310     // toString()
3311     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.%%.");
3312     KADateTime dt(QDate(1999, 2, 3), QTime(6, 5, 0), KADateTime::LocalZone);
3313     QString s = dt.toString(all);
3314     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.%.")
3315              .arg(locale.monthName(2, QLocale::LongFormat),
3316                   locale.monthName(2, QLocale::ShortFormat),
3317                   locale.dayName(3, QLocale::LongFormat),
3318                   locale.dayName(3, QLocale::ShortFormat)));
3319 
3320     KADateTime dtzone(QDate(1970, 4, 30), QTime(12, 45, 16, 25), london);
3321     s = dtzone.toString(all);
3322     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.%.")
3323              .arg(locale.monthName(4, QLocale::LongFormat),
3324                   locale.monthName(4, QLocale::ShortFormat),
3325                   locale.dayName(4, QLocale::LongFormat),
3326                   locale.dayName(4, QLocale::ShortFormat)));
3327 
3328     KADateTime dtutc(QDate(2000, 12, 31), QTime(13, 45, 16, 100), KADateTime::UTC);
3329     s = dtutc.toString(all);
3330     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.%.")
3331              .arg(locale.monthName(12, QLocale::LongFormat),
3332                   locale.monthName(12, QLocale::ShortFormat),
3333                   locale.dayName(7, QLocale::LongFormat),
3334                   locale.dayName(7, QLocale::ShortFormat)));
3335 
3336     // fromString() without QList<QTimeZone> parameter
3337     dt = KADateTime::fromString(QStringLiteral("2005/10/03/20:2,03"), QStringLiteral("%Y/%:m/%d/%S:%k,%M"));
3338     QCOMPARE(dt.date(), QDate(2005, 10, 3));
3339     QCOMPARE(dt.time(), QTime(2, 3, 20));
3340     QCOMPARE(dt.timeType(), KADateTime::LocalZone);
3341 
3342     dt = KADateTime::fromString(QStringLiteral("%1pm05ab%2t/032/20:2,03+10")
3343                                .arg(locale.dayName(1, QLocale::LongFormat),
3344                                     locale.monthName(10, QLocale::LongFormat)),
3345                                QStringLiteral("%a%p%yab%Bt/%e2/%S:%l,%M %z"));
3346     QCOMPARE(dt.date(), QDate(2005, 10, 3));
3347     QCOMPARE(dt.time(), QTime(14, 3, 20));
3348     QCOMPARE(dt.timeType(), KADateTime::OffsetFromUTC);
3349     QCOMPARE(dt.utcOffset(), 10 * 3600);
3350     dt = KADateTime::fromString(QStringLiteral("%1pm05ab%2t/032/20:2,03+10")
3351                                .arg(locale.dayName(1, QLocale::ShortFormat),
3352                                     locale.monthName(10, QLocale::ShortFormat)),
3353                                QStringLiteral("%a%p%yab%Bt/%d2/%s:%l,%:M %z"));
3354     QCOMPARE(dt.date(), QDate(2005, 10, 3));
3355     QCOMPARE(dt.time(), QTime(14, 3, 20));
3356     QCOMPARE(dt.timeType(), KADateTime::OffsetFromUTC);
3357     QCOMPARE(dt.utcOffset(), 10 * 3600);
3358     dt = KADateTime::fromString(QStringLiteral("monpm05aboCtt/032/20:2,03+10"), QStringLiteral("%a%p%yab%Bt/%d2/%S:%l,%M %z"));
3359     QCOMPARE(dt.date(), QDate(2005, 10, 3));
3360     QCOMPARE(dt.time(), QTime(14, 3, 20));
3361     QCOMPARE(dt.timeType(), KADateTime::OffsetFromUTC);
3362     QCOMPARE(dt.utcOffset(), 10 * 3600);
3363     dt = KADateTime::fromString(QStringLiteral("monDAYpm05aboCtoBert/032/20:2,03+10"), QStringLiteral("%a%p%yab%Bt/%e2/%S:%l,%M %z"));
3364     QCOMPARE(dt.date(), QDate(2005, 10, 3));
3365     QCOMPARE(dt.time(), QTime(14, 3, 20));
3366     QCOMPARE(dt.timeType(), KADateTime::OffsetFromUTC);
3367     QCOMPARE(dt.utcOffset(), 10 * 3600);
3368     dt = KADateTime::fromString(QStringLiteral("monDAYpm05abmzatemer/032/20:2,03+10"), QStringLiteral("%a%p%yab%B/%e2/%S:%l,%M %z"));
3369     QVERIFY(!dt.isValid());    // invalid month name
3370     dt = KADateTime::fromString(QStringLiteral("monDApm05aboct/032/20:2,03+10"), QStringLiteral("%a%p%yab%B/%e2/%S:%l,%M %z"));
3371     QVERIFY(!dt.isValid());    // invalid day name
3372     dt = KADateTime::fromString(QStringLiteral("mONdAYPM2005aboCtt/032/20:02,03+1000"), QStringLiteral("%:A%:p%Yab%Bt/%d2/%S:%I,%M %:u"));
3373     QCOMPARE(dt.date(), QDate(2005, 10, 3));
3374     QCOMPARE(dt.time(), QTime(14, 3, 20));
3375     QCOMPARE(dt.utcOffset(), 10 * 3600);
3376     QCOMPARE(dt.timeType(), KADateTime::OffsetFromUTC);
3377     KADateTime dtlocal = KADateTime::fromString(QStringLiteral("mONdAYPM2005abOctt/032/20:02,03+100"), QStringLiteral("%:A%:p%Yab%Bt/%e2/%S:%l,%M %:u"));
3378     QVERIFY(!dtlocal.isValid());    // wrong number of digits in UTC offset
3379     dtlocal = KADateTime::fromString(QStringLiteral("mONdAYPM2005abOctt/032/20:02,03+1"), QStringLiteral("%:A%:p%Yab%Bt/%d2/%S:%I,%M %z"));
3380     QVERIFY(!dtlocal.isValid());    // wrong number of digits in UTC offset
3381     dtlocal = KADateTime::fromString(QStringLiteral("mONdAYPM2005aboCtt/032/20:13,03+1000"), QStringLiteral("%:A%:p%Yab%Bt/%d2/%S:%I,%M %:u"));
3382     QVERIFY(!dtlocal.isValid());    // hours out of range for am/pm
3383     dtlocal = KADateTime::fromString(QStringLiteral("mONdAYPM2005aboCtt/032/20:00,03+1000"), QStringLiteral("%:A%:p%Yab%Bt/%d2/%S:%I,%M %:u"));
3384     QVERIFY(!dtlocal.isValid());    // hours out of range for am/pm
3385 
3386     // fromString() with QList<QTimeZone> parameter
3387     dt = KADateTime::fromString(QStringLiteral("mon 2005/10/03/20:2,03"), QStringLiteral("%:a %Y/%:m/%e/%S:%k,%M"), &zones);
3388     QCOMPARE(dt.date(), QDate(2005, 10, 3));
3389     QCOMPARE(dt.time(), QTime(2, 3, 20));
3390     QCOMPARE(dt.timeType(), KADateTime::LocalZone);
3391     dt = KADateTime::fromString(QStringLiteral("tue 2005/10/03/20:2,03"), QStringLiteral("%:a %Y/%:m/%d/%S:%k,%M"), &zones);
3392     QVERIFY(!dt.isValid());    // wrong day-of-week
3393 
3394     dt = KADateTime::fromString(QStringLiteral("pm2005aboCtt/03monday/20:2,03+03:00"), QStringLiteral("%p%Yab%Bt/%e%:A/%S:%l,%M %:z"), &zones);
3395     QCOMPARE(dt.date(), QDate(2005, 10, 3));
3396     QCOMPARE(dt.time(), QTime(14, 3, 20));
3397     QCOMPARE(dt.timeType(), KADateTime::OffsetFromUTC);
3398     QCOMPARE(dt.utcOffset(), 3 * 3600);
3399     QVERIFY(!dt.timeZone().isValid());
3400     dt = KADateTime::fromString(QStringLiteral("pm2005aboCtt/03sunday/20:2,03+03:00"), QStringLiteral("%p%Yab%Bt/%d%A/%S:%l,%M %:z"), &zones);
3401     QVERIFY(!dt.isValid());    // wrong day-of-week
3402 
3403     dtutc = KADateTime::fromString(QStringLiteral("2000-01-01T00:00:00.000+0000"), QStringLiteral("%Y-%m-%dT%H:%M%:S%:s%z"));
3404     QVERIFY(dtutc.isValid());
3405 
3406     dt = KADateTime::fromString(QStringLiteral("2000-01-01T05:00:00.000+0500"), QStringLiteral("%Y-%m-%dT%H:%M%:S%:s%z"));
3407     QVERIFY(dt.isValid());
3408     QVERIFY(dtutc == dt);
3409 
3410     dt = KADateTime::fromString(QStringLiteral("1999-12-31T20:30:00.000-0330"), QStringLiteral("%Y-%m-%dT%H:%M%:S%:s%z"));
3411     QVERIFY(dt.isValid());
3412     QVERIFY(dtutc == dt);
3413 
3414     dt = KADateTime::fromString(QStringLiteral("200510031430:01.3+0100"), QStringLiteral("%Y%m%d%H%M%:S%:s%z"), &zones, true);
3415     QCOMPARE(dt.date(), QDate(2005, 10, 3));
3416     QCOMPARE(dt.time(), QTime(14, 30, 01, 300));
3417     QCOMPARE(dt.timeType(), KADateTime::TimeZone);
3418     QCOMPARE(dt.timeZone(), london);
3419     QCOMPARE(dt.utcOffset(), 3600);
3420 
3421     dt = KADateTime::fromString(QStringLiteral("200510031430:01.3+0500"), QStringLiteral("%Y%m%d%H%M%:S%:s%z"), &zones, false);
3422     QCOMPARE(dt.date(), QDate(2005, 10, 3));
3423     QCOMPARE(dt.time(), QTime(14, 30, 01, 300));
3424     QCOMPARE(dt.timeType(), KADateTime::OffsetFromUTC);
3425     QCOMPARE(dt.utcOffset(), 5 * 3600);
3426 
3427     dt = KADateTime::fromString(QStringLiteral("200510031430:01.3+0200"), QStringLiteral("%Y%m%d%H%M%:S%:s%z"), &zones, true);
3428     QCOMPARE(dt.date(), QDate(2005, 10, 3));
3429     QCOMPARE(dt.time(), QTime(14, 30, 01, 300));
3430     QCOMPARE(dt.timeType(), KADateTime::OffsetFromUTC);
3431     QCOMPARE(dt.utcOffset(), 2 * 3600);
3432     dt = KADateTime::fromString(QStringLiteral("200509031430:01.3+0200"), QStringLiteral("%Y%m%d%H%M%:S%:s%z"), &zones, false);
3433     QVERIFY(!dt.isValid());    // matches paris and berlin
3434 
3435     dt = KADateTime::fromString(QStringLiteral("2005October051430 CEST"), QStringLiteral("%Y%:B%d%H%M%:S %Z"), &zones, true);
3436     QCOMPARE(dt.date(), QDate(2005, 10, 5));
3437     QCOMPARE(dt.time(), QTime(14, 30, 0));
3438     QCOMPARE(dt.timeType(), KADateTime::OffsetFromUTC);
3439     QCOMPARE(dt.utcOffset(), 2 * 3600);
3440     dt = KADateTime::fromString(QStringLiteral("2005October051430 CEST"), QStringLiteral("%Y%:B%d%H%M%:S %Z"), &zones, false);
3441     QVERIFY(!dt.isValid());    // matches paris and berlin
3442 
3443     dt = KADateTime::fromString(QStringLiteral("pm05aboCtobeRt/   052/   20:12,03+0100"), QStringLiteral("%:P%yab%:bt/  %e2/%t%S:%l,%M %z"), &zones);
3444     QCOMPARE(dt.date(), QDate(2005, 10, 5));
3445     QCOMPARE(dt.time(), QTime(12, 3, 20));
3446     QCOMPARE(dt.timeType(), KADateTime::TimeZone);
3447     QCOMPARE(dt.utcOffset(), 3600);
3448     QCOMPARE(dt.timeZone(), london);
3449 
3450     dt = KADateTime::fromString(QStringLiteral("2005aboCtt/022sun/20.0123456:12Am,3Africa/Cairo%"), QStringLiteral("%Yab%bt/%e2%a/%S%:s:%I%P,%:M %:Z%%"), &zones);
3451     QCOMPARE(dt.date(), QDate(2005, 10, 2));
3452     QCOMPARE(dt.time(), QTime(0, 3, 20, 12));
3453     QCOMPARE(dt.timeType(), KADateTime::TimeZone);
3454     QCOMPARE(dt.timeZone(), cairo);
3455     QCOMPARE(dt.utcOffset(), 2 * 3600);
3456 
3457     // Test large and minimum date values
3458     dt = KADateTime(QDate(-2005, 10, 3), QTime(0, 0, 06, 1), KADateTime::LocalZone);
3459     s = dt.toString(QStringLiteral("%Y"));
3460     QCOMPARE(s, QStringLiteral("-2005"));
3461 
3462     dt = KADateTime(QDate(-15, 10, 3), QTime(0, 0, 06, 1), KADateTime::LocalZone);
3463     s = dt.toString(QStringLiteral("%Y"));
3464     QCOMPARE(s, QStringLiteral("-0015"));
3465 
3466     dt = KADateTime::fromString(QStringLiteral("-471210031430:01.3+0500"), QStringLiteral("%Y%m%d%H%M%:S%:s%z"));
3467     QCOMPARE(dt.date(), QDate(-4712, 10, 3));
3468     QCOMPARE(dt.time(), QTime(14, 30, 1, 300));
3469     QCOMPARE(dt.utcOffset(), 5 * 3600);
3470     QVERIFY(dt.isValid());
3471 
3472     dt = KADateTime::fromString(QStringLiteral("999910031430:01.3+0500"), QStringLiteral("%Y%m%d%H%M%:S%:s%z"));
3473     QCOMPARE(dt.date(), QDate(9999, 10, 3));
3474     QCOMPARE(dt.time(), QTime(14, 30, 1, 300));
3475     QCOMPARE(dt.utcOffset(), 5 * 3600);
3476     QVERIFY(dt.isValid());
3477 
3478     dt = KADateTime::fromString(QStringLiteral("123456.10031430:01.3+0500"), QStringLiteral("%:Y.%m%d%H%M%:S%:s%z"));
3479     QCOMPARE(dt.date(), QDate(123456, 10, 3));
3480     QCOMPARE(dt.time(), QTime(14, 30, 1, 300));
3481     QCOMPARE(dt.utcOffset(), 5 * 3600);
3482     QVERIFY(dt.isValid());
3483     s = dt.toString(QStringLiteral("%Y"));
3484     QCOMPARE(s, QStringLiteral("123456"));
3485 
3486     dt = KADateTime::fromString(QStringLiteral("-471411231430:01.3+0500"), QStringLiteral("%Y%m%d%H%M%:S%:s%z"));
3487     QVERIFY(dt.isValid());
3488     QVERIFY(dt.date().toJulianDay() == -1);
3489 
3490     // Restore the original local time zone
3491     if (originalZone.isEmpty()) {
3492         unsetenv("TZ");
3493     } else {
3494         qputenv("TZ", originalZone);
3495     }
3496     ::tzset();
3497 }
3498 
3499 #ifdef COMPILING_TESTS
3500 // This test requires a specially-modified kalarmcal2, so use the same compile guard here
3501 // as used in kalarmcal2/src/kadatetime.cpp
cache()3502 void KADateTimeTest::cache()
3503 {
3504     QTimeZone london("Europe/London");
3505     QTimeZone losAngeles("America/Los_Angeles");
3506     QTimeZone cairo("Africa/Cairo");
3507 
3508     QByteArray originalZone = qgetenv("TZ");   // save the original local time zone
3509     qputenv("TZ", ":Europe/London");
3510     ::tzset();
3511 
3512     // Ensure that local time is different from UTC and different from 'london'
3513     qputenv("TZ", ":America/Los_Angeles");
3514     ::tzset();
3515 
3516     int utcHit  = KADateTime_utcCacheHit;
3517     int zoneHit = KADateTime_zoneCacheHit;
3518     KADateTime local(QDate(2005, 6, 1), QTime(12, 0, 0), KADateTime::LocalZone);
3519     QCOMPARE(KADateTime_utcCacheHit, utcHit);
3520     QCOMPARE(KADateTime_zoneCacheHit, zoneHit);
3521     KADateTime dt1 = local.toZone(london);
3522     QCOMPARE(KADateTime_utcCacheHit, utcHit);
3523     QCOMPARE(KADateTime_zoneCacheHit, zoneHit);
3524     KADateTime cai = local.toZone(cairo);
3525     ++utcHit;
3526     QCOMPARE(KADateTime_utcCacheHit, utcHit);
3527     QCOMPARE(KADateTime_zoneCacheHit, zoneHit);
3528     KADateTime dt2a = local.toZone(london);
3529     ++utcHit;
3530     QCOMPARE(KADateTime_utcCacheHit, utcHit);
3531     QCOMPARE(KADateTime_zoneCacheHit, zoneHit);
3532     KADateTime dt2 = local.toZone(london);
3533     ++zoneHit;
3534     QCOMPARE(KADateTime_utcCacheHit, utcHit);
3535     QCOMPARE(KADateTime_zoneCacheHit, zoneHit);
3536     KADateTime dt3 = dt2;
3537     QCOMPARE(KADateTime_utcCacheHit, utcHit);
3538     QCOMPARE(KADateTime_zoneCacheHit, zoneHit);
3539     KADateTime dt4 = dt2.toZone(losAngeles);
3540     ++zoneHit;
3541     QCOMPARE(KADateTime_utcCacheHit, utcHit);
3542     QCOMPARE(KADateTime_zoneCacheHit, zoneHit);
3543     KADateTime dt4a = dt3.toZone(losAngeles);
3544     ++zoneHit;
3545     QCOMPARE(KADateTime_utcCacheHit, utcHit);
3546     QCOMPARE(KADateTime_zoneCacheHit, zoneHit);
3547     KADateTime dt5 = dt2.toZone(losAngeles);
3548     ++zoneHit;
3549     QCOMPARE(KADateTime_utcCacheHit, utcHit);
3550     QCOMPARE(KADateTime_zoneCacheHit, zoneHit);
3551     KADateTime dt5a = dt3.toZone(losAngeles);
3552     ++zoneHit;
3553     QCOMPARE(KADateTime_utcCacheHit, utcHit);
3554     QCOMPARE(KADateTime_zoneCacheHit, zoneHit);
3555     KADateTime dt6 = dt2.toZone(cairo);
3556     ++utcHit;
3557     QCOMPARE(KADateTime_utcCacheHit, utcHit);
3558     QCOMPARE(KADateTime_zoneCacheHit, zoneHit);
3559     KADateTime dt6a = dt3.toZone(cairo);
3560     ++zoneHit;
3561     QCOMPARE(KADateTime_utcCacheHit, utcHit);
3562     QCOMPARE(KADateTime_zoneCacheHit, zoneHit);
3563     dt3.detach();
3564     KADateTime dt7 = dt2.toZone(london);
3565     QCOMPARE(KADateTime_utcCacheHit, utcHit);
3566     QCOMPARE(KADateTime_zoneCacheHit, zoneHit);
3567     KADateTime dt7a = dt3.toZone(london);
3568     QCOMPARE(KADateTime_utcCacheHit, utcHit);
3569     QCOMPARE(KADateTime_zoneCacheHit, zoneHit);
3570 
3571     // Check that cached time zone conversions are cleared correctly
3572     KADateTime utc1(QDate(2005, 7, 6), QTime(3, 40, 0), KADateTime::UTC);
3573     KADateTime la1 = utc1.toTimeSpec(losAngeles);
3574     KADateTime utc2 = utc1.addDays(1);
3575     KADateTime la2 = utc2.toTimeSpec(losAngeles);
3576     QVERIFY(la1 != la2);
3577     QCOMPARE(la1.secsTo(la2), 86400);
3578 
3579     // Restore the original local time zone
3580     if (originalZone.isEmpty()) {
3581         unsetenv("TZ");
3582     } else {
3583         qputenv("TZ", originalZone);
3584     }
3585     ::tzset();
3586 }
3587 #endif /* COMPILING_TESTS */
3588 
stream()3589 void KADateTimeTest::stream()
3590 {
3591     // Ensure that local time is different from UTC and different from 'london'
3592     QByteArray originalZone = qgetenv("TZ");   // save the original local time zone
3593     qputenv("TZ", ":America/Los_Angeles");
3594     ::tzset();
3595 
3596     // Ensure that the original contents of the KADateTime receiving a streamed value
3597     // don't affect the new contents.
3598     QByteArray data;
3599     QDataStream ds(&data, QIODevice::ReadWrite);
3600     KADateTime testdt;
3601     KADateTime result;
3602 
3603     data.clear();
3604     testdt = KADateTime(QDate(2005, 6, 1), QTime(12, 0, 0), KADateTime::LocalZone);
3605     result = KADateTime::currentUtcDateTime();
3606     ds << testdt;
3607     ds.device()->seek(0);
3608     ds >> result;
3609     QCOMPARE(result, testdt);
3610 
3611     data.clear();
3612     testdt = KADateTime(QDate(2005, 6, 1), QTime(12, 0, 0), KADateTime::LocalZone);
3613     result = KADateTime::currentLocalDateTime();
3614     ds.device()->seek(0);
3615     ds << testdt;
3616     ds.device()->seek(0);
3617     ds >> result;
3618     QCOMPARE(result, testdt);
3619 
3620     data.clear();
3621     testdt = KADateTime(QDate(2006, 8, 30), QTime(7, 0, 0), KADateTime::UTC);
3622     result = KADateTime::currentUtcDateTime();
3623     ds.device()->seek(0);
3624     ds << testdt;
3625     ds.device()->seek(0);
3626     ds >> result;
3627     QCOMPARE(result, testdt);
3628 
3629     data.clear();
3630     testdt = KADateTime(QDate(2006, 8, 30), QTime(7, 0, 0), KADateTime::UTC);
3631     result = KADateTime::currentLocalDateTime();
3632     ds.device()->seek(0);
3633     ds << testdt;
3634     ds.device()->seek(0);
3635     ds >> result;
3636     QCOMPARE(result, testdt);
3637 
3638     // Restore the original local time zone
3639     if (originalZone.isEmpty()) {
3640         unsetenv("TZ");
3641     } else {
3642         qputenv("TZ", originalZone);
3643     }
3644     ::tzset();
3645 }
3646 
misc()3647 void KADateTimeTest::misc()
3648 {
3649     // Ensure that local time is different from UTC and different from 'london'
3650     QByteArray originalZone = qgetenv("TZ");   // save the original local time zone
3651     qputenv("TZ", ":America/Los_Angeles");
3652     ::tzset();
3653 
3654     KADateTime local = KADateTime::currentLocalDateTime();
3655     KADateTime utc = KADateTime::currentUtcDateTime();
3656     QDateTime qcurrent = QDateTime::currentDateTime();
3657     // Because 3 calls to fetch the current time were made, they will differ slightly
3658     KADateTime localUtc = local.toUtc();
3659     int diff = localUtc.secsTo(utc);
3660     if (diff > 1  ||  diff < 0) {
3661         QCOMPARE(local.toUtc().date(), utc.date());
3662         QCOMPARE(local.toUtc().time(), utc.time());
3663     }
3664     diff = local.qDateTime().secsTo(qcurrent);
3665     if (diff > 1  ||  diff < 0) {
3666         QCOMPARE(local.qDateTime(), qcurrent);
3667     }
3668 
3669     // Restore the original local time zone
3670     if (originalZone.isEmpty()) {
3671         unsetenv("TZ");
3672     } else {
3673         qputenv("TZ", originalZone);
3674     }
3675     ::tzset();
3676 }
3677 
3678 // vim: et sw=4:
3679