2017-01-17 1 views
2

J'utilise Qt 5.7.1 sur Windows, version 64 bits. Dans mon application, je gère une date avec un fuseau horaire différent.Ces conversions de fuseau horaire sont-elles correctes?

J'ai récemment vu un comportement étrange, et voici un code simple à tester:

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(); 

Cette produire la sortie suivante:

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

Je ne comprends pas, parce que Je pensais que les 2 variables "ParisDate" et "PerthDate" devraient se référer au même moment, exprimé avec un fuseau horaire différent. Donc je crois que le "delta Paris => Perth" devrait être de 0 heures.

Je ne peux pas croire que le code Qt5 est cassé, alors qu'est-ce qui me manque ici?

+0

Il ressemble à un bug. 'PerthDate.utcOffset()' renvoie 0:/ –

Répondre

3

Ce bogue dans Qt qui a déjà été fixée, mais le correctif est pas publiée. Il semble que vous devrez attendre Qt 5.9 ou Qt 5.6.3.

En utilisant Qt branche dev J'ai cette sortie:

      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)) 
+0

un lien vers le bogue? Quand exactement le bug arrive-t-il? – Mike

+0

Ceci est une mauvaise nouvelle, mais merci! Pouvez-vous envoyer un lien vers ce bug, afin que je puisse suivre son statut? – Aurelien

+0

Je ne connais pas le rapport de bogue associé à ce bogue (même pas le commit qui l'a corrigé). Cependant le bug semble spécifique à Windows, je n'étais pas capable de le reproduire sur Ubuntu x64. –

1

Je ne peux pas parler de ce qui se passe avec Qt. Cependant, j'ai pensé que ce serait un exercice intéressant de changer la syntaxe de votre test pour utiliser ce free, open-source C++11/14 library, et de comparer à la fois la syntaxe de test et la sortie.

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'; 

Ce produit la sortie suivante:

      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