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
qislamiccivilcalendar.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// Qt-Security score:significant reason:default
4
5#include "qglobal.h"
8
10
11using namespace QRoundingDown;
12
13/*!
14 \since 5.14
15 \internal
16
17 \class QIslamicCivilCalendar
18 \inmodule QtCore
19 \brief Implements a commonly-used computed version of the Islamic calendar.
20
21 \section1 Civil Islamic Calendar
22
23 QIslamicCivilCalendar implements a tabular version of the Hijri calendar
24 which is known as the Islamic Civil Calendar. It has the same numbering of
25 years and months, but the months are determined by arithmetical rules rather
26 than by observation or astronomical calculations.
27
28 \section2 Calendar Organization
29
30 The civil calendar follows the usual tabular scheme of odd-numbered months
31 and the last month of each leap year being 30 days long, the rest being 29
32 days long. Its determination of leap years follows a 30-year cycle, in each
33 of which the years 2, 5, 7, 10, 13, 16, 18, 21, 24, 26 and 29 are leap
34 years.
35
36 \sa QHijriCalendar, QCalendar
37*/
38
39QString QIslamicCivilCalendar::name() const
40{
41 return QStringLiteral("Islamic Civil");
42}
43
44QStringList QIslamicCivilCalendar::nameList()
45{
46 return {
47 QStringLiteral("Islamic Civil"),
48 QStringLiteral("islamic-civil"), // CLDR name
49 QStringLiteral("islamicc"), // old CLDR name, still (2018) used by Mozilla
50 // Until we have a concrete implementation that knows all the needed ephemerides:
51 QStringLiteral("Islamic"),
52 };
53}
54
55bool QIslamicCivilCalendar::isLeapYear(int year) const
56{
57 if (year == QCalendar::Unspecified)
58 return false;
59 if (year < 0)
60 ++year;
61 return qMod<30>(year * 11 + 14) < 11;
62}
63
64// First day of first year (Gregorian 622 CE July 19th) is the base date here:
65constexpr qint64 EpochJd = 1948440;
66// Each 30 years has 11 leap years of 355 days and 19 ordinary years of 354:
67constexpr unsigned ThirtyYears = 11 * 355 + 19 * 354;
68// The first eleven months of the year alternate 30, 29, ..., 29, 30 days in length.
69constexpr unsigned ElevenMonths = 6 * 30 + 5 * 29;
70
71bool QIslamicCivilCalendar::dateToJulianDay(int year, int month, int day, qint64 *jd) const
72{
73 Q_ASSERT(jd);
74 if (!isDateValid(year, month, day))
75 return false;
76
77 *jd = qDiv<30>(qint64(ThirtyYears) * (year > 0 ? year - 1 : year) + 14)
78 + qDiv<11>(ElevenMonths * (month - 1) + 5)
79 + day + EpochJd - 1;
80 return true;
81}
82
83QCalendar::YearMonthDay QIslamicCivilCalendar::julianDayToDate(qint64 jd) const
84{
85 const auto year30Day = qDivMod<ThirtyYears>(30 * (jd - EpochJd) + 15);
86 // Its remainder changes by 30 per day, except roughly yearly.
87 const auto month11Day = qDivMod<ElevenMonths>(11 * qDiv<30>(year30Day.remainder) + 5);
88 // Its remainder changes by 11 per day except roughly monthly.
89 const int month = month11Day.quotient + 1;
90 const int day = qDiv<11>(month11Day.remainder) + 1;
91 const int y = year30Day.quotient + 1;
92 return QCalendar::YearMonthDay(y > 0 ? y : y - 1, month, day);
93}
94
95QT_END_NAMESPACE
Combined button and popup list for selecting options.
constexpr unsigned ElevenMonths
constexpr qint64 EpochJd
constexpr unsigned ThirtyYears