summaryrefslogtreecommitdiffstats
path: root/kdecore/ktimezones.h
blob: 3055f202f4d7177b6459a3237750ff5b1ec65a84 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
/*
   This file is part of the KDE libraries
   Copyright (c) 2005 S.R.Haque <[email protected]>.

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License version 2 as published by the Free Software Foundation.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.
*/

#ifndef _KTIMEZONES_H
#define _KTIMEZONES_H

#include "kdelibs_export.h"
#include <tqdatetime.h>
#include <tqnamespace.h>
#include <tqmap.h>
#include <tqstring.h>
#include <ksharedptr.h>

class KTimezoneDetails;
class KTimezoneDetailsPrivate;
class KTimezonePrivate;
class KTimezonesPrivate;

/**
 * The KTimezoneSource class contains information source-dependent functions
 * related to a timezone. Create subclasses to implement custom sources of
 * timezone information.
 *
 * For example, to be able to create {@link KTimezone } objects from libical's
 * VTIMEZONE objects:
 *<ul>
 *      <li>Subclass this class with a custom {@link parse() } routine.
 *      <li>Create one or more instances of this class.
 *      <li>Use the instance(s) to create {@link KTimezone } objects.
 *      <li>If required, add the objects to a {@link KTimezones } database.
 *</ul>
 * @since 3.5
 * @author S.R.Haque <[email protected]>.
 */
class KDECORE_EXPORT KTimezoneSource :
    public KShared
{
public:
    KTimezoneSource(const TQString &db);
    virtual ~KTimezoneSource();

    /**
     * Location of system timezone information.
     * @return value which can be combined with zone name to retrieve timezone info.
     */
    virtual TQString db();

    /**
     * Extract timezone detail information. The default implementation consists
     * of a parser for zoneinfo files in tzfile(5).
     * @return true if the parse encountered no errors.
     */
    virtual bool parse(const TQString &zone, KTimezoneDetails &dataReceiver) const;

private:
    TQString m_db;
};

/**
 * The KTimezone class contains core functions related to a timezone. Instances
 * are created in the context of a {@link KTimezoneSource } which provides
 * extended functionality via {@link KTimezoneDetails }.
 *
 * @see KTimezoneSource
 * @see KTimezoneDetails
 * @since 3.5
 * @author S.R.Haque <[email protected]>.
 */
class KDECORE_EXPORT KTimezone
{
public:
    /**
     * A representation for unknown locations; this is a float
     * that does not represent a real latitude or longitude.
     */
    static const float UNKNOWN;

    /**
     * A test for a valid latitude. The valid range is +90.0 (North Pole)
     * to -90.0 (South Pole).
     */
    static bool isValidLatitude(float latitude);

    /**
     * A test for a valid longitude. The valid range is +180.0 (east of
     * Greenwich) to -180.0 (west of Greenwich).
     */
    static bool isValidLongitude(float longitude);

    /**
     * Create a timezone.
     *
     * @param db database of timezones.
     * @param name in system-dependent format.
     * @param countryCode ISO 3166 2-character country code, empty if unknown.
     * @param latitude in degrees, UNKNOWN if not known.
     * @param longitude in degrees, UNKNOWN if not known.
     * @param comment description of the timezone, if any.
     */
    KTimezone(
        KSharedPtr<KTimezoneSource> db, const TQString &name,
        const TQString &countryCode = TQString(), float latitude = UNKNOWN, float longitude = UNKNOWN,
        const TQString &comment = TQString());
    ~KTimezone();

    /**
     * Returns the name of the timezone.
     *
     * @return name in system-dependent format.
     */
    TQString name() const;

    /**
     * Returns the two-letter country code of the timezone.
     *
     * @return ISO 3166 2-character country code, empty if unknown.
     */
    TQString countryCode() const;

    /**
     * Returns the latitude of the timezone.
     *
     * @return latitude in degrees, UNKNOWN if not known.
     */
    float latitude() const;

    /**
     * Returns the latitude of the timezone.
     *
     * @return latitude in degrees, UNKNOWN if not known.
     */
    float longitude() const;

    /**
     * Returns the current offset of this timezone to UTC or the local
     * timezone in seconds.
     *
     * Take care if you cache the results of this routine; that would
     * break if the result were stored across a daylight savings change.
     *
     * @return offset in seconds.
     */
    int offset(Qt::TimeSpec basisSpec = Qt::UTC) const;

    /**
     * Returns the offset of the given timezone to UTC at the given
     * date/time (which is interpreted as being UTC).
     *
     * @return offset in seconds.
     */
    int offset(const TQDateTime &dateTime) const;

    /**
     * Convert a date/time (which is interpreted as being localtime in this
     * timezone) into localtime in the given timezone.
     *
     * @return converted date/time.
     */
    TQDateTime convert(const KTimezone *newZone, const TQDateTime &dateTime) const;

    /**
     * Returns any comment for the timezone.
     *
     * @return comment, may be empty.
     */
    TQString comment() const;

    /**
     * Extract timezone detail information.
     * @return true if the parse encountered no errors.
     */
    bool parse(KTimezoneDetails &dataReceiver) const;

private:
    KTimezone(const KTimezone&);
    KTimezone& operator=(const KTimezone&);

    KSharedPtr<KTimezoneSource> m_db;
    TQString m_name;
    TQString m_countryCode;
    float m_latitude;
    float m_longitude;
    TQString m_comment;
    KTimezonePrivate *d;
};

/**
 * The KTimezoneDetails class contains extended functions related to a
 * timezone.
 *
 * The parser must be customised by overriding the given virtual callbacks:
 *<ul>
 *    <li>{@link parseEnded() }
 *    <li>{@link parseStarted() }
 *    <li>{@link gotHeader() }
 *    <li>{@link gotTransitionTime() }
 *    <li>{@link gotLocalTimeIndex() }
 *    <li>{@link gotLocalTime() }
 *    <li>{@link gotAbbreviation() }
 *    <li>{@link gotLeapAdjustment() }
 *    <li>{@link gotIsStandard() }
 *    <li>{@link gotIsUTC() }
 *</ul>
 *
 * @see KTimezone
 * @since 3.5
 * @author S.R.Haque <[email protected]>.
 */
class KDECORE_EXPORT KTimezoneDetails
{
public:
    KTimezoneDetails();
    virtual ~KTimezoneDetails();

    /**
     * Always called after all other callbacks.
     */
    virtual void parseEnded();

    /**
     * Always called before any other callback.
     */
    virtual void parseStarted();

    /**
     * Called when the header is seen.
     */
    virtual void gotHeader(
        unsigned ttIsGmtCnt, unsigned ttIsStdCnt, unsigned leapCnt,
        unsigned timeCnt, unsigned typeCnt, unsigned charCnt);

    /**
     * Called when a transition time is seen.
     */
    virtual void gotTransitionTime(int index, unsigned transitionTime);

    /**
     * Called when a local time index is seen.
     */
    virtual void gotLocalTimeIndex(int index, unsigned localTimeIndex);

    /**
     * Called when a local time is seen.
     */
    virtual void gotLocalTime(int index, int gmtOff, bool isDst, unsigned abbrIndex);

    /**
     * Called when a timezone abbreviation is seen. Note that the index here
     * is NOT a simple incrementing integer, rather it matches the sequence
     * of abbrIndex values from {@link gotLocalTime() }.
     */
    virtual void gotAbbreviation(int index, const TQString &abbr);

    /**
     * Called when a leap second adjustment is seen.
     */
    virtual void gotLeapAdjustment(int index, unsigned leapTime, unsigned leapSeconds);

    /**
     * Called when a standard/wall time indicator is seen.
     */
    virtual void gotIsStandard(int index, bool isStandard);

    /**
     * Called when a UTC/local time indicator is seen.
     */
    virtual void gotIsUTC(int index, bool isUTC);

private:
    KTimezoneDetailsPrivate *d;
};

/**
 * The KTimezones class models a timezone database. It supports system
 * timezones, and also has support for private timezone entries.
 *
 * @since 3.5
 * @author S.R.Haque <[email protected]>.
 */
class KDECORE_EXPORT KTimezones
{
public:
    KTimezones();
    ~KTimezones();

    /**
     * Returns the local timezone. The idea of this routine is to provide a
     * robust lookup of the local timezone.
     *
     * The problem is that on Unix systems, there are a variety of mechanisms
     * for setting this information, and no real way of getting it. For example,
     * if you set your timezone to "Europe/London", then the tzname[]
     * maintained by tzset() typically returns { "GMT", "BST" }. The point of
     * this routine is to actually return "Europe/London" (or rather, the
     * corresponding KTimezone).
     *
     * @return local timezone. If necessary, we will use a series of heuristics
     *         which end by returning UTC. We will never return NULL.
     */
    const KTimezone *local();

    /**
     * Returns the given timezone.
     *
     * @param name Name of timezone. Empty is equivalent to UTC.
     * @return named timezone, NULL on error.
     */
    const KTimezone *zone(const TQString &name);

    typedef TQMap<TQString, KTimezone *> ZoneMap;

    /**
     * Return timezone database.
     * @return known timezones.
     */
    const ZoneMap allZones();

    /**
     * Add user-defined timezone to database.
     */
    void add(KTimezone *zone);

private:
    KTimezones(const KTimezones&);
    KTimezones& operator=(const KTimezones&);

    float convertCoordinate(const TQString &coordinate);

    TQString m_zoneinfoDir;
    ZoneMap *m_zones;
    KTimezone *m_UTC;
    KTimezonesPrivate *d;
};

#endif