Revert QDateTime serialisation to pre-Qt 5 behaviour.
In Qt 5, I managed to break the guarantee that a deserialised local datetime is the same time of day (potentially different UTC time), regardless of which timezone it was serialised in. This happened after I fixed QTBUG-4057 with If650e7960dca7b6ab44b8233410a6369c41df73a, which serialised datetimes as UTC. This patch reverts QDateTime serialisation to pre-Qt 5 behaviour to restore the guarantee and consequently re-opens QTBUG-4057. Change-Id: Iea877f7ed886f530b928067789b53534e89fe8cb Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>bb10
parent
7e7d40eeb7
commit
83315ce8b2
|
|
@ -41,6 +41,14 @@ Third party components
|
|||
* [QTBUG-8836] QAbstractItemView now allows manual deselect in
|
||||
SingleSelection mode (with control modifier)
|
||||
|
||||
- QtCore
|
||||
|
||||
* The serialization behavior for QDateTime has reverted to pre-Qt 5,
|
||||
due to the issue mentioned in section 4 here:
|
||||
http://lists.qt-project.org/pipermail/development/2013-March/010559.html
|
||||
|
||||
This means that the QDataStream version will be 14 with Qt 5.1.
|
||||
|
||||
****************************************************************************
|
||||
* Library *
|
||||
****************************************************************************
|
||||
|
|
|
|||
|
|
@ -539,7 +539,7 @@ void QDataStream::setByteOrder(ByteOrder bo)
|
|||
\value Qt_4_8 Same as Qt_4_6.
|
||||
\value Qt_4_9 Same as Qt_4_6.
|
||||
\value Qt_5_0 Version 13 (Qt 5.0)
|
||||
\value Qt_5_1 Same as Qt_5_0.
|
||||
\value Qt_5_1 Version 14 (Qt 5.1)
|
||||
|
||||
\sa setVersion(), version()
|
||||
*/
|
||||
|
|
@ -571,6 +571,7 @@ void QDataStream::setByteOrder(ByteOrder bo)
|
|||
|
||||
\table
|
||||
\header \li Qt Version \li QDataStream Version
|
||||
\row \li Qt 5.1 \li 14
|
||||
\row \li Qt 5.0 \li 13
|
||||
\row \li Qt 4.6 \li 12
|
||||
\row \li Qt 4.5 \li 11
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ public:
|
|||
Qt_4_8 = Qt_4_7,
|
||||
Qt_4_9 = Qt_4_8,
|
||||
Qt_5_0 = 13,
|
||||
Qt_5_1 = Qt_5_0
|
||||
Qt_5_1 = 14
|
||||
#if QT_VERSION >= 0x050200
|
||||
#error Add the datastream version for this Qt version
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -3691,8 +3691,11 @@ QDataStream &operator>>(QDataStream &in, QTime &time)
|
|||
*/
|
||||
QDataStream &operator<<(QDataStream &out, const QDateTime &dateTime)
|
||||
{
|
||||
if (out.version() >= 13) {
|
||||
if (out.version() == 13) {
|
||||
if (dateTime.isValid()) {
|
||||
// This approach is wrong and should not be used again; it breaks
|
||||
// the guarantee that a deserialised local datetime is the same time
|
||||
// of day, regardless of which timezone it was serialised in.
|
||||
QDateTime asUTC = dateTime.toUTC();
|
||||
out << asUTC.d->date << asUTC.d->time;
|
||||
} else {
|
||||
|
|
@ -3721,7 +3724,7 @@ QDataStream &operator>>(QDataStream &in, QDateTime &dateTime)
|
|||
|
||||
in >> dateTime.d->date >> dateTime.d->time;
|
||||
|
||||
if (in.version() >= 13) {
|
||||
if (in.version() == 13) {
|
||||
qint8 ts = 0;
|
||||
in >> ts;
|
||||
if (dateTime.isValid()) {
|
||||
|
|
|
|||
|
|
@ -268,7 +268,8 @@ static int NColorRoles[] = {
|
|||
QPalette::ToolTipText + 1, // Qt_4_5
|
||||
QPalette::ToolTipText + 1, // Qt_4_6
|
||||
QPalette::ToolTipText + 1, // Qt_5_0
|
||||
0 // add the correct value for Qt_5_1 here later
|
||||
QPalette::ToolTipText + 1, // Qt_5_1
|
||||
0 // add the correct value for Qt_5_2 here later
|
||||
};
|
||||
|
||||
// Testing get/set functions
|
||||
|
|
|
|||
|
|
@ -1398,13 +1398,19 @@ void tst_QDateTime::operator_insert_extract()
|
|||
{
|
||||
QDataStream dataStream(&byteArray, QIODevice::WriteOnly);
|
||||
dataStream.setVersion(dataStreamVersion);
|
||||
if (dataStreamVersion >= QDataStream::Qt_5_0) {
|
||||
if (dataStreamVersion == QDataStream::Qt_5_0) {
|
||||
// Qt 5 serialises as UTC and converts back to the stored timeSpec when
|
||||
// deserialising; we don't need to do it ourselves...
|
||||
dataStream << dateTime << dateTime;
|
||||
} else {
|
||||
// ... but lower versions don't, so we have to here.
|
||||
// ... but other versions don't, so we have to here.
|
||||
dataStream << dateTimeAsUTC << dateTimeAsUTC;
|
||||
// We'll also make sure that a deserialised local datetime is the same
|
||||
// time of day (potentially different UTC time), regardless of which
|
||||
// timezone it was serialised in. E.g.: Tue Aug 14 08:00:00 2012
|
||||
// serialised in WST should be deserialised as Tue Aug 14 08:00:00 2012
|
||||
// HST.
|
||||
dataStream << dateTime;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1420,7 +1426,7 @@ void tst_QDateTime::operator_insert_extract()
|
|||
QDateTime deserialised;
|
||||
dataStream >> deserialised;
|
||||
|
||||
if (dataStreamVersion >= QDataStream::Qt_5_0) {
|
||||
if (dataStreamVersion == QDataStream::Qt_5_0) {
|
||||
// Ensure local time is still correct. Again, Qt 5 handles the timeSpec
|
||||
// conversion (in this case, UTC => LocalTime) for us when deserialising.
|
||||
QCOMPARE(deserialised, expectedLocalTime);
|
||||
|
|
@ -1453,6 +1459,14 @@ void tst_QDateTime::operator_insert_extract()
|
|||
QCOMPARE(deserialised, expectedLocalTime);
|
||||
// Sanity check UTC times.
|
||||
QCOMPARE(deserialised.toUTC(), expectedLocalTime.toUTC());
|
||||
|
||||
if (dataStreamVersion != QDataStream::Qt_5_0) {
|
||||
// Deserialised local datetime should be the same time of day,
|
||||
// regardless of which timezone it was serialised in.
|
||||
QDateTime localDeserialized;
|
||||
dataStream >> localDeserialized;
|
||||
QCOMPARE(localDeserialized, dateTime);
|
||||
}
|
||||
}
|
||||
|
||||
qputenv("TZ", previousTimeZone.toLocal8Bit().constData());
|
||||
|
|
|
|||
Loading…
Reference in New Issue