From 1bf3faa54b15b3eb0a89f251bff1d2d67eeda42e Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Fri, 23 Sep 2022 16:39:22 +0200 Subject: [PATCH] Correct handling of month-lengths in QDateTimeParser MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use calendar's month length upper bound instead of hard-coding 31. When year isn't specified, QCalendar can still tell us a month's "usual" number of days, so use that rather than giving up on getting the day of month within that bound. Still don't try to fix the day of the week when we don't know the year. Change-Id: I90fbe02b180fc4c88b809d2ca71c075ff4dfd473 Reviewed-by: MÃ¥rten Nordheim --- src/corelib/time/qdatetimeparser.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/corelib/time/qdatetimeparser.cpp b/src/corelib/time/qdatetimeparser.cpp index ab784912e55..8daf926c45a 100644 --- a/src/corelib/time/qdatetimeparser.cpp +++ b/src/corelib/time/qdatetimeparser.cpp @@ -1013,16 +1013,21 @@ static QDate actualDate(QDateTimeParser::Sections known, const QCalendar &calend } QDate first(year, month, 1, calendar); - int last = known & QDateTimeParser::YearSection && known & QDateTimeParser::MonthSection - ? first.daysInMonth(calendar) : 0; + int last = known & QDateTimeParser::MonthSection + ? (known & QDateTimeParser::YearSection + ? calendar.daysInMonth(month, year) : calendar.daysInMonth(month)) + : 0; + // We can only fix DOW if we know year as well as month (hence last): + const bool fixDayOfWeek = last && known & QDateTimeParser::YearSection + && known & QDateTimeParser::DayOfWeekSectionMask; // If we also know day-of-week, tweak last to the last in the month that matches it: - if (last && known & QDateTimeParser::DayOfWeekSectionMask) { - int diff = (dayofweek - calendar.dayOfWeek(first) - last) % 7; + if (fixDayOfWeek) { + const int diff = (dayofweek - calendar.dayOfWeek(first) - last) % 7; Q_ASSERT(diff <= 0); // C++11 specifies (-ve) % (+ve) to be <= 0. last += diff; } if (day < 1) { - if (known & QDateTimeParser::DayOfWeekSectionMask && last) { + if (fixDayOfWeek) { day = 1 + dayofweek - calendar.dayOfWeek(first); if (day < 1) day += 7; @@ -1030,7 +1035,7 @@ static QDate actualDate(QDateTimeParser::Sections known, const QCalendar &calend day = 1; } known &= ~QDateTimeParser::DaySection; - } else if (day > 31) { + } else if (day > calendar.maximumDaysInMonth()) { day = last; known &= ~QDateTimeParser::DaySection; } else if (last && day > last && (known & QDateTimeParser::DaySection) == 0) {