Posez votre question et obtenez un résumé du document en referencant cette page et le Provider AI de votre choix
Le contenu de cette page a été traduit à l'aide d'une IA.
Voir la dernière version du contenu original en anglaisSi vous avez une idée d’amélioration pour améliorer cette documentation, n’hésitez pas à contribuer en submitant une pull request sur GitHub.
Lien GitHub de la documentationCopier le Markdown du doc dans le presse-papiers
Formater les dates et les nombres par locale avec Intl
Traduire des chaînes n'est que la partie visible de l'i18n. La moitié qui génère des retours de bugs concerne le formatage : un utilisateur allemand qui voit 1,234.56 au lieu de 1.234,56, un utilisateur japonais qui voit 08/02/2026 et le lit comme le mois d'août, ou une date qui s'affiche différemment entre le serveur et le client, cassant la page lors de l'hydratation.
Rien de tout cela ne nécessite de bibliothèque externe. L'API Intl est disponible dans tous les runtimes modernes.
Table des matières
Commencez par supprimer vos helpers maison de date
Presque chaque projet possède une fonction formatDate écrite avant même que quiconque ne songe aux locales. Elle fige un ordre arbitraire, un séparateur et le plus souvent des noms de mois en anglais.
Copier le code dans le presse-papiers
Intl.DateTimeFormat la remplace avantageusement et gère parfaitement chaque locale :
Copier le code dans le presse-papiers
Le même constat s'applique aux nombres. toFixed(2) produit 1234.56 partout, ce qui est erroné dans la majeure partie de l'Europe.
Ce que couvre Intl
Ouvrir le tableau dans une fenêtre modale pour voir tout le contenu clairement
| API | Cas d'usage |
|---|---|
Intl.DateTimeFormat | Dates et heures, avec préréglages dateStyle / timeStyle |
Intl.NumberFormat | Décimaux, devises, pourcentages, unités, notation compacte |
Intl.RelativeTimeFormat | "il y a 3 jours", "dans 2 heures" |
Intl.ListFormat | "a, b et c" contre "a, b, and c" |
Intl.PluralRules | Catégorie plurielle dans laquelle se classe un nombre |
Intl.Collator | Tri linguistique correct des chaînes |
Intl.Collator est celui que l'on oublie fréquemment. array.sort() sur des chaînes utilise l'ordre des points de code Unicode, ce qui place les caractères accentués après z et classe le ö suédois au mauvais endroit. Si vous triez des listes destinées aux utilisateurs, triez avec un collator.
Copier le code dans le presse-papiers
Privilégiez les préréglages aux options manuelles
dateStyle et timeStyle laissent la locale décider de l'ordre logique et des séparateurs. Spécifier individuellement year, month et day vous donne un contrôle rarement souhaitable, car l'ordre correct diffère selon la région et vous risquez d'écraser les données CLDR avec vos propres hypothèses.
Copier le code dans le presse-papiers
N'utilisez des composants explicites que lorsque le design impose impérativement une largeur fixe, par exemple dans une colonne de tableau étroite.
Instancier les formateurs est coûteux
C'est le détail de performance qui change tout. Construire une instance de Intl.NumberFormat charge des données de locale volumineuses, et cette étape coûte bien plus cher que l'appel ultérieur à .format(). Le faire dans une boucle de rendu sur un millier de lignes crée un goulet d'étranglement évident.
Copier le code dans le presse-papiers
toLocaleDateString() et toLocaleString() souffrent du même travers caché : chaque invocation instancie un formateur. C'est tout à fait tolérable pour une valeur isolée, mais inadapté pour une liste.
Mettez-les en cache en combinant la locale et les options retenues :
Copier le code dans le presse-papiers
Le bug de fuseau horaire exclusif à la production
Ce problème a déjà coûté des après-midis entiers à de nombreuses équipes. Un serveur rend une date en SSR, le navigateur tente de l'hydrater, et React déclenche une erreur d'hydration mismatch car les deux ont généré un texte différent.
La cause est simple : Intl.DateTimeFormat se base sur le fuseau horaire ambiant de la machine lorsque vous n'en spécifiez aucun. Votre serveur de production tourne en UTC, alors que votre ordinateur portable de développement se trouve dans un autre fuseau horaire. L'anomalie est invisible en local et ne se produit qu'en production.
Copier le code dans le presse-papiers
Trois approches pragmatiques :
- Fixer un fuseau horaire côté serveur et le transmettre explicitement. Déterministe et rigoureux, mais tout le monde voit l'heure UTC.
- Rendre côté client uniquement, avec un placeholder stable lors de la passe serveur. Précis pour l'utilisateur, mais implique un léger saut visuel.
- Enregistrer le fuseau de l'utilisateur et le transmettre des deux côtés. Le rendu idéal, mais demande plus de tuyauterie.
Quelle que soit la solution retenue, spécifiez toujours timeZone explicitement pour toute date rendue à la fois côté serveur et côté client. Une date sans fuseau horaire explicite est une date à deux valeurs.
Une devise a besoin d'une devise, pas d'une locale
La locale et la devise sont deux concepts orthogonaux. fr-FR ne signifie pas euro : un utilisateur français peut tout à fait consulter une facture en dollars américains.
Copier le code dans le presse-papiers
La locale pilote les séparateurs, les regroupements de chiffres et l'emplacement du symbole. La devise provient de votre modèle de données. Déduire l'une de l'autre est une source d'erreurs comptables.
Notez également l'utilité de currencyDisplay. Dans une interface où cohabitent plusieurs devises portant le symbole dollar, l'option "code" élimine toute ambiguïté entre dollars américains, canadiens et australiens.
Le temps relatif est plus naturel que le temps absolu
Pour les événements récents, "il y a 2 heures" est bien plus lisible qu'un horodatage complet, et Intl.RelativeTimeFormat s'en charge nativement.
Copier le code dans le presse-papiers
numeric: "auto" permet d'obtenir "hier" au lieu de "il y a 1 jour". Sans cette option, vous n'obtiendrez que la forme numérique stricte, qui sonne très mécanique.
Ce qu'Intlayer apporte en complément
Intlayer englobe ces mécanismes dans des utilitaires pré-cachés afin que vous n'ayez pas à maintenir la Map de cache ci-dessus, et applique la locale active par défaut sans avoir à la transmettre à chaque appel.
Copier le code dans le presse-papiers
La fonction date() accepte également des préréglages ("short", "long", "dateOnly", "timeOnly", "full"), évitant d'avoir à manipuler un objet d'options pour les cas courants. Des équivalents React et Vue existent sous forme de hooks et de composables, résolvant la locale active directement depuis le contexte applicatif.
Il s'agit essentiellement d'une couche de mise en cache et d'injection de locale par défaut au-dessus de l'API standard. Le comportement de formatage reste celui d'Intl. Retrouvez les signatures complètes dans la documentation des formateurs.
Erreurs courantes
toLocaleDateString()sans locale spécifiée. Utilise la locale de la machine hôte, ce qui dépend entièrement de la configuration du conteneur sur un serveur.- Formater dans une boucle sans cache. L'instanciation du formateur absorbe l'essentiel du temps d'exécution.
- Oublier
timeZonesur les dates isomorphes. Erreur d'hydratation impossible à reproduire sur votre poste local. - Déduire la devise depuis la locale.
fr-FRne signifie pas automatiquement euros. sort()standard sur des textes affichés. Utilisez toujoursIntl.Collator.- Coder les noms de mois ou de jours en dur. Ils existent déjà dans le CLDR, pour chaque langue.
- Garder
numeric: "always"pour le temps relatif. Vous obtenez "il y a 1 jour" là où chaque langue possède un mot dédié pour hier.
Pour aller plus loin
- Formateurs et utilitaires de locale :
number,currency,date,relativeTime,list - Référence de configuration
- Rapports de benchmark entre frameworks
- Adaptateur de compatibilité react-intl
- Format de message ICU : pluriels, sélections et skeletons numériques
- Comment tester les traductions, formateurs et pluriels compris
- Ce que couvre réellement l'internationalisation
Commentaires
Aucun commentaire pour le moment. Soyez le premier à partager vos pensées.
