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