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
qmilankoviccalendar.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
4#include "qglobal.h"
6#include "qcalendarmath_p.h"
7
8#include <QtCore/qdatetime.h>
9
11
12using namespace QRoundingDown;
13
40{
41 return QStringLiteral("Milankovic");
42}
43
45{
46 return { QStringLiteral("Milankovic") };
47}
48
50{
51 if (year == QCalendar::Unspecified)
52 return false;
53 if (year <= 0)
54 ++year;
55 if (qMod<4>(year))
56 return false;
57 const auto yeardm = qDivMod<100>(year);
58 if (yeardm.remainder == 0) {
59 const qint16 century = qMod<9>(yeardm.quotient);
60 if (century != 2 && century != 6)
61 return false;
62 }
63 return true;
64}
65
66using namespace QRomanCalendrical;
67// End a Milankovic nine-century cycle on 1 BC, Feb 28 (Gregorian Feb 29):
69// Leap years every 4 years, except for 7 turn-of-century years per nine centuries:
70constexpr unsigned NineCenturies = 365 * 900 + 900 / 4 - 7;
71// When the turn-of-century is a leap year, the century has 25 leap years in it:
72constexpr unsigned LeapCentury = 365 * 100 + 25;
73
74bool QMilankovicCalendar::dateToJulianDay(int year, int month, int day, qint64 *jd) const
75{
76 Q_ASSERT(jd);
77 if (!isDateValid(year, month, day))
78 return false;
79
80 const auto yearDays = yearMonthToYearDays(year, month);
81 const auto centuryYear = qDivMod<100>(yearDays.year);
82 const qint64 fromYear = qDiv<9>(NineCenturies * centuryYear.quotient + 6)
83 + qDiv<100>(LeapCentury * centuryYear.remainder);
84 *jd = fromYear + yearDays.days + day + MilankovicBaseJd;
85 return true;
86}
87
89{
90 const auto century9Day = qDivMod<NineCenturies>(9 * (jd - MilankovicBaseJd) - 7);
91 // Its remainder changes by 9 per day, except roughly once per century.
92 const auto year100Day = qDivMod<LeapCentury>(100 * qDiv<9>(century9Day.remainder) + 99);
93 // Its remainder changes by 100 per day, except roughly once per year.
94 const auto ymd = dayInYearToYmd(qDiv<100>(year100Day.remainder));
95 const int y = 100 * century9Day.quotient + year100Day.quotient + ymd.year;
96 return QCalendar::YearMonthDay(y > 0 ? y : y - 1, ymd.month, ymd.day);
97}
98
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...
@ Unspecified
Definition qcalendar.h:57
QString name() const override
Returns the primary name of the calendar.
QCalendar::YearMonthDay julianDayToDate(qint64 jd) const override
Computes the year, month, and day in this calendar for the given Julian day number jd.
bool dateToJulianDay(int year, int month, int day, qint64 *jd) const override
Computes the Julian day number corresponding to the specified year, month, and day.
bool isLeapYear(int year) const override
Returns true if the specified year is a leap year for this calendar.
static QStringList nameList()
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
constexpr qint64 LeapDayGregorian1Bce
constexpr auto dayInYearToYmd(int dayInYear)
constexpr auto yearMonthToYearDays(int year, int month)
Combined button and popup list for selecting options.
constexpr qint64 MilankovicBaseJd
constexpr unsigned NineCenturies
constexpr unsigned LeapCentury
GLint y
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define QStringLiteral(str)
short qint16
Definition qtypes.h:47
long long qint64
Definition qtypes.h:60