• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KDECore

  • kdecore
  • date
ktimezone.cpp
Go to the documentation of this file.
1/*
2 This file is part of the KDE libraries
3 Copyright (c) 2005-2008,2011 David Jarvie <djarvie@kde.org>
4 Copyright (c) 2005 S.R.Haque <srhaque@iee.org>.
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
20*/
21
22#include "ktimezone.h"
23
24#include <config.h>
25#include <config-date.h> // SIZEOF_TIME_T
26
27#ifdef HAVE_SYS_TIME_H
28#include <sys/time.h>
29#endif
30#ifdef HAVE_TIME_H
31#include <time.h>
32#endif
33#include <climits>
34#include <cstdlib>
35
36#include <QtCore/QSet>
37#include <QtCore/QSharedData>
38#include <QtCore/QCoreApplication>
39
40#include <kdebug.h>
41#include <kglobal.h>
42
43int gmtoff(time_t t); // defined in ksystemtimezone.cpp
44
45
46/******************************************************************************/
47
48class KTimeZonesPrivate
49{
50public:
51 KTimeZonesPrivate() {}
52
53 KTimeZones::ZoneMap zones;
54};
55
56
57KTimeZones::KTimeZones()
58 : d(new KTimeZonesPrivate)
59{
60}
61
62KTimeZones::~KTimeZones()
63{
64 delete d;
65}
66
67const KTimeZones::ZoneMap KTimeZones::zones() const
68{
69 return d->zones;
70}
71
72bool KTimeZones::add(const KTimeZone &zone)
73{
74 if (!zone.isValid())
75 return false;
76 if (d->zones.find(zone.name()) != d->zones.end())
77 return false; // name already exists
78 d->zones.insert(zone.name(), zone);
79 return true;
80}
81
82KTimeZone KTimeZones::remove(const KTimeZone &zone)
83{
84 if (zone.isValid())
85 {
86 for (ZoneMap::Iterator it = d->zones.begin(), end = d->zones.end(); it != end; ++it)
87 {
88 if (it.value() == zone)
89 {
90 d->zones.erase(it);
91 return zone;
92 }
93 }
94 }
95 return KTimeZone();
96}
97
98KTimeZone KTimeZones::remove(const QString &name)
99{
100 if (!name.isEmpty())
101 {
102 ZoneMap::Iterator it = d->zones.find(name);
103 if (it != d->zones.end())
104 {
105 KTimeZone zone = it.value();
106 d->zones.erase(it);
107 return zone;
108 }
109 }
110 return KTimeZone();
111}
112
113void KTimeZones::clear()
114{
115 d->zones.clear();
116}
117
118KTimeZone KTimeZones::zone(const QString &name) const
119{
120 if (!name.isEmpty())
121 {
122 ZoneMap::ConstIterator it = d->zones.constFind(name);
123 if (it != d->zones.constEnd())
124 return it.value();
125 if (name == KTimeZone::utc().name())
126 return KTimeZone::utc();
127 }
128 return KTimeZone(); // error
129}
130
131
132/******************************************************************************/
133
134class KTimeZonePhasePrivate : public QSharedData
135{
136 public:
137 QByteArray abbreviations; // time zone abbreviations (zero-delimited)
138 QString comment; // optional comment
139 int utcOffset; // seconds to add to UTC
140 bool dst; // true if daylight savings time
141
142 explicit KTimeZonePhasePrivate(int offset = 0, bool ds = false)
143 : QSharedData(),
144 utcOffset(offset),
145 dst(ds)
146 {}
147 KTimeZonePhasePrivate(const KTimeZonePhasePrivate& rhs)
148 : QSharedData(rhs),
149 abbreviations(rhs.abbreviations),
150 comment(rhs.comment),
151 utcOffset(rhs.utcOffset),
152 dst(rhs.dst)
153 {}
154 bool operator==(const KTimeZonePhasePrivate &rhs) const
155 {
156 return abbreviations == rhs.abbreviations
157 && comment == rhs.comment
158 && utcOffset == rhs.utcOffset
159 && dst == rhs.dst;
160 }
161};
162
163
164KTimeZone::Phase::Phase()
165 : d(new KTimeZonePhasePrivate)
166{
167}
168
169KTimeZone::Phase::Phase(int utcOffset, const QByteArray &abbrevs,
170 bool dst, const QString &cmt)
171 : d(new KTimeZonePhasePrivate(utcOffset, dst))
172{
173 d->abbreviations = abbrevs;
174 d->comment = cmt;
175}
176
177KTimeZone::Phase::Phase(int utcOffset, const QList<QByteArray> &abbrevs,
178 bool dst, const QString &cmt)
179 : d(new KTimeZonePhasePrivate(utcOffset, dst))
180{
181 for (int i = 0, end = abbrevs.count(); i < end; ++i)
182 {
183 if (i > 0)
184 d->abbreviations += '\0';
185 d->abbreviations += abbrevs[i];
186 }
187 d->comment = cmt;
188}
189
190KTimeZone::Phase::Phase(const KTimeZone::Phase &rhs)
191 : d(rhs.d)
192{
193}
194
195KTimeZone::Phase::~Phase()
196{
197}
198
199KTimeZone::Phase &KTimeZone::Phase::operator=(const KTimeZone::Phase &rhs)
200{
201 d = rhs.d;
202 return *this;
203}
204
205bool KTimeZone::Phase::operator==(const KTimeZone::Phase &rhs) const
206{
207 return d == rhs.d || *d == *rhs.d;
208}
209
210int KTimeZone::Phase::utcOffset() const
211{
212 return d->utcOffset;
213}
214
215QList<QByteArray> KTimeZone::Phase::abbreviations() const
216{
217 return d->abbreviations.split('\0');
218}
219
220bool KTimeZone::Phase::isDst() const
221{
222 return d->dst;
223}
224
225QString KTimeZone::Phase::comment() const
226{
227 return d->comment;
228}
229
230
231/******************************************************************************/
232
233class KTimeZoneTransitionPrivate
234{
235public:
236 QDateTime time;
237 KTimeZone::Phase phase;
238};
239
240
241KTimeZone::Transition::Transition()
242 : d(new KTimeZoneTransitionPrivate)
243{
244}
245
246KTimeZone::Transition::Transition(const QDateTime &t, const KTimeZone::Phase &p)
247 : d(new KTimeZoneTransitionPrivate)
248{
249 d->time = t;
250 d->phase = p;
251}
252
253KTimeZone::Transition::Transition(const KTimeZone::Transition &t)
254 : d(new KTimeZoneTransitionPrivate)
255{
256 d->time = t.d->time;
257 d->phase = t.d->phase;
258}
259
260KTimeZone::Transition::~Transition()
261{
262 delete d;
263}
264
265KTimeZone::Transition &KTimeZone::Transition::operator=(const KTimeZone::Transition &t)
266{
267 d->time = t.d->time;
268 d->phase = t.d->phase;
269 return *this;
270}
271
272bool KTimeZone::Transition::operator<(const KTimeZone::Transition &rhs) const
273{
274 return d->time < rhs.d->time;
275}
276
277QDateTime KTimeZone::Transition::time() const { return d->time; }
278KTimeZone::Phase KTimeZone::Transition::phase() const { return d->phase; }
279
280
281/******************************************************************************/
282
283class KTimeZoneDataPrivate
284{
285 public:
286 QList<KTimeZone::Phase> phases;
287 QList<KTimeZone::Transition> transitions;
288 QList<KTimeZone::LeapSeconds> leapChanges;
289 QList<int> utcOffsets;
290 QList<QByteArray> abbreviations;
291 KTimeZone::Phase prePhase; // phase to use before the first transition
292
293 KTimeZoneDataPrivate() {}
294 // Find the last transition before a specified UTC or local date/time.
295 int transitionIndex(const QDateTime &dt) const;
296 bool transitionIndexes(const QDateTime &start, const QDateTime &end, int &ixstart, int &ixend) const;
297 bool isSecondOccurrence(const QDateTime &utcLocalTime, int transitionIndex) const;
298};
299
300
301/******************************************************************************/
302
303class KTimeZonePrivate : public QSharedData
304{
305public:
306 KTimeZonePrivate() : source(0), data(0), refCount(1), cachedTransitionIndex(-1) {}
307 KTimeZonePrivate(KTimeZoneSource *src, const QString& nam,
308 const QString &country, float lat, float lon, const QString &cmnt);
309 KTimeZonePrivate(const KTimeZonePrivate &);
310 ~KTimeZonePrivate() { delete data; }
311 KTimeZonePrivate &operator=(const KTimeZonePrivate &);
312 static KTimeZoneSource *utcSource();
313 static void cleanup();
314
315 KTimeZoneSource *source;
316 QString name;
317 QString countryCode;
318 QString comment;
319 float latitude;
320 float longitude;
321 mutable KTimeZoneData *data;
322 int refCount; // holds the number of KTimeZoneBackend instances using the KTimeZonePrivate instance as a d-pointer.
323 int cachedTransitionIndex;
324 QDateTime cachedTransitionStartZoneTime;
325 QDateTime cachedTransitionEndZoneTime;
326 bool cachedTransitionTimesValid;
327
328private:
329 static KTimeZoneSource *mUtcSource;
330};
331
332KTimeZoneSource *KTimeZonePrivate::mUtcSource = 0;
333
334
335KTimeZonePrivate::KTimeZonePrivate(KTimeZoneSource *src, const QString& nam,
336 const QString &country, float lat, float lon, const QString &cmnt)
337 : source(src),
338 name(nam),
339 countryCode(country.toUpper()),
340 comment(cmnt),
341 latitude(lat),
342 longitude(lon),
343 data(0),
344 refCount(1),
345 cachedTransitionIndex(-1)
346{
347 // Detect duff values.
348 if (latitude > 90 || latitude < -90)
349 latitude = KTimeZone::UNKNOWN;
350 if (longitude > 180 || longitude < -180)
351 longitude = KTimeZone::UNKNOWN;
352}
353
354KTimeZonePrivate::KTimeZonePrivate(const KTimeZonePrivate &rhs)
355 : QSharedData(rhs),
356 source(rhs.source),
357 name(rhs.name),
358 countryCode(rhs.countryCode),
359 comment(rhs.comment),
360 latitude(rhs.latitude),
361 longitude(rhs.longitude),
362 refCount(1),
363 cachedTransitionIndex(rhs.cachedTransitionIndex),
364 cachedTransitionStartZoneTime(rhs.cachedTransitionStartZoneTime),
365 cachedTransitionEndZoneTime(rhs.cachedTransitionEndZoneTime),
366 cachedTransitionTimesValid(rhs.cachedTransitionTimesValid)
367{
368 if (rhs.data)
369 data = rhs.data->clone();
370 else
371 data = 0;
372}
373
374KTimeZonePrivate &KTimeZonePrivate::operator=(const KTimeZonePrivate &rhs)
375{
376 // Changing the contents of a KTimeZonePrivate instance by means of operator=() doesn't affect how
377 // many references to it are held.
378 source = rhs.source;
379 name = rhs.name;
380 countryCode = rhs.countryCode;
381 comment = rhs.comment;
382 latitude = rhs.latitude;
383 longitude = rhs.longitude;
384 cachedTransitionIndex = rhs.cachedTransitionIndex;
385 cachedTransitionStartZoneTime = rhs.cachedTransitionStartZoneTime;
386 cachedTransitionEndZoneTime = rhs.cachedTransitionEndZoneTime;
387 cachedTransitionTimesValid = rhs.cachedTransitionTimesValid;
388 delete data;
389 if (rhs.data)
390 data = rhs.data->clone();
391 else
392 data = 0;
393 // refCount is unchanged
394 return *this;
395}
396
397KTimeZoneSource *KTimeZonePrivate::utcSource()
398{
399 if (!mUtcSource)
400 {
401 mUtcSource = new KTimeZoneSource;
402 qAddPostRoutine(KTimeZonePrivate::cleanup);
403 }
404 return mUtcSource;
405}
406
407void KTimeZonePrivate::cleanup()
408{
409 delete mUtcSource;
410}
411
412
413/******************************************************************************/
414
415K_GLOBAL_STATIC(KTimeZonePrivate, s_emptyTimeZonePrivate)
416
417KTimeZoneBackend::KTimeZoneBackend()
418 : d(&*s_emptyTimeZonePrivate)
419{
420 ++d->refCount;
421}
422
423KTimeZoneBackend::KTimeZoneBackend(const QString &name)
424 : d(new KTimeZonePrivate(KTimeZonePrivate::utcSource(), name, QString(), KTimeZone::UNKNOWN, KTimeZone::UNKNOWN, QString()))
425{}
426
427KTimeZoneBackend::KTimeZoneBackend(KTimeZoneSource *source, const QString &name,
428 const QString &countryCode, float latitude, float longitude, const QString &comment)
429 : d(new KTimeZonePrivate(source, name, countryCode, latitude, longitude, comment))
430{}
431
432KTimeZoneBackend::KTimeZoneBackend(const KTimeZoneBackend &other)
433 : d(other.d)
434{
435 ++d->refCount;
436}
437
438KTimeZoneBackend::~KTimeZoneBackend()
439{
440 if (d && --d->refCount == 0)
441 delete d;
442 d = 0;
443}
444
445KTimeZoneBackend &KTimeZoneBackend::operator=(const KTimeZoneBackend &other)
446{
447 if (d != other.d)
448 {
449 if (--d->refCount == 0)
450 delete d;
451 d = other.d;
452 ++d->refCount;
453 }
454 return *this;
455}
456
457QByteArray KTimeZoneBackend::type() const
458{
459 return "KTimeZone";
460}
461
462KTimeZoneBackend *KTimeZoneBackend::clone() const
463{
464 return new KTimeZoneBackend(*this);
465}
466
467int KTimeZoneBackend::offsetAtZoneTime(const KTimeZone* caller, const QDateTime &zoneDateTime, int *secondOffset) const
468{
469 if (!zoneDateTime.isValid() || zoneDateTime.timeSpec() != Qt::LocalTime) // check for invalid time
470 {
471 if (secondOffset)
472 *secondOffset = 0;
473 return 0;
474 }
475 const QList<KTimeZone::Transition> transitions = caller->transitions();
476 int index = d->cachedTransitionIndex;
477 if (index >= 0 && index < transitions.count())
478 {
479 // There is a cached transition - check whether zoneDateTime uses it.
480 // Caching is used because this method has been found to consume
481 // significant CPU in real life applications.
482 if (!d->cachedTransitionTimesValid)
483 {
484 const int offset = transitions[index].phase().utcOffset();
485 const int preoffset = (index > 0) ? transitions[index - 1].phase().utcOffset() : d->data ? d->data->previousUtcOffset() : 0;
486 d->cachedTransitionStartZoneTime = transitions[index].time().addSecs(qMax(offset, preoffset));
487 if (index + 1 < transitions.count())
488 {
489 const int postoffset = transitions[index + 1].phase().utcOffset();
490 d->cachedTransitionEndZoneTime = transitions[index + 1].time().addSecs(qMin(offset, postoffset));
491 }
492 d->cachedTransitionTimesValid = true;
493 }
494 QDateTime dtutc = zoneDateTime;
495 dtutc.setTimeSpec(Qt::UTC);
496 if (dtutc >= d->cachedTransitionStartZoneTime
497 && (index + 1 >= transitions.count() || dtutc < d->cachedTransitionEndZoneTime))
498 {
499 // The time falls within the cached transition limits, so return its UTC offset
500 const int offset = transitions[index].phase().utcOffset();
501 if (secondOffset)
502 *secondOffset = offset;
503#ifdef COMPILING_TESTS
504 kDebug(161) << "-> Using cache"; // enable the debug area to see this in the tests
505#endif
506 return offset;
507 }
508 }
509
510 // The time doesn't fall within the cached transition, or there isn't a cached transition
511#ifdef COMPILING_TESTS
512 kDebug(161) << "-> No cache"; // enable the debug area to see this in the tests
513#endif
514 bool validTime;
515 int secondIndex = -1;
516 index = caller->transitionIndex(zoneDateTime, (secondOffset ? &secondIndex : 0), &validTime);
517 const KTimeZone::Transition* tr = (index >= 0) ? &transitions[index] : 0;
518 const int offset = tr ? tr->phase().utcOffset()
519 : validTime ? (d->data ? d->data->previousUtcOffset() : 0)
520 : KTimeZone::InvalidOffset;
521 if (secondOffset)
522 *secondOffset = (secondIndex >= 0) ? transitions.at(secondIndex).phase().utcOffset() : offset;
523
524 // Cache transition data for subsequent date/time values which occur after the same transition.
525 d->cachedTransitionIndex = index;
526 d->cachedTransitionTimesValid = false;
527 return offset;
528}
529
530int KTimeZoneBackend::offsetAtUtc(const KTimeZone* caller, const QDateTime &utcDateTime) const
531{
532 if (!utcDateTime.isValid() || utcDateTime.timeSpec() != Qt::UTC) // check for invalid time
533 return 0;
534 const QList<KTimeZone::Transition> transitions = caller->transitions();
535 int index = d->cachedTransitionIndex;
536 if (index >= 0 && index < transitions.count())
537 {
538 // There is a cached transition - check whether utcDateTime uses it.
539 if (utcDateTime >= transitions[index].time()
540 && (index + 1 >= transitions.count()
541 || utcDateTime < transitions[index + 1].time()))
542 {
543 // The time falls within the cached transition, so return its UTC offset
544#ifdef COMPILING_TESTS
545 kDebug(161) << "Using cache"; // enable the debug area to see this in the tests
546#endif
547 return transitions[index].phase().utcOffset();
548 }
549 }
550
551 // The time doesn't fall within the cached transition, or there isn't a cached transition
552#ifdef COMPILING_TESTS
553 kDebug(161) << "No cache"; // enable the debug area to see this in the tests
554#endif
555 index = caller->transitionIndex(utcDateTime);
556 d->cachedTransitionIndex = index; // cache transition data
557 d->cachedTransitionTimesValid = false;
558 const KTimeZone::Transition* tr = (index >= 0) ? &transitions.at(index) : 0;
559 return tr ? tr->phase().utcOffset() : (d->data ? d->data->previousUtcOffset() : 0);
560}
561
562int KTimeZoneBackend::offset(const KTimeZone* caller, time_t t) const
563{
564 return offsetAtUtc(caller, KTimeZone::fromTime_t(t));
565}
566
567bool KTimeZoneBackend::isDstAtUtc(const KTimeZone* caller, const QDateTime &utcDateTime) const
568{
569 if (!utcDateTime.isValid() || utcDateTime.timeSpec() != Qt::UTC) // check for invalid time
570 return false;
571 const KTimeZone::Transition *tr = caller->transition(utcDateTime);
572 if (!tr)
573 return false;
574 return tr->phase().isDst();
575}
576
577bool KTimeZoneBackend::isDst(const KTimeZone* caller, time_t t) const
578{
579 return isDstAtUtc(caller, KTimeZone::fromTime_t(t));
580}
581
582bool KTimeZoneBackend::hasTransitions(const KTimeZone* caller) const
583{
584 Q_UNUSED(caller);
585 return false;
586}
587
588
589/******************************************************************************/
590
591#if SIZEOF_TIME_T == 8
592const time_t KTimeZone::InvalidTime_t = 0x800000000000000LL;
593#else
594const time_t KTimeZone::InvalidTime_t = 0x80000000;
595#endif
596const int KTimeZone::InvalidOffset = 0x80000000;
597const float KTimeZone::UNKNOWN = 1000.0;
598
599
600KTimeZone::KTimeZone()
601 : d(new KTimeZoneBackend())
602{}
603
604KTimeZone::KTimeZone(const QString &name)
605 : d(new KTimeZoneBackend(name))
606{}
607
608KTimeZone::KTimeZone(const KTimeZone &tz)
609 : d(tz.d->clone())
610{}
611
612KTimeZone::~KTimeZone()
613{
614 delete d;
615}
616
617KTimeZone::KTimeZone(KTimeZoneBackend *impl)
618 : d(impl)
619{
620 // 'impl' should be a newly constructed object, with refCount = 1
621 Q_ASSERT(d->d->refCount == 1 || d->d == &*s_emptyTimeZonePrivate);
622}
623
624KTimeZone &KTimeZone::operator=(const KTimeZone &tz)
625{
626 if (d != tz.d)
627 {
628 delete d;
629 d = tz.d->clone();
630 }
631 return *this;
632}
633
634bool KTimeZone::operator==(const KTimeZone &rhs) const
635{
636 return d->d == rhs.d->d;
637}
638
639QByteArray KTimeZone::type() const
640{
641 return d->type();
642}
643
644bool KTimeZone::isValid() const
645{
646 return !d->d->name.isEmpty();
647}
648
649QString KTimeZone::countryCode() const
650{
651 return d->d->countryCode;
652}
653
654float KTimeZone::latitude() const
655{
656 return d->d->latitude;
657}
658
659float KTimeZone::longitude() const
660{
661 return d->d->longitude;
662}
663
664QString KTimeZone::comment() const
665{
666 return d->d->comment;
667}
668
669QString KTimeZone::name() const
670{
671 return d->d->name;
672}
673
674QList<QByteArray> KTimeZone::abbreviations() const
675{
676 if (!data(true))
677 return QList<QByteArray>();
678 return d->d->data->abbreviations();
679}
680
681QByteArray KTimeZone::abbreviation(const QDateTime &utcDateTime) const
682{
683 if (utcDateTime.timeSpec() != Qt::UTC || !data(true))
684 return QByteArray();
685 return d->d->data->abbreviation(utcDateTime);
686}
687
688QList<int> KTimeZone::utcOffsets() const
689{
690 if (!data(true))
691 return QList<int>();
692 return d->d->data->utcOffsets();
693}
694
695QList<KTimeZone::Phase> KTimeZone::phases() const
696{
697 if (!data(true))
698 return QList<KTimeZone::Phase>();
699 return d->d->data->phases();
700}
701
702bool KTimeZone::hasTransitions() const
703{
704 return d->hasTransitions(this);
705}
706
707QList<KTimeZone::Transition> KTimeZone::transitions(const QDateTime &start, const QDateTime &end) const
708{
709 if (!data(true))
710 return QList<KTimeZone::Transition>();
711 return d->d->data->transitions(start, end);
712}
713
714const KTimeZone::Transition *KTimeZone::transition(const QDateTime &dt, const Transition **secondTransition,
715 bool *validTime) const
716{
717 if (!data(true)) {
718 if (validTime)
719 *validTime = false;
720 return 0;
721 }
722 return d->d->data->transition(dt, secondTransition, validTime);
723}
724
725int KTimeZone::transitionIndex(const QDateTime &dt, int *secondIndex, bool *validTime) const
726{
727 if (!data(true)) {
728 if (validTime)
729 *validTime = false;
730 return -1;
731 }
732 return d->d->data->transitionIndex(dt, secondIndex, validTime);
733}
734
735QList<QDateTime> KTimeZone::transitionTimes(const Phase &phase, const QDateTime &start, const QDateTime &end) const
736{
737 if (!data(true))
738 return QList<QDateTime>();
739 return d->d->data->transitionTimes(phase, start, end);
740}
741
742QList<KTimeZone::LeapSeconds> KTimeZone::leapSecondChanges() const
743{
744 if (!data(true))
745 return QList<KTimeZone::LeapSeconds>();
746 return d->d->data->leapSecondChanges();
747}
748
749KTimeZoneSource *KTimeZone::source() const
750{
751 return d->d->source;
752}
753
754const KTimeZoneData *KTimeZone::data(bool create) const
755{
756 if (!isValid())
757 return 0;
758 if (create && !d->d->data && d->d->source->useZoneParse())
759 d->d->data = d->d->source->parse(*this);
760 return d->d->data;
761}
762
763void KTimeZone::setData(KTimeZoneData *data, KTimeZoneSource *source)
764{
765 if (!isValid())
766 return;
767 delete d->d->data;
768 d->d->data = data;
769 if (source)
770 d->d->source = source;
771}
772
773bool KTimeZone::updateBase(const KTimeZone &other)
774{
775 if (d->d->name.isEmpty() || d->d->name != other.d->d->name)
776 return false;
777 d->d->countryCode = other.d->d->countryCode;
778 d->d->comment = other.d->d->comment;
779 d->d->latitude = other.d->d->latitude;
780 d->d->longitude = other.d->d->longitude;
781 return true;
782}
783
784bool KTimeZone::parse() const
785{
786 if (!isValid())
787 return false;
788 if (d->d->source->useZoneParse())
789 {
790 delete d->d->data;
791 d->d->data = d->d->source->parse(*this);
792 }
793 return d->d->data;
794}
795
796QDateTime KTimeZone::toUtc(const QDateTime &zoneDateTime) const
797{
798 if (!zoneDateTime.isValid() || zoneDateTime.timeSpec() != Qt::LocalTime)
799 return QDateTime();
800 const int secs = offsetAtZoneTime(zoneDateTime);
801 if (secs == InvalidOffset)
802 return QDateTime();
803 QDateTime dt = zoneDateTime;
804 dt.setTimeSpec(Qt::UTC);
805 return dt.addSecs(-secs);
806}
807
808QDateTime KTimeZone::toZoneTime(const QDateTime &utcDateTime, bool *secondOccurrence) const
809{
810 if (secondOccurrence)
811 *secondOccurrence = false;
812 if (!utcDateTime.isValid() || utcDateTime.timeSpec() != Qt::UTC) // check for invalid time
813 return QDateTime();
814
815 // Convert UTC to local time
816 if (hasTransitions())
817 {
818 if (!data(true))
819 {
820 // No data - default to UTC
821 QDateTime dt = utcDateTime;
822 dt.setTimeSpec(Qt::LocalTime);
823 return dt;
824 }
825
826 const KTimeZoneData *data = d->d->data;
827 const int index = data->transitionIndex(utcDateTime);
828 const int secs = (index >= 0) ? data->transitions().at(index).phase().utcOffset() : data->previousUtcOffset();
829 QDateTime dt = utcDateTime.addSecs(secs);
830 if (secondOccurrence)
831 {
832 // Check whether the local time occurs twice around a daylight savings time
833 // shift, and if so, whether it's the first or second occurrence.
834 *secondOccurrence = data->d->isSecondOccurrence(dt, index);
835 }
836 dt.setTimeSpec(Qt::LocalTime);
837 return dt;
838 }
839 else
840 {
841 const int secs = offsetAtUtc(utcDateTime);
842 QDateTime dt = utcDateTime.addSecs(secs);
843 dt.setTimeSpec(Qt::LocalTime);
844 if (secondOccurrence)
845 {
846 // Check whether the local time occurs twice around a daylight savings time
847 // shift, and if so, whether it's the first or second occurrence.
848 *secondOccurrence = (secs != offsetAtZoneTime(dt));
849 }
850 return dt;
851 }
852}
853
854QDateTime KTimeZone::convert(const KTimeZone &newZone, const QDateTime &zoneDateTime) const
855{
856 if (newZone == *this)
857 {
858 if (zoneDateTime.timeSpec() != Qt::LocalTime)
859 return QDateTime();
860 return zoneDateTime;
861 }
862 return newZone.toZoneTime(toUtc(zoneDateTime));
863}
864
865int KTimeZone::offsetAtZoneTime(const QDateTime &zoneDateTime, int *secondOffset) const
866{
867 return d->offsetAtZoneTime(this, zoneDateTime, secondOffset);
868}
869
870int KTimeZone::offsetAtUtc(const QDateTime &utcDateTime) const
871{
872 return d->offsetAtUtc(this, utcDateTime);
873}
874
875int KTimeZone::offset(time_t t) const
876{
877 return d->offset(this, t);
878}
879
880int KTimeZone::currentOffset(Qt::TimeSpec basis) const
881{
882 // Get current offset of this time zone to UTC
883 const time_t now = time(0);
884 const int secs = offset(now);
885
886 switch (basis)
887 {
888 case Qt::LocalTime:
889 // Return the current offset of this time zone to the local system time
890 return secs - gmtoff(now);
891 case Qt::UTC:
892 // Return the current offset of this time zone to UTC
893 return secs;
894
895 default:
896 break;
897 }
898 return 0;
899}
900
901bool KTimeZone::isDstAtUtc(const QDateTime &utcDateTime) const
902{
903 return d->isDstAtUtc(this, utcDateTime);
904}
905
906bool KTimeZone::isDst(time_t t) const
907{
908 return d->isDst(this, t);
909}
910
911KTimeZone KTimeZone::utc()
912{
913 static KTimeZone utcZone(QLatin1String("UTC"));
914 return utcZone;
915}
916
917QDateTime KTimeZone::fromTime_t(time_t t)
918{
919 static const int secondsADay = 86400;
920 static const QDate epochDate(1970,1,1);
921 static const QTime epochTime(0,0,0);
922 int days = t / secondsADay;
923 int secs;
924 if (t >= 0)
925 secs = t % secondsADay;
926 else
927 {
928 secs = secondsADay - (-t % secondsADay);
929 --days;
930 }
931 return QDateTime(epochDate.addDays(days), epochTime.addSecs(secs), Qt::UTC);
932}
933
934time_t KTimeZone::toTime_t(const QDateTime &utcDateTime)
935{
936 static const QDate epochDate(1970,1,1);
937 static const QTime epochTime(0,0,0);
938 if (utcDateTime.timeSpec() != Qt::UTC)
939 return InvalidTime_t;
940 const qint64 days = epochDate.daysTo(utcDateTime.date());
941 const qint64 secs = epochTime.secsTo(utcDateTime.time());
942 const qint64 t64 = days * 86400 + secs;
943 const time_t t = static_cast<time_t>(t64);
944 if (static_cast<qint64>(t) != t64)
945 return InvalidTime_t;
946 return t;
947}
948
949
950/******************************************************************************/
951
952class KTimeZoneSourcePrivate
953{
954public:
955 bool mUseZoneParse;
956};
957
958
959KTimeZoneSource::KTimeZoneSource()
960 : d(new KTimeZoneSourcePrivate)
961{
962 d->mUseZoneParse = true;
963}
964
965KTimeZoneSource::KTimeZoneSource(bool useZoneParse)
966 : d(new KTimeZoneSourcePrivate)
967{
968 d->mUseZoneParse = useZoneParse;
969}
970
971KTimeZoneSource::~KTimeZoneSource()
972{
973 delete d;
974}
975
976KTimeZoneData *KTimeZoneSource::parse(const KTimeZone &) const
977{
978 Q_ASSERT(d->mUseZoneParse); // method should never be called if it isn't usable
979 return new KTimeZoneData;
980}
981
982bool KTimeZoneSource::useZoneParse() const
983{
984 return d->mUseZoneParse;
985}
986
987
988/******************************************************************************/
989
990class KTimeZoneLeapSecondsPrivate
991{
992 public:
993 QDateTime dt; // UTC time when this change occurred
994 QString comment; // optional comment
995 int seconds; // number of leap seconds
996};
997
998
999KTimeZone::LeapSeconds::LeapSeconds()
1000 : d(new KTimeZoneLeapSecondsPrivate)
1001{
1002}
1003
1004KTimeZone::LeapSeconds::LeapSeconds(const QDateTime &utc, int leap, const QString &cmt)
1005 : d(new KTimeZoneLeapSecondsPrivate)
1006{
1007 if (utc.timeSpec() == Qt::UTC) // invalid if start time is not UTC
1008 {
1009 d->dt = utc;
1010 d->comment = cmt;
1011 d->seconds = leap;
1012 }
1013}
1014
1015KTimeZone::LeapSeconds::LeapSeconds(const KTimeZone::LeapSeconds &c)
1016 : d(new KTimeZoneLeapSecondsPrivate)
1017{
1018 d->dt = c.d->dt;
1019 d->comment = c.d->comment;
1020 d->seconds = c.d->seconds;
1021}
1022
1023KTimeZone::LeapSeconds::~LeapSeconds()
1024{
1025 delete d;
1026}
1027
1028KTimeZone::LeapSeconds &KTimeZone::LeapSeconds::operator=(const KTimeZone::LeapSeconds &c)
1029{
1030 d->dt = c.d->dt;
1031 d->comment = c.d->comment;
1032 d->seconds = c.d->seconds;
1033 return *this;
1034}
1035
1036bool KTimeZone::LeapSeconds::operator<(const KTimeZone::LeapSeconds& c) const
1037{
1038 return d->dt < c.d->dt;
1039}
1040
1041QDateTime KTimeZone::LeapSeconds::dateTime() const
1042{
1043 return d->dt;
1044}
1045
1046bool KTimeZone::LeapSeconds::isValid() const
1047{
1048 return d->dt.isValid();
1049}
1050
1051int KTimeZone::LeapSeconds::leapSeconds() const
1052{
1053 return d->seconds;
1054}
1055
1056QString KTimeZone::LeapSeconds::comment() const
1057{
1058 return d->comment;
1059}
1060
1061
1062/******************************************************************************/
1063
1064
1065int KTimeZoneDataPrivate::transitionIndex(const QDateTime &dt) const
1066{
1067 // Do a binary search to find the last transition before this date/time
1068 int start = -1;
1069 int end = transitions.count();
1070 if (dt.timeSpec() == Qt::UTC)
1071 {
1072 while (end - start > 1)
1073 {
1074 int i = (start + end) / 2;
1075 if (dt < transitions[i].time())
1076 end = i;
1077 else
1078 start = i;
1079 }
1080 }
1081 else
1082 {
1083 QDateTime dtutc = dt;
1084 dtutc.setTimeSpec(Qt::UTC);
1085 while (end - start > 1)
1086 {
1087 const int i = (start + end) / 2;
1088 if (dtutc.addSecs(-transitions[i].phase().utcOffset()) < transitions[i].time())
1089 end = i;
1090 else
1091 start = i;
1092 }
1093 }
1094 return end ? start : -1;
1095}
1096
1097// Find the indexes to the transitions at or after start, and before or at end.
1098// start and end must be UTC.
1099// Reply = false if none.
1100bool KTimeZoneDataPrivate::transitionIndexes(const QDateTime &start, const QDateTime &end, int &ixstart, int &ixend) const
1101{
1102 ixstart = 0;
1103 if (start.isValid() && start.timeSpec() == Qt::UTC)
1104 {
1105 ixstart = transitionIndex(start);
1106 if (ixstart < 0)
1107 ixstart = 0;
1108 else if (transitions[ixstart].time() < start)
1109 {
1110 if (++ixstart >= transitions.count())
1111 return false; // there are no transitions at/after 'start'
1112 }
1113 }
1114 ixend = -1;
1115 if (end.isValid() && end.timeSpec() == Qt::UTC)
1116 {
1117 ixend = transitionIndex(end);
1118 if (ixend < 0)
1119 return false; // there are no transitions at/before 'end'
1120 }
1121 return true;
1122}
1123
1124/* Check if it's a local time which occurs both before and after the specified
1125 * transition (for which it has to span a daylight saving to standard time change).
1126 * @param utcLocalTime local time set to Qt::UTC
1127 */
1128bool KTimeZoneDataPrivate::isSecondOccurrence(const QDateTime &utcLocalTime, int transitionIndex) const
1129{
1130 if (transitionIndex < 0)
1131 return false;
1132 const int offset = transitions[transitionIndex].phase().utcOffset();
1133 const int prevoffset = (transitionIndex > 0) ? transitions[transitionIndex-1].phase().utcOffset() : prePhase.utcOffset();
1134 const int phaseDiff = prevoffset - offset;
1135 if (phaseDiff <= 0)
1136 return false;
1137 // Find how long after the start of the latest phase 'dt' is
1138 const qint64 afterStart = transitions[transitionIndex].time().msecsTo(utcLocalTime)/1000 - offset;
1139 return (afterStart < phaseDiff);
1140}
1141
1142
1143
1144KTimeZoneData::KTimeZoneData()
1145 : d(new KTimeZoneDataPrivate)
1146{ }
1147
1148KTimeZoneData::KTimeZoneData(const KTimeZoneData &c)
1149 : d(new KTimeZoneDataPrivate)
1150{
1151 d->phases = c.d->phases;
1152 d->transitions = c.d->transitions;
1153 d->leapChanges = c.d->leapChanges;
1154 d->utcOffsets = c.d->utcOffsets;
1155 d->abbreviations = c.d->abbreviations;
1156 d->prePhase = c.d->prePhase;
1157}
1158
1159KTimeZoneData::~KTimeZoneData()
1160{
1161 delete d;
1162}
1163
1164KTimeZoneData &KTimeZoneData::operator=(const KTimeZoneData &c)
1165{
1166 d->phases = c.d->phases;
1167 d->transitions = c.d->transitions;
1168 d->leapChanges = c.d->leapChanges;
1169 d->utcOffsets = c.d->utcOffsets;
1170 d->abbreviations = c.d->abbreviations;
1171 d->prePhase = c.d->prePhase;
1172 return *this;
1173}
1174
1175KTimeZoneData *KTimeZoneData::clone() const
1176{
1177 return new KTimeZoneData(*this);
1178}
1179
1180QList<QByteArray> KTimeZoneData::abbreviations() const
1181{
1182 if (d->abbreviations.isEmpty())
1183 {
1184 for (int i = 0, end = d->phases.count(); i < end; ++i)
1185 {
1186 const QList<QByteArray> abbrevs = d->phases[i].abbreviations();
1187 for (int j = 0, jend = abbrevs.count(); j < jend; ++j)
1188 if (!d->abbreviations.contains(abbrevs[j]))
1189 d->abbreviations.append(abbrevs[j]);
1190 }
1191 if (d->abbreviations.isEmpty())
1192 d->abbreviations += "UTC";
1193 }
1194 return d->abbreviations;
1195}
1196
1197QByteArray KTimeZoneData::abbreviation(const QDateTime &utcDateTime) const
1198{
1199 if (d->phases.isEmpty())
1200 return "UTC";
1201 const KTimeZone::Transition *tr = transition(utcDateTime);
1202 const QList<QByteArray> abbrevs = tr ? tr->phase().abbreviations()
1203 : d->prePhase.abbreviations();
1204 if (abbrevs.isEmpty())
1205 return QByteArray();
1206 return abbrevs[0];
1207}
1208
1209QList<int> KTimeZoneData::utcOffsets() const
1210{
1211 if (d->utcOffsets.isEmpty())
1212 {
1213 for (int i = 0, end = d->phases.count(); i < end; ++i)
1214 {
1215 const int offset = d->phases[i].utcOffset();
1216 if (!d->utcOffsets.contains(offset))
1217 d->utcOffsets.append(offset);
1218 }
1219 if (d->utcOffsets.isEmpty())
1220 d->utcOffsets += 0;
1221 else
1222 qSort(d->utcOffsets);
1223 }
1224 return d->utcOffsets;
1225}
1226
1227QList<KTimeZone::Phase> KTimeZoneData::phases() const
1228{
1229 return d->phases;
1230}
1231
1232void KTimeZoneData::setPhases(const QList<KTimeZone::Phase> &phases, const KTimeZone::Phase& previousPhase)
1233{
1234 d->phases = phases;
1235 d->prePhase = previousPhase;
1236}
1237
1238void KTimeZoneData::setPhases(const QList<KTimeZone::Phase> &phases, int previousUtcOffset)
1239{
1240 d->phases = phases;
1241 d->prePhase = KTimeZone::Phase(previousUtcOffset, QByteArray(), false);
1242}
1243
1244bool KTimeZoneData::hasTransitions() const
1245{
1246 return false;
1247}
1248
1249QList<KTimeZone::Transition> KTimeZoneData::transitions(const QDateTime &start, const QDateTime &end) const
1250{
1251 int ixstart, ixend;
1252 if (!d->transitionIndexes(start, end, ixstart, ixend))
1253 return QList<KTimeZone::Transition>(); // there are no transitions within the time period
1254 if (ixend >= 0)
1255 return d->transitions.mid(ixstart, ixend - ixstart + 1);
1256 if (ixstart > 0)
1257 return d->transitions.mid(ixstart);
1258 return d->transitions;
1259}
1260
1261void KTimeZoneData::setTransitions(const QList<KTimeZone::Transition> &transitions)
1262{
1263 d->transitions = transitions;
1264}
1265
1266int KTimeZoneData::previousUtcOffset() const
1267{
1268 return d->prePhase.utcOffset();
1269}
1270
1271const KTimeZone::Transition *KTimeZoneData::transition(const QDateTime &dt, const KTimeZone::Transition **secondTransition,
1272 bool *validTime) const
1273{
1274 int secondIndex;
1275 const int index = transitionIndex(dt, (secondTransition ? &secondIndex : 0), validTime);
1276 if (secondTransition)
1277 *secondTransition = (secondIndex >= 0) ? &d->transitions[secondIndex] : 0;
1278 return (index >= 0) ? &d->transitions[index] : 0;
1279}
1280
1281int KTimeZoneData::transitionIndex(const QDateTime &dt, int *secondIndex, bool *validTime) const
1282{
1283 if (validTime)
1284 *validTime = true;
1285
1286 // Find the last transition before this date/time
1287 int index = d->transitionIndex(dt);
1288 if (dt.timeSpec() == Qt::UTC)
1289 {
1290 if (secondIndex)
1291 *secondIndex = index;
1292 return index;
1293 }
1294 else
1295 {
1296 /* Check whether the specified local time actually occurs.
1297 * Find the start of the next phase, and check if it falls in the gap
1298 * between the two phases.
1299 */
1300 QDateTime dtutc = dt;
1301 dtutc.setTimeSpec(Qt::UTC);
1302 const int count = d->transitions.count();
1303 const int next = (index >= 0) ? index + 1 : 0;
1304 if (next < count)
1305 {
1306 KTimeZone::Phase nextPhase = d->transitions[next].phase();
1307 const int offset = (index >= 0) ? d->transitions[index].phase().utcOffset() : d->prePhase.utcOffset();
1308 const int phaseDiff = nextPhase.utcOffset() - offset;
1309 if (phaseDiff > 0)
1310 {
1311 // Get UTC equivalent as if 'dt' was in the next phase
1312 if (dtutc.msecsTo(d->transitions[next].time())/1000 + nextPhase.utcOffset() <= phaseDiff)
1313 {
1314 // The time falls in the gap between the two phases,
1315 // so return an invalid value.
1316 if (validTime)
1317 *validTime = false;
1318 if (secondIndex)
1319 *secondIndex = -1;
1320 return -1;
1321 }
1322 }
1323 }
1324
1325 if (index < 0)
1326 {
1327 // The specified time is before the first phase
1328 if (secondIndex)
1329 *secondIndex = -1;
1330 return -1;
1331 }
1332
1333 /* Check if it's a local time which occurs both before and after the 'latest'
1334 * phase start time (for which it has to span a daylight saving to standard
1335 * time change).
1336 */
1337 bool duplicate = true;
1338 if (d->isSecondOccurrence(dtutc, index))
1339 {
1340 // 'dt' occurs twice
1341 if (secondIndex)
1342 {
1343 *secondIndex = index;
1344 duplicate = false;
1345 }
1346 // Get the transition containing the first occurrence of 'dt'
1347 if (index <= 0)
1348 return -1; // first occurrence of 'dt' is just before the first transition
1349 --index;
1350 }
1351
1352 if (secondIndex && duplicate)
1353 *secondIndex = index;
1354 return index;
1355 }
1356}
1357
1358QList<QDateTime> KTimeZoneData::transitionTimes(const KTimeZone::Phase &phase, const QDateTime &start, const QDateTime &end) const
1359{
1360 QList<QDateTime> times;
1361 int ixstart, ixend;
1362 if (d->transitionIndexes(start, end, ixstart, ixend))
1363 {
1364 if (ixend < 0)
1365 ixend = d->transitions.count() - 1;
1366 while (ixstart <= ixend)
1367 {
1368 if (d->transitions[ixstart].phase() == phase)
1369 times += d->transitions[ixstart].time();
1370 }
1371 }
1372 return times;
1373}
1374
1375QList<KTimeZone::LeapSeconds> KTimeZoneData::leapSecondChanges() const
1376{
1377 return d->leapChanges;
1378}
1379
1380void KTimeZoneData::setLeapSecondChanges(const QList<KTimeZone::LeapSeconds> &adjusts)
1381{
1382 d->leapChanges = adjusts;
1383}
1384
1385KTimeZone::LeapSeconds KTimeZoneData::leapSecondChange(const QDateTime &utc) const
1386{
1387 if (utc.timeSpec() != Qt::UTC)
1388 kError() << "KTimeZoneData::leapSecondChange(): non-UTC time specified" << endl;
1389 else
1390 {
1391 for (int i = d->leapChanges.count(); --i >= 0; )
1392 {
1393 if (d->leapChanges[i].dateTime() < utc)
1394 return d->leapChanges[i];
1395 }
1396 }
1397 return KTimeZone::LeapSeconds();
1398}
KTimeZoneBackend
Base backend class for KTimeZone classes.
Definition: ktimezone.h:1121
KTimeZoneBackend::offsetAtUtc
virtual int offsetAtUtc(const KTimeZone *caller, const QDateTime &utcDateTime) const
Implements KTimeZone::offsetAtUtc().
Definition: ktimezone.cpp:530
KTimeZoneBackend::hasTransitions
virtual bool hasTransitions(const KTimeZone *caller) const
Implements KTimeZone::hasTransitions().
Definition: ktimezone.cpp:582
KTimeZoneBackend::clone
virtual KTimeZoneBackend * clone() const
Creates a copy of this instance.
Definition: ktimezone.cpp:462
KTimeZoneBackend::offset
virtual int offset(const KTimeZone *caller, time_t t) const
Implements KTimeZone::offset().
Definition: ktimezone.cpp:562
KTimeZoneBackend::~KTimeZoneBackend
virtual ~KTimeZoneBackend()
Definition: ktimezone.cpp:438
KTimeZoneBackend::isDstAtUtc
virtual bool isDstAtUtc(const KTimeZone *caller, const QDateTime &utcDateTime) const
Implements KTimeZone::isDstAtUtc().
Definition: ktimezone.cpp:567
KTimeZoneBackend::operator=
KTimeZoneBackend & operator=(const KTimeZoneBackend &other)
Definition: ktimezone.cpp:445
KTimeZoneBackend::type
virtual QByteArray type() const
Returns the class name of the data represented by this instance.
Definition: ktimezone.cpp:457
KTimeZoneBackend::isDst
virtual bool isDst(const KTimeZone *caller, time_t t) const
Implements KTimeZone::isDst().
Definition: ktimezone.cpp:577
KTimeZoneBackend::KTimeZoneBackend
KTimeZoneBackend()
Implements KTimeZone::KTimeZone().
Definition: ktimezone.cpp:417
KTimeZoneBackend::offsetAtZoneTime
virtual int offsetAtZoneTime(const KTimeZone *caller, const QDateTime &zoneDateTime, int *secondOffset) const
Implements KTimeZone::offsetAtZoneTime().
Definition: ktimezone.cpp:467
KTimeZoneData
Base class for the parsed data returned by a KTimeZoneSource class.
Definition: ktimezone.h:1303
KTimeZoneData::previousUtcOffset
int previousUtcOffset() const
Returns the UTC offset to use before the start of data for the time zone.
Definition: ktimezone.cpp:1266
KTimeZoneData::operator=
KTimeZoneData & operator=(const KTimeZoneData &c)
Definition: ktimezone.cpp:1164
KTimeZoneData::leapSecondChanges
QList< KTimeZone::LeapSeconds > leapSecondChanges() const
Return all leap second adjustments, in time order.
Definition: ktimezone.cpp:1375
KTimeZoneData::transitions
QList< KTimeZone::Transition > transitions(const QDateTime &start=QDateTime(), const QDateTime &end=QDateTime()) const
Return all daylight saving transitions, in time order.
Definition: ktimezone.cpp:1249
KTimeZoneData::phases
QList< KTimeZone::Phase > phases() const
Return all daylight savings time phases.
Definition: ktimezone.cpp:1227
KTimeZoneData::abbreviations
virtual QList< QByteArray > abbreviations() const
Returns the complete list of time zone abbreviations.
Definition: ktimezone.cpp:1180
KTimeZoneData::setLeapSecondChanges
void setLeapSecondChanges(const QList< KTimeZone::LeapSeconds > &adjusts)
Initialise the leap seconds adjustment list.
Definition: ktimezone.cpp:1380
KTimeZoneData::transitionIndex
int transitionIndex(const QDateTime &dt, int *secondIndex=0, bool *validTime=0) const
Find the index to the last daylight savings time transition at or before a given UTC or local time.
Definition: ktimezone.cpp:1281
KTimeZoneData::transition
const KTimeZone::Transition * transition(const QDateTime &dt, const KTimeZone::Transition **secondTransition=0, bool *validTime=0) const
Find the last daylight savings time transition at or before a given UTC or local time.
Definition: ktimezone.cpp:1271
KTimeZoneData::leapSecondChange
KTimeZone::LeapSeconds leapSecondChange(const QDateTime &utc) const
Find the leap second adjustment which is applicable at a given UTC time.
Definition: ktimezone.cpp:1385
KTimeZoneData::clone
virtual KTimeZoneData * clone() const
Creates a new copy of this object.
Definition: ktimezone.cpp:1175
KTimeZoneData::abbreviation
virtual QByteArray abbreviation(const QDateTime &utcDateTime) const
Returns the time zone abbreviation current at a specified time.
Definition: ktimezone.cpp:1197
KTimeZoneData::hasTransitions
virtual bool hasTransitions() const
Return whether daylight saving transitions are available for the time zone.
Definition: ktimezone.cpp:1244
KTimeZoneData::setPhases
void setPhases(const QList< KTimeZone::Phase > &phases, const KTimeZone::Phase &previousPhase)
Initialise the daylight savings time phase list.
Definition: ktimezone.cpp:1232
KTimeZoneData::setTransitions
void setTransitions(const QList< KTimeZone::Transition > &transitions)
Initialise the daylight savings time transition list.
Definition: ktimezone.cpp:1261
KTimeZoneData::~KTimeZoneData
virtual ~KTimeZoneData()
Definition: ktimezone.cpp:1159
KTimeZoneData::KTimeZoneData
KTimeZoneData()
Definition: ktimezone.cpp:1144
KTimeZoneData::utcOffsets
virtual QList< int > utcOffsets() const
Returns the complete list of UTC offsets for the time zone, if the time zone's source makes such info...
Definition: ktimezone.cpp:1209
KTimeZoneData::transitionTimes
QList< QDateTime > transitionTimes(const KTimeZone::Phase &phase, const QDateTime &start=QDateTime(), const QDateTime &end=QDateTime()) const
Return the times of all daylight saving transitions to a given time zone phase, in time order.
Definition: ktimezone.cpp:1358
KTimeZoneSource
Base class representing a source of time zone information.
Definition: ktimezone.h:1231
KTimeZoneSource::parse
virtual KTimeZoneData * parse(const KTimeZone &zone) const
Extracts detail information for one time zone from the source database.
Definition: ktimezone.cpp:976
KTimeZoneSource::useZoneParse
bool useZoneParse() const
Return whether the source database supports the ad hoc extraction of data for individual time zones u...
Definition: ktimezone.cpp:982
KTimeZoneSource::KTimeZoneSource
KTimeZoneSource()
Definition: ktimezone.cpp:959
KTimeZoneSource::~KTimeZoneSource
virtual ~KTimeZoneSource()
Definition: ktimezone.cpp:971
KTimeZone::LeapSeconds
Definition: ktimezone.h:561
KTimeZone::LeapSeconds::LeapSeconds
LeapSeconds()
Definition: ktimezone.cpp:999
KTimeZone::LeapSeconds::operator=
LeapSeconds & operator=(const LeapSeconds &c)
Definition: ktimezone.cpp:1028
KTimeZone::LeapSeconds::isValid
bool isValid() const
Return whether this instance holds valid data.
Definition: ktimezone.cpp:1046
KTimeZone::LeapSeconds::leapSeconds
int leapSeconds() const
Return the cumulative number of leap seconds to be added after this change occurs.
Definition: ktimezone.cpp:1051
KTimeZone::LeapSeconds::operator<
bool operator<(const LeapSeconds &c) const
Definition: ktimezone.cpp:1036
KTimeZone::LeapSeconds::~LeapSeconds
~LeapSeconds()
Definition: ktimezone.cpp:1023
KTimeZone::LeapSeconds::dateTime
QDateTime dateTime() const
Return the UTC date/time when this change occurred.
Definition: ktimezone.cpp:1041
KTimeZone::LeapSeconds::comment
QString comment() const
Return the comment (if any) applying to this change.
Definition: ktimezone.cpp:1056
KTimeZone::Phase
Definition: ktimezone.h:430
KTimeZone::Phase::Phase
Phase()
Default constructor.
Definition: ktimezone.cpp:164
KTimeZone::Phase::utcOffset
int utcOffset() const
Return the UTC offset in seconds during this phase.
Definition: ktimezone.cpp:210
KTimeZone::Phase::operator=
Phase & operator=(const Phase &rhs)
Definition: ktimezone.cpp:199
KTimeZone::Phase::comment
QString comment() const
Return the comment (if any) applying to this phase.
Definition: ktimezone.cpp:225
KTimeZone::Phase::abbreviations
QList< QByteArray > abbreviations() const
Return the time zone abbreviations which apply to this phase.
Definition: ktimezone.cpp:215
KTimeZone::Phase::~Phase
~Phase()
Definition: ktimezone.cpp:195
KTimeZone::Phase::operator==
bool operator==(const Phase &rhs) const
Definition: ktimezone.cpp:205
KTimeZone::Phase::isDst
bool isDst() const
Return whether daylight savings time applies during this phase.
Definition: ktimezone.cpp:220
KTimeZone::Transition
Definition: ktimezone.h:514
KTimeZone::Transition::operator=
Transition & operator=(const KTimeZone::Transition &t)
Definition: ktimezone.cpp:265
KTimeZone::Transition::~Transition
~Transition()
Definition: ktimezone.cpp:260
KTimeZone::Transition::operator<
bool operator<(const Transition &rhs) const
Compare the date/time values of two transitions.
Definition: ktimezone.cpp:272
KTimeZone::Transition::Transition
Transition()
Definition: ktimezone.cpp:241
KTimeZone::Transition::time
QDateTime time() const
Return the UTC time of the transition.
Definition: ktimezone.cpp:277
KTimeZone::Transition::phase
Phase phase() const
Return the time zone phase which takes effect after the transition.
Definition: ktimezone.cpp:278
KTimeZone
Base class representing a time zone.
Definition: ktimezone.h:417
KTimeZone::source
KTimeZoneSource * source() const
Returns the source reader/parser for the time zone's source database.
Definition: ktimezone.cpp:749
KTimeZone::InvalidTime_t
static const time_t InvalidTime_t
Indicates an invalid time_t value.
Definition: ktimezone.h:1077
KTimeZone::~KTimeZone
virtual ~KTimeZone()
Definition: ktimezone.cpp:612
KTimeZone::offset
virtual int offset(time_t t) const
Returns the offset of this time zone to UTC at a specified UTC time.
Definition: ktimezone.cpp:875
KTimeZone::InvalidOffset
static const int InvalidOffset
Indicates an invalid UTC offset.
Definition: ktimezone.h:1073
KTimeZone::data
const KTimeZoneData * data(bool create=false) const
Returns the detailed parsed data for the time zone.
Definition: ktimezone.cpp:754
KTimeZone::transitionIndex
int transitionIndex(const QDateTime &dt, int *secondIndex=0, bool *validTime=0) const
Find the index to the last daylight savings time transition at or before a given UTC or local time.
Definition: ktimezone.cpp:725
KTimeZone::offsetAtZoneTime
virtual int offsetAtZoneTime(const QDateTime &zoneDateTime, int *secondOffset=0) const
Returns the offset of this time zone to UTC at the given local date/time.
Definition: ktimezone.cpp:865
KTimeZone::name
QString name() const
Returns the name of the time zone.
Definition: ktimezone.cpp:669
KTimeZone::isValid
bool isValid() const
Checks whether the instance is valid.
Definition: ktimezone.cpp:644
KTimeZone::transitions
QList< KTimeZone::Transition > transitions(const QDateTime &start=QDateTime(), const QDateTime &end=QDateTime()) const
Return all daylight saving transitions, in time order.
Definition: ktimezone.cpp:707
KTimeZone::isDstAtUtc
virtual bool isDstAtUtc(const QDateTime &utcDateTime) const
Returns whether daylight savings time is in operation at the given UTC date/time.
Definition: ktimezone.cpp:901
KTimeZone::offsetAtUtc
virtual int offsetAtUtc(const QDateTime &utcDateTime) const
Returns the offset of this time zone to UTC at the given UTC date/time.
Definition: ktimezone.cpp:870
KTimeZone::countryCode
QString countryCode() const
Returns the two-letter country code of the time zone.
Definition: ktimezone.cpp:649
KTimeZone::transitionTimes
QList< QDateTime > transitionTimes(const Phase &phase, const QDateTime &start=QDateTime(), const QDateTime &end=QDateTime()) const
Return the times of all daylight saving transitions to a given time zone phase, in time order.
Definition: ktimezone.cpp:735
KTimeZone::longitude
float longitude() const
Returns the latitude of the time zone.
Definition: ktimezone.cpp:659
KTimeZone::abbreviation
QByteArray abbreviation(const QDateTime &utcDateTime) const
Returns the time zone abbreviation current at a specified time.
Definition: ktimezone.cpp:681
KTimeZone::fromTime_t
static QDateTime fromTime_t(time_t t)
Converts a UTC time, measured in seconds since 00:00:00 UTC 1st January 1970 (as returned by time(2))...
Definition: ktimezone.cpp:917
KTimeZone::toZoneTime
QDateTime toZoneTime(const QDateTime &utcDateTime, bool *secondOccurrence=0) const
Converts a UTC date/time into local time in this time zone.
Definition: ktimezone.cpp:808
KTimeZone::transition
const KTimeZone::Transition * transition(const QDateTime &dt, const Transition **secondTransition=0, bool *validTime=0) const
Find the last daylight savings time transition at or before a given UTC or local time.
Definition: ktimezone.cpp:714
KTimeZone::operator==
bool operator==(const KTimeZone &rhs) const
Checks whether this is the same instance as another one.
Definition: ktimezone.cpp:634
KTimeZone::KTimeZone
KTimeZone()
Constructs a null time zone.
Definition: ktimezone.cpp:600
KTimeZone::comment
QString comment() const
Returns any comment for the time zone.
Definition: ktimezone.cpp:664
KTimeZone::toTime_t
static time_t toTime_t(const QDateTime &utcDateTime)
Converts a UTC QDateTime to a UTC time, measured in seconds since 00:00:00 UTC 1st January 1970 (as r...
Definition: ktimezone.cpp:934
KTimeZone::operator=
KTimeZone & operator=(const KTimeZone &tz)
Definition: ktimezone.cpp:624
KTimeZone::utcOffsets
QList< int > utcOffsets() const
Returns the complete list of UTC offsets used by the time zone.
Definition: ktimezone.cpp:688
KTimeZone::parse
bool parse() const
Extracts time zone detail information for this time zone from the source database.
Definition: ktimezone.cpp:784
KTimeZone::latitude
float latitude() const
Returns the latitude of the time zone.
Definition: ktimezone.cpp:654
KTimeZone::type
QByteArray type() const
Returns the class name of the data represented by this instance.
Definition: ktimezone.cpp:639
KTimeZone::UNKNOWN
static const float UNKNOWN
A representation for unknown locations; this is a float that does not represent a real latitude or lo...
Definition: ktimezone.h:1083
KTimeZone::toUtc
QDateTime toUtc(const QDateTime &zoneDateTime) const
Converts a date/time, which is interpreted as local time in this time zone, into UTC.
Definition: ktimezone.cpp:796
KTimeZone::abbreviations
QList< QByteArray > abbreviations() const
Returns the list of time zone abbreviations used by the time zone.
Definition: ktimezone.cpp:674
KTimeZone::utc
static KTimeZone utc()
Returns a standard UTC time zone, with name "UTC".
Definition: ktimezone.cpp:911
KTimeZone::isDst
virtual bool isDst(time_t t) const
Returns whether daylight savings time is in operation at a specified UTC time.
Definition: ktimezone.cpp:906
KTimeZone::currentOffset
int currentOffset(Qt::TimeSpec basis=Qt::UTC) const
Returns the current offset of this time zone to UTC or the local system time zone.
Definition: ktimezone.cpp:880
KTimeZone::setData
void setData(KTimeZoneData *data, KTimeZoneSource *source=0)
Sets the detailed parsed data for the time zone, and optionally a new time zone source object.
Definition: ktimezone.cpp:763
KTimeZone::leapSecondChanges
QList< LeapSeconds > leapSecondChanges() const
Return all leap second adjustments, in time order.
Definition: ktimezone.cpp:742
KTimeZone::hasTransitions
virtual bool hasTransitions() const
Return whether daylight saving transitions are available for the time zone.
Definition: ktimezone.cpp:702
KTimeZone::updateBase
bool updateBase(const KTimeZone &other)
Update the definition of the time zone to be identical to another KTimeZone instance.
Definition: ktimezone.cpp:773
KTimeZone::convert
QDateTime convert(const KTimeZone &newZone, const QDateTime &zoneDateTime) const
Converts a date/time, which is interpreted as being local time in this time zone, into local time in ...
Definition: ktimezone.cpp:854
KTimeZone::phases
QList< Phase > phases() const
Return all daylight savings time phases for the time zone.
Definition: ktimezone.cpp:695
KTimeZones::remove
KTimeZone remove(const KTimeZone &zone)
Removes a time zone from the collection.
Definition: ktimezone.cpp:82
KTimeZones::KTimeZones
KTimeZones()
Definition: ktimezone.cpp:57
KTimeZones::zone
KTimeZone zone(const QString &name) const
Returns the time zone with the given name.
Definition: ktimezone.cpp:118
KTimeZones::add
bool add(const KTimeZone &zone)
Adds a time zone to the collection.
Definition: ktimezone.cpp:72
KTimeZones::clear
void clear()
Clears the collection.
Definition: ktimezone.cpp:113
KTimeZones::~KTimeZones
~KTimeZones()
Definition: ktimezone.cpp:62
KTimeZones::zones
const ZoneMap zones() const
Returns all the time zones defined in this collection.
Definition: ktimezone.cpp:67
KTimeZones::ZoneMap
QMap< QString, KTimeZone > ZoneMap
Map of KTimeZone instances, indexed by time zone name.
Definition: ktimezone.h:323
QDateTime
QList
Definition: kaboutdata.h:33
QString
qint64
K_GLOBAL_STATIC
#define K_GLOBAL_STATIC(TYPE, NAME)
This macro makes it easy to use non-POD types as global statics.
Definition: kglobal.h:221
kDebug
#define kDebug
Definition: kdebug.h:316
kError
static QDebug kError(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
Definition: kdebug.h:187
operator==
bool operator==(const KEntry &k1, const KEntry &k2)
Definition: kconfigdata.h:72
kdebug.h
kglobal.h
gmtoff
int gmtoff(time_t t)
Definition: ksystemtimezone.cpp:70
gmtoff
int gmtoff(time_t t)
Definition: ksystemtimezone.cpp:70
ktimezone.h
Time zone functions.
transition
static QDateTime transition(const SYSTEMTIME &st, int year)
Definition: ktimezone_win.cpp:357
transitions
Transitions transitions(const TIME_ZONE_INFORMATION &tz, int year)
Definition: ktimezone_win.cpp:368
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDECore

Skip menu "KDECore"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal