Refactor QGregorianCalendar::julianFromParts to return std::optional
It's a private static used to optimize internal use, so we can freely get rid of its out parameter this way. Change-Id: Id62612987f10ecbbd9702610fd172286adbfd442 Reviewed-by: Marc Mutz <marc.mutz@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
22909abeae
commit
4c93b9c1d0
@ -63,9 +63,9 @@ static inline QDate fixedDate(QCalendar::YearMonthDay parts)
|
||||
{
|
||||
if (parts.year) {
|
||||
parts.day = qMin(parts.day, QGregorianCalendar::monthLength(parts.month, parts.year));
|
||||
qint64 jd;
|
||||
if (QGregorianCalendar::julianFromParts(parts.year, parts.month, parts.day, &jd))
|
||||
return QDate::fromJulianDay(jd);
|
||||
const auto jd = QGregorianCalendar::julianFromParts(parts.year, parts.month, parts.day);
|
||||
if (jd)
|
||||
return QDate::fromJulianDay(*jd);
|
||||
}
|
||||
return QDate();
|
||||
}
|
||||
@ -437,9 +437,7 @@ QDate::QDate(int y, int m, int d)
|
||||
{
|
||||
static_assert(QDate::maxJd() == JulianDayMax);
|
||||
static_assert(QDate::minJd() == JulianDayMin);
|
||||
|
||||
if (!QGregorianCalendar::julianFromParts(y, m, d, &jd))
|
||||
jd = nullJd();
|
||||
jd = QGregorianCalendar::julianFromParts(y, m, d).value_or(nullJd());
|
||||
}
|
||||
|
||||
QDate::QDate(int y, int m, int d, QCalendar cal)
|
||||
@ -698,9 +696,8 @@ int QDate::dayOfYear(QCalendar cal) const
|
||||
int QDate::dayOfYear() const
|
||||
{
|
||||
if (isValid()) {
|
||||
qint64 first;
|
||||
if (QGregorianCalendar::julianFromParts(year(), 1, 1, &first))
|
||||
return jd - first + 1;
|
||||
if (const auto first = QGregorianCalendar::julianFromParts(year(), 1, 1))
|
||||
return jd - *first + 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -1303,11 +1300,9 @@ QString QDate::toString(QStringView format, QCalendar cal) const
|
||||
*/
|
||||
bool QDate::setDate(int year, int month, int day)
|
||||
{
|
||||
if (QGregorianCalendar::julianFromParts(year, month, day, &jd))
|
||||
return true;
|
||||
|
||||
jd = nullJd();
|
||||
return false;
|
||||
const auto maybe = QGregorianCalendar::julianFromParts(year, month, day);
|
||||
jd = maybe.value_or(nullJd());
|
||||
return bool(maybe);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -2698,10 +2693,11 @@ QDateTimePrivate::ZoneState QDateTimePrivate::expressUtcAsLocal(qint64 utcMSecs)
|
||||
// dates might be right, and adjust by the number of days that was off:
|
||||
const qint64 jd = msecsToJulianDay(utcMSecs);
|
||||
const auto ymd = QGregorianCalendar::partsFromJulian(jd);
|
||||
qint64 fakeJd, diffMillis, fakeUtc;
|
||||
if (Q_UNLIKELY(!QGregorianCalendar::julianFromParts(systemTimeYearMatching(ymd.year),
|
||||
ymd.month, ymd.day, &fakeJd)
|
||||
|| mul_overflow(jd - fakeJd, std::integral_constant<qint64, MSECS_PER_DAY>(),
|
||||
qint64 diffMillis, fakeUtc;
|
||||
const auto fakeJd = QGregorianCalendar::julianFromParts(systemTimeYearMatching(ymd.year),
|
||||
ymd.month, ymd.day);
|
||||
if (Q_UNLIKELY(!fakeJd
|
||||
|| mul_overflow(jd - *fakeJd, std::integral_constant<qint64, MSECS_PER_DAY>(),
|
||||
&diffMillis)
|
||||
|| sub_overflow(utcMSecs, diffMillis, &fakeUtc))) {
|
||||
return result;
|
||||
@ -2724,11 +2720,11 @@ static auto millisToWithinRange(qint64 millis)
|
||||
qint64 shifted = 0;
|
||||
bool good = false;
|
||||
} result;
|
||||
qint64 jd = msecsToJulianDay(millis), fakeJd;
|
||||
qint64 jd = msecsToJulianDay(millis);
|
||||
auto ymd = QGregorianCalendar::partsFromJulian(jd);
|
||||
result.good = QGregorianCalendar::julianFromParts(systemTimeYearMatching(ymd.year),
|
||||
ymd.month, ymd.day, &fakeJd)
|
||||
&& !daysAndMillisOverflow(fakeJd - jd, millis, &result.shifted);
|
||||
const auto fakeJd = QGregorianCalendar::julianFromParts(systemTimeYearMatching(ymd.year),
|
||||
ymd.month, ymd.day);
|
||||
result.good = fakeJd && !daysAndMillisOverflow(*fakeJd - jd, millis, &result.shifted);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -98,7 +98,10 @@ int QGregorianCalendar::weekDayOfJulian(qint64 jd)
|
||||
|
||||
bool QGregorianCalendar::dateToJulianDay(int year, int month, int day, qint64 *jd) const
|
||||
{
|
||||
return julianFromParts(year, month, day, jd);
|
||||
const auto maybe = julianFromParts(year, month, day);
|
||||
if (maybe)
|
||||
*jd = *maybe;
|
||||
return bool(maybe);
|
||||
}
|
||||
|
||||
QCalendar::YearMonthDay QGregorianCalendar::julianDayToDate(qint64 jd) const
|
||||
@ -175,17 +178,15 @@ constexpr qint64 BaseJd = LeapDayGregorian1Bce;
|
||||
// Every four centures there are 97 leap years:
|
||||
constexpr unsigned FourCenturies = 400 * 365 + 97;
|
||||
|
||||
bool QGregorianCalendar::julianFromParts(int year, int month, int day, qint64 *jd)
|
||||
std::optional<qint64> QGregorianCalendar::julianFromParts(int year, int month, int day)
|
||||
{
|
||||
Q_ASSERT(jd);
|
||||
if (!validParts(year, month, day))
|
||||
return false;
|
||||
return std::nullopt;
|
||||
|
||||
const auto yearDays = yearMonthToYearDays(year, month);
|
||||
const qint64 y = yearDays.year;
|
||||
const qint64 fromYear = 365 * y + qDiv<4>(y) - qDiv<100>(y) + qDiv<400>(y);
|
||||
*jd = fromYear + yearDays.days + day + BaseJd ;
|
||||
return true;
|
||||
return fromYear + yearDays.days + day + BaseJd;
|
||||
}
|
||||
|
||||
QCalendar::YearMonthDay QGregorianCalendar::partsFromJulian(qint64 jd)
|
||||
|
@ -17,6 +17,8 @@
|
||||
|
||||
#include "qromancalendar_p.h"
|
||||
|
||||
#include <optional>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class Q_CORE_EXPORT QGregorianCalendar : public QRomanCalendar
|
||||
@ -45,7 +47,7 @@ public:
|
||||
static int monthLength(int month, int year);
|
||||
static bool validParts(int year, int month, int day);
|
||||
static QCalendar::YearMonthDay partsFromJulian(qint64 jd);
|
||||
static bool julianFromParts(int year, int month, int day, qint64 *jd);
|
||||
static std::optional<qint64> julianFromParts(int year, int month, int day);
|
||||
// Used internally:
|
||||
static int yearStartWeekDay(int year);
|
||||
static int yearSharingWeekDays(QDate date);
|
||||
|
@ -167,10 +167,8 @@ struct tm timeToTm(qint64 localDay, int secs, QDateTimePrivate::DaylightStatus d
|
||||
|
||||
inline std::optional<qint64> tmToJd(const struct tm &date)
|
||||
{
|
||||
qint64 jd;
|
||||
return QGregorianCalendar::julianFromParts(qYearFromTmYear(date.tm_year),
|
||||
date.tm_mon + 1, date.tm_mday, &jd)
|
||||
? std::optional<qint64>(jd) : std::nullopt;
|
||||
date.tm_mon + 1, date.tm_mday);
|
||||
}
|
||||
|
||||
#define IC(N) std::integral_constant<qint64, N>()
|
||||
@ -374,9 +372,7 @@ QDateTimePrivate::ZoneState mapLocalTime(qint64 local, QDateTimePrivate::Dayligh
|
||||
SystemMillisRange computeSystemMillisRange()
|
||||
{
|
||||
// Assert this here, as this is called just once, in a static initialization.
|
||||
[[maybe_unused]] qint64 epochJd;
|
||||
Q_ASSERT(QGregorianCalendar::julianFromParts(1970, 1, 1, &epochJd)
|
||||
&& epochJd == JULIAN_DAY_FOR_EPOCH);
|
||||
Q_ASSERT(QGregorianCalendar::julianFromParts(1970, 1, 1) == JULIAN_DAY_FOR_EPOCH);
|
||||
|
||||
constexpr qint64 TIME_T_MAX = std::numeric_limits<time_t>::max();
|
||||
using Bounds = std::numeric_limits<qint64>;
|
||||
|
@ -368,13 +368,12 @@ void tst_QCalendar::gregory()
|
||||
// dateToJulianDay() and weekDayOfJulian():
|
||||
if (!year) // No year zero.
|
||||
continue;
|
||||
qint64 first, last;
|
||||
QVERIFY2(QGregorianCalendar::julianFromParts(year, 1, 1, &first),
|
||||
"Only year zero should lack a first day");
|
||||
const auto first = QGregorianCalendar::julianFromParts(year, 1, 1);
|
||||
QVERIFY2(first, "Only year zero should lack a first day");
|
||||
QCOMPARE(QGregorianCalendar::yearStartWeekDay(year),
|
||||
QGregorianCalendar::weekDayOfJulian(first));
|
||||
QVERIFY2(QGregorianCalendar::julianFromParts(year, 12, 31, &last),
|
||||
"Only year zero should lack a last day");
|
||||
QGregorianCalendar::weekDayOfJulian(*first));
|
||||
const auto last = QGregorianCalendar::julianFromParts(year, 12, 31);
|
||||
QVERIFY2(last, "Only year zero should lack a last day");
|
||||
|
||||
const int lastTwo = (year + (year < 0 ? 1 : 0)) % 100 + (year < -1 ? 100 : 0);
|
||||
const QDate probe(year, lastTwo && lastTwo <= 12 ? lastTwo : 8,
|
||||
@ -392,13 +391,14 @@ void tst_QCalendar::gregory()
|
||||
if (year > 0 && lastTwo > 31)
|
||||
QCOMPARE(match % 100, lastTwo);
|
||||
// Its first and last days of the year match those of year:
|
||||
qint64 day;
|
||||
QVERIFY(QGregorianCalendar::julianFromParts(match, 1, 1, &day));
|
||||
QCOMPARE(QGregorianCalendar::weekDayOfJulian(day),
|
||||
QGregorianCalendar::weekDayOfJulian(first));
|
||||
QVERIFY(QGregorianCalendar::julianFromParts(match, 12, 31, &day));
|
||||
QCOMPARE(QGregorianCalendar::weekDayOfJulian(day),
|
||||
QGregorianCalendar::weekDayOfJulian(last));
|
||||
auto day = QGregorianCalendar::julianFromParts(match, 1, 1);
|
||||
QVERIFY(day);
|
||||
QCOMPARE(QGregorianCalendar::weekDayOfJulian(*day),
|
||||
QGregorianCalendar::weekDayOfJulian(*first));
|
||||
day = QGregorianCalendar::julianFromParts(match, 12, 31);
|
||||
QVERIFY(day);
|
||||
QCOMPARE(QGregorianCalendar::weekDayOfJulian(*day),
|
||||
QGregorianCalendar::weekDayOfJulian(*last));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user