Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qtimezone.h
Go to the documentation of this file.
1// Copyright (C) 2017 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// Qt-Security score:significant reason:default
5
6#ifndef QTIMEZONE_H
7#define QTIMEZONE_H
8
9#include <QtCore/qcompare.h>
10#include <QtCore/qdatetime.h>
11#include <QtCore/qlocale.h>
12#include <QtCore/qswap.h>
13#include <QtCore/qtclasshelpermacros.h>
14
15#include <chrono>
16
17#if QT_CONFIG(timezone) && (defined(Q_OS_DARWIN) || defined(Q_QDOC))
20#endif
21
23
24class QTimeZonePrivate;
25
26class Q_CORE_EXPORT QTimeZone
27{
28 struct ShortData
29 {
30#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
31 quintptr mode : 2;
32#endif
33 qintptr offset : sizeof(void *) * 8 - 2;
34
35#if Q_BYTE_ORDER == Q_BIG_ENDIAN
36 quintptr mode : 2;
37#endif
38
39 // mode is a cycled Qt::TimeSpec, (int(spec) + 1) % 4, so that zero
40 // (lowest bits of a pointer) matches spec being Qt::TimeZone, for which
41 // Data holds a QTZP pointer instead of ShortData.
42 // Passing Qt::TimeZone gets the equivalent of a null QTZP; it is not short.
43 constexpr ShortData(Qt::TimeSpec spec, int secondsAhead = 0)
44#if Q_BYTE_ORDER == Q_BIG_ENDIAN
45 : offset(spec == Qt::OffsetFromUTC ? secondsAhead : 0),
46 mode((int(spec) + 1) & 3)
47#else
48 : mode((int(spec) + 1) & 3),
49 offset(spec == Qt::OffsetFromUTC ? secondsAhead : 0)
50#endif
51 {
52 }
53 friend constexpr bool operator==(ShortData lhs, ShortData rhs)
54 { return lhs.mode == rhs.mode && lhs.offset == rhs.offset; }
55 constexpr Qt::TimeSpec spec() const { return Qt::TimeSpec((mode + 3) & 3); }
56 };
57
58 union Data
59 {
60 Data() noexcept;
61 Data(ShortData sd) : s(sd) {}
62 Data(const Data &other) noexcept;
63 Data(Data &&other) noexcept : d(std::exchange(other.d, nullptr)) {}
64 Data &operator=(const Data &other) noexcept;
65 Data &operator=(Data &&other) noexcept { swap(other); return *this; }
66 ~Data();
67
68 void swap(Data &other) noexcept { qt_ptr_swap(d, other.d); }
69 // isShort() is equivalent to s.spec() != Qt::TimeZone
70 bool isShort() const { return s.mode; } // a.k.a. quintptr(d) & 3
71
72 // Typse must support: out << wrap("C-strings");
73 template <typename Stream, typename Wrap>
74 void serialize(Stream &out, const Wrap &wrap) const;
75
76 Data(QTimeZonePrivate *dptr) noexcept;
77 Data &operator=(QTimeZonePrivate *dptr) noexcept;
78 const QTimeZonePrivate *operator->() const { Q_ASSERT(!isShort()); return d; }
79 QTimeZonePrivate *operator->() { Q_ASSERT(!isShort()); return d; }
80
81 QTimeZonePrivate *d = nullptr;
82 ShortData s;
83 };
84
85 friend class QTypeInfo<Data>;
86
87 QTimeZone(ShortData sd) : d(sd) {}
88 QTimeZone(Qt::TimeSpec) Q_DECL_EQ_DELETE_X(
89 "Would be treated as int offsetSeconds. "
90 "Use QTimeZone::UTC or QTimeZone::LocalTime instead.");
91
92public:
93 // Sane UTC offsets range from -16 to +16 hours:
94 static constexpr int MinUtcOffsetSecs = -16 * 3600;
95 // No known modern zone > 12 hrs West of Greenwich.
96 // Until 1844, Asia/Manila (in The Philippines) was at 15:56 West.
97 static constexpr int MaxUtcOffsetSecs = +16 * 3600;
98 // No known modern zone > 14 hrs East of Greenwich.
99 // Until 1867, America/Metlakatla (in Alaska) was at 15:13:42 East.
100
101 enum Initialization { LocalTime, UTC };
102
103 QTimeZone() noexcept;
104 Q_IMPLICIT QTimeZone(Initialization spec) noexcept
105 : d(ShortData(spec == UTC ? Qt::UTC : Qt::LocalTime)) {}
106
107#if QT_CONFIG(timezone)
108 explicit QTimeZone(int offsetSeconds);
109 explicit QTimeZone(const QByteArray &ianaId);
110 QTimeZone(const QByteArray &zoneId, int offsetSeconds, const QString &name,
111 const QString &abbreviation, QLocale::Territory territory = QLocale::AnyTerritory,
112 const QString &comment = QString());
113#endif // timezone backends
114
115 QTimeZone(const QTimeZone &other) noexcept;
116 QTimeZone(QTimeZone &&other) noexcept : d(std::move(other.d)) {}
117 ~QTimeZone();
118
119 QTimeZone &operator=(const QTimeZone &other);
120 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QTimeZone)
121
122 void swap(QTimeZone &other) noexcept
123 { d.swap(other.d); }
124
125#if QT_CORE_REMOVED_SINCE(6, 7)
126 bool operator==(const QTimeZone &other) const;
127 bool operator!=(const QTimeZone &other) const;
128#endif
129
130 bool isValid() const;
131
132 static QTimeZone fromDurationAheadOfUtc(std::chrono::seconds offset)
133 {
134 return QTimeZone((offset.count() >= MinUtcOffsetSecs && offset.count() <= MaxUtcOffsetSecs)
135 ? ShortData(offset.count() ? Qt::OffsetFromUTC : Qt::UTC,
136 int(offset.count()))
137 : ShortData(Qt::TimeZone));
138 }
139 static QTimeZone fromSecondsAheadOfUtc(int offset)
140 {
141 return fromDurationAheadOfUtc(std::chrono::seconds{offset});
142 }
143 constexpr Qt::TimeSpec timeSpec() const noexcept { return d.s.spec(); }
144 constexpr int fixedSecondsAheadOfUtc() const noexcept
145 { return timeSpec() == Qt::OffsetFromUTC ? int(d.s.offset) : 0; }
146
147 static constexpr bool isUtcOrFixedOffset(Qt::TimeSpec spec) noexcept
148 { return spec == Qt::UTC || spec == Qt::OffsetFromUTC; }
149 constexpr bool isUtcOrFixedOffset() const noexcept { return isUtcOrFixedOffset(timeSpec()); }
150
151#if QT_CONFIG(timezone)
152 QTimeZone asBackendZone() const;
153
154 enum TimeType {
155 StandardTime = 0,
156 DaylightTime = 1,
157 GenericTime = 2
158 };
159
160 enum NameType {
161 DefaultName = 0,
162 LongName = 1,
163 ShortName = 2,
164 OffsetName = 3
165 };
166
167 struct OffsetData {
168 QString abbreviation;
169 QDateTime atUtc;
170 int offsetFromUtc;
171 int standardTimeOffset;
172 int daylightTimeOffset;
173 };
174 typedef QList<OffsetData> OffsetDataList;
175
176 bool hasAlternativeName(QByteArrayView alias) const;
177 QByteArray id() const;
178 QLocale::Territory territory() const;
179# if QT_DEPRECATED_SINCE(6, 6)
180 QT_DEPRECATED_VERSION_X_6_6("Use territory() instead")
181 QLocale::Country country() const;
182# endif
183 QString comment() const;
184
185 QString displayName(const QDateTime &atDateTime, NameType nameType = DefaultName,
186 const QLocale &locale = QLocale()) const;
187 QString displayName(TimeType timeType, NameType nameType = DefaultName,
188 const QLocale &locale = QLocale()) const;
189 QString abbreviation(const QDateTime &atDateTime) const;
190
191 int offsetFromUtc(const QDateTime &atDateTime) const;
192 int standardTimeOffset(const QDateTime &atDateTime) const;
193 int daylightTimeOffset(const QDateTime &atDateTime) const;
194
195 bool hasDaylightTime() const;
196 bool isDaylightTime(const QDateTime &atDateTime) const;
197
198 OffsetData offsetData(const QDateTime &forDateTime) const;
199
200 bool hasTransitions() const;
201 OffsetData nextTransition(const QDateTime &afterDateTime) const;
202 OffsetData previousTransition(const QDateTime &beforeDateTime) const;
203 OffsetDataList transitions(const QDateTime &fromDateTime, const QDateTime &toDateTime) const;
204
205 static QByteArray systemTimeZoneId();
206 static QTimeZone systemTimeZone();
207 static QTimeZone utc();
208
209 static bool isTimeZoneIdAvailable(const QByteArray &ianaId);
210
211 static QList<QByteArray> availableTimeZoneIds();
212 static QList<QByteArray> availableTimeZoneIds(QLocale::Territory territory);
213 static QList<QByteArray> availableTimeZoneIds(int offsetSeconds);
214
215 static QByteArray ianaIdToWindowsId(const QByteArray &ianaId);
216 static QByteArray windowsIdToDefaultIanaId(const QByteArray &windowsId);
217 static QByteArray windowsIdToDefaultIanaId(const QByteArray &windowsId,
218 QLocale::Territory territory);
219 static QList<QByteArray> windowsIdToIanaIds(const QByteArray &windowsId);
220 static QList<QByteArray> windowsIdToIanaIds(const QByteArray &windowsId,
221 QLocale::Territory territory);
222
223# if defined(Q_OS_DARWIN) || defined(Q_QDOC)
224 static QTimeZone fromCFTimeZone(CFTimeZoneRef timeZone);
225 CFTimeZoneRef toCFTimeZone() const Q_DECL_CF_RETURNS_RETAINED;
226 static QTimeZone fromNSTimeZone(const NSTimeZone *timeZone);
227 NSTimeZone *toNSTimeZone() const Q_DECL_NS_RETURNS_AUTORELEASED;
228# endif
229
230# if __cpp_lib_chrono >= 201907L || defined(Q_QDOC)
231 QT_POST_CXX17_API_IN_EXPORTED_CLASS
232 static QTimeZone fromStdTimeZonePtr(const std::chrono::time_zone *timeZone)
233 {
234 if (!timeZone)
235 return QTimeZone();
236 const std::string_view timeZoneName = timeZone->name();
237 return QTimeZone(QByteArrayView(timeZoneName).toByteArray());
238 }
239# endif
240#endif // feature timezone
241private:
242 friend Q_CORE_EXPORT bool comparesEqual(const QTimeZone &lhs, const QTimeZone &rhs) noexcept;
243 Q_DECLARE_EQUALITY_COMPARABLE(QTimeZone)
244
245#ifndef QT_NO_DATASTREAM
246 friend Q_CORE_EXPORT QDataStream &operator<<(QDataStream &ds, const QTimeZone &tz);
247#endif
248#ifndef QT_NO_DEBUG_STREAM
249 friend Q_CORE_EXPORT QDebug operator<<(QDebug dbg, const QTimeZone &tz);
250#endif
251 QTimeZone(QTimeZonePrivate &dd);
252 friend class QTimeZonePrivate;
253 friend class QDateTime;
254 friend class QDateTimePrivate;
255 Data d;
256};
257
258#if QT_CONFIG(timezone)
259Q_DECLARE_TYPEINFO(QTimeZone::OffsetData, Q_RELOCATABLE_TYPE);
260#endif
261
264
265#ifndef QT_NO_DATASTREAM
266Q_CORE_EXPORT QDataStream &operator<<(QDataStream &ds, const QTimeZone &tz);
267Q_CORE_EXPORT QDataStream &operator>>(QDataStream &ds, QTimeZone &tz);
268#endif
269
270#ifndef QT_NO_DEBUG_STREAM
271Q_CORE_EXPORT QDebug operator<<(QDebug dbg, const QTimeZone &tz);
272#endif
273
274#if QT_CONFIG(timezone) && __cpp_lib_chrono >= 201907L
275// zoned_time
276template <typename> // QT_POST_CXX17_API_IN_EXPORTED_CLASS
277inline QDateTime QDateTime::fromStdZonedTime(const std::chrono::zoned_time<
278 std::chrono::milliseconds,
279 const std::chrono::time_zone *
280 > &time)
281{
282 const auto sysTime = time.get_sys_time();
283 const QTimeZone timeZone = QTimeZone::fromStdTimeZonePtr(time.get_time_zone());
284 return fromMSecsSinceEpoch(sysTime.time_since_epoch().count(), timeZone);
285}
286#endif
287
288QT_END_NAMESPACE
289
290#endif // QTIMEZONE_H
const QtCbor::ByteData * byteData(QtCbor::Element e) const
static int compareElement_helper(const QCborContainerPrivate *c1, QtCbor::Element e1, const QCborContainerPrivate *c2, QtCbor::Element e2, QtCbor::Comparison mode) noexcept
QCborContainerPrivate(const QCborContainerPrivate &)=default
static QCborValueRef findOrAddMapKey(QCborValueRef self, KeyType key)
void appendAsciiString(QStringView s)
void appendNonAsciiString(QStringView s)
void append(QtCbor::Undefined)
QCborValue extractAt_complex(QtCbor::Element e)
void replaceAt_complex(QtCbor::Element &e, const QCborValue &value, ContainerDisposition disp)
QCborContainerPrivate * d
Definition qcborvalue.h:456
\inmodule QtCore\reentrant
Definition qdatastream.h:50
\inmodule QtCore
Definition qtimezone.h:27
Combined button and popup list for selecting options.
static int typeOrder(QCborValue::Type e1, QCborValue::Type e2)
static Q_DECL_UNUSED constexpr int MaximumRecursionDepth
Q_CORE_EXPORT const char * qt_cbor_simpletype_id(QCborSimpleType st)
void qt_to_latin1_unchecked(uchar *dst, const char16_t *uc, qsizetype len)
Definition qstring.cpp:1189
static int compareStringsInUtf8(QStringView lhs, QStringView rhs, Comparison mode) noexcept
static bool shouldArrayRemainArray(qint64 key, QCborValue::Type t, QCborContainerPrivate *container)
static auto nextUtf32Character(const char16_t *&ptr, const char16_t *end) noexcept
static int compareContainer(const QCborContainerPrivate *c1, const QCborContainerPrivate *c2, Comparison mode) noexcept
static QCborContainerPrivate * assignContainer(QCborContainerPrivate *&d, QCborContainerPrivate *x)
static qsizetype stringLengthInUtf8(const char16_t *ptr, const char16_t *end) noexcept
static QCborValue::Type convertToExtendedType(QCborContainerPrivate *d)
Q_CORE_EXPORT const char * qt_cbor_tag_id(QCborTag tag)
bool comparesEqual(const QCborArray &lhs, const QCborArray &rhs) noexcept
static QCborContainerPrivate * maybeGrow(QCborContainerPrivate *container, qsizetype index)
static QDebug debugContents(QDebug &dbg, const QCborValue &v)
static int compareElementRecursive(const QCborContainerPrivate *c1, const Element &e1, const QCborContainerPrivate *c2, const Element &e2, Comparison mode) noexcept
static void convertArrayToMap(QCborContainerPrivate *&array)
bool comparesEqual(const QCborMap &lhs, const QCborMap &rhs) noexcept
static int compareElementNoData(const Element &e1, const Element &e2) noexcept
Q_DECLARE_TYPEINFO(QDateTime::Data, Q_RELOCATABLE_TYPE)
QDebug operator<<(QDebug debug, QDir::Filters filters)
Definition qdir.cpp:2582
Q_CORE_EXPORT QDebug operator<<(QDebug debug, QDir::Filters filters)
Definition qdir.cpp:2582
QDebug operator<<(QDebug dbg, const QFileInfo &fi)
bool comparesEqual(const QFileInfo &lhs, const QFileInfo &rhs)
constexpr size_t qHash(const QSize &s, size_t seed=0) noexcept
Definition qsize.h:192
const char * byte() const
double fpvalue() const