1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
|
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "calendarbackend.h"
#include <QCalendar>
JulianGregorianCalendar::JulianGregorianCalendar(QDate endJulian, QAnyStringView name = {})
: m_julianUntil(julian.partsFromDate(endJulian)),
m_gregorianSince(gregorian.partsFromDate(endJulian.addDays(1))),
m_name(name.isEmpty()
? endJulian.toString(u"Julian until yyyy-MM-dd", julian)
: name.toString())
{
Q_ASSERT_X(m_julianUntil.year < m_gregorianSince.year
|| (m_julianUntil.year == m_gregorianSince.year
&& (m_julianUntil.month < m_gregorianSince.month
|| (m_julianUntil.month == m_gregorianSince.month
&& m_julianUntil.day < m_gregorianSince.day))),
"JulianGregorianCalendar::JulianGregorianCalendar()",
"Perversely early date for Julian-to-Gregorian transition");
}
QString JulianGregorianCalendar::name() const
{
return QStringLiteral("JulianGregorian");
}
int JulianGregorianCalendar::daysInMonth(int month, int year) const
{
if (year == QCalendar::Unspecified)
return QRomanCalendar::daysInMonth(month, year);
if (year < m_julianUntil.year
|| (year == m_julianUntil.year && month < m_julianUntil.month)) {
return julian.daysInMonth(month, year);
}
if ((year > m_gregorianSince.year)
|| (year == m_gregorianSince.year && month > m_gregorianSince.month)) {
return gregorian.daysInMonth(month, year);
}
if (m_julianUntil.year == m_gregorianSince.year) {
Q_ASSERT(year == m_julianUntil.year);
if (m_julianUntil.month == m_gregorianSince.month) {
Q_ASSERT(month == m_julianUntil.month);
return QRomanCalendar::daysInMonth(month, year)
+ m_julianUntil.day - m_gregorianSince.day + 1;
}
}
if (year == m_julianUntil.year && month == m_julianUntil.month)
return m_julianUntil.day;
if (year == m_gregorianSince.year && month == m_gregorianSince.month)
return gregorian.daysInMonth(month, year) + 1 - m_gregorianSince.day;
Q_ASSERT(year > 3900);
return 0;
}
bool JulianGregorianCalendar::isLeapYear(int year) const
{
if (year < m_julianUntil.year
|| (year == m_julianUntil.year
&& (m_julianUntil.month > 2
|| (m_julianUntil.month == 2 && m_julianUntil.day == 29)))) {
return julian.isLeapYear(year);
}
return gregorian.isLeapYear(year);
}
//![0]
bool JulianGregorianCalendar::dateToJulianDay(int year, int month, int day, qint64 *jd) const
{
if (year == m_julianUntil.year && month == m_julianUntil.month) {
if (m_julianUntil.day < day && day < m_gregorianSince.day) {
// Requested date is in the gap skipped over by the transition.
*jd = 0;
return false;
}
}
QDate givenDate = gregorian.dateFromParts(year, month, day);
QDate julianUntil = julian.dateFromParts(m_julianUntil);
if (givenDate > julianUntil) {
*jd = givenDate.toJulianDay();
return true;
}
*jd = julian.dateFromParts(year, month, day).toJulianDay();
return true;
}
//![0]
//![1]
QCalendar::YearMonthDay JulianGregorianCalendar::julianDayToDate(qint64 jd) const
{
const qint64 jdForChange = julian.dateFromParts(m_julianUntil).toJulianDay();
if (jdForChange < jd) {
QCalendar gregorian(QCalendar::System::Gregorian);
QDate date = QDate::fromJulianDay(jd);
return gregorian.partsFromDate(date);
} else if (jd <= jdForChange) {
QCalendar julian(QCalendar::System::Julian);
QDate date = QDate::fromJulianDay(jd);
return julian.partsFromDate(date);
}
return QCalendar::YearMonthDay(QCalendar::Unspecified, QCalendar::Unspecified,
QCalendar::Unspecified);
}
//![1]
|