Make QDateTimeParser recognize local time offsets
Fixes: QTBUG-84209 Pick-to: 5.15 Change-Id: Iedbc7beafcaa55c72fec3ac5a5f519c6ed5f7770 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
This commit is contained in:
parent
33fc622686
commit
cfbb30decd
@ -1726,29 +1726,26 @@ QDateTimeParser::ParsedSection QDateTimeParser::findUtcOffset(QStringRef str) co
|
||||
QDateTimeParser::ParsedSection
|
||||
QDateTimeParser::findTimeZoneName(QStringRef str, const QDateTime &when) const
|
||||
{
|
||||
int index = startsWithLocalTimeZone(str);
|
||||
if (index > 0) // won't actually use the offset, but need it to be valid
|
||||
return ParsedSection(Acceptable, when.toLocalTime().offsetFromUtc(), index);
|
||||
|
||||
const int systemLength = startsWithLocalTimeZone(str);
|
||||
#if QT_CONFIG(timezone)
|
||||
const int size = str.length();
|
||||
|
||||
// Collect up plausibly-valid characters; let QTimeZone work out what's
|
||||
// truly valid.
|
||||
for (; index < size; ++index) {
|
||||
const QChar here = str[index];
|
||||
if (here >= 127 || (!here.isLetterOrNumber() && !QLatin1String("/-_.+:").contains(here)))
|
||||
break;
|
||||
}
|
||||
const auto invalidZoneNameCharacter = [] (const QChar &c) {
|
||||
return c.unicode() >= 127u
|
||||
|| (!c.isLetterOrNumber() && !QLatin1String("+-./:_").contains(c));
|
||||
};
|
||||
int index = std::distance(str.cbegin(),
|
||||
std::find_if(str.cbegin(), str.cend(), invalidZoneNameCharacter));
|
||||
|
||||
while (index > 0) {
|
||||
for (; index > systemLength; --index) { // Find longest match
|
||||
str.truncate(index);
|
||||
QTimeZone zone(str.toLatin1());
|
||||
if (zone.isValid())
|
||||
return ParsedSection(Acceptable, zone.offsetFromUtc(when), index);
|
||||
index--; // maybe we collected too much ...
|
||||
}
|
||||
#endif
|
||||
if (systemLength > 0) // won't actually use the offset, but need it to be valid
|
||||
return ParsedSection(Acceptable, when.toLocalTime().offsetFromUtc(), systemLength);
|
||||
return ParsedSection();
|
||||
}
|
||||
|
||||
|
@ -119,6 +119,8 @@ private slots:
|
||||
void fromStringDateFormat();
|
||||
void fromStringStringFormat_data();
|
||||
void fromStringStringFormat();
|
||||
void fromStringStringFormat_localTimeZone_data();
|
||||
void fromStringStringFormat_localTimeZone();
|
||||
#if defined(Q_OS_WIN) && QT_CONFIG(textdate)
|
||||
void fromString_LOCALE_ILDATE();
|
||||
#endif
|
||||
@ -2675,6 +2677,7 @@ void tst_QDateTime::fromStringStringFormat()
|
||||
|
||||
QDateTime dt = QDateTime::fromString(string, format);
|
||||
|
||||
QCOMPARE(dt, expected);
|
||||
if (expected.isValid()) {
|
||||
QCOMPARE(dt.timeSpec(), expected.timeSpec());
|
||||
#if QT_CONFIG(timezone)
|
||||
@ -2684,7 +2687,42 @@ void tst_QDateTime::fromStringStringFormat()
|
||||
// OffsetFromUTC needs an offset check - we may as well do it for all:
|
||||
QCOMPARE(dt.offsetFromUtc(), expected.offsetFromUtc());
|
||||
}
|
||||
QCOMPARE(dt, expected);
|
||||
}
|
||||
|
||||
void tst_QDateTime::fromStringStringFormat_localTimeZone_data()
|
||||
{
|
||||
QTest::addColumn<QByteArray>("localTimeZone");
|
||||
QTest::addColumn<QString>("string");
|
||||
QTest::addColumn<QString>("format");
|
||||
QTest::addColumn<QDateTime>("expected");
|
||||
|
||||
#if QT_CONFIG(timezone)
|
||||
QTimeZone etcGmtWithOffset("Etc/GMT+3");
|
||||
if (etcGmtWithOffset.isValid()) {
|
||||
QTest::newRow("local-timezone-with-offset:Etc/GMT+3") << QByteArrayLiteral("GMT")
|
||||
<< QString("2008-10-13 Etc/GMT+3 11.50") << QString("yyyy-MM-dd t hh.mm")
|
||||
<< QDateTime(QDate(2008, 10, 13), QTime(11, 50), etcGmtWithOffset);
|
||||
}
|
||||
QTimeZone gmtWithOffset("GMT-2");
|
||||
if (gmtWithOffset.isValid()) {
|
||||
QTest::newRow("local-timezone-with-offset:GMT-2") << QByteArrayLiteral("GMT")
|
||||
<< QString("2008-10-13 GMT-2 11.50") << QString("yyyy-MM-dd t hh.mm")
|
||||
<< QDateTime(QDate(2008, 10, 13), QTime(11, 50), gmtWithOffset);
|
||||
}
|
||||
QTimeZone gmt("GMT");
|
||||
if (gmt.isValid()) {
|
||||
QTest::newRow("local-timezone-with-offset:GMT") << QByteArrayLiteral("GMT")
|
||||
<< QString("2008-10-13 GMT 11.50") << QString("yyyy-MM-dd t hh.mm")
|
||||
<< QDateTime(QDate(2008, 10, 13), QTime(11, 50), gmt);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void tst_QDateTime::fromStringStringFormat_localTimeZone()
|
||||
{
|
||||
QFETCH(QByteArray, localTimeZone);
|
||||
TimeZoneRollback useZone(localTimeZone); // enforce test's time zone
|
||||
fromStringStringFormat(); // call basic fromStringStringFormat test
|
||||
}
|
||||
|
||||
#if defined(Q_OS_WIN) && QT_CONFIG(textdate)
|
||||
|
Loading…
Reference in New Issue
Block a user