Question Les meilleures pratiques en matière d'heure et de fuseau horaire [fermé]


J'espère faire de cette question et de ses réponses le guide définitif du traitement de l'heure d'été, en particulier pour faire face aux changements réels.

Si vous avez quelque chose à ajouter, faites s'il vous plaît

De nombreux systèmes dépendent de la précision de l'heure, le problème est lié aux changements de l'heure en raison de l'heure d'été - en déplaçant l'horloge vers l'avant ou vers l'arrière.

Par exemple, on a des règles d'affaires dans un système de prise de commande qui dépendent de l'heure de la commande - si l'horloge change, les règles peuvent ne pas être aussi claires. Comment le temps de l'ordre devrait-il être maintenu? Il y a bien sûr un nombre infini de scénarios - celui-ci est simplement illustratif.

  • Comment avez-vous géré le problème de l'heure d'été?
  • Quelles hypothèses font partie de votre solution? (cherchez le contexte ici)

Aussi important, sinon plus:

  • Qu'avez-vous essayé qui n'a pas fonctionné?
  • Pourquoi cela n'a-t-il pas fonctionné?

Je serais intéressé par la programmation, le système d'exploitation, la persistance des données et d'autres aspects pertinents du problème.

Les réponses générales sont excellentes, mais j'aimerais aussi voir les détails, surtout s'ils ne sont disponibles que sur une plateforme.


1885


origine


Réponses:



Résumé des réponses et autres données: (veuillez ajouter les vôtres)

Faire:

  • Chaque fois que vous faites référence à un moment précis dans le temps, persistez le temps selon une norme unifiée qui n'est pas affectée par l'heure d'été. (GMT et UTC sont équivalents à cet égard, mais il est préférable d'utiliser le terme UTC. zoulou ou Z temps.)
  • Si vous choisissez plutôt de conserver une heure en utilisant une valeur d'heure locale, incluez le décalage de l'heure locale pour cette heure particulière depuis UTC (ce décalage peut changer tout au long de l'année), de sorte que l'horodatage puisse être interprété sans ambiguïté.
  • Dans certains cas, vous devrez peut-être stocker tous les deux l'heure UTC et l'heure locale équivalente. Souvent, cela est fait avec deux champs distincts, mais certaines plates-formes prennent en charge un datetimeoffset type qui peut stocker les deux dans un seul champ.
  • Lorsque vous stockez des horodatages en tant que valeur numérique, utilisez Unix temps - qui est le nombre de secondes entières depuis 1970-01-01T00:00:00Z (sauf les secondes intercalaires). Si vous avez besoin d'une plus grande précision, utilisez des millisecondes à la place. Cette valeur doit toujours être basée sur UTC, sans aucun ajustement de fuseau horaire.
  • Si vous devez ultérieurement modifier l'horodatage, incluez l'ID de fuseau horaire d'origine pour pouvoir déterminer si le décalage peut avoir changé par rapport à la valeur d'origine enregistrée.
  • Lors de la planification d'événements futurs, l'heure locale est généralement préférée à la place de l'heure UTC, car il est courant que l'offset change. Voir la réponse, et article de blog.
  • Lorsque vous stockez des dates entières, telles que des anniversaires et des anniversaires, ne convertissez pas en UTC ou tout autre fuseau horaire.
    • Lorsque cela est possible, stockez-le dans un type de données à date unique qui n'inclut pas d'heure du jour.
    • Si un tel type n'est pas disponible, veillez à toujours ignorer l'heure de la journée lors de l'interprétation de la valeur. Si vous ne pouvez pas être assuré que l'heure du jour sera ignorée, choisissez 12:00 à minuit, plutôt que 00:00 à minuit comme heure représentative plus sûre ce jour-là.
  • N'oubliez pas que les décalages de fuseau horaire ne sont pas toujours un nombre entier d'heures (par exemple, l'heure normale indienne est UTC + 05: 30 et le Népal utilise UTC + 05: 45).
  • Si vous utilisez Java, utilisez java.time pour Java 8, ou utiliser Joda Time pour Java 7 ou moins.
  • Si vous utilisez .NET, pensez à utiliser Noda Time.
  • Si vous utilisez .NET sans Noda Time, considérez que DateTimeOffset est souvent un meilleur choix que DateTime.
  • Si vous utilisez Perl, utilisez DateTime.
  • Si vous utilisez Python, utilisez pytz ou dateutil.
  • Si vous utilisez JavaScript, utilisez moment.js avec le moment-fuseau horaire extension.
  • Si vous utilisez PHP> 5.2, utilisez les conversions de fuseaux horaires natifs fournies par DateTime, et DateTimeZone Des classes. Soyez prudent lorsque vous utilisez DateTimeZone::listAbbreviations() - voir la réponse. Pour garder PHP à jour avec les données Olson, installez périodiquement le timezonedb Paquet PECL; voir la réponse.
  • Si vous utilisez C ++, assurez-vous d'utiliser une bibliothèque qui utilise correctement la Base de données de fuseau horaire de l'IANA. Ceux-ci inclus cctz, ICU, et La bibliothèque "tz" de Howard Hinnant.
    • Ne pas utiliser Renforcer pour les conversions de fuseaux horaires. Tandis que son API prétend soutenir les identifiants IANA standard (aka "zoneinfo"), il les cartographie grossièrement aux données de style POSIX, sans tenir compte de la riche histoire des changements que chaque zone a pu avoir. (En outre, le fichier est tombé en panne de maintenance.)
  • La plupart des règles métier utilisent l'heure civile, plutôt que l'heure UTC ou GMT. Par conséquent, prévoyez de convertir les horodatages UTC en fuseau horaire local avant d'appliquer la logique d'application.
  • Rappelez-vous que les fuseaux horaires et les décalages ne sont pas fixes et peuvent changer. Par exemple, historiquement, les États-Unis et le Royaume-Uni ont utilisé les mêmes dates pour «avancer» et «reculer». Cependant, en 2007, les États-Unis ont changé les dates auxquelles les horloges sont changées. Cela signifie maintenant que pour 48 semaines de l'année, la différence entre l'heure de Londres et l'heure de New York est de 5 heures et pour 4 semaines (3 au printemps, 1 à l'automne), il est de 4 heures. Soyez conscient des éléments de ce type dans les calculs impliquant plusieurs zones.
  • Considérez le type d'heure (heure de l'événement réel, heure de diffusion, heure relative, heure historique, heure récurrente) quels éléments (horodatage, décalage de fuseau horaire et nom de fuseau horaire) vous devez stocker pour une récupération correcte - voir Types de temps dans cette réponse.
  • Gardez vos fichiers OS, bases de données et fichiers tzdata d'application synchronisés entre eux et le reste du monde.
  • Sur les serveurs, définissez les horloges matérielles et les horloges du système d'exploitation sur UTC plutôt que sur un fuseau horaire local.
  • Indépendamment de la puce précédente, code côté serveur, y compris les sites Web, devrait jamais Attendez-vous à ce que le fuseau horaire local du serveur soit quelque chose en particulier. voir la réponse.
  • Préférez travailler avec des fuseaux horaires au cas par cas dans votre code d'application, plutôt que globalement via les paramètres de fichier de configuration ou les valeurs par défaut.
  • Utilisation NTP services sur tous les serveurs.
  • Si vous utilisez FAT32, rappelez-vous que les horodatages sont stockés en heure locale, pas UTC.
  • Lorsque vous traitez des événements récurrents (émission de télévision hebdomadaire, par exemple), n'oubliez pas que l'heure change avec l'heure d'été et qu'elle sera différente d'un fuseau horaire à l'autre.
  • Toujours interroger les valeurs de date et d'heure limite inférieure incluse, limite supérieure exclusive (>=, <).

Ne pas:

  • Ne confondez pas un "fuseau horaire", tel que America/New_York avec un "décalage de fuseau horaire", tel que -05:00. Ce sont deux choses différentes. Voir le wiki tag de fuseau horaire.
  • Ne pas utiliser JavaScript Date objet pour effectuer des calculs de date et d'heure dans les anciens navigateurs Web, comme ECMAScript 5.1 et inférieur a un défaut de conception cela peut utiliser l'heure d'été de manière incorrecte. (Ceci a été corrigé dans ECMAScript 6/2015).
  • Ne faites jamais confiance à l'horloge du client. Cela peut très bien être incorrect.
  • Ne dites pas aux gens de "toujours utiliser UTC partout". Ce conseil répandu est à courte vue de plusieurs scénarios valides décrits plus haut dans ce document. Au lieu de cela, utilisez la référence temporelle appropriée pour les données avec lesquelles vous travaillez. (Horodatage peut utiliser l'UTC, mais les valeurs de programmation horaire et de date uniquement ne le devraient pas.)

Essai:

  • Lors des tests, assurez-vous de tester les pays de l'Ouest, de l'Est, du Nord et Du sud hémisphères (en fait dans chaque quart du globe, donc 4 régions), avec DST en cours et non (donne 8), et un pays qui n'utilise pas DST (4 autres pour couvrir toutes les régions, soit 12 au total).
  • Tester la transition de l'heure d'été, c'est-à-dire lorsque vous êtes actuellement en heure d'été, sélectionnez une valeur de temps en hiver.
  • Tester les cas limites, tels que le fuseau horaire UTC + 12, avec DST, ce qui rend l'heure locale UTC + 13 en été et même en UTC + 13 en hiver
  • Testez toutes les bibliothèques et applications tierces et assurez-vous qu'elles traitent correctement les données de fuseau horaire.
  • Testez les fuseaux horaires d'une demi-heure, au moins.

Référence:

Autre:

  • Faites pression sur votre représentant pour mettre fin à l'abomination qui est DST. Nous pouvons toujours espérer ...
  • Lobby pour Heure normale de la Terre

802



Je ne suis pas sûr de ce que je peux ajouter aux réponses ci-dessus, mais voici quelques points de moi:

Types de temps

Il y a quatre moments différents que vous devriez considérer:

  1. Heure de l'événement: par exemple, le moment où survient un événement sportif international, ou un couronnement / un décès / etc. Cela dépend du fuseau horaire de l'événement et non du spectateur.
  2. Heure de la télévision: par exemple, une émission de télévision particulière est diffusée à 21h00 heure locale dans le monde entier. Important lorsque vous envisagez de publier les résultats (par exemple, American Idol) sur votre site Web
  3. Temps relatif: par exemple: Cette question a une fermeture de prime ouverte en 21 heures. C'est facile à afficher
  4. Par exemple: Une émission de télévision est diffusée tous les lundis à 21h, même lorsque l'heure d'été change.

Il y a aussi le temps historique / alternatif. Ce sont ennuyeux parce qu'ils ne peuvent pas remonter à l'heure standard. Par exemple: les dates juliennes, les dates selon un calendrier lunaire sur Saturne, le calendrier Klingon.

Le stockage des horodatages de début / fin en UTC fonctionne bien. Pour 1, vous avez besoin d'un nom de fuseau horaire + décalage stocké avec l'événement. Pour 2, vous avez besoin d'un identifiant de temps local stocké avec chaque région et d'un nom de fuseau horaire local + décalage stocké pour chaque visionneuse (il est possible de dériver cela de l'adresse IP si vous êtes dans un crunch). Pour 3, stocker en secondes UTC et pas besoin de fuseaux horaires. 4 est un cas particulier de 1 ou 2 selon qu'il s'agit d'un événement global ou local, mais vous devez également stocker créé à horodatage afin de savoir si une définition de fuseau horaire a été modifiée avant ou après la création de cet événement. Ceci est nécessaire si vous avez besoin de montrer des données historiques.

Temps de stockage

  • Toujours stocker l'heure en UTC
  • Convertir en heure locale sur l'affichage (local étant défini par l'utilisateur regardant les données)
  • Lorsque vous stockez un fuseau horaire, vous avez besoin du nom, de l'horodatage et du décalage. Ceci est nécessaire parce que les gouvernements changent parfois les significations de leurs fuseaux horaires (par exemple: le gouvernement américain a changé les dates DST), et votre application doit gérer les choses avec élégance ... Ex: L'horodatage exact lorsque les épisodes de LOST montrent avant et après les règles DST modifié.

Décalages et noms

Un exemple de ce qui précède serait:

Le match de finale de coupe du monde de football   arrivé en Afrique du Sud (UTC + 2 - SAST)   le 11 juillet 2010 à 19h00 UTC.

Avec cette information, nous pouvons historiquement déterminer l'heure exacte à laquelle les finales WCS 2010 ont eu lieu même si la définition du fuseau horaire sud-africain change, et être capable d'afficher cela aux téléspectateurs dans leur fuseau horaire local au moment où ils interrogent la base de données.

Le temps du système

Vous devez également synchroniser les fichiers de votre système d'exploitation, de votre base de données et de votre application, les uns avec les autres, et avec le reste du monde, et effectuer des tests intensifs lors de la mise à niveau. Il n'est pas rare qu'une application tierce dont vous dépendez n'ait pas géré correctement une modification TZ.

Assurez-vous que les horloges matérielles sont définies sur UTC et, si vous exécutez des serveurs dans le monde entier, assurez-vous que leurs systèmes d'exploitation sont également configurés pour utiliser UTC. Cela devient apparent lorsque vous avez besoin de copier des fichiers journaux Apache tournés toutes les heures à partir de serveurs dans plusieurs fuseaux horaires. Les trier par nom de fichier ne fonctionne que si tous les fichiers sont nommés avec le même fuseau horaire. Cela signifie également que vous n'avez pas à faire de calcul de date dans votre tête lorsque vous passez d'une boîte à l'autre et que vous devez comparer les horodatages.

En outre, exécutez ntpd sur toutes les cases.

Clients

Ne faites jamais confiance à l'horodatage que vous recevez d'une machine client comme valide. Par exemple, les en-têtes Date: HTTP ou un javascript Date.getTime() appel. Ils sont parfaits lorsqu'ils sont utilisés en tant qu'identificateurs opaques, ou lorsque vous effectuez des calculs de date au cours d'une seule session sur le même client, mais n'essayez pas de faire des références croisées avec un élément que vous avez sur le serveur. Vos clients n'exécutent pas NTP et n'ont pas forcément de batterie de travail pour leur horloge BIOS.

Anecdotes

Enfin, les gouvernements vont parfois faire des choses très bizarres:

L'heure normale aux Pays-Bas était   exactement 19 minutes et 32,13 secondes   devant UTC par la loi de 1909-05-01   à 1937-06-30. Ce fuseau horaire   ne peut pas être représenté exactement en utilisant   le format HH: MM.

Ok, je pense que j'ai fini.


288



C'est un problème important et étonnamment difficile. La vérité est qu'il n'y a pas de norme complètement satisfaisante pour le temps persistant. Par exemple, le standard SQL et le format ISO (ISO 8601) ne sont clairement pas suffisants.

Du point de vue conceptuel, on traite habituellement deux types de données de date-heure, et il est pratique de les distinguer (les normes ci-dessus ne le font pas): "temps physique" et "heure civile".

Un instant "physique" du temps est un point dans la chronologie universelle continue que la physique traite (en ignorant la relativité, bien sûr). Ce concept peut être codé de manière adéquate - persistant en UTC, par exemple (si vous pouvez ignorer les secondes intercalaires).

Un temps "civil" est une spécification datetime qui suit les normes civiles: un point de temps ici est entièrement spécifié par un ensemble de champs datetime (Y, M, D, H, MM, S, FS) plus un TZ (spécification fuseau horaire) (aussi un "calendrier", en fait, mais supposons que nous limitons la discussion au calendrier grégorien). Un fuseau horaire et un calendrier permettent conjointement (en principe) de cartographier d'une représentation à l'autre. Mais les instants civils et physiques sont des types de grandeurs fondamentalement différents, et ils doivent être séparés conceptuellement et traités différemment (une analogie: des tableaux d'octets et des chaînes de caractères).

Le problème est confus parce que nous parlons de ces types d'événements de façon interchangeable, et parce que les temps civils sont sujets à des changements politiques. Le problème (et la nécessité de distinguer ces concepts) devient plus évident pour les événements futurs. Exemple (tiré de ma discussion ici.

John enregistre dans son calendrier un rappel pour un événement au datetime 2019-Jul-27, 10:30:00, TZ =Chile/Santiago, (qui a décalé GMT-4, d'où il correspond à UTC 2019-Jul-27 14:30:00). Mais un jour à l'avenir, le pays décide de modifier la compensation TZ en GMT-5.

Maintenant, quand le jour viendra ... devrait ce rappel déclencher à

UNE) 2019-Jul-27 10:30:00 Chile/Santiago  = UTC time 2019-Jul-27 15:30:00 ?

ou

B) 2019-Jul-27 9:30:00 Chile/Santiago  = UTC time 2019-Jul-27 14:30:00 ?

Il n'y a pas de bonne réponse, à moins que l'on sache ce que John a voulu dire conceptuellement quand il a dit au calendrier "S'il vous plaît sonner à moi 2019-Jul-27, 10:30:00 TZ=Chile/Santiago".

Voulait-il dire une "date civile" ("quand les horloges de ma ville racontent 10:30 ") Dans ce cas, A) est la bonne réponse.

Ou voulait-il dire un "instant physique du temps", un point dans le continu par exemple, "quand la prochaine éclipse solaire Dans ce cas, la réponse B) est la bonne.

Quelques API Date / Heure ont cette distinction: parmi eux, Jodatime, qui est le fondement de la prochaine (troisième!) API Java DateTime (JSR 310).


81



Faire clairement la séparation architecturale des préoccupations - pour savoir exactement quel niveau interagit avec les utilisateurs, et doit changer la date-heure pour / à partir de la représentation canonique (UTC). La date-heure non-UTC est la présentation (suit le fuseau horaire local des utilisateurs), L'heure UTC est le modèle (reste unique pour back-end et mi-tiers).

Aussi, décidez quel est votre public actuel, ce que vous n'avez pas à servir et où tracez-vous la ligne. Ne touchez pas aux calendriers exotiques, sauf si vous y avez réellement des clients importants, puis considérez des serveurs séparés pour l'utilisateur, uniquement pour cette région.

Si vous pouvez acquérir et maintenir l'emplacement de l'utilisateur, utilisez l'emplacement pour la conversion date-heure systématique (par exemple culture .NET ou un tableau SQL) mais fournissez un moyen pour l'utilisateur final de choisir des substitutions si la date-heure est critique pour vos utilisateurs.

S'il y a des obligations d'audit historiques impliqué (comme dire exactement quand Jo en AZ a payé une facture il y a 2 ans en septembre) puis gardez à la fois l'heure UTC et l'heure locale pour l'enregistrement (vos tables de conversion changeront au cours du temps).

Définir le fuseau horaire référentiel temporel pour les données en vrac - comme les fichiers, les services Web, etc. Disons que la compagnie de la côte Est a un centre de données dans l'AC - vous devez demander et savoir ce qu'ils utilisent comme standard plutôt que d'assumer l'un ou l'autre.

Ne pas faire confiance aux décalages de fuseau horaire intégrés dans la représentation textuelle de la date et de l'heure n'accepte pas d'analyser et de les suivre. Au lieu de cela, demandez toujours que le fuseau horaire et / ou la zone de référence soient explicitement définis. Vous pouvez facilement recevoir du temps avec le décalage de la TVP, mais le temps est en fait de l'EST puisque c'est l'heure de référence du client et les enregistrements ont été simplement exportés sur un serveur qui est en PST.


53



Vous devez savoir sur le Olson base de données tz, qui est disponible à partir de ftp://elsie.nci.nih.gov/pub  http://iana.org/time-zones/. Il est mis à jour plusieurs fois par an pour gérer les changements de dernière minute (et le fait de savoir si) passer de l'hiver à l'été (standard et à l'heure d'été) dans différents pays du monde. En 2009, la dernière version était 2009s; en 2010, c'était 2010n; en 2011, c'était 2011n; à la fin de mai 2012, la sortie était 2012c. Notez qu'il existe un ensemble de code pour gérer les données et les données de fuseau horaire proprement dites, dans deux archives distinctes (tzcode20xxy.tar.gz et tzdata20xxy.tar.gz). Le code et les données sont dans le domaine public.

C'est la source des noms de fuseaux horaires tels que America / Los_Angeles (et des synonymes tels que US / Pacific).

Si vous devez suivre différentes zones, vous avez besoin de la base de données Olson. Comme d'autres l'ont conseillé, vous souhaitez également stocker les données dans un format fixe - UTC est normalement celui choisi - avec un enregistrement du fuseau horaire dans lequel les données ont été générées. Vous pouvez faire la distinction entre le décalage d'UTC à ce moment et le nom du fuseau horaire; cela peut faire une différence plus tard. De plus, sachant qu'il est actuellement 2010-03-28T23: 47: 00-07: 00 (États-Unis / Pacifique) peut ou non vous aider à interpréter la valeur 2010-11-15T12: 30 - qui est probablement spécifiée dans la TVP ( Pacific Standard Time) plutôt que PDT (heure avancée du Pacifique).

Les interfaces de bibliothèque C standard ne sont pas terriblement utiles avec ce genre de choses.


Les données d'Olson ont changé, en partie parce que A D Olson prendra sa retraite bientôt, et en partie parce qu'il y avait une poursuite (maintenant rejetée) contre les mainteneurs pour violation du droit d'auteur. La base de données des fuseaux horaires est maintenant gérée sous les auspices de IANA, l'Internet Assigned Numbers Authority, et il y a un lien sur la première page à 'Base de données de fuseaux horaires'. La liste de diffusion de discussion est maintenant tz@iana.org; la liste d'annonces est tz-announce@iana.org.


38



En général, inclure le décalage de l'heure locale (y compris le décalage de l'heure d'été) dans les horodatages stockés: UTC seul n'est pas suffisant si vous souhaitez afficher ultérieurement l'horodatage dans son fuseau horaire d'origine (et le réglage DST).

Gardez à l'esprit que le décalage n'est pas toujours un nombre entier d'heures (par exemple, l'heure standard indienne est UTC + 05: 30).

Par exemple, les formats appropriés sont un tuple (temps unix, décalage en minutes) ou ISO 8601.


24



Traverser la limite du «temps de l'ordinateur» et du «temps des gens» est un cauchemar. La principale étant qu'il n'y a pas de norme pour les règles régissant les fuseaux horaires et les heures d'été. Les pays sont libres de changer leurs règles de fuseau horaire et de DST à tout moment, et ils le font.

Certains pays, par exemple Israël, au Brésil, décide chaque année de l'heure d'été, il est donc impossible de savoir à l'avance quand (si) l'heure d'été sera en vigueur. D'autres ont des règles (ish) fixes quant au moment où l'heure d'été est en vigueur. Les autres pays n'utilisent pas la DST comme tous.

Les fuseaux horaires ne doivent pas être des différences d'heure complète par rapport à GMT. Le Népal est de +5,45. Il y a même des fuseaux horaires qui sont +13. Cela signifie que:

SUN 23:00 in Howland Island (-12)
MON 11:00 GMT 
TUE 00:00 in Tonga (+13)

sont tous en même temps, mais 3 jours différents!

Il n'y a pas non plus de standard clair sur les abréviations pour les fuseaux horaires, et comment ils changent quand ils sont dans l'heure d'été afin de vous retrouver avec des choses comme ceci:

AST Arab Standard Time     UTC+03
AST Arabian Standard Time  UTC+04
AST Arabic Standard Time   UTC+03

Le meilleur conseil est de rester à l'écart des heures locales autant que possible et s'en tenir à l'UTC où vous le pouvez. Convertissez uniquement aux heures locales au dernier moment possible.

Lors des tests, assurez-vous de tester les pays de l'hémisphère occidental et oriental, avec les deux DST en cours et non et un pays qui n'utilise pas DST (6 au total).


22



Pour PHP:

La classe DateTimeZone dans PHP> 5.2 est déjà basée sur la BD Olson que d'autres mentionnent, donc si vous faites des conversions de fuseau horaire en PHP et pas dans la BD, vous êtes exempt de travailler avec les fichiers Olson (difficiles à comprendre).

Toutefois, PHP n'est pas mis à jour aussi fréquemment que la base de données Olson. Par conséquent, le simple fait d'utiliser les conversions de fuseau horaire PHP peut vous donner des informations DST obsolètes et influencer l'exactitude de vos données. Bien que cela ne devrait pas se produire fréquemment, cela peut arriver, et volonté arriver si vous avez une grande base d'utilisateurs dans le monde entier.

Pour résoudre le problème ci-dessus, utilisez le paquet pecl timezonedb, cette fonction est de mettre à jour les données de fuseau horaire de PHP. Installez ce paquet aussi souvent qu'il est mis à jour. (Je ne suis pas sûr que les mises à jour des paquets suivent exactement les mises à jour d'Olson, mais elles semblent être mises à jour dans une fréquence qui est au moins très proche des mises à jour d'Olson.)


18



Si votre conception peut l'accommoder, évitez la conversion de l'heure locale tous ensemble! 

Je sais que cela peut sembler fou mais pensez à UX: les utilisateurs traitent les dates relatives (aujourd'hui, hier, lundi prochain) plus rapidement que les dates absolues (2010.09.17, vendredi 17 septembre) au coup d'œil. Et quand on y pense plus, la précision des fuseaux horaires (et DST) est d'autant plus importante que la date est proche de now(), donc si vous pouvez exprimer des dates / datetime dans un format relatif pendant +/- 1 ou 2 semaines, le reste des dates peut être UTC et cela n'a pas d'importance à 95% des utilisateurs.

De cette façon, vous pouvez stocker toutes les dates en UTC et faire les comparaisons relatives en UTC et simplement afficher les dates UTC de l'utilisateur en dehors de votre seuil de date relative.

Cela peut également s'appliquer à l'entrée de l'utilisateur (mais généralement de façon plus limitée). Sélectionner à partir d'une liste déroulante qui n'a que {Hier, Aujourd'hui, Demain, Lundi prochain, Jeudi prochain} est tellement plus simple et facile pour l'utilisateur qu'un sélecteur de date. Les cueilleurs de dattes sont parmi les composants induisant le plus de douleur dans le remplissage des formulaires. Bien sûr, cela ne fonctionnera pas dans tous les cas, mais vous pouvez voir qu'il suffit d'un peu de design intelligent pour le rendre très puissant.


15



Bien que je ne l'aie pas essayé, une approche des ajustements de fuseau horaire que je trouverais convaincante serait la suivante:

  1. Stockez tout en UTC.

  2. Créer une table TZOffsets avec trois colonnes: RegionClassId, StartDateTime et OffsetMinutes (int, en minutes).

Dans la table, stockez une liste de dates et d'heures quand l'heure locale a changé, et de combien. Le nombre de régions dans le tableau et le nombre de dates dépend de la gamme de dates et de zones du monde que vous devez prendre en charge. Pensez-y comme s'il s'agissait d'une date «historique», même si les dates devraient inclure le futur dans une certaine limite pratique.

Lorsque vous devez calculer l'heure locale d'une heure UTC, faites simplement ceci:

SELECT DATEADD('m', SUM(OffsetMinutes), @inputdatetime) AS LocalDateTime
FROM   TZOffsets
WHERE  StartDateTime <= @inputdatetime
       AND RegionClassId = @RegionClassId;

Vous pouvez mettre cette table en cache dans votre application et utiliser LINQ ou d'autres moyens similaires pour effectuer les requêtes au lieu de cliquer sur la base de données.

Ces données peuvent être distillées à partir du base de données tz du domaine public.

Avantages et notes de bas de page de cette approche:

  1. Aucune règle n'est incorporée dans le code, vous pouvez facilement ajuster les décalages pour de nouvelles régions ou plages de dates.
  2. Vous n'avez pas besoin de prendre en charge toutes les plages ou dates, vous pouvez les ajouter au besoin.
  3. Les régions ne doivent pas correspondre directement aux frontières géopolitiques, et pour éviter la duplication des lignes (par exemple, la plupart des états des États-Unis traitent DST de la même manière), vous pouvez avoir des entrées RegionClass larges reliant dans une autre table à des listes plus traditionnelles. États, pays, etc.
  4. Pour des situations comme les États-Unis où la date de début et de fin de l'heure d'été a changé au cours des dernières années, il est assez facile à gérer.
  5. Etant donné que le champ StartDateTime peut également stocker une heure, le temps de passage standard de 2:00 AM est géré facilement.
  6. Pas partout dans le monde utilise une heure d'été d'une heure. Cela gère facilement ces cas.
  7. La table de données est multi-plateforme et pourrait être un projet open-source séparé qui pourrait être utilisé par les développeurs qui utilisent presque n'importe quelle plate-forme de base de données ou langage de programmation.
  8. Cela peut être utilisé pour des décalages qui n'ont rien à voir avec les fuseaux horaires. Par exemple, les ajustements d'une seconde qui se produisent de temps en temps pour ajuster la rotation de la Terre, les ajustements historiques au calendrier grégorien, etc.
  9. Comme il s'agit d'une table de base de données, les requêtes de rapport standard, etc. peuvent tirer parti des données sans passer par le code de logique métier.
  10. Cela gère également les décalages de fuseau horaire si vous le souhaitez, et peut même prendre en compte des cas historiques spéciaux dans lesquels une région est affectée à un autre fuseau horaire. Tout ce dont vous avez besoin est une date initiale qui attribue un décalage de fuseau horaire à chaque région avec une date de début minimale. Cela nécessiterait de créer au moins une région pour chaque fuseau horaire, mais vous permettrait de poser des questions intéressantes comme: "Quelle est la différence entre Yuma, Arizona et Seattle, Washington le 2 février 1989 à 5h00?" (Juste soustraire un SUM () de l'autre).

Maintenant, le seul inconvénient de cette approche ou tout autre est-ce que les conversions de L'heure locale à GMT n'est pas parfaite, car tout changement de DST qui a un décalage négatif à l'horloge répète une heure locale donnée. Je crains que ce ne soit pas un moyen facile d'y faire face, ce qui est une des raisons pour lesquelles stocker les heures locales est une mauvaise nouvelle en premier lieu.


15



J'ai frappé ceci sur deux types de systèmes, "les systèmes de planification de décalage (par exemple les ouvriers d'usine)" et "les systèmes de gestion de gaz dépendant) ...

Les longues journées de 23 et 25 heures sont pénibles, de même que les quarts de travail de 8 heures qui durent 7 heures ou 9 heures. Le problème est que vous constaterez que chaque client, ou même chaque département du client, a créé des règles différentes (souvent sans les documenter) sur ce qu'il fait dans ces cas particuliers.

Il est préférable de ne pas poser certaines questions au client avant d'avoir payé votre logiciel «sur étagère». Il est très rare de trouver un client qui pense à ce type de problème dès l'achat d'un logiciel.

Je pense que dans tous les cas, vous devriez enregistrer l'heure en UTC et convertir vers / à partir de l'heure locale avant de stocker la date / heure. Cependant, même savoir ce qui prend un certain temps est peut être difficile avec l'heure d'été et les fuseaux horaires.


12