16 points par GN⁺ 2024-08-25 | 5 commentaires | Partager sur WhatsApp
  • Parmi les évolutions récentes d’ECMAScript, la plus remarquable est la proposition Temporal
    • Cette API peut déjà être utilisée via le polyfill fourni par l’équipe de FullCalendar
    • L’un de ses principaux avantages est qu’il existe enfin un objet natif pour représenter un "Zoned Date Time"

Qu’est-ce qu’un Zoned Date Time ?

  • Lorsqu’on manipule des dates humaines, on omet généralement le fuseau horaire et on parle simplement de date et d’heure
  • Mais l’objet Date de JavaScript ne manipule que des nombres, ce qui fait perdre le sens original de la date
  • Par exemple, pour enregistrer le moment d’un paiement par carte, beaucoup de personnes pourraient utiliser un code comme celui-ci
    const paymentDate = new Date('2024-07-20T10:30:00');  
    
  • Le navigateur calcule alors les millisecondes en fonction du fuseau horaire de l’utilisateur (CET). Mais l’information stockée peut être interprétée différemment selon le fuseau horaire
  • En JavaScript, les dates ne reposent pas sur UTC mais sur POSIX, où les secondes intercalaires sont totalement ignorées. Au-delà de ce point très important, le problème est aussi que, lorsqu’il ne reste qu’un nombre, le sens initial de la date disparaît
  • Beaucoup pensent qu’il est sûr de travailler en UTC ou de transmettre les dates au format ISO, mais ce n’est pas exact, car des informations peuvent encore être perdues

UTC ne suffit pas

  • Même en travaillant au format ISO, il manque toujours des informations de fuseau horaire au moment d’afficher la date
  • Une fonction qui convertit un timestamp en date lisible par un humain n’est pas injective
  • Par exemple, après un voyage de Madrid à Sydney puis le retour, des problèmes de fuseau horaire dans l’historique bancaire peuvent devenir source de confusion

Introduction à l’API Temporal

  • L’API Temporal introduit l’objet Temporal.ZonedDateTime, qui représente une date et une heure avec fuseau horaire
  • Elle propose une extension de la RFC 3339 afin de définir un standard pour sérialiser et désérialiser les dates sous forme de chaîne
  • 1996-12-19T16:39:57-08:00[America/Los_Angeles]
    • Cette chaîne représente le 19 décembre 1996 à 16 h 39 min 57 s
    • L’offset est de -08:00 par rapport à UTC (heure normale du Pacifique, PST, à laquelle appartient Los Angeles)
    • Le fuseau horaire standard correspondant ("heure normale du Pacifique") est également indiqué afin que les applications conscientes des fuseaux horaires puissent en tenir compte
  • Elle prend en charge divers systèmes de calendrier (par ex. bouddhiste, chinois, Dangi, grégorien, islamique, persan, japonais, etc.)

Opérations de base

Création de dates
  • L’API Temporal fournit des outils puissants pour gérer les fuseaux horaires
  • Par exemple, lors de la création d’un objet Temporal.ZonedDateTime, elle garantit que le fuseau horaire est correctement pris en compte :
    const zonedDateTime = Temporal.ZonedDateTime.from({  year: 2024,  month: 8,  day: 16,  hour: 12,  minute: 30,  second: 0,  timeZone: 'Europe/Madrid'});  
    
  • Cela permet de conserver une heure exacte même en cas de changement de fuseau ou d’ajustements d’heure locale comme le DST
Comparaison de dates
  • Les objets ZonedDateTime fournissent la méthode compare, qui permet de comparer deux ZonedDateTime :
    const one = Temporal.ZonedDateTime.from('2020-11-01T01:45-07:00[America/Los_Angeles]');  
    const two = Temporal.ZonedDateTime.from('2020-11-01T01:15-08:00[America/Los_Angeles]');  
    Temporal.ZonedDateTime.compare(one, two);  // => -1  
    
Fonctions intégrées utiles
  • La propriété hoursInDay renvoie le nombre réel d’heures dans cette journée :
    Temporal.ZonedDateTime.from('2020-03-08T12:00-07:00[America/Los_Angeles]').hoursInDay;  // => 23  (jour de début du DST)  
    
Conversion de fuseau horaire
  • La méthode withTimeZone permet de changer le fuseau horaire d’un ZonedDateTime :
    zdt = Temporal.ZonedDateTime.from('1995-12-07T03:24:30+09:00[Asia/Tokyo]');  
    zdt.withTimeZone('Africa/Accra').toString(); // => '1995-12-06T18:24:30+00:00[Africa/Accra]'  
    
Opérations arithmétiques de base
  • La méthode .add permet d’ajouter ou de soustraire des dates en respectant les règles du DST :
    zdt = Temporal.ZonedDateTime.from('2020-03-08T00:00-08:00[America/Los_Angeles]');  
    laterDay = zdt.add({ days: 1 });  // => 2020-03-09T00:00:00-07:00[America/Los_Angeles]  
    
Calculer la différence entre des dates
  • La méthode .until calcule la différence entre deux instants et renvoie un objet Temporal.Duration
    • Par exemple, elle peut être utilisée comme zdt.until(other)

Conclusion

  • L’API Temporal transforme en profondeur la manière de gérer le temps en JavaScript
  • Cet article a abordé la différence entre les dates lisibles par un humain et les dates UTC, ainsi que la manière de les représenter correctement avec l’objet Temporal.ZonedDateTime
  • Le prochain article explorera d’autres objets intéressants comme Instant, PlainDate et Duration

L’avis de GN⁺

  • Le problème de la gestion des dates et heures, qui compliquait la vie des développeurs JavaScript depuis longtemps, devrait être résolu avec l’API Temporal
  • Comme elle peut gérer automatiquement les fuseaux horaires et les problèmes liés au DST, elle sera très utile pour développer des applications globales
  • La compatibilité avec l’objet Date existant et les questions de migration restent des points à prendre en compte
  • L’API Temporal est conçue de manière claire et intuitive, et elle est également excellente du point de vue de l’internationalisation, notamment grâce à la prise en charge de divers systèmes de calendrier
  • On peut s’attendre à ce que ces changements améliorent fortement la productivité des développeurs JavaScript

5 commentaires

 
kyc1682 2024-08-26

Enfin !

 
hongminhee 2024-08-26
 
huiya 2024-08-26

Énorme. Quand je concevais des services globaux, les dates me donnaient toujours mal à la tête.
J’aimerais bien essayer ça une fois.

 
jjpark78 2024-08-26

Vraiment, est-ce qu’on va enfin pouvoir se passer de moment ou de dayjs ?

 
GN⁺ 2024-08-25
Avis Hacker News
  • En Javascript, gérer les dates et les heures est très difficile

    • La bibliothèque Moment confond les dates et les heures, ce qui provoque beaucoup de problèmes
    • La bibliothèque Arrow de Python commet la même erreur
    • La bibliothèque Chrono de Rust est prévisible et comporte moins de défauts
    • Date de JS et Moment sont difficiles à utiliser
  • On espère que la nouvelle API résoudra les problèmes de fuseaux horaires en JS

    • Il y a un problème où certains fuseaux horaires sont analysés correctement, mais dans d'autres cas ils sont supposés être en UTC
    • J'ai eu beaucoup de mal avec ce problème dans mon ancien travail
  • Une fonction qui convertit un timestamp en date lisible par un humain n'est pas injective

    • Il y a une confusion entre les notions d'injectivité et de well-definedness
    • Pour un timestamp t, il n'existe pas de date lisible par un humain x unique
  • Une blague sur la courbe de difficulté du traitement du temps

    • Les débutants n'utilisent que des timestamps UTC
    • Les intermédiaires affirment qu'il faut stocker et convertir les fuseaux horaires
    • Les experts reviennent à n'utiliser que des timestamps UTC
  • Utiliser davantage d'exemples de dates futures rendrait l'article plus convaincant

    • Lorsqu'on enregistre un timestamp, on n'a besoin que de l'UTC et de l'emplacement
    • L'exemple bancaire n'est qu'un problème d'UX, pas une perte d'information
  • Un utilisateur se dit anxieux parce qu'il ne comprend pas le traitement du temps

    • Il demande une bonne introduction pour comprendre les problèmes de gestion du temps dans des langages comme Python
  • Avoir un bon standard datetime représente la moitié de la bataille

    • L'autre moitié, c'est son adoption à grande échelle
    • Pour la compatibilité avec d'autres systèmes, il est plus sûr de convertir en chaîne ISO ou en timestamp Unix
  • Une chaîne de date ISO doit capturer des informations précises

    • L'idée que JavaScript ou d'autres langages aient besoin d'une structure intégrée est remise en question
    • Temporal et Date résolvent des problèmes simples de manière compliquée
  • Question sur la manière de gérer ce problème dans Postgres

  • Il manque des preuves que Temporal sera réellement adopté

    • Comme beaucoup d'autres propositions JS prometteuses, cela fait longtemps que le sujet est seulement discuté