Skip to content

Commit

Permalink
OGR provider: addFeature/changeAttribueValues: convert local time to …
Browse files Browse the repository at this point in the history
…UTC for GeoPackage

Fixes #57262
  • Loading branch information
rouault committed May 23, 2024
1 parent c629bd2 commit 0e15f97
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 2 deletions.
13 changes: 11 additions & 2 deletions src/core/providers/ogr/qgsogrprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1615,10 +1615,12 @@ bool QgsOgrProvider::addFeaturePrivate( QgsFeature &f, Flags flags, QgsFeatureId
}
case OFTDateTime:
{
const QDateTime dt = attrVal.toDateTime();
QDateTime dt = attrVal.toDateTime();
if ( dt.isValid() )
{
ok = true;
if ( mConvertLocalTimeToUTC && dt.timeSpec() == Qt::LocalTime )
dt = dt.toUTC();
const QDate date = dt.date();
const QTime time = dt.time();
OGR_F_SetFieldDateTimeEx( feature.get(), ogrAttributeId,
Expand Down Expand Up @@ -2577,10 +2579,12 @@ bool QgsOgrProvider::changeAttributeValues( const QgsChangedAttributesMap &attr_
}
case OFTDateTime:
{
const QDateTime dt = it2->toDateTime();
QDateTime dt = it2->toDateTime();
if ( dt.isValid() )
{
ok = true;
if ( mConvertLocalTimeToUTC && dt.timeSpec() == Qt::LocalTime )
dt = dt.toUTC();
const QDate date = dt.date();
const QTime time = dt.time();
OGR_F_SetFieldDateTimeEx( of.get(), f,
Expand Down Expand Up @@ -4013,6 +4017,11 @@ void QgsOgrProvider::open( OpenMode mode )
mGDALDriverName = mOgrOrigLayer->driverName();
mShareSameDatasetAmongLayers = QgsOgrProviderUtils::canDriverShareSameDatasetAmongLayers( mGDALDriverName );

// Should we set it to true unconditionally? as OGR doesn't do any time
// zone conversion for local time. For now, only do that for GeoPackage
// since it requires UTC.
mConvertLocalTimeToUTC = ( mGDALDriverName == QLatin1String( "GPKG" ) );

QgsDebugMsgLevel( "OGR opened using Driver " + mGDALDriverName, 2 );

mOgrLayer = mOgrOrigLayer.get();
Expand Down
3 changes: 3 additions & 0 deletions src/core/providers/ogr/qgsogrprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,9 @@ class QgsOgrProvider final: public QgsVectorDataProvider
void invalidateNetworkCache();

bool mShapefileHadSpatialIndex = false;

//! Whether to convert Qt DateTime with local time to UTC
bool mConvertLocalTimeToUTC = false;
};

///@endcond
Expand Down
28 changes: 28 additions & 0 deletions tests/src/python/test_provider_ogr_gpkg.py
Original file line number Diff line number Diff line change
Expand Up @@ -2715,6 +2715,34 @@ def testDateTimeTimeZoneMilliseconds(self):
got = [feat for feat in vl.getFeatures()]
self.assertEqual(got[0]["dt"], new_dt)

def testWriteDateTimeFromLocalTime(self):

tmpfile = os.path.join(self.basetestpath, 'testWriteDateTimeFromLocalTime.gpkg')
ds = ogr.GetDriverByName('GPKG').CreateDataSource(tmpfile)
lyr = ds.CreateLayer('test', geom_type=ogr.wkbNone)
lyr.CreateField(ogr.FieldDefn('dt', ogr.OFTDateTime))
ds = None

vl = QgsVectorLayer(tmpfile, 'test', 'ogr')

f = QgsFeature(vl.fields())
dt = QDateTime(QDate(2023, 1, 28), QTime(12, 34, 56, 789), Qt.TimeSpec.LocalTime)
f.setAttribute(1, dt)
self.assertTrue(vl.startEditing())
self.assertTrue(vl.addFeatures([f]))
self.assertTrue(vl.commitChanges())

got = [feat for feat in vl.getFeatures()]
self.assertEqual(got[0]["dt"], dt.toUTC())

self.assertTrue(vl.startEditing())
dt = QDateTime(QDate(2024, 1, 1), QTime(12, 34, 56, 789), Qt.TimeSpec.LocalTime)
self.assertTrue(vl.changeAttributeValue(1, 1, dt))
self.assertTrue(vl.commitChanges())

got = [feat for feat in vl.getFeatures()]
self.assertEqual(got[0]["dt"], dt.toUTC())

def testTransactionModeAutoWithFilter(self):

temp_dir = QTemporaryDir()
Expand Down

0 comments on commit 0e15f97

Please sign in to comment.