6 points par GN⁺ 2026-01-13 | 1 commentaires | Partager sur WhatsApp
  • L’objet Date existant de JavaScript est critiqué pour son caractère incomplet et incohérent, et l’API Temporal est présentée comme son remplaçant
  • Date fonctionne comme un objet mutable, en décalage avec le concept réel de date, et souffre de problèmes structurels comme des erreurs de parsing et des limites dans la gestion des fuseaux horaires
  • Temporal fournit un nouveau modèle de gestion des dates et heures fondé sur l’immuabilité, avec des classes détaillées comme PlainDate, ZonedDateTime, Duration
  • Les méthodes de Temporal ne modifient pas l’objet existant mais renvoient un nouvel objet, permettant un chaînage d’opérations clair et sûr
  • Temporal est actuellement au stade 3 de standardisation (Stage 3) et bénéficie d’une prise en charge expérimentale dans les navigateurs récents comme Chrome et Firefox

Problèmes de l’objet Date de JavaScript

  • Le constructeur Date provoque de la confusion avec des règles de parsing incohérentes et une indexation peu intuitive
    • Exemple : le mois (month) commence à 0, tandis que le jour (day) et l’année (year) commencent à 1
    • Les chaînes "99" et "100" sont interprétées respectivement comme 1999 et 0100, ce qui illustre le manque de cohérence
  • Date a été conçu autour du temps et stocke en interne un timestamp Unix (en millisecondes)
  • La prise en charge des fuseaux horaires est limitée, et l’objet ne comprend ni l’heure d’été (DST) ni les calendriers non grégoriens
  • En raison de ces limites, il est courant de dépendre de grandes bibliothèques tierces comme Moment.js ou date-fns, ce qui entraîne une baisse des performances

Conflit entre immuabilité et notion de référence

  • En JavaScript, les valeurs primitives sont immuables et stockées par valeur, tandis que les objets sont stockés par référence et peuvent être modifiés
  • Date est un objet créé via un constructeur, il est donc mutable
    • Exemple : quand on appelle setMonth() ou setDate(), l’objet d’origine est directement modifié
  • Cela entraîne des changements de valeur inattendus entre des variables qui référencent le même objet
    • Exemple : si une fonction reçoit today en argument et modifie la date en interne, l’objet today d’origine est lui aussi modifié
    Publicité

Temporal : une nouvelle API de date et d’heure

  • Temporal n’est pas un constructeur mais un objet d’espace de noms, de structure similaire à Math
    • Principaux composants : PlainDate, PlainDateTime, PlainTime, ZonedDateTime, Duration, Now, etc.
  • Temporal.Now renvoie le moment présent sous différentes formes
    • plainDateISO() → date au format ISO
    • zonedDateTimeISO() → date et heure avec fuseau horaire
  • Les objets Temporal fournissent un ensemble de méthodes explicites
    • add({ days: 1 }), subtract({ years: 2 }), etc. permettent d’effectuer des opérations explicites par unité
    • Au lieu de modifier l’objet existant, ils renvoient un nouvel objet, préservant ainsi l’immuabilité
Publicité

Fonctionnement et avantages de Temporal

  • Les objets Temporal restent des objets, mais suivent un schéma d’utilisation intentionnellement immuable
    • Exemple : today.add({ days: 1 }) renvoie un nouvel objet date, tandis que today reste inchangé
  • Temporal offre une syntaxe plus concise et plus claire que Date
    • Exemple :
      const today = Temporal.Now.plainDateISO();  
      console.log(`Tomorrow will be ${ today.add({ days: 1 }) }. Today is ${ today }.`);  
      // 결과: Tomorrow will be 2026-01-01. Today is 2025-12-31.  
      
  • Il répond aux besoins modernes comme la définition des fuseaux horaires, le calcul de durées et le maintien du format ISO
  • Grâce au chaînage de méthodes comme add, subtract, since et until, il devient possible d’exprimer simplement des calculs de date complexes

État de la standardisation et perspectives

  • Temporal a atteint le stade 3 (Stage 3) de la proposition ECMAScript, un niveau où l’implémentation par les navigateurs est recommandée
  • Une prise en charge expérimentale a déjà commencé dans Chrome et Firefox, et d’autres navigateurs devraient suivre
  • Les développeurs peuvent dès maintenant participer à l’amélioration de la spécification en testant l’API et en faisant des retours
  • Date continuera d’exister, mais à l’avenir, Temporal devrait devenir la méthode par défaut pour gérer les dates
  • L’article se conclut en disant qu’« il aurait fallu le remplacer en 1995, mais même maintenant, Temporal.Now arrive au moment idéal »

1 commentaires

 
GN⁺ 2026-01-13
Réactions sur Hacker News
  • Cet article traite des nombreux comportements aberrants du constructeur Date de JavaScript
    En particulier, il explique le problème où le format 'YYYY-MM-DD' est interprété comme minuit UTC, ce qui décale la date d’un jour dans les fuseaux horaires locaux
    À l’origine, dans l’ISO 8601, si aucun fuseau horaire n’est précisé, cela devrait être interprété comme l’heure locale, mais lors de la rédaction de la spec ES5, une erreur a conduit à le traiter comme "Z" (UTC)
    Une correction a ensuite été envisagée dans ES2015, mais comme d’innombrables sites web dépendaient déjà de ce comportement erroné, elle a été annulée pour des raisons de compatibilité web
    Voir la section Broken Parser pour plus de détails

    • On aurait aimé un directive 'strict datetime', à l’image de 'use strict'
      Cela aurait permis d’appliquer sélectivement un comportement correct sans introduire d’incompatibilités avec le code existant
      Ou bien un mécanisme du type import Date from 'browser:date', permettant de charger via un module interne un objet global corrigé
    • Moi aussi, autrefois, je découpais moi-même les chaînes pour créer des objets date sans fuseau horaire
      Pour quelque chose comme un anniversaire, qui ne représente qu’une date, il est absurde que le fuseau horaire la modifie
      Je me souviens qu’Outlook stockait les anniversaires avec un fuseau horaire, ce qui les faisait glisser d’un jour à chaque changement de pays
    • L’expression « sacrifié sur l’autel de la compatibilité web » est marquante
      Mais y avait-il vraiment une alternative ? Forcer des branches selon la version du navigateur, comme à l’époque d’IE5, aurait sans doute été pire
    • Le site jsdate.wtf permet d’expérimenter directement les comportements étranges de JS Date
    • Quand on pense à quel point ces problèmes sont à l’origine d’innombrables petits bugs, c’est à la fois drôle et triste
  • J’envie vraiment la gestion du temps dans Rails et Ruby
    Une API comme Time.current.in_time_zone('America/Los_Angeles') + 3.days - 4.months + 1.hour est intuitive et puissante
    Ruby surcharge les objets Time en un seul objet cohérent, ce qui évite presque totalement les soucis de conversion ou de casting
    En JS aussi, ce serait formidable de pouvoir écrire simplement quelque chose comme new Date().add({ days: 1 })

    • Cela dit, certains s’interrogent sur la qualité d’une syntaxe comme 3.days - 4.months + 1.hour
      Et il reste permis de débattre de l’intérêt de surcharger la bibliothèque standard de cette manière
  • C’est dommage que Safari ne prenne toujours pas en charge l’API Temporal
    Espérons que ce sera le cas l’année prochaine

  • Date a beaucoup de problèmes en JavaScript, mais je ne pense pas que le fait que ce soit un objet soit en soi le vrai souci
    Il aurait mieux valu qu’il soit immuable, mais qu’un objet mutable soit modifié n’a rien de surprenant

    • Le vrai problème, c’est qu’un autre morceau de code peut modifier implicitement l’objet Date que je détiens
      Le véritable danger de la mutabilité vient des modifications non locales, pas des modifications locales
  • Il est gênant que l’API Temporal ne gère absolument pas les informations de seconde intercalaire (leap second)
    J’aimerais créer un outil JS pour des calculs astronomiques, et il faut des données de secondes intercalaires pour les conversions UTC
    Il existe des contournements comme temporal-tai, mais cela oblige à maintenir côté client un fichier de secondes intercalaires, ce qui est pénible
    À cause de la SOP (politique CORS), on ne peut pas non plus récupérer directement ce fichier depuis un site externe
    Les navigateurs se mettent pourtant à jour régulièrement, alors pourquoi n’intègrent-ils pas ces informations ?

    • Dire que la SOP bloque les fichiers de secondes intercalaires est une confusion
      Si le serveur définit l’en-tête Access-Control-Allow-Origin ou les fournit sous forme de fichier JS, c’est possible
      En revanche, inclure et maintenir nativement ces données dans le navigateur peut représenter un coût important
    • Dire que l’API « ne gère que l’UTC » n’est pas exact
      L’UTC inclut par définition les secondes intercalaires, donc en réalité, il serait plus juste de dire qu’elle ne gère que le temps POSIX
  • Dans l’exemple de code, il faudrait dire qu’on bascule vers les années 1900 à partir de "50", et non "33" — simple signalement de coquille

  • J’utilise le polyfill Temporal et jusqu’ici j’en suis très satisfait

    • En revanche, avec 51 KB, ce n’est pas particulièrement léger (lien bundlephobia)
      C’est acceptable côté serveur ou dans de grosses applications, mais cela peut peser pour les petites apps
    • Quelqu’un se demande aussi comment il se compare à moment ou luxon
  • Il est étrange que l’article ne mentionne jamais Date.now()
    Pour comparer avec Temporal, il aurait fallu partir de Date.now() comme référence
    Cette fonction renvoie le nombre de millisecondes écoulées depuis le 1er janvier 1970
    Temporal offre certes une API plus agréable, mais au fond, le but reste d’exprimer une distance relative dans le temps

    • Mais les bugs liés aux timestamps évoqués dans l’article existent aussi
      Dans ce cas, comment convertir directement vers le format voulu sans passer par Date ?
  • Petite correction, mais importante : on dit non pas “daylight savings time”, mais “daylight saving time”

  • Je n’avais jamais réalisé à quel point JS Date était bancal

    • Ce qui est encore plus regrettable, c’est que ces problèmes étaient déjà clairement visibles dès 1995
      Avec un peu plus de prudence à l’époque, d’innombrables développeurs auraient pu éviter tous ces pièges