summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2023-01-16 18:42:24 +0100
committerEdward Welbourne <edward.welbourne@qt.io>2023-01-31 17:35:13 +0100
commit19c913b43d0cadc0fee3081be4043bd6f083f8f7 (patch)
tree1168246a797f7fdf8fea9a448c565ca6608b3489 /src
parent0e653246b163adb58d0fd955f45aaefc8a506443 (diff)
Deploy QRoundingDown::qDivMod() in date-time calculations
This saves duplicate computations and incidentally now fixes some overflow issues. In the process, simplify some calendrical calculations. Fixes: QTBUG-109845 Change-Id: Iee331803e8281bbf822a001722a6faa3e66f6322 Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/time/qdatetime.cpp6
-rw-r--r--src/corelib/time/qislamiccivilcalendar.cpp10
-rw-r--r--src/corelib/time/qjuliancalendar.cpp14
-rw-r--r--src/corelib/time/qlocaltime.cpp17
-rw-r--r--src/corelib/time/qmilankoviccalendar.cpp30
5 files changed, 36 insertions, 41 deletions
diff --git a/src/corelib/time/qdatetime.cpp b/src/corelib/time/qdatetime.cpp
index 098b47e31a..c8865bf9cd 100644
--- a/src/corelib/time/qdatetime.cpp
+++ b/src/corelib/time/qdatetime.cpp
@@ -3053,12 +3053,12 @@ static QPair<QDate, QTime> getDateTime(const QDateTimeData &d)
{
auto status = getStatus(d);
const qint64 msecs = getMSecs(d);
- const qint64 days = QRoundingDown::qDiv<MSECS_PER_DAY>(msecs);
+ const auto dayMilli = QRoundingDown::qDivMod<MSECS_PER_DAY>(msecs);
return { status.testFlag(QDateTimePrivate::ValidDate)
- ? QDate::fromJulianDay(JULIAN_DAY_FOR_EPOCH + days)
+ ? QDate::fromJulianDay(JULIAN_DAY_FOR_EPOCH + dayMilli.quotient)
: QDate(),
status.testFlag(QDateTimePrivate::ValidTime)
- ? QTime::fromMSecsSinceStartOfDay(msecs - days * MSECS_PER_DAY)
+ ? QTime::fromMSecsSinceStartOfDay(dayMilli.remainder)
: QTime() };
}
diff --git a/src/corelib/time/qislamiccivilcalendar.cpp b/src/corelib/time/qislamiccivilcalendar.cpp
index 96b73dcd43..48bb0064c8 100644
--- a/src/corelib/time/qislamiccivilcalendar.cpp
+++ b/src/corelib/time/qislamiccivilcalendar.cpp
@@ -77,11 +77,11 @@ bool QIslamicCivilCalendar::dateToJulianDay(int year, int month, int day, qint64
QCalendar::YearMonthDay QIslamicCivilCalendar::julianDayToDate(qint64 jd) const
{
constexpr qint64 epoch = 1948440;
- const int32_t k2 = 30 * (jd - epoch) + 15;
- const int32_t k1 = 11 * qDiv<30>(qMod<10631>(k2)) + 5;
- int y = qDiv<10631>(k2) + 1;
- const int month = qDiv<325>(k1) + 1;
- const int day = qDiv<11>(qMod<325>(k1)) + 1;
+ const auto k2dm = qDivMod<10631>(30 * (jd - epoch) + 15);
+ int y = k2dm.quotient + 1;
+ const auto k1dm = qDivMod<325>(11 * qDiv<30>(k2dm.remainder) + 5);
+ const int month = k1dm.quotient + 1;
+ const int day = qDiv<11>(k1dm.remainder) + 1;
return QCalendar::YearMonthDay(y > 0 ? y : y - 1, month, day);
}
diff --git a/src/corelib/time/qjuliancalendar.cpp b/src/corelib/time/qjuliancalendar.cpp
index e1ea27b3d5..1c63d4e170 100644
--- a/src/corelib/time/qjuliancalendar.cpp
+++ b/src/corelib/time/qjuliancalendar.cpp
@@ -75,14 +75,12 @@ bool QJulianCalendar::dateToJulianDay(int year, int month, int day, qint64 *jd)
QCalendar::YearMonthDay QJulianCalendar::julianDayToDate(qint64 jd) const
{
- const qint64 y2 = jd - 1721118;
- const qint64 k2 = 4 * y2 + 3;
- const qint64 k1 = 5 * qDiv<4>(qMod<1461>(k2)) + 2;
- const qint64 x1 = qDiv<153>(k1);
- const qint64 c0 = qDiv<12>(x1 + 2);
- const int y = qint16(qDiv<1461>(k2) + c0);
- const int month = quint8(x1 - 12 * c0 + 3);
- const int day = qDiv<5>(qMod<153>(k1)) + 1;
+ const auto k2dm = qDivMod<1461>(4 * (jd - 1721118) + 3);
+ const auto k1dm = qDivMod<153>(5 * qDiv<4>(k2dm.remainder) + 2);
+ const auto c0dm = qDivMod<12>(k1dm.quotient + 2);
+ const int y = qint16(k2dm.quotient + c0dm.quotient);
+ const int month = quint8(c0dm.remainder + 1);
+ const int day = qDiv<5>(k1dm.remainder) + 1;
return QCalendar::YearMonthDay(y > 0 ? y : y - 1, month, day);
}
diff --git a/src/corelib/time/qlocaltime.cpp b/src/corelib/time/qlocaltime.cpp
index 9056695967..3ff603d8dd 100644
--- a/src/corelib/time/qlocaltime.cpp
+++ b/src/corelib/time/qlocaltime.cpp
@@ -312,8 +312,9 @@ inline bool secondsAndMillisOverflow(qint64 epochSeconds, qint64 millis, qint64
// returns the local milliseconds, offset from UTC and DST status.
QDateTimePrivate::ZoneState utcToLocal(qint64 utcMillis)
{
- const time_t epochSeconds = QRoundingDown::qDiv<MSECS_PER_SEC>(utcMillis);
- const int msec = utcMillis - epochSeconds * MSECS_PER_SEC;
+ const auto epoch = QRoundingDown::qDivMod<MSECS_PER_SEC>(utcMillis);
+ const time_t epochSeconds = epoch.quotient;
+ const int msec = epoch.remainder;
Q_ASSERT(msec >= 0 && msec < MSECS_PER_SEC);
if (qint64(epochSeconds) * MSECS_PER_SEC + msec != utcMillis) // time_t range too narrow
return {utcMillis};
@@ -341,10 +342,10 @@ QDateTimePrivate::ZoneState utcToLocal(qint64 utcMillis)
QString localTimeAbbbreviationAt(qint64 local, QDateTimePrivate::DaylightStatus dst)
{
- const qint64 localDays = QRoundingDown::qDiv<MSECS_PER_DAY>(local);
- qint64 millis = local - localDays * MSECS_PER_DAY;
+ const auto localDayMilli = QRoundingDown::qDivMod<MSECS_PER_DAY>(local);
+ qint64 millis = localDayMilli.remainder;
Q_ASSERT(0 <= millis && millis < MSECS_PER_DAY); // Definition of QRD::qDiv.
- struct tm tmLocal = timeToTm(localDays, int(millis / MSECS_PER_SEC), dst);
+ struct tm tmLocal = timeToTm(localDayMilli.quotient, int(millis / MSECS_PER_SEC), dst);
time_t utcSecs;
if (!callMkTime(&tmLocal, &utcSecs))
return {};
@@ -356,11 +357,11 @@ QDateTimePrivate::ZoneState mapLocalTime(qint64 local, QDateTimePrivate::Dayligh
{
qint64 localSecs = local / MSECS_PER_SEC;
qint64 millis = local - localSecs * MSECS_PER_SEC; // 0 or with same sign as local
- const qint64 localDays = QRoundingDown::qDiv<SECS_PER_DAY>(localSecs);
- qint64 daySecs = localSecs - localDays * SECS_PER_DAY;
+ const auto localDaySec = QRoundingDown::qDivMod<SECS_PER_DAY>(localSecs);
+ qint64 daySecs = localDaySec.remainder;
Q_ASSERT(0 <= daySecs && daySecs < SECS_PER_DAY); // Definition of QRD::qDiv.
- struct tm tmLocal = timeToTm(localDays, daySecs, dst);
+ struct tm tmLocal = timeToTm(localDaySec.quotient, daySecs, dst);
time_t utcSecs;
if (!callMkTime(&tmLocal, &utcSecs))
return {local};
diff --git a/src/corelib/time/qmilankoviccalendar.cpp b/src/corelib/time/qmilankoviccalendar.cpp
index 428b0169d4..3d848fb372 100644
--- a/src/corelib/time/qmilankoviccalendar.cpp
+++ b/src/corelib/time/qmilankoviccalendar.cpp
@@ -55,8 +55,9 @@ bool QMilankovicCalendar::isLeapYear(int year) const
++year;
if (qMod<4>(year))
return false;
- if (qMod<100>(year) == 0) {
- const qint16 century = qMod<9>(qDiv<100>(year));
+ const auto yeardm = qDivMod<100>(year);
+ if (yeardm.remainder == 0) {
+ const qint16 century = qMod<9>(yeardm.quotient);
if (century != 2 && century != 6)
return false;
}
@@ -72,11 +73,9 @@ bool QMilankovicCalendar::dateToJulianDay(int year, int month, int day, qint64 *
++year;
const qint16 c0 = month < 3 ? -1 : 0;
const qint16 x1 = month - 12 * c0 - 3;
- const qint16 x4 = year + c0;
- const qint16 x3 = qDiv<100>(x4);
- const qint16 x2 = qMod<100>(x4);
- *jd = qDiv<9>(328718 * x3 + 6)
- + qDiv<100>(36525 * x2)
+ const auto x4dm = qDivMod<100>(year + c0);
+ *jd = qDiv<9>(328718 * x4dm.quotient + 6)
+ + qDiv<100>(36525 * x4dm.remainder)
+ qDiv<5>(153 * x1 + 2)
+ day + 1721119;
return true;
@@ -84,16 +83,13 @@ bool QMilankovicCalendar::dateToJulianDay(int year, int month, int day, qint64 *
QCalendar::YearMonthDay QMilankovicCalendar::julianDayToDate(qint64 jd) const
{
- const qint64 k3 = 9 * (jd - 1721120) + 2;
- const qint64 x3 = qDiv<328718>(k3);
- const qint64 k2 = 100 * qDiv<9>(qMod<328718>(k3)) + 99;
- const qint64 k1 = qDiv<100>(qMod<36525>(k2)) * 5 + 2;
- const qint64 x2 = qDiv<36525>(k2);
- const qint64 x1 = qDiv<153>(5 * qDiv<100>(qMod<36525>(k2)) + 2);
- const qint64 c0 = qDiv<12>(x1 + 2);
- const int y = 100 * x3 + x2 + c0;
- const int month = x1 - 12 * c0 + 3;
- const int day = qDiv<5>(qMod<153>(k1)) + 1;
+ const auto k3dm = qDivMod<328718>(9 * (jd - 1721120) + 2);
+ const auto k2dm = qDivMod<36525>(100 * qDiv<9>(k3dm.remainder) + 99);
+ const auto k1dm = qDivMod<153>(qDiv<100>(k2dm.remainder) * 5 + 2);
+ const auto c0dm = qDivMod<12>(k1dm.quotient + 2);
+ const int y = 100 * k3dm.quotient + k2dm.quotient + c0dm.quotient;
+ const int month = c0dm.remainder + 1;
+ const int day = qDiv<5>(k1dm.remainder) + 1;
return QCalendar::YearMonthDay(y > 0 ? y : y - 1, month, day);
}