61 votes

Comment fonctionne DateTime.ToUniversalTime ()?

Comment fonctionne la conversion en UTC à partir du format DateTime standard?

Plus précisément: si je crée un objet DateTime dans un fuseau horaire, puis que je change de fuseau horaire et que j'exécute ToUniversalTime (), comment saura-t-elle que la conversion a été effectuée correctement et que l'heure est toujours représentée avec exactitude?

Merci

71voto

womp Points 71924

Il n'est pas implicite fuseau horaire attaché à un DateTime objet. Si vous exécutez ToUniversalTime() sur, il utilise le fuseau horaire de la contexte que le code est en cours d'exécution.

Par exemple, si je crée un DateTime à partir de l'époque de 1/1/1970, il me donne le même DateTime objet n'importe où dans le monde que je suis.

Si j'exécute ToUniversalTime() quand je suis en cours d'exécution le code de Greenwich, puis-je obtenir en même temps. Si je le fais pendant que je vis à Vancouver, puis-je obtenir un décalage DateTime objet de 8 heures.

C'est pourquoi il est important de stocker de temps les informations relatives à votre base de données que l'UTC fois quand vous en avez besoin pour n'importe quel type de conversion de date ou de la localisation. Considérez si votre base de code s'est déplacé d'un serveur d'installation dans un autre fuseau horaire ;)

Edit: note de Joël réponse - DateTime des objets par défaut sont typées comme DateTimeKind.Local. Si vous analysez une date et le définir comme DateTimeKind.Utc, alors ToUniversalTime() n'effectue aucune conversion.

Et voici un article sur "les Meilleures Pratiques de Codage avec la Date des Temps", et un article sur la Conversion de DateTimes avec .Net.

34voto

Jon Skeet Points 692016

Tout d'abord, il vérifie si l' Kind de la DateTime est connu pour être UTC déjà. Si oui, il retourne la même valeur.

Sinon, c'est supposé être un local du temps au local de l'ordinateur, il est exécuté sur, et en particulier dans la zone de temps que l'ordinateur a été utilisé lorsque certains de la propriété privée a d'abord été initialisées. Cela signifie que si vous modifiez le fuseau horaire après que votre application a été commencé, il ya une bonne chance qu'il sera toujours à l'aide de l'ancien.

Le fuseau horaire contient suffisamment d'information pour convertir une, heure locale, à une heure UTC ou vice-versa, bien qu'il y a des fois que c'est ambigu ou non valide. (Il y a des fois qui se produisent deux fois, et l'heure locale qui ne peut se produire en raison de l'heure d'été.) Les règles de gestion de ces cas sont spécifiés dans la documentation:

Si la date et l'heure de l'instance de la valeur est l'ambiguïté du temps, cette méthode suppose que c'est un standard de temps. (Un ambigu que le temps est un qui permet de cartographier les soit à un moment précis ou à une l'heure d'été à l'heure locale zone) Si la date et l'heure de l'instance la valeur est invalide le temps, cette méthode simplement soustrait de l'heure locale de le fuseau horaire est UTC offset de retour de l'UTC. (Une heure non valide est un qui n'existe pas en raison de la l'application de l'heure d'été règles d'ajustement.)

La valeur retournée aura un Kind de DateTimeKind.Utc, donc si vous appelez ToUniveralTime sur de ne pas appliquer le décalage de nouveau. (C'est une grande amélioration par rapport .NET 1.1!)

Si vous voulez un non-locale, fuseau horaire, vous devez utiliser TimeZoneInfo qui a été introduit dans .NET 3.5 (il y a hacky solutions pour les versions antérieures, mais ils ne sont pas sympa). Pour représenter un instant dans le temps, vous devriez envisager d'utiliser DateTimeOffset qui a été introduit dans .NET 2.0SP1, .NET3.0SP1 et .NET 3.5. Cependant, ce n'est pas pour avoir un temps réel de la zone associée avec juste un décalage de l'heure UTC. Cela signifie que vous ne savez pas à quelle heure locale sera d'une heure plus tard, par exemple -, les règles d'heure d'été peut varier entre les fuseaux horaires qui s'est passé à utiliser le même décalage pour l'instant. TimeZoneInfo est conçu pour prendre historiques et futures règles en compte, par opposition à l' TimeZone ce qui est un peu simpliste.

Fondamentalement, le soutien dans .NET 3.5 est beaucoup mieux qu'il ne l'était, mais laisse encore à désirer pour un bon calendrier de l'arithmétique. Tout le monde envie de portage Joda Time pour .NET? ;)

7voto

Joel Coehoorn Points 190579

Qu'est-ce que @womp a dit , avec en plus qu'il vérifie la propriété Kind de DateTime pour voir s'il peut déjà s'agir d'une date UTC.

3voto

Michael McCloskey Points 1765

DateTime.ToUniversalTime supprime le décalage de fuseau horaire du fuseau horaire local pour normaliser un DateTime en UTC. Si vous utilisez ensuite DateTime.ToLocalTime sur la valeur normalisée dans un autre fuseau horaire, le décalage de fuseau horaire de ce fuseau horaire sera ajouté à la valeur normalisée pour une représentation correcte dans ce fuseau horaire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X