Являются ли эти преобразования часовых поясов правильными?

Я использую Qt 5.7.1 на Windows, 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 не работает, так что я здесь упустил?

2 ответа

Решение

Это ошибка в 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))

Я не могу говорить о том, что происходит с 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
Другие вопросы по тегам