Introduction : pourquoi le temps est un casse-tête
\n\nQuiconque a déjà écrit du code en JavaScript a rencontré cette douleur. Vous affichez l'heure 12:00 à l'utilisateur, et il écrit : « Chez moi il est 14:00, tout est cassé ». Ou vous enregistrez une date dans la base de données, et au chargement, elle se décale d'une heure en arrière. Ça vous dit quelque chose ?
\n\nTravailler avec les fuseaux horaires en JavaScript est un sujet que de nombreux développeurs remettent à plus tard. Et c'est dommage. Parce que si vous ne comprenez pas cela tout de suite, vous devrez réécrire la moitié de l'application plus tard.
\n\nDans cet article, je vais vous expliquer comment travailler correctement avec les fuseaux horaires en JS, vous montrer des exemples de code réels et vous donner quelques astuces qui vous feront gagner des heures de débogage. C'est parti !
\n\nPourquoi JavaScript gère-t-il les dates de manière si étrange ?
\n\nCommençons par l'essentiel : l'objet Date en JavaScript n'est, pour le moins dire, pas un cadeau. Il stocke le temps en millisecondes depuis le 1er janvier 1970 UTC. Et tout irait bien, mais :
- \n
getMonth()renvoie les mois de 0 à 11 (janvier est 0, décembre est 11) \n - Les méthodes
getHours(),getMinutes()renvoient l'heure dans le fuseau horaire local de l'utilisateur \n - Et les méthodes
getUTCHours(),getUTCMinutes()renvoient l'heure en UTC \n
Et c'est là que la confusion commence. Supposons que vous écriviez :
\n\nconst now = new Date();\nconsole.log(now.getHours()); // 14 — si vous êtes en MSK\nconsole.log(now.getUTCHours()); // 11 — UTC\n\nSi vous enregistrez now dans la base de données, puis le récupérez sur un serveur dans un autre fuseau horaire, vous obtiendrez un mélange. Par conséquent, la première règle pour travailler avec les dates et fuseaux horaires en JavaScript est de toujours stocker l'heure en UTC et de convertir côté client.
Intl.DateTimeFormat : le sauveur intégré
\n\nBeaucoup ne le savent pas, mais le JavaScript moderne dispose d'une API intégrée puissante pour travailler avec le formatage des dates en tenant compte du fuseau horaire. Il s'agit de Intl.DateTimeFormat. Il prend en charge tous les principaux fuseaux horaires et sait formater les dates de manière élégante.
Exemple de base
\n\nconst date = new Date('2025-03-15T12:00:00Z');\n\nconst formatter = new Intl.DateTimeFormat('fr-FR', {\n timeZone: 'America/New_York',\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit'\n});\n\nconsole.log(formatter.format(date)); \n// "15 mars 2025, 08:00" — heure à New York\n\nNotez que nous passons la date en UTC (lettre Z à la fin), et Intl.DateTimeFormat la convertit lui-même dans le fuseau horaire souhaité. C'est idéal pour afficher l'heure aux utilisateurs de différentes régions.
Liste de tous les fuseaux horaires
\n\nSi vous ne savez pas quel fuseau horaire spécifier, vous pouvez obtenir la liste complète :
\n\nconsole.log(Intl.supportedValuesOf('timeZone'));\n// ["Africa/Abidjan", "Africa/Accra", ..., "Pacific/Wallis"]\n\nCette liste comprend plus de 500 fuseaux horaires. Utilisez-la pour vous assurer que votre fuseau horaire est pris en charge.
\n\nMoment.js : un classique, mais avec des réserves
\n\nPendant longtemps, moment.js a été la norme pour travailler avec les dates en JavaScript. Il sait analyser, formater, manipuler les dates et, bien sûr, travailler avec les fuseaux horaires via le plugin moment-timezone.
Installation
\n\nnpm install moment moment-timezone\n\nExemple avec les fuseaux horaires
\n\nconst moment = require('moment-timezone');\n\nconst now = moment();\nconsole.log(now.tz('Europe/Moscow').format('YYYY-MM-DD HH:mm'));\n// 2025-03-15 14:00 — heure de Moscou\n\nconst nyTime = moment.tz('2025-03-15 12:00', 'America/New_York');\nconsole.log(nyTime.clone().tz('Europe/Moscow').format('YYYY-MM-DD HH:mm'));\n// 2025-03-15 19:00 — différence de 7 heures\n\nImportant : moment.js est une bibliothèque legacy. Les auteurs eux-mêmes recommandent de passer