这些时区转换是否正确?

Are these timezone conversions correct?

我在 Windows 上使用 Qt 5.7.1,64 位版本。 在我的应用程序中,我管理一些不同时区的日期时间。

我最近看到了一些奇怪的行为,这里有一个简单的代码来测试它:

QDateTime ParisDate(QDate(2016, 1, 20), QTime(2, 0, 0), QTimeZone("Europe/Paris"));
QDateTime PerthDate(QDate(2016, 1, 20), QTime(9, 0, 0), QTimeZone("Australia/Perth"));
QDateTime ParisConvertedToPerth = ParisDate.toTimeZone(QTimeZone("Australia/Perth"));

qDebug() << "                                ParisDate = " << ParisDate;
qDebug() << "                                PerthDate = " << PerthDate;
qDebug() << "                     delta Paris => Perth = " << ParisDate.secsTo(PerthDate) / 3600;
qDebug() << "     delta ParisConvertedToPerth => Perth = " << ParisConvertedToPerth.secsTo(PerthDate) / 3600;
qDebug() << "                         ParisDate to UTC = " << ParisDate.toUTC();
qDebug() << "                         PerthDate to UTC = " << PerthDate.toUTC();
qDebug() << "             ParisConvertedToPerth to UTC = " << ParisConvertedToPerth.toUTC();

这会产生以下输出:

                            ParisDate =  QDateTime(2016-01-20 02:00:00.000 Paris, Madrid Qt::TimeSpec(TimeZone) Europe/Paris)
                            PerthDate =  QDateTime(2016-01-20 09:00:00.000 Australie (Ouest) Qt::TimeSpec(TimeZone) Australia/Perth)
                delta  Paris => Perth =  8
delta  ParisConvertedToPerth => Perth =  0
                     ParisDate to UTC =  QDateTime(2016-01-20 01:00:00.000 UTC Qt::TimeSpec(UTC))
                     PerthDate to UTC =  QDateTime(2016-01-20 09:00:00.000 UTC Qt::TimeSpec(UTC))
         ParisConvertedToPerth to UTC =  QDateTime(2016-01-20 09:00:00.000 UTC Qt::TimeSpec(UTC))

我不明白,因为我认为 "ParisDate" 和 "PerthDate" 这两个变量应该指的是同一个时间点,不同时区。

所以我认为 "delta Paris => Perth" 应该是 0 小时。

我不敢相信 Qt5 代码被破坏了,所以我在这里错过了什么?

我不能说 Qt 发生了什么。但是,我认为更改测试语法以使用此 free, open-source C++11/14 library 并比较测试语法和输出将是一个有趣的练习。

auto ParisDate = make_zoned("Europe/Paris", local_days{2016_y/1/20} + 2h);
auto PerthDate = make_zoned("Australia/Perth", local_days{2016_y/1/20} + 9h);
auto ParisConvertedToPerth = make_zoned("Australia/Perth", ParisDate);

cout << "                           ParisDate = " << ParisDate << '\n';
cout << "                           PerthDate = " << PerthDate << '\n';
cout << "                delta Paris => Perth = "
     << floor<hours>(PerthDate.get_sys_time() - ParisDate.get_sys_time()) << '\n';
cout << "delta ParisConvertedToPerth => Perth = "
     << floor<hours>(PerthDate.get_sys_time() - ParisConvertedToPerth.get_sys_time()) << '\n';
cout << "                    ParisDate to UTC = " << ParisDate.get_sys_time() << '\n';
cout << "                    PerthDate to UTC = " << PerthDate.get_sys_time() << '\n';
cout << "        ParisConvertedToPerth to UTC = " << ParisConvertedToPerth.get_sys_time() << '\n';

这产生了以下输出:

                           ParisDate = 2016-01-20 02:00:00 CET
                           PerthDate = 2016-01-20 09:00:00 AWST
                delta Paris => Perth = 0h
delta ParisConvertedToPerth => Perth = 0h
                    ParisDate to UTC = 2016-01-20 01:00:00
                    PerthDate to UTC = 2016-01-20 01:00:00
        ParisConvertedToPerth to UTC = 2016-01-20 01:00:00

这是 Qt 中的一个错误,已修复,但修复未发布。看来您将不得不等待 Qt 5.9 或 Qt 5.6.3。

使用 Qt 开发分支我有这个输出:

                            ParisDate =  QDateTime(2016-01-20 02:00:00.000 Paris, Madrid Qt::TimeSpec(TimeZone) Europe/Paris)
                            PerthDate =  QDateTime(2016-01-20 09:00:00.000 Australie (Ouest) Qt::TimeSpec(TimeZone) Australia/Perth)
                 delta Paris => Perth =  0
 delta ParisConvertedToPerth => Perth =  0
                     ParisDate to UTC =  QDateTime(2016-01-20 01:00:00.000 UTC Qt::TimeSpec(UTC))
                     PerthDate to UTC =  QDateTime(2016-01-20 01:00:00.000 UTC Qt::TimeSpec(UTC))
         ParisConvertedToPerth to UTC =  QDateTime(2016-01-20 01:00:00.000 UTC Qt::TimeSpec(UTC))