J'espère faire de cette question et de ses réponses le guide ultime pour gérer l'heure d'été, en particulier pour gérer les changements effectifs.
Si vous avez quelque chose à ajouter, merci de le faire
De nombreux systèmes dépendent de la précision de l'heure. Le problème réside dans les changements d'heure dus à l'heure avancée, qui font avancer ou reculer l'horloge.
Par exemple, dans un système de prise de commande, les règles de gestion dépendent de l'heure de la commande. Si l'horloge change, les règles risquent de ne pas être aussi claires. Comment faut-il conserver l'heure de la commande? Il existe bien sûr un nombre infini de scénarios - celui-ci est simplement illustratif.
Aussi important, sinon plus:
Je serais intéressé par la programmation, le système d'exploitation, la persistance des données et d'autres aspects pertinents de la question.
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 seule plateforme.
Faites:
datetimeoffset
pouvant stocker les deux dans un seul champ.1970-01-01T00:00:00Z
(à l'exclusion des secondes intercalaires). Si vous avez besoin d'une plus grande précision, utilisez plutôt les millisecondes. Cette valeur doit toujours être basée sur UTC, sans aucun ajustement de fuseau horaire.DateTimeOffset
est souvent un meilleur choix que DateTime
.DateTime
et DateTimeZone
. Soyez prudent lorsque vous utilisez DateTimeZone::listAbbreviations()
- voir réponse . Pour conserver PHP avec les données Olson à jour, installez périodiquement le paquet PECL timezonedb ; voir la réponse .>=
, <
).Ne pas:
America/New_York
avec un "décalage de fuseau horaire", tel que -05:00
. Ce sont deux choses différentes. Voir le wiki de la balise de fuseau horaire .Date
de JavaScript pour effectuer des calculs de date et d'heure dans les navigateurs Web plus anciens, car ECMAScript version 5.1 ou antérieure présente un défaut de conception qui peut utiliser de manière incorrecte l'heure d'été. (Ceci a été corrigé dans ECMAScript 6/2015).Test:
Référence:
timezone
sur le dépassement de capacité de la piledst
timezone
Autre:
Je ne sais pas ce que je peux ajouter aux réponses ci-dessus, mais voici quelques points de ma part:
Vous devez considérer quatre moments différents:
Il y a aussi historique/temps alternatif. Ce sont agaçants car ils peuvent ne pas correspondre à l'heure normale. Ex: dates juliennes, dates selon un calendrier lunaire de Saturne, le calendrier Klingon.
L'enregistrement des horodatages de début/fin en UTC fonctionne bien. Pour 1, vous avez besoin d'un nom de fuseau horaire d'événement + offset stocké avec l'événement. Pour 2, vous avez besoin d’un identifiant d’heure locale stocké avec chaque région et d’un nom de fuseau horaire local + décalage stockés pour chaque visualiseur (il est possible de le déduire de l’IP si vous êtes en crise). Pour 3, enregistrez en secondes UTC et n’avez pas besoin de fuseaux horaires. 4 est un cas particulier de 1 ou 2 selon qu'il s'agisse d'un événement global ou local, mais vous devez également stocker un créé à horodatage afin que vous peut indiquer si une définition de fuseau horaire a été modifiée avant ou après la création de cet événement. Cela est nécessaire si vous devez afficher des données historiques.
Un exemple de ce qui précède serait:
La finale de la coupe du monde de football a eu lieu en Afrique du Sud (UTC + 2 - SAST) le 11 juillet 2010 à 19h00 UTC.
Avec ces informations, nous pouvons déterminer historiquement l’heure exacte à laquelle la finale du WCS a eu lieu même si la définition du fuseau horaire sud-africaine change et peut être affichée aux téléspectateurs dans leur région. fuseau horaire au moment où ils interrogent la base de données.
Vous devez également synchroniser les fichiers tzdata de votre système d'exploitation, de votre base de données et de votre application, à la fois entre eux et avec le reste du monde, et effectuer des tests approfondis lors de la mise à niveau. Il n'est pas rare qu'une application tierce dont vous dépendez n'ait pas géré correctement un changement de zone de stockage.
Assurez-vous que les horloges matérielles sont définies sur UTC et, si vous utilisez des serveurs dans le monde entier, assurez-vous que leurs systèmes d'exploitation sont également configurés pour utiliser l'UTC. Cela devient évident lorsque vous devez copier des fichiers journaux Apache soumis à une rotation horaire à 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'êtes pas obligé de faire des calculs mathématiques dans votre tête lorsque vous passez d'une boîte à une autre et que vous devez comparer les horodatages.
En outre, exécutez ntpd sur toutes les boîtes.
Ne faites jamais confiance à l'horodatage que vous obtenez d'un ordinateur client comme étant valide. Par exemple, les en-têtes Date: HTTP ou un appel javascript Date.getTime()
. Celles-ci conviennent très bien lorsqu'elles sont utilisées comme identificateurs opaques ou lorsque vous faites des calculs mathématiques au cours d'une seule session sur le même client, mais n'essayez pas de faire une référence croisée à ces valeurs avec quelque chose que vous avez sur le serveur. Vos clients n'exécutent pas NTP et ne disposent pas nécessairement d'une batterie en état de fonctionnement pour leur horloge BIOS.
Enfin, les gouvernements font parfois des choses très étranges:
Aux Pays-Bas, l'heure normale était exactement de 19 minutes et 32,13 secondes d'avance sur UTC, conformément à la loi, du 1909-05-01 au 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.
C'est un problème important et étonnamment difficile. La vérité est qu’il n’existe pas de norme totalement satisfaisante pour la persistance du temps. Par exemple, le standard SQL et le format ISO (ISO 8601) ne sont clairement pas suffisants.
Du point de vue conceptuel, on traite généralement deux types de données de date/heure et il convient de les distinguer (les normes ci-dessus ne le font pas): " le temps physique "et" heure civile ".
Un instant de temps "physique" est un point de la chronologie universelle continue à laquelle la physique traite (en ignorant la relativité, bien sûr). Ce concept peut être codé de manière adéquate et persister en UTC, par exemple (si vous pouvez ignorer les secondes intercalaires).
Une "heure civile" est une spécification de date/heure qui suit les normes civiles: un instant ici est entièrement spécifié par un ensemble de champs de date/heure (Y, M, J, H, MM, S, FS) plus une TZ (spécification de fuseau horaire) (également un "calendrier", en fait; mais supposons que nous limitions la discussion au calendrier grégorien). Un fuseau horaire et un calendrier permettent conjointement (en principe) de mapper d'une représentation à une autre. Mais les instants de temps civils et physiques sont fondamentalement des types de grandeurs différents, et ils doivent être séparés conceptuellement et traités différemment (une analogie: tableaux d’octets et chaînes de caractères).
La question est confuse parce que nous parlons de ces types d’événements de manière interchangeable et 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 à venir. Exemple (tiré de ma discussion ici .
John enregistre dans son calendrier un rappel d’événement à la date et à l’heure 2019-Jul-27, 10:30:00
, TZ = Chile/Santiago
, (avec décalage GMT-4 et correspond donc à UTC 2019-Jul-27 14:30:00
). Mais un jour dans l’avenir, le pays décide de changer l’offset TZ en GMT-5.
Maintenant, quand le jour vient ... si ce rappel se déclenche à
A) 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’ya pas de réponse correcte, à moins que l’on sache ce que John pensait conceptuellement en disant au calendrier "Appelle-moi, appelle-moi à 2019-Jul-27, 10:30:00 TZ=Chile/Santiago
".
Voulait-il dire un "jour civil" ("quand les horloges de ma ville disent 10h30")? Dans ce cas, A) est la bonne réponse.
Ou voulait-il dire un "instant physique du temps", un point dans la ligne continue du temps de notre univers, par exemple, "quand la prochaine éclipse solaire aura lieu". Dans ce cas, la réponse B) est la bonne.
Quelques API Date/Heure ont cette distinction: Jodatime , qui constitue le fondement de la prochaine (troisième!) Java API DateTime (JSR 310).
Séparez clairement les préoccupations architecturales - 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 et l'heure en dehors de l'heure UTC correspondent à la présentation (suit le fuseau horaire local de l'utilisateur), l'heure UTC est le modèle (reste unique pour les niveaux dorsal et intermédiaire).
En outre, décidez quel est votre public actuel, ce que vous n'avez pas à servir et où tracez-vous la ligne. Ne touchez pas à des calendriers exotiques, sauf si vous y avez des clients importants, puis envisagez de créer un ou plusieurs serveurs distincts pour chaque région, uniquement pour cette région.
Si vous pouvez acquérir et conserver l'emplacement de l'utilisateur, utilisez cet emplacement pour la conversion systématique date-heure (par exemple, une culture .NET ou une table SQL), mais fournissez un moyen pour l'utilisateur final de choisir des remplacements si la date-heure est essentielle pour vos utilisateurs.
S'il y a des obligations de vérification historiques impliqué (comme dire exactement quand Jo en AZ a payé une facture il y a 2 ans en septembre) alors conservez l'heure UTC et l'heure locale pour l'enregistrement (votre les tables de conversion changeront avec le temps).
Définissez le fuseau horaire de référence pour les données en vrac - comme des fichiers, des services Web, etc. Dites qu'une entreprise de la côte Est dispose d'un centre de données en CA. Vous devez demander et savoir ce qu'ils utilisent comme norme. d'assumer l'un ou l'autre.
Ne vous fiez pas aux décalages de fuseaux horaires intégrés dans la représentation textuelle de la date et de l'heure et n'accepte pas de les 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 l'heure avec un décalage PST, mais l'heure est en fait EST, car il s'agit de l'heure de référence du client et les enregistrements ont simplement été exportés sur un serveur qui se trouve dans PST.
Vous devez connaître la base de données Olson tz database , disponible à ftp://elsie.nci.nih.gov/pub http://iana.org/time-zones/ . Il est mis à jour plusieurs fois par an pour tenir compte des changements souvent de dernière minute intervenant dans le choix du moment (et de l'heure à laquelle) pour passer de l'heure d'hiver à l'heure d'été (heure d'été ou d'hiver) dans différents pays du monde. En 2009, la dernière version était celle de 2009; en 2010, c'était 2010n; en 2011, c'était 2011n; à la fin du mois de mai 2012, la publication était 2012c. Notez qu'il existe un ensemble de code permettant de 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.
Il s'agit de la source de noms de fuseaux horaires tels que America/Los_Angeles (et de 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), ainsi qu'un enregistrement du fuseau horaire dans lequel les données ont été générées. Vous souhaiterez peut-être faire la distinction entre le décalage par rapport à UTC à l'heure et le nom du fuseau horaire; cela peut faire la différence plus tard. De plus, savoir qu’il s’agit actuellement de 2010-03-28T23: 47: 00-07: 00 (États-Unis/Pacifique) peut vous aider ou non à interpréter la valeur 2010-11-15T12: 30 - qui est probablement spécifiée dans PST ( Heure normale du Pacifique) au lieu de l’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 Olson ont été déplacées, en partie parce que DA D Olson va bientôt prendre sa retraite, et en partie parce qu’un procès (maintenant rejeté) a été intenté contre les responsables de la maintenance pour violation du droit d’auteur. La base de données de fuseaux horaires est maintenant gérée sous les auspices de IANA , l'autorité Internet de numéros attribués, et la page d'accueil contient un lien vers "Base de données de fuseaux horaires" . La liste de discussion est maintenant [email protected]
; la liste des annonces est [email protected]
.
En général, inclut le décalage de l'heure locale (y compris le décalage de l'heure d'été) dans les horodatages stockés: l'heure UTC seule ne suffit pas si vous souhaitez afficher ultérieurement l'horodatage dans son format. fuseau horaire d'origine (et réglage de l'heure d'été).
N'oubliez pas 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 (heure unix, décalage en minutes) ou ISO 8601 .
Traverser la frontière du "temps informatique" et du "temps humain" est un cauchemar. Le principal est qu’il n’existe aucune sorte de norme pour les règles régissant les fuseaux horaires et l’heure avancée. Les pays sont libres de modifier leurs règles de fuseau horaire et d'heure d'été à tout moment, et ils le font.
Certains pays, par exemple Israël et le Brésil décident chaque année de l'heure avancée, il est donc impossible de savoir à l'avance quand (si) l'heure d'été sera effective. D'autres ont fixé (ish) des règles quant à quand DST est en vigueur. D'autres pays n'utilisent pas l'heure d'été comme tous.
Les fuseaux horaires ne doivent pas nécessairement être des différences d'heure complète par rapport à l'heure GMT. Le Népal est +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 la même heure, pourtant 3 jours différents!
Il n’existe pas non plus de norme claire sur les abréviations des fuseaux horaires et sur la façon dont elles changent à l’heure d'été, vous vous retrouvez ainsi:
AST Arab Standard Time UTC+03
AST Arabian Standard Time UTC+04
AST Arabic Standard Time UTC+03
Le meilleur conseil est d'éviter autant que possible les heures locales et de rester à l'UTC autant que possible. Convertissez uniquement aux heures locales au dernier moment possible.
Lors du test, assurez-vous de tester les pays des hémisphères occidentaux et orientaux, avec ou sans le DST en cours et avec un pays qui ne l'utilise pas (6 au total).
Pour PHP:
La classe DateTimeZone dans PHP> 5.2 est déjà basée sur la base de données Olson mentionnée par d’autres. Par conséquent, si vous effectuez des conversions de fuseau horaire dans PHP et non dans la base de données, vous êtes dispensé de travailler. avec les fichiers Olson (difficiles à comprendre).
Cependant, PHP n'est pas mis à jour aussi souvent que la base de données Olson. Par conséquent, le simple fait d'utiliser les conversions de fuseau horaire PHP peut vous laisser avec des informations DST obsolètes et influer sur l'exactitude de vos données. Bien que cela ne devrait pas se produire fréquemment, cela peut arriver, et se produira si vous avez un grand nombre d'utilisateurs dans le monde entier.
Pour faire face au problème ci-dessus, utilisez le paquetage timezonedb pecl , sa fonction consiste à mettre à jour les données de fuseau horaire de PHP. Installez ce paquet aussi souvent qu'il est mis à jour. (Je ne sais pas si les mises à jour de ces paquets suivent exactement les mises à jour Olson, mais il semble que la fréquence de mise à jour soit très proche de celle des mises à jour Olson.)
Si votre conception le permet, évitez la conversion de l'heure locale en même temps!
Cela peut sembler insensé à certains, mais pensez à UX: les utilisateurs traitent les dates proches (aujourd'hui, hier, lundi prochain) plus rapidement que les dates absolues (vendredi 09 septembre 2010 - 17.17). Et quand vous y réfléchissez davantage, la précision des fuseaux horaires (et de l'heure d'été) est d'autant plus importante que la date est proche de now()
, donc si vous pouvez exprimer des dates/dates-heures dans un format relatif de +/- 1 ou 2 semaines, le reste des dates peut être UTC et cela importera peu à 95% des utilisateurs.
De cette façon, vous pouvez stocker toutes les dates au format UTC, effectuer les comparaisons relatives au format UTC et simplement afficher les dates UTC de l'utilisateur en dehors de votre seuil de date relative.
Cela peut également s'appliquer à la saisie de l'utilisateur (mais généralement de manière plus limitée). La sélection dans un menu déroulant comportant uniquement {Hier, aujourd'hui, demain, lundi prochain, jeudi prochain} est tellement plus simple et plus facile pour l'utilisateur qu'un sélecteur de date. Les sélecteurs de dattes sont parmi les composants les plus douloureux du remplissage des formulaires. Bien sûr, cela ne fonctionnera pas dans tous les cas, mais vous pouvez constater qu’il suffit d’un peu de design astucieux pour le rendre très puissant.
Bien que je ne l'aie pas essayée, une approche des ajustements de fuseau horaire qui me conviendrait le mieux serait la suivante:
Tout stocker en UTC.
Créez une table TZOffsets
avec trois colonnes: RegionClassId, StartDateTime et OffsetMinutes (int, en minutes).
Dans la table, stockez une liste de dates et d'heures lorsque l'heure locale a changé et de combien. Le nombre de régions dans le tableau et le nombre de dates dépendent de la plage de dates et de régions du monde à prendre en charge. Pensez-y comme si c'était une date "historique", même si les dates devraient inclure l'avenir à une certaine limite pratique.
Lorsque vous devez calculer l'heure locale d'une heure UTC, procédez comme suit:
SELECT DATEADD('m', SUM(OffsetMinutes), @inputdatetime) AS LocalDateTime
FROM TZOffsets
WHERE StartDateTime <= @inputdatetime
AND RegionClassId = @RegionClassId;
Vous voudrez peut-être mettre en cache cette table dans votre application et utiliser LINQ ou un moyen similaire pour effectuer les requêtes plutôt que de consulter la base de données.
Ces données peuvent être extraites de base de données tz du domaine public .
Avantages et notes de bas de page de cette approche:
Maintenant, le seul inconvénient de cette approche ou de toute autre est que les conversions de l’heure locale à l’heure GMT ne sont pas parfaites, car tout changement DST qui a un décalage négatif par rapport à l’horloge répète une heure locale donnée. Je crains que ce ne soit pas un moyen facile de régler ce problème. C’est une des raisons pour lesquelles enregistrer l’heure locale est une mauvaise nouvelle en premier lieu.
Je me suis penché sur deux types de systèmes, les "systèmes de planification des équipes (par exemple, les ouvriers d’usine)" et les "systèmes de gestion dépendants du gaz)…
Les journées de 23 et 25 heures sont pénibles, de même que les quarts de travail de 8 heures qui durent entre 7 et 9 heures. Le problème est que vous constaterez que chaque client, ou même chaque service du client, a créé des règles différentes (souvent sans documenter) sur ce qu’il fait dans ces cas particuliers.
Il est préférable de ne pas poser certaines questions au client avant que celui-ci ait payé votre logiciel "standard". Il est très rare de trouver un client qui réfléchisse à ce type de problème dès l’achat de logiciel.
Je pense que dans tous les cas, vous devriez enregistrer l'heure au format UTC et convertir en/à partir de l'heure locale avant d'enregistrer la date et l'heure. Cependant, même savoir quelle heure est prise peut être difficile avec l'heure d'été et les fuseaux horaires.
J'ai récemment eu un problème dans une application Web où, après Ajax, la date-heure renvoyée sur mon code côté serveur était différente de la date et l'heure servies.
Cela concernait très probablement mon code JavaScript sur le client qui a construit la date de publication sur le client sous forme de chaîne, car JavaScript s'ajuste en fonction du fuseau horaire et de l'heure avancée, et dans certains navigateurs, le calcul du moment auquel appliquer l'heure avancée. semblait être différent de celui des autres.
En fin de compte, j'ai choisi de supprimer entièrement les calculs de date et d'heure sur le client et de l'envoyer à mon serveur sur une clé entière qui a ensuite été traduite en heure de jour sur le serveur, afin de permettre des transformations cohérentes.
Ce que je retiens de ceci: N'utilisez pas les calculs de date et heure JavaScript dans les applications Web à moins que vous ne deviez ABSOLUMENT le faire.
Lorsqu'il s'agit d'applications qui s'exécutent sur un serveur, y compris les sites Web et autres services principaux, le paramètre de fuseau horaire du serveur doit être ignoré par l'application.
Le conseil commun est de définir le fuseau horaire du serveur sur UTC. Il s’agit bien d’une bonne pratique, mais c’est là une aide précieuse pour les applications qui ne suivent pas d’autres meilleures pratiques. Par exemple, un service peut écrire dans des fichiers journaux avec des horodatages locaux au lieu d'horodatages basés sur UTC, créant ainsi des ambiguïtés lors de la transition de repli de l'heure d'été. La définition du fuseau horaire du serveur sur UTC corrigera l'application that. Cependant, le vrai remède serait que l’application se connecte en commençant par UTC.
Le code côté serveur, y compris les sites Web, doit jamais s'attendre à ce que le fuseau horaire local du serveur soit particulier.
Dans certaines langues, le fuseau horaire local peut facilement s’insérer dans le code de l’application. Par exemple, la méthode DateTime.ToUniversalTime
dans .NET convertit from le fuseau horaire local en UTC, et la propriété DateTime.Now
renvoie l'heure actuelle dans le fuseau horaire local. De plus, le constructeur Date
en JavaScript utilise le fuseau horaire local de l'ordinateur. Il y a beaucoup d'autres exemples comme celui-ci. Il est important de pratiquer la programmation défensive en évitant tout code utilisant le paramètre de fuseau horaire local de l'ordinateur.
Réservez en utilisant le fuseau horaire local pour le code côté client, tel que les applications de bureau, les applications mobiles et le JavaScript côté client.
Pour le Web, les règles ne sont pas si compliquées ...
Le reste ne concerne que la conversion UTC/locale à l'aide de vos bibliothèques datetime côté serveur. Bon aller ...
Laissez vos serveurs réglés sur UTC et assurez-vous qu’ils sont tous configurés pour NTP ou l’équivalent.
UTC évite les problèmes liés à l'heure d'été et les serveurs désynchronisés peuvent entraîner des résultats imprévisibles nécessitant un certain temps pour effectuer un diagnostic.
Soyez prudent lorsque vous traitez avec des horodatages stockés dans le système de fichiers FAT32 - il est toujours conservé dans les coordonnées temporelles locales (qui incluent DST - voir article msdn ). Je me suis brûlé dessus.
Une autre chose, assurez-vous que le correctif de l'heure d'été à jour est appliqué sur les serveurs.
L'année dernière, nous avons connu une situation où notre temps était constamment inférieur d'une heure pendant trois semaines aux utilisateurs nord-américains, même si nous utilisions un système basé sur UTC.
En fin de compte, c’était les serveurs. Ils avaient juste besoin d'un correctif à jour appliqué ( Windows Server 20 ).
DateTimeZone::listAbbreviations()
outputCette méthode PHP renvoie un tableau associatif contenant des fuseaux horaires "majeurs" (comme CEST), qui contiennent à leur tour des fuseaux horaires "géographiques" plus spécifiques (tels que Europe/Amsterdam).
Si vous utilisez ces fuseaux horaires et leurs informations de décalage/DST, il est extrêmement important de réaliser ce qui suit:
Il semble que toutes les configurations offset/DST différentes (y compris les configurations historiques) de chaque fuseau horaire soient incluses!
Par exemple, Europe/Amsterdam peut être trouvé six fois dans la sortie de cette fonction. Deux occurrences (offset 1172/4772) correspondent à l’heure d’Amsterdam jusqu’en 1937; deux (1200/4800) correspondent à la période utilisée entre 1937 et 1940; et deux (3600/4800) sont utilisés depuis 1940.
Par conséquent, , vous ne pouvez pas vous fier aux informations de décalage/DST renvoyées par cette fonction comme correctes/en cours d'utilisation!
Si vous voulez connaître le décalage/l'heure d'été d'un certain fuseau horaire, vous devrez procéder comme suit:
<?php
$now = new DateTime(null, new DateTimeZone('Europe/Amsterdam'));
echo $now->getOffset();
?>
Si vous maintenez des systèmes de base de données qui fonctionnent avec DST actif, vérifiez avec soin s'ils doivent être arrêtés pendant la transition en automne. Mandy DBS (ou d’autres systèmes) n’aime pas passer deux fois au même endroit (local), c’est exactement ce qui se passe lorsque vous remontez l’horloge à l’automne. SAP a résolu ce problème avec une solution de contournement (à mon humble avis): au lieu de revenir en arrière, ils laissent simplement l'horloge interne fonctionner à la moitié de la vitesse habituelle pendant deux heures ...
Les règles métier doivent toujours fonctionner sur heure civile (à moins qu'une législation n'indique le contraire). Sachez que le temps civil est un gâchis, mais c'est ce que les gens utilisent, alors c'est ce qui est important.
En interne, conservez les horodatages dans quelque chose comme civil-seconde-de-Epoch. Le Epoch n'a pas d'importance (je préfère le nix Epoch ) mais cela rend les choses plus faciles que l'alternative. Imaginez que secondes intercalaires n'existent pas sauf si vous faites quelque chose qui en a vraiment besoin (par exemple, le suivi par satellite) . Le mappage entre les horodatages et l'heure affichée est le seul point d'application des règles DST ; les règles changent fréquemment (au niveau mondial, plusieurs fois par an; blâmez les politiciens), vous devez donc vous assurer de ne pas coder en dur la cartographie. Olson's base de données TZ est inestimable.
Utilisez-vous le framework .NET ? Si tel est le cas, laissez-moi vous présenter le type DateTimeOffset , ajouté avec .NET 3.5.
Cette structure contient à la fois une DateTime
et un décalage (TimeSpan
), qui spécifient la différence entre la date et l'heure de l'instance DateTimeOffset
et le temps universel coordonné (UTC).
La méthode statique DateTimeOffset.Now
renvoie une instance DateTimeOffset
composée de l'heure actuelle (locale) et du décalage local (comme défini dans les informations régionales du système d'exploitation).
La méthode statique DateTimeOffset.UtcNow
retournera une instance DateTimeOffset
composée de l'heure actuelle en UTC (comme si vous étiez à Greenwich).
Les autres types utiles sont les classes TimeZone et TimeZoneInfo .
Pour ceux qui luttent avec cela sur . NET , voyez si utiliser DateTimeOffset
et/ou TimeZoneInfo
vaut la peine.
Si vous voulez utiliser fuseaux horaires IANA/Olson , ou trouvez que les types prédéfinis ne suffisent pas à vos besoins, consultez Noda Time , qui offre une date et une heure beaucoup plus intelligentes. API pour .NET.
Voici mon expérience: -
(Ne nécessite aucune bibliothèque tierce)
Je voulais juste souligner deux choses qui semblent inexactes ou du moins déroutantes:
Conservez toujours l'heure conformément à une norme unifiée qui ne soit pas affectée par l'heure d'été. GMT et UTC ont été mentionnés par différentes personnes, même si UTC semble être mentionné le plus souvent.
Aux fins de (presque) toutes les fins de calcul, UTC est en fait GMT. À moins que vous ne voyiez un horodatage avec une fraction de seconde, vous avez affaire à GMT, ce qui rend cette distinction redondante.
Incluez le décalage de l'heure locale tel quel (y compris le décalage de l'heure d'été) lors de l'enregistrement des horodatages.
Un horodatage est toujours représenté dans l'heure GMT et n'a donc pas de décalage.
Tom Scott's vidéo sur les fuseaux horaires sur YouTube sur la chaîne Computerphile propose également une description agréable et divertissante du sujet. Les exemples comprennent:
Ne comptez jamais uniquement sur des constructeurs tels que
new DateTime(int year, int month, int day, int hour, int minute, TimeZone timezone)
Ils peuvent déclencher des exceptions lorsqu'aucune heure précise n'existe en raison de l'heure d'été. Au lieu de cela, créez vos propres méthodes pour créer de telles dates. Dans celles-ci, interceptez toutes les exceptions dues à DST et ajustez l'heure avec le décalage de transition. L’heure d’été peut se produire à différentes dates et à différentes heures (même à minuit pour le Brésil) en fonction du fuseau horaire.
En fait, kernel32.dll n'exporte pas SystemTimeToTzSpecificLocation. Il exporte toutefois les deux suivants: SystemTimeToTzSpecificLocalTime et TzSpecificLocalTimeToSystemTime ...
Un seul exemple pour prouver que le temps de traitement est le désordre énorme décrit et que vous ne pouvez jamais être complaisant. À plusieurs endroits sur cette page, les secondes intercalaires ont été ignorées.
Il y a plusieurs années, le système d'exploitation Android utilisait des satellites GPS pour obtenir une référence de temps UTC, mais il ignorait le fait que les satellites GPS n'utilisaient pas de secondes intercalaires. Personne ne s’est aperçu jusqu’à la confusion du Nouvel An, lorsque les Apple utilisateurs du téléphone et le Android utilisateurs du téléphone ont effectué leur décompte à environ 15 secondes d’écart.
Je pense que cela a été corrigé depuis, mais vous ne savez jamais quand ces "détails mineurs" reviendront vous hanter.
struct tm
en C.¹¹ Certaines implémentations de struct tm
enregistrent le décalage UTC, mais cela n’a pas été intégré dans la norme.