Datetime and time-zone inconsistencies
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?