1 | // Copyright (C) 2022 The Qt Company Ltd. |
2 | // Copyright (C) 2016 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_P_H |
6 | #define QDATETIME_P_H |
7 | |
8 | // |
9 | // W A R N I N G |
10 | // ------------- |
11 | // |
12 | // This file is not part of the Qt API. It exists purely as an |
13 | // implementation detail. This header file may change from version to |
14 | // version without notice, or even be removed. |
15 | // |
16 | // We mean it. |
17 | // |
18 | |
19 | #include <QtCore/private/qglobal_p.h> |
20 | #include "qplatformdefs.h" |
21 | #include "QtCore/qatomic.h" |
22 | #include "QtCore/qdatetime.h" |
23 | #include "QtCore/qshareddata.h" |
24 | #include "QtCore/qtimezone.h" |
25 | |
26 | #if QT_CONFIG(timezone) |
27 | #include "qtimezone.h" |
28 | #endif |
29 | |
30 | #include <chrono> |
31 | |
32 | QT_BEGIN_NAMESPACE |
33 | |
34 | class QDateTimePrivate : public QSharedData |
35 | { |
36 | public: |
37 | // forward the declarations from QDateTime (this makes them public) |
38 | typedef QDateTime::ShortData QDateTimeShortData; |
39 | typedef QDateTime::Data QDateTimeData; |
40 | |
41 | // Never change or delete this enum, it is required for backwards compatible |
42 | // serialization of QDateTime before 5.2, so is essentially public API |
43 | enum Spec { |
44 | LocalUnknown = -1, |
45 | LocalStandard = 0, |
46 | LocalDST = 1, |
47 | UTC = 2, |
48 | OffsetFromUTC = 3, |
49 | TimeZone = 4 |
50 | }; |
51 | |
52 | // Daylight Time Status |
53 | enum DaylightStatus { |
54 | UnknownDaylightTime = -1, |
55 | StandardTime = 0, |
56 | DaylightTime = 1 |
57 | }; |
58 | |
59 | // Status of date/time |
60 | enum StatusFlag { |
61 | ShortData = 0x01, |
62 | |
63 | ValidDate = 0x02, |
64 | ValidTime = 0x04, |
65 | ValidDateTime = 0x08, |
66 | |
67 | TimeSpecMask = 0x30, |
68 | |
69 | SetToStandardTime = 0x40, |
70 | SetToDaylightTime = 0x80, |
71 | ValidityMask = ValidDate | ValidTime | ValidDateTime, |
72 | DaylightMask = SetToStandardTime | SetToDaylightTime, |
73 | }; |
74 | Q_DECLARE_FLAGS(StatusFlags, StatusFlag) |
75 | |
76 | enum { |
77 | TimeSpecShift = 4, |
78 | }; |
79 | |
80 | struct ZoneState { |
81 | qint64 when; // ms after zone/local 1970 start; may be revised from the input time. |
82 | int offset = 0; // seconds |
83 | DaylightStatus dst = UnknownDaylightTime; |
84 | // Other fields are set, if possible, even when valid is false due to spring-forward. |
85 | bool valid = false; |
86 | |
87 | ZoneState(qint64 local) : when(local) {} |
88 | ZoneState(qint64 w, int o, DaylightStatus d, bool v = true) |
89 | : when(w), offset(o), dst(d), valid(v) {} |
90 | }; |
91 | |
92 | static QDateTime::Data create(QDate toDate, QTime toTime, const QTimeZone &timeZone); |
93 | #if QT_CONFIG(timezone) |
94 | static ZoneState zoneStateAtMillis(const QTimeZone &zone, qint64 millis, DaylightStatus dst); |
95 | #endif // timezone |
96 | |
97 | static ZoneState expressUtcAsLocal(qint64 utcMSecs); |
98 | |
99 | static ZoneState localStateAtMillis(qint64 millis, DaylightStatus dst); |
100 | static QString localNameAtMillis(qint64 millis, DaylightStatus dst); // empty if unknown |
101 | |
102 | StatusFlags m_status = StatusFlag(Qt::LocalTime << TimeSpecShift); |
103 | qint64 m_msecs = 0; |
104 | int m_offsetFromUtc = 0; |
105 | QTimeZone m_timeZone; |
106 | }; |
107 | |
108 | Q_DECLARE_OPERATORS_FOR_FLAGS(QDateTimePrivate::StatusFlags) |
109 | |
110 | namespace QtPrivate { |
111 | namespace DateTimeConstants { |
112 | using namespace std::chrono; |
113 | constexpr qint64 SECS_PER_MIN = minutes::period::num; |
114 | constexpr qint64 SECS_PER_HOUR = hours::period::num; |
115 | constexpr qint64 SECS_PER_DAY = SECS_PER_HOUR * 24; // std::chrono::days is C++20 |
116 | |
117 | constexpr qint64 MINS_PER_HOUR = std::ratio_divide<hours::period, minutes::period>::num; |
118 | |
119 | constexpr qint64 MSECS_PER_SEC = milliseconds::period::den; |
120 | constexpr qint64 MSECS_PER_MIN = SECS_PER_MIN * MSECS_PER_SEC; |
121 | constexpr qint64 MSECS_PER_HOUR = SECS_PER_HOUR * MSECS_PER_SEC; |
122 | constexpr qint64 MSECS_PER_DAY = SECS_PER_DAY * MSECS_PER_SEC; |
123 | |
124 | constexpr qint64 JULIAN_DAY_FOR_EPOCH = 2440588; // result of QDate(1970, 1, 1).toJulianDay() |
125 | |
126 | constexpr qint64 JulianDayMax = Q_INT64_C( 784354017364); |
127 | constexpr qint64 JulianDayMin = Q_INT64_C(-784350574879); |
128 | } |
129 | } |
130 | |
131 | QT_END_NAMESPACE |
132 | |
133 | #endif // QDATETIME_P_H |
134 | |