|
39 | 39 | #include "qgsfontmanager.h"
|
40 | 40 | #include "qgsvariantutils.h"
|
41 | 41 |
|
| 42 | +#include <cmath> |
42 | 43 | #include <QTextCodec>
|
43 | 44 | #include <QUuid>
|
44 | 45 | #include <cpl_error.h>
|
@@ -103,6 +104,29 @@ void gdal::GDALWarpOptionsDeleter::operator()( GDALWarpOptions *options ) const
|
103 | 104 | GDALDestroyWarpOptions( options );
|
104 | 105 | }
|
105 | 106 |
|
| 107 | +static void setQTTimeZoneFromOGRTZFlag( QDateTime &dt, int nTZFlag ) |
| 108 | +{ |
| 109 | + // Take into account time zone |
| 110 | + if ( nTZFlag == 0 ) |
| 111 | + { |
| 112 | + // unknown time zone |
| 113 | + } |
| 114 | + else if ( nTZFlag == 1 ) |
| 115 | + { |
| 116 | + dt.setTimeSpec( Qt::LocalTime ); |
| 117 | + } |
| 118 | + else if ( nTZFlag == 100 ) |
| 119 | + { |
| 120 | + dt.setTimeSpec( Qt::UTC ); |
| 121 | + } |
| 122 | + else |
| 123 | + { |
| 124 | + // TZFlag = 101 ==> UTC+00:15 |
| 125 | + // TZFlag = 99 ==> UTC-00:15 |
| 126 | + dt.setOffsetFromUtc( ( nTZFlag - 100 ) * 15 * 60 ); |
| 127 | + } |
| 128 | +} |
| 129 | + |
106 | 130 | QVariant QgsOgrUtils::OGRFieldtoVariant( const OGRField *value, OGRFieldType type )
|
107 | 131 | {
|
108 | 132 | if ( !value || OGR_RawField_IsUnset( value ) || OGR_RawField_IsNull( value ) )
|
@@ -130,15 +154,17 @@ QVariant QgsOgrUtils::OGRFieldtoVariant( const OGRField *value, OGRFieldType typ
|
130 | 154 | {
|
131 | 155 | float secondsPart = 0;
|
132 | 156 | float millisecondPart = std::modf( value->Date.Second, &secondsPart );
|
133 |
| - return QTime( value->Date.Hour, value->Date.Minute, static_cast< int >( secondsPart ), static_cast< int >( 1000 * millisecondPart ) ); |
| 157 | + return QTime( value->Date.Hour, value->Date.Minute, static_cast< int >( secondsPart ), static_cast< int >( std::round( 1000 * millisecondPart ) ) ); |
134 | 158 | }
|
135 | 159 |
|
136 | 160 | case OFTDateTime:
|
137 | 161 | {
|
138 | 162 | float secondsPart = 0;
|
139 | 163 | float millisecondPart = std::modf( value->Date.Second, &secondsPart );
|
140 |
| - return QDateTime( QDate( value->Date.Year, value->Date.Month, value->Date.Day ), |
141 |
| - QTime( value->Date.Hour, value->Date.Minute, static_cast< int >( secondsPart ), static_cast< int >( 1000 * millisecondPart ) ) ); |
| 164 | + QDateTime dt = QDateTime( QDate( value->Date.Year, value->Date.Month, value->Date.Day ), |
| 165 | + QTime( value->Date.Hour, value->Date.Minute, static_cast< int >( secondsPart ), static_cast< int >( std::round( 1000 * millisecondPart ) ) ) ); |
| 166 | + setQTTimeZoneFromOGRTZFlag( dt, value->Date.TZFlag ); |
| 167 | + return dt; |
142 | 168 | }
|
143 | 169 |
|
144 | 170 | case OFTBinary:
|
@@ -186,6 +212,13 @@ QVariant QgsOgrUtils::OGRFieldtoVariant( const OGRField *value, OGRFieldType typ
|
186 | 212 | return QVariant();
|
187 | 213 | }
|
188 | 214 |
|
| 215 | +int QgsOgrUtils::OGRTZFlagFromQt( const QDateTime &datetime ) |
| 216 | +{ |
| 217 | + if ( datetime.timeSpec() == Qt::LocalTime ) |
| 218 | + return 1; |
| 219 | + return 100 + datetime.offsetFromUtc() / ( 60 * 15 ); |
| 220 | +} |
| 221 | + |
189 | 222 | std::unique_ptr< OGRField > QgsOgrUtils::variantToOGRField( const QVariant &value )
|
190 | 223 | {
|
191 | 224 | std::unique_ptr< OGRField > res = std::make_unique< OGRField >();
|
@@ -225,20 +258,22 @@ std::unique_ptr< OGRField > QgsOgrUtils::variantToOGRField( const QVariant &valu
|
225 | 258 | const QTime time = value.toTime();
|
226 | 259 | res->Date.Hour = time.hour();
|
227 | 260 | res->Date.Minute = time.minute();
|
228 |
| - res->Date.Second = time.second() + static_cast< double >( time.msec() ) / 1000; |
| 261 | + res->Date.Second = static_cast<float>( time.second() + static_cast< double >( time.msec() ) / 1000 ); |
229 | 262 | res->Date.TZFlag = 0;
|
230 | 263 | break;
|
231 | 264 | }
|
232 | 265 | case QVariant::DateTime:
|
233 | 266 | {
|
234 |
| - const QDateTime dateTime = value.toDateTime(); |
235 |
| - res->Date.Day = dateTime.date().day(); |
236 |
| - res->Date.Month = dateTime.date().month(); |
237 |
| - res->Date.Year = dateTime.date().year(); |
238 |
| - res->Date.Hour = dateTime.time().hour(); |
239 |
| - res->Date.Minute = dateTime.time().minute(); |
240 |
| - res->Date.Second = dateTime.time().second() + static_cast< double >( dateTime.time().msec() ) / 1000; |
241 |
| - res->Date.TZFlag = 0; |
| 267 | + const QDateTime dt = value.toDateTime(); |
| 268 | + const QDate date = dt.date(); |
| 269 | + res->Date.Day = date.day(); |
| 270 | + res->Date.Month = date.month(); |
| 271 | + res->Date.Year = static_cast<GInt16>( date.year() ); |
| 272 | + const QTime time = dt.time(); |
| 273 | + res->Date.Hour = time.hour(); |
| 274 | + res->Date.Minute = time.minute(); |
| 275 | + res->Date.Second = static_cast<float>( time.second() + static_cast< double >( time.msec() ) / 1000 ); |
| 276 | + res->Date.TZFlag = OGRTZFlagFromQt( dt ); |
242 | 277 | break;
|
243 | 278 | }
|
244 | 279 |
|
@@ -417,10 +452,14 @@ QVariant QgsOgrUtils::getOgrFeatureAttribute( OGRFeatureH ogrFet, const QgsField
|
417 | 452 | if ( field.type() == QVariant::Date )
|
418 | 453 | value = QDate( year, month, day );
|
419 | 454 | else if ( field.type() == QVariant::Time )
|
420 |
| - value = QTime( hour, minute, static_cast< int >( secondsPart ), static_cast< int >( 1000 * millisecondPart ) ); |
| 455 | + value = QTime( hour, minute, static_cast< int >( secondsPart ), static_cast< int >( std::round( 1000 * millisecondPart ) ) ); |
421 | 456 | else
|
422 |
| - value = QDateTime( QDate( year, month, day ), |
423 |
| - QTime( hour, minute, static_cast< int >( secondsPart ), static_cast< int >( 1000 * millisecondPart ) ) ); |
| 457 | + { |
| 458 | + QDateTime dt = QDateTime( QDate( year, month, day ), |
| 459 | + QTime( hour, minute, static_cast< int >( secondsPart ), static_cast< int >( std::round( 1000 * millisecondPart ) ) ) ); |
| 460 | + setQTTimeZoneFromOGRTZFlag( dt, tzf ); |
| 461 | + value = dt; |
| 462 | + } |
424 | 463 | }
|
425 | 464 | break;
|
426 | 465 |
|
|
0 commit comments