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

KDECore

  • sources
  • kde-4.14
  • kdelibs
  • 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 
43 int gmtoff(time_t t); // defined in ksystemtimezone.cpp
44 
45 
46 /******************************************************************************/
47 
48 class KTimeZonesPrivate
49 {
50 public:
51  KTimeZonesPrivate() {}
52 
53  KTimeZones::ZoneMap zones;
54 };
55 
56 
57 KTimeZones::KTimeZones()
58  : d(new KTimeZonesPrivate)
59 {
60 }
61 
62 KTimeZones::~KTimeZones()
63 {
64  delete d;
65 }
66 
67 const KTimeZones::ZoneMap KTimeZones::zones() const
68 {
69  return d->zones;
70 }
71 
72 bool 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 
82 KTimeZone 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 
98 KTimeZone 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 
113 void KTimeZones::clear()
114 {
115  d->zones.clear();
116 }
117 
118 KTimeZone 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 
134 class 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 
164 KTimeZone::Phase::Phase()
165  : d(new KTimeZonePhasePrivate)
166 {
167 }
168 
169 KTimeZone::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 
177 KTimeZone::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 
190 KTimeZone::Phase::Phase(const KTimeZone::Phase &rhs)
191  : d(rhs.d)
192 {
193 }
194 
195 KTimeZone::Phase::~Phase()
196 {
197 }
198 
199 KTimeZone::Phase &KTimeZone::Phase::operator=(const KTimeZone::Phase &rhs)
200 {
201  d = rhs.d;
202  return *this;
203 }
204 
205 bool KTimeZone::Phase::operator==(const KTimeZone::Phase &rhs) const
206 {
207  return d == rhs.d || *d == *rhs.d;
208 }
209 
210 int KTimeZone::Phase::utcOffset() const
211 {
212  return d->utcOffset;
213 }
214 
215 QList<QByteArray> KTimeZone::Phase::abbreviations() const
216 {
217  return d->abbreviations.split('\0');
218 }
219 
220 bool KTimeZone::Phase::isDst() const
221 {
222  return d->dst;
223 }
224 
225 QString KTimeZone::Phase::comment() const
226 {
227  return d->comment;
228 }
229 
230 
231 /******************************************************************************/
232 
233 class KTimeZoneTransitionPrivate
234 {
235 public:
236  QDateTime time;
237  KTimeZone::Phase phase;
238 };
239 
240 
241 KTimeZone::Transition::Transition()
242  : d(new KTimeZoneTransitionPrivate)
243 {
244 }
245 
246 KTimeZone::Transition::Transition(const QDateTime &t, const KTimeZone::Phase &p)
247  : d(new KTimeZoneTransitionPrivate)
248 {
249  d->time = t;
250  d->phase = p;
251 }
252 
253 KTimeZone::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 
260 KTimeZone::Transition::~Transition()
261 {
262  delete d;
263 }
264 
265 KTimeZone::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 
272 bool KTimeZone::Transition::operator<(const KTimeZone::Transition &rhs) const
273 {
274  return d->time < rhs.d->time;
275 }
276 
277 QDateTime KTimeZone::Transition::time() const { return d->time; }
278 KTimeZone::Phase KTimeZone::Transition::phase() const { return d->phase; }
279 
280 
281 /******************************************************************************/
282 
283 class 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 
303 class KTimeZonePrivate : public QSharedData
304 {
305 public:
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 
328 private:
329  static KTimeZoneSource *mUtcSource;
330 };
331 
332 KTimeZoneSource *KTimeZonePrivate::mUtcSource = 0;
333 
334 
335 KTimeZonePrivate::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 
354 KTimeZonePrivate::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 
374 KTimeZonePrivate &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 
397 KTimeZoneSource *KTimeZonePrivate::utcSource()
398 {
399  if (!mUtcSource)
400  {
401  mUtcSource = new KTimeZoneSource;
402  qAddPostRoutine(KTimeZonePrivate::cleanup);
403  }
404  return mUtcSource;
405 }
406 
407 void KTimeZonePrivate::cleanup()
408 {
409  delete mUtcSource;
410 }
411 
412 
413 /******************************************************************************/
414 
415 K_GLOBAL_STATIC(KTimeZonePrivate, s_emptyTimeZonePrivate)
416 
417 KTimeZoneBackend::KTimeZoneBackend()
418  : d(&*s_emptyTimeZonePrivate)
419 {
420  ++d->refCount;
421 }
422 
423 KTimeZoneBackend::KTimeZoneBackend(const QString &name)
424  : d(new KTimeZonePrivate(KTimeZonePrivate::utcSource(), name, QString(), KTimeZone::UNKNOWN, KTimeZone::UNKNOWN, QString()))
425 {}
426 
427 KTimeZoneBackend::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 
432 KTimeZoneBackend::KTimeZoneBackend(const KTimeZoneBackend &other)
433  : d(other.d)
434 {
435  ++d->refCount;
436 }
437 
438 KTimeZoneBackend::~KTimeZoneBackend()
439 {
440  if (d && --d->refCount == 0)
441  delete d;
442  d = 0;
443 }
444 
445 KTimeZoneBackend &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 
457 QByteArray KTimeZoneBackend::type() const
458 {
459  return "KTimeZone";
460 }
461 
462 KTimeZoneBackend *KTimeZoneBackend::clone() const
463 {
464  return new KTimeZoneBackend(*this);
465 }
466 
467 int 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 
530 int 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 
562 int KTimeZoneBackend::offset(const KTimeZone* caller, time_t t) const
563 {
564  return offsetAtUtc(caller, KTimeZone::fromTime_t(t));
565 }
566 
567 bool 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 
577 bool KTimeZoneBackend::isDst(const KTimeZone* caller, time_t t) const
578 {
579  return isDstAtUtc(caller, KTimeZone::fromTime_t(t));
580 }
581 
582 bool 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
592 const time_t KTimeZone::InvalidTime_t = 0x800000000000000LL;
593 #else
594 const time_t KTimeZone::InvalidTime_t = 0x80000000;
595 #endif
596 const int KTimeZone::InvalidOffset = 0x80000000;
597 const float KTimeZone::UNKNOWN = 1000.0;
598 
599 
600 KTimeZone::KTimeZone()
601  : d(new KTimeZoneBackend())
602 {}
603 
604 KTimeZone::KTimeZone(const QString &name)
605  : d(new KTimeZoneBackend(name))
606 {}
607 
608 KTimeZone::KTimeZone(const KTimeZone &tz)
609  : d(tz.d->clone())
610 {}
611 
612 KTimeZone::~KTimeZone()
613 {
614  delete d;
615 }
616 
617 KTimeZone::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 
624 KTimeZone &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 
634 bool KTimeZone::operator==(const KTimeZone &rhs) const
635 {
636  return d->d == rhs.d->d;
637 }
638 
639 QByteArray KTimeZone::type() const
640 {
641  return d->type();
642 }
643 
644 bool KTimeZone::isValid() const
645 {
646  return !d->d->name.isEmpty();
647 }
648 
649 QString KTimeZone::countryCode() const
650 {
651  return d->d->countryCode;
652 }
653 
654 float KTimeZone::latitude() const
655 {
656  return d->d->latitude;
657 }
658 
659 float KTimeZone::longitude() const
660 {
661  return d->d->longitude;
662 }
663 
664 QString KTimeZone::comment() const
665 {
666  return d->d->comment;
667 }
668 
669 QString KTimeZone::name() const
670 {
671  return d->d->name;
672 }
673 
674 QList<QByteArray> KTimeZone::abbreviations() const
675 {
676  if (!data(true))
677  return QList<QByteArray>();
678  return d->d->data->abbreviations();
679 }
680 
681 QByteArray 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 
688 QList<int> KTimeZone::utcOffsets() const
689 {
690  if (!data(true))
691  return QList<int>();
692  return d->d->data->utcOffsets();
693 }
694 
695 QList<KTimeZone::Phase> KTimeZone::phases() const
696 {
697  if (!data(true))
698  return QList<KTimeZone::Phase>();
699  return d->d->data->phases();
700 }
701 
702 bool KTimeZone::hasTransitions() const
703 {
704  return d->hasTransitions(this);
705 }
706 
707 QList<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 
714 const 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 
725 int 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 
735 QList<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 
742 QList<KTimeZone::LeapSeconds> KTimeZone::leapSecondChanges() const
743 {
744  if (!data(true))
745  return QList<KTimeZone::LeapSeconds>();
746  return d->d->data->leapSecondChanges();
747 }
748 
749 KTimeZoneSource *KTimeZone::source() const
750 {
751  return d->d->source;
752 }
753 
754 const 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 
763 void 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 
773 bool 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 
784 bool 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 
796 QDateTime 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 
808 QDateTime 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 
854 QDateTime 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 
865 int KTimeZone::offsetAtZoneTime(const QDateTime &zoneDateTime, int *secondOffset) const
866 {
867  return d->offsetAtZoneTime(this, zoneDateTime, secondOffset);
868 }
869 
870 int KTimeZone::offsetAtUtc(const QDateTime &utcDateTime) const
871 {
872  return d->offsetAtUtc(this, utcDateTime);
873 }
874 
875 int KTimeZone::offset(time_t t) const
876 {
877  return d->offset(this, t);
878 }
879 
880 int 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 
901 bool KTimeZone::isDstAtUtc(const QDateTime &utcDateTime) const
902 {
903  return d->isDstAtUtc(this, utcDateTime);
904 }
905 
906 bool KTimeZone::isDst(time_t t) const
907 {
908  return d->isDst(this, t);
909 }
910 
911 KTimeZone KTimeZone::utc()
912 {
913  static KTimeZone utcZone(QLatin1String("UTC"));
914  return utcZone;
915 }
916 
917 QDateTime 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 
934 time_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 
952 class KTimeZoneSourcePrivate
953 {
954 public:
955  bool mUseZoneParse;
956 };
957 
958 
959 KTimeZoneSource::KTimeZoneSource()
960  : d(new KTimeZoneSourcePrivate)
961 {
962  d->mUseZoneParse = true;
963 }
964 
965 KTimeZoneSource::KTimeZoneSource(bool useZoneParse)
966  : d(new KTimeZoneSourcePrivate)
967 {
968  d->mUseZoneParse = useZoneParse;
969 }
970 
971 KTimeZoneSource::~KTimeZoneSource()
972 {
973  delete d;
974 }
975 
976 KTimeZoneData *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 
982 bool KTimeZoneSource::useZoneParse() const
983 {
984  return d->mUseZoneParse;
985 }
986 
987 
988 /******************************************************************************/
989 
990 class 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 
999 KTimeZone::LeapSeconds::LeapSeconds()
1000  : d(new KTimeZoneLeapSecondsPrivate)
1001 {
1002 }
1003 
1004 KTimeZone::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 
1015 KTimeZone::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 
1023 KTimeZone::LeapSeconds::~LeapSeconds()
1024 {
1025  delete d;
1026 }
1027 
1028 KTimeZone::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 
1036 bool KTimeZone::LeapSeconds::operator<(const KTimeZone::LeapSeconds& c) const
1037 {
1038  return d->dt < c.d->dt;
1039 }
1040 
1041 QDateTime KTimeZone::LeapSeconds::dateTime() const
1042 {
1043  return d->dt;
1044 }
1045 
1046 bool KTimeZone::LeapSeconds::isValid() const
1047 {
1048  return d->dt.isValid();
1049 }
1050 
1051 int KTimeZone::LeapSeconds::leapSeconds() const
1052 {
1053  return d->seconds;
1054 }
1055 
1056 QString KTimeZone::LeapSeconds::comment() const
1057 {
1058  return d->comment;
1059 }
1060 
1061 
1062 /******************************************************************************/
1063 
1064 
1065 int 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.
1100 bool 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  */
1128 bool 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 
1144 KTimeZoneData::KTimeZoneData()
1145  : d(new KTimeZoneDataPrivate)
1146 { }
1147 
1148 KTimeZoneData::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 
1159 KTimeZoneData::~KTimeZoneData()
1160 {
1161  delete d;
1162 }
1163 
1164 KTimeZoneData &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 
1175 KTimeZoneData *KTimeZoneData::clone() const
1176 {
1177  return new KTimeZoneData(*this);
1178 }
1179 
1180 QList<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 
1197 QByteArray 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 
1209 QList<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 
1227 QList<KTimeZone::Phase> KTimeZoneData::phases() const
1228 {
1229  return d->phases;
1230 }
1231 
1232 void KTimeZoneData::setPhases(const QList<KTimeZone::Phase> &phases, const KTimeZone::Phase& previousPhase)
1233 {
1234  d->phases = phases;
1235  d->prePhase = previousPhase;
1236 }
1237 
1238 void KTimeZoneData::setPhases(const QList<KTimeZone::Phase> &phases, int previousUtcOffset)
1239 {
1240  d->phases = phases;
1241  d->prePhase = KTimeZone::Phase(previousUtcOffset, QByteArray(), false);
1242 }
1243 
1244 bool KTimeZoneData::hasTransitions() const
1245 {
1246  return false;
1247 }
1248 
1249 QList<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 
1261 void KTimeZoneData::setTransitions(const QList<KTimeZone::Transition> &transitions)
1262 {
1263  d->transitions = transitions;
1264 }
1265 
1266 int KTimeZoneData::previousUtcOffset() const
1267 {
1268  return d->prePhase.utcOffset();
1269 }
1270 
1271 const 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 
1281 int 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 
1358 QList<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 
1375 QList<KTimeZone::LeapSeconds> KTimeZoneData::leapSecondChanges() const
1376 {
1377  return d->leapChanges;
1378 }
1379 
1380 void KTimeZoneData::setLeapSecondChanges(const QList<KTimeZone::LeapSeconds> &adjusts)
1381 {
1382  d->leapChanges = adjusts;
1383 }
1384 
1385 KTimeZone::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 }
QDate::daysTo
int daysTo(const QDate &d) const
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
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::Transition::time
QDateTime time() const
Return the UTC time of the transition.
Definition: ktimezone.cpp:277
qint64
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::Transition::~Transition
~Transition()
Definition: ktimezone.cpp:260
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
kdebug.h
KTimeZone::parse
bool parse() const
Extracts time zone detail information for this time zone from the source database.
Definition: ktimezone.cpp:784
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
KTimeZoneBackend::hasTransitions
virtual bool hasTransitions(const KTimeZone *caller) const
Implements KTimeZone::hasTransitions().
Definition: ktimezone.cpp:582
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
KTimeZoneBackend::type
virtual QByteArray type() const
Returns the class name of the data represented by this instance.
Definition: ktimezone.cpp:457
KTimeZoneData::setPhases
void setPhases(const QList< KTimeZone::Phase > &phases, const KTimeZone::Phase &previousPhase)
Initialise the daylight savings time phase list.
Definition: ktimezone.cpp:1232
QByteArray
KTimeZone::Phase::isDst
bool isDst() const
Return whether daylight savings time applies during this phase.
Definition: ktimezone.cpp:220
KTimeZone::LeapSeconds::operator=
LeapSeconds & operator=(const LeapSeconds &c)
Definition: ktimezone.cpp:1028
KTimeZoneData
Base class for the parsed data returned by a KTimeZoneSource class.
Definition: ktimezone.h:1302
KTimeZoneBackend::~KTimeZoneBackend
virtual ~KTimeZoneBackend()
Definition: ktimezone.cpp:438
transitions
Transitions transitions(const TIME_ZONE_INFORMATION &tz, int year)
Definition: ktimezone_win.cpp:368
KTimeZones::KTimeZones
KTimeZones()
Definition: ktimezone.cpp:57
KTimeZone::isValid
bool isValid() const
Checks whether the instance is valid.
Definition: ktimezone.cpp:644
KTimeZoneBackend::offsetAtZoneTime
virtual int offsetAtZoneTime(const KTimeZone *caller, const QDateTime &zoneDateTime, int *secondOffset) const
Implements KTimeZone::offsetAtZoneTime().
Definition: ktimezone.cpp:467
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
QList::at
const T & at(int i) const
QMap
KTimeZoneData::setLeapSecondChanges
void setLeapSecondChanges(const QList< KTimeZone::LeapSeconds > &adjusts)
Initialise the leap seconds adjustment list.
Definition: ktimezone.cpp:1380
kError
static QDebug kError(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
Definition: kdebug.h:187
QDateTime::time
QTime time() const
KTimeZoneSource::parse
virtual KTimeZoneData * parse(const KTimeZone &zone) const
Extracts detail information for one time zone from the source database.
Definition: ktimezone.cpp:976
KTimeZoneData::setTransitions
void setTransitions(const QList< KTimeZone::Transition > &transitions)
Initialise the daylight savings time transition list.
Definition: ktimezone.cpp:1261
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
KTimeZones::add
bool add(const KTimeZone &zone)
Adds a time zone to the collection.
Definition: ktimezone.cpp:72
KTimeZones::remove
KTimeZone remove(const KTimeZone &zone)
Removes a time zone from the collection.
Definition: ktimezone.cpp:82
KTimeZone::hasTransitions
virtual bool hasTransitions() const
Return whether daylight saving transitions are available for the time zone.
Definition: ktimezone.cpp:702
QTime
KTimeZone::LeapSeconds::~LeapSeconds
~LeapSeconds()
Definition: ktimezone.cpp:1023
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::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
KTimeZone::source
KTimeZoneSource * source() const
Returns the source reader/parser for the time zone's source database.
Definition: ktimezone.cpp:749
KTimeZone::Phase
Definition: ktimezone.h:429
KTimeZone::Phase::Phase
Phase()
Default constructor.
Definition: ktimezone.cpp:164
operator==
bool operator==(const KEntry &k1, const KEntry &k2)
Definition: kconfigdata.h:72
QDateTime::setTimeSpec
void setTimeSpec(Qt::TimeSpec spec)
KTimeZone::latitude
float latitude() const
Returns the latitude of the time zone.
Definition: ktimezone.cpp:654
KTimeZoneData::clone
virtual KTimeZoneData * clone() const
Creates a new copy of this object.
Definition: ktimezone.cpp:1175
kglobal.h
QSharedData
gmtoff
int gmtoff(time_t t)
Definition: ksystemtimezone.cpp:70
QList::count
int count(const T &value) const
KTimeZone::countryCode
QString countryCode() const
Returns the two-letter country code of the time zone.
Definition: ktimezone.cpp:649
KTimeZone::data
const KTimeZoneData * data(bool create=false) const
Returns the detailed parsed data for the time zone.
Definition: ktimezone.cpp:754
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
KTimeZoneBackend::operator=
KTimeZoneBackend & operator=(const KTimeZoneBackend &other)
Definition: ktimezone.cpp:445
KTimeZone::Transition::phase
Phase phase() const
Return the time zone phase which takes effect after the transition.
Definition: ktimezone.cpp:278
KTimeZone::type
QByteArray type() const
Returns the class name of the data represented by this instance.
Definition: ktimezone.cpp:639
KTimeZone::abbreviation
QByteArray abbreviation(const QDateTime &utcDateTime) const
Returns the time zone abbreviation current at a specified time.
Definition: ktimezone.cpp:681
KTimeZoneBackend::clone
virtual KTimeZoneBackend * clone() const
Creates a copy of this instance.
Definition: ktimezone.cpp:462
KTimeZone::phases
QList< Phase > phases() const
Return all daylight savings time phases for the time zone.
Definition: ktimezone.cpp:695
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::LeapSeconds::operator<
bool operator<(const LeapSeconds &c) const
Definition: ktimezone.cpp:1036
QList::isEmpty
bool isEmpty() const
QString::isEmpty
bool isEmpty() const
KTimeZone::LeapSeconds
Definition: ktimezone.h:560
KTimeZoneData::abbreviations
virtual QList< QByteArray > abbreviations() const
Returns the complete list of time zone abbreviations.
Definition: ktimezone.cpp:1180
KTimeZone::Phase::operator=
Phase & operator=(const Phase &rhs)
Definition: ktimezone.cpp:199
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::InvalidTime_t
static const time_t InvalidTime_t
Indicates an invalid time_t value.
Definition: ktimezone.h:1077
QTime::addSecs
QTime addSecs(int s) const
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
KTimeZoneBackend::isDst
virtual bool isDst(const KTimeZone *caller, time_t t) const
Implements KTimeZone::isDst().
Definition: ktimezone.cpp:577
QDate
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::Transition::operator=
Transition & operator=(const KTimeZone::Transition &t)
Definition: ktimezone.cpp:265
KTimeZoneData::leapSecondChanges
QList< KTimeZone::LeapSeconds > leapSecondChanges() const
Return all leap second adjustments, in time order.
Definition: ktimezone.cpp:1375
ktimezone.h
Time zone functions.
KTimeZone::Phase::abbreviations
QList< QByteArray > abbreviations() const
Return the time zone abbreviations which apply to this phase.
Definition: ktimezone.cpp:215
QString
QList< QByteArray >
KTimeZone::InvalidOffset
static const int InvalidOffset
Indicates an invalid UTC offset.
Definition: ktimezone.h:1073
KTimeZoneSource::KTimeZoneSource
KTimeZoneSource()
Definition: ktimezone.cpp:959
KTimeZone::LeapSeconds::comment
QString comment() const
Return the comment (if any) applying to this change.
Definition: ktimezone.cpp:1056
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::longitude
float longitude() const
Returns the latitude of the time zone.
Definition: ktimezone.cpp:659
KTimeZone::LeapSeconds::leapSeconds
int leapSeconds() const
Return the cumulative number of leap seconds to be added after this change occurs.
Definition: ktimezone.cpp:1051
QDateTime::timeSpec
Qt::TimeSpec timeSpec() const
KTimeZoneData::~KTimeZoneData
virtual ~KTimeZoneData()
Definition: ktimezone.cpp:1159
KTimeZone
Base class representing a time zone.
Definition: ktimezone.h:416
KTimeZone::Transition::operator<
bool operator<(const Transition &rhs) const
Compare the date/time values of two transitions.
Definition: ktimezone.cpp:272
QDateTime::isValid
bool isValid() const
KTimeZone::leapSecondChanges
QList< LeapSeconds > leapSecondChanges() const
Return all leap second adjustments, in time order.
Definition: ktimezone.cpp:742
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
QDateTime::date
QDate date() const
KTimeZoneData::previousUtcOffset
int previousUtcOffset() const
Returns the UTC offset to use before the start of data for the time zone.
Definition: ktimezone.cpp:1266
KTimeZones::~KTimeZones
~KTimeZones()
Definition: ktimezone.cpp:62
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
QLatin1String
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
KTimeZones::clear
void clear()
Clears the collection.
Definition: ktimezone.cpp:113
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::~KTimeZone
virtual ~KTimeZone()
Definition: ktimezone.cpp:612
KTimeZone::Phase::comment
QString comment() const
Return the comment (if any) applying to this phase.
Definition: ktimezone.cpp:225
KTimeZoneData::operator=
KTimeZoneData & operator=(const KTimeZoneData &c)
Definition: ktimezone.cpp:1164
KTimeZone::operator==
bool operator==(const KTimeZone &rhs) const
Checks whether this is the same instance as another one.
Definition: ktimezone.cpp:634
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::KTimeZone
KTimeZone()
Constructs a null time zone.
Definition: ktimezone.cpp:600
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::Phase::utcOffset
int utcOffset() const
Return the UTC offset in seconds during this phase.
Definition: ktimezone.cpp:210
KTimeZoneData::phases
QList< KTimeZone::Phase > phases() const
Return all daylight savings time phases.
Definition: ktimezone.cpp:1227
KTimeZoneBackend::offsetAtUtc
virtual int offsetAtUtc(const KTimeZone *caller, const QDateTime &utcDateTime) const
Implements KTimeZone::offsetAtUtc().
Definition: ktimezone.cpp:530
KTimeZone::LeapSeconds::isValid
bool isValid() const
Return whether this instance holds valid data.
Definition: ktimezone.cpp:1046
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
KTimeZone::Transition
Definition: ktimezone.h:513
KTimeZone::Phase::operator==
bool operator==(const Phase &rhs) const
Definition: ktimezone.cpp:205
KTimeZone::Phase::~Phase
~Phase()
Definition: ktimezone.cpp:195
kDebug
#define kDebug
Definition: kdebug.h:316
KTimeZone::name
QString name() const
Returns the name of the time zone.
Definition: ktimezone.cpp:669
QDate::addDays
QDate addDays(int ndays) const
QMap::Iterator
typedef Iterator
KTimeZones::zones
const ZoneMap zones() const
Returns all the time zones defined in this collection.
Definition: ktimezone.cpp:67
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
QDateTime::addSecs
QDateTime addSecs(int s) const
QMap::ConstIterator
typedef ConstIterator
KTimeZoneBackend::offset
virtual int offset(const KTimeZone *caller, time_t t) const
Implements KTimeZone::offset().
Definition: ktimezone.cpp:562
KTimeZoneSource
Base class representing a source of time zone information.
Definition: ktimezone.h:1230
KTimeZone::utcOffsets
QList< int > utcOffsets() const
Returns the complete list of UTC offsets used by the time zone.
Definition: ktimezone.cpp:688
KTimeZoneData::KTimeZoneData
KTimeZoneData()
Definition: ktimezone.cpp:1144
KTimeZone::abbreviations
QList< QByteArray > abbreviations() const
Returns the list of time zone abbreviations used by the time zone.
Definition: ktimezone.cpp:674
KTimeZone::comment
QString comment() const
Returns any comment for the time zone.
Definition: ktimezone.cpp:664
KTimeZone::LeapSeconds::LeapSeconds
LeapSeconds()
Definition: ktimezone.cpp:999
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::Transition::Transition
Transition()
Definition: ktimezone.cpp:241
KTimeZone::LeapSeconds::dateTime
QDateTime dateTime() const
Return the UTC date/time when this change occurred.
Definition: ktimezone.cpp:1041
KTimeZoneData::abbreviation
virtual QByteArray abbreviation(const QDateTime &utcDateTime) const
Returns the time zone abbreviation current at a specified time.
Definition: ktimezone.cpp:1197
QTime::secsTo
int secsTo(const QTime &t) const
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::utc
static KTimeZone utc()
Returns a standard UTC time zone, with name "UTC".
Definition: ktimezone.cpp:911
KTimeZoneBackend::isDstAtUtc
virtual bool isDstAtUtc(const KTimeZone *caller, const QDateTime &utcDateTime) const
Implements KTimeZone::isDstAtUtc().
Definition: ktimezone.cpp:567
KTimeZoneBackend::KTimeZoneBackend
KTimeZoneBackend()
Implements KTimeZone::KTimeZone().
Definition: ktimezone.cpp:417
KTimeZones::zone
KTimeZone zone(const QString &name) const
Returns the time zone with the given name.
Definition: ktimezone.cpp:118
QDateTime
QDateTime::msecsTo
qint64 msecsTo(const QDateTime &other) const
KTimeZoneData::hasTransitions
virtual bool hasTransitions() const
Return whether daylight saving transitions are available for the time zone.
Definition: ktimezone.cpp:1244
KTimeZoneSource::~KTimeZoneSource
virtual ~KTimeZoneSource()
Definition: ktimezone.cpp:971
KTimeZoneBackend
Base backend class for KTimeZone classes.
Definition: ktimezone.h:1120
KTimeZone::operator=
KTimeZone & operator=(const KTimeZone &tz)
Definition: ktimezone.cpp:624
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:22:11 by doxygen 1.8.7 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 API Reference

Skip menu "kdelibs 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

Search



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