File: calendarbackend.cpp

package info (click to toggle)
qt6-base 6.9.1%2Bdfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 316,752 kB
  • sloc: cpp: 2,112,334; ansic: 381,848; xml: 142,587; python: 21,632; java: 8,505; asm: 4,009; javascript: 2,290; sh: 1,657; perl: 1,028; makefile: 131
file content (103 lines) | stat: -rw-r--r-- 3,970 bytes parent folder | download
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]