summaryrefslogtreecommitdiffstats
path: root/src/corelib/time/qlocaltime.cpp
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2023-09-26 14:38:16 +0200
committerEdward Welbourne <edward.welbourne@qt.io>2023-09-28 14:51:33 +0200
commit02d8dc5f8c346e7ce0656511c75c3d7c70538536 (patch)
tree96490bddbc78983a9b9113e05403dfbed4ff022c /src/corelib/time/qlocaltime.cpp
parent44cbd4c31520017188257bff14f3f1820d8fdf8c (diff)
Rework getting normalized dates adjacent to a given one
I originally wrote dateNormalize() because I expected to need it more, but it turns out to only be needed for two cases of getting the days before and after a given one. So rename to adjacentDay(), pass the +1 or -1 step and simplify a little. In the process, fix a mistake in the winding backwards across a year boundary, where I'd incremented the year instead of decrementing it. Change-Id: I1bb0a8323fec7c1caffa7f20879f08d3526ba7ea Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/time/qlocaltime.cpp')
-rw-r--r--src/corelib/time/qlocaltime.cpp57
1 files changed, 29 insertions, 28 deletions
diff --git a/src/corelib/time/qlocaltime.cpp b/src/corelib/time/qlocaltime.cpp
index a5cb75ab896..3e134fd1802 100644
--- a/src/corelib/time/qlocaltime.cpp
+++ b/src/corelib/time/qlocaltime.cpp
@@ -195,36 +195,41 @@ struct tm matchYearMonth(struct tm when, const struct tm &base)
}
Q_DECL_COLD_FUNCTION
-struct tm dateNormalize(struct tm when)
+struct tm adjacentDay(struct tm when, int dayStep)
{
- int daysInMonth = 28;
- // We have to wind through months one at a time, since their lengths vary.
- while (when.tm_mday < 1) {
- // Month before's day-count; but tm_mon's value is one less than Qt's
- // month numbering so, before we decrement it, it has the value we need,
- // unless it's 0.
- daysInMonth = when.tm_mon
- ? QGregorianCalendar::monthLength(when.tm_mon, qYearFromTmYear(when.tm_year))
- : QGregorianCalendar::monthLength(12, qYearFromTmYear(when.tm_year - 1));
- when.tm_mday += daysInMonth;
- if (--when.tm_mon < 0) {
- ++when.tm_year;
- when.tm_mon = 11;
+ // Before we adjust it, when is a return from timeToTm(), so in normal form.
+ Q_ASSERT(dayStep * dayStep == 1);
+ when.tm_mday += dayStep;
+ // That may have bumped us across a month boundary or even a year one.
+ // So now we normalize it.
+
+ if (dayStep < 0) {
+ if (when.tm_mday <= 0) {
+ // Month before's day-count; but tm_mon's value is one less than Qt's
+ // month numbering so, before we decrement it, it has the value we need,
+ // unless it's 0.
+ int daysInMonth = when.tm_mon
+ ? QGregorianCalendar::monthLength(when.tm_mon, qYearFromTmYear(when.tm_year))
+ : QGregorianCalendar::monthLength(12, qYearFromTmYear(when.tm_year - 1));
+ when.tm_mday += daysInMonth;
+ if (--when.tm_mon < 0) {
+ --when.tm_year;
+ when.tm_mon = 11;
+ }
+ Q_ASSERT(when.tm_mday >= 1);
}
- }
- // If we came via that loop, we have set daysInMonth and when.tm_mday is <= it.
- // Otherwise, daysInMonth is 28, so this serves as a cheap pre-test:
- if (when.tm_mday > daysInMonth) {
- daysInMonth = QGregorianCalendar::monthLength(
+ } else if (when.tm_mday > 28) {
+ // We have to wind through months one at a time, since their lengths vary.
+ int daysInMonth = QGregorianCalendar::monthLength(
when.tm_mon + 1, qYearFromTmYear(when.tm_year));
- while (when.tm_mday > daysInMonth) {
+ if (when.tm_mday > daysInMonth) {
when.tm_mday -= daysInMonth;
if (++when.tm_mon > 11) {
++when.tm_year;
when.tm_mon = 0;
}
- daysInMonth = QGregorianCalendar::monthLength(
- when.tm_mon + 1, qYearFromTmYear(when.tm_year));
+ Q_ASSERT(when.tm_mday <= QGregorianCalendar::monthLength(
+ when.tm_mon + 1, qYearFromTmYear(when.tm_year)));
}
}
return when;
@@ -278,12 +283,8 @@ MkTimeResult resolveRejected(struct tm base, MkTimeResult result,
constexpr time_t twoDaysInSeconds = 2 * 24 * 60 * 60;
// Bracket base, one day each side (in case the zone skipped a whole day):
- struct tm adjust = base;
- --adjust.tm_mday;
- MkTimeResult early(dateNormalize(adjust));
- adjust = base;
- ++adjust.tm_mday;
- MkTimeResult later(dateNormalize(adjust));
+ MkTimeResult early(adjacentDay(base, -1));
+ MkTimeResult later(adjacentDay(base, +1));
if (!early.good || !later.good) // Assume out of range, rather than gap.
return {};