KDSoap icon indicating copy to clipboard operation
KDSoap copied to clipboard

Datetime and time-zone inconsistencies

Open rokm opened this issue 7 years ago • 0 comments

While debugging timestamp-related issues, I came across the following issue and inconsistency in time-zone handling. Consider the following minimal example (in the actual code, we would be passing QDateTime objects to KDSoapValueList::addArgument() to add timestamp information to SOAP request):

#include <KDSoapClient/KDSoapClientInterface.h>
#include <KDSoapClient/KDDateTime.h>

#include <QtCore>

int main ()
{
    // Obtain current time, with and without milliseconds in local time-zone and UTC
    qint64 epoch = QDateTime::currentMSecsSinceEpoch();
    qint64 epoch0 = (epoch/1000)*1000;

    QDateTime current = QDateTime::fromMSecsSinceEpoch(epoch, Qt::LocalTime);
    QDateTime currentUtc = QDateTime::fromMSecsSinceEpoch(epoch, Qt::UTC);

    QDateTime current0 = QDateTime::fromMSecsSinceEpoch(epoch0, Qt::LocalTime);
    QDateTime currentUtc0 = QDateTime::fromMSecsSinceEpoch(epoch0, Qt::UTC);

    // Display QDateTime and corresponding date string from KDDateTime
    qInfo() << current << "->" << KDDateTime(current).toDateString();
    qInfo() << currentUtc << "->" << KDDateTime(currentUtc).toDateString();
    qInfo() << current0 << "->" << KDDateTime(current0).toDateString();
    qInfo() << currentUtc0 << "->" << KDDateTime(currentUtc0).toDateString();

    return 0;
}

Running the above program (compiled with Qt5) prints the following:

QDateTime(2018-03-29 20:32:08.806 CEST Qt::TimeSpec(LocalTime)) -> "2018-03-29T20:32:08.806"
QDateTime(2018-03-29 18:32:08.806 UTC Qt::TimeSpec(UTC)) -> "2018-03-29T18:32:08.806"
QDateTime(2018-03-29 20:32:08.000 CEST Qt::TimeSpec(LocalTime)) -> "2018-03-29T20:32:08"
QDateTime(2018-03-29 18:32:08.000 UTC Qt::TimeSpec(UTC)) -> "2018-03-29T18:32:08Z"

The second row displays the date string for the UTC datetime, and is missing the 'Z' at the end - so on the server side, it would be treated as being in "local" time or un-timezoned.

However, this behavior is also inconsistent; if datetime has no milliseconds, the UTC variant will get the 'Z' at the end due to the following branch: https://github.com/KDAB/KDSoap/blob/57cccea63c21c96fd530cc039f30f1e121d203b7/src/KDSoapClient/KDDateTime.cpp#L111

It would seem that one is expected to explicitly set the time-zone string to KDDateTime object via KDDateTime::setTimeZone(). However, I think it would be better if KDDateTime honored the timespec of the input QDateTime instead. Or perhaps KDDateTime::toDateString() should check if time-zone string is empty and in that case append "Z" if timespec is UTC. Would that be acceptable?

rokm avatar Mar 29 '18 19:03 rokm