1 | // Copyright (C) 2021 The Qt Company Ltd. |
---|---|
2 | // Copyright (C) 2021 Intel Corporation. |
3 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
4 | |
5 | #ifndef QDATETIME_H |
6 | #define QDATETIME_H |
7 | |
8 | #include <QtCore/qcalendar.h> |
9 | #include <QtCore/qcompare.h> |
10 | #include <QtCore/qlocale.h> |
11 | #include <QtCore/qnamespace.h> |
12 | #include <QtCore/qshareddata.h> |
13 | #include <QtCore/qstring.h> |
14 | |
15 | #include <limits> |
16 | #include <chrono> |
17 | |
18 | #if defined(Q_OS_DARWIN) || defined(Q_QDOC) |
19 | Q_FORWARD_DECLARE_CF_TYPE(CFDate); |
20 | Q_FORWARD_DECLARE_OBJC_CLASS(NSDate); |
21 | #endif |
22 | |
23 | QT_BEGIN_NAMESPACE |
24 | |
25 | class QTimeZone; |
26 | class QDateTime; |
27 | |
28 | class Q_CORE_EXPORT QDate |
29 | { |
30 | explicit constexpr QDate(qint64 julianDay) : jd(julianDay) {} |
31 | public: |
32 | constexpr QDate() : jd(nullJd()) {} |
33 | QDate(int y, int m, int d); |
34 | QDate(int y, int m, int d, QCalendar cal); |
35 | #if __cpp_lib_chrono >= 201907L || defined(Q_QDOC) |
36 | QT_POST_CXX17_API_IN_EXPORTED_CLASS |
37 | Q_IMPLICIT constexpr QDate(std::chrono::year_month_day date) noexcept |
38 | : jd(date.ok() ? stdSysDaysToJulianDay(date) : nullJd()) |
39 | {} |
40 | |
41 | QT_POST_CXX17_API_IN_EXPORTED_CLASS |
42 | Q_IMPLICIT constexpr QDate(std::chrono::year_month_day_last date) noexcept |
43 | : jd(date.ok() ? stdSysDaysToJulianDay(date) : nullJd()) |
44 | {} |
45 | |
46 | QT_POST_CXX17_API_IN_EXPORTED_CLASS |
47 | Q_IMPLICIT constexpr QDate(std::chrono::year_month_weekday date) noexcept |
48 | : jd(date.ok() ? stdSysDaysToJulianDay(date) : nullJd()) |
49 | {} |
50 | |
51 | QT_POST_CXX17_API_IN_EXPORTED_CLASS |
52 | Q_IMPLICIT constexpr QDate(std::chrono::year_month_weekday_last date) noexcept |
53 | : jd(date.ok() ? stdSysDaysToJulianDay(date) : nullJd()) |
54 | {} |
55 | |
56 | QT_POST_CXX17_API_IN_EXPORTED_CLASS |
57 | static constexpr QDate fromStdSysDays(const std::chrono::sys_days &days) noexcept |
58 | { |
59 | return QDate(stdSysDaysToJulianDay(days)); |
60 | } |
61 | |
62 | QT_POST_CXX17_API_IN_EXPORTED_CLASS |
63 | constexpr std::chrono::sys_days toStdSysDays() const noexcept |
64 | { |
65 | const qint64 days = isValid() ? jd - unixEpochJd() : 0; |
66 | return std::chrono::sys_days(std::chrono::days(days)); |
67 | } |
68 | #endif |
69 | |
70 | constexpr bool isNull() const { return !isValid(); } |
71 | constexpr bool isValid() const { return jd >= minJd() && jd <= maxJd(); } |
72 | |
73 | // Gregorian-optimized: |
74 | int year() const; |
75 | int month() const; |
76 | int day() const; |
77 | int dayOfWeek() const; |
78 | int dayOfYear() const; |
79 | int daysInMonth() const; |
80 | int daysInYear() const; |
81 | int weekNumber(int *yearNum = nullptr) const; // ISO 8601, always Gregorian |
82 | |
83 | int year(QCalendar cal) const; |
84 | int month(QCalendar cal) const; |
85 | int day(QCalendar cal) const; |
86 | int dayOfWeek(QCalendar cal) const; |
87 | int dayOfYear(QCalendar cal) const; |
88 | int daysInMonth(QCalendar cal) const; |
89 | int daysInYear(QCalendar cal) const; |
90 | |
91 | #if QT_DEPRECATED_SINCE(6, 9) |
92 | QT_DEPRECATED_VERSION_X_6_9("Pass QTimeZone instead") |
93 | QDateTime startOfDay(Qt::TimeSpec spec, int offsetSeconds = 0) const; |
94 | QT_DEPRECATED_VERSION_X_6_9("Pass QTimeZone instead") |
95 | QDateTime endOfDay(Qt::TimeSpec spec, int offsetSeconds = 0) const; |
96 | #endif |
97 | |
98 | QDateTime startOfDay(const QTimeZone &zone) const; |
99 | QDateTime endOfDay(const QTimeZone &zone) const; |
100 | QDateTime startOfDay() const; |
101 | QDateTime endOfDay() const; |
102 | |
103 | #if QT_CONFIG(datestring) |
104 | QString toString(Qt::DateFormat format = Qt::TextDate) const; |
105 | QString toString(const QString &format) const; |
106 | QString toString(const QString &format, QCalendar cal) const |
107 | { return toString(format: qToStringViewIgnoringNull(s: format), cal); } |
108 | QString toString(QStringView format) const; |
109 | QString toString(QStringView format, QCalendar cal) const; |
110 | #endif |
111 | bool setDate(int year, int month, int day); // Gregorian-optimized |
112 | bool setDate(int year, int month, int day, QCalendar cal); |
113 | |
114 | void getDate(int *year, int *month, int *day) const; |
115 | |
116 | [[nodiscard]] QDate addDays(qint64 days) const; |
117 | #if __cpp_lib_chrono >= 201907L || defined(Q_QDOC) |
118 | QT_POST_CXX17_API_IN_EXPORTED_CLASS |
119 | [[nodiscard]] QDate addDuration(std::chrono::days days) const |
120 | { |
121 | return addDays(days.count()); |
122 | } |
123 | #endif |
124 | // Gregorian-optimized: |
125 | [[nodiscard]] QDate addMonths(int months) const; |
126 | [[nodiscard]] QDate addYears(int years) const; |
127 | [[nodiscard]] QDate addMonths(int months, QCalendar cal) const; |
128 | [[nodiscard]] QDate addYears(int years, QCalendar cal) const; |
129 | qint64 daysTo(QDate d) const; |
130 | |
131 | static QDate currentDate(); |
132 | #if QT_CONFIG(datestring) |
133 | // No DateFormat accepts a two-digit year, so no need for baseYear: |
134 | static QDate fromString(QStringView string, Qt::DateFormat format = Qt::TextDate); |
135 | static QDate fromString(const QString &string, Qt::DateFormat format = Qt::TextDate) |
136 | { return fromString(string: qToStringViewIgnoringNull(s: string), format); } |
137 | |
138 | // Accept calendar without over-ride of base year: |
139 | static QDate fromString(QStringView string, QStringView format, QCalendar cal) |
140 | { return fromString(string: string.toString(), format, baseYear: QLocale::DefaultTwoDigitBaseYear, cal); } |
141 | QT_CORE_INLINE_SINCE(6, 7) |
142 | static QDate fromString(const QString &string, QStringView format, QCalendar cal); |
143 | static QDate fromString(const QString &string, const QString &format, QCalendar cal) |
144 | { return fromString(string, format: qToStringViewIgnoringNull(s: format), baseYear: QLocale::DefaultTwoDigitBaseYear, cal); } |
145 | |
146 | // Overriding base year is likely more common than overriding calendar (and |
147 | // likely to get more so, as the legacy base drops ever further behind us). |
148 | static QDate fromString(QStringView string, QStringView format, |
149 | int baseYear = QLocale::DefaultTwoDigitBaseYear) |
150 | { return fromString(string: string.toString(), format, baseYear); } |
151 | static QDate fromString(QStringView string, QStringView format, |
152 | int baseYear, QCalendar cal) |
153 | { return fromString(string: string.toString(), format, baseYear, cal); } |
154 | static QDate fromString(const QString &string, QStringView format, |
155 | int baseYear = QLocale::DefaultTwoDigitBaseYear); |
156 | static QDate fromString(const QString &string, QStringView format, |
157 | int baseYear, QCalendar cal); |
158 | static QDate fromString(const QString &string, const QString &format, |
159 | int baseYear = QLocale::DefaultTwoDigitBaseYear) |
160 | { return fromString(string, format: qToStringViewIgnoringNull(s: format), baseYear); } |
161 | static QDate fromString(const QString &string, const QString &format, |
162 | int baseYear, QCalendar cal) |
163 | { return fromString(string, format: qToStringViewIgnoringNull(s: format), baseYear, cal); } |
164 | #endif |
165 | static bool isValid(int y, int m, int d); |
166 | static bool isLeapYear(int year); |
167 | |
168 | static constexpr inline QDate fromJulianDay(qint64 jd_) |
169 | { return jd_ >= minJd() && jd_ <= maxJd() ? QDate(jd_) : QDate() ; } |
170 | constexpr inline qint64 toJulianDay() const { return jd; } |
171 | |
172 | private: |
173 | // using extra parentheses around min to avoid expanding it if it is a macro |
174 | static constexpr inline qint64 nullJd() { return (std::numeric_limits<qint64>::min)(); } |
175 | static constexpr inline qint64 minJd() { return Q_INT64_C(-784350574879); } |
176 | static constexpr inline qint64 maxJd() { return Q_INT64_C( 784354017364); } |
177 | static constexpr inline qint64 unixEpochJd() { return Q_INT64_C(2440588); } |
178 | |
179 | #if __cpp_lib_chrono >= 201907L |
180 | #if !QT_CORE_REMOVED_SINCE(6, 7) |
181 | QT_POST_CXX17_API_IN_EXPORTED_CLASS |
182 | #endif |
183 | static constexpr qint64 |
184 | stdSysDaysToJulianDay(const std::chrono::sys_days &days) noexcept |
185 | { |
186 | const auto epochDays = days.time_since_epoch().count(); |
187 | // minJd() and maxJd() fit into 40 bits. |
188 | if constexpr (sizeof(epochDays) * CHAR_BIT >= 41) { |
189 | constexpr auto top = maxJd() - unixEpochJd(); |
190 | constexpr auto bottom = minJd() - unixEpochJd(); |
191 | if (epochDays > top || epochDays < bottom) |
192 | return nullJd(); |
193 | } |
194 | return unixEpochJd() + epochDays; |
195 | } |
196 | #endif // __cpp_lib_chrono >= 201907L |
197 | |
198 | qint64 jd; |
199 | |
200 | friend class QDateTime; |
201 | friend class QDateTimeParser; |
202 | friend class QDateTimePrivate; |
203 | |
204 | friend constexpr bool comparesEqual(const QDate &lhs, const QDate &rhs) noexcept |
205 | { return lhs.jd == rhs.jd; } |
206 | friend constexpr Qt::strong_ordering |
207 | compareThreeWay(const QDate &lhs, const QDate &rhs) noexcept |
208 | { return Qt::compareThreeWay(lhs: lhs.jd, rhs: rhs.jd); } |
209 | Q_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE(QDate) |
210 | |
211 | #ifndef QT_NO_DATASTREAM |
212 | friend Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, QDate); |
213 | friend Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QDate &); |
214 | #endif |
215 | }; |
216 | Q_DECLARE_TYPEINFO(QDate, Q_RELOCATABLE_TYPE); |
217 | |
218 | class Q_CORE_EXPORT QTime |
219 | { |
220 | explicit constexpr QTime(int ms) : mds(ms) |
221 | {} |
222 | public: |
223 | constexpr QTime(): mds(NullTime) |
224 | {} |
225 | QTime(int h, int m, int s = 0, int ms = 0); |
226 | |
227 | constexpr bool isNull() const { return mds == NullTime; } |
228 | bool isValid() const; |
229 | |
230 | int hour() const; |
231 | int minute() const; |
232 | int second() const; |
233 | int msec() const; |
234 | #if QT_CONFIG(datestring) |
235 | QString toString(Qt::DateFormat f = Qt::TextDate) const; |
236 | QString toString(const QString &format) const |
237 | { return toString(format: qToStringViewIgnoringNull(s: format)); } |
238 | QString toString(QStringView format) const; |
239 | #endif |
240 | bool setHMS(int h, int m, int s, int ms = 0); |
241 | |
242 | [[nodiscard]] QTime addSecs(int secs) const; |
243 | int secsTo(QTime t) const; |
244 | [[nodiscard]] QTime addMSecs(int ms) const; |
245 | int msecsTo(QTime t) const; |
246 | |
247 | static constexpr inline QTime fromMSecsSinceStartOfDay(int msecs) { return QTime(msecs); } |
248 | constexpr inline int msecsSinceStartOfDay() const { return mds == NullTime ? 0 : mds; } |
249 | |
250 | static QTime currentTime(); |
251 | #if QT_CONFIG(datestring) |
252 | static QTime fromString(QStringView string, Qt::DateFormat format = Qt::TextDate); |
253 | static QTime fromString(QStringView string, QStringView format) |
254 | { return fromString(string: string.toString(), format); } |
255 | static QTime fromString(const QString &string, QStringView format); |
256 | static QTime fromString(const QString &string, Qt::DateFormat format = Qt::TextDate) |
257 | { return fromString(string: qToStringViewIgnoringNull(s: string), format); } |
258 | static QTime fromString(const QString &string, const QString &format) |
259 | { return fromString(string, format: qToStringViewIgnoringNull(s: format)); } |
260 | #endif |
261 | static bool isValid(int h, int m, int s, int ms = 0); |
262 | |
263 | private: |
264 | enum TimeFlag { NullTime = -1 }; |
265 | constexpr inline int ds() const { return mds == -1 ? 0 : mds; } |
266 | int mds; |
267 | |
268 | friend constexpr bool comparesEqual(const QTime &lhs, const QTime &rhs) noexcept |
269 | { return lhs.mds == rhs.mds; } |
270 | friend constexpr Qt::strong_ordering |
271 | compareThreeWay(const QTime &lhs, const QTime &rhs) noexcept |
272 | { return Qt::compareThreeWay(lhs: lhs.mds, rhs: rhs.mds); } |
273 | Q_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE(QTime) |
274 | |
275 | friend class QDateTime; |
276 | friend class QDateTimePrivate; |
277 | #ifndef QT_NO_DATASTREAM |
278 | friend Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, QTime); |
279 | friend Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QTime &); |
280 | #endif |
281 | }; |
282 | Q_DECLARE_TYPEINFO(QTime, Q_RELOCATABLE_TYPE); |
283 | |
284 | class QDateTimePrivate; |
285 | |
286 | class Q_CORE_EXPORT QDateTime |
287 | { |
288 | struct ShortData { |
289 | #if QT_VERSION >= QT_VERSION_CHECK(7,0,0) || defined(QT_BOOTSTRAPPED) |
290 | # if Q_BYTE_ORDER == Q_LITTLE_ENDIAN |
291 | qint64 status : 8; |
292 | # endif |
293 | qint64 msecs : 56; |
294 | |
295 | # if Q_BYTE_ORDER == Q_BIG_ENDIAN |
296 | qint64 status : 8; |
297 | # endif |
298 | #else |
299 | # if Q_BYTE_ORDER == Q_LITTLE_ENDIAN |
300 | quintptr status : 8; |
301 | # endif |
302 | // note: this is only 24 bits on 32-bit systems... |
303 | qintptr msecs : sizeof(void *) * 8 - 8; |
304 | |
305 | # if Q_BYTE_ORDER == Q_BIG_ENDIAN |
306 | quintptr status : 8; |
307 | # endif |
308 | #endif |
309 | friend constexpr bool operator==(ShortData lhs, ShortData rhs) |
310 | { return lhs.status == rhs.status && lhs.msecs == rhs.msecs; } |
311 | }; |
312 | |
313 | union Data { |
314 | // To be of any use, we need at least 60 years around 1970, which |
315 | // is 1,893,456,000,000 ms. That requires 41 bits to store, plus |
316 | // the sign bit. With the status byte, the minimum size is 50 bits. |
317 | static constexpr bool CanBeSmall = sizeof(ShortData) * 8 > 50; |
318 | |
319 | Data() noexcept; |
320 | Data(const QTimeZone &); |
321 | Data(const Data &other) noexcept; |
322 | Data(Data &&other) noexcept; |
323 | Data &operator=(const Data &other) noexcept; |
324 | Data &operator=(Data &&other) noexcept { swap(other); return *this; } |
325 | ~Data(); |
326 | |
327 | void swap(Data &other) noexcept |
328 | { std::swap(a&: data, b&: other.data); } |
329 | |
330 | bool isShort() const; |
331 | inline void invalidate(); |
332 | void detach(); |
333 | QTimeZone timeZone() const; |
334 | |
335 | const QDateTimePrivate *operator->() const; |
336 | QDateTimePrivate *operator->(); |
337 | |
338 | QDateTimePrivate *d; |
339 | ShortData data; |
340 | }; |
341 | |
342 | public: |
343 | QDateTime() noexcept; |
344 | |
345 | enum class TransitionResolution { |
346 | Reject = 0, |
347 | RelativeToBefore, |
348 | RelativeToAfter, |
349 | PreferBefore, |
350 | PreferAfter, |
351 | PreferStandard, |
352 | PreferDaylightSaving, |
353 | // Closest match to behavior prior to introducing TransitionResolution: |
354 | LegacyBehavior = RelativeToBefore |
355 | }; |
356 | |
357 | #if QT_DEPRECATED_SINCE(6, 9) |
358 | QT_DEPRECATED_VERSION_X_6_9("Pass QTimeZone instead") |
359 | QDateTime(QDate date, QTime time, Qt::TimeSpec spec, int offsetSeconds = 0); |
360 | #endif |
361 | #if QT_CORE_REMOVED_SINCE(6, 7) |
362 | QDateTime(QDate date, QTime time, const QTimeZone &timeZone); |
363 | QDateTime(QDate date, QTime time); |
364 | #endif |
365 | QDateTime(QDate date, QTime time, const QTimeZone &timeZone, |
366 | TransitionResolution resolve = TransitionResolution::LegacyBehavior); |
367 | QDateTime(QDate date, QTime time, |
368 | TransitionResolution resolve = TransitionResolution::LegacyBehavior); |
369 | QDateTime(const QDateTime &other) noexcept; |
370 | QDateTime(QDateTime &&other) noexcept; |
371 | ~QDateTime(); |
372 | |
373 | QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QDateTime) |
374 | QDateTime &operator=(const QDateTime &other) noexcept; |
375 | |
376 | void swap(QDateTime &other) noexcept { d.swap(other&: other.d); } |
377 | |
378 | bool isNull() const; |
379 | bool isValid() const; |
380 | |
381 | QDate date() const; |
382 | QTime time() const; |
383 | Qt::TimeSpec timeSpec() const; |
384 | int offsetFromUtc() const; |
385 | QTimeZone timeRepresentation() const; |
386 | #if QT_CONFIG(timezone) |
387 | QTimeZone timeZone() const; |
388 | #endif // timezone |
389 | QString timeZoneAbbreviation() const; |
390 | bool isDaylightTime() const; |
391 | |
392 | qint64 toMSecsSinceEpoch() const; |
393 | qint64 toSecsSinceEpoch() const; |
394 | |
395 | #if QT_CORE_REMOVED_SINCE(6, 7) |
396 | void setDate(QDate date); |
397 | void setTime(QTime time); |
398 | #endif |
399 | void setDate(QDate date, TransitionResolution resolve = TransitionResolution::LegacyBehavior); |
400 | void setTime(QTime time, TransitionResolution resolve = TransitionResolution::LegacyBehavior); |
401 | |
402 | #if QT_DEPRECATED_SINCE(6, 9) |
403 | QT_DEPRECATED_VERSION_X_6_9("Use setTimeZone() instead") |
404 | void setTimeSpec(Qt::TimeSpec spec); |
405 | QT_DEPRECATED_VERSION_X_6_9("Use setTimeZone() instead") |
406 | void setOffsetFromUtc(int offsetSeconds); |
407 | #endif |
408 | #if QT_CORE_REMOVED_SINCE(6, 7) |
409 | void setTimeZone(const QTimeZone &toZone); |
410 | #endif |
411 | void setTimeZone(const QTimeZone &toZone, |
412 | TransitionResolution resolve = TransitionResolution::LegacyBehavior); |
413 | void setMSecsSinceEpoch(qint64 msecs); |
414 | void setSecsSinceEpoch(qint64 secs); |
415 | |
416 | #if QT_CONFIG(datestring) |
417 | QString toString(Qt::DateFormat format = Qt::TextDate) const; |
418 | QString toString(const QString &format) const; |
419 | QString toString(const QString &format, QCalendar cal) const |
420 | { return toString(format: qToStringViewIgnoringNull(s: format), cal); } |
421 | QString toString(QStringView format) const; |
422 | QString toString(QStringView format, QCalendar cal) const; |
423 | #endif |
424 | [[nodiscard]] QDateTime addDays(qint64 days) const; |
425 | [[nodiscard]] QDateTime addMonths(int months) const; |
426 | [[nodiscard]] QDateTime addYears(int years) const; |
427 | [[nodiscard]] QDateTime addSecs(qint64 secs) const; |
428 | [[nodiscard]] QDateTime addMSecs(qint64 msecs) const; |
429 | [[nodiscard]] QDateTime addDuration(std::chrono::milliseconds msecs) const |
430 | { |
431 | return addMSecs(msecs: msecs.count()); |
432 | } |
433 | |
434 | #if QT_DEPRECATED_SINCE(6, 9) |
435 | QT_DEPRECATED_VERSION_X_6_9("Use toTimeZone instead") |
436 | QDateTime toTimeSpec(Qt::TimeSpec spec) const; |
437 | #endif |
438 | QDateTime toLocalTime() const; |
439 | QDateTime toUTC() const; |
440 | QDateTime toOffsetFromUtc(int offsetSeconds) const; |
441 | QDateTime toTimeZone(const QTimeZone &toZone) const; |
442 | |
443 | qint64 daysTo(const QDateTime &) const; |
444 | qint64 secsTo(const QDateTime &) const; |
445 | qint64 msecsTo(const QDateTime &) const; |
446 | |
447 | static QDateTime currentDateTime(const QTimeZone &zone); |
448 | static QDateTime currentDateTime(); |
449 | static QDateTime currentDateTimeUtc(); |
450 | #if QT_CONFIG(datestring) |
451 | // No DateFormat accepts a two-digit year, so no need for baseYear: |
452 | static QDateTime fromString(QStringView string, Qt::DateFormat format = Qt::TextDate); |
453 | static QDateTime fromString(const QString &string, Qt::DateFormat format = Qt::TextDate) |
454 | { return fromString(string: qToStringViewIgnoringNull(s: string), format); } |
455 | |
456 | // Accept calendar without over-ride of base year: |
457 | static QDateTime fromString(QStringView string, QStringView format, QCalendar cal) |
458 | { return fromString(string: string.toString(), format, baseYear: QLocale::DefaultTwoDigitBaseYear, cal); } |
459 | QT_CORE_INLINE_SINCE(6, 7) |
460 | static QDateTime fromString(const QString &string, QStringView format, QCalendar cal); |
461 | static QDateTime fromString(const QString &string, const QString &format, QCalendar cal) |
462 | { return fromString(string, format: qToStringViewIgnoringNull(s: format), baseYear: QLocale::DefaultTwoDigitBaseYear, cal); } |
463 | |
464 | // Overriding base year is likely more common than overriding calendar (and |
465 | // likely to get more so, as the legacy base drops ever further behind us). |
466 | static QDateTime fromString(QStringView string, QStringView format, |
467 | int baseYear = QLocale::DefaultTwoDigitBaseYear) |
468 | { return fromString(string: string.toString(), format, baseYear); } |
469 | static QDateTime fromString(QStringView string, QStringView format, |
470 | int baseYear, QCalendar cal) |
471 | { return fromString(string: string.toString(), format, baseYear, cal); } |
472 | static QDateTime fromString(const QString &string, QStringView format, |
473 | int baseYear = QLocale::DefaultTwoDigitBaseYear); |
474 | static QDateTime fromString(const QString &string, QStringView format, |
475 | int baseYear, QCalendar cal); |
476 | static QDateTime fromString(const QString &string, const QString &format, |
477 | int baseYear = QLocale::DefaultTwoDigitBaseYear) |
478 | { return fromString(string, format: qToStringViewIgnoringNull(s: format), baseYear); } |
479 | static QDateTime fromString(const QString &string, const QString &format, |
480 | int baseYear, QCalendar cal) |
481 | { return fromString(string, format: qToStringViewIgnoringNull(s: format), baseYear, cal); } |
482 | #endif |
483 | |
484 | #if QT_DEPRECATED_SINCE(6, 9) |
485 | QT_DEPRECATED_VERSION_X_6_9("Pass QTimeZone instead of time-spec, offset") |
486 | static QDateTime fromMSecsSinceEpoch(qint64 msecs, Qt::TimeSpec spec, int offsetFromUtc = 0); |
487 | QT_DEPRECATED_VERSION_X_6_9("Pass QTimeZone instead of time-spec, offset") |
488 | static QDateTime fromSecsSinceEpoch(qint64 secs, Qt::TimeSpec spec, int offsetFromUtc = 0); |
489 | #endif |
490 | |
491 | static QDateTime fromMSecsSinceEpoch(qint64 msecs, const QTimeZone &timeZone); |
492 | static QDateTime fromSecsSinceEpoch(qint64 secs, const QTimeZone &timeZone); |
493 | static QDateTime fromMSecsSinceEpoch(qint64 msecs); |
494 | static QDateTime fromSecsSinceEpoch(qint64 secs); |
495 | |
496 | static qint64 currentMSecsSinceEpoch() noexcept; |
497 | static qint64 currentSecsSinceEpoch() noexcept; |
498 | |
499 | #if defined(Q_OS_DARWIN) || defined(Q_QDOC) |
500 | static QDateTime fromCFDate(CFDateRef date); |
501 | CFDateRef toCFDate() const Q_DECL_CF_RETURNS_RETAINED; |
502 | static QDateTime fromNSDate(const NSDate *date); |
503 | NSDate *toNSDate() const Q_DECL_NS_RETURNS_AUTORELEASED; |
504 | #endif |
505 | |
506 | static QDateTime fromStdTimePoint( |
507 | std::chrono::time_point< |
508 | std::chrono::system_clock, |
509 | std::chrono::milliseconds |
510 | > time |
511 | ); |
512 | |
513 | #if __cpp_lib_chrono >= 201907L || defined(Q_QDOC) |
514 | #if __cpp_concepts >= 201907L || defined(Q_QDOC) |
515 | private: |
516 | // The duration type of the result of a clock_cast<system_clock>. |
517 | // This duration may differ from the duration of the input. |
518 | template <typename Clock, typename Duration> |
519 | using system_clock_cast_duration = decltype( |
520 | std::chrono::clock_cast<std::chrono::system_clock>( |
521 | std::declval<const std::chrono::time_point<Clock, Duration> &>() |
522 | ).time_since_epoch() |
523 | ); |
524 | |
525 | public: |
526 | // Generic clock, as long as it's compatible with us (= system_clock) |
527 | template <typename Clock, typename Duration> |
528 | static QDateTime fromStdTimePoint(const std::chrono::time_point<Clock, Duration> &time) |
529 | requires |
530 | requires(const std::chrono::time_point<Clock, Duration> &t) { |
531 | // the clock can be converted to system_clock |
532 | std::chrono::clock_cast<std::chrono::system_clock>(t); |
533 | // after the conversion to system_clock, the duration type |
534 | // we get is convertible to milliseconds |
535 | requires std::is_convertible_v< |
536 | system_clock_cast_duration<Clock, Duration>, |
537 | std::chrono::milliseconds |
538 | >; |
539 | } |
540 | { |
541 | using namespace std::chrono; |
542 | const sys_time<milliseconds> sysTime = clock_cast<system_clock>(time); |
543 | return fromStdTimePoint(sysTime); |
544 | } |
545 | #endif // __cpp_concepts |
546 | |
547 | // local_time |
548 | QT_POST_CXX17_API_IN_EXPORTED_CLASS |
549 | static QDateTime fromStdTimePoint(const std::chrono::local_time<std::chrono::milliseconds> &time) |
550 | { |
551 | return fromStdLocalTime(time); |
552 | } |
553 | |
554 | QT_POST_CXX17_API_IN_EXPORTED_CLASS |
555 | static QDateTime fromStdLocalTime(const std::chrono::local_time<std::chrono::milliseconds> &time) |
556 | { |
557 | QDateTime result(QDate(1970, 1, 1), QTime(0, 0, 0), TransitionResolution::LegacyBehavior); |
558 | return result.addMSecs(time.time_since_epoch().count()); |
559 | } |
560 | |
561 | #if QT_CONFIG(timezone) && (__cpp_lib_chrono >= 201907L || defined(Q_QDOC)) |
562 | // zoned_time. defined in qtimezone.h |
563 | QT_POST_CXX17_API_IN_EXPORTED_CLASS |
564 | static QDateTime fromStdZonedTime(const std::chrono::zoned_time< |
565 | std::chrono::milliseconds, |
566 | const std::chrono::time_zone * |
567 | > &time); |
568 | #endif // QT_CONFIG(timezone) |
569 | |
570 | QT_POST_CXX17_API_IN_EXPORTED_CLASS |
571 | std::chrono::sys_time<std::chrono::milliseconds> toStdSysMilliseconds() const |
572 | { |
573 | const std::chrono::milliseconds duration(toMSecsSinceEpoch()); |
574 | return std::chrono::sys_time<std::chrono::milliseconds>(duration); |
575 | } |
576 | |
577 | QT_POST_CXX17_API_IN_EXPORTED_CLASS |
578 | std::chrono::sys_seconds toStdSysSeconds() const |
579 | { |
580 | const std::chrono::seconds duration(toSecsSinceEpoch()); |
581 | return std::chrono::sys_seconds(duration); |
582 | } |
583 | #endif // __cpp_lib_chrono >= 201907L |
584 | |
585 | friend std::chrono::milliseconds operator-(const QDateTime &lhs, const QDateTime &rhs) |
586 | { |
587 | return std::chrono::milliseconds(rhs.msecsTo(lhs)); |
588 | } |
589 | |
590 | friend QDateTime operator+(const QDateTime &dateTime, std::chrono::milliseconds duration) |
591 | { |
592 | return dateTime.addMSecs(msecs: duration.count()); |
593 | } |
594 | |
595 | friend QDateTime operator+(std::chrono::milliseconds duration, const QDateTime &dateTime) |
596 | { |
597 | return dateTime + duration; |
598 | } |
599 | |
600 | QDateTime &operator+=(std::chrono::milliseconds duration) |
601 | { |
602 | *this = addMSecs(msecs: duration.count()); |
603 | return *this; |
604 | } |
605 | |
606 | friend QDateTime operator-(const QDateTime &dateTime, std::chrono::milliseconds duration) |
607 | { |
608 | return dateTime.addMSecs(msecs: -duration.count()); |
609 | } |
610 | |
611 | QDateTime &operator-=(std::chrono::milliseconds duration) |
612 | { |
613 | *this = addMSecs(msecs: -duration.count()); |
614 | return *this; |
615 | } |
616 | |
617 | // (1<<63) ms is 292277024.6 (average Gregorian) years, counted from the start of 1970, so |
618 | // Last is floor(1970 + 292277024.6); no year 0, so First is floor(1970 - 1 - 292277024.6) |
619 | enum class YearRange : qint32 { First = -292275056, Last = +292278994 }; |
620 | |
621 | private: |
622 | bool equals(const QDateTime &other) const; |
623 | #if QT_CORE_REMOVED_SINCE(6, 7) |
624 | bool precedes(const QDateTime &other) const; |
625 | #endif |
626 | friend class QDateTimePrivate; |
627 | |
628 | Data d; |
629 | |
630 | friend bool comparesEqual(const QDateTime &lhs, const QDateTime &rhs) |
631 | { return lhs.equals(other: rhs); } |
632 | friend Q_CORE_EXPORT Qt::weak_ordering |
633 | compareThreeWay(const QDateTime &lhs, const QDateTime &rhs); |
634 | Q_DECLARE_WEAKLY_ORDERED_NON_NOEXCEPT(QDateTime) |
635 | |
636 | #ifndef QT_NO_DATASTREAM |
637 | friend Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QDateTime &); |
638 | friend Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QDateTime &); |
639 | #endif |
640 | |
641 | #if !defined(QT_NO_DEBUG_STREAM) && QT_CONFIG(datestring) |
642 | friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QDateTime &); |
643 | #endif |
644 | }; |
645 | Q_DECLARE_SHARED(QDateTime) |
646 | |
647 | #ifndef QT_NO_DATASTREAM |
648 | Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, QDate); |
649 | Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QDate &); |
650 | Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, QTime); |
651 | Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QTime &); |
652 | Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QDateTime &); |
653 | Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QDateTime &); |
654 | #endif // QT_NO_DATASTREAM |
655 | |
656 | #if !defined(QT_NO_DEBUG_STREAM) && QT_CONFIG(datestring) |
657 | Q_CORE_EXPORT QDebug operator<<(QDebug, QDate); |
658 | Q_CORE_EXPORT QDebug operator<<(QDebug, QTime); |
659 | Q_CORE_EXPORT QDebug operator<<(QDebug, const QDateTime &); |
660 | #endif |
661 | |
662 | // QDateTime is not noexcept for now -- to be revised once |
663 | // timezone and calendaring support is added |
664 | Q_CORE_EXPORT size_t qHash(const QDateTime &key, size_t seed = 0); |
665 | Q_CORE_EXPORT size_t qHash(QDate key, size_t seed = 0) noexcept; |
666 | Q_CORE_EXPORT size_t qHash(QTime key, size_t seed = 0) noexcept; |
667 | |
668 | #if QT_CONFIG(datestring) && QT_CORE_INLINE_IMPL_SINCE(6, 7) |
669 | QDate QDate::fromString(const QString &string, QStringView format, QCalendar cal) |
670 | { |
671 | return fromString(string, format, baseYear: QLocale::DefaultTwoDigitBaseYear, cal); |
672 | } |
673 | |
674 | QDateTime QDateTime::fromString(const QString &string, QStringView format, QCalendar cal) |
675 | { |
676 | return fromString(string, format, baseYear: QLocale::DefaultTwoDigitBaseYear, cal); |
677 | } |
678 | #endif |
679 | |
680 | QT_END_NAMESPACE |
681 | |
682 | #endif // QDATETIME_H |
683 |
Definitions
- QDate
- QDate
- QDate
- isNull
- isValid
- toString
- fromString
- fromString
- fromString
- fromString
- fromString
- fromString
- fromString
- fromJulianDay
- toJulianDay
- nullJd
- minJd
- maxJd
- unixEpochJd
- comparesEqual
- compareThreeWay
- QTime
- QTime
- QTime
- isNull
- toString
- fromMSecsSinceStartOfDay
- msecsSinceStartOfDay
- fromString
- fromString
- fromString
- TimeFlag
- ds
- comparesEqual
- compareThreeWay
- QDateTime
- ShortData
- operator==
- Data
- CanBeSmall
- operator=
- swap
- TransitionResolution
- swap
- toString
- addDuration
- fromString
- fromString
- fromString
- fromString
- fromString
- fromString
- fromString
- operator-
- operator+
- operator+
- operator+=
- operator-
- operator-=
- YearRange
- comparesEqual
- fromString
Learn Advanced QML with KDAB
Find out more