2

我在 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))

我不明白,因为我认为 2 个变量“ParisDate”和“PerthDate”应该指的是同一个时间点,用不同的时区表示。

所以我相信“delta Paris => Perth”应该是0小时。

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

4

2 回答 2

3

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

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

                            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))
于 2017-01-17T17:41:56.080 回答
1

我无法谈论 Qt 发生了什么。但是,我认为更改测试语法以使用这个免费的开源 C++11/14 库并比较测试语法和输出将是一个有趣的练习。

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
于 2017-01-17T15:38:21.990 回答