Les temps relatifs avec Intl.RelativeTimeFormat()
Introduite dans Chrome 71, la classe Intl.RelativeTimeFormat
propose un formateur de temps relatif (il y a X secondes, dans X minutes, hier, maintenant…). Offrant un texte plus convivial, cette mécanique fut utilisée et popularisée par Facebook dans les commentaires et publications de ses utilisateurs. Jusqu’ici, il était nécessaire d’utiliser des librairies tierces comme Moment.js ou date-fns, impactant le poids de notre page.
Utilisation par défaut
Pour utiliser Intl.RelativeTimeFormat
, on débute par créer une nouvelle instance de la classe en indiquant la langue (ou la locale) voulue : fr
pour le français, en
pour l’anglais, es
pour l’espagnol etc…
const rtf = new Intl.RelativeTimeFormat("fr");
Nous pouvons ensuite utilisé la méthode format
en indiquant la valeur numérique et l’unité de temps parmi second
, minut
, hour
, day
, week
,month
, quarter
ou year
Nous obtenons donc :
const rtf = new Intl.RelativeTimeFormat("fr");
rtf.format(0, "second"); // "dans 0 seconde"
rtf.format(-0, "second"); // "il y a 0 seconde"
rtf.format(-2, "hour"); // "il y a 2 heures"
rtf.format(-1, "day"); // "il y a 1 jour"
rtf.format(1, "day"); // "dans 1 jour"
rtf.format(2, "week"); // "dans 2 semaines"
rtf.format(-3, "month"); // "il y a 3 mois"
rtf.format(1, "quarter"); // "dans 1 trimestre"
rtf.format(1, "year"); // "dans 1 an"
rtf.format(-1, "year"); // "il y a 1 an"
Comme on peut le remarquer le texte alterne entre ‘il y a’ et ‘dans’ en fonction du caractère négatif ou positif de la valeur numérique en entrée. Toutefois, le rendu s’avère très générique et peu convivial au final… Peut-on mieux faire ? Absolument !
Personnalisation du formatage
La classe Intl.RelativeTimeFormat
accueille un second paramètre dans son constructeur sous forme d’un objet JavaScript: il s’agit d’options de personnalisation. Attardons-nous sur deux d’entre elles.
1- L’option numeric
L’option numeric
accepte deux valeurs : always
(par défaut) et auto
. Elle permet de modifier les conditions d’affichage du nombre en entrée. L’option par défaut, always
, force l’apparition de la valeur numérique et c’est pour cette raison que nos exemples précédents alternent seulement entre ‘il y a’ et ‘dans’. En utilisant auto
, nous obtenons un formatage plus convivial et comparable à celui de Facebook :
const rtf = new Intl.RelativeTimeFormat("fr", { numeric: "auto" });
rtf.format(0, "second"); // "maintenant"
rtf.format(-0, "second"); // "maintenant"
rtf.format(-2, "hour"); // "il y a 2 heures"
rtf.format(-2, "hour"); // "hier"
rtf.format(1, "day"); // "demain"
rtf.format(2, "week"); // "dans 2 semaines"
rtf.format(-3, "month"); // "il y a 3 mois"
rtf.format(1, "quarter"); // "le trimestre prochain"
rtf.format(1, "year"); // "l’année prochaine"
rtf.format(-1, "year"); // "l’année dernière"
Le verdict reste sans appel : les textes se veulent plus sympathiques qu’auparavant ! D’ailleurs, j’ignore la raison pour laquelle auto
n’est pas la valeur par défaut…
2 - L’option style
L’option style
impacte la longueur globale de la phrase. Par défaut, long
renvoie le texte sans effort de raccourcissement. Les deux autres possibilités short
et narrow
abrègent le rendu, à des échelles variables :
const rtf = new Intl.RelativeTimeFormat("fr", { style: "short" });
rtf.format(0, "second"); // "dans 0 s"
rtf.format(-0, "second"); // "il y a 0 s"
rtf.format(-2, "hour"); // "il y a 2 h"
rtf.format(-2, "hour"); // "il y a 2 h"
rtf.format(1, "day"); // "dans 1 j"
rtf.format(2, "week"); // "dans 2 sem."
rtf.format(2, "week"); // "dans 2 sem."
rtf.format(2, "minute"); // "dans 2 min"
rtf.format(-3, "month"); // "il y a 3 m."
rtf.format(1, "quarter"); // "dans 1 trim."
rtf.format(1, "year"); // "dans 1 a"
rtf.format(-1, "year"); // "il y a 1 a"
const rtf2 = new Intl.RelativeTimeFormat("fr", { style: "narrow" });
rtf2.format(0, "second"); // "+0 s"
rtf2.format(-0, "second"); // "-0 s"
rtf2.format(-2, "hour"); // "-2 h"
rtf2.format(-2, "hour"); // "-2 h"
rtf2.format(1, "day"); // "+1 j"
rtf2.format(2, "week"); // "+2 sem."
rtf2.format(2, "week"); // "+2 sem."
rtf2.format(2, "minute"); // "+2 min"
rtf2.format(-3, "month"); // "-3 m."
rtf2.format(1, "quarter"); // "+1 trim."
rtf2.format(1, "year"); // "+1 a"
rtf2.format(-1, "year"); // "-1 a"
Quid de la compatibilité…
Comme toutes nouvelles fonctionnalités, la question de sa compatibilité se pose. Cette dernière n’est pas encore totale et il faudra certainement attendre quelques mois/années pour une prise en charge totale :
Supportés : Chrome - Firefox et Opéra. Non supportés: Edge, Internet Explorer et Safari
Conclusion
Bien qu’encore mal supporté Intl.RelativeTimeFormat
reste prometteur pour créer des dates relatives sans librairie tierce.
On peut toutefois regretter que cette classe ne propose pas de mise à jour automatique du texte en fonction d’une date en entrée, un comportement qu’il nous faudra recréer soi-même pour le moment. Espérons toutefois que cette modification viendra un jour !
Pour aller plus loin :
https://developers.google.com/web/updates/2018/10/intl-relativetimeformat