File indexing completed on 2024-04-14 14:20:08

0001 /*
0002    This file is part of the KDE libraries
0003    Copyright (c) 2005-2007 David Jarvie <djarvie@kde.org>
0004    Copyright (c) 2005 S.R.Haque <srhaque@iee.org>.
0005 
0006    This library is free software; you can redistribute it and/or
0007    modify it under the terms of the GNU Library General Public
0008    License as published by the Free Software Foundation; either
0009    version 2 of the License, or (at your option) any later version.
0010 
0011    This library is distributed in the hope that it will be useful,
0012    but WITHOUT ANY WARRANTY; without even the implied warranty of
0013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0014    Library General Public License for more details.
0015 
0016    You should have received a copy of the GNU Library General Public License
0017    along with this library; see the file COPYING.LIB.  If not, write to
0018    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0019    Boston, MA 02110-1301, USA.
0020 */
0021 
0022 /** @file
0023  * Time zone functions
0024  * @author David Jarvie <djarvie@kde.org>.
0025  * @author S.R.Haque <srhaque@iee.org>.
0026  */
0027 
0028 #ifndef _KTIMEZONES_H
0029 #define _KTIMEZONES_H
0030 
0031 #include <kdelibs4support_export.h>
0032 
0033 #include <sys/time.h>
0034 #include <ctime>
0035 
0036 #include <QDateTime>
0037 #include <QMap>
0038 #include <QList>
0039 #include <QString>
0040 #include <QByteArray>
0041 #include <QSharedDataPointer>
0042 
0043 class KTimeZone;
0044 class KTimeZoneBackend;
0045 class KTimeZoneData;
0046 class KTimeZoneSource;
0047 class KTimeZonesPrivate;
0048 class KTimeZonePrivate;
0049 class KTimeZoneSourcePrivate;
0050 class KTimeZoneDataPrivate;
0051 class KTimeZoneTransitionPrivate;
0052 class KTimeZoneLeapSecondsPrivate;
0053 
0054 /** @defgroup timezones Time zone classes
0055  *
0056  * The time zone classes provide a framework for accessing time zone data, and
0057  * converting times and dates between different time zones. They provide access
0058  * to the system time zone database, and also allow developers to derive classes
0059  * to access custom sources of time zone information such as calendar files.
0060  *
0061  * A time zone is represented by the KTimeZone class. This provides access to
0062  * the time zone's detailed definition and contains methods to convert times to
0063  * and from that zone. In order to save processing, KTimeZone obtains its time
0064  * zone details only when they are actually required. Each KTimeZone class has
0065  * a corresponding KTimeZoneBackend backend class which implements reference
0066  * counting of the time zone's data.
0067  *
0068  * A collection of time zones is represented by the KTimeZones class, which acts
0069  * as a container of KTimeZone objects. Within any KTimeZones object, each
0070  * KTimeZone instance is uniquely identified by its name. Typically, each
0071  * individual source of time zone information would be represented by a different
0072  * KTimeZones object. This scheme allows conflicting time zone definitions
0073  * between the different sources to be handled, since KTimeZone names need only
0074  * be unique within a single KTimeZones object. Note that KTimeZone instances do
0075  * not have to belong to any KTimeZones container.
0076  *
0077  * Time zone source data can come in all sorts of different forms: TZFILE format
0078  * for a UNIX system time zone database, definitions within calendar files, calls
0079  * to libraries (e.g. libc), etc. The KTimeZoneSource class provides reading and
0080  * parsing functions to access such data, handing off the parsed data for a
0081  * specific time zone in a KTimeZoneData object. Both of these are base classes
0082  * from which should be derived other classes which know about the particular
0083  * access method and data format (KTimeZoneSource) and which details are actually
0084  * provided (KTimeZoneData). When a KTimeZone instance needs its time zone's
0085  * definition, it calls KTimeZoneSource::parse() and receives the data back in a
0086  * KTimeZoneData object which it keeps for reference.
0087  *
0088  * KTimeZoneData holds the definitions of the different daylight saving time and
0089  * standard time phases in KTimeZone::Phase objects, and the timed sequence of
0090  * daylight saving time changes in KTimeZone::Transition objects. Leap seconds
0091  * adjustments are held in KTimeZone::LeapSeconds objects. You can access this
0092  * data directly via KTimeZone and KTimeZoneData methods if required.
0093  *
0094  * The mapping of the different classes to external data is as follows:
0095  *
0096  * - Each different source data format or access method is represented by a
0097  *   different KTimeZoneSource class.
0098  *
0099  * - Each different set of data provided from source data is represented by a
0100  *   different KTimeZoneData class. For example, some time zone sources provide
0101  *   only the absolute basic information about time zones, i.e. name, transition
0102  *   times and offsets from UTC. Others provide information on leap second
0103  *   adjustments, while still others might contain information on which countries
0104  *   use the time zone. To allow for this variation, KTimeZoneData is made
0105  *   available for inheritance. When the necessary information is not available,
0106  *   the KTimeZone::Phase, KTimeZone::Transition and KTimeZone::LeapSeconds data
0107  *   will be empty.
0108  *
0109  * - Each KTimeZoneData class will have a corresponding KTimeZone class, and
0110  *   related KTimeZoneBackend class, which can interpret its data.
0111  *
0112  * - Each different source database will typically be represented by a different
0113  *   KTimeZones instance, to avoid possible conflicts between time zone definitions.
0114  *   If it is known that two source databases are definitely compatible, they can
0115  *   be grouped together into the same KTimeZones instance.
0116  *
0117  *
0118  * \section sys System time zones
0119  *
0120  * Access to system time zones is provided by the KSystemTimeZones class, which
0121  * reads the zone.tab file to obtain the list of system time zones, and creates a
0122  * KSystemTimeZone instance for each one. KSystemTimeZone has a
0123  * KSystemTimeZoneBackend backend class, and uses the KSystemTimeZoneSource
0124  * and KSystemTimeZoneData classes to obtain time zone data via libc library
0125  * functions.
0126  *
0127  * Normally, KSystemTimeZoneSource and KSystemTimeZoneData operate in the
0128  * background and you will not need to use them directly.
0129  *
0130  * @warning The KSystemTimeZone class uses the standard system libraries to
0131  * access time zone data, and its functionality is limited to what these libraries
0132  * provide. On many systems, dates earlier than 1902 are not handled, and on
0133  * non-GNU systems there is no guarantee that the time zone abbreviation returned
0134  * for a given date will be correct if the abbreviations applicable then were
0135  * not those currently in use. The KSystemTimeZones::readZone() method overcomes
0136  * these restrictions by reading the time zone definition directly from the
0137  * system time zone database files.
0138  *
0139  * \section tzfile Tzfile access
0140  *
0141  * The KTzfileTimeZone class provides access to tzfile(5) time zone definition
0142  * files, which are used to form the time zone database on UNIX systems. Usually,
0143  * for current information, it is easier to use the KSystemTimeZones class to
0144  * access system tzfile data. However, for dealing with past data the
0145  * KTzfileTimeZone class provides better guarantees of accurary, although it
0146  * cannot handle dates earlier than 1902. It also provides more detailed
0147  * information, and allows you to read non-system tzfile files. Alternatively,
0148  * the KSystemTimeZones::readZone() method uses the KTzfileTimeZone class to
0149  * read system time zone definition files.
0150  *
0151  * KTzfileTimeZone has a KTzfileTimeZoneBackend backend class, and uses the
0152  * KTzfileTimeZoneSource and KTzfileTimeZoneData classes to obtain time zone
0153  * data from tzfile files.
0154  *
0155  *
0156  * \section deriving Handling time zone data from other sources
0157  *
0158  * To implement time zone classes to access a new time zone data source, you need
0159  * as a minimum to derive a new class from KTimeZoneSource, and implement one or
0160  * more parse() methods. If you can know in advance what KTimeZone instances to create
0161  * without having to parse the source data, you should reimplement the virtual method
0162  * KTimeZoneSource::parse(const KTimeZone&). Otherwise, you need to define your
0163  * own parse() methods with appropriate signatures, to both read and parse the new
0164  * data, and create new KTimeZone instances.
0165  *
0166  * If the data for each time zone which is available from the new source happens
0167  * to be the same as for another source for which KTimeZone classes already exist,
0168  * you could simply use the existing KTimeZone, KTimeZoneBackend and KTimeZoneData
0169  * derived classes to receive the parsed data from your new KTimeZoneSource class:
0170  *
0171  * \code
0172  * class NewTimeZoneSource : public KTimeZoneSource
0173  * {
0174  *     public:
0175  *         NewTimeZoneSource(...);  // parameters might include location of data source ...
0176  *         ~NewTimeZoneSource();
0177  *
0178  *         // Option 1: reimplement KTimeZoneSource::parse() if you can
0179  *         // pre-create the KTimeZone instances.
0180  *         KTimeZoneData *parse(const KTimeZone &zone) const;
0181  *
0182  *         // Option 2: implement new parse() methods if you don't know
0183  *         // in advance what KTimeZone instances to create.
0184  *         void parse(..., KTimeZones *zones) const;
0185  *         NewTimeZone *parse(...) const;
0186  * };
0187  *
0188  * // Option 1:
0189  * KTimeZoneData *NewTimeZoneSource::parse(const KTimeZone &zone) const
0190  * {
0191  *     QString zoneName = zone.name();
0192  *     ExistingTimeZoneData* data = new ExistingTimeZoneData();
0193  *
0194  *     // Read the data for 'zoneName' from the new data source.
0195  *
0196  *     // Parse what we have read, and write it into 'data'.
0197  *     // Compile the sequence of daylight savings changes and leap
0198  *     // seconds adjustments (if available) and write into 'data'.
0199  *
0200  *     return data;
0201  * }
0202  * \endcode
0203  *
0204  * If the data from the new source is different from what any existing
0205  * KTimeZoneData class contains, you will need to implement new KTimeZone,
0206  * KTimeZoneBackend and KTimeZoneData classes in addition to the KTimeZoneSource
0207  * class illustrated above:
0208  *
0209  * \code
0210  * class NewTimeZone : public KTimeZone
0211  * {
0212  *     public:
0213  *         NewTimeZone(NewTimeZoneSource *source, const QString &name, ...);
0214  *         ~NewTimeZone();
0215  *
0216  *         // Methods implementing KTimeZone virtual methods are implemented
0217  *         // in NewTimeZoneBackend, not here.
0218  *
0219  *         // Anything else which you need
0220  *     private:
0221  *         // No d-pointer !
0222  * };
0223  *
0224  * class NewTimeZoneBackend : public KTimeZoneBackend
0225  * {
0226  *     public:
0227  *         NewTimeZoneBackend(NewTimeZoneSource *source, const QString &name, ...);
0228  *         ~NewTimeZoneBackend();
0229  *
0230  *         KTimeZoneBackend *clone() const;
0231  *
0232  *         // Virtual methods which need to be reimplemented
0233  *         int offsetAtZoneTime(const KTimeZone *caller, const QDateTime &zoneDateTime, int *secondOffset = 0) const;
0234  *         int offsetAtUtc(const KTimeZone *caller, const QDateTime &utcDateTime) const;
0235  *         int offset(const KTimeZone *caller, time_t t) const;
0236  *         int isDstAtUtc(const KTimeZone *caller, const QDateTime &utcDateTime) const;
0237  *         bool isDst(const KTimeZone *caller, time_t t) const;
0238  *
0239  *         // Anything else which you need
0240  *     private:
0241  *         NewTimeZonePrivate *d;   // non-const !
0242  * };
0243  *
0244  * class NewTimeZoneData : public KTimeZoneData
0245  * {
0246  *         friend class NewTimeZoneSource;
0247  *
0248  *     public:
0249  *         NewTimeZoneData();
0250  *         ~NewTimeZoneData();
0251  *
0252  *         // Virtual methods which need to be reimplemented
0253  *         KTimeZoneData *clone() const;
0254  *         QList<QByteArray> abbreviations() const;
0255  *         QByteArray abbreviation(const QDateTime &utcDateTime) const;
0256  *
0257  *         // Data members containing whatever is read by NewTimeZoneSource
0258  * };
0259  * \endcode
0260  *
0261  * Here is a guide to implementing the offset() and offsetAtUtc() methods, in
0262  * the case where the source data does not use time_t for its time measurement:
0263  *
0264  * \code
0265  * int NewTimeZoneBackend::offsetAtUtc(const KTimeZone *caller, const QDateTime &utcDateTime) const
0266  * {
0267  *     // Access this time zone's data. If we haven't already read it,
0268  *     // force a read from source now.
0269  *     NewTimeZoneData *zdata = caller->data(true);
0270  *
0271  *     // Use 'zdata' contents to work out the UTC offset
0272  *
0273  *     return offset;
0274  * }
0275  *
0276  * int NewTimeZoneBackend::offset(const KTimeZone *caller, time_t t) const
0277  * {
0278  *     return offsetAtUtc(KTimeZone::fromTime_t(t));
0279  * }
0280  * \endcode
0281  *
0282  * The other NewTimeZoneBackend methods would work in an analogous way to
0283  * NewTimeZoneBackend::offsetAtUtc() and NewTimeZoneBackend::offset().
0284  */
0285 
0286 /**
0287  * The KTimeZones class represents a time zone database which consists of a
0288  * collection of individual time zone definitions.
0289  *
0290  * Each individual time zone is defined in a KTimeZone instance, which provides
0291  * generic support for private or system time zones. The time zones in the
0292  * collection are indexed by name, which must be unique within the collection.
0293  *
0294  * Different time zone sources could define the same time zone differently. (For
0295  * example, a calendar file originating from another system might hold its own
0296  * time zone definitions, which may not necessarily be identical to your own
0297  * system's definitions.) In order to keep conflicting definitions separate,
0298  * it will often be necessary when dealing with multiple time zone sources to
0299  * create a separate KTimeZones instance for each source collection.
0300  *
0301  * If you want to access system time zones, use the KSystemTimeZones class.
0302  *
0303  * @short Represents a time zone database or collection
0304  * @ingroup timezones
0305  * @author David Jarvie <djarvie@kde.org>.
0306  * @author S.R.Haque <srhaque@iee.org>.
0307  */
0308 class KDELIBS4SUPPORT_EXPORT KTimeZones
0309 {
0310 public:
0311     KTimeZones();
0312     ~KTimeZones();
0313 
0314     /**
0315      * Returns the time zone with the given name.
0316      *
0317      * @param name name of time zone
0318      * @return time zone, or 0 if not found
0319      */
0320     KTimeZone zone(const QString &name) const;
0321 
0322     /** Map of KTimeZone instances, indexed by time zone name. */
0323     typedef QMap<QString, KTimeZone> ZoneMap;
0324 
0325     /**
0326      * Returns all the time zones defined in this collection.
0327      *
0328      * @return time zone collection, indexed by time zone name
0329      */
0330     const ZoneMap zones() const;
0331 
0332     /**
0333      * Adds a time zone to the collection.
0334      * The time zone's name must be unique within the collection.
0335      *
0336      * @param zone time zone to add
0337      * @return @c true if successful, @c false if zone's name duplicates one already in the collection
0338      * @see remove()
0339      */
0340     bool add(const KTimeZone &zone);
0341 
0342     /**
0343      * Removes a time zone from the collection.
0344      *
0345      * @param zone time zone to remove
0346      * @return the time zone which was removed, or invalid if not found
0347      * @see clear(), add()
0348      */
0349     KTimeZone remove(const KTimeZone &zone);
0350 
0351     /**
0352      * Removes a time zone from the collection.
0353      *
0354      * @param name name of time zone to remove
0355      * @return the time zone which was removed, or invalid if not found
0356      * @see clear(), add()
0357      */
0358     KTimeZone remove(const QString &name);
0359 
0360     /**
0361      * Clears the collection.
0362      *
0363      * @see remove()
0364      */
0365     void clear();
0366 
0367 private:
0368     KTimeZones(const KTimeZones &);              // prohibit copying
0369     KTimeZones &operator=(const KTimeZones &);   // prohibit copying
0370 
0371     KTimeZonesPrivate *const d;
0372 };
0373 
0374 /**
0375  * Base class representing a time zone.
0376  *
0377  * The KTimeZone base class contains general descriptive data about the time zone, and
0378  * provides an interface for methods to read and parse time zone definitions, and to
0379  * translate between UTC and local time. Derived classes must implement these methods,
0380  * and may also hold the actual details of the dates and times of daylight savings
0381  * changes, offsets from UTC, etc. They should be tailored to deal with the type and
0382  * format of data held by a particular type of time zone database.
0383  *
0384  * If this base class is instantiated as a valid instance, it always represents the
0385  * UTC time zone.
0386  *
0387  * KTimeZone is designed to work in partnership with KTimeZoneSource. KTimeZone
0388  * provides access to individual time zones, while classes derived from
0389  * KTimeZoneSource read and parse a particular format of time zone definition.
0390  * Because time zone sources can differ in what information they provide about time zones,
0391  * the parsed data retured by KTimeZoneSource can vary between different sources,
0392  * resulting in the need to create different KTimeZone classes to handle the data.
0393  *
0394  * KTimeZone instances are often grouped into KTimeZones collections.
0395  *
0396  * Copying KTimeZone instances is very efficient since the class data is explicitly
0397  * shared, meaning that only a pointer to the data is actually copied. To achieve
0398  * this, each class inherited from KTimeZone must have a corresponding backend
0399  * class derived from KTimeZoneBackend.
0400  *
0401  * @note Classes derived from KTimeZone should not have their own d-pointer. The
0402  * d-pointer is instead contained in their backend class (derived from
0403  * KTimeZoneBackend). This allows KTimeZone's reference-counting of private data to
0404  * take care of the derived class's data as well, ensuring that instance data is
0405  * not deleted while any references to the class instance remains. All virtual
0406  * methods which override KTimeZone virtual methods must be defined in the
0407  * backend class instead.
0408  *
0409  * @short Base class representing a time zone
0410  * @see KTimeZoneBackend, KTimeZoneSource, KTimeZoneData
0411  * @ingroup timezones
0412  * @author David Jarvie <djarvie@kde.org>.
0413  * @author S.R.Haque <srhaque@iee.org>.
0414  */
0415 class KDELIBS4SUPPORT_EXPORT KTimeZone  //krazy:exclude=dpointer (has non-const d-pointer to Backend class)
0416 {
0417 public:
0418 
0419     /*
0420      * Time zone phase.
0421      *
0422      * A phase can be daylight savings time or standard time. It holds the
0423      * UTC offset and time zone abbreviation (e.g. EST, GMT).
0424      *
0425      * @short Time zone phase
0426      * @author David Jarvie <djarvie@kde.org>.
0427      */
0428     class KDELIBS4SUPPORT_EXPORT Phase
0429     {
0430     public:
0431         /**
0432         * Default constructor.
0433          * Creates a standard-time time zone phase with UTC offset 0.
0434          */
0435         Phase();
0436 
0437         /**
0438          * Constructor.
0439          *
0440          * @param utcOffset number of seconds to add to UTC to get local time in this phase
0441          * @param abbreviations time zone abbreviation for this phase. If translations exist,
0442          *                      concatenate all abbreviations as null-terminated strings.
0443          * @param dst true if daylight savings time, false if standard time
0444          * @param comment optional comment
0445          */
0446         Phase(int utcOffset, const QByteArray &abbreviations, bool dst,
0447               const QString &comment = QString());
0448 
0449         /**
0450          * Constructor.
0451          *
0452          * @param utcOffset number of seconds to add to UTC to get local time in this phase
0453          * @param abbreviations time zone abbreviation for this phase, plus any translations
0454          * @param dst true if daylight savings time, false if standard time
0455          * @param comment optional comment
0456          */
0457         Phase(int utcOffset, const QList<QByteArray> &abbreviations, bool dst,
0458               const QString &comment = QString());
0459 
0460         Phase(const Phase &rhs);
0461         ~Phase();
0462         Phase &operator=(const Phase &rhs);
0463         bool operator==(const Phase &rhs) const;
0464         bool operator!=(const Phase &rhs) const
0465         {
0466             return !operator==(rhs);
0467         }
0468 
0469         /**
0470          * Return the UTC offset in seconds during this phase.
0471          * The UTC offset is the number of seconds which you must add to UTC
0472          * to get local time.
0473          *
0474          * @return offset in seconds to add to UTC
0475          */
0476         int utcOffset() const;
0477 
0478         /**
0479          * Return the time zone abbreviations which apply to this phase.
0480          *
0481          * More than one abbreviation may be returned, to allow for possible translations.
0482          *
0483          * @return time zone abbreviations
0484          */
0485         QList<QByteArray> abbreviations() const;
0486 
0487         /**
0488          * Return whether daylight savings time applies during this phase.
0489          *
0490          * @return true if daylight savings are in operation, false otherwise
0491          */
0492         bool isDst() const;
0493 
0494         /**
0495          * Return the comment (if any) applying to this phase.
0496          *
0497          * @return comment
0498          */
0499         QString comment() const;
0500 
0501     private:
0502         QSharedDataPointer<class KTimeZonePhasePrivate> d;
0503     };
0504 
0505     /*
0506      * Time zone daylight saving time transition.
0507      *
0508      * A Transition instance holds details of a transition to daylight saving time or
0509      * standard time, including the UTC time of the change.
0510      *
0511      * @short Time zone transition
0512      * @author David Jarvie <djarvie@kde.org>.
0513      */
0514     class KDELIBS4SUPPORT_EXPORT Transition
0515     {
0516     public:
0517         Transition();
0518         Transition(const QDateTime &dt, const Phase &phase);
0519         Transition(const KTimeZone::Transition &t);
0520         ~Transition();
0521         Transition &operator=(const KTimeZone::Transition &t);
0522 
0523         /**
0524          * Return the UTC time of the transition.
0525          *
0526          * @return UTC time
0527          */
0528         QDateTime time() const;
0529 
0530         /**
0531          * Return the time zone phase which takes effect after the transition.
0532          *
0533          * @return time zone phase
0534          */
0535         Phase phase() const;
0536 
0537         /**
0538          * Compare the date/time values of two transitions.
0539          *
0540          * @param rhs other instance
0541          * @return @c true if this Transition is earlier than @p rhs
0542          */
0543         bool operator<(const Transition &rhs) const;
0544 
0545     private:
0546         KTimeZoneTransitionPrivate *const d;
0547     };
0548 
0549     /*
0550      * Leap seconds adjustment for a time zone.
0551      *
0552      * This class defines a leap seconds adjustment for a time zone by its UTC time of
0553      * occurrence and the cumulative number of leap seconds to be added at that time.
0554      *
0555      * @short Leap seconds adjustment for a time zone
0556      * @see KTimeZone, KTimeZoneData
0557      * @ingroup timezones
0558      * @author David Jarvie <djarvie@kde.org>.
0559      */
0560     class KDELIBS4SUPPORT_EXPORT LeapSeconds
0561     {
0562     public:
0563         LeapSeconds();
0564         LeapSeconds(const QDateTime &utcTime, int leapSeconds, const QString &comment = QString());
0565         LeapSeconds(const LeapSeconds &c);
0566         ~LeapSeconds();
0567         LeapSeconds &operator=(const LeapSeconds &c);
0568         bool operator<(const LeapSeconds &c) const;    // needed by qSort()
0569 
0570         /**
0571          * Return whether this instance holds valid data.
0572          *
0573          * @return true if valid, false if invalid
0574          */
0575         bool isValid() const;
0576 
0577         /**
0578          * Return the UTC date/time when this change occurred.
0579          *
0580          * @return date/time
0581          */
0582         QDateTime dateTime() const;
0583 
0584         /**
0585          * Return the cumulative number of leap seconds to be added after this
0586          * change occurs.
0587          *
0588          * @return number of leap seconds
0589          */
0590         int leapSeconds() const;
0591 
0592         /**
0593          * Return the comment (if any) applying to this change.
0594          *
0595          * @return comment
0596          */
0597         QString comment() const;
0598 
0599     private:
0600         KTimeZoneLeapSecondsPrivate *const d;
0601     };
0602 
0603     /**
0604      * Constructs a null time zone. A null time zone is invalid.
0605      *
0606      * @see isValid()
0607      */
0608     KTimeZone();
0609 
0610     /**
0611      * Constructs a UTC time zone.
0612      *
0613      * @param name name of the UTC time zone
0614      */
0615     KDELIBS4SUPPORT_DEPRECATED explicit KTimeZone(const QString &name);
0616 
0617     KTimeZone(const KTimeZone &tz);
0618     KTimeZone &operator=(const KTimeZone &tz);
0619 
0620     virtual ~KTimeZone();
0621 
0622     /**
0623      * Checks whether this is the same instance as another one.
0624      * Note that only the pointers to the time zone data are compared, not the
0625      * contents. So it will only return equality if one instance was copied
0626      * from the other.
0627      *
0628      * @param rhs other instance
0629      * @return true if the same instance, else false
0630      */
0631     bool operator==(const KTimeZone &rhs) const;
0632     bool operator!=(const KTimeZone &rhs) const
0633     {
0634         return !operator==(rhs);
0635     }
0636 
0637     /**
0638      * Returns the class name of the data represented by this instance.
0639      * If a derived class object has been assigned to this instance, this
0640      * method will return the name of that class.
0641      *
0642      * @return "KTimeZone" or the class name of a derived class
0643      */
0644     QByteArray type() const;
0645 
0646     /**
0647      * Checks whether the instance is valid.
0648      *
0649      * @return true if valid, false if invalid
0650      */
0651     bool isValid() const;
0652 
0653     /**
0654      * Returns the name of the time zone.
0655      * If it is held in a KTimeZones container, the name is the time zone's unique
0656      * identifier within that KTimeZones instance.
0657      *
0658      * @return name in system-dependent format
0659      */
0660     QString name() const;
0661 
0662     /**
0663      * Returns the two-letter country code of the time zone.
0664      *
0665      * @return upper case ISO 3166 2-character country code, empty if unknown
0666      */
0667     QString countryCode() const;
0668 
0669     /**
0670      * Returns the latitude of the time zone.
0671      *
0672      * @return latitude in degrees, UNKNOWN if not known
0673      */
0674     float latitude() const;
0675 
0676     /**
0677      * Returns the latitude of the time zone.
0678      *
0679      * @return latitude in degrees, UNKNOWN if not known
0680      */
0681     float longitude() const;
0682 
0683     /**
0684      * Returns any comment for the time zone.
0685      *
0686      * @return comment, may be empty
0687      */
0688     QString comment() const;
0689 
0690     /**
0691      * Returns the list of time zone abbreviations used by the time zone.
0692      * This may include historical ones which are no longer in use or have
0693      * been superseded.
0694      *
0695      * @return list of abbreviations
0696      * @see abbreviation()
0697      */
0698     QList<QByteArray> abbreviations() const;
0699 
0700     /**
0701      * Returns the time zone abbreviation current at a specified time.
0702      *
0703      * @param utcDateTime UTC date/time. An error occurs if
0704      *                    @p utcDateTime.timeSpec() is not Qt::UTC.
0705      * @return time zone abbreviation, or empty string if error
0706      * @see abbreviations()
0707      */
0708     QByteArray abbreviation(const QDateTime &utcDateTime) const;
0709 
0710     /**
0711      * Returns the complete list of UTC offsets used by the time zone. This may
0712      * include historical ones which are no longer in use or have been
0713      * superseded.
0714      *
0715      * A UTC offset is the number of seconds which you must add to UTC to get
0716      * local time in this time zone.
0717      *
0718      * If due to the nature of the source data for the time zone, compiling a
0719      * complete list would require significant processing, an empty list is
0720      * returned instead.
0721      *
0722      * @return sorted list of UTC offsets, or empty list if not readily available.
0723      */
0724     QList<int> utcOffsets() const;
0725 
0726     /**
0727      * Converts a date/time, which is interpreted as being local time in this
0728      * time zone, into local time in another time zone.
0729      *
0730      * @param newZone other time zone which the time is to be converted into
0731      * @param zoneDateTime local date/time. An error occurs if
0732      *                     @p zoneDateTime.timeSpec() is not Qt::LocalTime.
0733      * @return converted date/time, or invalid date/time if error
0734      * @see toUtc(), toZoneTime()
0735      */
0736     QDateTime convert(const KTimeZone &newZone, const QDateTime &zoneDateTime) const;
0737 
0738     /**
0739      * Converts a date/time, which is interpreted as local time in this time
0740      * zone, into UTC.
0741      *
0742      * Because of daylight savings time shifts, the date/time may occur twice. In
0743      * such cases, this method returns the UTC time for the first occurrence.
0744      * If you need the UTC time of the second occurrence, use offsetAtZoneTime().
0745      *
0746      * @param zoneDateTime local date/time. An error occurs if
0747      *                     @p zoneDateTime.timeSpec() is not Qt::LocalTime.
0748      * @return UTC date/time, or invalid date/time if error
0749      * @see toZoneTime(), convert()
0750      */
0751     QDateTime toUtc(const QDateTime &zoneDateTime) const;
0752 
0753     /**
0754      * Converts a UTC date/time into local time in this time zone.
0755      *
0756      * Because of daylight savings time shifts, some local date/time values occur
0757      * twice. The @p secondOccurrence parameter may be used to determine whether
0758      * the time returned is the first or second occurrence of that time.
0759      *
0760      * @param utcDateTime UTC date/time. An error occurs if
0761      *                    @p utcDateTime.timeSpec() is not Qt::UTC.
0762      * @param secondOccurrence if non-null, returns @p true if the return value
0763      *                    is the second occurrence of that time, else @p false
0764      * @return local date/time, or invalid date/time if error
0765      * @see toUtc(), convert()
0766      */
0767     QDateTime toZoneTime(const QDateTime &utcDateTime, bool *secondOccurrence = nullptr) const;
0768 
0769     /**
0770      * Returns the current offset of this time zone to UTC or the local
0771      * system time zone. The offset is the number of seconds which you must
0772      * add to UTC or the local system time to get local time in this time zone.
0773      *
0774      * Take care if you cache the results of this routine; that would
0775      * break if the result were stored across a daylight savings change.
0776      *
0777      * @param basis Qt::UTC to return the offset to UTC, Qt::LocalTime
0778      *                  to return the offset to local system time
0779      * @return offset in seconds
0780      * @see offsetAtZoneTime(), offsetAtUtc()
0781      */
0782     int currentOffset(Qt::TimeSpec basis = Qt::UTC) const;
0783 
0784     /**
0785      * Returns the offset of this time zone to UTC at the given local date/time.
0786      * Because of daylight savings time shifts, the date/time may occur twice. Optionally,
0787      * the offsets at both occurrences of @p dateTime are calculated.
0788      *
0789      * The offset is the number of seconds which you must add to UTC to get
0790      * local time in this time zone.
0791      *
0792      * @param zoneDateTime the date/time at which the offset is to be calculated. This
0793      *                     is interpreted as a local time in this time zone. An error
0794      *                     occurs if @p zoneDateTime.timeSpec() is not Qt::LocalTime.
0795      * @param secondOffset if non-null, and the @p zoneDateTime occurs twice, receives the
0796      *                     UTC offset for the second occurrence. Otherwise, it is set
0797      *                     the same as the return value.
0798      * @return offset in seconds. If @p zoneDateTime occurs twice, it is the offset at the
0799      *         first occurrence which is returned. If @p zoneDateTime does not exist because
0800      *         of daylight savings time shifts, InvalidOffset is returned. If any other error
0801      *         occurs, 0 is returned.
0802      * @see offsetAtUtc(), currentOffset()
0803      */
0804     virtual int offsetAtZoneTime(const QDateTime &zoneDateTime, int *secondOffset = nullptr) const;
0805 
0806     /**
0807      * Returns the offset of this time zone to UTC at the given UTC date/time.
0808      *
0809      * The offset is the number of seconds which you must add to UTC to get
0810      * local time in this time zone.
0811      *
0812      * If a derived class needs to work in terms of time_t (as when accessing the
0813      * system time functions, for example), it should override both this method and
0814      * offset() so as to implement its offset calculations in offset(), and
0815      * reimplement this method simply as
0816      * \code
0817      *     offset(toTime_t(utcDateTime));
0818      * \endcode
0819      *
0820      * @param utcDateTime the UTC date/time at which the offset is to be calculated.
0821      *                    An error occurs if @p utcDateTime.timeSpec() is not Qt::UTC.
0822      * @return offset in seconds, or 0 if error
0823      * @see offset(), offsetAtZoneTime(), currentOffset()
0824      */
0825     virtual int offsetAtUtc(const QDateTime &utcDateTime) const;
0826 
0827     /**
0828      * Returns the offset of this time zone to UTC at a specified UTC time.
0829      *
0830      * The offset is the number of seconds which you must add to UTC to get
0831      * local time in this time zone.
0832      *
0833      * Note that time_t has a more limited range than QDateTime, so consider using
0834      * offsetAtUtc() instead.
0835      *
0836      * @param t the UTC time at which the offset is to be calculated, measured in seconds
0837      *          since 00:00:00 UTC 1st January 1970 (as returned by time(2))
0838      * @return offset in seconds, or 0 if error
0839      * @see offsetAtUtc()
0840      */
0841     virtual int offset(time_t t) const;
0842 
0843     /**
0844      * Returns whether daylight savings time is in operation at the given UTC date/time.
0845      *
0846      * If a derived class needs to work in terms of time_t (as when accessing the
0847      * system time functions, for example), it should override both this method and
0848      * isDst() so as to implement its offset calculations in isDst(), and reimplement
0849      * this method simply as
0850      * \code
0851      *     isDst(toTime_t(utcDateTime));
0852      * \endcode
0853      *
0854      * @param utcDateTime the UTC date/time. An error occurs if
0855      *                    @p utcDateTime.timeSpec() is not Qt::UTC.
0856      * @return @c true if daylight savings time is in operation, @c false otherwise
0857      * @see isDst()
0858      */
0859     virtual bool isDstAtUtc(const QDateTime &utcDateTime) const;
0860 
0861     /**
0862      * Returns whether daylight savings time is in operation at a specified UTC time.
0863      *
0864      * Note that time_t has a more limited range than QDateTime, so consider using
0865      * isDstAtUtc() instead.
0866      *
0867      * @param t the UTC time, measured in seconds since 00:00:00 UTC 1st January 1970
0868      *          (as returned by time(2))
0869      * @return @c true if daylight savings time is in operation, @c false otherwise
0870      * @see isDstAtUtc()
0871      */
0872     virtual bool isDst(time_t t) const;
0873 
0874     /**
0875      * Return all daylight savings time phases for the time zone.
0876      *
0877      * Note that some time zone data sources (such as system time zones accessed
0878      * via the system libraries) may not allow a list of daylight savings time
0879      * changes to be compiled easily. In such cases, this method will return an
0880      * empty list.
0881      *
0882      * @return list of phases
0883      */
0884     QList<Phase> phases() const;
0885 
0886     /**
0887      * Return whether daylight saving transitions are available for the time zone.
0888      *
0889      * The base class returns @c false.
0890      *
0891      * @return @c true if transitions are available, @c false if not
0892      * @see transitions(), transition()
0893      */
0894     virtual bool hasTransitions() const;
0895 
0896     /**
0897      * Return all daylight saving transitions, in time order. If desired, the
0898      * transitions returned may be restricted to a specified time range.
0899      *
0900      * Note that some time zone data sources (such as system time zones accessed
0901      * via the system libraries) may not allow a list of daylight saving time
0902      * changes to be compiled easily. In such cases, this method will return an
0903      * empty list.
0904      *
0905      * @param start start UTC date/time, or invalid date/time to return all transitions
0906      *              up to @p end. @p start.timeSpec() must be Qt::UTC, else
0907      *              @p start will be considered invalid.
0908      * @param end end UTC date/time, or invalid date/time for no end. @p end.timeSpec()
0909      *                must be Qt::UTC, else @p end will be considered invalid.
0910      * @return list of transitions, in time order
0911      * @see hasTransitions(), transition(), transitionTimes()
0912      */
0913     QList<KTimeZone::Transition> transitions(const QDateTime &start = QDateTime(), const QDateTime &end = QDateTime()) const;
0914 
0915     /**
0916      * Find the last daylight savings time transition at or before a given
0917      * UTC or local time.
0918      *
0919      * Because of daylight savings time shifts, a local time may occur twice or
0920      * may not occur at all. In the former case, the transitions at or before
0921      * both occurrences of @p dt may optionally be calculated and returned in
0922      * @p secondTransition. The latter case may optionally be detected by use of
0923      * @p validTime.
0924      *
0925      * @param dt date/time. @p dt.timeSpec() may be set to Qt::UTC or Qt::LocalTime.
0926      * @param secondTransition if non-null, and the @p dt occurs twice, receives the
0927      *                     transition for the second occurrence. Otherwise, it is set
0928      *                     the same as the return value.
0929      * @param validTime if non-null, is set to false if @p dt does not occur, or
0930      *                  to true otherwise
0931      * @return time zone transition, or null either if @p dt is either outside the
0932      *         defined range of the transition data or if @p dt does not occur
0933      * @see transitionIndex(), hasTransitions(), transitions()
0934      */
0935     const KTimeZone::Transition *transition(const QDateTime &dt, const Transition **secondTransition = nullptr, bool *validTime = nullptr) const;
0936 
0937     /**
0938      * Find the index to the last daylight savings time transition at or before
0939      * a given UTC or local time. The return value is the index into the transition
0940      * list returned by transitions().
0941      *
0942      * Because of daylight savings time shifts, a local time may occur twice or
0943      * may not occur at all. In the former case, the transitions at or before
0944      * both occurrences of @p dt may optionally be calculated and returned in
0945      * @p secondIndex. The latter case may optionally be detected by use of
0946      * @p validTime.
0947      *
0948      * @param dt date/time. @p dt.timeSpec() may be set to Qt::UTC or Qt::LocalTime.
0949      * @param secondIndex if non-null, and the @p dt occurs twice, receives the
0950      *                    index to the transition for the second occurrence. Otherwise,
0951      *                    it is set the same as the return value.
0952      * @param validTime if non-null, is set to false if @p dt does not occur, or
0953      *                  to true otherwise
0954      * @return index into the time zone transition list, or -1 either if @p dt is
0955      *         either outside the defined range of the transition data or if @p dt
0956      *         does not occur
0957      * @see transition(), transitions(), hasTransitions()
0958      */
0959     int transitionIndex(const QDateTime &dt, int *secondIndex = nullptr, bool *validTime = nullptr) const;
0960 
0961     /**
0962      * Return the times of all daylight saving transitions to a given time zone
0963      * phase, in time order. If desired, the times returned may be restricted to
0964      * a specified time range.
0965      *
0966      * Note that some time zone data sources (such as system time zones accessed
0967      * via the system libraries) may not allow a list of daylight saving time
0968      * changes to be compiled easily. In such cases, this method will return an
0969      * empty list.
0970      *
0971      * @param phase time zone phase
0972      * @param start start UTC date/time, or invalid date/time to return all transitions
0973      *              up to @p end. @p start.timeSpec() must be Qt::UTC, else
0974      *              @p start will be considered invalid.
0975      * @param end end UTC date/time, or invalid date/time for no end. @p end.timeSpec()
0976      *                must be Qt::UTC, else @p end will be considered invalid.
0977      * @return ordered list of transition times
0978      * @see hasTransitions(), transition(), transitions()
0979      */
0980     QList<QDateTime> transitionTimes(const Phase &phase, const QDateTime &start = QDateTime(), const QDateTime &end = QDateTime()) const;
0981 
0982     /**
0983      * Return all leap second adjustments, in time order.
0984      *
0985      * Note that some time zone data sources (such as system time zones accessed
0986      * via the system libraries) may not provide information on leap second
0987      * adjustments. In such cases, this method will return an empty list.
0988      *
0989      * @return list of adjustments
0990      */
0991     QList<LeapSeconds> leapSecondChanges() const;
0992 
0993     /**
0994      * Returns the source reader/parser for the time zone's source database.
0995      *
0996      * @return reader/parser
0997      */
0998     KTimeZoneSource *source() const;
0999 
1000     /**
1001      * Extracts time zone detail information for this time zone from the source database.
1002      *
1003      * @return @c false if the parse encountered errors, @c true otherwise
1004      */
1005     bool parse() const;
1006 
1007     /**
1008      * Returns the detailed parsed data for the time zone.
1009      * This will return null unless either parse() has been called beforehand, or
1010      * @p create is true.
1011      *
1012      * @param create true to parse the zone's data first if not already parsed
1013      * @return pointer to data, or null if data has not been parsed
1014      */
1015     const KTimeZoneData *data(bool create = false) const;
1016 
1017     /**
1018      * Update the definition of the time zone to be identical to another
1019      * KTimeZone instance. A prerequisite is that the two instances must
1020      * have the same name.
1021      *
1022      * The main purpose of this method is to allow updates of the time zone
1023      * definition by derived classes without invalidating pointers to the
1024      * instance (particularly pointers held by KDateTime objects). Note
1025      * that the KTimeZoneData object and KTimeZoneSource pointer are not
1026      * updated: the caller class should do this itself by calling setData().
1027      *
1028      * @param other time zone whose definition is to be used
1029      * @return true if definition was updated (i.e. names are the same)
1030      *
1031      * @see setData()
1032      */
1033     bool updateBase(const KTimeZone &other);
1034 
1035     /**
1036      * Converts a UTC time, measured in seconds since 00:00:00 UTC 1st January 1970
1037      * (as returned by time(2)), to a UTC QDateTime value.
1038      * QDateTime::setTime_t() is limited to handling @p t >= 0, since its parameter
1039      * is unsigned. This method takes a parameter of time_t which is signed.
1040      *
1041      * @return converted time
1042      * @see toTime_t()
1043      */
1044     static QDateTime fromTime_t(time_t t);
1045 
1046     /**
1047      * Converts a UTC QDateTime to a UTC time, measured in seconds since 00:00:00 UTC
1048      * 1st January 1970 (as returned by time(2)).
1049      * QDateTime::toTime_t() returns an unsigned value. This method returns a time_t
1050      * value, which is signed.
1051      *
1052      * @param utcDateTime date/time. An error occurs if @p utcDateTime.timeSpec() is
1053      *                    not Qt::UTC.
1054      * @return converted time, or -1 if the date is out of range for time_t or
1055      *         @p utcDateTime.timeSpec() is not Qt::UTC
1056      * @see fromTime_t()
1057      */
1058     static time_t toTime_t(const QDateTime &utcDateTime);
1059 
1060     /**
1061      * Returns a standard UTC time zone, with name "UTC".
1062      *
1063      * @note The KTimeZone returned by this method does not belong to any
1064      * KTimeZones collection. Any KTimeZones instance may contain its own UTC
1065      * KTimeZone defined by its time zone source data, but that will be a
1066      * different instance than this KTimeZone.
1067      *
1068      * @return UTC time zone
1069      */
1070     static KTimeZone utc();
1071 
1072     /** Indicates an invalid UTC offset. This is returned by offsetAtZoneTime() when
1073      *  the local time does not occur due to a shift to daylight savings time.
1074      */
1075     static const int InvalidOffset;
1076 
1077     /** Indicates an invalid time_t value.
1078      */
1079     static const time_t InvalidTime_t;
1080 
1081     /**
1082      * A representation for unknown locations; this is a float
1083      * that does not represent a real latitude or longitude.
1084      */
1085     static const float UNKNOWN;
1086 
1087 protected:
1088     KTimeZone(KTimeZoneBackend *impl);
1089 
1090     /**
1091      * Sets the detailed parsed data for the time zone, and optionally
1092      * a new time zone source object.
1093      *
1094      * @param data parsed data
1095      * @param source if non-null, the new source object for the time zone
1096      *
1097      * @see data()
1098      */
1099     void setData(KTimeZoneData *data, KTimeZoneSource *source = nullptr);
1100 
1101 private:
1102     KTimeZoneBackend *d;
1103 };
1104 
1105 /**
1106  * Base backend class for KTimeZone classes.
1107  *
1108  * KTimeZone and each class inherited from it must have a corresponding
1109  * backend class to implement its constructors and its virtual methods,
1110  * and to provide a virtual clone() method. This allows KTimeZone virtual methods
1111  * to work together with reference counting of private data.
1112  *
1113  * @note Classes derived from KTimeZoneBackend should not normally implement their
1114  * own copy constructor or assignment operator, and must have a non-const d-pointer.
1115  *
1116  * @short Base backend class for KTimeZone classes
1117  * @see KTimeZone
1118  * @ingroup timezones
1119  * @author David Jarvie <djarvie@kde.org>.
1120  */
1121 class KDELIBS4SUPPORT_EXPORT KTimeZoneBackend  //krazy:exclude=dpointer (non-const d-pointer for KTimeZoneBackend-derived classes)
1122 {
1123 public:
1124     /** Implements KTimeZone::KTimeZone(). */
1125     KTimeZoneBackend();
1126     /** Implements KTimeZone::KTimeZone(const QString&). */
1127     KDELIBS4SUPPORT_DEPRECATED explicit KTimeZoneBackend(const QString &name);
1128 
1129     KTimeZoneBackend(const KTimeZoneBackend &other);
1130     KTimeZoneBackend &operator=(const KTimeZoneBackend &other);
1131     virtual ~KTimeZoneBackend();
1132 
1133     /**
1134      * Creates a copy of this instance.
1135      *
1136      * @note Every inherited class must reimplement clone().
1137      *
1138      * @return new copy
1139      */
1140     virtual KTimeZoneBackend *clone() const;
1141 
1142     /**
1143      * Returns the class name of the data represented by this instance.
1144      *
1145      * @note Every inherited class must reimplement type().
1146      *
1147      * This base class returns "KTimeZone".
1148      *
1149      * @return the class name
1150      */
1151     virtual QByteArray type() const;
1152 
1153     /**
1154      * Implements KTimeZone::offsetAtZoneTime().
1155      *
1156      * @param caller calling KTimeZone object
1157      */
1158     virtual int offsetAtZoneTime(const KTimeZone *caller, const QDateTime &zoneDateTime, int *secondOffset) const;
1159     /**
1160      * Implements KTimeZone::offsetAtUtc().
1161      *
1162      * @param caller calling KTimeZone object
1163      */
1164     virtual int offsetAtUtc(const KTimeZone *caller, const QDateTime &utcDateTime) const;
1165     /**
1166      * Implements KTimeZone::offset().
1167      *
1168      * @param caller calling KTimeZone object
1169      */
1170     virtual int offset(const KTimeZone *caller, time_t t) const;
1171     /**
1172      * Implements KTimeZone::isDstAtUtc().
1173      *
1174      * @param caller calling KTimeZone object
1175      */
1176     virtual bool isDstAtUtc(const KTimeZone *caller, const QDateTime &utcDateTime) const;
1177     /**
1178      * Implements KTimeZone::isDst().
1179      *
1180      * @param caller calling KTimeZone object
1181      */
1182     virtual bool isDst(const KTimeZone *caller, time_t t) const;
1183     /**
1184      * Implements KTimeZone::hasTransitions().
1185      *
1186      * @param caller calling KTimeZone object
1187      */
1188     virtual bool hasTransitions(const KTimeZone *caller) const;
1189 
1190 protected:
1191     /**
1192      * Constructs a time zone.
1193      *
1194      * @param source      reader/parser for the database containing this time zone. This will
1195      *                    be an instance of a class derived from KTimeZoneSource.
1196      * @param name        in system-dependent format. The name must be unique within any
1197      *                    KTimeZones instance which contains this KTimeZone.
1198      * @param countryCode ISO 3166 2-character country code, empty if unknown
1199      * @param latitude    in degrees (between -90 and +90), UNKNOWN if not known
1200      * @param longitude   in degrees (between -180 and +180), UNKNOWN if not known
1201      * @param comment     description of the time zone, if any
1202      */
1203     KTimeZoneBackend(KTimeZoneSource *source, const QString &name,
1204                      const QString &countryCode = QString(), float latitude = KTimeZone::UNKNOWN,
1205                      float longitude = KTimeZone::UNKNOWN, const QString &comment = QString());
1206 
1207 private:
1208     KTimeZonePrivate *d;   // non-const
1209     friend class KTimeZone;
1210 };
1211 
1212 /**
1213  * Base class representing a source of time zone information.
1214  *
1215  * Derive subclasses from KTimeZoneSource to read and parse time zone details
1216  * from a time zone database or other source of time zone information. If can know
1217  * in advance what KTimeZone instances to create without having to parse the source
1218  * data, you should reimplement the virtual method parse(const KTimeZone&). Otherwise,
1219  * you need to define your own parse() methods with appropriate signatures, to both
1220  * read and parse the new data, and create new KTimeZone instances.
1221  *
1222  * KTimeZoneSource itself may be used as a dummy source which returns empty
1223  * time zone details.
1224  *
1225  * @short Base class representing a source of time zone information
1226  * @see KTimeZone, KTimeZoneData
1227  * @ingroup timezones
1228  * @author David Jarvie <djarvie@kde.org>.
1229  * @author S.R.Haque <srhaque@iee.org>.
1230  */
1231 class KDELIBS4SUPPORT_EXPORT KTimeZoneSource
1232 {
1233 public:
1234     KTimeZoneSource();
1235     virtual ~KTimeZoneSource();
1236 
1237     /**
1238      * Extracts detail information for one time zone from the source database.
1239      *
1240      * In this base class, the method always succeeds and returns an empty data
1241      * instance. Derived classes should reimplement this method to return an
1242      * appropriate data class derived from KTimeZoneData. Some source databases
1243      * may not be compatible with this method of parsing. In these cases, they
1244      * should use the constructor KTimeZoneSource(false) and calling this method
1245      * will produce a fatal error.
1246      *
1247      * @param zone the time zone for which data is to be extracted.
1248      * @return an instance of a class derived from KTimeZoneData containing
1249      *         the parsed data. The caller is responsible for deleting the
1250      *         KTimeZoneData instance.
1251      *         Null is returned on error.
1252      */
1253     virtual KTimeZoneData *parse(const KTimeZone &zone) const;
1254 
1255     /**
1256      * Return whether the source database supports the ad hoc extraction of data for
1257      * individual time zones using parse(const KTimeZone&).
1258      *
1259      * @return true if parse(const KTimeZone&) works, false if parsing must be
1260      *         performed by other methods
1261      */
1262     bool useZoneParse() const;
1263 
1264 protected:
1265     /**
1266      * Constructor for use by derived classes, which specifies whether the
1267      * source database supports the ad hoc extraction of data for individual
1268      * time zones using parse(const KTimeZone&).
1269      *
1270      * If parse(const KTimeZone&) cannot be used, KTimeZone derived classes
1271      * which use this KTimeZoneSource derived class must create a
1272      * KTimeZoneData object at construction time so that KTimeZone::data()
1273      * will always return a data object.
1274      *
1275      * Note the default constructor is equivalent to KTimeZoneSource(true), i.e.
1276      * it is only necessary to use this constructor if parse(const KTimeZone&)
1277      * does not work.
1278      *
1279      * @param useZoneParse true if parse(const KTimeZone&) works, false if
1280      *                     parsing must be performed by other methods
1281      */
1282     KDELIBS4SUPPORT_DEPRECATED explicit KTimeZoneSource(bool useZoneParse);
1283 
1284 private:
1285     KTimeZoneSourcePrivate *const d;
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  */
1302 class KDELIBS4SUPPORT_EXPORT KTimeZoneData
1303 {
1304     friend class KTimeZone;
1305 
1306 public:
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 = nullptr, bool *validTime = nullptr) 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 = nullptr, bool *validTime = nullptr) 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 
1488 protected:
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 
1528 private:
1529     KTimeZoneDataPrivate *const d;
1530 };
1531 
1532 #endif