Являются ли эти преобразования часовых поясов правильными?
Я использую 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