summaryrefslogtreecommitdiffstats
path: root/src/corelib/time/qdatetime_p.h
blob: de4de85d8c2b7f6edd3fda31723334ddfec2b8a2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// Copyright (C) 2022 The Qt Company Ltd.
// Copyright (C) 2016 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only

#ifndef QDATETIME_P_H
#define QDATETIME_P_H

//
//  W A R N I N G
//  -------------
//
// This file is not part of the Qt API.  It exists purely as an
// implementation detail.  This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//

#include <QtCore/private/qglobal_p.h>
#include "qplatformdefs.h"
#include "QtCore/qatomic.h"
#include "QtCore/qdatetime.h"
#include "QtCore/qshareddata.h"

#if QT_CONFIG(timezone)
#include "qtimezone.h"
#endif

#include <chrono>

QT_BEGIN_NAMESPACE

class QDateTimePrivate : public QSharedData
{
public:
    // forward the declarations from QDateTime (this makes them public)
    typedef QDateTime::ShortData QDateTimeShortData;
    typedef QDateTime::Data QDateTimeData;

    // Never change or delete this enum, it is required for backwards compatible
    // serialization of QDateTime before 5.2, so is essentially public API
    enum Spec {
        LocalUnknown = -1,
        LocalStandard = 0,
        LocalDST = 1,
        UTC = 2,
        OffsetFromUTC = 3,
        TimeZone = 4
    };

    // Daylight Time Status
    enum DaylightStatus {
        UnknownDaylightTime = -1,
        StandardTime = 0,
        DaylightTime = 1
    };

    // Status of date/time
    enum StatusFlag {
        ShortData           = 0x01,

        ValidDate           = 0x02,
        ValidTime           = 0x04,
        ValidDateTime       = 0x08,
        ValidWhenMask       = ValidDate | ValidTime | ValidDateTime,

        TimeSpecMask        = 0x30,

        SetToStandardTime   = 0x40,
        SetToDaylightTime   = 0x80,
        ValidityMask        = ValidDate | ValidTime | ValidDateTime,
        DaylightMask        = SetToStandardTime | SetToDaylightTime,
    };
    Q_DECLARE_FLAGS(StatusFlags, StatusFlag)

    enum {
        TimeSpecShift = 4,
    };

    struct ZoneState {
        qint64 when; // ms after zone/local 1970 start; may be revised from the input time.
        int offset = 0; // seconds
        DaylightStatus dst = UnknownDaylightTime;
        // Other fields are set, if possible, even when valid is false due to spring-forward.
        bool valid = false;

        ZoneState(qint64 local) : when(local) {}
        ZoneState(qint64 w, int o, DaylightStatus d, bool v = true)
            : when(w), offset(o), dst(d), valid(v) {}
    };

    static QDateTime::Data create(QDate toDate, QTime toTime, Qt::TimeSpec toSpec,
                                  int offsetSeconds);

#if QT_CONFIG(timezone)
    static QDateTime::Data create(QDate toDate, QTime toTime, const QTimeZone & timeZone);

    static ZoneState zoneStateAtMillis(const QTimeZone &zone, qint64 millis, DaylightStatus dst);
#endif // timezone

    static ZoneState expressUtcAsLocal(qint64 utcMSecs);

    static ZoneState localStateAtMillis(qint64 millis, DaylightStatus dst);
    static QString localNameAtMillis(qint64 millis, DaylightStatus dst); // empty if unknown

    StatusFlags m_status = StatusFlag(Qt::LocalTime << TimeSpecShift);
    qint64 m_msecs = 0;
    int m_offsetFromUtc = 0;
#if QT_CONFIG(timezone)
    QTimeZone m_timeZone;
#endif // timezone
};

Q_DECLARE_OPERATORS_FOR_FLAGS(QDateTimePrivate::StatusFlags)

namespace QtPrivate {
namespace DateTimeConstants {
using namespace std::chrono;
constexpr qint64 SECS_PER_MIN = minutes::period::num;
constexpr qint64 SECS_PER_HOUR = hours::period::num;
constexpr qint64 SECS_PER_DAY = SECS_PER_HOUR * 24; // std::chrono::days is C++20

constexpr qint64 MINS_PER_HOUR = std::ratio_divide<hours::period, minutes::period>::num;

constexpr qint64 MSECS_PER_SEC = milliseconds::period::den;
constexpr qint64 MSECS_PER_MIN = SECS_PER_MIN * MSECS_PER_SEC;
constexpr qint64 MSECS_PER_HOUR = SECS_PER_HOUR * MSECS_PER_SEC;
constexpr qint64 MSECS_PER_DAY = SECS_PER_DAY * MSECS_PER_SEC;

constexpr qint64 JULIAN_DAY_FOR_EPOCH = 2440588; // result of QDate(1970, 1, 1).toJulianDay()
}
}

QT_END_NAMESPACE

#endif // QDATETIME_P_H