summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/tools/qdatetimeparser.cpp29
-rw-r--r--tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp8
2 files changed, 33 insertions, 4 deletions
diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp
index 18c44c3a17..e6afd510fd 100644
--- a/src/corelib/tools/qdatetimeparser.cpp
+++ b/src/corelib/tools/qdatetimeparser.cpp
@@ -1341,12 +1341,33 @@ QDateTimeParser::scanString(const QDateTime &defaultValue,
const QDate date(year, month, day);
const QTime time(hour, minute, second, msec);
- return StateNode(
+ const QDateTime when =
#if QT_CONFIG(timezone)
- tspec == Qt::TimeZone ? QDateTime(date, time, timeZone) :
+ tspec == Qt::TimeZone ? QDateTime(date, time, timeZone) :
#endif
- QDateTime(date, time, tspec, zoneOffset),
- state, padding, conflicts);
+ QDateTime(date, time, tspec, zoneOffset);
+
+ // If hour wasn't specified, check the default we're using exists on the
+ // given date (which might be a spring-forward, skipping an hour).
+ if (parserType == QVariant::DateTime && !(isSet & HourSectionMask) && !when.isValid()) {
+ qint64 msecs = when.toMSecsSinceEpoch();
+ // Fortunately, that gets a useful answer ...
+ const QDateTime replace =
+#if QT_CONFIG(timezone)
+ tspec == Qt::TimeZone
+ ? QDateTime::fromMSecsSinceEpoch(msecs, timeZone) :
+#endif
+ QDateTime::fromMSecsSinceEpoch(msecs, tspec, zoneOffset);
+ const QTime tick = replace.time();
+ if (replace.date() == date
+ && (!(isSet & MinuteSection) || tick.minute() == minute)
+ && (!(isSet & SecondSection) || tick.second() == second)
+ && (!(isSet & MSecSection) || tick.msec() == msec)) {
+ return StateNode(replace, state, padding, conflicts);
+ }
+ }
+
+ return StateNode(when, state, padding, conflicts);
}
/*!
diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
index d460beafde..943805e228 100644
--- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
+++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
@@ -2390,6 +2390,14 @@ void tst_QDateTime::fromStringStringFormat_data()
QTest::newRow("data16") << QString("2005-06-28T07:57:30.001Z")
<< QString("yyyy-MM-ddThh:mm:ss.zt")
<< QDateTime(QDate(2005, 06, 28), QTime(07, 57, 30, 1), Qt::UTC);
+#if QT_CONFIG(timezone)
+ QTimeZone southBrazil("America/Sao_Paulo");
+ if (southBrazil.isValid()) {
+ QTest::newRow("spring-forward-midnight")
+ << QString("2008-10-19 23:45.678 America/Sao_Paulo") << QString("yyyy-MM-dd mm:ss.zzz t")
+ << QDateTime(QDate(2008, 10, 19), QTime(1, 23, 45, 678), southBrazil);
+ }
+#endif
QTest::newRow("late") << QString("9999-12-31T23:59:59.999Z")
<< QString("yyyy-MM-ddThh:mm:ss.zZ")
<< QDateTime(QDate(9999, 12, 31), QTime(23, 59, 59, 999));