SQL/Firebird: Fix interpretation of time stamp with timezone
The firebird api expects the timestamp (ISC_TIMESTAMP_TZ) of a timestamp with time zone is provided in UTC. Pick-to: 6.7 Task-number: QTBUG-128493 Change-Id: Iacc85ca1141407f5ab73fd0198c7b2db770bf589 Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de> Reviewed-by: Johann Anhofer <johann.anhofer@meon-medical.com> (cherry picked from commit 8d8805214df22bf8dccbb30c9ca4a9953f3a1068) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
ae4a48decc
commit
b0d73b947f
@ -263,16 +263,20 @@ static inline QDateTime fromTimeStampTz(const char *buffer)
|
||||
|
||||
QByteArray timeZoneName = qFbTzIdToIanaIdMap()->value(fpTzID);
|
||||
if (!timeZoneName.isEmpty())
|
||||
return QDateTime(d, t, QTimeZone(timeZoneName));
|
||||
{
|
||||
const auto utc = QDateTime(d, t, QTimeZone(QTimeZone::UTC));
|
||||
return utc.toTimeZone(QTimeZone(timeZoneName));
|
||||
}
|
||||
else
|
||||
return {};
|
||||
}
|
||||
|
||||
static inline ISC_TIMESTAMP_TZ toTimeStampTz(const QDateTime &dt)
|
||||
{
|
||||
const auto dtUtc = dt.toUTC();
|
||||
ISC_TIMESTAMP_TZ ts;
|
||||
ts.utc_timestamp.timestamp_time = dt.time().msecsSinceStartOfDay() * 10;
|
||||
ts.utc_timestamp.timestamp_date = s_ibaseBaseDate.daysTo(dt.date());
|
||||
ts.utc_timestamp.timestamp_time = dtUtc.time().msecsSinceStartOfDay() * 10;
|
||||
ts.utc_timestamp.timestamp_date = s_ibaseBaseDate.daysTo(dtUtc.date());
|
||||
ts.time_zone = qIanaIdToFbTzIdMap()->value(dt.timeZone().id().simplified(), 0);
|
||||
return ts;
|
||||
}
|
||||
|
@ -259,6 +259,9 @@ private slots:
|
||||
void ibaseInt128_data() { generic_data("QIBASE"); }
|
||||
void ibaseInt128();
|
||||
|
||||
void QTBUG_128493_data() { generic_data("QIBASE"); }
|
||||
void QTBUG_128493();
|
||||
|
||||
|
||||
void psqlJsonOperator_data() { generic_data("QPSQL"); }
|
||||
void psqlJsonOperator();
|
||||
@ -4868,6 +4871,56 @@ void tst_QSqlQuery::ibaseDateTimeWithTZ()
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QSqlQuery::QTBUG_128493()
|
||||
{
|
||||
QFETCH(QString, dbName);
|
||||
QSqlDatabase db = QSqlDatabase::database(dbName);
|
||||
CHECK_DATABASE(db);
|
||||
if (tst_Databases::getDatabaseType(db) != QSqlDriver::Interbase)
|
||||
QSKIP("Implemented only for Interbase");
|
||||
|
||||
if (tst_Databases::getIbaseEngineVersion(db).majorVersion() < 4)
|
||||
QSKIP("Time zone support only implemented for firebird engine version 4 and greater");
|
||||
|
||||
|
||||
QSqlQuery q{db};
|
||||
|
||||
#if QT_CONFIG(timezone)
|
||||
const auto currentDateTime = QDateTime::currentDateTime().toTimeZone(QTimeZone("Europe/Vienna"_ba));
|
||||
//Set session time zone
|
||||
QVERIFY_SQL(q, exec(u"set time zone 'Europe/Vienna'"_s));
|
||||
#else
|
||||
const auto currentDateTime = QDateTime::currentDateTime();
|
||||
#endif // QT_CONFIG(timezone)
|
||||
|
||||
QVERIFY_SQL(q, exec(u"select current_timestamp from rdb$database"_s));
|
||||
QVERIFY_SQL(q, isActive());
|
||||
QVERIFY_SQL(q, next());
|
||||
const auto currentDateTimeDB = q.value(0).toDateTime();
|
||||
|
||||
QCOMPARE(currentDateTime.date(), currentDateTimeDB.date());
|
||||
QCOMPARE(currentDateTime.offsetFromUtc(), currentDateTimeDB.offsetFromUtc());
|
||||
QCOMPARE(currentDateTime.isDaylightTime(), currentDateTimeDB.isDaylightTime());
|
||||
|
||||
QCOMPARE(currentDateTime.time().hour(), currentDateTimeDB.time().hour());
|
||||
|
||||
const QString tableName(qTableName(u"dateTimeTS"_s, __FILE__, db));
|
||||
QVERIFY_SQL(q, exec(u"CREATE TABLE "_s + tableName + u"(dt timestamp with time zone)"_s));
|
||||
|
||||
QVERIFY_SQL(q, prepare(u"INSERT INTO %1 values(:dt)"_s.arg(tableName)));
|
||||
q.bindValue(":dt", currentDateTime );
|
||||
QVERIFY_SQL(q, exec());
|
||||
|
||||
QVERIFY_SQL(q, exec(u"SELECT cast(dt AS VARCHAR(50)) FROM "_s + tableName));
|
||||
QVERIFY_SQL(q, next());
|
||||
|
||||
const auto currentDateTimeFromDBString = q.value(0).toString();
|
||||
auto currentDateTimeFromDB = QDateTime::fromString(currentDateTimeFromDBString,
|
||||
u"yyyy-MM-dd hh:mm:ss.zzz0 tttt"_s);
|
||||
|
||||
QCOMPARE(currentDateTimeFromDB, currentDateTime);
|
||||
}
|
||||
|
||||
void tst_QSqlQuery::sqliteVirtualTable()
|
||||
{
|
||||
// Virtual tables can behave differently when it comes to prepared
|
||||
|
Loading…
x
Reference in New Issue
Block a user