web-dev-qa-db-fra.com

Le fuseau horaire de Windows écrit dans le registre est-il fiable?

Je crée un projet c ++ qui devrait fonctionner sur plusieurs fuseaux horaires. L'application reçoit un événement, avec un fuseau horaire de référence, et cet événement est représenté graphiquement à l'utilisateur à l'heure correcte, dans son fuseau horaire local. Par exemple, un utilisateur travaillant à Berlin reçoit un événement écrit à Tokyo. L'événement de Tokyo est d'abord converti en heure UTC, puis reconverti de l'heure UTC en heure locale de l'ordinateur à Berlin, et enfin montré à l'utilisateur sur son interface graphique.

Pour convertir de l'UTC en heure locale, j'ai plusieurs fonctions de l'API Windows à ma disposition pour faire le travail. Mais pour convertir une heure d'un autre fuseau horaire en UTC, j'ai besoin d'obtenir les informations de fuseau horaire à partir du registre Windows.

Certains fuseaux horaires ont également une heure d'été à considérer. Je peux créer une règle de récurrence à partir des informations Windows sans problème. Cependant, j'ai remarqué que le jour où l'heure d'été devait se produire est parfois incorrect sur plusieurs fuseaux horaires. Par exemple, l '"Heure standard de l'Amérique du Sud". Avec la récurrence fournie par Windows, le jour de début de l'heure d'été commence 1 semaine plus tôt.

Si j'ai bien compris, la règle de récurrence renvoyée par Windows pour ce fuseau horaire spécifique dit "chaque année, le 2ème mois, la 2ème semaine du mois". Cependant, cette règle correspond rarement à la date correcte publiée sur Internet pour le changement d'heure, alors que les dates sont toutes correctes si la règle était "chaque année, le 2ème mois, la 3ème semaine du mois". De plus, comme vous pouvez le voir sur la capture d'écran fournie, les données du registre Windows affichent 2 semaines pour l'heure de début de l'heure d'été (surlignée en bleu), mais 3 semaines pour l'heure de fin de l'heure d'été (entourée en rouge), qui est calculée correctement par mon code . La description du contenu des données peut être trouvée ici: http://msdn.Microsoft.com/en-us/library/windows/desktop/ms725481 (v = vs.85) .aspx

enter image description here

J'ai plusieurs questions

  • Ai-je bien compris la règle de récurrence? (Voici ce qu'en dit MSDN: https://msdn.Microsoft.com/en-us/library/windows/desktop/ms725481 (v = vs.85) .aspx )
  • Existe-t-il des problèmes connus concernant plusieurs fuseaux horaires, en particulier celui de "E. South America Standard Time"?
  • Y a-t-il une raison pour laquelle une date de début d'heure d'été, qui se produit régulièrement chaque année, la 3e semaine du 10e mois, a une valeur définie la 2e semaine?
  • Le fuseau horaire écrit dans le registre Windows est-il fiable, sinon, quelle fonction de l'API Windows dois-je utiliser pour convertir un fuseau horaire avec l'heure d'été à partir d'une date écrite dans un fuseau horaire différent de celui défini sur la machine locale?

[~ # ~] note [~ # ~] J'ai fortement vérifié si les données que j'ai lues dans le registre étaient correctes avant de publier ce message. Je suis sûr que ce n'est pas une erreur de ce type.

[~ # ~] note [~ # ~] Je travaille avec Windows 7, mais le problème reste le même sous Windows 10

21

En tant qu'employé de Microsoft impliqué de manière significative dans les données de fuseau horaire de Windows, permettez-moi de vous assurer que Microsoft travaille très dur pour garantir la publication de mises à jour afin de conserver les données de fuseau horaire de Windows aussi précises que possible.

Il y a plusieurs défis, y compris le moment des changements de fuseau horaire tel qu'indiqué par les gouvernements. Par exemple, nous avons récemment publié un avis sur les modifications à venir du fuseau horaire de Windows pour Fidji, Chypre, le Soudan, les Tonga, la Namibie et les îles Turques et Caïques . Dans certains cas, nous pouvons respecter les dates d'entrée en vigueur établies par ces différents gouvernements. Dans certains cas, nous ne pouvons pas, car ils n'offrent pas suffisamment de délais.

Prenons le cas récent du Soudan, qui a informé la liste de diffusion IANA tz le 17 octobre 2017 d'un changement effectif le 1er novembre 2017. L'IANA a traité ce changement, tout comme Microsoft. Mais en raison du court préavis et du temps nécessaire pour traiter un tel changement dans le système d'exploitation Windows, il faudra un peu de temps avant qu'il y ait un nouveau "Sudan Standard Time" fuseau horaire créé dans les données de fuseau horaire de Windows. Ainsi, nous émettons des directives provisoires pour utiliser un fuseau horaire différent pour le moment, puis revenons en arrière une fois que nous avons des données qui reflètent correctement l'historique complet du temps dans la région affectée.

En ce qui concerne le fuseau horaire de Windows que vous avez mentionné, "E. South America Standard Time", les données de fuseau horaire sont correctes. Si vous développez l'entrée de Registre, vous verrez qu'il existe une sous-clé appelée "Dynamic DST" qui contient les modifications d'année en année des données. Pour certains fuseaux horaires, cela n'est pas nécessaire du tout, et pour d'autres fuseaux horaires, vous trouverez une très petite quantité de données car la même règle se répète année après année. Mais dans le cas du Brésil, vous remarquerez des entrées Dynamic DST pour 2009 à 2040.

Windows TZ Registry Data

(cliquez sur l'image pour voir la pleine résolution, et notez les zones que j'ai marquées manuellement en rouge qui changent d'année en année)

Les entrées Dynamic DST prennent en charge Win32 DYNAMIC_TIME_ZONE_INFORMATION structure, et les API correspondantes avec "dynamique" dans leur nom, comme GetDynamicTimeZoneInformation. (Ils soutiennent également le System.TimeZoneInfo classe dans le .NET Framework.) La plupart de ces API existent depuis Windows Vista/Server 2008, avec d'autres à venir dans Windows 7/Server 2012.

Notez que l'entrée TZI qui se trouve dans la clé parent est copiée à partir de la règle dynamique de l'année en cours par des processus Windows internes. Cela prend en charge les API qui fonctionnent avec Win32 TIME_ZONE_INFORMATION structures, qui sont en place depuis Windows 2000.

Pour répondre aux questions spécifiques que vous avez posées:

Ai-je bien compris la règle de récurrence?

La règle spécifique que vous avez citée concerne uniquement 2017 et indique que l'heure d'été se termine le 2ème mois (février), le 3ème samedi à 23 heures: 59: 59.999 heure locale, et recommence le 10e mois (octobre), le 2e samedi, à 23: 59: 59.999 heure locale. Gardez à l'esprit que le Brésil est dans l'hémisphère sud, donc l'heure d'été commence à la fin de l'année et se termine au début de l'année suivante.

En outre, vous vous demandez peut-être pourquoi il est 23: 59: 59.999 le samedi au lieu de 00: 00: 00.000 le dimanche. Ceci est un artefact de l'histoire. Dans le passé, certains programmes et processus ont utilisé de manière incorrecte <= au lieu de < pour évaluer la transition, et ainsi déplacer accidentellement l'horloge d'une milliseconde le lendemain, en ressortir, puis y revenir. Les événements générés par le changement de jour par erreur pourraient alors entraîner de nouveaux problèmes. Microsoft a fait de son mieux pour corriger ces bogues, mais choisit toujours d'être à 1 ms au lieu de risquer que le problème surgisse un jour dans un nouvel endroit. (Cela ne s'applique qu'aux transitions qui se produisent exactement à minuit.)

Existe-t-il des problèmes connus concernant plusieurs fuseaux horaires, en particulier celui de "E. South America Standard Time"?

Il n'y a aucun problème connu pour ce fuseau horaire, mais il existe un problème connu selon lequel les fuseaux horaires Windows (même avec les données DST dynamiques) ne peuvent prendre en charge qu'un maximum de deux transitions de fuseau horaire en une seule année. Donc, dans des endroits comme le Maroc cette transition quatre fois par an il existe des solutions de contournement internes qui maintiennent le fuseau horaire actuel des données synchronisées telles que "maintenant" est une représentation précise de l'heure locale, mais ne peut pas représenter correctement tous les points de l'année à un moment donné.

Nous n'avons actuellement pas de fuseau horaire qui mappe proprement pour Troll Station, Antarctique . La raison en est que de 2005 à 2015, cette station de recherche (population de moins de 50 ans) est passée par trois décalages différents (UTC + 0, UTC + 1 et UTC + 2) chaque année.

Si votre application dépend de façon critique de l'un des scénarios ci-dessus, je recommande d'utiliser une API avec des sources de données IANA au lieu des API Win32.

Y a-t-il une raison pour laquelle une date de début d'heure d'été, qui se produit régulièrement chaque année, la 3e semaine du 10e mois, a une valeur définie la 2e semaine?

Oui, comme mentionné ci-dessus, cela est dû à l'erreur intentionnelle de 1 ms. DST en 2017, dans les régions du Brésil qui ont DST, commence le dimanche 15 octobre à 00: 00: 00.000. C'est le troisième dimanche du mois. 1 ms avant est 23: 59: 59.999 le samedi 14 octobre, qui est le deuxième samedi du mois. Cela peut être différent chaque année, c'est pourquoi il existe des données Dynamic DST.

Le fuseau horaire écrit dans le registre Windows est-il fiable, sinon, quelle fonction de l'API Windows dois-je utiliser pour convertir un fuseau horaire avec l'heure d'été à partir d'une date écrite dans un fuseau horaire différent de celui défini sur la machine locale?

Si vous utilisez les API Win32, elles utilisent elles-mêmes les données de registre, il n'est donc pas nécessaire de travailler directement avec les données de registre. Vous devriez préférer les versions "dynamiques" des API, car elles tiennent correctement compte des changements d'une année à l'autre dans les données Dynamic DST. Parfois, ceux-ci sont étiquetés comme "Ex". Par exemple, la fonction que vous avez demandée est mieux gérée par la fonction TzSpecificLocalTimeToSystemTimeEx .

...

Cela dit, si vous pouvez éviter d'utiliser les données de fuseau horaire de Windows dans votre application, je vous recommande de le faire. Préférez les sources de données IANA ou celles qui en dérivent. Il existe de nombreuses voies pour travailler avec les données de fuseau horaire IANA. API Windows plus récentes comme Windows.Globalization.Calendar et Windows.Globalization.DatetimeFormatting.DateTimeFormatter dans WinRT/UWP utilise en effet fuseaux horaires IANA , et c'est clairement la voie à suivre. Dans l'espace C++ standard, je recommande fortement d'utiliser les bibliothèques date/tz de Howard Hinnant , ou celles fournies par le projet IC . Il existe également plusieurs autres choix viables.

62

Super de voir le niveau de détail dans le post de Matt.

Sur la question "Y a-t-il des problèmes connus concernant plusieurs fuseaux horaires, en particulier le" E. Heure normale d'Amérique du Sud "une?"

Rien de plus à ajouter, à part qu'en plus des contributions incroyablement détaillées et approfondies de Matt aux données de fuseau horaire de Windows, il existe un contrôle considérable auprès de différentes agences, ONG et organismes gouvernementaux qui a été décrit ailleurs. Par exemple, il y a des défis supplémentaires dans des endroits comme le Maroc qui non seulement transite quatre fois par an, mais les informations sont soumises au gouvernement fixant le respect officiel de l'heure d'été dans la région, et parfois avec peu de temps , ce qui entraîne des problèmes supplémentaires de publication et de déploiement. (Sans mentionner quand un gouvernement révise une décision plusieurs fois .)

Ainsi, pour certaines applications avec des dépendances critiques, une API vers la source IANA peut être préférée, ou appeler les données de fuseau horaire dans Windows.

Tout cela arrive à point nommé, si vous pardonnez le jeu de mots, juste avant que nous ne retombions dans l'hémisphère nord également.

1
M3 Sweatt