Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qcalendar.cpp
Go to the documentation of this file.
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#include "qcalendar.h"
6#ifndef QT_BOOTSTRAPPED
7#include "qjuliancalendar_p.h"
9#endif
10#if QT_CONFIG(jalalicalendar)
11#include "qjalalicalendar_p.h"
12#endif
13#if QT_CONFIG(islamiccivilcalendar)
15#endif
16
17#include <private/qflatmap_p.h>
18#include "qatomic.h"
19#include "qdatetime.h"
20#include "qcalendarmath_p.h"
21#include <qhash.h>
22#include <qreadwritelock.h>
23
24#include <vector>
25
27
36
37namespace QtPrivate {
38
39/*
40 \internal
41 Handles calendar backend registration.
42*/
44{
45 Q_DISABLE_COPY_MOVE(QCalendarRegistry); // This is a singleton.
46
47 static constexpr qsizetype ExpectedNumberOfBackends = qsizetype(QCalendar::System::Last) + 1;
48
49 /*
50 Lock protecting the registry from concurrent modification.
51 */
52 QReadWriteLock lock;
53
54 /*
55 Vector containing all registered backends.
56
57 The indices 0 to \c QCalendar::System::Last inclusive are allocated
58 for system backends and always present (but may be null).
59 */
60 std::vector<QCalendarBackend *> byId;
61
62 /*
63 Backends registered by name.
64
65 Each backend may be registered with several names associated with it.
66 The names are case-insensitive.
67 */
72 std::vector<QCalendarBackend *>
73 > byName;
74
75 /*
76 Pointer to the Gregorian backend for faster lockless access to it.
77
78 This pointer may be null if the Gregorian backend is not yet registered.
79 This pointer may only be set once and only when write lock is held on
80 the registry.
81 */
82 QAtomicPointer<const QCalendarBackend> gregorianCalendar = nullptr;
83
84 enum : int {
85 Unpopulated, // The standard backends may not yet be created
86 Populated, // All standard backends were created
87 IsBeingDestroyed, // The registry and the backends are being destroyed
88 };
89
90 /*
91 Fast way to check whether the standard calendars were populated.
92
93 The status should only be changed while the write lock is held.
94 */
95 QAtomicInt status = Unpopulated;
96
97 void ensurePopulated();
98 QCalendarBackend *registerSystemBackendLockHeld(QCalendar::System system);
99 void registerBackendLockHeld(QCalendarBackend *backend, const QStringList &names,
100 QCalendar::System system);
101
102public:
104 {
105 byId.resize(ExpectedNumberOfBackends);
106 byName.reserve(ExpectedNumberOfBackends * 2); // assume one alias on average
107 }
108
110
111 bool isBeingDestroyed() const { return status.loadRelaxed() == IsBeingDestroyed; }
112
114
116
117 /*
118 Returns backend for Gregorian calendar.
119
120 The backend is returned without locking the registry if possible.
121 */
123 {
124 const QCalendarBackend *backend = gregorianCalendar.loadAcquire();
125 if (Q_LIKELY(backend != nullptr))
126 return backend;
128 }
129
130 /*
131 Returns \a true if the argument matches the registered Gregorian backend.
132
133 \a backend should not be \nullptr.
134 */
135 bool isGregorian(const QCalendarBackend *backend) const
136 {
137 return backend == gregorianCalendar.loadRelaxed();
138 }
139
141 const QCalendarBackend *fromIndex(size_t index);
143
145};
146
147/*
148 Destroy the registry.
149
150 This destroys all registered backends. This destructor should only be called
151 in a single-threaded context at program exit.
152*/
154{
155 QWriteLocker locker(&lock);
156
157 status.storeRelaxed(IsBeingDestroyed);
158
159 qDeleteAll(byId);
160}
161
162/*
163 Registers a custom backend.
164
165 A new unique ID is allocated for the \a backend. The registry takes
166 ownership of the \a backend.
167
168 The \a names of the backend are also registered. Already registered
169 names are not updated.
170
171 The \a backend should not be already registered.
172
173 The \a backend should be fully initialized. It becomes available
174 to other threads before this function returns.
175*/
177{
178 Q_ASSERT(!backend->calendarId().isValid());
179
180 ensurePopulated();
181
182 QWriteLocker locker(&lock);
183 registerBackendLockHeld(backend, names, QCalendar::System::User);
184}
185
186/*
187 Ensures all system calendars have been instantiated.
188
189 This arranges for each system backend to be registered. The method only
190 does anything on its first call, which ensures that name-based lookups can
191 always find all the calendars available via the \c QCalendar::System other
192 than \c QCalendar::System::User.
193*/
194void QCalendarRegistry::ensurePopulated()
195{
196 if (Q_LIKELY(status.loadAcquire() != Unpopulated))
197 return;
198
199 QWriteLocker locker(&lock);
200 if (status.loadAcquire() != Unpopulated)
201 return;
202
203 for (int i = 0; i <= int(QCalendar::System::Last); ++i) {
204 if (byId[i] == nullptr)
205 registerSystemBackendLockHeld(QCalendar::System(i));
206 }
207
208#if defined(QT_FORCE_ASSERTS) || !defined(QT_NO_DEBUG)
209 auto oldValue = status.fetchAndStoreRelease(Populated);
210 Q_ASSERT(oldValue == Unpopulated);
211#else
212 status.storeRelease(Populated);
213#endif
214}
215
216/*
217 Helper functions for system backend registration.
218
219 This function must be called with write lock held on the registry.
220
221 \sa registerSystemBackend
222*/
223QCalendarBackend *QCalendarRegistry::registerSystemBackendLockHeld(QCalendar::System system)
224{
226
227 QCalendarBackend *backend = nullptr;
229
230 switch (system) {
232 backend = new QGregorianCalendar;
234 break;
235#ifndef QT_BOOTSTRAPPED
237 backend = new QJulianCalendar;
239 break;
241 backend = new QMilankovicCalendar;
243 break;
244#endif
245#if QT_CONFIG(jalalicalendar)
246 case QCalendar::System::Jalali:
247 backend = new QJalaliCalendar;
249 break;
250#endif
251#if QT_CONFIG(islamiccivilcalendar)
252 case QCalendar::System::IslamicCivil:
253 backend = new QIslamicCivilCalendar;
255 break;
256#else // When highest-numbered system isn't enabled, ensure we have a case for Last:
258#endif
260 Q_UNREACHABLE();
261 }
262 if (!backend)
263 return nullptr;
264
265 registerBackendLockHeld(backend, names, system);
266 Q_ASSERT(backend == byId[size_t(system)]);
267
268 return backend;
269}
270
271/*
272 Helper function for backend registration.
273
274 This function must be called with write lock held on the registry.
275
276 \sa registerBackend
277*/
278void QCalendarRegistry::registerBackendLockHeld(QCalendarBackend *backend, const QStringList &names,
279 QCalendar::System system)
280{
281 Q_ASSERT(!backend->calendarId().isValid());
282
283 auto index = size_t(system);
284
285 // Note: it is important to update the calendar ID before making
286 // the calendar available for queries.
287 if (system == QCalendar::System::User) {
288 backend->setIndex(byId.size());
289 byId.push_back(backend);
290 } else if (byId[index] == nullptr) {
291 backend->setIndex(index);
292 if (system == QCalendar::System::Gregorian) {
293#if defined(QT_FORCE_ASSERTS) || !defined(QT_NO_DEBUG)
294 auto oldValue = gregorianCalendar.fetchAndStoreRelease(backend);
295 Q_ASSERT(oldValue == nullptr);
296#else
297 gregorianCalendar.storeRelease(backend);
298#endif
299 }
300
301 Q_ASSERT(byId.size() > index);
302 Q_ASSERT(byId[index] == nullptr);
303 byId[index] = backend;
304 }
305
306 // Register any names.
307 for (const auto &name : names) {
308 auto [it, inserted] = byName.try_emplace(name, backend);
309 if (!inserted) {
311 qWarning("Cannot register name %ls (already in use) for %ls",
313 }
314 }
315}
316
317/*
318 Returns a list of names of the available calendar systems.
319
320 Any QCalendarBackend sub-class must be registered before being exposed to Date
321 and Time APIs.
322
323 \sa fromName()
324*/
326{
327 ensurePopulated();
328
329 QReadLocker locker(&lock);
330 return byName.keys();
331}
332
333/*
334 Returns a pointer to a named calendar backend.
335
336 If the given \a name is present in availableCalendars(), the backend
337 matching it is returned. Otherwise, \nullptr is returned. Matching of
338 names ignores case.
339
340 \sa availableCalendars(), fromEnum(), fromIndex()
341*/
343{
344 ensurePopulated();
345
346 QReadLocker locker(&lock);
347 return byName.value(name, nullptr);
348}
349
350/*
351 Returns a pointer to a calendar backend, specified by index.
352
353 If a calendar with ID \a index is known to the calendar registry, the backend
354 with this ID is returned. Otherwise, \nullptr is returned.
355
356 \sa fromEnum(), calendarId()
357*/
359{
360 {
361 QReadLocker locker(&lock);
362
363 if (index >= byId.size())
364 return nullptr;
365
366 if (auto backend = byId[index])
367 return backend;
368 }
369
370 if (index <= size_t(QCalendar::System::Last))
372
373 return nullptr;
374}
375
376/*
377 Returns a pointer to a calendar backend, specified by \a system.
378
379 This will instantiate the indicated calendar (which will enable fromName()
380 to return it subsequently), but only for the Qt-supported calendars for
381 which (where relevant) the appropriate feature has been enabled.
382
383 \a system should be a member of \a QCalendar::System other than
384 \a QCalendar::System::User.
385
386 \sa fromName(), fromId()
387*/
389{
391 auto index = size_t(system);
392
393 {
394 QReadLocker locker(&lock);
395 Q_ASSERT(byId.size() > index);
396 if (auto backend = byId[index])
397 return backend;
398 }
399
400 QWriteLocker locker(&lock);
401
402 // Check if the backend was registered after releasing the read lock above.
403 if (auto backend = byId[index])
404 return backend;
405
406 return registerSystemBackendLockHeld(system);
407}
408
409/*
410 Returns a list of names \a backend was registered with.
411*/
413{
414 QStringList l;
415 l.reserve(byName.size()); // too large, but never really large, so ok
416
418 // Clang complains about the reference still causing a copy. The reference is idiomatic, but
419 // runs afoul of QFlatMap's iterators which return a pair of references instead of a reference
420 // to pair. Suppress the warning, because `const auto [key, value]` would look wrong.
421 QT_WARNING_DISABLE_CLANG("-Wrange-loop-analysis")
422 for (const auto &[key, value] : byName) {
423 if (value == backend)
424 l.push_back(key);
425 }
427
428 return l;
429}
430
431} // namespace QtPrivate
432
434
518{
519 Q_ASSERT(!m_id.isValid() || calendarRegistry.isDestroyed()
520 || calendarRegistry->isBeingDestroyed());
521}
522
538{
539 if (Q_UNLIKELY(calendarRegistry.isDestroyed()))
540 return {};
541
542 return calendarRegistry->backendNames(this);
543}
544
551void QCalendarBackend::setIndex(size_t index)
552{
553 Q_ASSERT(!m_id.isValid());
554 m_id.id = index;
555}
556
580{
581 Q_ASSERT(!m_id.isValid());
582
583 if (Q_LIKELY(!calendarRegistry.isDestroyed()))
584 calendarRegistry->registerCustomBackend(this, names);
585
586 return m_id;
587}
588
590{
591 if (Q_UNLIKELY(calendarRegistry.isDestroyed()))
592 return false;
593
594 return calendarRegistry->isGregorian(this);
595}
596
617
618/*
619 Create local variable d containing the backend associated with a QCalendar
620 instance unless the calendar registry is destroyed together with all backends,
621 then return nullptr.
622
623 This assumes that the registry is only destroyed in single threaded context.
624*/
625#define SAFE_D() const auto d = Q_UNLIKELY(calendarRegistry.isDestroyed()) ? nullptr : d_ptr
626
635{
636 SAFE_D();
637 return d ? d->name() : QString();
638}
639
640// date queries
659// properties of the calendar
660
718{
719 return monthsInYear(year) ? isLeapYear(year) ? 366 : 365 : 0;
720}
721
731{
732 return year > 0 || (year < 0 ? isProleptic() : hasYearZero()) ? 12 : 0;
733}
734
748bool QCalendarBackend::isDateValid(int year, int month, int day) const
749{
750 return day > 0 && day <= daysInMonth(month, year);
751}
752
764{
765 return true;
766}
767
776{
777 return false;
778}
779
794{
795 return 31;
796}
797
806{
807 return 29;
808}
809
818{
819 return 12;
820}
821
822// Julian day number calculations
823
871{
872 return QRoundingDown::qMod<7>(jd) + 1;
873}
874
895{
896 Q_ASSERT(parts.isValid());
897 // Brute-force solution as fall-back.
898 const auto checkOffset = [parts, dow, this](int centuries) -> std::optional<qint64> {
899 // Offset parts.year by the given number of centuries:
900 int year = parts.year + centuries * 100;
901 // but take into account the effect of crossing zero, if we did:
902 if (!hasYearZero() && (parts.year > 0) != (year > 0))
903 year += parts.year > 0 ? -1 : +1;
904 qint64 jd;
905 if (isDateValid(year, parts.month, parts.day)
906 && dateToJulianDay(year, parts.month, parts.day, &jd)
907 && dayOfWeek(jd) == dow) {
908 return jd;
909 }
910 return std::nullopt;
911 };
912 // Empirically, aside from Gregorian, each calendar finds every dow within
913 // any 29-century run, so 14 centuries is the biggest offset we ever need.
914 for (int offset = 0; offset < 15; ++offset) {
915 if (auto jd = checkOffset(offset))
916 return *jd;
917 if (offset) {
918 if (auto jd = checkOffset(-offset))
919 return *jd;
920 }
921 }
922 return (std::numeric_limits<qint64>::min)();
923}
924
925// Month and week-day name look-ups (implemented in qlocale.cpp):
1026// End of methods implemented in qlocale.cpp
1027
1036{
1037 if (Q_UNLIKELY(calendarRegistry.isDestroyed()))
1038 return {};
1039
1040 return calendarRegistry->availableCalendars();
1041}
1042
1053const QCalendarBackend *QCalendarBackend::fromName(QAnyStringView name)
1054{
1055 if (Q_UNLIKELY(calendarRegistry.isDestroyed()))
1056 return nullptr;
1057
1058 return calendarRegistry->fromName(name);
1059}
1060
1070const QCalendarBackend *QCalendarBackend::fromId(QCalendar::SystemId id)
1071{
1072 if (Q_UNLIKELY(calendarRegistry.isDestroyed() || !id.isValid()))
1073 return nullptr;
1074
1075 return calendarRegistry->fromIndex(id.index());
1076}
1077
1088const QCalendarBackend *QCalendarBackend::fromEnum(QCalendar::System system)
1089{
1090 if (Q_UNLIKELY(calendarRegistry.isDestroyed() || system == QCalendar::System::User))
1091 return nullptr;
1092
1093 return calendarRegistry->fromEnum(system);
1094}
1095
1102const QCalendarBackend *QCalendarBackend::gregorian()
1103{
1104 if (Q_UNLIKELY(calendarRegistry.isDestroyed()))
1105 return nullptr;
1106
1107 return calendarRegistry->gregorian();
1108}
1109
1211 : d_ptr(QCalendarBackend::gregorian())
1212{
1213 Q_ASSERT(!d_ptr || d_ptr->calendarId().isValid());
1214}
1215
1217{
1218 // If system is valid, we should get a valid d for that system.
1219 Q_ASSERT(!d_ptr || (uint(system) > uint(QCalendar::System::Last))
1220 || (d_ptr->calendarId().index() == size_t(system)));
1221}
1222
1235 : d_ptr(QCalendarBackend::fromId(id))
1236{
1237 Q_ASSERT(!d_ptr || d_ptr->calendarId().index() == id.index());
1238}
1239
1241 : d_ptr(QCalendarBackend::fromName(name))
1242{
1243 Q_ASSERT(!d_ptr || d_ptr->calendarId().isValid());
1244}
1245
1255// Date queries:
1256
1266int QCalendar::daysInMonth(int month, int year) const
1267{
1268 SAFE_D();
1269 return d ? d->daysInMonth(month, year) : 0;
1270}
1271
1277int QCalendar::daysInYear(int year) const
1278{
1279 SAFE_D();
1280 return d ? d->daysInYear(year) : 0;
1281}
1282
1291int QCalendar::monthsInYear(int year) const
1292{
1293 SAFE_D();
1294 return d ? year == Unspecified ? d->maximumMonthsInYear() : d->monthsInYear(year) : 0;
1295}
1296
1305bool QCalendar::isDateValid(int year, int month, int day) const
1306{
1307 SAFE_D();
1308 return d && d->isDateValid(year, month, day);
1309}
1310
1311// properties of the calendar
1312
1318{
1319 SAFE_D();
1320 return d && d->isGregorian();
1321}
1322
1332bool QCalendar::isLeapYear(int year) const
1333{
1334 SAFE_D();
1335 return d && d->isLeapYear(year);
1336}
1337
1344{
1345 SAFE_D();
1346 return d && d->isLunar();
1347}
1348
1357{
1358 SAFE_D();
1359 return d && d->isLuniSolar();
1360}
1361
1369{
1370 SAFE_D();
1371 return d && d->isSolar();
1372}
1373
1384{
1385 SAFE_D();
1386 return d && d->isProleptic();
1387}
1388
1415{
1416 SAFE_D();
1417 return d && d->hasYearZero();
1418}
1419
1426{
1427 SAFE_D();
1428 return d ? d->maximumDaysInMonth() : 0;
1429}
1430
1437{
1438 SAFE_D();
1439 return d ? d->minimumDaysInMonth() : 0;
1440}
1441
1448{
1449 SAFE_D();
1450 return d ? d->maximumMonthsInYear() : 0;
1451}
1452
1453// Julian Day conversions:
1454
1469QDate QCalendar::dateFromParts(int year, int month, int day) const
1470{
1471 SAFE_D();
1472 qint64 jd;
1473 return d && d->dateToJulianDay(year, month, day, &jd)
1474 ? QDate::fromJulianDay(jd) : QDate();
1475}
1476
1478{
1479 return parts.isValid() ? dateFromParts(parts.year, parts.month, parts.day) : QDate();
1480}
1481
1502{
1503 SAFE_D();
1504 return d && parts.isValid()
1505 ? QDate::fromJulianDay(d->matchCenturyToWeekday(parts, dow)) : QDate();
1506}
1507
1518{
1519 SAFE_D();
1520 return d && date.isValid() ? d->julianDayToDate(date.toJulianDay()) : YearMonthDay();
1521}
1522
1533{
1534 SAFE_D();
1535 return d && date.isValid() ? d->dayOfWeek(date.toJulianDay()) : 0;
1536}
1537
1538// Locale data access
1539
1559QString QCalendar::monthName(const QLocale &locale, int month, int year,
1561{
1562 SAFE_D();
1563 const int maxMonth = year == Unspecified ? maximumMonthsInYear() : monthsInYear(year);
1564 if (!d || month < 1 || month > maxMonth)
1565 return QString();
1566
1567 return d->monthName(locale, month, year, format);
1568}
1569
1589QString QCalendar::standaloneMonthName(const QLocale &locale, int month, int year,
1591{
1592 SAFE_D();
1593 const int maxMonth = year == Unspecified ? maximumMonthsInYear() : monthsInYear(year);
1594 if (!d || month < 1 || month > maxMonth)
1595 return QString();
1596
1597 return d->standaloneMonthName(locale, month, year, format);
1598}
1599
1616{
1617 SAFE_D();
1618 return d ? d->weekDayName(locale, day, format) : QString();
1619}
1620
1639{
1640 SAFE_D();
1641 return d ? d->standaloneWeekDayName(locale, day, format) : QString();
1642}
1643
1664 QDate dateOnly, QTime timeOnly,
1665 const QLocale &locale) const
1666{
1667 SAFE_D();
1668 return d ? d->dateTimeToString(format, datetime, dateOnly, timeOnly, locale) : QString();
1669}
1670
1682
1684
1685#ifndef QT_BOOTSTRAPPED
1686#include "moc_qcalendar.cpp"
1687#endif
\inmodule QtCore
static Q_CORE_EXPORT int compare(QAnyStringView lhs, QAnyStringView rhs, Qt::CaseSensitivity cs=Qt::CaseSensitive) noexcept
Compares the string view lhs with the string view rhs and returns a negative integer if lhs is less t...
Definition qstring.cpp:1599
\inmodule QtCore
Definition qatomic.h:112
T fetchAndStoreRelease(T newValue) noexcept
void storeRelaxed(T newValue) noexcept
T loadAcquire() const noexcept
void storeRelease(T newValue) noexcept
T loadRelaxed() const noexcept
Type fetchAndStoreRelease(Type newValue) noexcept
void storeRelease(Type newValue) noexcept
The QCalendarBackend class provides basic calendaring functions.
virtual int daysInMonth(int month, int year=QCalendar::Unspecified) const =0
Returns number of days in the month number month, in year year.
QCalendar::System calendarSystem() const
The calendar system of this calendar.
virtual bool isProleptic() const
Returns true if this calendar is a proleptic calendar.
virtual ~QCalendarBackend()
Destroys the calendar backend.
virtual bool hasYearZero() const
Returns true if year number 0 is considered a valid year in this calendar.
QCalendar::SystemId calendarId() const
virtual int dayOfWeek(qint64 jd) const
Returns the day of the week for the given Julian Day Number jd.
static QStringList availableCalendars()
Returns a list of names of the available calendar systems.
virtual bool isLeapYear(int year) const =0
Returns true if the specified year is a leap year for this calendar.
bool isGregorian() const
virtual int minimumDaysInMonth() const
Returns the minimum number of days in any valid month of any valid year.
virtual bool dateToJulianDay(int year, int month, int day, qint64 *jd) const =0
Computes the Julian day number corresponding to the specified year, month, and day.
virtual int maximumDaysInMonth() const
Returns the maximum number of days in a month for any year.
virtual int monthsInYear(int year) const
Returns the total number of months in the year number year.
virtual QString name() const =0
Returns the primary name of the calendar.
virtual int daysInYear(int year) const
Returns the total number of days in the year number year.
QStringList names() const
Returns list of names this backend was registered with.
virtual qint64 matchCenturyToWeekday(const QCalendar::YearMonthDay &parts, int dow) const
QCalendar::SystemId registerCustomBackend(const QStringList &names)
Register this backend as a custom backend.
virtual int maximumMonthsInYear() const
Returns the maximum number of months possible in any year.
virtual bool isDateValid(int year, int month, int day) const
Returns true if the date specified by year, month, and day is valid for this calendar; otherwise retu...
\inmodule QtCore
Definition qcalendar.h:98
constexpr bool isValid() const noexcept
Returns true if this is a valid calendar implementation identifier, false otherwise.
Definition qcalendar.h:108
constexpr size_t index() const noexcept
Definition qcalendar.h:107
bool isGregorian() const
Returns true if this calendar object is the Gregorian calendar object used as default calendar by oth...
QDate dateFromParts(int year, int month, int day) const
System
This enumerated type is used to specify a choice of calendar system.
Definition qcalendar.h:73
int minimumDaysInMonth() const
Returns the number of days in the shortest month in the calendar, in any year.
bool isDateValid(int year, int month, int day) const
Returns true precisely if the given year, month, and day specify a valid date in this calendar.
@ Unspecified
Definition qcalendar.h:57
QString standaloneMonthName(const QLocale &locale, int month, int year=Unspecified, QLocale::FormatType format=QLocale::LongFormat) const
Returns a suitably localised standalone name for a month.
static QStringList availableCalendars()
Returns a list of names of the available calendar systems.
bool isLunar() const
Returns true if this calendar is a lunar calendar.
QDate matchCenturyToWeekday(const YearMonthDay &parts, int dow) const
QString dateTimeToString(QStringView format, const QDateTime &datetime, QDate dateOnly, QTime timeOnly, const QLocale &locale) const
Returns a string representing a given date, time or date-time.
QString name() const
The primary name of this calendar.
QString monthName(const QLocale &locale, int month, int year=Unspecified, QLocale::FormatType format=QLocale::LongFormat) const
Returns a suitably localised name for a month.
YearMonthDay partsFromDate(QDate date) const
Converts a QDate to a year, month, and day of the month.
int maximumMonthsInYear() const
Returns the largest number of months that any year may contain.
int maximumDaysInMonth() const
Returns the number of days in the longest month in the calendar, in any year.
bool hasYearZero() const
Returns true if this calendar has a year zero.
int monthsInYear(int year) const
Returns the number of months in the given year.
int dayOfWeek(QDate date) const
Returns the day of the week number for the given date.
bool isLuniSolar() const
Returns true if this calendar is luni-solar.
bool isLeapYear(int year) const
Returns true if the given year is a leap year.
QString standaloneWeekDayName(const QLocale &locale, int day, QLocale::FormatType format=QLocale::LongFormat) const
Returns a suitably localised standalone name for a day of the week.
bool isProleptic() const
Returns true if this calendar is proleptic.
int daysInMonth(int month, int year=Unspecified) const
Returns the number of days in the given month of the given year.
int daysInYear(int year) const
Returns the number of days in the given year.
bool isSolar() const
Returns true if this calendar is solar.
QString weekDayName(const QLocale &locale, int day, QLocale::FormatType format=QLocale::LongFormat) const
Returns a suitably localised name for a day of the week.
\inmodule QtCore\reentrant
Definition qdatetime.h:283
\inmodule QtCore \reentrant
Definition qdatetime.h:29
constexpr bool isValid() const
Returns true if this date is valid; otherwise returns false.
Definition qdatetime.h:71
constexpr qint64 toJulianDay() const
Converts the date to a Julian day.
Definition qdatetime.h:170
static constexpr QDate fromJulianDay(qint64 jd_)
Converts the Julian day jd to a QDate.
Definition qdatetime.h:168
const key_container_type & keys() const noexcept
Definition qflatmap_p.h:582
T value(const Key &key, const T &defaultValue) const
Definition qflatmap_p.h:636
std::pair< iterator, bool > try_emplace(const Key &key, Args &&...args)
Definition qflatmap_p.h:700
size_type size() const noexcept
Definition qflatmap_p.h:577
The QGregorianCalendar class implements the Gregorian calendar.
static QStringList nameList()
Implements a commonly-used computed version of the Islamic calendar.
static QStringList nameList()
The QJalaliCalendar class provides Jalali (Hijri Shamsi) calendar system implementation.
static QStringList nameList()
The QJulianCalendar class provides Julian calendar system implementation.
static QStringList nameList()
The QMilankovicCalendar class provides Milanković calendar system implementation.
static QStringList nameList()
\inmodule QtCore
\inmodule QtCore
\inmodule QtCore
\inmodule QtCore
Definition qstringview.h:78
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
\inmodule QtCore \reentrant
Definition qdatetime.h:215
\inmodule QtCore
const QCalendarBackend * fromEnum(QCalendar::System system)
const QCalendarBackend * fromName(QAnyStringView name)
void registerCustomBackend(QCalendarBackend *backend, const QStringList &names)
bool isGregorian(const QCalendarBackend *backend) const
const QCalendarBackend * fromIndex(size_t index)
QStringList backendNames(const QCalendarBackend *backend)
const QCalendarBackend * gregorian()
QDate date
[1]
qDeleteAll(list.begin(), list.end())
QSet< QString >::iterator it
Combined button and popup list for selecting options.
\macro QT_NO_KEYWORDS >
@ CaseInsensitive
#define SAFE_D()
#define Q_UNLIKELY(x)
#define QT_WARNING_POP
#define Q_LIKELY(x)
#define QT_WARNING_PUSH
#define QT_WARNING_DISABLE_CLANG(text)
QList< QString > QStringList
Constructs a string list that contains the given string, str.
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
#define qWarning
Definition qlogging.h:166
GLuint64 key
GLuint index
[2]
GLenum GLuint id
[7]
GLenum GLuint GLintptr offset
GLuint name
GLint GLsizei GLsizei GLenum format
GLuint GLuint * names
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define qUtf16Printable(string)
Definition qstring.h:1543
ptrdiff_t qsizetype
Definition qtypes.h:165
unsigned int uint
Definition qtypes.h:34
long long qint64
Definition qtypes.h:60
bool operator()(QAnyStringView lhs, QAnyStringView rhs) const
Definition qcalendar.cpp:31
bool isValid() const
Definition qcalendar.h:63