summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/tools/qdatetime.cpp33
-rw-r--r--tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp76
2 files changed, 103 insertions, 6 deletions
diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp
index 293838e9a5..3324408fde 100644
--- a/src/corelib/tools/qdatetime.cpp
+++ b/src/corelib/tools/qdatetime.cpp
@@ -3666,9 +3666,19 @@ QDataStream &operator>>(QDataStream &in, QTime &time)
*/
QDataStream &operator<<(QDataStream &out, const QDateTime &dateTime)
{
- out << dateTime.d->date << dateTime.d->time;
- if (out.version() >= 7)
- out << (qint8)dateTime.d->spec;
+ if (out.version() >= 13) {
+ if (dateTime.isValid()) {
+ QDateTime asUTC = dateTime.toUTC();
+ out << asUTC.d->date << asUTC.d->time;
+ } else {
+ out << dateTime.d->date << dateTime.d->time;
+ }
+ out << (qint8)dateTime.timeSpec();
+ } else {
+ out << dateTime.d->date << dateTime.d->time;
+ if (out.version() >= 7)
+ out << (qint8)dateTime.d->spec;
+ }
return out;
}
@@ -3684,11 +3694,22 @@ QDataStream &operator>>(QDataStream &in, QDateTime &dateTime)
{
dateTime.detach();
- qint8 ts = (qint8)QDateTimePrivate::LocalUnknown;
in >> dateTime.d->date >> dateTime.d->time;
- if (in.version() >= 7)
+
+ if (in.version() >= 13) {
+ qint8 ts = 0;
in >> ts;
- dateTime.d->spec = (QDateTimePrivate::Spec)ts;
+ if (dateTime.isValid()) {
+ // We always store the datetime as UTC in 13 onwards.
+ dateTime.d->spec = QDateTimePrivate::UTC;
+ dateTime = dateTime.toTimeSpec(static_cast<Qt::TimeSpec>(ts));
+ }
+ } else {
+ qint8 ts = (qint8)QDateTimePrivate::LocalUnknown;
+ if (in.version() >= 7)
+ in >> ts;
+ dateTime.d->spec = (QDateTimePrivate::Spec)ts;
+ }
return in;
}
#endif // QT_NO_DATASTREAM
diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
index 6327e73ba5..70b761f705 100644
--- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
+++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
@@ -106,6 +106,8 @@ private slots:
void msecsTo();
void operator_eqeq_data();
void operator_eqeq();
+ void operator_insert_extract_data();
+ void operator_insert_extract();
void currentDateTime();
void currentDateTimeUtc();
void currentDateTimeUtc2();
@@ -1221,6 +1223,80 @@ void tst_QDateTime::operator_eqeq()
}
}
+void tst_QDateTime::operator_insert_extract_data()
+{
+ QTest::addColumn<QDateTime>("dateTime");
+ QTest::addColumn<QString>("serialiseAs");
+ QTest::addColumn<QString>("deserialiseAs");
+
+ const QDateTime positiveYear(QDateTime(QDate(2012, 8, 14), QTime(8, 0, 0), Qt::LocalTime));
+ const QDateTime negativeYear(QDateTime(QDate(-2012, 8, 14), QTime(8, 0, 0), Qt::LocalTime));
+
+ const QString westernAustralia(QString::fromLatin1("AWST-8AWDT-9,M10.5.0,M3.5.0/03:00:00"));
+ const QString hawaii(QString::fromLatin1("HAW10"));
+
+ QTest::newRow("14/08/2012 08:00 WA => HAWAII") << positiveYear << westernAustralia << hawaii;
+ QTest::newRow("14/08/2012 08:00 WA => HAWAII") << positiveYear << westernAustralia << hawaii;
+ QTest::newRow("14/08/2012 08:00 WA => HAWAII") << positiveYear << westernAustralia << hawaii;
+ QTest::newRow("14/08/2012 08:00 WA => WA") << positiveYear << westernAustralia << westernAustralia;
+ QTest::newRow("14/08/-2012 08:00 HAWAII => WA") << negativeYear << hawaii << westernAustralia;
+ QTest::newRow("14/08/-2012 08:00 HAWAII => WA") << negativeYear << hawaii << westernAustralia;
+ QTest::newRow("14/08/-2012 08:00 HAWAII => WA") << negativeYear << hawaii << westernAustralia;
+ QTest::newRow("14/08/2012 08:00 HAWAII => HAWAII") << positiveYear << hawaii << hawaii;
+}
+
+void tst_QDateTime::operator_insert_extract()
+{
+ QFETCH(QDateTime, dateTime);
+ QFETCH(QString, serialiseAs);
+ QFETCH(QString, deserialiseAs);
+
+ QString previousTimeZone = qgetenv("TZ");
+ qputenv("TZ", serialiseAs.toLocal8Bit().constData());
+ tzset();
+ QDateTime dateTimeAsUTC(dateTime.toUTC());
+
+ QByteArray byteArray;
+ {
+ QDataStream dataStream(&byteArray, QIODevice::WriteOnly);
+ dataStream << dateTime;
+ dataStream << dateTime;
+ }
+
+ // Ensure that a change in timezone between serialisation and deserialisation
+ // still results in identical UTC-converted datetimes.
+ qputenv("TZ", deserialiseAs.toLocal8Bit().constData());
+ tzset();
+ QDateTime expectedLocalTime(dateTimeAsUTC.toLocalTime());
+ {
+ // Deserialise whole QDateTime at once.
+ QDataStream dataStream(&byteArray, QIODevice::ReadOnly);
+ QDateTime deserialised;
+ dataStream >> deserialised;
+ // Ensure local time is still correct.
+ QCOMPARE(deserialised, expectedLocalTime);
+ // Sanity check UTC times.
+ QCOMPARE(deserialised.toUTC(), expectedLocalTime.toUTC());
+
+ // Deserialise each component individually.
+ QDate deserialisedDate;
+ dataStream >> deserialisedDate;
+ QTime deserialisedTime;
+ dataStream >> deserialisedTime;
+ qint8 deserialisedSpec;
+ dataStream >> deserialisedSpec;
+ deserialised = QDateTime(deserialisedDate, deserialisedTime, Qt::UTC);
+ deserialised = deserialised.toTimeSpec(static_cast<Qt::TimeSpec>(deserialisedSpec));
+ // Ensure local time is still correct.
+ QCOMPARE(deserialised, expectedLocalTime);
+ // Sanity check UTC times.
+ QCOMPARE(deserialised.toUTC(), expectedLocalTime.toUTC());
+ }
+
+ qputenv("TZ", previousTimeZone.toLocal8Bit().constData());
+ tzset();
+}
+
void tst_QDateTime::toString_strformat_data()
{
QTest::addColumn<QDateTime>("dt");