Retour à l'accueil

Analyseur de dates JavaScript : Erreurs cachées et corrections

L’article analyse le comportement inattendu du constructeur Date en JavaScript, qui parse des dates à partir de n’importe quel texte. Décrit l’algorithme V8, les problèmes de fuseau horaire et les recommandations pour un parsing sûr en production.

Pourquoi JS transforme du texte en dates : Analyse de l’analyseur V8
Advertisement 728x90

Le parseur de dates JavaScript dangereux : comment éviter les pièges

Le constructeur new Date(string) en JavaScript tente d'extraire une date à partir de n'importe quelle chaîne, souvent avec des résultats inattendus. Ce n'est pas une erreur — c'est une fonctionnalité des moteurs V8 et SpiderMonkey, où le parseur interprète agressivement le texte.

Des exemples illustrent bien le problème :

new Date("2020-01-23")
// Wed Jan 22 2020 19:00:00 GMT-0500 (interprété comme UTC)

new Date("Today is 2020-01-23")
// Thu Jan 23 2020 00:00:00 GMT-0500 (heure locale)

new Date("Route 66")
// Sat Jan 01 1966 00:00:00 GMT-0500

new Date("Beverly Hills, 90210")
// Mon Jan 01 90210 00:00:00 GMT-0500

Ces conversions produisent des objets Date valides mais aux valeurs erronées — ce qui rend le débogage compliqué. Le cas « Catch 22 » retourne Invalid Date, rare mais en réalité correct.

Google AdInline article slot

Comment fonctionne le parseur V8

La spécification ECMAScript impose un parsing uniquement pour une sous-ensemble de l'ISO 8601. Tout le reste dépend de l'implémentation.

Algorithme de V8 :

  • Vérifier si la chaîne suit l'ISO 8601 : doit commencer par une année à quatre chiffres ou un signe.
  • Recourir au parseur hérité : ignorer les mots jusqu'à trouver le premier nombre.
  • Traiter les nombres dans DayComposer :

- 1–12 : interprétés comme mois.

Google AdInline article slot

- 13–31 : ambigus, souvent rejetés.

- 32+ : traités comme année (50–99 +1900).

- Valeur par défaut : 1er janvier.

Google AdInline article slot

Cela explique pourquoi "Route 66" devient 1966 et "90210" devient l'année 90210.

Confusion liée aux fuseaux horaires

Les chaînes ISO comme "2020-01-23" sont analysées en UTC, tandis que les formats anciens utilisent l'heure locale. La différence provient des préfixes :

  • Chaîne pure ISO : analysée en UTC.
  • Chaînes contenant du texte : mode hérité, heure locale.

Les espaces avant ou après changent le comportement du parseur, pouvant décaler les résultats d'un jour selon le fuseau horaire.

Safari (JavaScriptCore) est plus strict : il rejette les exemples hérités et les chaînes avec espaces en fin.

Bugs réels et solutions

Dans des projets concrets, revenir à new Date() pour l’entrée utilisateur peut transformer "Route 66" en date, corrompant les tables de données. Solution : se fier uniquement à des parseurs personnalisés avec validation regex.

Bonnes pratiques pour développeurs confirmés :

  • Valider le format avec regex avant d’appeler new Date().
  • Utiliser date-fns parseISO() pour un parsing stricte de l’ISO.
  • Pour un contrôle total, utiliser des bibliothèques comme Luxon ou Day.js avec parseurs sur mesure.
  • Jamais utiliser new Date(string) avec une entrée non fiable.
  • Tester sur plusieurs navigateurs : V8, SpiderMonkey, JSC.

JavaScript vs Python : une comparaison

Python évite toute ambiguïté :

  • datetime.fromisoformat(): accepte uniquement l’ISO 8601.
  • strptime(): format strict, aucun caractère superflu autorisé.

Le parseur JavaScript hérité devine silencieusement ; Python lance une ValueError.

Points clés

  • Le parseur Date crée des objets valides mais incorrects à partir de textes aléatoires.
  • Le comportement du parseur (ISO vs hérité) dépend des préfixes et des espaces.
  • En production : valider toujours l’entrée avant le parsing.
  • Migration vers l’API Temporal pour un code pérenne.
  • Le test multi-navigateur est essentiel en raison des différences entre moteurs.

— Editorial Team

Advertisement 728x90

Lire ensuite