Question

Comment fonctionne la conversion en UTC du format standard DateTime ?

Plus précisément, si je crée un objet DateTime dans un fuseau horaire, puis passe à un autre fuseau horaire et exécute ToUniversalTime () , comment connaît-il le la conversion a été effectuée correctement et que le temps est toujours représenté avec précision?

Était-ce utile?

La solution

Il n'y a pas de fuseau horaire implicite associé à un objet DateTime . Si vous exécutez ToUniversalTime () , le fuseau horaire du contexte dans lequel le code est exécuté est utilisé.

Par exemple, si je crée un DateTime depuis l'époque du 1/1/1970, le même objet DateTime me sera délivré, où que je sois dans le monde. .

Si j'exécute ToUniversalTime () lorsque j'exécute le code à Greenwich, le temps est identique. Si je le fais alors que j'habite à Vancouver, j'obtiens un objet DateTime offset de -8 heures.

C’est pourquoi il est important de stocker les informations relatives à l’heure dans votre base de données sous forme d’heures UTC lorsque vous devez effectuer tout type de conversion ou de localisation de date. Déterminez si votre base de code a été déplacée vers un serveur dans un autre fuseau horaire;)

Éditer: note de la réponse de Joel - Les objets DateTime sont saisis par défaut sous la forme DateTimeKind.Local . Si vous analysez une date et la définissez comme DateTimeKind.Utc , ToUniversalTime () n'effectue aucune conversion.

Et voici un article sur le "Codage des meilleures pratiques avec la date et l'heure" et un article sur la Conversion de DateTimes avec .Net .

Autres conseils

Tout d'abord, il vérifie si le Kind du DateTime est déjà connu pour être UTC. Si tel est le cas, la même valeur est renvoyée.

Sinon, l'heure locale est supposée être locale, c'est-à-dire locale pour l'ordinateur sur lequel il est exécuté, et en particulier pour le fuseau horaire utilisé par l'ordinateur lors de l'initialisation initiale d'une propriété privée. Cela signifie que si vous modifiez le fuseau horaire après le démarrage de votre application, il y a de bonnes chances qu'il utilise toujours l'ancien.

Le fuseau horaire contient suffisamment d’informations pour convertir une heure locale en une heure UTC ou inversement, bien que cela puisse parfois être ambigu ou invalide. (Il existe des heures locales qui se produisent deux fois et d'autres qui ne se produisent jamais en raison de l'heure avancée.) Les règles de traitement de ces cas sont spécifiées dans la documentation :

  

Si la valeur de l'instance de date et heure est   un temps ambigu, cette méthode suppose   que c'est un temps standard. (Un   temps ambigu est celui qui peut cartographier   soit à une heure normale ou à un   heure d'été selon l'heure locale   zone) Si l'instance de date et heure   la valeur est une heure invalide, cette méthode   soustrait simplement l'heure locale de   décalage UTC du fuseau horaire local à   retourner UTC. (Un temps invalide est un   cela n'existe pas à cause de la   application de l'heure d'été   règles de réglage.)

La valeur renvoyée aura un type de DateTimeKind.Utc . Par conséquent, si vous appelez ToUniveralTime , le décalage ne sera pas appliqué. encore. (Il s'agit d'une amélioration considérable par rapport à .NET 1.1!)

Si vous souhaitez un fuseau horaire non local, vous devez utiliser < code> TimeZoneInfo qui a été introduit dans .NET 3.5 (il existe des solutions pour hacky pour les versions antérieures, mais elles ne sont pas agréables). Pour représenter un instant dans le temps, vous devez envisager d'utiliser DateTimeOffset introduit dans .NET 2.0SP1, .NET3.0SP1 et .NET 3.5. Cependant, aucun fuseau horaire n’est associé à cela - il n’ya qu’un décalage par rapport à UTC. Cela signifie que vous ne savez pas quelle heure locale sera une heure plus tard, par exemple - les règles DST peuvent varier entre les fuseaux horaires pour lesquels le même décalage a été utilisé pour cet instant particulier. TimeZoneInfo est conçu pour prendre en compte les règles historiques et futures, par opposition à TimeZone , ce qui est quelque peu simpliste.

Fondamentalement, la prise en charge de .NET 3.5 est bien meilleure qu’elle ne l’était, mais laisse tout de même quelque chose à désirer pour une arithmétique appropriée du calendrier. Quelqu'un souhaite-t-il transférer Joda Time vers .NET? ;)

Ce que @womp a déclaré , en ajoutant qu'il vérifie la propriété Kind de DateTime pour voir si elle peut déjà être une date UTC.

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top