891 votes

DateTime vs DateTimeOffset

Actuellement, nous avons un moyen standard de traitant de .net dates/heures de manière consciente de fuseau horaire : chaque fois que nous produisons un DateTime nous le faisons en UTC (p. ex. utiliser DateTime.UtcNow), et chaque fois que nous affichons un, nous convertir à l’heure UTC en heure locale de l’utilisateur.

Qui fonctionne très bien, mais j’ai lu sur DateTimeOffset et comment il capture le local et l’heure UTC dans l’objet lui-même. Donc la question est, quels seraient les avantages d’utiliser DateTimeOffset vs ce que nous faisons déjà ?

1416voto

Matt Johnson Points 33433

DateTimeOffset est une représentation instantanée de temps. Par cela, je veux dire à un moment dans le temps qui est universel pour tout le monde (ne tenant pas compte de la relativité). Une autre façon de représenter instantanée temps est avec un DateTime.Kind est DateTimeKind.Utc.

Elle est distincte de calendrier de temps, qui est une position sur un calendrier, et il ya beaucoup de différents calendriers de tous les coins du globe. Nous appelons ces calendriers des fuseaux horaires. Calendrier le temps est représenté par un DateTime.Kind est DateTimeKind.Unspecifiedou DateTimeKind.Local. Et .Local n'est significative que dans les scénarios où vous avez une compréhension implicite de l'endroit où l'ordinateur en utilisant le résultat est positionné. (Par exemple, un utilisateur de poste de travail)

Alors, pourquoi DateTimeOffset au lieu d'une UTC DateTime? C'est tout une question de perspective. Nous allons utiliser une analogie - nous allons faire semblant d'être des photographes.

Imaginez-vous sur un calendrier, chronologie, en pointant un appareil photo à une personne sur la timeline instantanée énoncées en face de vous. Vous ligne votre appareil photo numérique, selon les règles de votre fuseau horaire - qui changent périodiquement en raison de l'heure d'été, ou en raison d'autres modifications à la définition juridique de votre fuseau horaire. (Vous n'avez pas une main ferme, de sorte que votre appareil photo est fragile.)

La personne debout dans la photo, voir l'angle auquel votre appareil est de. Si d'autres prenaient des photos, ils pourraient l'être à partir de différents angles. C'est ce que l' Offset de la partie de l' DateTimeOffset représente.

Donc, si vous étiquette de votre appareil photo "Heure de l'est", parfois, vous avez un pointage de -5, et parfois, vous avez un pointage de -4. Il y a des caméras partout dans le monde, toutes marquées de choses différentes, et pointent toutes dans la même timeline instantanée à partir de différents angles. Certains d'entre eux sont juste à côté de (ou sur) les uns des autres, il suffit donc de connaître le nombre n'est pas suffisant pour déterminer le fuseau horaire de l'heure est de.

Et que dire de l'UTC? Eh bien, c'est une caméra qui est la garantie d'avoir une main ferme. C'est sur un trépied, fermement ancré dans le sol. Il ne va pas n'importe où. Nous appelons l'angle de son point de vue, le décalage de zéro.

Instantaneous Time vs Calendar Time Visualization

Ce n'cette analogie nous dire? Il fournit un peu intuitive de lignes directrices.

  • Si vous êtes représentant de temps par rapport à certains endroit en particulier, de la représenter dans les de calendrier fois avec un DateTime. Juste être sûr que vous ne jamais confondre un calendrier avec un autre. Unspecified devrait être votre hypothèse. Local n'est utile à venir à partir d' DateTime.Now. Par exemple, je pourrais obtenir de l' DateTime.Now et l'enregistrer dans une base de données mais quand je le récupère, je suppose que c'est - Unspecified. Je ne peux compter que mon calendrier est le même calendrier qu'il a été initialement prise.

  • Si vous devez toujours être sûr de ce moment, assurez-vous que vous êtes représentant d'instantané de temps. Utiliser DateTimeOffset de l'appliquer, ou de l'utilisation UTC DateTime par la convention.

  • Si vous avez besoin de suivre un moment d'instantané de temps, mais vous voulez également savoir "à Quelle heure l'utilisateur pense que c'était sur leur calendrier local?" - ensuite, vous devez utiliser un DateTimeOffset. Ceci est très important pour les systèmes de chronométrage, par exemple - à la fois technique et juridique des préoccupations.

  • Si jamais vous avez besoin de modifier enregistrée précédemment DateTimeOffset - vous ne pas avoir assez d'informations dans le décalage de vous assurer que le nouveau décalage est encore pertinente pour l'utilisateur. Vous devez également stocker l'identifiant du fuseau horaire (pense - j'ai besoin du nom de l'appareil photo afin que je puisse prendre une nouvelle photo, même si la position a changé).

    Il convient également de souligner que Noda Temps , a une représentation appelée ZonedDateTime pour cette, tandis que le .Net de la bibliothèque de classes de base n'a rien de semblable. Vous auriez besoin de les stocker à la fois un DateTimeOffset et TimeZoneInfo.Id de la valeur.

  • Parfois, vous voulez représenter un calendrier de temps qui est local à "quiconque est à la recherche à elle". Par exemple, lors de la définition de ce qu' aujourd'hui les moyens. Aujourd'hui est toujours minuit à minuit, mais ils représentent une quasi-infinité d'intervalles qui se chevauchent sur la timeline instantanée. (Dans la pratique, nous avons un nombre fini de fuseaux horaires, mais vous pouvez exprimer des décalages vers le bas de la tique) Donc, dans ces situations, assurez-vous de comprendre comment limiter l' "qui pose la question?" question à un seul fuseau horaire, ou de traiter avec la traduction de leur retour instantané délai si nécessaire.

Voici quelques autres petites choses à propos de DateTimeOffset qui cette analogie, et quelques conseils pour conserver les droites:

  • Si vous comparez les deux DateTimeOffset valeurs, ils sont d'abord normalisé à zéro offset avant de les comparer. En d'autres termes, 2012-01-01T00:00:00+00:00 et 2012-01-01T02:00:00+02:00 se référer au même moment instantané, et sont donc équivalentes.

  • Si vous faites des tests unitaires et ont besoin d'être certains de l'offset, de tester à la fois l' DateTimeOffset de la valeur, et l' .Offset propriété séparément.

  • Il y a une conversion implicite construit dans pour les .Net framework qui vous permet de passer un DateTime dans n'importe quel DateTimeOffset paramètre ou d'une variable. Ce faisant, l' .Kind questions. Si vous passez un UTC genre, il portera avec un décalage de zéro, mais si vous passez soit .Local ou .Unspecified, il assumera à être locale. Le cadre est essentiellement en disant: "eh Bien, vous m'avez demandé de convertir calendrier de temps pour instantanée de temps, mais je n'ai aucune idée d'où cela venait, je vais juste utiliser le calendrier local." C'est un énorme piège si vous chargez une quelconque DateTime sur un ordinateur avec un autre fuseau horaire. (À mon humble avis - que doit lever une exception, mais elle n'a pas.)

435voto

Clay Points 1060

À Partir De Microsoft:

Ces usages pour DateTimeOffset valeurs sont beaucoup plus fréquents que ceux pour les valeurs DateTime. En conséquence, DateTimeOffset doit être considérée comme la valeur par défaut de la date et de l'heure type de développement d'applications.

http://msdn.microsoft.com/en-us/library/bb384267.aspx

Nous utilisons DateTimeOffset pour à peu près tout ce que notre application traite notamment des points dans le temps (par exemple, lorsqu'un enregistrement a été créé/mis à jour). Comme une note côté, nous utilisons DATETIMEOFFSET dans SQL Server 2008.

Je vois DateTime utile lorsque vous voulez traiter avec des dates seulement, de temps seulement, ou de traiter avec que ce soit dans un sens générique. Par exemple, si vous avez une alarme que vous voulez aller tous les jours à 7 heures du matin, vous pouvez la stocker dans une DateTime , en utilisant un DateTimeKind de Unspecified parce que vous voulez aller à 7h du matin, indépendamment de l'heure d'été. Mais si vous voulez représenter l'histoire de l'alarme événements, vous devez utiliser DateTimeOffset.

Soyez prudent lors de l'utilisation d'un mélange d' DateTimeOffset et DateTime en particulier lors de l'attribution et de la comparaison entre les types. Aussi, y a qu'à comparer DateTime instances que sont le même DateTimeKind car DateTime ignore le décalage horaire lors de la comparaison.

97voto

Hans Passant Points 475940

DateTime est capable de stocker seulement deux fois distincts, l’heure locale et UTC. La propriété Kind indique quel.

DateTimeOffset étend sur cela en étant en mesure de stocker des heures locales depuis n’importe où dans le monde. Il stocke également le décalage entre l’heure locale et UTC. Notez comment DateTime ne peut pas faire cela à moins que vous ajouteriez un membre supplémentaire à votre classe pour stocker ce décalage UTC. Ou ne jamais travailler sur l’heure UTC. Qui en soi est une belle idée, btw.

34voto

Dean Harding Points 40164

Il y a quelques endroits où les DateTimeOffset de sens. C'est quand vous avez affaire à des événements récurrents et de l'heure d'été. Disons que je veux mettre un réveil pour aller à 9 heures tous les jours. Si j'utilise le "magasin que l'UTC, afficher en heure locale" de la règle, alors que l'alarme va descendre à un les différents temps lors de l'heure d'été est en vigueur.

Il y a probablement d'autres, mais l'exemple ci-dessus est en fait l'un que j'ai couru dans le passé (c'était avant l'ajout de l' DateTimeOffset de la BCL - ma solution était à l'époque pour stocker explicitement l'heure dans le fuseau horaire local, et enregistrer les informations de fuseau horaire à côté de ça, c'est essentiellement ce DateTimeOffset n'en interne).

7voto

Joe Points 60749

Une différence majeure est que peut être utilisé en conjonction avec pour convertir en heures locales dans des fuseaux horaires autres que celui en cours.

C’est utile sur une application serveur (par exemple, ASP.NET) qui est accessible par les utilisateurs dans différents fuseaux horaires.

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