summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2020-11-25 12:18:49 +0100
committerEdward Welbourne <edward.welbourne@qt.io>2020-11-27 13:26:53 +0100
commit3a4115d1236bc78dda078657883283cc92df8e8a (patch)
tree8585f482de896841470dbb96c5ba506f0880c755 /src
parentcdcfb7c4f905fd75887d9f7aa5646dd91edde3ab (diff)
Return a more useful date-time on parser failure in spring-forward gap
Up to 5.15.0, QDateTime::fromString(), when parsing a string that matched the format but represented a date-time in a spring-forward's gap, would return an invalid date-time object that represented a "best shot" date-time, correcting the error in the string as best it could. In 5.15, in order to handle time-spec information correctly, we adapted the date-time parser to have a fromString() variant that parsed a date-time as a whole, rather than as a date and a time; as a result, QDTP::fromString() now returns false and QDT::fromString() returned a default-constructed instance instead of the invalid date-time that QDTP had produced. Amend 76054516047d8efb8529443830bb4d9ddf01010f to restore the prior behavior of returning the invalid date-time object from QDTP instead of a default-constructed invalid date-time. Also document what this implies for the caller's ability to recover from the situation, if a best shot result is better than nothing. [ChangeLog][QtCore][QDateTime] Restored pre-5.15.0 behavior when parsing a date-time from a string (and document what it implies): if the string has the right form but represents a date-time that was skipped by a time-zone transition (e.g. a DST spring-forward), the invalid date-time object returned can, none the less, be used to recover a near-by date-time that may be more useful in some cases. From 5.15.0 to 5.15.2 and in 6.0.0, a default-constructed QDateTime was returned in place of this more informative invalid date-time. Task-number: QTBUG-88633 Pick-to: 6.0 5.15 Change-Id: If0b439038d5fe48eefb951c62f3aae2933bb5651 Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/text/qlocale.cpp9
-rw-r--r--src/corelib/time/qdatetime.cpp10
2 files changed, 15 insertions, 4 deletions
diff --git a/src/corelib/text/qlocale.cpp b/src/corelib/text/qlocale.cpp
index 3ce1f501c4..02f020b032 100644
--- a/src/corelib/text/qlocale.cpp
+++ b/src/corelib/text/qlocale.cpp
@@ -2282,7 +2282,12 @@ QDate QLocale::toDate(const QString &string, const QString &format, QCalendar ca
\note The month and day names used must be given in the user's local
language.
- If the string could not be parsed, returns an invalid QDateTime.
+ If the string could not be parsed, returns an invalid QDateTime. If the
+ string can be parsed and represents an invalid date-time (e.g. in a gap
+ skipped by a time-zone transition), an invalid QDateTime is returned, whose
+ toMSecsSinceEpoch() represents a near-by date-time that is valid. Passing
+ that to fromMSecsSinceEpoch() will produce a valid date-time that isn't
+ faithfully represented by the string parsed.
\sa dateTimeFormat(), toTime(), toDate(), QDateTime::fromString()
*/
@@ -2302,7 +2307,7 @@ QDateTime QLocale::toDateTime(const QString &string, const QString &format, QCal
QDateTimeParser dt(QMetaType::QDateTime, QDateTimeParser::FromString, cal);
dt.setDefaultLocale(*this);
- if (dt.parseFormat(format) && dt.fromString(string, &datetime))
+ if (dt.parseFormat(format) && (dt.fromString(string, &datetime) || !datetime.isValid()))
return datetime;
#else
Q_UNUSED(string);
diff --git a/src/corelib/time/qdatetime.cpp b/src/corelib/time/qdatetime.cpp
index 342ff5ccde..757636ede2 100644
--- a/src/corelib/time/qdatetime.cpp
+++ b/src/corelib/time/qdatetime.cpp
@@ -4977,7 +4977,13 @@ QDateTime QDateTime::fromString(QStringView string, Qt::DateFormat format)
\snippet code/src_corelib_time_qdatetime.cpp 12
- If the format is not satisfied, an invalid QDateTime is returned.
+ If the format is not satisfied, an invalid QDateTime is returned. If the
+ format is satisfied but \a string represents an invalid date-time (e.g. in a
+ gap skipped by a time-zone transition), an invalid QDateTime is returned,
+ whose toMSecsSinceEpoch() represents a near-by date-time that is
+ valid. Passing that to fromMSecsSinceEpoch() will produce a valid date-time
+ that isn't faithfully represented by the string parsed.
+
The expressions that don't have leading zeroes (d, M, h, m, s, z) will be
greedy. This means that they will use two digits (or three, for z) even if this will
put them outside the range and/or leave too few digits for other
@@ -5025,7 +5031,7 @@ QDateTime QDateTime::fromString(const QString &string, QStringView format, QCale
QDateTimeParser dt(QMetaType::QDateTime, QDateTimeParser::FromString, cal);
dt.setDefaultLocale(QLocale::c());
- if (dt.parseFormat(format) && dt.fromString(string, &datetime))
+ if (dt.parseFormat(format) && (dt.fromString(string, &datetime) || !datetime.isValid()))
return datetime;
#else
Q_UNUSED(string);