1 | // Copyright (C) 2022 The Qt Company Ltd. |
2 | // Copyright (C) 2013 John Layt <jlayt@kde.org> |
3 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
4 | |
5 | |
6 | #ifndef QTIMEZONEPRIVATE_P_H |
7 | #define QTIMEZONEPRIVATE_P_H |
8 | |
9 | // |
10 | // W A R N I N G |
11 | // ------------- |
12 | // |
13 | // This file is not part of the Qt API. It exists for the convenience |
14 | // of internal files. This header file may change from version to version |
15 | // without notice, or even be removed. |
16 | // |
17 | // We mean it. |
18 | // |
19 | |
20 | #include "qlist.h" |
21 | #include "qtimezone.h" |
22 | #include "private/qlocale_p.h" |
23 | #include "private/qdatetime_p.h" |
24 | |
25 | #if QT_CONFIG(icu) |
26 | #include <unicode/ucal.h> |
27 | #endif |
28 | |
29 | #ifdef Q_OS_DARWIN |
30 | Q_FORWARD_DECLARE_OBJC_CLASS(NSTimeZone); |
31 | #endif // Q_OS_DARWIN |
32 | |
33 | #ifdef Q_OS_WIN |
34 | #include <qt_windows.h> |
35 | #endif // Q_OS_WIN |
36 | |
37 | #ifdef Q_OS_ANDROID |
38 | #include <QJniObject> |
39 | #endif |
40 | |
41 | QT_REQUIRE_CONFIG(timezone); |
42 | QT_BEGIN_NAMESPACE |
43 | |
44 | class Q_AUTOTEST_EXPORT QTimeZonePrivate : public QSharedData |
45 | { |
46 | public: |
47 | // Version of QTimeZone::OffsetData struct using msecs for efficiency |
48 | struct Data { |
49 | QString abbreviation; |
50 | qint64 atMSecsSinceEpoch; |
51 | int offsetFromUtc; |
52 | int standardTimeOffset; |
53 | int daylightTimeOffset; |
54 | Data() |
55 | : atMSecsSinceEpoch(QTimeZonePrivate::invalidMSecs()), |
56 | offsetFromUtc(QTimeZonePrivate::invalidSeconds()), |
57 | standardTimeOffset(QTimeZonePrivate::invalidSeconds()), |
58 | daylightTimeOffset(QTimeZonePrivate::invalidSeconds()) |
59 | {} |
60 | Data(const QString &name, qint64 when, int offset, int standard) |
61 | : abbreviation(name), |
62 | atMSecsSinceEpoch(when), |
63 | offsetFromUtc(offset), |
64 | standardTimeOffset(standard), |
65 | daylightTimeOffset(offset - standard) |
66 | {} |
67 | }; |
68 | typedef QList<Data> DataList; |
69 | |
70 | // Create null time zone |
71 | QTimeZonePrivate(); |
72 | QTimeZonePrivate(const QTimeZonePrivate &other); |
73 | virtual ~QTimeZonePrivate(); |
74 | |
75 | virtual QTimeZonePrivate *clone() const; |
76 | |
77 | bool operator==(const QTimeZonePrivate &other) const; |
78 | bool operator!=(const QTimeZonePrivate &other) const; |
79 | |
80 | bool isValid() const; |
81 | |
82 | QByteArray id() const; |
83 | virtual QLocale::Territory territory() const; |
84 | virtual QString () const; |
85 | |
86 | virtual QString displayName(qint64 atMSecsSinceEpoch, |
87 | QTimeZone::NameType nameType, |
88 | const QLocale &locale) const; |
89 | virtual QString displayName(QTimeZone::TimeType timeType, |
90 | QTimeZone::NameType nameType, |
91 | const QLocale &locale) const; |
92 | virtual QString abbreviation(qint64 atMSecsSinceEpoch) const; |
93 | |
94 | virtual int offsetFromUtc(qint64 atMSecsSinceEpoch) const; |
95 | virtual int standardTimeOffset(qint64 atMSecsSinceEpoch) const; |
96 | virtual int daylightTimeOffset(qint64 atMSecsSinceEpoch) const; |
97 | |
98 | virtual bool hasDaylightTime() const; |
99 | virtual bool isDaylightTime(qint64 atMSecsSinceEpoch) const; |
100 | |
101 | virtual Data data(qint64 forMSecsSinceEpoch) const; |
102 | virtual Data data(QTimeZone::TimeType timeType) const; |
103 | virtual bool isDataLocale(const QLocale &locale) const; |
104 | QDateTimePrivate::ZoneState stateAtZoneTime(qint64 forLocalMSecs, |
105 | QDateTimePrivate::TransitionOptions resolve) const; |
106 | |
107 | virtual bool hasTransitions() const; |
108 | virtual Data nextTransition(qint64 afterMSecsSinceEpoch) const; |
109 | virtual Data previousTransition(qint64 beforeMSecsSinceEpoch) const; |
110 | DataList transitions(qint64 fromMSecsSinceEpoch, qint64 toMSecsSinceEpoch) const; |
111 | |
112 | virtual QByteArray systemTimeZoneId() const; |
113 | |
114 | virtual bool isTimeZoneIdAvailable(const QByteArray &ianaId) const; |
115 | virtual QList<QByteArray> availableTimeZoneIds() const; |
116 | virtual QList<QByteArray> availableTimeZoneIds(QLocale::Territory territory) const; |
117 | virtual QList<QByteArray> availableTimeZoneIds(int utcOffset) const; |
118 | |
119 | virtual void serialize(QDataStream &ds) const; |
120 | |
121 | // Static Utility Methods |
122 | [[nodiscard]] static constexpr qint64 maxMSecs() |
123 | { return (std::numeric_limits<qint64>::max)(); } |
124 | [[nodiscard]] static constexpr qint64 minMSecs() |
125 | { return (std::numeric_limits<qint64>::min)() + 1; } |
126 | [[nodiscard]] static constexpr qint64 invalidMSecs() |
127 | { return (std::numeric_limits<qint64>::min)(); } |
128 | [[nodiscard]] static constexpr int invalidSeconds() |
129 | { return (std::numeric_limits<int>::min)(); } |
130 | static QTimeZone::OffsetData invalidOffsetData(); |
131 | static QTimeZone::OffsetData toOffsetData(const Data &data); |
132 | static bool isValidId(const QByteArray &ianaId); |
133 | static QString isoOffsetFormat(int offsetFromUtc, |
134 | QTimeZone::NameType mode = QTimeZone::OffsetName); |
135 | |
136 | static QByteArray aliasToIana(QByteArrayView alias); |
137 | static QByteArray ianaIdToWindowsId(const QByteArray &ianaId); |
138 | static QByteArray windowsIdToDefaultIanaId(const QByteArray &windowsId); |
139 | static QByteArray windowsIdToDefaultIanaId(const QByteArray &windowsId, |
140 | QLocale::Territory territory); |
141 | static QList<QByteArray> windowsIdToIanaIds(const QByteArray &windowsId); |
142 | static QList<QByteArray> windowsIdToIanaIds(const QByteArray &windowsId, |
143 | QLocale::Territory territory); |
144 | |
145 | // returns "UTC" QString and QByteArray |
146 | [[nodiscard]] static inline QString utcQString() |
147 | { |
148 | return QStringLiteral("UTC" ); |
149 | } |
150 | |
151 | [[nodiscard]] static inline QByteArray utcQByteArray() |
152 | { |
153 | return QByteArrayLiteral("UTC" ); |
154 | } |
155 | |
156 | protected: |
157 | // Zones CLDR data says match a condition. |
158 | // Use to filter what the backend has available. |
159 | QList<QByteArrayView> matchingTimeZoneIds(QLocale::Territory territory) const; |
160 | QList<QByteArrayView> matchingTimeZoneIds(int utcOffset) const; |
161 | |
162 | #if QT_CONFIG(timezone_locale) |
163 | private: |
164 | // Defined in qtimezonelocale.cpp |
165 | QString localeName(qint64 atMSecsSinceEpoch, int offsetFromUtc, |
166 | QTimeZone::TimeType timeType, |
167 | QTimeZone::NameType nameType, |
168 | const QLocale &locale) const; |
169 | #endif // L10n helpers. |
170 | |
171 | protected: |
172 | QByteArray m_id; |
173 | }; |
174 | Q_DECLARE_TYPEINFO(QTimeZonePrivate::Data, Q_RELOCATABLE_TYPE); |
175 | |
176 | template<> QTimeZonePrivate *QSharedDataPointer<QTimeZonePrivate>::clone(); |
177 | |
178 | class Q_AUTOTEST_EXPORT QUtcTimeZonePrivate final : public QTimeZonePrivate |
179 | { |
180 | public: |
181 | // Create default UTC time zone |
182 | QUtcTimeZonePrivate(); |
183 | // Create named time zone |
184 | QUtcTimeZonePrivate(const QByteArray &utcId); |
185 | // Create offset from UTC |
186 | QUtcTimeZonePrivate(qint32 offsetSeconds); |
187 | // Create custom offset from UTC |
188 | QUtcTimeZonePrivate(const QByteArray &zoneId, int offsetSeconds, const QString &name, |
189 | const QString &abbreviation, QLocale::Territory territory, |
190 | const QString &); |
191 | QUtcTimeZonePrivate(const QUtcTimeZonePrivate &other); |
192 | virtual ~QUtcTimeZonePrivate(); |
193 | |
194 | // Fall-back for UTC[+-]\d+(:\d+){,2} IDs. |
195 | static qint64 offsetFromUtcString(QByteArrayView id); |
196 | |
197 | QUtcTimeZonePrivate *clone() const override; |
198 | |
199 | Data data(qint64 forMSecsSinceEpoch) const override; |
200 | Data data(QTimeZone::TimeType timeType) const override; |
201 | bool isDataLocale(const QLocale &locale) const override; |
202 | |
203 | QLocale::Territory territory() const override; |
204 | QString () const override; |
205 | |
206 | QString displayName(qint64 atMSecsSinceEpoch, |
207 | QTimeZone::NameType nameType, |
208 | const QLocale &locale) const override; |
209 | QString displayName(QTimeZone::TimeType timeType, |
210 | QTimeZone::NameType nameType, |
211 | const QLocale &locale) const override; |
212 | QString abbreviation(qint64 atMSecsSinceEpoch) const override; |
213 | |
214 | int standardTimeOffset(qint64 atMSecsSinceEpoch) const override; |
215 | int daylightTimeOffset(qint64 atMSecsSinceEpoch) const override; |
216 | |
217 | QByteArray systemTimeZoneId() const override; |
218 | |
219 | bool isTimeZoneIdAvailable(const QByteArray &ianaId) const override; |
220 | QList<QByteArray> availableTimeZoneIds() const override; |
221 | QList<QByteArray> availableTimeZoneIds(QLocale::Territory country) const override; |
222 | QList<QByteArray> availableTimeZoneIds(int utcOffset) const override; |
223 | |
224 | void serialize(QDataStream &ds) const override; |
225 | |
226 | private: |
227 | void init(const QByteArray &zoneId, int offsetSeconds, const QString &name, |
228 | const QString &abbreviation, QLocale::Territory territory, |
229 | const QString &); |
230 | |
231 | QString m_name; |
232 | QString m_abbreviation; |
233 | QString ; |
234 | QLocale::Territory m_territory; |
235 | int m_offsetFromUtc; |
236 | }; |
237 | |
238 | // TODO: shuffle (almost reverse) order of and rework #if-ery here to use #elif |
239 | // and match the #if-ery in each of QTZ's newBackendTimeZone() cascades for |
240 | // backend selection. |
241 | #if QT_CONFIG(icu) && !defined(Q_OS_UNIX) |
242 | class Q_AUTOTEST_EXPORT QIcuTimeZonePrivate final : public QTimeZonePrivate |
243 | { |
244 | public: |
245 | // Create default time zone |
246 | QIcuTimeZonePrivate(); |
247 | // Create named time zone |
248 | QIcuTimeZonePrivate(const QByteArray &ianaId); |
249 | QIcuTimeZonePrivate(const QIcuTimeZonePrivate &other); |
250 | ~QIcuTimeZonePrivate(); |
251 | |
252 | QIcuTimeZonePrivate *clone() const override; |
253 | |
254 | using QTimeZonePrivate::displayName; |
255 | QString displayName(QTimeZone::TimeType timeType, QTimeZone::NameType nameType, |
256 | const QLocale &locale) const override; |
257 | |
258 | int offsetFromUtc(qint64 atMSecsSinceEpoch) const override; |
259 | int standardTimeOffset(qint64 atMSecsSinceEpoch) const override; |
260 | int daylightTimeOffset(qint64 atMSecsSinceEpoch) const override; |
261 | |
262 | bool hasDaylightTime() const override; |
263 | bool isDaylightTime(qint64 atMSecsSinceEpoch) const override; |
264 | |
265 | using QTimeZonePrivate::data; |
266 | Data data(qint64 forMSecsSinceEpoch) const override; |
267 | |
268 | bool hasTransitions() const override; |
269 | Data nextTransition(qint64 afterMSecsSinceEpoch) const override; |
270 | Data previousTransition(qint64 beforeMSecsSinceEpoch) const override; |
271 | |
272 | QByteArray systemTimeZoneId() const override; |
273 | |
274 | bool isTimeZoneIdAvailable(const QByteArray &ianaId) const override; |
275 | QList<QByteArray> availableTimeZoneIds() const override; |
276 | QList<QByteArray> availableTimeZoneIds(QLocale::Territory territory) const override; |
277 | QList<QByteArray> availableTimeZoneIds(int offsetFromUtc) const override; |
278 | |
279 | private: |
280 | void init(const QByteArray &ianaId); |
281 | |
282 | UCalendar *m_ucal; |
283 | }; |
284 | #endif // ICU not on Unix. |
285 | |
286 | #if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN) && !defined(Q_OS_ANDROID) |
287 | struct QTzTransitionTime |
288 | { |
289 | qint64 atMSecsSinceEpoch; |
290 | quint8 ruleIndex; |
291 | }; |
292 | Q_DECLARE_TYPEINFO(QTzTransitionTime, Q_PRIMITIVE_TYPE); |
293 | struct QTzTransitionRule |
294 | { |
295 | int stdOffset = 0; |
296 | int dstOffset = 0; |
297 | quint8 abbreviationIndex = 0; |
298 | }; |
299 | Q_DECLARE_TYPEINFO(QTzTransitionRule, Q_PRIMITIVE_TYPE); |
300 | constexpr inline bool operator==(const QTzTransitionRule &lhs, const QTzTransitionRule &rhs) noexcept |
301 | { return lhs.stdOffset == rhs.stdOffset && lhs.dstOffset == rhs.dstOffset && lhs.abbreviationIndex == rhs.abbreviationIndex; } |
302 | constexpr inline bool operator!=(const QTzTransitionRule &lhs, const QTzTransitionRule &rhs) noexcept |
303 | { return !operator==(lhs, rhs); } |
304 | |
305 | // These are stored separately from QTzTimeZonePrivate so that they can be |
306 | // cached, avoiding the need to re-parse them from disk constantly. |
307 | struct QTzTimeZoneCacheEntry |
308 | { |
309 | QList<QTzTransitionTime> m_tranTimes; |
310 | QList<QTzTransitionRule> m_tranRules; |
311 | QList<QByteArray> m_abbreviations; |
312 | QByteArray m_posixRule; |
313 | QTzTransitionRule m_preZoneRule; |
314 | bool m_hasDst = false; |
315 | }; |
316 | |
317 | class Q_AUTOTEST_EXPORT QTzTimeZonePrivate final : public QTimeZonePrivate |
318 | { |
319 | QTzTimeZonePrivate(const QTzTimeZonePrivate &) = default; |
320 | public: |
321 | // Create default time zone |
322 | QTzTimeZonePrivate(); |
323 | // Create named time zone |
324 | QTzTimeZonePrivate(const QByteArray &ianaId); |
325 | ~QTzTimeZonePrivate(); |
326 | |
327 | QTzTimeZonePrivate *clone() const override; |
328 | |
329 | QLocale::Territory territory() const override; |
330 | QString () const override; |
331 | |
332 | using QTimeZonePrivate::displayName; |
333 | QString displayName(QTimeZone::TimeType timeType, |
334 | QTimeZone::NameType nameType, |
335 | const QLocale &locale) const override; |
336 | QString abbreviation(qint64 atMSecsSinceEpoch) const override; |
337 | |
338 | int offsetFromUtc(qint64 atMSecsSinceEpoch) const override; |
339 | int standardTimeOffset(qint64 atMSecsSinceEpoch) const override; |
340 | int daylightTimeOffset(qint64 atMSecsSinceEpoch) const override; |
341 | |
342 | bool hasDaylightTime() const override; |
343 | bool isDaylightTime(qint64 atMSecsSinceEpoch) const override; |
344 | |
345 | Data data(qint64 forMSecsSinceEpoch) const override; |
346 | Data data(QTimeZone::TimeType timeType) const override; |
347 | bool isDataLocale(const QLocale &locale) const override; |
348 | |
349 | bool hasTransitions() const override; |
350 | Data nextTransition(qint64 afterMSecsSinceEpoch) const override; |
351 | Data previousTransition(qint64 beforeMSecsSinceEpoch) const override; |
352 | |
353 | QByteArray systemTimeZoneId() const override; |
354 | |
355 | bool isTimeZoneIdAvailable(const QByteArray &ianaId) const override; |
356 | QList<QByteArray> availableTimeZoneIds() const override; |
357 | QList<QByteArray> availableTimeZoneIds(QLocale::Territory territory) const override; |
358 | |
359 | private: |
360 | static QByteArray staticSystemTimeZoneId(); |
361 | QList<QTimeZonePrivate::Data> getPosixTransitions(qint64 msNear) const; |
362 | |
363 | Data dataForTzTransition(QTzTransitionTime tran) const; |
364 | Data dataFromRule(QTzTransitionRule rule, qint64 msecsSinceEpoch) const; |
365 | QTzTimeZoneCacheEntry cached_data; |
366 | const QList<QTzTransitionTime> &tranCache() const { return cached_data.m_tranTimes; } |
367 | }; |
368 | #endif // Q_OS_UNIX |
369 | |
370 | #ifdef Q_OS_DARWIN |
371 | class Q_AUTOTEST_EXPORT QMacTimeZonePrivate final : public QTimeZonePrivate |
372 | { |
373 | public: |
374 | // Create default time zone |
375 | QMacTimeZonePrivate(); |
376 | // Create named time zone |
377 | QMacTimeZonePrivate(const QByteArray &ianaId); |
378 | QMacTimeZonePrivate(const QMacTimeZonePrivate &other); |
379 | ~QMacTimeZonePrivate(); |
380 | |
381 | QMacTimeZonePrivate *clone() const override; |
382 | |
383 | QString comment() const override; |
384 | |
385 | using QTimeZonePrivate::displayName; |
386 | QString displayName(QTimeZone::TimeType timeType, QTimeZone::NameType nameType, |
387 | const QLocale &locale) const override; |
388 | QString abbreviation(qint64 atMSecsSinceEpoch) const override; |
389 | |
390 | int offsetFromUtc(qint64 atMSecsSinceEpoch) const override; |
391 | int standardTimeOffset(qint64 atMSecsSinceEpoch) const override; |
392 | int daylightTimeOffset(qint64 atMSecsSinceEpoch) const override; |
393 | |
394 | bool hasDaylightTime() const override; |
395 | bool isDaylightTime(qint64 atMSecsSinceEpoch) const override; |
396 | |
397 | using QTimeZonePrivate::data; |
398 | Data data(qint64 forMSecsSinceEpoch) const override; |
399 | |
400 | bool hasTransitions() const override; |
401 | Data nextTransition(qint64 afterMSecsSinceEpoch) const override; |
402 | Data previousTransition(qint64 beforeMSecsSinceEpoch) const override; |
403 | |
404 | QByteArray systemTimeZoneId() const override; |
405 | bool isTimeZoneIdAvailable(const QByteArray &ianaId) const override; |
406 | QList<QByteArray> availableTimeZoneIds() const override; |
407 | |
408 | NSTimeZone *nsTimeZone() const; |
409 | |
410 | private: |
411 | void init(const QByteArray &zoneId); |
412 | |
413 | NSTimeZone *m_nstz; |
414 | }; |
415 | #endif // Q_OS_DARWIN |
416 | |
417 | #if defined(Q_OS_WIN) && !QT_CONFIG(icu) |
418 | class Q_AUTOTEST_EXPORT QWinTimeZonePrivate final : public QTimeZonePrivate |
419 | { |
420 | public: |
421 | struct QWinTransitionRule { |
422 | int startYear; |
423 | int standardTimeBias; |
424 | int daylightTimeBias; |
425 | SYSTEMTIME standardTimeRule; |
426 | SYSTEMTIME daylightTimeRule; |
427 | }; |
428 | |
429 | // Create default time zone |
430 | QWinTimeZonePrivate(); |
431 | // Create named time zone |
432 | QWinTimeZonePrivate(const QByteArray &ianaId); |
433 | QWinTimeZonePrivate(const QWinTimeZonePrivate &other); |
434 | ~QWinTimeZonePrivate(); |
435 | |
436 | QWinTimeZonePrivate *clone() const override; |
437 | |
438 | QString comment() const override; |
439 | |
440 | using QTimeZonePrivate::displayName; |
441 | QString displayName(QTimeZone::TimeType timeType, QTimeZone::NameType nameType, |
442 | const QLocale &locale) const override; |
443 | QString abbreviation(qint64 atMSecsSinceEpoch) const override; |
444 | |
445 | int offsetFromUtc(qint64 atMSecsSinceEpoch) const override; |
446 | int standardTimeOffset(qint64 atMSecsSinceEpoch) const override; |
447 | int daylightTimeOffset(qint64 atMSecsSinceEpoch) const override; |
448 | |
449 | bool hasDaylightTime() const override; |
450 | bool isDaylightTime(qint64 atMSecsSinceEpoch) const override; |
451 | |
452 | using QTimeZonePrivate::data; |
453 | Data data(qint64 forMSecsSinceEpoch) const override; |
454 | |
455 | bool hasTransitions() const override; |
456 | Data nextTransition(qint64 afterMSecsSinceEpoch) const override; |
457 | Data previousTransition(qint64 beforeMSecsSinceEpoch) const override; |
458 | |
459 | QByteArray systemTimeZoneId() const override; |
460 | |
461 | QList<QByteArray> availableTimeZoneIds() const override; |
462 | |
463 | // For use within implementation's TransitionTimePair: |
464 | QTimeZonePrivate::Data ruleToData(const QWinTransitionRule &rule, qint64 atMSecsSinceEpoch, |
465 | QTimeZone::TimeType type, bool fakeDst = false) const; |
466 | private: |
467 | void init(const QByteArray &ianaId); |
468 | |
469 | QByteArray m_windowsId; |
470 | QString m_displayName; |
471 | QString m_standardName; |
472 | QString m_daylightName; |
473 | QList<QWinTransitionRule> m_tranRules; |
474 | }; |
475 | #endif // Q_OS_WIN && !icu |
476 | |
477 | #ifdef Q_OS_ANDROID |
478 | class QAndroidTimeZonePrivate final : public QTimeZonePrivate |
479 | { |
480 | public: |
481 | // Create default time zone |
482 | QAndroidTimeZonePrivate(); |
483 | // Create named time zone |
484 | QAndroidTimeZonePrivate(const QByteArray &ianaId); |
485 | QAndroidTimeZonePrivate(const QAndroidTimeZonePrivate &other); |
486 | ~QAndroidTimeZonePrivate(); |
487 | |
488 | QAndroidTimeZonePrivate *clone() const override; |
489 | |
490 | using QTimeZonePrivate::displayName; |
491 | QString displayName(QTimeZone::TimeType timeType, QTimeZone::NameType nameType, |
492 | const QLocale &locale) const override; |
493 | QString abbreviation(qint64 atMSecsSinceEpoch) const override; |
494 | |
495 | int offsetFromUtc(qint64 atMSecsSinceEpoch) const override; |
496 | int standardTimeOffset(qint64 atMSecsSinceEpoch) const override; |
497 | int daylightTimeOffset(qint64 atMSecsSinceEpoch) const override; |
498 | |
499 | bool hasDaylightTime() const override; |
500 | bool isDaylightTime(qint64 atMSecsSinceEpoch) const override; |
501 | |
502 | using QTimeZonePrivate::data; |
503 | Data data(qint64 forMSecsSinceEpoch) const override; |
504 | |
505 | QByteArray systemTimeZoneId() const override; |
506 | bool isTimeZoneIdAvailable(const QByteArray &ianaId) const override; |
507 | QList<QByteArray> availableTimeZoneIds() const override; |
508 | |
509 | private: |
510 | void init(const QByteArray &zoneId); |
511 | |
512 | QJniObject androidTimeZone; |
513 | |
514 | }; |
515 | #endif // Q_OS_ANDROID |
516 | |
517 | QT_END_NAMESPACE |
518 | |
519 | #endif // QTIMEZONEPRIVATE_P_H |
520 | |