Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qttemporalpattern_p.h
Go to the documentation of this file.
1// Copyright (C) 2026 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// Qt-Security score:significant reason:default
4
5#ifndef QTTEMPORALPATTERN_P_H
6#define QTTEMPORALPATTERN_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 implementation
13// detail. This header file may change from version to version without notice,
14// or even be removed.
15//
16// We mean it.
17//
18
19#include <QtCore/qcalendar.h>
20#include <QtCore/qdatetime.h>
21#include <QtCore/qflags.h>
22#include <QtCore/qlist.h>
23#include <QtCore/qlocale.h>
24#include <QtCore/qmetaobject.h>
25#include <QtCore/qspan.h>
26#include <QtCore/qstring.h>
27#include <QtCore/qstringview.h>
28
29#include <optional>
30
32QT_BEGIN_NAMESPACE
33
34namespace QtTemporalPattern {
35
36 // Model the LDML spec's range of possible fields, see QTBUG-70516 and
37 // https://www.unicode.org/reports/tr35/tr35-dates.html#table-date-field-symbol-table
40
41 // Special:
43
44 // Time:
45 // MillisecondInDay = 17,
47 Minute = 24, // MinuteFraction = 25,
48 PeriodInDay = 30, // am/pm; LDML also has noon, midnight, "at night" and others.
49 HourMod12 = 31, Hour = 32, // HourFraction = 33,
50
51 // Date:
52 DayOfWeek = 64, DayOfMonth = 65, // DayOfYear = 68, JulianDay = 69,
53 // WeekOfMonth = 72,
54 // WeekOfYear = 73, // QTBUG-57212, QTBUG-83678, QTBUG-117055
55 Month = 80,
56 // Quarter = 84,
57 // RelatedGregorianYear = 90, Century = 91,
59 // Era = 100,
60
62 };
64
66 Numeric = 1, Verbal = 2, Standalone = 4,
67 Narrow = 0x10, Abbreviated = 0x20, Short = 0x40, Wide = 0x80,
68 ZeroPad = 0x0100, // For TimeZone, ZeroPad applies only to hour fields.
69 SpacePad = 0x0200, FlexSpace = 0x0400, StrictSpace = 0x0800,
70 // Qt used to impose case on am/pm fields:
71 LowerCase = 0x1000, UpperCase = 0x2000, // Otherwise follow locale-supplied case.
72 IgnoreCase = 0x4000, // Parsing Literal or Verbal: match case insensitively
73 // Year-specific:
75 // Zone-specific:
76 LocalizedZone = 0x01'0000, // Localized forms, various.
77 Iso8601 = 0x02'0000, // Non-localized standard offset forms.
78 AcceptUtcPrefix = 0x04'0000, NeedNoUtcPrefix = 0x08'0000, // On offsets
79 AllowZSuffix = 0x10'0000, // Iso8601 zero-offset may be indicated by Z.
80 // Time-types (if none specified, infer time type from date/time fields):
81 GenericTime = 0x20'0000, StandardTime = 0x40'0000, DaylightSavingTime = 0x80'0000,
82 // Local time from system info:
83 LocalTimeName = 0x8000'0000 // That's the last bit available to us.
84 };
87
88 namespace FieldGroup {
102 }
103
104 // Implement group-related tests:
105 constexpr inline
113
114 constexpr inline
122
123 // Classify the categories:
124 enum class DateTimePart { None, Date = 1, Time = 2, Zone = 4 };
127#ifdef QT_BUILD_INTERNAL
131#endif // For testing.
132
134 {
136 return DateTimePart::None;
137 if (quint8(category) < 16)
138 return DateTimePart::Zone;
139 if (quint8(category) < 64) // a.k.a. 0x40
140 return DateTimePart::Time;
141 return DateTimePart::Date;
142 }
143
144 // Combine with related information:
146 QString literal; // Only relevant to Literal
147 qsizetype width; // Lower bound, usually only relevant to Numeric.
150 DateTimePart part() const noexcept { return classify(category); }
151 friend bool comparesEqual(const TemporalField &lhs, const TemporalField &rhs) noexcept
152 {
153 return lhs.literal == rhs.literal
154 && lhs.width == rhs.width
155 && lhs.options == rhs.options
156 && lhs.category == rhs.category;
157 }
159 };
160
161 inline DateTimeParts hasFieldsFor(QSpan<const TemporalField> range)
162 {
163 DateTimeParts result = DateTimePart::None;
164 for (const TemporalField &it : range)
165 result |= it.part();
166 return result;
167 }
168
169 enum class SupportType { Partial = -1, None = 0, Clear = 1, HasStrays };
170 Q_CORE_EXPORT
172 bool hasBaseYear = false) noexcept;
173} // namespace QtTemporalPattern
174
175/* We may eventually want to make the following public API (along with a
176 forward-declaration of QtTemporalPattern::TemporalField), while leaving the
177 above in a private header. See QTBUG-70516, QTBUG-81056.
178
179 This may, of course, involve splitting the types below into a public facade
180 with the actual data members hidden from view behind a shared d-pointer to a
181 private internal class.
182
183 Please bear that in mind when considering the design of the APIs below, and
184 any future changes thereto.
185*/
186
187namespace QtTemporalPattern {
188template <typename Payload>
190{
191 Payload payload;
193};
194} // namespace QtTemporalPattern
195
197{
199 QList<Field> m_fields;
200 QLocale m_locale;
201 QCalendar m_calendar;
202 std::optional<int> m_baseYear;
203 explicit QDateTimePattern(const QList<Field> &fs) : m_fields(fs) {}
204 explicit QDateTimePattern(const QList<Field> &fs, int centuryStart)
205 : m_fields(fs), m_baseYear(centuryStart) {}
206
207 QtTemporalPattern::SupportType dateTimeSupport() const noexcept
208 {
209 using namespace QtTemporalPattern;
210 constexpr DateTimeParts NeededParts = DateTimePart::Date | DateTimePart::Time;
211 const DateTimeParts got = hasFieldsFor(m_fields);
212 // Must have date and time (zone optional) and support what it has:
213 if (got.testFlags(NeededParts))
214 return supports(got, m_fields, m_baseYear.has_value());
216 }
217public:
218 bool isValid() const noexcept
219 {
220 return dateTimeSupport() == QtTemporalPattern::SupportType::Clear;
221 }
222 void setLocale(const QLocale &loc) { m_locale = loc; }
223 const QLocale &locale() const noexcept { return m_locale; }
224
225 void setBaseYear(int centuryStart) { m_baseYear = centuryStart; }
226 void clearBaseYear() noexcept { m_baseYear = std::nullopt; }
227 std::optional<int> baseYear() const noexcept { return m_baseYear; }
228
229 void setCalendar(QCalendar cal) { m_calendar = cal; }
230 QCalendar calendar() const noexcept { return m_calendar; }
231
233 parse(QStringView text, const QDateTime &defaults = {}) const;
234 Q_CORE_EXPORT QString serialize(const QDateTime &datetime) const;
235
236 static Q_CORE_EXPORT QDateTimePattern fromQtFormat(QStringView format);
237 static
238 QDateTimePattern forLocale(const QLocale &locale,
239 QLocale::FormatType format = QLocale::LongFormat)
240 {
241 auto pat = fromQtFormat(locale.dateTimeFormat(format));
242 pat.setLocale(locale);
243 return pat;
244 }
245};
246
248{
250 QList<Field> m_fields;
251 QLocale m_locale;
252 explicit QTimePattern(const QList<Field> &fs) : m_fields(fs) {}
253
254 QtTemporalPattern::SupportType timeSupport() const noexcept
255 {
256 using namespace QtTemporalPattern;
257 return supports({DateTimePart::Time}, m_fields);
258 }
259public:
260 bool isValid() const noexcept
261 {
262 return timeSupport() == QtTemporalPattern::SupportType::Clear;
263 }
264 void setLocale(const QLocale &loc) { m_locale = loc; }
265 const QLocale &locale() const noexcept { return m_locale; }
266
268 parse(QStringView text, QTime defaults = {}) const;
269 Q_CORE_EXPORT QString serialize(const QTime &time) const;
270
271 static Q_CORE_EXPORT QTimePattern fromQtFormat(QStringView format);
272 static
273 QTimePattern forLocale(const QLocale &locale, QLocale::FormatType format = QLocale::LongFormat)
274 {
275 auto pat = fromQtFormat(locale.timeFormat(format));
276 pat.setLocale(locale);
277 return pat;
278 }
279};
280
282{
284 QList<Field> m_fields;
285 QLocale m_locale;
286 QCalendar m_calendar;
287 std::optional<int> m_baseYear;
288 explicit QDatePattern(const QList<Field> &fs) : m_fields(fs) {}
289 explicit QDatePattern(const QList<Field> &fs, int centuryStart)
290 : m_fields(fs), m_baseYear(centuryStart) {}
291
292 QtTemporalPattern::SupportType dateSupport() const noexcept
293 {
294 using namespace QtTemporalPattern;
295 return supports({DateTimePart::Date}, m_fields, m_baseYear.has_value());
296 }
297public:
298 bool isValid() const noexcept
299 {
300 return dateSupport() == QtTemporalPattern::SupportType::Clear;
301 }
302 void setLocale(const QLocale &loc) { m_locale = loc; }
303 const QLocale &locale() const noexcept { return m_locale; }
304
305 void setBaseYear(int centuryStart) { m_baseYear = centuryStart; }
306 void clearBaseYear() noexcept { m_baseYear = std::nullopt; }
307 std::optional<int> baseYear() const noexcept { return m_baseYear; }
308
309 void setCalendar(QCalendar cal) { m_calendar = cal; }
310 QCalendar calendar() const noexcept { return m_calendar; }
311
313 parse(QStringView text, QDate defaults = {}) const;
314 Q_CORE_EXPORT QString serialize(const QDate &date) const;
315
316 static Q_CORE_EXPORT QDatePattern fromQtFormat(QStringView format);
317 static
318 QDatePattern forLocale(const QLocale &locale, QLocale::FormatType format = QLocale::LongFormat)
319 {
320 auto pat = fromQtFormat(locale.dateFormat(format));
321 pat.setLocale(locale);
322 return pat;
323 }
324};
325
326QT_END_NAMESPACE
327
328#endif // QTTEMPORALPATTERN_P_H
A description of a serialization format for a date.
void setBaseYear(int centuryStart)
const QLocale & locale() const noexcept
Returns the current locale in use by this pattern.
QCalendar calendar() const noexcept
Returns the current calendar in use by this pattern.
bool isValid() const noexcept
static QDatePattern forLocale(const QLocale &locale, QLocale::FormatType format=QLocale::LongFormat)
Construct a QDatePattern appropriate to the given locale.
void setCalendar(QCalendar cal)
void setLocale(const QLocale &loc)
void clearBaseYear() noexcept
std::optional< int > baseYear() const noexcept
A description of a serialization format for a datetime.
bool isValid() const noexcept
void clearBaseYear() noexcept
void setBaseYear(int centuryStart)
QCalendar calendar() const noexcept
Returns the current calendar in use by this pattern.
void setCalendar(QCalendar cal)
static QDateTimePattern forLocale(const QLocale &locale, QLocale::FormatType format=QLocale::LongFormat)
Construct a QDateTimePattern appropriate to the given locale.
std::optional< int > baseYear() const noexcept
void setLocale(const QLocale &loc)
const QLocale & locale() const noexcept
Returns the current locale in use by this pattern.
A description of a serialization format for a time.
void setLocale(const QLocale &loc)
bool isValid() const noexcept
static QTimePattern forLocale(const QLocale &locale, QLocale::FormatType format=QLocale::LongFormat)
Construct a QTimePattern appropriate to the given locale.
const QLocale & locale() const noexcept
Returns the current locale in use by this pattern.
Supporting types and functions for temporal patterns.
constexpr auto EndTemporalFieldCategories
DateTimeParts hasFieldsFor(QSpan< const TemporalField > range)
Identify the parts to which the given fields contribute data.
QT_REQUIRE_CONFIG(datestring)