Fuseaux horaires, décalages et ObjectScript, un vrai casse-tête !
Votre mission
Imaginons que vous êtes un espion international qui consacre sa vie à protéger les habitants de notre planète contre les dangers. La mission suivante vous est confiée:
Cher agent IRIS,
Nous sommes désolés d'interrompre vos vacances aux
Bahamas, mais notre agent àLondresvient de nous informer qu'une "bombe à explosion retardée" est prête à exploser dans une zone très peuplée deLos Angeles. Selon nos informateurs, la "bombe à explosion retardée" devrait se déclencher à15h14aujourd'hui.Dépêchez-vous, les citoyens comptent sur vous!
Le problème
Alors que vous vous précipitez et vous préparez à partir pour Los Angeles, vous vous rendez compte qu'il vous manque un renseignement essentiel : cette "bombe à explosion retardée" explosera-t-elle à 15h14 heure des Bahamas ou à 15h14 heure de Los Angeles? ...ou peut-être même à 15h14 heure de Londres.
Vous comprenez bien vite que l'heure fournie (15h14) ne vous donne pas assez de renseignements pour déterminer le moment où vous devez vous rendre à Los Angeles.
L'heure indiquée (15h14) était ambiguë. Vous avez besoin de plus de renseignements pour déterminer une heure exacte.
Quelques solutions
Lorsque vous réfléchissez au problème, vous vous rendez compte qu'il existe des méthodes pour surmonter l'ambiguïté de l'heure indiquée qui vous a été fournie:
Votre informateur aurait pu vous fournir le lieu où l'heure locale était
3:14 PM. Par exemple,Los Angeles, lesBahamas, ouLondres.Votre informateur aurait pu utiliser un standard telle que l'UTC (temps universel coordonné) pour vous fournir un décalage par rapport à un lieu convenu (tel que Greenwich, Londres).
La fin heureuse
Vous téléphonez à votre informateur et confirmez que l'heure fournie était bien 15h14 heure de Los Angeles. Vous pouvez vous rendre à Los Angeles, désamorcer la "bombe à explosion retardée" avant 15h14, et retourner rapidement aux Bahamas pour y terminer vos vacances.
Le but
Quel est donc le but de cet exercice de réflexion? Je doute qu'aucun d'entre nous soit confronté au problème présenté ci-dessus, mais si vous travaillez avec une application ou un code qui déplace des données d'un lieu à un autre (en particulier si les lieux se trouvent dans des fuseaux horaires différents), vous devez savoir comment gérer les dates-heures et les fuseaux horaires.
Les fuseaux horaires, C'EST DUR!
Eh bien, les fuseaux horaires ne sont pas si mauvais. Ce sont l'heure d'été et les périmètres politiques qui rendent les fuseaux horaires si difficiles à gérer.
Je croyais avoir toujours compris l'idée "générale" des fuseaux horaires: le globe est divisé en tranches verticales par fuseau horaire, où chaque fuseau horaire est en retard d'une heure par rapport au fuseau horaire situé à l'Est.

Bien que cette simplification soit valable pour de nombreux endroits, il existe malheureusement de nombreuses exceptions à cette règle.
Référence: Fuseaux horaires du monde (Wikipedia)
Représentation du temps UTC ("l'origine")
Pour simplifier la communication de l'heure spécifique, le monde a décidé d'utiliser l'UTC (le temps universel coordonné). Ce standard fixe "l'origine" à la longitude 0° qui passe par Greenwich, Londres.
Définition du "décalage"
En utilisant le temps universel coordonné (UTC) comme base, tous les autres fuseaux horaires peuvent être définis par rapport à l'UTC. Cette relation est appelée décalage UTC.
Si vous connaissez l'heure locale et le décalage, vous n'avez plus d'heure ambiguë (comme dans notre exemple d'espionnage ci-dessus) ; vous avez une heure définie et spécifique, sans ambiguïté.
Le format type utilisé pour indiquer le décalage UTC est le suivant: ±HHMM[SS[.ffffff]].
- Le symbole moins
-indique un décalage à l'ouest de l'UTC. - Le signe plus
+indique un décalage à l'est de l'UTC.. HHindique les heures (avec un zéro initial)MMindique les minutes (avec un zéro initial)SSindique les secondes (avec un zéro initial).ffffffindique les fractions de secondes
Par exemple, en Amérique, le fuseau horaire de l'Est (EST) est défini comme -0500 UTC. Cela signifie que toutes les localités situées dans le fuseau horaire EST sont en retard de 5 heures par rapport à l'UTC. Si l'heure est 9:00 PM à UTC, l'heure locale à EST est 4:00 PM.
Dans le fuseau horaire central occidental d'Australie (ACWST), le décalage est défini comme +0845 UTC. Si l'heure est 21h00 à UTC, l'heure locale d'EST est 16h00.
Heure d'été
Revenons aux cartes des fuseaux horaires ci-dessus. Vous y trouverez de nombreux fuseaux horaires qui suivent les frontières politiques des pays et des régions. Cela complique légèrement le calcul des fuseaux horaires, mais c'est assez facile à comprendre.
Malheureusement, il y a un autre élément à prendre en compte lorsque l'on travaille avec des heures et des fuseaux horaires.
Regardons Los Angeles.
Cette carte indique que le décalage UTC pour Los Angeles est de -8 en Standard Time. L'heure normale est généralement suivie pendant les mois d'hiver, tandis que l'heure d'été est généralement suivie pendant les mois d'été.
L'heure d'été (en anglais; Daylight Savings Time (DST) avance les horloges d'un fuseau horaire donné (généralement d'une heure pendant les mois d'été). Les régions politiques peuvent choisir de suivre l'heure d'été pour plusieurs raisons (économies d'énergie, meilleure utilisation de la lumière du jour, etc.) La difficulté et la complexité de l'heure d'été résident dans le fait que l'heure d'été n'est pas appliquée de manière uniforme dans le monde entier. Selon votre situation géographique, votre région peut suivre ou non l'heure d'été.
Base de données de fuseaux horaires
La combinaison des frontières politiques et de l'heure d'été augmentant considérablement la complexité de la détermination d'une heure spécifique, une base de données des fuseaux horaires est nécessaire pour faire correspondre correctement les heures locales à des heures spécifiques par rapport à l'UTC. La base de données des fuseaux horaires de l'IANA (Internet Assigned Numbers Authority) est la source commune de renseignements sur les fuseaux horaires utilisée par les systèmes d'exploitation et les langages de programmation.
La base de données comprend les noms et alias de tous les fuseaux horaires, des renseignements sur le décalage, des renseignements sur l'utilisation de l'heure d'été, les abréviations des fuseaux horaires et les plages de données auxquelles les différentes règles s'appliquent.
Des copies et des renseignements concernant la base de données sur les fuseaux horaires sont disponibles sur le site web de l'IANA.
La plupart des systèmes UNIX disposent d'une copie de la base de données qui est mise à jour par le gestionnaire de paquetages du système d'exploitation (généralement installé dans /usr/share/zoneinfo). Certains langages de programmation ont la base de données intégrée. D'autres la rendent disponible par le biais d'une bibliothèque ou peuvent lire la copie de la base de données du système.
Noms et identifiants des fuseaux horaires
La base de données des fuseaux horaires contient un grand nombre de noms et d'alias pour des fuseaux horaires spécifiques. La plupart des saisies incluent un pays (ou un continent) et une grande ville dans le nom. Par exemple:
- Amérique/New_York
- Amérique/Los_Angeles
- Europe/Rome
- Australie/Melbourne
Conversion et formatage à l'aide d'ObjectScript
Ainsi, voici ce que nous savons:
- les heures locales (heures ambiguës sans décalage ni emplacement)
- les décalages UTC (le décalage relatif d'un horodatage ou d'un emplacement par rapport à l'« origine » UTC à Greenwich, Londres)
- l'heure d'été (une tentative d'aider la civilisation au détriment des décalages de fuseaux horaires)
- base de données des fuseaux horaires (qui contient des renseignements sur les fuseaux horaires et le respect de l'heure d'été dans de nombreux lieux et régions).
Sachant cela, comment pouvons-nous travailler avec les heures-dates et les fuseaux horaires en ObjectScript?
***Note: Je crois que toutes les affirmations suivantes sont vraies à propos d'ObjectScript, mais n'hésitez pas à me faire savoir si j'ai mal expliqué comment ObjectScript fonctionne avec les fuseaux horaires et les décalages.
Variables et fonctions intégrées
Si vous avez besoin de convertir des horodatages entre différents formats dans le fuseau horaire du processus exécutant IRIS, les fonctionnalités intégrées d'ObjectScript devraient être suffisantes. Voici une brève liste des variables/fonctions relatives au temps dans ObjectScript:
$ZTIMESTAMP / $ZTS
- Format interne d'IRIS en tant que valeur UTC (décalage +0000).
- Format: ddddd,sssss.fffffff
$NOW(tzmins)
- Heure locale du système actuel avec le décalage de
tzminsdonné par rapport à UTC. - Heure d'été n'est pas prise en compte.
- Par défaut, tzmins est basé sur la variable $ZTIMEZONE.
- Format: ddddd,sssss.fffffff
- Heure locale du système actuel avec le décalage de
$HOROLOG
- Heure locale actuelle du système (basée sur $ZTIMEZONE), avec prise en compte de l'heure d'été.
- Format: ddddd,sssss.fffffff
$ZTIMEZONE
- Renvoie ou définit le décalage UTC local du système en minutes.
$ZDATETIME() / $ZDT()
- Conversion du format $HOROLOG en un format d'affichage spécifique.
- Peut être utilisé pour la conversion de l'heure locale du système à l'heure UTC (+0000).
$ZDATETIMEH() / $ZDTH()
- Conversion d'une chaîne de date au format interne $HOROLOG.
- Peut être utilisé pour convertir l'heure UTC (+0000) en heure locale.
Pour autant que je sache, ces fonctionnalités ne peuvent manipuler les dates qu'en utilisant le fuseau horaire du système local. Il ne semble pas y avoir de moyen de travailler avec des fuseaux horaires arbitraires en ObjectScript.
Accès à la bibliothèque tz sur Open Exchange
Pour faciliter la conversion vers et depuis des fuseaux horaires arbitraires, j'ai créé la bibliothèque de conversion de fuseaux horaires ObjectScript tz - ObjectScript Time Zone Conversion Library.
Cette bibliothèque accède à la base de données des fuseaux horaires installée sur votre système afin d'offrir un support pour la conversion des horodatages entre les fuseaux horaires et les formats.
Par exemple, si vous disposez de l'heure locale de Los Angeles (Amérique/Los_Angeles), vous pouvez la convertir dans le fuseau horaire utilisé aux Bahamas (Amérique/New_York) ou dans le fuseau horaire utilisé à Londres (Europe/Londres):
USER>zw ##class(tz.Ens).TZ("2024-12-20 3:14 PM", "America/Los_Angeles", "America/New_York")
"2024-12-20 06:14 PM"
USER>zw ##class(tz.Ens).TZ("2024-12-20 3:14 PM", "America/Los_Angeles", "Europe/London")
"2024-12-20 11:14 PM"
Si l'on vous donne un horodatage avec un décalage, vous pouvez le convertir en heure locale à Eucla, Australie (Australie/Eucla), même si vous ne connaissez pas le fuseau horaire d'origine:
USER>zw ##class(tz.Ens).TZ("2024-12-20 08:00 PM -0500", "Australia/Eucla")
"2024-12-21 09:45 AM +0845"
Si vous travaillez avec des messages HL7, la bibliothèque tz dispose de plusieurs méthodes associées aux règles d'interopérabilité et aux DTL pour vous aider à convertir facilement les fuseaux horaires, les heures locales, les heures avec décalage, etc.:
// Conversion de l'heure locale d'un fuseau horaire à l'autre
set datetime = "20240102033045"
set newDatetime = ##class(tz.Ens).TZ(datetime,"America/New_York","America/Chicago")
// Conversion de l'heure locale en décalage
set datetime = "20240102033045"
set newDatetime = ##class(tz.Ens).TZOffset(datetime,"America/Chicago","America/New_York")
// Conversion du décalage en heure locale
set datetime = "20240102033045-0500"
set newDatetime = ##class(tz.Ens).TZLocal(datetime,"America/Chicago")
// Conversion vers un format alternatif au HL7
set datetime = "20240102033045-0500"
set newDatetime = ##class(tz.Ens).TZ(datetime,"America/Chicago",,"%m/%d/%Y %H:%M:%S %z")
Résumé
Je vous remercie de m'avoir suivi dans ce "voyage à travers le monde" où nous avons rencontré des fuseaux horaires, l'heure d'été, les cartes du monde et les "bombes à explosion retardée". J'espère que ce travail vous a permis d'éclairer (et de simplifier) les nombreuses complexités liées à l'utilisation des dates et des fuseaux horaires.
Consultez la bibliothèque tz - ObjectScript Time Zone Conversion Library et faites-moi savoir si vous avez des questions (ou des corrections/clarifications à propos de quelque chose que j'ai dit ici.
Merci!
Références / Liens intéressants
- https://en.wikipedia.org/wiki/Coordinated_Universal_Time
- https://en.wikipedia.org/wiki/Time_zone
- https://en.wikipedia.org/wiki/Daylight_saving_time
- https://www.worldtimeserver.com/learn/unusual-time-zones/
- https://www.worldtimeserver.com/learn/history-of-time-zones/
- https://www.worldtimeserver.com/learn/what-is-a-time-zone/
- https://en.wikipedia.org/wiki/Tz_database
- https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
- https://en.wikipedia.org/wiki/Internet_Assigned_Numbers_Authority
- https://www.iana.org/time-zones
- https://www.gnu.org/software/libc/manual/html_node/Calendar-Time.html