QtBase  v6.3.1
qcalendar.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2021 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 #include "qcalendar.h"
40 #include "qcalendarbackend_p.h"
41 #include "qgregoriancalendar_p.h"
42 #ifndef QT_BOOTSTRAPPED
43 #include "qjuliancalendar_p.h"
44 #include "qmilankoviccalendar_p.h"
45 #endif
46 #if QT_CONFIG(jalalicalendar)
47 #include "qjalalicalendar_p.h"
48 #endif
49 #if QT_CONFIG(islamiccivilcalendar)
51 #endif
52 
53 #include "qatomic.h"
54 #include "qdatetime.h"
55 #include "qcalendarmath_p.h"
56 #include <qhash.h>
57 #include <qreadwritelock.h>
58 
59 #include <vector>
60 
62 
63 namespace {
64 
65 struct CalendarName : public QString
66 {
68 };
69 
70 inline bool operator==(const CalendarName &u, const CalendarName &v)
71 {
72  return u.compare(v, Qt::CaseInsensitive) == 0;
73 }
74 
75 inline size_t qHash(const CalendarName &key, size_t seed = 0) noexcept
76 {
77  return qHash(key.toLower(), seed);
78 }
79 
80 } // anonymous namespace
81 
82 namespace QtPrivate {
83 
84 /*
85  \internal
86  Handles calendar backend registration.
87 */
89 {
90  Q_DISABLE_COPY_MOVE(QCalendarRegistry); // This is a singleton.
91 
92  /*
93  Lock protecting the registry from concurrent modification.
94  */
95  QReadWriteLock lock;
96 
97  /*
98  Vector containing all registered backends.
99 
100  The indices 0 to \c QCalendar::System::Last inclusive are allocated
101  for system backends and always present (but may be null).
102  */
103  std::vector<QCalendarBackend *> byId;
104 
105  /*
106  Backends registered by name.
107 
108  Each backend may be registered with several names associated with it.
109  The names are case-insensitive.
110  */
112 
113  /*
114  Pointer to the Gregorian backend for faster lockless access to it.
115 
116  This pointer may be null if the Gregorian backend is not yet registered.
117  This pointer may only be set once and only when write lock is held on
118  the registry.
119  */
120  QAtomicPointer<const QCalendarBackend> gregorianCalendar = nullptr;
121 
122  enum : int {
123  Unpopulated, // The standard backends may not yet be created
124  Populated, // All standard backends were created
125  IsBeingDestroyed, // The registry and the backends are being destroyed
126  };
127 
128  /*
129  Fast way to check whether the standard calendars were populated.
130 
131  The status should only be changed while the write lock is held.
132  */
133  QAtomicInt status = Unpopulated;
134 
135  void ensurePopulated();
136  QCalendarBackend *registerSystemBackendLockHeld(QCalendar::System system);
137  void registerBackendLockHeld(QCalendarBackend *backend, const QStringList &names,
138  QCalendar::System system);
139 
140 public:
141  QCalendarRegistry() { byId.resize(int(QCalendar::System::Last) + 1); }
142 
144 
145  bool isBeingDestroyed() const { return status.loadRelaxed() == IsBeingDestroyed; }
146 
148 
150 
151  /*
152  Returns backend for Gregorian calendar.
153 
154  The backend is returned without locking the registry if possible.
155  */
157  {
158  const QCalendarBackend *backend = gregorianCalendar.loadAcquire();
159  if (Q_LIKELY(backend != nullptr))
160  return backend;
162  }
163 
164  /*
165  Returns \a true if the argument matches the registered Gregorian backend.
166 
167  \a backend should not be \nullptr.
168  */
169  bool isGregorian(const QCalendarBackend *backend) const
170  {
171  return backend == gregorianCalendar.loadRelaxed();
172  }
173 
175  const QCalendarBackend *fromIndex(size_t index);
177 
178  QStringList backendNames(const QCalendarBackend *backend);
179 };
180 
181 /*
182  Destroy the registry.
183 
184  This destroys all registered backends. This destructor should only be called
185  in a single-threaded context at program exit.
186 */
188 {
189  QWriteLocker locker(&lock);
190 
191  status.storeRelaxed(IsBeingDestroyed);
192 
193  qDeleteAll(byId);
194 }
195 
196 /*
197  Registers a custom backend.
198 
199  A new unique ID is allocated for the \a backend. The registry takes
200  ownership of the \a backend.
201 
202  The \a names of the backend are also registered. Already registered
203  names are not updated.
204 
205  The \a backend should not be already registered.
206 
207  The \a backend should be fully initialized. It becomes available
208  to other threads before this function returns.
209 */
211 {
212  Q_ASSERT(!backend->calendarId().isValid());
213 
214  ensurePopulated();
215 
216  QWriteLocker locker(&lock);
217  registerBackendLockHeld(backend, names, QCalendar::System::User);
218 }
219 
220 /*
221  Ensures all system calendars have been instantiated.
222 
223  This arranges for each system backend to be registered. The method only
224  does anything on its first call, which ensures that name-based lookups can
225  always find all the calendars available via the \c QCalendar::System other
226  than \c QCalendar::System::User.
227 */
228 void QCalendarRegistry::ensurePopulated()
229 {
230  if (Q_LIKELY(status.loadAcquire() != Unpopulated))
231  return;
232 
233  QWriteLocker locker(&lock);
234  if (status.loadAcquire() != Unpopulated)
235  return;
236 
237  for (int i = 0; i <= int(QCalendar::System::Last); ++i) {
238  if (byId[i] == nullptr)
239  registerSystemBackendLockHeld(QCalendar::System(i));
240  }
241 
242 #if defined(QT_FORCE_ASSERTS) || !defined(QT_NO_DEBUG)
243  auto oldValue = status.fetchAndStoreRelease(Populated);
244  Q_ASSERT(oldValue == Unpopulated);
245 #else
246  status.storeRelease(Populated);
247 #endif
248 }
249 
250 /*
251  Helper functions for system backend registration.
252 
253  This function must be called with write lock held on the registry.
254 
255  \sa registerSystemBackend
256 */
257 QCalendarBackend *QCalendarRegistry::registerSystemBackendLockHeld(QCalendar::System system)
258 {
260 
261  QCalendarBackend *backend = nullptr;
263 
264  switch (system) {
266  backend = new QGregorianCalendar;
268  break;
269 #ifndef QT_BOOTSTRAPPED
271  backend = new QJulianCalendar;
273  break;
275  backend = new QMilankovicCalendar;
277  break;
278 #endif
279 #if QT_CONFIG(jalalicalendar)
280  case QCalendar::System::Jalali:
281  backend = new QJalaliCalendar;
283  break;
284 #endif
285 #if QT_CONFIG(islamiccivilcalendar)
286  case QCalendar::System::IslamicCivil:
287  backend = new QIslamicCivilCalendar;
289  break;
290 #else // When highest-numbered system isn't enabled, ensure we have a case for Last:
292 #endif
294  Q_UNREACHABLE();
295  }
296  if (!backend)
297  return nullptr;
298 
299  registerBackendLockHeld(backend, names, system);
300  Q_ASSERT(backend == byId[size_t(system)]);
301 
302  return backend;
303 }
304 
305 /*
306  Helper function for backend registration.
307 
308  This function must be called with write lock held on the registry.
309 
310  \sa registerBackend
311 */
312 void QCalendarRegistry::registerBackendLockHeld(QCalendarBackend *backend, const QStringList &names,
313  QCalendar::System system)
314 {
315  Q_ASSERT(!backend->calendarId().isValid());
316 
317  auto index = size_t(system);
318 
319  // Note: it is important to update the calendar ID before making
320  // the calendar available for queries.
321  if (system == QCalendar::System::User) {
322  backend->setIndex(byId.size());
323  byId.push_back(backend);
324  } else if (byId[index] == nullptr) {
325  backend->setIndex(index);
326  if (system == QCalendar::System::Gregorian) {
327 #if defined(QT_FORCE_ASSERTS) || !defined(QT_NO_DEBUG)
328  auto oldValue = gregorianCalendar.fetchAndStoreRelease(backend);
329  Q_ASSERT(oldValue == nullptr);
330 #else
331  gregorianCalendar.storeRelease(backend);
332 #endif
333  }
334 
335  Q_ASSERT(byId.size() > index);
336  Q_ASSERT(byId[index] == nullptr);
337  byId[index] = backend;
338  }
339 
340  // Register any names.
341  for (const auto &name : names) {
342  if (byName.contains(name)) {
344  qWarning("Cannot register name %ls (already in use) for %ls",
345  qUtf16Printable(name), qUtf16Printable(backend->name()));
346  } else {
347  byName[name] = backend;
348  }
349  }
350 }
351 
352 /*
353  Returns a list of names of the available calendar systems.
354 
355  Any QCalendarBackend sub-class must be registered before being exposed to Date
356  and Time APIs.
357 
358  \sa fromName()
359 */
361 {
362  ensurePopulated();
363 
364  QReadLocker locker(&lock);
365  return QStringList(byName.keyBegin(), byName.keyEnd());
366 }
367 
368 /*
369  Returns a pointer to a named calendar backend.
370 
371  If the given \a name is present in availableCalendars(), the backend
372  matching it is returned. Otherwise, \nullptr is returned. Matching of
373  names ignores case.
374 
375  \sa availableCalendars(), fromEnum(), fromIndex()
376 */
378 {
379  ensurePopulated();
380 
381  const QString nameU16 = name.toString();
382  QReadLocker locker(&lock);
383  return byName.value(nameU16, nullptr);
384 }
385 
386 /*
387  Returns a pointer to a calendar backend, specified by index.
388 
389  If a calendar with ID \a index is known to the calendar registry, the backend
390  with this ID is returned. Otherwise, \nullptr is returned.
391 
392  \sa fromEnum(), calendarId()
393 */
395 {
396  {
397  QReadLocker locker(&lock);
398 
399  if (index >= byId.size())
400  return nullptr;
401 
402  if (auto backend = byId[index])
403  return backend;
404  }
405 
406  if (index <= size_t(QCalendar::System::Last))
408 
409  return nullptr;
410 }
411 
412 /*
413  Returns a pointer to a calendar backend, specified by \a system.
414 
415  This will instantiate the indicated calendar (which will enable fromName()
416  to return it subsequently), but only for the Qt-supported calendars for
417  which (where relevant) the appropriate feature has been enabled.
418 
419  \a system should be a member of \a QCalendar::System other than
420  \a QCalendar::System::User.
421 
422  \sa fromName(), fromId()
423 */
425 {
427  auto index = size_t(system);
428 
429  {
430  QReadLocker locker(&lock);
431  Q_ASSERT(byId.size() > index);
432  if (auto backend = byId[index])
433  return backend;
434  }
435 
436  QWriteLocker locker(&lock);
437 
438  // Check if the backend was registered after releasing the read lock above.
439  if (auto backend = byId[index])
440  return backend;
441 
442  return registerSystemBackendLockHeld(system);
443 }
444 
445 /*
446  Returns a list of names \a backend was registered with.
447 */
449 {
450  QStringList l;
451  l.reserve(byName.size()); // too large, but never really large, so ok
452 
453  // same as byName.keys(backend), except for
454  // - the missing const on mapped_type and
455  // - CalendarName != QString as the key_type
456  for (auto it = byName.cbegin(), end = byName.cend(); it != end; ++it) {
457  if (it.value() == backend)
458  l.push_back(it.key());
459  }
460 
461  return l;
462 }
463 
464 } // namespace QtPrivate
465 
467 
551 {
552  Q_ASSERT(!m_id.isValid() || calendarRegistry.isDestroyed()
553  || calendarRegistry->isBeingDestroyed());
554 }
555 
571 {
572  if (Q_UNLIKELY(calendarRegistry.isDestroyed()))
573  return {};
574 
575  return calendarRegistry->backendNames(this);
576 }
577 
584 void QCalendarBackend::setIndex(size_t index)
585 {
586  Q_ASSERT(!m_id.isValid());
587  m_id.id = index;
588 }
589 
613 {
614  Q_ASSERT(!m_id.isValid());
615 
616  if (Q_LIKELY(!calendarRegistry.isDestroyed()))
617  calendarRegistry->registerCustomBackend(this, names);
618 
619  return m_id;
620 }
621 
623 {
624  if (Q_UNLIKELY(calendarRegistry.isDestroyed()))
625  return false;
626 
627  return calendarRegistry->isGregorian(this);
628 }
629 
647 {
648  return m_id.isInEnum() ? QCalendar::System(m_id.index()) : QCalendar::System::User;
649 }
650 
651 /*
652  Create local variable d containing the backend associated with a QCalendar
653  instance unless the calendar registry is destroyed together with all backends,
654  then return nullptr.
655 
656  This assumes that the registry is only destroyed in single threaded context.
657 */
658 #define SAFE_D() const auto d = Q_UNLIKELY(calendarRegistry.isDestroyed()) ? nullptr : d_ptr
659 
668 {
669  SAFE_D();
670  return d ? d->name() : QString();
671 }
672 
673 // date queries
692 // properties of the calendar
693 
750 int QCalendarBackend::daysInYear(int year) const
751 {
752  return monthsInYear(year) ? isLeapYear(year) ? 366 : 365 : 0;
753 }
754 
764 {
765  return year > 0 || (year < 0 ? isProleptic() : hasYearZero()) ? 12 : 0;
766 }
767 
781 bool QCalendarBackend::isDateValid(int year, int month, int day) const
782 {
783  return day > 0 && day <= daysInMonth(month, year);
784 }
785 
797 {
798  return true;
799 }
800 
809 {
810  return false;
811 }
812 
827 {
828  return 31;
829 }
830 
839 {
840  return 29;
841 }
842 
851 {
852  return 12;
853 }
854 
855 // Julian day number calculations
856 
899 {
900  return QRoundingDown::qMod(jd, 7) + 1;
901 }
902 
903 // Month and week-day name look-ups (implemented in qlocale.cpp):
1004 // End of methods implemented in qlocale.cpp
1005 
1014 {
1015  if (Q_UNLIKELY(calendarRegistry.isDestroyed()))
1016  return {};
1017 
1018  return calendarRegistry->availableCalendars();
1019 }
1020 
1031 const QCalendarBackend *QCalendarBackend::fromName(QAnyStringView name)
1032 {
1033  if (Q_UNLIKELY(calendarRegistry.isDestroyed()))
1034  return nullptr;
1035 
1036  return calendarRegistry->fromName(name);
1037 }
1038 
1048 const QCalendarBackend *QCalendarBackend::fromId(QCalendar::SystemId id)
1049 {
1050  if (Q_UNLIKELY(calendarRegistry.isDestroyed() || !id.isValid()))
1051  return nullptr;
1052 
1053  return calendarRegistry->fromIndex(id.index());
1054 }
1055 
1066 const QCalendarBackend *QCalendarBackend::fromEnum(QCalendar::System system)
1067 {
1068  if (Q_UNLIKELY(calendarRegistry.isDestroyed() || system == QCalendar::System::User))
1069  return nullptr;
1070 
1071  return calendarRegistry->fromEnum(system);
1072 }
1073 
1080 const QCalendarBackend *QCalendarBackend::gregorian()
1081 {
1082  if (Q_UNLIKELY(calendarRegistry.isDestroyed()))
1083  return nullptr;
1084 
1085  return calendarRegistry->gregorian();
1086 }
1087 
1187  : d_ptr(QCalendarBackend::gregorian())
1188 {
1189  Q_ASSERT(!d_ptr || d_ptr->calendarId().isValid());
1190 }
1191 
1192 QCalendar::QCalendar(QCalendar::System system) : d_ptr(QCalendarBackend::fromEnum(system))
1193 {
1194  // If system is valid, we should get a valid d for that system.
1195  Q_ASSERT(!d_ptr || (uint(system) > uint(QCalendar::System::Last))
1196  || (d_ptr->calendarId().index() == size_t(system)));
1197 }
1198 
1211  : d_ptr(QCalendarBackend::fromId(id))
1212 {
1213  Q_ASSERT(!d_ptr || d_ptr->calendarId().index() == id.index());
1214 }
1215 
1217  : d_ptr(QCalendarBackend::fromName(name))
1218 {
1219  Q_ASSERT(!d_ptr || d_ptr->calendarId().isValid());
1220 }
1221 
1223  : d_ptr(QCalendarBackend::fromName(name))
1224 {
1225  Q_ASSERT(!d_ptr || d_ptr->calendarId().isValid());
1226 }
1227 
1237 // Date queries:
1238 
1248 int QCalendar::daysInMonth(int month, int year) const
1249 {
1250  SAFE_D();
1251  return d ? d->daysInMonth(month, year) : 0;
1252 }
1253 
1259 int QCalendar::daysInYear(int year) const
1260 {
1261  SAFE_D();
1262  return d ? d->daysInYear(year) : 0;
1263 }
1264 
1273 int QCalendar::monthsInYear(int year) const
1274 {
1275  SAFE_D();
1276  return d ? year == Unspecified ? d->maximumMonthsInYear() : d->monthsInYear(year) : 0;
1277 }
1278 
1287 bool QCalendar::isDateValid(int year, int month, int day) const
1288 {
1289  SAFE_D();
1290  return d && d->isDateValid(year, month, day);
1291 }
1292 
1293 // properties of the calendar
1294 
1300 {
1301  SAFE_D();
1302  return d && d->isGregorian();
1303 }
1304 
1314 bool QCalendar::isLeapYear(int year) const
1315 {
1316  SAFE_D();
1317  return d && d->isLeapYear(year);
1318 }
1319 
1326 {
1327  SAFE_D();
1328  return d && d->isLunar();
1329 }
1330 
1339 {
1340  SAFE_D();
1341  return d && d->isLuniSolar();
1342 }
1343 
1351 {
1352  SAFE_D();
1353  return d && d->isSolar();
1354 }
1355 
1366 {
1367  SAFE_D();
1368  return d && d->isProleptic();
1369 }
1370 
1397 {
1398  SAFE_D();
1399  return d && d->hasYearZero();
1400 }
1401 
1408 {
1409  SAFE_D();
1410  return d ? d->maximumDaysInMonth() : 0;
1411 }
1412 
1419 {
1420  SAFE_D();
1421  return d ? d->minimumDaysInMonth() : 0;
1422 }
1423 
1430 {
1431  SAFE_D();
1432  return d ? d->maximumMonthsInYear() : 0;
1433 }
1434 
1435 // Julian Day conversions:
1436 
1451 QDate QCalendar::dateFromParts(int year, int month, int day) const
1452 {
1453  SAFE_D();
1454  qint64 jd;
1455  return d && d->dateToJulianDay(year, month, day, &jd)
1456  ? QDate::fromJulianDay(jd) : QDate();
1457 }
1458 
1460 {
1461  return parts.isValid() ? dateFromParts(parts.year, parts.month, parts.day) : QDate();
1462 }
1463 
1474 {
1475  SAFE_D();
1476  return d && date.isValid() ? d->julianDayToDate(date.toJulianDay()) : YearMonthDay();
1477 }
1478 
1489 {
1490  SAFE_D();
1491  return d && date.isValid() ? d->dayOfWeek(date.toJulianDay()) : 0;
1492 }
1493 
1494 // Locale data access
1495 
1515 QString QCalendar::monthName(const QLocale &locale, int month, int year,
1517 {
1518  SAFE_D();
1519  const int maxMonth = year == Unspecified ? maximumMonthsInYear() : monthsInYear(year);
1520  if (!d || month < 1 || month > maxMonth)
1521  return QString();
1522 
1523  return d->monthName(locale, month, year, format);
1524 }
1525 
1545 QString QCalendar::standaloneMonthName(const QLocale &locale, int month, int year,
1547 {
1548  SAFE_D();
1549  const int maxMonth = year == Unspecified ? maximumMonthsInYear() : monthsInYear(year);
1550  if (!d || month < 1 || month > maxMonth)
1551  return QString();
1552 
1553  return d->standaloneMonthName(locale, month, year, format);
1554 }
1555 
1570 QString QCalendar::weekDayName(const QLocale &locale, int day,
1572 {
1573  SAFE_D();
1574  return d ? d->weekDayName(locale, day, format) : QString();
1575 }
1576 
1595 {
1596  SAFE_D();
1597  return d ? d->standaloneWeekDayName(locale, day, format) : QString();
1598 }
1599 
1620  QDate dateOnly, QTime timeOnly,
1621  const QLocale &locale) const
1622 {
1623  SAFE_D();
1624  return d ? d->dateTimeToString(format, datetime, dateOnly, timeOnly, locale) : QString();
1625 }
1626 
1635 {
1637 }
1638 
1640 
1641 #ifndef QT_BOOTSTRAPPED
1642 #include "moc_qcalendar.cpp"
1643 #endif
small capitals from c petite p scientific f u
Definition: afcover.h:88
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
The QAtomicInt class provides platform-independent atomic operations on int.
Definition: qatomic.h:158
T fetchAndStoreRelease(T newValue) noexcept
Definition: qbasicatomic.h:132
void storeRelaxed(T newValue) noexcept
Definition: qbasicatomic.h:91
T loadAcquire() const noexcept
Definition: qbasicatomic.h:93
void storeRelease(T newValue) noexcept
Definition: qbasicatomic.h:94
T loadRelaxed() const noexcept
Definition: qbasicatomic.h:90
Type fetchAndStoreRelease(Type newValue) noexcept
Definition: qbasicatomic.h:264
Type loadAcquire() const noexcept
Definition: qbasicatomic.h:233
Type loadRelaxed() const noexcept
Definition: qbasicatomic.h:226
void storeRelease(Type newValue) noexcept
Definition: qbasicatomic.h:234
constexpr bool isValid() const noexcept
Definition: qcalendar.h:144
constexpr size_t index() const noexcept
Definition: qcalendar.h:143
virtual int daysInMonth(int month, int year=QCalendar::Unspecified) const =0
QCalendar::System calendarSystem() const
Definition: qcalendar.cpp:646
virtual bool isProleptic() const
Definition: qcalendar.cpp:796
virtual ~QCalendarBackend()
Definition: qcalendar.cpp:550
virtual bool hasYearZero() const
Definition: qcalendar.cpp:808
QCalendar::SystemId calendarId() const
virtual int dayOfWeek(qint64 jd) const
Definition: qcalendar.cpp:898
static QStringList availableCalendars()
Definition: qcalendar.cpp:1013
virtual bool isLeapYear(int year) const =0
bool isGregorian() const
Definition: qcalendar.cpp:622
virtual int minimumDaysInMonth() const
Definition: qcalendar.cpp:838
virtual int maximumDaysInMonth() const
Definition: qcalendar.cpp:826
virtual int monthsInYear(int year) const
Definition: qcalendar.cpp:763
virtual QString name() const =0
virtual int daysInYear(int year) const
Definition: qcalendar.cpp:750
QStringList names() const
Definition: qcalendar.cpp:570
QCalendar::SystemId registerCustomBackend(const QStringList &names)
Definition: qcalendar.cpp:612
virtual int maximumMonthsInYear() const
Definition: qcalendar.cpp:850
virtual bool isDateValid(int year, int month, int day) const
Definition: qcalendar.cpp:781
bool isGregorian() const
Definition: qcalendar.cpp:1299
QDate dateFromParts(int year, int month, int day) const
Definition: qcalendar.cpp:1451
int minimumDaysInMonth() const
Definition: qcalendar.cpp:1418
bool isDateValid(int year, int month, int day) const
Definition: qcalendar.cpp:1287
QString standaloneMonthName(const QLocale &locale, int month, int year=Unspecified, QLocale::FormatType format=QLocale::LongFormat) const
Definition: qcalendar.cpp:1545
static QStringList availableCalendars()
Definition: qcalendar.cpp:1634
bool isLunar() const
Definition: qcalendar.cpp:1325
QString dateTimeToString(QStringView format, const QDateTime &datetime, QDate dateOnly, QTime timeOnly, const QLocale &locale) const
Definition: qcalendar.cpp:1619
QString name() const
Definition: qcalendar.cpp:667
QString monthName(const QLocale &locale, int month, int year=Unspecified, QLocale::FormatType format=QLocale::LongFormat) const
Definition: qcalendar.cpp:1515
YearMonthDay partsFromDate(QDate date) const
Definition: qcalendar.cpp:1473
int maximumMonthsInYear() const
Definition: qcalendar.cpp:1429
int maximumDaysInMonth() const
Definition: qcalendar.cpp:1407
bool hasYearZero() const
Definition: qcalendar.cpp:1396
int monthsInYear(int year) const
Definition: qcalendar.cpp:1273
int dayOfWeek(QDate date) const
Definition: qcalendar.cpp:1488
bool isLuniSolar() const
Definition: qcalendar.cpp:1338
bool isLeapYear(int year) const
Definition: qcalendar.cpp:1314
QString standaloneWeekDayName(const QLocale &locale, int day, QLocale::FormatType format=QLocale::LongFormat) const
Definition: qcalendar.cpp:1593
bool isProleptic() const
Definition: qcalendar.cpp:1365
@ Unspecified
Definition: qcalendar.h:93
int daysInMonth(int month, int year=Unspecified) const
Definition: qcalendar.cpp:1248
int daysInYear(int year) const
Definition: qcalendar.cpp:1259
bool isSolar() const
Definition: qcalendar.cpp:1350
QString weekDayName(const QLocale &locale, int day, QLocale::FormatType format=QLocale::LongFormat) const
Definition: qcalendar.cpp:1570
The QDate class provides date functions.
Definition: qdatetime.h:64
constexpr bool isValid() const
Definition: qdatetime.h:72
constexpr qint64 toJulianDay() const
Definition: qdatetime.h:139
static constexpr QDate fromJulianDay(qint64 jd_)
Definition: qdatetime.h:137
The QDateTime class provides date and time functions.
Definition: qdatetime.h:238
template< typename Enum > size_t qHash(QFlags< Enum > flags, size_t seed=0) noexcept
template< typename Enum > bool operator==(Enum lhs, QFlags< Enum > rhs)
The QGregorianCalendar class implements the Gregorian calendar.
static QStringList nameList()
key_iterator keyEnd() const noexcept
Definition: qhash.h:1164
const_iterator cbegin() const noexcept
Definition: qhash.h:1157
qsizetype size() const noexcept
Definition: qhash.h:880
bool contains(const Key &key) const noexcept
Definition: qhash.h:944
key_iterator keyBegin() const noexcept
Definition: qhash.h:1163
T value(const Key &key) const noexcept
Definition: qhash.h:997
const_iterator cend() const noexcept
Definition: qhash.h:1161
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 QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal.
Definition: qstring.h:84
FormatType
Definition: qlocale.h:894
The QMilankovicCalendar class provides Milanković calendar system implementation.
static QStringList nameList()
The QReadLocker class is a convenience class that simplifies locking and unlocking read-write locks f...
The QReadWriteLock class provides read-write locking.
The QString class provides a Unicode character string.
Definition: qstring.h:388
The QStringList class provides a list of strings.
The QStringView class provides a unified view on UTF-16 strings with a read-only subset of the QStrin...
Definition: qstringview.h:122
The QTime class provides clock time functions.
Definition: qdatetime.h:166
The QWriteLocker class is a convenience class that simplifies locking and unlocking read-write locks ...
const QCalendarBackend * fromEnum(QCalendar::System system)
Definition: qcalendar.cpp:424
QStringList availableCalendars()
Definition: qcalendar.cpp:360
const QCalendarBackend * fromName(QAnyStringView name)
Definition: qcalendar.cpp:377
void registerCustomBackend(QCalendarBackend *backend, const QStringList &names)
Definition: qcalendar.cpp:210
bool isGregorian(const QCalendarBackend *backend) const
Definition: qcalendar.cpp:169
const QCalendarBackend * fromIndex(size_t index)
Definition: qcalendar.cpp:394
QStringList backendNames(const QCalendarBackend *backend)
Definition: qcalendar.cpp:448
const QCalendarBackend * gregorian()
Definition: qcalendar.cpp:156
QDate date
[1]
qDeleteAll(list.begin(), list.end())
constexpr Int qMod(Int a, unsigned b)
@ CaseInsensitive
Definition: qnamespace.h:1283
#define QString()
Definition: parse-defines.h:51
#define SAFE_D()
Definition: qcalendar.cpp:658
Q_GLOBAL_STATIC(QtPrivate::QCalendarRegistry, calendarRegistry)
#define Q_UNLIKELY(x)
#define Q_LIKELY(x)
#define Q_UNREACHABLE()
QList< QString > QStringList
Definition: qcontainerfwd.h:64
unsigned int uint
Definition: qglobal.h:334
long long qint64
Definition: qglobal.h:298
#define qWarning
Definition: qlogging.h:179
GLenum GLuint id
[6]
Definition: qopengl.h:270
GLsizei const GLfloat * v
[13]
GLuint64 key
GLuint index
[2]
GLuint GLuint end
GLuint name
GLint GLsizei GLsizei GLenum format
GLuint GLuint * names
Definition: qopenglext.h:5654
#define Q_ASSERT(cond)
Definition: qrandom.cpp:84
QStringList::Iterator it
bool isValid() const
Definition: qcalendar.h:99
CalendarName(const QString &name)
Definition: qcalendar.cpp:67