diff options
author | Edward Welbourne <edward.welbourne@qt.io> | 2020-09-30 12:51:18 +0200 |
---|---|---|
committer | Edward Welbourne <edward.welbourne@qt.io> | 2020-10-07 15:57:43 +0200 |
commit | 6404084b9c1eba20421ced02a123bec7b857f012 (patch) | |
tree | 02032d6df6095ba6aa52d941d96edc5cd7f87e07 | |
parent | e1e61daf39903b8b7595465c50a9871dea308f06 (diff) |
Use start of day when wrapping 24:00 to the next day
Previously we used 0:0 on the next day, which might fall in a
fall-back's gap.
[ChangeLog][QtCore][QDateTime] When fromString() reads 24:00 in ISO
format, it now uses the start of the next day, rather than 0:0 on the
next day. This only makes a difference if the next day's first hour is
skipped by a time-zone transition.
Change-Id: Ib81feca5dc09fa735321b6ab76d5d118d6db6fd2
Reviewed-by: Andreas Buhr <andreas.buhr@qt.io>
Reviewed-by: Paul Wicking <paul.wicking@qt.io>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
-rw-r--r-- | src/corelib/global/qnamespace.qdoc | 33 | ||||
-rw-r--r-- | src/corelib/time/qdatetime.cpp | 4 | ||||
-rw-r--r-- | tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp | 5 |
3 files changed, 24 insertions, 18 deletions
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index c81608ab4d..a877b17a4f 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -704,22 +704,23 @@ \note For \c ISODate formats, each \c y, \c M and \c d represents a single digit of the year, month, and day used to specify the date. Each \c H, \c m, and \c s represents a single digit of the hour (up to 24), minute and second - used to specify the time. A \c{.zzz} stands for a fractional part suffix on - the preceding field, which may be separated from that field either by a - comma \c{','} or the dot \c{'.'} shown. Precision beyond milliseconds is - accepted but discarded, rounding to the nearest millisecond or, when - rounding fractional seconds up would change the second field, rounded - down. The presence of a literal \c T character is used to separate the date - and time when both are specified. For the \c TextDate and \c RFC2822Date - formats, \c{ddd} stands for the first three letters of the name of the day - of the week and \c{MMM} stands for the first three letters of the month - name. The names of days and months are always in English (C locale) - regardless of user preferences or system settings. The other format - characters have the same meaning as for the ISODate format. Parts of the - format enclosed in square brackets \c{[...]} are optional; the square - brackets do not form part of the format. The plus-or-minus character \c{'±'} - here stands for either sign character, \c{'-'} for minus or \c{'+'} for - plus. + used to specify the time. An hour of 24, with zero for all other time + fields, is understood as the start of the next day. A \c{.zzz} stands for a + fractional part suffix on the preceding field, which may be separated from + that field either by a comma \c{','} or the dot \c{'.'} shown. Precision + beyond milliseconds is accepted but discarded, rounding to the nearest + millisecond or, when rounding fractional seconds up would change the second + field, rounded down. The presence of a literal \c T character is used to + separate the date and time when both are specified. For the \c TextDate and + \c RFC2822Date formats, \c{ddd} stands for the first three letters of the + name of the day of the week and \c{MMM} stands for the first three letters + of the month name. The names of days and months are always in English (C + locale) regardless of user preferences or system settings. The other format + characters have the same meaning as for the ISODate format, except that 24 + is not accepted as an hour. Parts of a format enclosed in square brackets + \c{[...]} are optional; the square brackets do not form part of the + format. The plus-or-minus character \c{'±'} here stands for either sign + character, \c{'-'} for minus or \c{'+'} for plus. \sa QDate::toString(), QTime::toString(), QDateTime::toString(), QDate::fromString(), QTime::fromString(), QDateTime::fromString() diff --git a/src/corelib/time/qdatetime.cpp b/src/corelib/time/qdatetime.cpp index 3ddad29080..ff4c57b1f8 100644 --- a/src/corelib/time/qdatetime.cpp +++ b/src/corelib/time/qdatetime.cpp @@ -4773,8 +4773,8 @@ QDateTime QDateTime::fromString(QStringView string, Qt::DateFormat format) QTime time = fromIsoTimeString(isoString, format, &isMidnight24); if (!time.isValid()) return QDateTime(); - if (isMidnight24) - date = date.addDays(1); + if (isMidnight24) // time is 0:0, but we want the start of next day: + return date.addDays(1).startOfDay(spec, offset); return QDateTime(date, time, spec, offset); } case Qt::TextDate: { diff --git a/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp index b414458466..18b7a9d74f 100644 --- a/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp @@ -2297,6 +2297,11 @@ void tst_QDateTime::fromStringDateFormat_data() // 24:00:00 Should be next day according to ISO 8601 section 4.2.3. QTest::newRow("ISO 24:00") << QString::fromLatin1("2012-06-04T24:00:00") << Qt::ISODate << QDateTime(QDate(2012, 6, 5), QTime(0, 0), Qt::LocalTime); + QTest::newRow("ISO 24:00 in DST") // Only special if TZ=America/Sao_Paulo + << QString::fromLatin1("2008-10-18T24:00") << Qt::ISODate + << QDateTime(QDate(2008, 10, 19), + QTime(QTimeZone::systemTimeZoneId() == "America/Sao_Paulo" ? 1 : 0, 0), + Qt::LocalTime); QTest::newRow("ISO 24:00 end of month") << QString::fromLatin1("2012-06-30T24:00:00") << Qt::ISODate << QDateTime(QDate(2012, 7, 1), QTime(0, 0), Qt::LocalTime); QTest::newRow("ISO 24:00 end of year") << QString::fromLatin1("2012-12-31T24:00:00") |