奇怪的是,我使用 Qt 5.6.0 和这个调整后的示例复制了它。
QDateTime test1 = QDateTime(QDate(2016, 11, 11), QTime(15, 00), QTimeZone("Europe/Moscow"));
QDateTime test2 = QDateTime(QDate(2016, 11, 11), QTime(15, 00), QTimeZone("Asia/Yekaterinburg"));
QDateTime test3 = QDateTime(QDate(2016, 11, 11), QTime(15, 00), QTimeZone("Europe/Berlin"));
qDebug() << test1;
qDebug() << test2;
qDebug() << test3;
qDebug() << test1.addSecs(5*60);
qDebug() << test2.addSecs(5*60);
qDebug() << test3.addSecs(5*60);
输出:
QDateTime(2016-11-11 15:00:00.000 RTZ 2 Qt::TimeSpec(TimeZone) Europe/Moscow)
QDateTime(2016-11-11 15:00:00.000 RTZ 4 Qt::TimeSpec(TimeZone) Asia/Yekaterinburg)
QDateTime(2016-11-11 15:00:00.000 MEZ Qt::TimeSpec(TimeZone) Europe/Berlin)
QDateTime(2016-11-11 18:05:00.000 RTZ 2 Qt::TimeSpec(TimeZone) Europe/Moscow)
QDateTime(2016-11-11 20:05:00.000 RTZ 4 Qt::TimeSpec(TimeZone) Asia/Yekaterinburg)
QDateTime(2016-11-11 15:05:00.000 MEZ Qt::TimeSpec(TimeZone) Europe/Berlin)
QDateTime(2016-11-11 18:05:00.000 RTZ 2 Qt::TimeSpec(TimeZone) Europe/Moscow)
请注意,我添加了另一个时区,这是我的本地时区。您可能注意到这是有效的时区 ( Europe/Berlin
)。
接下来要做的是偏移分析。您会看到以下偏移量:
Europe/Moscow
: +3 小时
Asia/Yekaterinburg
: +5小时
查看一些时区地图,可能会注意到两个区域之间的偏移量正好是2h。那么+3h是从哪里来的呢?
不用说,我又进行了一次测试。
QDateTime dt = QDateTime(QDate(2016, 11, 11), QTime(15, 00), QTimeZone("UTC"));
qDebug() << dt;
qDebug() << dt.addSecs(5*60);
qDebug() << dt.addSecs(5*60).toTimeZone(QTimeZone("Asia/Yekaterinburg"));
输出:
QDateTime(2016-11-11 15:00:00.000 UTC Qt::TimeSpec(TimeZone) UTC)
QDateTime(2016-11-11 15:05:00.000 UTC Qt::TimeSpec(TimeZone) UTC)
QDateTime(2016-11-11 20:05:00.000 RTZ 4 Qt::TimeSpec(TimeZone) Asia/Yekaterinburg)
在这里我们开始:似乎Qt在计算之前没有将时区转换为UTC,而是将其用作UTC,这会导致具有相应偏移量的后移。
可是等等...
QDateTime dt = QDateTime(QDate(2016, 11, 11), QTime(15, 00), Qt::UTC);
qDebug() << dt.toLocalTime();
qDebug() << dt.toTimeZone(QTimeZone("Asia/Yekaterinburg"));
qDebug() << dt.toUTC();
输出:
QDateTime(2016-11-11 16:00:00.000 MEZ Qt::TimeSpec(LocalTime))
QDateTime(2016-11-11 20:00:00.000 RTZ 4 Qt::TimeSpec(TimeZone) Asia/Yekaterinburg)
QDateTime(2016-11-11 15:00:00.000 UTC Qt::TimeSpec(UTC))
现在看起来,如果构造函数获取一个时区,它会假定它是 UTC,而不是提供的。如果不考虑 Qt 需要本地时间,这是显而易见的。
由于没有记录它曾经在哪里,这对我来说似乎是一个错误。
长话短说,该怎么办?
如果适用,请尝试将时间提供为当地时间或 UTC,将它们转换为 UTC,用它们进行计算,然后格式化为所需的输出。
QDateTime dt = QDateTime(QDate(2016, 11, 11), QTime(10, 00), Qt::UTC);
qDebug() << dt.toTimeZone(QTimeZone("Asia/Yekaterinburg"));
qDebug() << dt.addSecs(5*60).toTimeZone(QTimeZone("Asia/Yekaterinburg"));
输出:
QDateTime(2016-11-11 15:00:00.000 RTZ 4 Qt::TimeSpec(TimeZone) Asia/Yekaterinburg)
QDateTime(2016-11-11 15:05:00.000 RTZ 4 Qt::TimeSpec(TimeZone) Asia/Yekaterinburg)