web-dev-qa-db-fra.com

Stockage de DateTime (UTC) et stockage de DateTimeOffset

J'ai généralement un "intercepteur" qui, juste avant la lecture/l'écriture de/vers la base de données, effectue la conversion DateTime (de UTC à l'heure locale et de l'heure locale à UTC), donc je peux utiliser DateTime.Now (dérivations et comparaisons) dans tout le système sans se soucier des fuseaux horaires.

En ce qui concerne la sérialisation et le déplacement des données entre les ordinateurs, il n'y a pas lieu de s'inquiéter, car le datetime est toujours UTC.

Dois-je continuer à stocker mes dates (SQL 2008 - datetime) au format UTC ou dois-je plutôt les stocker à l'aide de DateTimeOffset (SQL 2008 - datetimeoffset)?

Les dates UTC dans la base de données (type datetime) fonctionnent et sont connues depuis si longtemps, pourquoi les changer? Quels sont les avantages?

J'ai déjà examiné des articles comme celui-ci , mais je ne suis pas convaincu à 100%. Des pensées?

82
Frederico

Il y a une énorme différence, où vous ne pouvez pas utiliser UTC seul.

  • Si vous avez un scénario comme celui-ci

    • n serveur et plusieurs clients (tous géographiquement dans différents fuseaux horaires)
    • Les clients créent des données avec des informations datetime
    • Les clients stockent tout sur le serveur central
  • Ensuite:

    • datetimeoffset stocke l'heure UTC et le décalage AUSSI à l'heure locale du client
    • tous les clients connaissent l'heure UTC de toutes les données ainsi que l'heure locale à l'endroit où les informations ont été générées
  • Mais:

    • TC datetime stocke uniquement UTC datetime, vous n'avez donc pas d'informations sur l'heure locale à l'emplacement du client d'où proviennent les données
    • D'autres clients ne connaissent pas l'heure locale de l'endroit, d'où proviennent les informations datetime
    • Les autres clients peuvent uniquement calculer leur heure locale à partir de la base de données (en utilisant l'heure UTC) et non l'heure locale du client, d'où proviennent les données.

Un exemple simple est le système de réservation de billets d'avion ... Le billet de vol doit contenir 2 fois: - l'heure de "décollage" (dans le fuseau horaire de la "ville") - l'heure "d'atterrissage" (dans le fuseau horaire de la ville "de destination")

114
Thetam

Vous avez absolument raison d'utiliser UTC pour toutes les périodes historiques (c'est-à-dire que les événements d'enregistrement se sont produits). Il est toujours possible de passer de l'UTC à l'heure locale mais pas toujours l'inverse.

Quand utiliser l'heure locale? Répond a cette question:

Si le gouvernement décide soudainement de changer l'heure d'été, aimeriez-vous que ces données changent avec lui?

Ne stockez l'heure locale que si la réponse est "oui". Évidemment, ce ne sera que pour les dates futures, et généralement uniquement pour les dates qui affectent les gens d'une manière ou d'une autre.

Pourquoi enregistrer un fuseau horaire/décalage?

Tout d'abord, si vous souhaitez enregistrer le décalage pour l'utilisateur qui a effectué l'action, vous feriez probablement mieux de le faire, c'est-à-dire lors de la connexion, enregistrez l'emplacement et le fuseau horaire de cet utilisateur.

Deuxièmement, si vous souhaitez convertir pour l'affichage, vous devez avoir un tableau de toutes les transitions de décalage d'heure locale pour ce fuseau horaire, sachant simplement que le décalage actuel n'est pas suffisant, car si vous affichez une date/heure d'il y a six mois, le décalage sera sois différent.

21
Ben

Un DATETIMEOFFSET vous donne la possibilité de stocker l'heure locale et l'heure UTC dans un champ.

Cela permet un reporting très simple et efficace en heure locale ou UTC sans avoir à traiter les données pour les afficher de quelque manière que ce soit.

Ce sont les deux exigences les plus courantes: l'heure locale pour les rapports locaux et l'heure UTC pour les rapports de groupe.

L'heure locale est stockée dans la partie DATETIME du DATETIMEOFFSET et le OFFSET d'UTC est stocké dans la partie OFFSET, ainsi la conversion est simple et, puisqu'elle ne nécessite aucune connaissance du fuseau horaire d'où proviennent les données, tout peut être fait au niveau de la base de données .

Si vous n'avez pas besoin de temps en millisecondes, par exemple en quelques minutes ou secondes, vous pouvez utiliser DATETIMEOFFSET (0). Le champ DATETIMEOFFSET ne nécessitera alors que 8 octets de stockage, comme un DATETIME.

L'utilisation d'un DATETIMEOFFSET plutôt que d'un UTC DATETIME donne donc plus de flexibilité, d'efficacité et de simplicité pour le reporting.

18
PapillonUK