SQL/PostgreSQL: fix parsing timestamptz return values

When setting the timezone explicitly to something different to the
localtime (e.g. UTC), the strings returned for timestamptz columns
contain a '+xx' annotation which resulted in a parser error.

Fixes: QTBUG-129983
Change-Id: I4f5e45860e88a5c44b2f1409dae667984ac90913
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
(cherry picked from commit 00edd47762df96614a38f1362c2131e539e43abd)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Christian Ehrlicher 2024-10-14 18:09:29 +02:00 committed by Qt Cherry-pick Bot
parent 85c3a2f544
commit 8ebf6dcd12

View File

@ -651,10 +651,12 @@ QVariant QPSQLResult::data(int i)
case QMetaType::QTime: case QMetaType::QTime:
return QVariant(QTime::fromString(QString::fromLatin1(val), Qt::ISODate)); return QVariant(QTime::fromString(QString::fromLatin1(val), Qt::ISODate));
case QMetaType::QDateTime: { case QMetaType::QDateTime: {
QString tzString(QString::fromLatin1(val)); const QLatin1StringView tzString(val);
if (!tzString.endsWith(u'Z')) const auto timeString(tzString.sliced(11));
tzString.append(u'Z'); // make UTC if (timeString.contains(u'-') || timeString.contains(u'+') || timeString.endsWith(u'Z'))
return QVariant(QDateTime::fromString(tzString, Qt::ISODate)); return QDateTime::fromString(tzString, Qt::ISODate);
const auto utc = tzString.toString() + u'Z';
return QVariant(QDateTime::fromString(utc, Qt::ISODate));
} }
#else #else
case QMetaType::QDate: case QMetaType::QDate:
@ -1456,8 +1458,7 @@ QString QPSQLDriver::formatValue(const QSqlField &field, bool trimStrings) const
// this is safe since postgresql stores only the UTC value and not the timezone offset (only used // this is safe since postgresql stores only the UTC value and not the timezone offset (only used
// while parsing), so we have correct behavior in both case of with timezone and without tz // while parsing), so we have correct behavior in both case of with timezone and without tz
r = QStringLiteral("TIMESTAMP WITH TIME ZONE ") + u'\'' + r = QStringLiteral("TIMESTAMP WITH TIME ZONE ") + u'\'' +
QLocale::c().toString(dt.toUTC(), u"yyyy-MM-ddThh:mm:ss.zzz") + dt.toOffsetFromUtc(dt.offsetFromUtc()).toString(Qt::ISODateWithMs) + u'\'';
u'Z' + u'\'';
} else { } else {
r = nullStr(); r = nullStr();
} }