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
32QT_BEGIN_NAMESPACE
33
34class QDateTimePrivate : public QSharedData
35{
36public:
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
108Q_DECLARE_OPERATORS_FOR_FLAGS(QDateTimePrivate::StatusFlags)
109
110namespace QtPrivate {
111namespace DateTimeConstants {
112using namespace std::chrono;
113constexpr qint64 SECS_PER_MIN = minutes::period::num;
114constexpr qint64 SECS_PER_HOUR = hours::period::num;
115constexpr qint64 SECS_PER_DAY = SECS_PER_HOUR * 24; // std::chrono::days is C++20
116
117constexpr qint64 MINS_PER_HOUR = std::ratio_divide<hours::period, minutes::period>::num;
118
119constexpr qint64 MSECS_PER_SEC = milliseconds::period::den;
120constexpr qint64 MSECS_PER_MIN = SECS_PER_MIN * MSECS_PER_SEC;
121constexpr qint64 MSECS_PER_HOUR = SECS_PER_HOUR * MSECS_PER_SEC;
122constexpr qint64 MSECS_PER_DAY = SECS_PER_DAY * MSECS_PER_SEC;
123
124constexpr qint64 JULIAN_DAY_FOR_EPOCH = 2440588; // result of QDate(1970, 1, 1).toJulianDay()
125
126constexpr qint64 JulianDayMax = Q_INT64_C( 784354017364);
127constexpr qint64 JulianDayMin = Q_INT64_C(-784350574879);
128}
129}
130
131QT_END_NAMESPACE
132
133#endif // QDATETIME_P_H
134

source code of qtbase/src/corelib/time/qdatetime_p.h