web-dev-qa-db-fra.com

Est-ce toujours une bonne idée de stocker l'heure en UTC ou est-ce le cas où il est préférable de stocker l'heure locale?

En règle générale, il est recommandé de stocker l'heure en UTC et comme indiqué dans ici et ici .

Supposons qu'il y ait un événement récurrent, disons l'heure de fin, qui est toujours à la même heure locale, disons 17h00, que l'heure d'été soit activée ou désactivée pour ce fuseau horaire. De plus, il est nécessaire de ne pas modifier l'heure manuellement lorsque l'heure d'été est activée ou désactivée pour un fuseau horaire particulier. Il est également nécessaire que chaque fois que l'heure de fin soit demandée par d'autres systèmes via l'API (c'est-à-dire GetEndTimeByEvent), elle envoie toujours l'heure de fin au format UTC.

Approche 1: S'il est décidé de stocker en UTC , il peut être stocké dans la table de base de données comme ci-dessous.

Event      UTCEndTime
=====================
ABC         07:00:00
MNO         06:00:00
PQR         04:00:00

Pour le premier événement ABC, l'heure de fin en UTC est 07h00. Si elle est convertie pour afficher de l'UTC en heure locale le 1er juillet 2012, elle se traduira par 17h00 heure locale et si elle est convertie le 10 octobre 2012 ( la date à laquelle l'heure d'été est activée pour le fuseau horaire) donnera alors 18 heures, ce qui n'est pas l'heure de fin correcte.

Une façon possible que je pourrais penser est de stocker l'heure DST dans la colonne supplémentaire et d'utiliser cette heure lorsque le fuseau horaire a l'heure d'été activée.

Approche 2: Cependant, si elle est stockée comme heure locale comme ci-dessous par exemple, pour l'événement ABC, il sera toujours 17h00 à n'importe quelle date car il n'y a pas de conversion de UTC à l'heure locale.

Event      LocalEndTime
=======================
ABC         17:00:00
MNO         16:00:00
PQR         14:00:00

Et une couche d'application convertit l'heure locale en heure UTC pour l'envoyer à d'autres systèmes via (API GetEndTimeByEvent).

Est-ce toujours une bonne idée de stocker l'heure en UTC dans ce cas? Si oui, alors comment obtenir une heure locale constante?

Questions connexes: Y a-t-il jamais une bonne raison de stocker du temps non en UTC?

57
Sun

Je pense que pour répondre à cette question, nous devons réfléchir aux avantages de l'utilisation de l'UTC pour stocker les horodatages.

Personnellement, je pense que le principal avantage est que le temps est toujours (principalement) garanti cohérent. En d'autres termes, chaque fois que le fuseau horaire est modifié ou que l'heure d'été est appliquée, vous ne vous déplacez pas dans les temps. Cela est particulièrement utile dans les systèmes de fichiers, les journaux, etc. Mais est-ce nécessaire dans votre application?

Pensez à deux choses. Tout d'abord, sur l'heure du décalage d'horloge DST. Est-il probable que vos événements se produisent entre 2 heures du matin et 3 heures du matin (le jour où l'horloge est terminée)? Que devrait-il arriver alors?

Deuxièmement, l'application sera-t-elle soumise à de réels changements de fuseau horaire? En d'autres termes, allez-vous voyager avec elle de Londres à Varsovie et changer le fuseau horaire de votre ordinateur en conséquence? Que doit-il se passer dans ce cas?

Si vous avez répondu non à ces deux questions, alors vous êtes mieux avec l'heure locale. Cela rendra votre application plus simple. Mais si vous avez répondu oui au moins une fois, alors je pense que vous devriez y réfléchir davantage.


Et c'était tout sur la base de données. L'autre chose est le format d'heure utilisé en interne par l'application, et cela devrait dépendre de ce que vous ferez réellement avec cette heure.

Vous l'avez mentionné en exposant l'heure via une API. L'application interrogera-t-elle la base de données à chaque demande? Si vous stockez l'heure en interne au format UTC, vous devrez soit le faire, soit vous assurer autrement que sur l'heure d'été/heure locale, les heures mises en cache seront ajustées/élaguées.

Va-t-il faire quelque chose avec le temps lui-même? Comme l'impression l'événement se produira dans 8 heures ou se suspendre pendant environ cette période? Si oui, l'UTC sera probablement mieux. Bien sûr, vous devez penser à tous les problèmes mentionnés ci-dessus.

76
Michał Górny

J'aime y penser de cette façon:

Les ordinateurs ne se soucient pas du temps en tant que représentation compréhensible par l'homme. Ils ne se soucient pas des fuseaux horaires, du formatage des chaînes de date et d'heure ou de tout cela. Seuls les humains se soucient de la façon d'interpréter et de représenter le temps.

Laissez la base de données faire ce qu'elle fait: stocker l'heure sous forme de nombre - soit une époque UNIX (nombre de secondes écoulées depuis le 01/01/1970) ou un horodatage UTC (pas de fuseau horaire ni d'heure d'été). Ne vous préoccupez de représenter le temps d'une manière compréhensible par l'homme que lorsque vous le devez. Cela signifie que dans votre logique d'application, votre système de génération de rapports, votre application console ou tout autre endroit, un être humain consultera les données.

22
NathanAldenSr

Ce qui suit ne s'appliquerait pas à un produit global véritablement multi-locataire SaaS, donc cette opinion s'adresse aux simples développeurs d'applications "Line of Business".

Le stockage au format UTC est correct, mais il y a une exigence qui cause de la douleur si vous faites cela: "Pouvez-vous m'écrire un rapport qui me montre combien de X se produisent par jour?"

Si vous stockez des dates au format UTC, cette exigence causera de la douleur; vous devez écrire le code de réglage du fuseau horaire sur le serveur d'applications et dans vos rapports; Chaque requête ad hoc que vous effectuez sur des données incluant des critères de date devra en tenir compte.

Si votre candidature répond aux critères suivants:

  1. Chaque instance est basée sur un seul fuseau horaire.
  2. Les transitions de fuseau horaire sont généralement en dehors des heures de bureau ou vous ne vous souciez pas vraiment des "durées" des choses au niveau où une heure manquante sera importante.

Je vous suggère de stocker le datetime comme heure de date locale, tout en utilisant une bibliothèque qui vous isole des problèmes de configuration du fuseau horaire du serveur (par exemple Noda.Time dans le monde de .net).

8
Gumzle

Si vos messages inter-système utilisent ISO 8601 et que votre base de données stocke l'heure locale d'origine + décalage (comme datetimeoffset dans MSSQL ou ISODate dans Mongo comme ISO 8601 le capture) et vous êtes en utilisant uniquement DateTimeOffset dans .NET ou OffsetDateTime dans Java ou un équivalent dans votre code, aucune conversion n'est nécessaire, du tout. Vous venez de le stocker. Toutes les fonctions de comparaison fonctionneront simplement.

Si vous vous convertissez en UTC dans votre persistance, vous avez perdu le décalage du point de vue de l'utilisateur. L'affichage lorsque votre utilisateur a signé un document il y a dix ans est désormais un problème difficile. Travailler sur UTC signifiera rechercher les règles DST qui étaient en vigueur à ce moment-là sur ce territoire. Cauchemar.

Je crois que la raison pour laquelle nous sommes tous si habitués à convertir en UTC pour la persistance est parce que nous n'avions jamais l'habitude d'avoir les bonnes infrastructures de données/types de données pour nous permettre de faire la bonne chose.

6
Luke Puplett

Je voudrais simplement stocker le composant Time uniquement sans aucune zone. Chaque fois que l'API doit la diffuser, ajoutez la date correcte et convertissez-la en heure locale en UTC pour cette date.

Base de données = 17:00 (utilisez un horodatage sans date, heures en octet, minutes en octet, chaîne)

Récupérer = Date à laquelle nous voulons l'événement + Base de données 17:00 => Convertir cela de local en UTC

De cette façon, vous serez toujours au bon moment en UTC.

2
IvoTops

En fait, vous ne stockez pas un moment précis comme le supposent la plupart du temps les API. Utilisez des intervalles si votre base de données le prend en charge (PostgreSQL le fait) ou stockez-le sous forme d'entier représentant le nombre de secondes (minutes/heures) depuis minuit ou le début correspondant du calendrier (lundi, le premier du mois, etc.). Dans les deux cas, vous avez perdu beaucoup de maux de tête de vous soucier de la façon dont le "temps" est géré entre les systèmes, et ajouté seulement un mal de tête très mineur de conversion des secondes en heure de la journée à votre avis.

1
Rich Remer