1/*
2 This file is part of the KDE libraries
3 Copyright (c) 2005-2007 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/** @file
23 * Time zone functions
24 * @author David Jarvie <djarvie@kde.org>.
25 * @author S.R.Haque <srhaque@iee.org>.
26 */
27
28#ifndef _KTIMEZONES_H
29#define _KTIMEZONES_H
30
31#include <kdecore_export.h>
32
33#include <sys/time.h>
34#include <ctime>
35
36#include <QtCore/QDateTime>
37#include <QtCore/QMap>
38#include <QtCore/QList>
39#include <QtCore/QString>
40#include <QtCore/QByteArray>
41#include <QtCore/QSharedDataPointer>
42
43class KTimeZone;
44class KTimeZoneBackend;
45class KTimeZoneData;
46class KTimeZoneSource;
47class KTimeZonesPrivate;
48class KTimeZonePrivate;
49class KTimeZoneSourcePrivate;
50class KTimeZoneDataPrivate;
51class KTimeZoneTransitionPrivate;
52class KTimeZoneLeapSecondsPrivate;
53
54/** @defgroup timezones Time zone classes
55 *
56 * The time zone classes provide a framework for accessing time zone data, and
57 * converting times and dates between different time zones. They provide access
58 * to the system time zone database, and also allow developers to derive classes
59 * to access custom sources of time zone information such as calendar files.
60 *
61 * A time zone is represented by the KTimeZone class. This provides access to
62 * the time zone's detailed definition and contains methods to convert times to
63 * and from that zone. In order to save processing, KTimeZone obtains its time
64 * zone details only when they are actually required. Each KTimeZone class has
65 * a corresponding KTimeZoneBackend backend class which implements reference
66 * counting of the time zone's data.
67 *
68 * A collection of time zones is represented by the KTimeZones class, which acts
69 * as a container of KTimeZone objects. Within any KTimeZones object, each
70 * KTimeZone instance is uniquely identified by its name. Typically, each
71 * individual source of time zone information would be represented by a different
72 * KTimeZones object. This scheme allows conflicting time zone definitions
73 * between the different sources to be handled, since KTimeZone names need only
74 * be unique within a single KTimeZones object. Note that KTimeZone instances do
75 * not have to belong to any KTimeZones container.
76 *
77 * Time zone source data can come in all sorts of different forms: TZFILE format
78 * for a UNIX system time zone database, definitions within calendar files, calls
79 * to libraries (e.g. libc), etc. The KTimeZoneSource class provides reading and
80 * parsing functions to access such data, handing off the parsed data for a
81 * specific time zone in a KTimeZoneData object. Both of these are base classes
82 * from which should be derived other classes which know about the particular
83 * access method and data format (KTimeZoneSource) and which details are actually
84 * provided (KTimeZoneData). When a KTimeZone instance needs its time zone's
85 * definition, it calls KTimeZoneSource::parse() and receives the data back in a
86 * KTimeZoneData object which it keeps for reference.
87 *
88 * KTimeZoneData holds the definitions of the different daylight saving time and
89 * standard time phases in KTimeZone::Phase objects, and the timed sequence of
90 * daylight saving time changes in KTimeZone::Transition objects. Leap seconds
91 * adjustments are held in KTimeZone::LeapSeconds objects. You can access this
92 * data directly via KTimeZone and KTimeZoneData methods if required.
93 *
94 * The mapping of the different classes to external data is as follows:
95 *
96 * - Each different source data format or access method is represented by a
97 * different KTimeZoneSource class.
98 *
99 * - Each different set of data provided from source data is represented by a
100 * different KTimeZoneData class. For example, some time zone sources provide
101 * only the absolute basic information about time zones, i.e. name, transition
102 * times and offsets from UTC. Others provide information on leap second
103 * adjustments, while still others might contain information on which countries
104 * use the time zone. To allow for this variation, KTimeZoneData is made
105 * available for inheritance. When the necessary information is not available,
106 * the KTimeZone::Phase, KTimeZone::Transition and KTimeZone::LeapSeconds data
107 * will be empty.
108 *
109 * - Each KTimeZoneData class will have a corresponding KTimeZone class, and
110 * related KTimeZoneBackend class, which can interpret its data.
111 *
112 * - Each different source database will typically be represented by a different
113 * KTimeZones instance, to avoid possible conflicts between time zone definitions.
114 * If it is known that two source databases are definitely compatible, they can
115 * be grouped together into the same KTimeZones instance.
116 *
117 *
118 * \section sys System time zones
119 *
120 * Access to system time zones is provided by the KSystemTimeZones class, which
121 * reads the zone.tab file to obtain the list of system time zones, and creates a
122 * KSystemTimeZone instance for each one. KSystemTimeZone has a
123 * KSystemTimeZoneBackend backend class, and uses the KSystemTimeZoneSource
124 * and KSystemTimeZoneData classes to obtain time zone data via libc library
125 * functions.
126 *
127 * Normally, KSystemTimeZoneSource and KSystemTimeZoneData operate in the
128 * background and you will not need to use them directly.
129 *
130 * @warning The KSystemTimeZone class uses the standard system libraries to
131 * access time zone data, and its functionality is limited to what these libraries
132 * provide. On many systems, dates earlier than 1902 are not handled, and on
133 * non-GNU systems there is no guarantee that the time zone abbreviation returned
134 * for a given date will be correct if the abbreviations applicable then were
135 * not those currently in use. The KSystemTimeZones::readZone() method overcomes
136 * these restrictions by reading the time zone definition directly from the
137 * system time zone database files.
138 *
139 * \section tzfile Tzfile access
140 *
141 * The KTzfileTimeZone class provides access to tzfile(5) time zone definition
142 * files, which are used to form the time zone database on UNIX systems. Usually,
143 * for current information, it is easier to use the KSystemTimeZones class to
144 * access system tzfile data. However, for dealing with past data the
145 * KTzfileTimeZone class provides better guarantees of accurary, although it
146 * cannot handle dates earlier than 1902. It also provides more detailed
147 * information, and allows you to read non-system tzfile files. Alternatively,
148 * the KSystemTimeZones::readZone() method uses the KTzfileTimeZone class to
149 * read system time zone definition files.
150 *
151 * KTzfileTimeZone has a KTzfileTimeZoneBackend backend class, and uses the
152 * KTzfileTimeZoneSource and KTzfileTimeZoneData classes to obtain time zone
153 * data from tzfile files.
154 *
155 *
156 * \section deriving Handling time zone data from other sources
157 *
158 * To implement time zone classes to access a new time zone data source, you need
159 * as a minimum to derive a new class from KTimeZoneSource, and implement one or
160 * more parse() methods. If you can know in advance what KTimeZone instances to create
161 * without having to parse the source data, you should reimplement the virtual method
162 * KTimeZoneSource::parse(const KTimeZone&). Otherwise, you need to define your
163 * own parse() methods with appropriate signatures, to both read and parse the new
164 * data, and create new KTimeZone instances.
165 *
166 * If the data for each time zone which is available from the new source happens
167 * to be the same as for another source for which KTimeZone classes already exist,
168 * you could simply use the existing KTimeZone, KTimeZoneBackend and KTimeZoneData
169 * derived classes to receive the parsed data from your new KTimeZoneSource class:
170 *
171 * \code
172 * class NewTimeZoneSource : public KTimeZoneSource
173 * {
174 * public:
175 * NewTimeZoneSource(...); // parameters might include location of data source ...
176 * ~NewTimeZoneSource();
177 *
178 * // Option 1: reimplement KTimeZoneSource::parse() if you can
179 * // pre-create the KTimeZone instances.
180 * KTimeZoneData *parse(const KTimeZone &zone) const;
181 *
182 * // Option 2: implement new parse() methods if you don't know
183 * // in advance what KTimeZone instances to create.
184 * void parse(..., KTimeZones *zones) const;
185 * NewTimeZone *parse(...) const;
186 * };
187 *
188 * // Option 1:
189 * KTimeZoneData *NewTimeZoneSource::parse(const KTimeZone &zone) const
190 * {
191 * QString zoneName = zone.name();
192 * ExistingTimeZoneData* data = new ExistingTimeZoneData();
193 *
194 * // Read the data for 'zoneName' from the new data source.
195 *
196 * // Parse what we have read, and write it into 'data'.
197 * // Compile the sequence of daylight savings changes and leap
198 * // seconds adjustments (if available) and write into 'data'.
199 *
200 * return data;
201 * }
202 * \endcode
203 *
204 * If the data from the new source is different from what any existing
205 * KTimeZoneData class contains, you will need to implement new KTimeZone,
206 * KTimeZoneBackend and KTimeZoneData classes in addition to the KTimeZoneSource
207 * class illustrated above:
208 *
209 * \code
210 * class NewTimeZone : public KTimeZone
211 * {
212 * public:
213 * NewTimeZone(NewTimeZoneSource *source, const QString &name, ...);
214 * ~NewTimeZone();
215 *
216 * // Methods implementing KTimeZone virtual methods are implemented
217 * // in NewTimeZoneBackend, not here.
218 *
219 * // Anything else which you need
220 * private:
221 * // No d-pointer !
222 * };
223 *
224 * class NewTimeZoneBackend : public KTimeZoneBackend
225 * {
226 * public:
227 * NewTimeZoneBackend(NewTimeZoneSource *source, const QString &name, ...);
228 * ~NewTimeZoneBackend();
229 *
230 * KTimeZoneBackend *clone() const;
231 *
232 * // Virtual methods which need to be reimplemented
233 * int offsetAtZoneTime(const KTimeZone *caller, const QDateTime &zoneDateTime, int *secondOffset = 0) const;
234 * int offsetAtUtc(const KTimeZone *caller, const QDateTime &utcDateTime) const;
235 * int offset(const KTimeZone *caller, time_t t) const;
236 * int isDstAtUtc(const KTimeZone *caller, const QDateTime &utcDateTime) const;
237 * bool isDst(const KTimeZone *caller, time_t t) const;
238 *
239 * // Anything else which you need
240 * private:
241 * NewTimeZonePrivate *d; // non-const !
242 * };
243 *
244 * class NewTimeZoneData : public KTimeZoneData
245 * {
246 * friend class NewTimeZoneSource;
247 *
248 * public:
249 * NewTimeZoneData();
250 * ~NewTimeZoneData();
251 *
252 * // Virtual methods which need to be reimplemented
253 * KTimeZoneData *clone() const;
254 * QList<QByteArray> abbreviations() const;
255 * QByteArray abbreviation(const QDateTime &utcDateTime) const;
256 *
257 * // Data members containing whatever is read by NewTimeZoneSource
258 * };
259 * \endcode
260 *
261 * Here is a guide to implementing the offset() and offsetAtUtc() methods, in
262 * the case where the source data does not use time_t for its time measurement:
263 *
264 * \code
265 * int NewTimeZoneBackend::offsetAtUtc(const KTimeZone *caller, const QDateTime &utcDateTime) const
266 * {
267 * // Access this time zone's data. If we haven't already read it,
268 * // force a read from source now.
269 * NewTimeZoneData *zdata = caller->data(true);
270 *
271 * // Use 'zdata' contents to work out the UTC offset
272 *
273 * return offset;
274 * }
275 *
276 * int NewTimeZoneBackend::offset(const KTimeZone *caller, time_t t) const
277 * {
278 * return offsetAtUtc(KTimeZone::fromTime_t(t));
279 * }
280 * \endcode
281 *
282 * The other NewTimeZoneBackend methods would work in an analogous way to
283 * NewTimeZoneBackend::offsetAtUtc() and NewTimeZoneBackend::offset().
284 */
285
286/**
287 * The KTimeZones class represents a time zone database which consists of a
288 * collection of individual time zone definitions.
289 *
290 * Each individual time zone is defined in a KTimeZone instance, which provides
291 * generic support for private or system time zones. The time zones in the
292 * collection are indexed by name, which must be unique within the collection.
293 *
294 * Different time zone sources could define the same time zone differently. (For
295 * example, a calendar file originating from another system might hold its own
296 * time zone definitions, which may not necessarily be identical to your own
297 * system's definitions.) In order to keep conflicting definitions separate,
298 * it will often be necessary when dealing with multiple time zone sources to
299 * create a separate KTimeZones instance for each source collection.
300 *
301 * If you want to access system time zones, use the KSystemTimeZones class.
302 *
303 * @short Represents a time zone database or collection
304 * @ingroup timezones
305 * @author David Jarvie <djarvie@kde.org>.
306 * @author S.R.Haque <srhaque@iee.org>.
307 */
308class KDECORE_EXPORT KTimeZones
309{
310public:
311 KTimeZones();
312 ~KTimeZones();
313
314 /**
315 * Returns the time zone with the given name.
316 *
317 * @param name name of time zone
318 * @return time zone, or 0 if not found
319 */
320 KTimeZone zone(const QString &name) const;
321
322 /** Map of KTimeZone instances, indexed by time zone name. */
323 typedef QMap<QString, KTimeZone> ZoneMap;
324
325 /**
326 * Returns all the time zones defined in this collection.
327 *
328 * @return time zone collection, indexed by time zone name
329 */
330 const ZoneMap zones() const;
331
332 /**
333 * Adds a time zone to the collection.
334 * The time zone's name must be unique within the collection.
335 *
336 * @param zone time zone to add
337 * @return @c true if successful, @c false if zone's name duplicates one already in the collection
338 * @see remove()
339 */
340 bool add(const KTimeZone &zone);
341
342 /**
343 * Removes a time zone from the collection.
344 *
345 * @param zone time zone to remove
346 * @return the time zone which was removed, or invalid if not found
347 * @see clear(), add()
348 */
349 KTimeZone remove(const KTimeZone &zone);
350
351 /**
352 * Removes a time zone from the collection.
353 *
354 * @param name name of time zone to remove
355 * @return the time zone which was removed, or invalid if not found
356 * @see clear(), add()
357 */
358 KTimeZone remove(const QString &name);
359
360 /**
361 * Clears the collection.
362 *
363 * @see remove()
364 */
365 void clear();
366
367private:
368 KTimeZones(const KTimeZones &); // prohibit copying
369 KTimeZones &operator=(const KTimeZones &); // prohibit copying
370
371 KTimeZonesPrivate * const d;
372};
373
374
375/**
376 * Base class representing a time zone.
377 *
378 * The KTimeZone base class contains general descriptive data about the time zone, and
379 * provides an interface for methods to read and parse time zone definitions, and to
380 * translate between UTC and local time. Derived classes must implement these methods,
381 * and may also hold the actual details of the dates and times of daylight savings
382 * changes, offsets from UTC, etc. They should be tailored to deal with the type and
383 * format of data held by a particular type of time zone database.
384 *
385 * If this base class is instantiated as a valid instance, it always represents the
386 * UTC time zone.
387 *
388 * KTimeZone is designed to work in partnership with KTimeZoneSource. KTimeZone
389 * provides access to individual time zones, while classes derived from
390 * KTimeZoneSource read and parse a particular format of time zone definition.
391 * Because time zone sources can differ in what information they provide about time zones,
392 * the parsed data retured by KTimeZoneSource can vary between different sources,
393 * resulting in the need to create different KTimeZone classes to handle the data.
394 *
395 * KTimeZone instances are often grouped into KTimeZones collections.
396 *
397 * Copying KTimeZone instances is very efficient since the class data is explicitly
398 * shared, meaning that only a pointer to the data is actually copied. To achieve
399 * this, each class inherited from KTimeZone must have a corresponding backend
400 * class derived from KTimeZoneBackend.
401 *
402 * @note Classes derived from KTimeZone should not have their own d-pointer. The
403 * d-pointer is instead contained in their backend class (derived from
404 * KTimeZoneBackend). This allows KTimeZone's reference-counting of private data to
405 * take care of the derived class's data as well, ensuring that instance data is
406 * not deleted while any references to the class instance remains. All virtual
407 * methods which override KTimeZone virtual methods must be defined in the
408 * backend class instead.
409 *
410 * @short Base class representing a time zone
411 * @see KTimeZoneBackend, KTimeZoneSource, KTimeZoneData
412 * @ingroup timezones
413 * @author David Jarvie <djarvie@kde.org>.
414 * @author S.R.Haque <srhaque@iee.org>.
415 */
416class KDECORE_EXPORT KTimeZone //krazy:exclude=dpointer (has non-const d-pointer to Backend class)
417{
418public:
419
420 /*
421 * Time zone phase.
422 *
423 * A phase can be daylight savings time or standard time. It holds the
424 * UTC offset and time zone abbreviation (e.g. EST, GMT).
425 *
426 * @short Time zone phase
427 * @author David Jarvie <djarvie@kde.org>.
428 */
429 class KDECORE_EXPORT Phase
430 {
431 public:
432 /**
433 * Default constructor.
434 * Creates a standard-time time zone phase with UTC offset 0.
435 */
436 Phase();
437
438 /**
439 * Constructor.
440 *
441 * @param utcOffset number of seconds to add to UTC to get local time in this phase
442 * @param abbreviations time zone abbreviation for this phase. If translations exist,
443 * concatenate all abbreviations as null-terminated strings.
444 * @param dst true if daylight savings time, false if standard time
445 * @param comment optional comment
446 */
447 Phase(int utcOffset, const QByteArray &abbreviations, bool dst,
448 const QString &comment = QString());
449
450 /**
451 * Constructor.
452 *
453 * @param utcOffset number of seconds to add to UTC to get local time in this phase
454 * @param abbreviations time zone abbreviation for this phase, plus any translations
455 * @param dst true if daylight savings time, false if standard time
456 * @param comment optional comment
457 */
458 Phase(int utcOffset, const QList<QByteArray> &abbreviations, bool dst,
459 const QString &comment = QString());
460
461 Phase(const Phase &rhs);
462 ~Phase();
463 Phase &operator=(const Phase &rhs);
464 bool operator==(const Phase &rhs) const;
465 bool operator!=(const Phase &rhs) const { return !operator==(rhs); }
466
467 /**
468 * Return the UTC offset in seconds during this phase.
469 * The UTC offset is the number of seconds which you must add to UTC
470 * to get local time.
471 *
472 * @return offset in seconds to add to UTC
473 */
474 int utcOffset() const;
475
476 /**
477 * Return the time zone abbreviations which apply to this phase.
478 *
479 * More than one abbreviation may be returned, to allow for possible translations.
480 *
481 * @return time zone abbreviations
482 */
483 QList<QByteArray> abbreviations() const;
484
485 /**
486 * Return whether daylight savings time applies during this phase.
487 *
488 * @return true if daylight savings are in operation, false otherwise
489 */
490 bool isDst() const;
491
492 /**
493 * Return the comment (if any) applying to this phase.
494 *
495 * @return comment
496 */
497 QString comment() const;
498
499 private:
500 QSharedDataPointer<class KTimeZonePhasePrivate> d;
501 };
502
503
504 /*
505 * Time zone daylight saving time transition.
506 *
507 * A Transition instance holds details of a transition to daylight saving time or
508 * standard time, including the UTC time of the change.
509 *
510 * @short Time zone transition
511 * @author David Jarvie <djarvie@kde.org>.
512 */
513 class KDECORE_EXPORT Transition
514 {
515 public:
516 Transition();
517 Transition(const QDateTime &dt, const Phase &phase);
518 Transition(const KTimeZone::Transition &t);
519 ~Transition();
520 Transition &operator=(const KTimeZone::Transition &t);
521
522 /**
523 * Return the UTC time of the transition.
524 *
525 * @return UTC time
526 */
527 QDateTime time() const;
528
529 /**
530 * Return the time zone phase which takes effect after the transition.
531 *
532 * @return time zone phase
533 */
534 Phase phase() const;
535
536 /**
537 * Compare the date/time values of two transitions.
538 *
539 * @param rhs other instance
540 * @return @c true if this Transition is earlier than @p rhs
541 */
542 bool operator<(const Transition &rhs) const;
543
544 private:
545 KTimeZoneTransitionPrivate *const d;
546 };
547
548
549 /*
550 * Leap seconds adjustment for a time zone.
551 *
552 * This class defines a leap seconds adjustment for a time zone by its UTC time of
553 * occurrence and the cumulative number of leap seconds to be added at that time.
554 *
555 * @short Leap seconds adjustment for a time zone
556 * @see KTimeZone, KTimeZoneData
557 * @ingroup timezones
558 * @author David Jarvie <djarvie@kde.org>.
559 */
560 class KDECORE_EXPORT LeapSeconds
561 {
562 public:
563 LeapSeconds();
564 LeapSeconds(const QDateTime &utcTime, int leapSeconds, const QString &comment = QString());
565 LeapSeconds(const LeapSeconds &c);
566 ~LeapSeconds();
567 LeapSeconds &operator=(const LeapSeconds &c);
568 bool operator<(const LeapSeconds &c) const; // needed by qSort()
569
570 /**
571 * Return whether this instance holds valid data.
572 *
573 * @return true if valid, false if invalid
574 */
575 bool isValid() const;
576
577 /**
578 * Return the UTC date/time when this change occurred.
579 *
580 * @return date/time
581 */
582 QDateTime dateTime() const;
583
584 /**
585 * Return the cumulative number of leap seconds to be added after this
586 * change occurs.
587 *
588 * @return number of leap seconds
589 */
590 int leapSeconds() const;
591
592 /**
593 * Return the comment (if any) applying to this change.
594 *
595 * @return comment
596 */
597 QString comment() const;
598
599 private:
600 KTimeZoneLeapSecondsPrivate *const d;
601 };
602
603
604 /**
605 * Constructs a null time zone. A null time zone is invalid.
606 *
607 * @see isValid()
608 */
609 KTimeZone();
610
611 /**
612 * Constructs a UTC time zone.
613 *
614 * @param name name of the UTC time zone
615 */
616 explicit KTimeZone(const QString &name);
617
618 KTimeZone(const KTimeZone &tz);
619 KTimeZone &operator=(const KTimeZone &tz);
620
621 virtual ~KTimeZone();
622
623 /**
624 * Checks whether this is the same instance as another one.
625 * Note that only the pointers to the time zone data are compared, not the
626 * contents. So it will only return equality if one instance was copied
627 * from the other.
628 *
629 * @param rhs other instance
630 * @return true if the same instance, else false
631 */
632 bool operator==(const KTimeZone &rhs) const;
633 bool operator!=(const KTimeZone &rhs) const { return !operator==(rhs); }
634
635 /**
636 * Returns the class name of the data represented by this instance.
637 * If a derived class object has been assigned to this instance, this
638 * method will return the name of that class.
639 *
640 * @return "KTimeZone" or the class name of a derived class
641 */
642 QByteArray type() const;
643
644 /**
645 * Checks whether the instance is valid.
646 *
647 * @return true if valid, false if invalid
648 */
649 bool isValid() const;
650
651 /**
652 * Returns the name of the time zone.
653 * If it is held in a KTimeZones container, the name is the time zone's unique
654 * identifier within that KTimeZones instance.
655 *
656 * @return name in system-dependent format
657 */
658 QString name() const;
659
660 /**
661 * Returns the two-letter country code of the time zone.
662 *
663 * @return upper case ISO 3166 2-character country code, empty if unknown
664 */
665 QString countryCode() const;
666
667 /**
668 * Returns the latitude of the time zone.
669 *
670 * @return latitude in degrees, UNKNOWN if not known
671 */
672 float latitude() const;
673
674 /**
675 * Returns the latitude of the time zone.
676 *
677 * @return latitude in degrees, UNKNOWN if not known
678 */
679 float longitude() const;
680
681 /**
682 * Returns any comment for the time zone.
683 *
684 * @return comment, may be empty
685 */
686 QString comment() const;
687
688 /**
689 * Returns the list of time zone abbreviations used by the time zone.
690 * This may include historical ones which are no longer in use or have
691 * been superseded.
692 *
693 * @return list of abbreviations
694 * @see abbreviation()
695 */
696 QList<QByteArray> abbreviations() const;
697
698 /**
699 * Returns the time zone abbreviation current at a specified time.
700 *
701 * @param utcDateTime UTC date/time. An error occurs if
702 * @p utcDateTime.timeSpec() is not Qt::UTC.
703 * @return time zone abbreviation, or empty string if error
704 * @see abbreviations()
705 */
706 QByteArray abbreviation(const QDateTime &utcDateTime) const;
707
708 /**
709 * Returns the complete list of UTC offsets used by the time zone. This may
710 * include historical ones which are no longer in use or have been
711 * superseded.
712 *
713 * A UTC offset is the number of seconds which you must add to UTC to get
714 * local time in this time zone.
715 *
716 * If due to the nature of the source data for the time zone, compiling a
717 * complete list would require significant processing, an empty list is
718 * returned instead.
719 *
720 * @return sorted list of UTC offsets, or empty list if not readily available.
721 */
722 QList<int> utcOffsets() const;
723
724 /**
725 * Converts a date/time, which is interpreted as being local time in this
726 * time zone, into local time in another time zone.
727 *
728 * @param newZone other time zone which the time is to be converted into
729 * @param zoneDateTime local date/time. An error occurs if
730 * @p zoneDateTime.timeSpec() is not Qt::LocalTime.
731 * @return converted date/time, or invalid date/time if error
732 * @see toUtc(), toZoneTime()
733 */
734 QDateTime convert(const KTimeZone &newZone, const QDateTime &zoneDateTime) const;
735
736 /**
737 * Converts a date/time, which is interpreted as local time in this time
738 * zone, into UTC.
739 *
740 * Because of daylight savings time shifts, the date/time may occur twice. In
741 * such cases, this method returns the UTC time for the first occurrence.
742 * If you need the UTC time of the second occurrence, use offsetAtZoneTime().
743 *
744 * @param zoneDateTime local date/time. An error occurs if
745 * @p zoneDateTime.timeSpec() is not Qt::LocalTime.
746 * @return UTC date/time, or invalid date/time if error
747 * @see toZoneTime(), convert()
748 */
749 QDateTime toUtc(const QDateTime &zoneDateTime) const;
750
751 /**
752 * Converts a UTC date/time into local time in this time zone.
753 *
754 * Because of daylight savings time shifts, some local date/time values occur
755 * twice. The @p secondOccurrence parameter may be used to determine whether
756 * the time returned is the first or second occurrence of that time.
757 *
758 * @param utcDateTime UTC date/time. An error occurs if
759 * @p utcDateTime.timeSpec() is not Qt::UTC.
760 * @param secondOccurrence if non-null, returns @p true if the return value
761 * is the second occurrence of that time, else @p false
762 * @return local date/time, or invalid date/time if error
763 * @see toUtc(), convert()
764 */
765 QDateTime toZoneTime(const QDateTime &utcDateTime, bool *secondOccurrence = 0) const;
766
767 /**
768 * Returns the current offset of this time zone to UTC or the local
769 * system time zone. The offset is the number of seconds which you must
770 * add to UTC or the local system time to get local time in this time zone.
771 *
772 * Take care if you cache the results of this routine; that would
773 * break if the result were stored across a daylight savings change.
774 *
775 * @param basis Qt::UTC to return the offset to UTC, Qt::LocalTime
776 * to return the offset to local system time
777 * @return offset in seconds
778 * @see offsetAtZoneTime(), offsetAtUtc()
779 */
780 int currentOffset(Qt::TimeSpec basis = Qt::UTC) const;
781
782 /**
783 * Returns the offset of this time zone to UTC at the given local date/time.
784 * Because of daylight savings time shifts, the date/time may occur twice. Optionally,
785 * the offsets at both occurrences of @p dateTime are calculated.
786 *
787 * The offset is the number of seconds which you must add to UTC to get
788 * local time in this time zone.
789 *
790 * @param zoneDateTime the date/time at which the offset is to be calculated. This
791 * is interpreted as a local time in this time zone. An error
792 * occurs if @p zoneDateTime.timeSpec() is not Qt::LocalTime.
793 * @param secondOffset if non-null, and the @p zoneDateTime occurs twice, receives the
794 * UTC offset for the second occurrence. Otherwise, it is set
795 * the same as the return value.
796 * @return offset in seconds. If @p zoneDateTime occurs twice, it is the offset at the
797 * first occurrence which is returned. If @p zoneDateTime does not exist because
798 * of daylight savings time shifts, InvalidOffset is returned. If any other error
799 * occurs, 0 is returned.
800 * @see offsetAtUtc(), currentOffset()
801 */
802 virtual int offsetAtZoneTime(const QDateTime &zoneDateTime, int *secondOffset = 0) const;
803
804 /**
805 * Returns the offset of this time zone to UTC at the given UTC date/time.
806 *
807 * The offset is the number of seconds which you must add to UTC to get
808 * local time in this time zone.
809 *
810 * If a derived class needs to work in terms of time_t (as when accessing the
811 * system time functions, for example), it should override both this method and
812 * offset() so as to implement its offset calculations in offset(), and
813 * reimplement this method simply as
814 * \code
815 * offset(toTime_t(utcDateTime));
816 * \endcode
817 *
818 * @param utcDateTime the UTC date/time at which the offset is to be calculated.
819 * An error occurs if @p utcDateTime.timeSpec() is not Qt::UTC.
820 * @return offset in seconds, or 0 if error
821 * @see offset(), offsetAtZoneTime(), currentOffset()
822 */
823 virtual int offsetAtUtc(const QDateTime &utcDateTime) const;
824
825 /**
826 * Returns the offset of this time zone to UTC at a specified UTC time.
827 *
828 * The offset is the number of seconds which you must add to UTC to get
829 * local time in this time zone.
830 *
831 * Note that time_t has a more limited range than QDateTime, so consider using
832 * offsetAtUtc() instead.
833 *
834 * @param t the UTC time at which the offset is to be calculated, measured in seconds
835 * since 00:00:00 UTC 1st January 1970 (as returned by time(2))
836 * @return offset in seconds, or 0 if error
837 * @see offsetAtUtc()
838 */
839 virtual int offset(time_t t) const;
840
841 /**
842 * Returns whether daylight savings time is in operation at the given UTC date/time.
843 *
844 * If a derived class needs to work in terms of time_t (as when accessing the
845 * system time functions, for example), it should override both this method and
846 * isDst() so as to implement its offset calculations in isDst(), and reimplement
847 * this method simply as
848 * \code
849 * isDst(toTime_t(utcDateTime));
850 * \endcode
851 *
852 * @param utcDateTime the UTC date/time. An error occurs if
853 * @p utcDateTime.timeSpec() is not Qt::UTC.
854 * @return @c true if daylight savings time is in operation, @c false otherwise
855 * @see isDst()
856 */
857 virtual bool isDstAtUtc(const QDateTime &utcDateTime) const;
858
859 /**
860 * Returns whether daylight savings time is in operation at a specified UTC time.
861 *
862 * Note that time_t has a more limited range than QDateTime, so consider using
863 * isDstAtUtc() instead.
864 *
865 * @param t the UTC time, measured in seconds since 00:00:00 UTC 1st January 1970
866 * (as returned by time(2))
867 * @return @c true if daylight savings time is in operation, @c false otherwise
868 * @see isDstAtUtc()
869 */
870 virtual bool isDst(time_t t) const;
871
872 /**
873 * Return all daylight savings time phases for the time zone.
874 *
875 * Note that some time zone data sources (such as system time zones accessed
876 * via the system libraries) may not allow a list of daylight savings time
877 * changes to be compiled easily. In such cases, this method will return an
878 * empty list.
879 *
880 * @return list of phases
881 */
882 QList<Phase> phases() const;
883
884 /**
885 * Return whether daylight saving transitions are available for the time zone.
886 *
887 * The base class returns @c false.
888 *
889 * @return @c true if transitions are available, @c false if not
890 * @see transitions(), transition()
891 */
892 virtual bool hasTransitions() const;
893
894 /**
895 * Return all daylight saving transitions, in time order. If desired, the
896 * transitions returned may be restricted to a specified time range.
897 *
898 * Note that some time zone data sources (such as system time zones accessed
899 * via the system libraries) may not allow a list of daylight saving time
900 * changes to be compiled easily. In such cases, this method will return an
901 * empty list.
902 *
903 * @param start start UTC date/time, or invalid date/time to return all transitions
904 * up to @p end. @p start.timeSpec() must be Qt::UTC, else
905 * @p start will be considered invalid.
906 * @param end end UTC date/time, or invalid date/time for no end. @p end.timeSpec()
907 * must be Qt::UTC, else @p end will be considered invalid.
908 * @return list of transitions, in time order
909 * @see hasTransitions(), transition(), transitionTimes()
910 */
911 QList<KTimeZone::Transition> transitions(const QDateTime &start = QDateTime(), const QDateTime &end = QDateTime()) const;
912
913 /**
914 * Find the last daylight savings time transition at or before a given
915 * UTC or local time.
916 *
917 * Because of daylight savings time shifts, a local time may occur twice or
918 * may not occur at all. In the former case, the transitions at or before
919 * both occurrences of @p dt may optionally be calculated and returned in
920 * @p secondTransition. The latter case may optionally be detected by use of
921 * @p validTime.
922 *
923 * @param dt date/time. @p dt.timeSpec() may be set to Qt::UTC or Qt::LocalTime.
924 * @param secondTransition if non-null, and the @p dt occurs twice, receives the
925 * transition for the second occurrence. Otherwise, it is set
926 * the same as the return value.
927 * @param validTime if non-null, is set to false if @p dt does not occur, or
928 * to true otherwise
929 * @return time zone transition, or null either if @p dt is either outside the
930 * defined range of the transition data or if @p dt does not occur
931 * @see transitionIndex(), hasTransitions(), transitions()
932 */
933 const KTimeZone::Transition *transition(const QDateTime &dt, const Transition **secondTransition = 0, bool *validTime = 0) const;
934
935 /**
936 * Find the index to the last daylight savings time transition at or before
937 * a given UTC or local time. The return value is the index into the transition
938 * list returned by transitions().
939 *
940 * Because of daylight savings time shifts, a local time may occur twice or
941 * may not occur at all. In the former case, the transitions at or before
942 * both occurrences of @p dt may optionally be calculated and returned in
943 * @p secondIndex. The latter case may optionally be detected by use of
944 * @p validTime.
945 *
946 * @param dt date/time. @p dt.timeSpec() may be set to Qt::UTC or Qt::LocalTime.
947 * @param secondIndex if non-null, and the @p dt occurs twice, receives the
948 * index to the transition for the second occurrence. Otherwise,
949 * it is set the same as the return value.
950 * @param validTime if non-null, is set to false if @p dt does not occur, or
951 * to true otherwise
952 * @return index into the time zone transition list, or -1 either if @p dt is
953 * either outside the defined range of the transition data or if @p dt
954 * does not occur
955 * @see transition(), transitions(), hasTransitions()
956 */
957 int transitionIndex(const QDateTime &dt, int *secondIndex = 0, bool *validTime = 0) const;
958
959 /**
960 * Return the times of all daylight saving transitions to a given time zone
961 * phase, in time order. If desired, the times returned may be restricted to
962 * a specified time range.
963 *
964 * Note that some time zone data sources (such as system time zones accessed
965 * via the system libraries) may not allow a list of daylight saving time
966 * changes to be compiled easily. In such cases, this method will return an
967 * empty list.
968 *
969 * @param phase time zone phase
970 * @param start start UTC date/time, or invalid date/time to return all transitions
971 * up to @p end. @p start.timeSpec() must be Qt::UTC, else
972 * @p start will be considered invalid.
973 * @param end end UTC date/time, or invalid date/time for no end. @p end.timeSpec()
974 * must be Qt::UTC, else @p end will be considered invalid.
975 * @return ordered list of transition times
976 * @see hasTransitions(), transition(), transitions()
977 */
978 QList<QDateTime> transitionTimes(const Phase &phase, const QDateTime &start = QDateTime(), const QDateTime &end = QDateTime()) const;
979
980 /**
981 * Return all leap second adjustments, in time order.
982 *
983 * Note that some time zone data sources (such as system time zones accessed
984 * via the system libraries) may not provide information on leap second
985 * adjustments. In such cases, this method will return an empty list.
986 *
987 * @return list of adjustments
988 */
989 QList<LeapSeconds> leapSecondChanges() const;
990
991 /**
992 * Returns the source reader/parser for the time zone's source database.
993 *
994 * @return reader/parser
995 */
996 KTimeZoneSource *source() const;
997
998 /**
999 * Extracts time zone detail information for this time zone from the source database.
1000 *
1001 * @return @c false if the parse encountered errors, @c true otherwise
1002 */
1003 bool parse() const;
1004
1005 /**
1006 * Returns the detailed parsed data for the time zone.
1007 * This will return null unless either parse() has been called beforehand, or
1008 * @p create is true.
1009 *
1010 * @param create true to parse the zone's data first if not already parsed
1011 * @return pointer to data, or null if data has not been parsed
1012 */
1013 const KTimeZoneData *data(bool create = false) const;
1014
1015 /**
1016 * Update the definition of the time zone to be identical to another
1017 * KTimeZone instance. A prerequisite is that the two instances must
1018 * have the same name.
1019 *
1020 * The main purpose of this method is to allow updates of the time zone
1021 * definition by derived classes without invalidating pointers to the
1022 * instance (particularly pointers held by KDateTime objects). Note
1023 * that the KTimeZoneData object and KTimeZoneSource pointer are not
1024 * updated: the caller class should do this itself by calling setData().
1025 *
1026 * @param other time zone whose definition is to be used
1027 * @return true if definition was updated (i.e. names are the same)
1028 *
1029 * @see setData()
1030 */
1031 bool updateBase(const KTimeZone &other);
1032
1033 /**
1034 * Converts a UTC time, measured in seconds since 00:00:00 UTC 1st January 1970
1035 * (as returned by time(2)), to a UTC QDateTime value.
1036 * QDateTime::setTime_t() is limited to handling @p t >= 0, since its parameter
1037 * is unsigned. This method takes a parameter of time_t which is signed.
1038 *
1039 * @return converted time
1040 * @see toTime_t()
1041 */
1042 static QDateTime fromTime_t(time_t t);
1043
1044 /**
1045 * Converts a UTC QDateTime to a UTC time, measured in seconds since 00:00:00 UTC
1046 * 1st January 1970 (as returned by time(2)).
1047 * QDateTime::toTime_t() returns an unsigned value. This method returns a time_t
1048 * value, which is signed.
1049 *
1050 * @param utcDateTime date/time. An error occurs if @p utcDateTime.timeSpec() is
1051 * not Qt::UTC.
1052 * @return converted time, or -1 if the date is out of range for time_t or
1053 * @p utcDateTime.timeSpec() is not Qt::UTC
1054 * @see fromTime_t()
1055 */
1056 static time_t toTime_t(const QDateTime &utcDateTime);
1057
1058 /**
1059 * Returns a standard UTC time zone, with name "UTC".
1060 *
1061 * @note The KTimeZone returned by this method does not belong to any
1062 * KTimeZones collection. Any KTimeZones instance may contain its own UTC
1063 * KTimeZone defined by its time zone source data, but that will be a
1064 * different instance than this KTimeZone.
1065 *
1066 * @return UTC time zone
1067 */
1068 static KTimeZone utc();
1069
1070 /** Indicates an invalid UTC offset. This is returned by offsetAtZoneTime() when
1071 * the local time does not occur due to a shift to daylight savings time.
1072 */
1073 static const int InvalidOffset;
1074
1075 /** Indicates an invalid time_t value.
1076 */
1077 static const time_t InvalidTime_t;
1078
1079 /**
1080 * A representation for unknown locations; this is a float
1081 * that does not represent a real latitude or longitude.
1082 */
1083 static const float UNKNOWN;
1084
1085protected:
1086 KTimeZone(KTimeZoneBackend *impl);
1087
1088 /**
1089 * Sets the detailed parsed data for the time zone, and optionally
1090 * a new time zone source object.
1091 *
1092 * @param data parsed data
1093 * @param source if non-null, the new source object for the time zone
1094 *
1095 * @see data()
1096 */
1097 void setData(KTimeZoneData *data, KTimeZoneSource *source = 0);
1098
1099private:
1100 KTimeZoneBackend *d;
1101};
1102
1103
1104/**
1105 * Base backend class for KTimeZone classes.
1106 *
1107 * KTimeZone and each class inherited from it must have a corresponding
1108 * backend class to implement its constructors and its virtual methods,
1109 * and to provide a virtual clone() method. This allows KTimeZone virtual methods
1110 * to work together with reference counting of private data.
1111 *
1112 * @note Classes derived from KTimeZoneBackend should not normally implement their
1113 * own copy constructor or assignment operator, and must have a non-const d-pointer.
1114 *
1115 * @short Base backend class for KTimeZone classes
1116 * @see KTimeZone
1117 * @ingroup timezones
1118 * @author David Jarvie <djarvie@kde.org>.
1119 */
1120class KDECORE_EXPORT KTimeZoneBackend //krazy:exclude=dpointer (non-const d-pointer for KTimeZoneBackend-derived classes)
1121{
1122public:
1123 /** Implements KTimeZone::KTimeZone(). */
1124 KTimeZoneBackend();
1125 /** Implements KTimeZone::KTimeZone(const QString&). */
1126 explicit KTimeZoneBackend(const QString &name);
1127
1128 KTimeZoneBackend(const KTimeZoneBackend &other);
1129 KTimeZoneBackend &operator=(const KTimeZoneBackend &other);
1130 virtual ~KTimeZoneBackend();
1131
1132 /**
1133 * Creates a copy of this instance.
1134 *
1135 * @note Every inherited class must reimplement clone().
1136 *
1137 * @return new copy
1138 */
1139 virtual KTimeZoneBackend *clone() const;
1140
1141 /**
1142 * Returns the class name of the data represented by this instance.
1143 *
1144 * @note Every inherited class must reimplement type().
1145 *
1146 * This base class returns "KTimeZone".
1147 *
1148 * @return the class name
1149 */
1150 virtual QByteArray type() const;
1151
1152 /**
1153 * Implements KTimeZone::offsetAtZoneTime().
1154 *
1155 * @param caller calling KTimeZone object
1156 */
1157 virtual int offsetAtZoneTime(const KTimeZone* caller, const QDateTime &zoneDateTime, int *secondOffset) const;
1158 /**
1159 * Implements KTimeZone::offsetAtUtc().
1160 *
1161 * @param caller calling KTimeZone object
1162 */
1163 virtual int offsetAtUtc(const KTimeZone* caller, const QDateTime &utcDateTime) const;
1164 /**
1165 * Implements KTimeZone::offset().
1166 *
1167 * @param caller calling KTimeZone object
1168 */
1169 virtual int offset(const KTimeZone* caller, time_t t) const;
1170 /**
1171 * Implements KTimeZone::isDstAtUtc().
1172 *
1173 * @param caller calling KTimeZone object
1174 */
1175 virtual bool isDstAtUtc(const KTimeZone* caller, const QDateTime &utcDateTime) const;
1176 /**
1177 * Implements KTimeZone::isDst().
1178 *
1179 * @param caller calling KTimeZone object
1180 */
1181 virtual bool isDst(const KTimeZone* caller, time_t t) const;
1182 /**
1183 * Implements KTimeZone::hasTransitions().
1184 *
1185 * @param caller calling KTimeZone object
1186 */
1187 virtual bool hasTransitions(const KTimeZone* caller) const;
1188
1189protected:
1190 /**
1191 * Constructs a time zone.
1192 *
1193 * @param source reader/parser for the database containing this time zone. This will
1194 * be an instance of a class derived from KTimeZoneSource.
1195 * @param name in system-dependent format. The name must be unique within any
1196 * KTimeZones instance which contains this KTimeZone.
1197 * @param countryCode ISO 3166 2-character country code, empty if unknown
1198 * @param latitude in degrees (between -90 and +90), UNKNOWN if not known
1199 * @param longitude in degrees (between -180 and +180), UNKNOWN if not known
1200 * @param comment description of the time zone, if any
1201 */
1202 KTimeZoneBackend(KTimeZoneSource *source, const QString &name,
1203 const QString &countryCode = QString(), float latitude = KTimeZone::UNKNOWN,
1204 float longitude = KTimeZone::UNKNOWN, const QString &comment = QString());
1205
1206private:
1207 KTimeZonePrivate *d; // non-const
1208 friend class KTimeZone;
1209};
1210
1211/**
1212 * Base class representing a source of time zone information.
1213 *
1214 * Derive subclasses from KTimeZoneSource to read and parse time zone details
1215 * from a time zone database or other source of time zone information. If can know
1216 * in advance what KTimeZone instances to create without having to parse the source
1217 * data, you should reimplement the virtual method parse(const KTimeZone&). Otherwise,
1218 * you need to define your own parse() methods with appropriate signatures, to both
1219 * read and parse the new data, and create new KTimeZone instances.
1220 *
1221 * KTimeZoneSource itself may be used as a dummy source which returns empty
1222 * time zone details.
1223 *
1224 * @short Base class representing a source of time zone information
1225 * @see KTimeZone, KTimeZoneData
1226 * @ingroup timezones
1227 * @author David Jarvie <djarvie@kde.org>.
1228 * @author S.R.Haque <srhaque@iee.org>.
1229 */
1230class KDECORE_EXPORT KTimeZoneSource
1231{
1232public:
1233 KTimeZoneSource();
1234 virtual ~KTimeZoneSource();
1235
1236 /**
1237 * Extracts detail information for one time zone from the source database.
1238 *
1239 * In this base class, the method always succeeds and returns an empty data
1240 * instance. Derived classes should reimplement this method to return an
1241 * appropriate data class derived from KTimeZoneData. Some source databases
1242 * may not be compatible with this method of parsing. In these cases, they
1243 * should use the constructor KTimeZoneSource(false) and calling this method
1244 * will produce a fatal error.
1245 *
1246 * @param zone the time zone for which data is to be extracted.
1247 * @return an instance of a class derived from KTimeZoneData containing
1248 * the parsed data. The caller is responsible for deleting the
1249 * KTimeZoneData instance.
1250 * Null is returned on error.
1251 */
1252 virtual KTimeZoneData *parse(const KTimeZone &zone) const;
1253
1254 /**
1255 * Return whether the source database supports the ad hoc extraction of data for
1256 * individual time zones using parse(const KTimeZone&).
1257 *
1258 * @return true if parse(const KTimeZone&) works, false if parsing must be
1259 * performed by other methods
1260 */
1261 bool useZoneParse() const;
1262
1263protected:
1264 /**
1265 * Constructor for use by derived classes, which specifies whether the
1266 * source database supports the ad hoc extraction of data for individual
1267 * time zones using parse(const KTimeZone&).
1268 *
1269 * If parse(const KTimeZone&) cannot be used, KTimeZone derived classes
1270 * which use this KTimeZoneSource derived class must create a
1271 * KTimeZoneData object at construction time so that KTimeZone::data()
1272 * will always return a data object.
1273 *
1274 * Note the default constructor is equivalent to KTimeZoneSource(true), i.e.
1275 * it is only necessary to use this constructor if parse(const KTimeZone&)
1276 * does not work.
1277 *
1278 * @param useZoneParse true if parse(const KTimeZone&) works, false if
1279 * parsing must be performed by other methods
1280 */
1281 explicit KTimeZoneSource(bool useZoneParse);
1282
1283private:
1284 KTimeZoneSourcePrivate * const d;
1285};
1286
1287
1288/**
1289 * Base class for the parsed data returned by a KTimeZoneSource class.
1290 *
1291 * It contains all the data available from the KTimeZoneSource class,
1292 * including, when available, a complete list of daylight savings time
1293 * changes and leap seconds adjustments.
1294 *
1295 * This base class can be instantiated, but contains no data.
1296 *
1297 * @short Base class for parsed time zone data
1298 * @see KTimeZone, KTimeZoneSource
1299 * @ingroup timezones
1300 * @author David Jarvie <djarvie@kde.org>.
1301 */
1302class KDECORE_EXPORT KTimeZoneData
1303{
1304 friend class KTimeZone;
1305
1306public:
1307 KTimeZoneData();
1308 KTimeZoneData(const KTimeZoneData &c);
1309 virtual ~KTimeZoneData();
1310 KTimeZoneData &operator=(const KTimeZoneData &c);
1311
1312 /**
1313 * Creates a new copy of this object.
1314 * The caller is responsible for deleting the copy.
1315 * Derived classes must reimplement this method to return a copy of the
1316 * calling instance.
1317 *
1318 * @return copy of this instance
1319 */
1320 virtual KTimeZoneData *clone() const;
1321
1322 /**
1323 * Returns the complete list of time zone abbreviations. This may include
1324 * translations.
1325 *
1326 * @return the list of abbreviations.
1327 * In this base class, it consists of the single string "UTC".
1328 * @see abbreviation()
1329 */
1330 virtual QList<QByteArray> abbreviations() const;
1331
1332 /**
1333 * Returns the time zone abbreviation current at a specified time.
1334 *
1335 * @param utcDateTime UTC date/time. An error occurs if
1336 * @p utcDateTime.timeSpec() is not Qt::UTC.
1337 * @return time zone abbreviation, or empty string if error
1338 * @see abbreviations()
1339 */
1340 virtual QByteArray abbreviation(const QDateTime &utcDateTime) const;
1341
1342 /**
1343 * Returns the complete list of UTC offsets for the time zone, if the time
1344 * zone's source makes such information readily available. If compiling a
1345 * complete list would require significant processing, an empty list is
1346 * returned instead.
1347 *
1348 * @return sorted list of UTC offsets, or empty list if not readily available.
1349 * In this base class, it consists of the single value 0.
1350 */
1351 virtual QList<int> utcOffsets() const;
1352
1353 /**
1354 * Returns the UTC offset to use before the start of data for the time zone.
1355 *
1356 * @return UTC offset
1357 */
1358 int previousUtcOffset() const;
1359
1360 /**
1361 * Return all daylight savings time phases.
1362 *
1363 * Note that some time zone data sources (such as system time zones accessed
1364 * via the system libraries) may not allow a list of daylight savings time
1365 * changes to be compiled easily. In such cases, this method will return an
1366 * empty list.
1367 *
1368 * @return list of phases
1369 */
1370 QList<KTimeZone::Phase> phases() const;
1371
1372 /**
1373 * Return whether daylight saving transitions are available for the time zone.
1374 *
1375 * The base class returns @c false.
1376 *
1377 * @return @c true if transitions are available, @c false if not
1378 * @see transitions(), transition()
1379 */
1380 virtual bool hasTransitions() const;
1381
1382 /**
1383 * Return all daylight saving transitions, in time order. If desired, the
1384 * transitions returned may be restricted to a specified time range.
1385 *
1386 * Note that some time zone data sources (such as system time zones accessed
1387 * via the system libraries) may not allow a list of daylight saving time
1388 * changes to be compiled easily. In such cases, this method will return an
1389 * empty list.
1390 *
1391 * @param start start date/time, or invalid date/time to return all transitions up
1392 * to @p end. @p start.timeSpec() must be Qt::UTC, else
1393 * @p start will be considered invalid.
1394 * @param end end date/time, or invalid date/time for no end. @p end.timeSpec()
1395 * must be Qt::UTC, else @p end will be considered invalid.
1396 * @return list of transitions, in time order
1397 * @see hasTransitions(), transition(), transitionTimes()
1398 */
1399 QList<KTimeZone::Transition> transitions(const QDateTime &start = QDateTime(), const QDateTime &end = QDateTime()) const;
1400
1401 /**
1402 * Find the last daylight savings time transition at or before a given
1403 * UTC or local time.
1404 *
1405 * Because of daylight savings time shifts, a local time may occur twice or
1406 * may not occur at all. In the former case, the transitions at or before
1407 * both occurrences of @p dt may optionally be calculated and returned in
1408 * @p secondTransition. The latter case may optionally be detected by use of
1409 * @p validTime.
1410 *
1411 * @param dt date/time. @p dt.timeSpec() may be set to Qt::UTC or Qt::LocalTime.
1412 * @param secondTransition if non-null, and the @p dt occurs twice, receives the
1413 * transition for the second occurrence. Otherwise, it is set
1414 * the same as the return value.
1415 * @param validTime if non-null, is set to false if @p dt does not occur, or
1416 * to true otherwise
1417 * @return time zone transition, or null either if @p dt is either outside the
1418 * defined range of the transition data or if @p dt does not occur
1419 * @see transitionIndex(), hasTransitions(), transitions()
1420 */
1421 const KTimeZone::Transition *transition(const QDateTime &dt, const KTimeZone::Transition **secondTransition = 0, bool *validTime = 0) const;
1422
1423 /**
1424 * Find the index to the last daylight savings time transition at or before
1425 * a given UTC or local time. The return value is the index into the transition
1426 * list returned by transitions().
1427 *
1428 * Because of daylight savings time shifts, a local time may occur twice or
1429 * may not occur at all. In the former case, the transitions at or before
1430 * both occurrences of @p dt may optionally be calculated and returned in
1431 * @p secondIndex. The latter case may optionally be detected by use of
1432 * @p validTime.
1433 *
1434 * @param dt date/time. @p dt.timeSpec() may be set to Qt::UTC or Qt::LocalTime.
1435 * @param secondIndex if non-null, and the @p dt occurs twice, receives the
1436 * index to the transition for the second occurrence. Otherwise,
1437 * it is set the same as the return value.
1438 * @param validTime if non-null, is set to false if @p dt does not occur, or
1439 * to true otherwise
1440 * @return index into the time zone transition list, or -1 either if @p dt is
1441 * either outside the defined range of the transition data or if @p dt
1442 * does not occur
1443 * @see transition(), transitions(), hasTransitions()
1444 */
1445 int transitionIndex(const QDateTime &dt, int *secondIndex = 0, bool *validTime = 0) const;
1446
1447 /**
1448 * Return the times of all daylight saving transitions to a given time zone
1449 * phase, in time order. If desired, the times returned may be restricted to
1450 * a specified time range.
1451 *
1452 * Note that some time zone data sources (such as system time zones accessed
1453 * via the system libraries) may not allow a list of daylight saving time
1454 * changes to be compiled easily. In such cases, this method will return an
1455 * empty list.
1456 *
1457 * @param phase time zone phase
1458 * @param start start UTC date/time, or invalid date/time to return all transitions
1459 * up to @p end. @p start.timeSpec() must be Qt::UTC, else
1460 * @p start will be considered invalid.
1461 * @param end end UTC date/time, or invalid date/time for no end. @p end.timeSpec()
1462 * must be Qt::UTC, else @p end will be considered invalid.
1463 * @return ordered list of transition times
1464 * @see hasTransitions(), transition(), transitions()
1465 */
1466 QList<QDateTime> transitionTimes(const KTimeZone::Phase &phase, const QDateTime &start = QDateTime(), const QDateTime &end = QDateTime()) const;
1467
1468 /**
1469 * Return all leap second adjustments, in time order.
1470 *
1471 * Note that some time zone data sources (such as system time zones accessed
1472 * via the system libraries) may not provide information on leap second
1473 * adjustments. In such cases, this method will return an empty list.
1474 *
1475 * @return list of adjustments
1476 */
1477 QList<KTimeZone::LeapSeconds> leapSecondChanges() const;
1478
1479 /**
1480 * Find the leap second adjustment which is applicable at a given UTC time.
1481 *
1482 * @param utc UTC date/time. An error occurs if @p utc.timeSpec() is not Qt::UTC.
1483 * @return leap second adjustment, or invalid if @p utc is earlier than the
1484 * first leap second adjustment or @p utc is a local time
1485 */
1486 KTimeZone::LeapSeconds leapSecondChange(const QDateTime &utc) const;
1487
1488protected:
1489 /**
1490 * Initialise the daylight savings time phase list.
1491 *
1492 * @param phases list of phases
1493 * @param previousPhase phase to use before the first daylight savings time
1494 * transition
1495 * @see phases()
1496 * @since 4.8.3
1497 */
1498 void setPhases(const QList<KTimeZone::Phase> &phases, const KTimeZone::Phase& previousPhase);
1499
1500 /**
1501 * Initialise the daylight savings time phase list.
1502 * This setPhases() variant should be used when the time zone abbreviation
1503 * used before the start of the first phase is not known.
1504 *
1505 * @param phases list of phases
1506 * @param previousUtcOffset UTC offset to use before the start of the first
1507 * phase
1508 * @see phases()
1509 */
1510 void setPhases(const QList<KTimeZone::Phase> &phases, int previousUtcOffset);
1511
1512 /**
1513 * Initialise the daylight savings time transition list.
1514 *
1515 * @param transitions list of transitions
1516 * @see transitions()
1517 */
1518 void setTransitions(const QList<KTimeZone::Transition> &transitions);
1519
1520 /**
1521 * Initialise the leap seconds adjustment list.
1522 *
1523 * @param adjusts list of adjustments
1524 * @see leapSecondChanges()
1525 */
1526 void setLeapSecondChanges(const QList<KTimeZone::LeapSeconds> &adjusts);
1527
1528private:
1529 KTimeZoneDataPrivate * const d;
1530};
1531
1532#endif
1533