1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QCALENDAR_H
5#define QCALENDAR_H
6
7#include <limits>
8
9#include <QtCore/qglobal.h>
10#include <QtCore/qlocale.h>
11#include <QtCore/qstring.h>
12#include <QtCore/qstringview.h>
13
14/* Suggested enum names for other calendars known to CLDR (v33.1)
15
16 Not yet implemented - see QCalendar::System - contributions welcome:
17
18 * Buddhist -- Thai Buddhist, to be specific
19 * Chinese
20 * Coptic
21 * Dangi -- Korean
22 * Ethiopic (Amete Mihret - epoch approx. 8 C.E.)
23 * EthiopicAmeteAlem (Amete Alem - epoch approx. 5493 B.C.E; data from
24 type="ethiopic-amete-alem", an alias for type="ethioaa")
25 * Hebrew
26 * Indian -- National
27 * Islamic -- Based on astronomical observations, not predictions, so hard to
28 implement. CLDR's data for type="islamic" apply, unless overridden, to the
29 other Islamic calendar variants, i.e. IslamicCivil, above, and the three
30 following. See QHijriCalendar, a common base to provide that data.
31 * IslamicTabular -- tabular, astronomical epoch (same as IslamicCivil, except
32 for epoch), CLDR type="islamic-tbla"
33 * Saudi -- Saudi Arabia, sighting; CLDR type="islamic-rgsa"
34 * UmmAlQura -- Umm al-Qura, Saudi Arabia, calculated; CLDR type="islamic-umalqura"
35 * Iso8601 -- as Gregorian, but treating ISO 8601 weeks as "months"
36 * Japanese -- Imperial calendar
37 * Minguo -- Republic of China, Taiwan; CLDR type="roc"
38
39 See:
40 http://www.unicode.org/repos/cldr/tags/latest/common/bcp47/calendar.xml
41
42 These can potentially be supported, as features, using CLDR's data; any
43 others shall need hand-crafted localization data; it would probably be best
44 to do that by contributing data for them to CLDR.
45*/
46
47QT_BEGIN_NAMESPACE
48
49class QCalendarBackend;
50class QDate;
51
52class Q_CORE_EXPORT QCalendar
53{
54 Q_GADGET
55public:
56 // (Extra parentheses to suppress bogus reading of min() as a macro.)
57 enum : int { Unspecified = (std::numeric_limits<int>::min)() };
58 struct YearMonthDay
59 {
60 YearMonthDay() = default;
61 YearMonthDay(int y, int m = 1, int d = 1) : year(y), month(m), day(d) {}
62
63 bool isValid() const
64 { return month != Unspecified && day != Unspecified; }
65 // (The first year supported by QDate has year == Unspecified.)
66
67 int year = Unspecified;
68 int month = Unspecified;
69 int day = Unspecified;
70 };
71 // Feature (\w+)calendar uses CLDR type="\1" data, except as noted in type="..." comments below
72 enum class System
73 {
74 Gregorian, // CLDR: type = "gregory", alias = "gregorian"
75#ifndef QT_BOOTSTRAPPED
76 Julian = 8,
77 Milankovic = 9,
78#endif // These are Roman-based, so share Gregorian's CLDR data
79
80 // Feature-controlled calendars:
81#if QT_CONFIG(jalalicalendar) // type="persian"
82 Jalali = 10,
83#endif
84#if QT_CONFIG(islamiccivilcalendar) // type="islamic-civil", uses data from type="islamic"
85 IslamicCivil = 11,
86 // tabular, civil epoch
87 // 30 year cycle, leap on 2, 5, 7, 10, 13, 16, 18, 21, 24, 26 and 29
88 // (Other variants: 2, 5, 8, (10|11), 13, 16, 19, 21, 24, 27 and 29.)
89#endif
90
91 Last = 11, // Highest number of any above
92 User = -1
93 };
94 // New entries must be added to the \enum doc in qcalendar.cpp and
95 // handled in QCalendarBackend::fromEnum()
96 Q_ENUM(System)
97 class SystemId
98 {
99 size_t id;
100 friend class QCalendarBackend;
101 constexpr bool isInEnum() const { return id <= size_t(QCalendar::System::Last); }
102 constexpr explicit SystemId(QCalendar::System e) : id(size_t(e)) { }
103 constexpr explicit SystemId(size_t i) : id(i) { }
104
105 public:
106 constexpr SystemId() : id(~size_t(0)) {}
107 constexpr size_t index() const noexcept { return id; }
108 constexpr bool isValid() const noexcept { return ~id; }
109 };
110
111 explicit QCalendar(); // Gregorian, optimised
112 explicit QCalendar(System system);
113#if QT_CORE_REMOVED_SINCE(6, 4)
114 explicit QCalendar(QLatin1StringView name);
115 explicit QCalendar(QStringView name);
116#endif
117 explicit QCalendar(QAnyStringView name);
118 explicit QCalendar(SystemId id);
119
120 // QCalendar is a trivially copyable value type.
121 bool isValid() const { return d_ptr != nullptr; }
122
123 // Date queries:
124 int daysInMonth(int month, int year = Unspecified) const;
125 int daysInYear(int year) const;
126 int monthsInYear(int year) const;
127 bool isDateValid(int year, int month, int day) const;
128
129 // Leap years:
130 bool isLeapYear(int year) const;
131
132 // Properties of the calendar:
133 bool isGregorian() const;
134 bool isLunar() const;
135 bool isLuniSolar() const;
136 bool isSolar() const;
137 bool isProleptic() const;
138 bool hasYearZero() const;
139 int maximumDaysInMonth() const;
140 int minimumDaysInMonth() const;
141 int maximumMonthsInYear() const;
142 QString name() const;
143
144 // QDate conversions:
145 QDate dateFromParts(int year, int month, int day) const;
146 QDate dateFromParts(const YearMonthDay &parts) const;
147 YearMonthDay partsFromDate(QDate date) const;
148 int dayOfWeek(QDate date) const;
149
150 // Month and week-day names (as in QLocale):
151 QString monthName(const QLocale &locale, int month, int year = Unspecified,
152 QLocale::FormatType format=QLocale::LongFormat) const;
153 QString standaloneMonthName(const QLocale &locale, int month, int year = Unspecified,
154 QLocale::FormatType format = QLocale::LongFormat) const;
155 QString weekDayName(const QLocale &locale, int day,
156 QLocale::FormatType format = QLocale::LongFormat) const;
157 QString standaloneWeekDayName(const QLocale &locale, int day,
158 QLocale::FormatType format=QLocale::LongFormat) const;
159
160 // Formatting of date-times:
161 QString dateTimeToString(QStringView format, const QDateTime &datetime,
162 QDate dateOnly, QTime timeOnly,
163 const QLocale &locale) const;
164
165 // What's available ?
166 static QStringList availableCalendars();
167private:
168 // Always supplied by QCalendarBackend and expected to be a singleton
169 // Note that the calendar registry destroys all backends when it is itself
170 // destroyed. The code should check if the registry is destroyed before
171 // dereferencing this pointer.
172 const QCalendarBackend *d_ptr;
173};
174
175QT_END_NAMESPACE
176
177#endif // QCALENDAR_H
178

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