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>
This commit is contained in:
parent
44cbd4c315
commit
02d8dc5f8c
@ -195,36 +195,41 @@ struct tm matchYearMonth(struct tm when, const struct tm &base)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Q_DECL_COLD_FUNCTION
|
Q_DECL_COLD_FUNCTION
|
||||||
struct tm dateNormalize(struct tm when)
|
struct tm adjacentDay(struct tm when, int dayStep)
|
||||||
{
|
{
|
||||||
int daysInMonth = 28;
|
// Before we adjust it, when is a return from timeToTm(), so in normal form.
|
||||||
// We have to wind through months one at a time, since their lengths vary.
|
Q_ASSERT(dayStep * dayStep == 1);
|
||||||
while (when.tm_mday < 1) {
|
when.tm_mday += dayStep;
|
||||||
// Month before's day-count; but tm_mon's value is one less than Qt's
|
// That may have bumped us across a month boundary or even a year one.
|
||||||
// month numbering so, before we decrement it, it has the value we need,
|
// So now we normalize it.
|
||||||
// unless it's 0.
|
|
||||||
daysInMonth = when.tm_mon
|
if (dayStep < 0) {
|
||||||
? QGregorianCalendar::monthLength(when.tm_mon, qYearFromTmYear(when.tm_year))
|
if (when.tm_mday <= 0) {
|
||||||
: QGregorianCalendar::monthLength(12, qYearFromTmYear(when.tm_year - 1));
|
// Month before's day-count; but tm_mon's value is one less than Qt's
|
||||||
when.tm_mday += daysInMonth;
|
// month numbering so, before we decrement it, it has the value we need,
|
||||||
if (--when.tm_mon < 0) {
|
// unless it's 0.
|
||||||
++when.tm_year;
|
int daysInMonth = when.tm_mon
|
||||||
when.tm_mon = 11;
|
? 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);
|
||||||
}
|
}
|
||||||
}
|
} else if (when.tm_mday > 28) {
|
||||||
// If we came via that loop, we have set daysInMonth and when.tm_mday is <= it.
|
// We have to wind through months one at a time, since their lengths vary.
|
||||||
// Otherwise, daysInMonth is 28, so this serves as a cheap pre-test:
|
int daysInMonth = QGregorianCalendar::monthLength(
|
||||||
if (when.tm_mday > daysInMonth) {
|
|
||||||
daysInMonth = QGregorianCalendar::monthLength(
|
|
||||||
when.tm_mon + 1, qYearFromTmYear(when.tm_year));
|
when.tm_mon + 1, qYearFromTmYear(when.tm_year));
|
||||||
while (when.tm_mday > daysInMonth) {
|
if (when.tm_mday > daysInMonth) {
|
||||||
when.tm_mday -= daysInMonth;
|
when.tm_mday -= daysInMonth;
|
||||||
if (++when.tm_mon > 11) {
|
if (++when.tm_mon > 11) {
|
||||||
++when.tm_year;
|
++when.tm_year;
|
||||||
when.tm_mon = 0;
|
when.tm_mon = 0;
|
||||||
}
|
}
|
||||||
daysInMonth = QGregorianCalendar::monthLength(
|
Q_ASSERT(when.tm_mday <= QGregorianCalendar::monthLength(
|
||||||
when.tm_mon + 1, qYearFromTmYear(when.tm_year));
|
when.tm_mon + 1, qYearFromTmYear(when.tm_year)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return when;
|
return when;
|
||||||
@ -278,12 +283,8 @@ MkTimeResult resolveRejected(struct tm base, MkTimeResult result,
|
|||||||
|
|
||||||
constexpr time_t twoDaysInSeconds = 2 * 24 * 60 * 60;
|
constexpr time_t twoDaysInSeconds = 2 * 24 * 60 * 60;
|
||||||
// Bracket base, one day each side (in case the zone skipped a whole day):
|
// Bracket base, one day each side (in case the zone skipped a whole day):
|
||||||
struct tm adjust = base;
|
MkTimeResult early(adjacentDay(base, -1));
|
||||||
--adjust.tm_mday;
|
MkTimeResult later(adjacentDay(base, +1));
|
||||||
MkTimeResult early(dateNormalize(adjust));
|
|
||||||
adjust = base;
|
|
||||||
++adjust.tm_mday;
|
|
||||||
MkTimeResult later(dateNormalize(adjust));
|
|
||||||
if (!early.good || !later.good) // Assume out of range, rather than gap.
|
if (!early.good || !later.good) // Assume out of range, rather than gap.
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user