Est-ce que Windows timezone est écrit dans le registre fiable?

je crée un projet c++ qui devrait fonctionner sur plusieurs fuseaux horaires. L'application reçoit un événement, avec une référence fuseau horaire, et cet événement est représenté graphiquement à l'utilisateur à la bonne heure, 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 temps UTC, puis reconverti de UTC à L'heure locale de L'ordinateur à Berlin, et enfin montré à l'utilisateur sur son graphique interface.

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

maintenant, certains fuseaux horaires ont aussi une heure D'été à considérer. Je suis capable de créer une règle de récurrence à partir de L'Information Windows sans problèmes. Cependant, j'ai remarqué que le jour où le DST devrait se produire est parfois incorrect sur plusieurs fuseaux horaires. Par exemple, le "E. Amérique du Sud Standard Time". Avec la récurrence fournie par Windows, le jour de début DST commence 1 semaine plus tôt.

si j'ai bien compris, la règle de récurrence retournée par Windows pour ce fuseau horaire précis dit "chaque année, le 2e mois, la 2e semaine du mois". Toutefois, cette règle correspond rarement à la date correcte publiée sur l'internet pour le changement d'heure, alors que les dates sont toutes correctes si la règle est "chaque année, le 2ème mois, sur la 3e semaine du mois". En outre, comme vous pouvez le voir sur la capture d'écran fournie, les données du registre de Windows Montre 2 semaines pour l'Heure de début de la TVD (en surbrillance bleue), mais 3 semaines pour l'Heure de fin de la TVD (entouré en rouge), qui est calculé correctement par mon code. La description du contenu des données peut être trouvé 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 la récurrence? (Voici ce que MSDN en dit: https://msdn.microsoft.com/en-us/library/windows/desktop/ms725481(v=vs. 85).aspx)
  • y a-t-il des problèmes connus à propos de plusieurs fuseaux horaires, en particulier le " E. South America Temps Standard "un"?
  • y a-t-il une raison pour laquelle une date de début de la DST, qui se produit évidemment régulièrement chaque année, la 3ème semaine du 10ème mois, a une valeur fixée sur la 2ème semaine?
  • est-ce que le fuseau horaire écrit dans le Registre de Windows est fiable, sinon, quelle fonction de L'API Windows dois-je utiliser pour convertir un fuseau horaire avec DST à partir d'une date écrite dans un fuseau horaire différent de celui affiché sur la machine locale?

NOTE j'ai fortement vérifié si les données que j'ai lues du registre étaient correctes avant de poster ce message. Je suis sûr que ce n'est pas une erreur de ce genre.

NOTE je travaille avec Windows 7, mais le problème reste le même sur Windows 10

18
demandé sur Jean-Milost Reymond 2017-11-04 00:59:22

2 réponses

en tant qu'employé de Microsoft ayant une implication significative avec les données des fuseaux horaires de Windows, permettez-moi de vous assurer que Microsoft travaille très dur pour s'assurer qu'il publie des mises à jour pour garder les données des fuseaux horaires de Windows aussi précises que possible.

il y a plusieurs défis, dont le calendrier des modifications de fuseau horaire telles que données par les gouvernements. Par exemple, nous avons récemment a publié un avis sur les changements à venir du fuseau horaire de Windows Pour Fidji, Chypre, Soudan, Tonga, Namibie et Turks & Caicos. Dans certains cas, nous pouvons respecter les dates d'entrée en vigueur établies par ces différents gouvernements. Dans certains cas, nous ne le pouvons pas parce qu'ils n'offrent pas assez de temps d'avance.

prenons le cas récent du Soudan, qui a dit au IANA tz liste de diffusion, le 17 octobre, en 2017 d'un changement en vigueur le 1er novembre 2017. IANA a traité ce changement, tout comme Microsoft. Mais en raison de la court, et le temps qu'il faut pour traiter un tel changement dans le système D'exploitation Windows, il sera un peu de temps avant qu'il n'y ait un nouveau "Sudan Standard Time" fuseau horaire créé dans les données de fuseau horaire Windows. Par conséquent, nous émettons des directives provisoires pour utiliser un fuseau horaire différent pour le moment, puis nous revenons en arrière une fois que nous avons des données qui reflètent correctement l'histoire complète du temps dans la région touchée.

en ce qui concerne le fuseau horaire de Windows que vous avez mentionné, "E. South America Standard Time", les données du fuseau horaire sont correctes. Si vous développez l'entrée de registre, vous verrez qu'il y a une sous-clé appelée "DST dynamique" qui contient les changements d'année en année aux données. Pour certains fuseaux horaires, ce n'est pas du tout nécessaire, 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 DST dynamiques pour 2009 à 2040.

Windows TZ Registry Data

(cliquer sur l'image pour voir la pleine résolution, et noter les zones I manuellement marqué en rouge qui changent d'une année à l')

les entrées DST dynamiques supportent le Win32 DYNAMIC_TIME_ZONE_INFORMATION structure, et API correspondantes avec "dynamic" dans leur nom, comme GetDynamicTimeZoneInformation. (Ils soutiennent également le System.TimeZoneInfo classe dans le cadre de .NET.) La plupart de ces API ont été dans des endroits depuis Windows Vista / Server 2008, avec d'autres venant dans Windows 7 / Server 2012.

notez que le TZI l'entrée qui est dans la clé mère est copiée à partir du courant règle dynamique de l'année par les processus Windows internes. Cela supporte les API qui fonctionnent avec Win32 TIME_ZONE_INFORMATION les structures qui sont en place depuis Windows 2000.

toutes les réponses Aux questions que vous avez posées:

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

La règle spécifique que vous avez cité est pour 2017 seulement, et il est dit que l'heure d'été se termine le 2ème mois (février), le 3ème samedi, à 23:59:59.999 local heure, et recommence le 10ème mois (octobre), le 2ème samedi, à 23:59:59.999 heure locale. N'oubliez pas que le Brésil est situé dans l'hémisphère sud, de sorte que l'heure D'été commence à la fin de l'année et se termine au début de l'année suivante.

vous pouvez aussi vous demander pourquoi il est 23:59:59.999 le samedi au lieu de 00:00:00.000 le dimanche. C'est un artefact de l'histoire. Il y a eu dans le passé certains programmes et processus qui ont été mal utilisés <= au lieu de < évaluer la transition, et donc aurait accidentellement déplacer l'horloge de la milliseconde le jour suivant, trouver, puis de nouveau en guerre. Les événements générés par le changement de jour erronément pourrait alors conduire à d'autres problèmes. Microsoft a fait de son mieux pour corriger ces bugs, mais encore choisit d'être 1ms au lieu de risques le problème d'apparaître dans un nouvel endroit un jour. (Ceci ne s'applique qu'aux transitions qui se produisent exactement à minuit.)

Est-il des problèmes connus sur plusieurs fuseaux horaires, en particulier celui de "L'heure normale de L'Amérique du Sud"?

il n'y a aucun problème connu pour ce fuseau horaire, cependant il y a un problème connu que les fuseaux horaires de Windows (même avec les données DST dynamiques) ne peuvent supporter qu'un maximum de deux transitions de fuseau horaire dans une seule année. Alors, dans des endroits comme le Maroc!--55-->la transition quatre fois par année il y a des solutions de rechange internes qui maintiennent les fuseau horaire de données de synchronisation telles que "maintenant" est une représentation précise de l'heure locale, mais ne peut pas représenter tous les points de l'année correctement à un moment donné.

nous n'avons pas non plus de fuseau horaire pour Station De Troll, Antarctique. La raison en est que, de 2005 à 2015, ce station de recherche (population de moins de 50 ans) a traversé trois périodes de transition différentes (UTC+0, UTC+1 et UTC+2) chaque année.

Si votre application est critique en fonction de l'un ou l'autre 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 de L'heure D'été, qui se produit évidemment régulièrement chaque année, la 3ème semaine du 10ème mois, ont une valeur fixée sur la 2ème semaine?

Oui, comme mentionné ci-dessus, c'est dû à l'erreur intentionnelle de 1ms. DST en 2017, dans les parties du Brésil qui ont DST, commence le dimanche 15 octobre à 00: 00: 00.000. C'est le troisième dimanche du mois. 1ms avant 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 DST dynamiques.

est-ce que le fuseau horaire est écrit dans le registre de Windows fiable, sinon, quelle fonction de L'API Windows devrais-je utiliser pour convertir un fuseau horaire avec DST à partir d'une date écrite dans un fuseau horaire différent de celui défini sur le local de la machine?

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

...

Que tous les cela dit, si vous êtes en mesure d'éviter D'utiliser les données de fuseau horaire de Windows dans votre application, je recommande de le faire. Préfèrent les sources de données de L'IANA ou celles qui en sont dérivées. Il existe de nombreuses façons de travailler avec les données des fuseaux horaires de L'IANA. Les nouveaux APIs Windows comme Windows.Globalization.Calendar et Windows.Globalization.DatetimeFormatting.DateTimeFormatter dans WinRT/UWP faire, en effet, utiliser fuseaux horaires IANA, et c'est clairement la voie à suivre. Dans l'espace C++ standard, je recommande fortement d'utiliser Howard Hinnant de la date/tz bibliothèques, ou celles prévues par le projet UTI. Il existe également plusieurs autres choix viables.

59
répondu Matt Johnson 2017-11-04 03:07:42

Génial de voir le niveau de détail dans Matt.

sur la question de "y a-t-il des problèmes connus à propos de plusieurs fuseaux horaires, en particulier celui de "L'heure normale de L'Amérique du Sud"?"

rien de plus à ajouter sauf qu'en plus des contributions incroyablement détaillées et approfondies de Matt aux données des fuseaux horaires de Windows, il y a de nombreux contrôles avec différents organismes, ONG et organismes gouvernementaux qui ont été décrits ailleurs. Comme un exemple, il y a d'autres défis dans des endroits comme le Maroc qui non seulement change quatre fois par an, mais l'information est soumise au gouvernement fixant le respect officiel de la DST dans la région, et parfois avec peu de temps, ce qui entraîne des difficultés supplémentaires de publication et de déploiement. (Pour ne pas mentionner quand un gouvernement révise un décision plusieurs fois.)

ainsi, pour certaines applications avec des dépendances critiques, une API vers IANA source peut être préférée, ou j'appelle les données du fuseau horaire dans Windows.Mondialisation.

tout ceci arrive à point nommé, si vous voulez bien me pardonner le jeu de mots, juste avant que nous Retombions dans l'hémisphère nord également.

1
répondu M3 Sweatt 2017-11-04 02:24:33