Comment formater des plages comme 3-5 ou 100-200
Utilisez JavaScript pour afficher des plages de nombres avec un formatage adapté à la locale
Introduction
Les plages de nombres apparaissent partout dans les interfaces utilisateur. Les plages de prix s'affichent sous la forme 100-200 $, les numéros de page sous la forme 1-10, et les estimations de quantité sous la forme 3-5 articles. Ces plages communiquent qu'une valeur se situe entre deux extrémités, fournissant aux utilisateurs une information bornée plutôt qu'un seul nombre précis.
Lorsque vous codez en dur le séparateur entre les valeurs de plage, vous supposez que tous les utilisateurs suivent les mêmes conventions typographiques. Les anglophones utilisent généralement des traits d'union ou des tirets demi-cadratin pour les plages, mais d'autres langues utilisent des symboles ou des mots différents. L'allemand utilise "bis" entre les nombres, tandis que certaines langues placent des espaces autour des séparateurs.
JavaScript fournit la méthode formatRange() sur Intl.NumberFormat pour gérer automatiquement le formatage des plages. Cette méthode applique des conventions spécifiques à la locale à la fois aux nombres et au séparateur, garantissant que les plages s'affichent correctement pour les utilisateurs du monde entier.
Pourquoi les plages de nombres nécessitent un formatage spécifique à la locale
Différentes cultures ont développé différentes conventions pour exprimer les plages. Ces conventions impliquent à la fois le symbole séparateur et l'espacement autour de celui-ci.
En anglais américain, les plages utilisent généralement un tiret demi-cadratin sans espaces : 3-5, 100-200. Dans certains guides de style, des espaces apparaissent autour du tiret : 3 - 5. La convention exacte varie selon le contexte et les normes de publication.
En allemand, les plages utilisent souvent "bis" comme séparateur : 3 bis 5, 100 bis 200. Cette approche basée sur un mot rend la relation de plage explicite plutôt que de s'appuyer sur la ponctuation.
En espagnol, les plages peuvent utiliser un tiret comme en anglais ou le mot "a" : 3-5 ou 3 a 5. Le choix dépend de la région hispanophone spécifique et du contexte.
Lors du formatage de plages incluant des devises ou des unités, la complexité augmente. Une plage de prix peut s'afficher comme $100-$200 en anglais américain, mais comme 100 €-200 € en allemand, ou 100-200 € avec le symbole apparaissant une seule fois. Différentes locales placent les symboles de devise différemment et gèrent la répétition différemment.
Le formatage manuel de plages nécessite de connaître ces conventions et d'implémenter une logique spécifique à chaque locale. L'API Intl encapsule ces connaissances, en appliquant le formatage approprié en fonction de la locale.
Utiliser formatRange pour formater des plages de nombres
La méthode formatRange() accepte deux nombres et renvoie une chaîne formatée représentant la plage. Créez une instance Intl.NumberFormat avec la locale et les options souhaitées, puis appelez formatRange() avec les valeurs de début et de fin.
const formatter = new Intl.NumberFormat("en-US");
console.log(formatter.formatRange(3, 5));
// Output: "3–5"
console.log(formatter.formatRange(100, 200));
// Output: "100–200"
console.log(formatter.formatRange(1000, 5000));
// Output: "1,000–5,000"
Le formateur applique des séparateurs de milliers aux deux nombres de la plage et utilise un séparateur approprié entre eux. Pour l'anglais américain, il s'agit d'un tiret demi-cadratin sans espaces.
Vous pouvez formater la même plage pour différentes locales en modifiant l'identifiant de locale.
const usFormatter = new Intl.NumberFormat("en-US");
console.log(usFormatter.formatRange(100, 200));
// Output: "100–200"
const deFormatter = new Intl.NumberFormat("de-DE");
console.log(deFormatter.formatRange(100, 200));
// Output: "100–200"
const esFormatter = new Intl.NumberFormat("es-ES");
console.log(esFormatter.formatRange(100, 200));
// Output: "100-200"
Chaque locale applique ses propres conventions pour le séparateur et l'espacement. L'API gère ces détails automatiquement en fonction des normes typographiques de la locale.
Formater des plages de devises
Le formatage de plages fonctionne avec toutes les options de formatage de nombres, y compris les devises. Lorsque vous formatez des plages de devises, le formateur gère à la fois le placement du symbole de devise et le séparateur de plage.
const formatter = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0
});
console.log(formatter.formatRange(100, 200));
// Output: "$100 – $200"
console.log(formatter.formatRange(1000, 5000));
// Output: "$1,000 – $5,000"
Le formateur place le symbole de devise avant chaque nombre de la plage. Cela indique clairement que les deux valeurs représentent des montants en devise.
Différentes locales placent les symboles de devise différemment.
const usFormatter = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0
});
console.log(usFormatter.formatRange(100, 200));
// Output: "$100 – $200"
const deFormatter = new Intl.NumberFormat("de-DE", {
style: "currency",
currency: "EUR",
maximumFractionDigits: 0
});
console.log(deFormatter.formatRange(100, 200));
// Output: "100–200 €"
Le formateur allemand place le symbole euro après la plage plutôt qu'avant chaque nombre. Cela suit les conventions typographiques allemandes pour les plages de devises.
Que se passe-t-il lorsque les valeurs de plage sont approximativement égales
Lorsque les valeurs de début et de fin s'arrondissent au même nombre après formatage, le formateur réduit la plage et peut ajouter un symbole d'approximation.
const formatter = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0
});
console.log(formatter.formatRange(100, 200));
// Output: "$100 – $200"
console.log(formatter.formatRange(100, 120));
// Output: "$100 – $120"
console.log(formatter.formatRange(100.2, 100.8));
// Output: "~$100"
Le troisième exemple montre deux valeurs qui s'arrondissent au même nombre entier. Au lieu d'afficher "$100 – $100", qui ne transmet aucune information de plage, le formateur affiche "~$100". Le symbole tilde indique que la valeur est approximative.
Ce comportement s'applique lorsque les options de formatage font apparaître les valeurs de début et de fin comme identiques.
const formatter = new Intl.NumberFormat("en-US", {
maximumFractionDigits: 1
});
console.log(formatter.formatRange(2.9, 3.1));
// Output: "~3"
console.log(formatter.formatRange(2.94, 2.96));
// Output: "~2.9"
Le formateur insère le symbole d'approximation uniquement lorsque nécessaire. Lorsque les valeurs s'arrondissent à des nombres différents, il les affiche comme une plage standard.
Formatage des plages avec décimales
Le formatage de plage préserve les paramètres de décimales des options du formateur. Vous pouvez contrôler la précision pour les deux valeurs de la plage.
const formatter = new Intl.NumberFormat("en-US", {
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
console.log(formatter.formatRange(3.5, 5.7));
// Output: "3.50–5.70"
console.log(formatter.formatRange(100, 200));
// Output: "100.00–200.00"
Le formateur applique les paramètres de décimales aux deux nombres de la plage. Cela garantit une précision cohérente sur l'ensemble de l'affichage de la plage.
Vous pouvez combiner le formatage décimal avec des devises ou d'autres styles.
const formatter = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
console.log(formatter.formatRange(99.99, 199.99));
// Output: "$99.99 – $199.99"
Formatage des plages de nombres dans différentes langues
Le formatage de plage s'adapte aux conventions de chaque locale pour les nombres, les séparateurs et l'espacement.
const enFormatter = new Intl.NumberFormat("en-US");
console.log(enFormatter.formatRange(1000, 5000));
// Output: "1,000–5,000"
const deFormatter = new Intl.NumberFormat("de-DE");
console.log(deFormatter.formatRange(1000, 5000));
// Output: "1.000–5.000"
const frFormatter = new Intl.NumberFormat("fr-FR");
console.log(frFormatter.formatRange(1000, 5000));
// Output: "1 000–5 000"
const jaFormatter = new Intl.NumberFormat("ja-JP");
console.log(jaFormatter.formatRange(1000, 5000));
// Output: "1,000~5,000"
L'anglais utilise des virgules pour les séparateurs de milliers et un tiret demi-cadratin pour la plage. L'allemand utilise des points pour les milliers et un tiret demi-cadratin. Le français utilise des espaces pour les milliers et un tiret demi-cadratin. Le japonais utilise des virgules pour les milliers et un tilde ondulé (~) pour la plage.
Ces différences s'étendent au formatage des devises.
const enFormatter = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD"
});
console.log(enFormatter.formatRange(100, 200));
// Output: "$100.00 – $200.00"
const deFormatter = new Intl.NumberFormat("de-DE", {
style: "currency",
currency: "EUR"
});
console.log(deFormatter.formatRange(100, 200));
// Output: "100,00–200,00 €"
const jaFormatter = new Intl.NumberFormat("ja-JP", {
style: "currency",
currency: "JPY"
});
console.log(jaFormatter.formatRange(100, 200));
// Output: "¥100~¥200"
Chaque locale applique ses propres règles pour le placement du symbole monétaire, les séparateurs décimaux et les séparateurs de plage. L'API gère automatiquement toutes ces variations.
Combiner formatRange avec la notation compacte
Le formatage de plage fonctionne avec la notation compacte, vous permettant d'afficher des plages comme 1K-5K ou 1M-5M.
const formatter = new Intl.NumberFormat("en-US", {
notation: "compact"
});
console.log(formatter.formatRange(1000, 5000));
// Output: "1K–5K"
console.log(formatter.formatRange(1000000, 5000000));
// Output: "1M–5M"
console.log(formatter.formatRange(1200, 4800));
// Output: "1.2K–4.8K"
Le formateur applique la notation compacte aux deux valeurs de la plage. Cela permet de garder la sortie concise tout en transmettant l'information de plage.
Lorsque la plage couvre différents niveaux de magnitude, le formateur gère chaque valeur de manière appropriée.
const formatter = new Intl.NumberFormat("en-US", {
notation: "compact"
});
console.log(formatter.formatRange(500, 1500));
// Output: "500–1.5K"
console.log(formatter.formatRange(900000, 1200000));
// Output: "900K–1.2M"
La valeur de début peut ne pas utiliser la notation compacte tandis que la valeur de fin le fait, ou elles peuvent utiliser différents indicateurs de magnitude. Le formateur prend ces décisions en fonction de la taille de chaque valeur.
Utiliser formatRangeToParts pour un style personnalisé
La méthode formatRangeToParts() renvoie un tableau d'objets représentant les parties de la plage formatée. Cela vous permet de styliser ou de manipuler les composants individuels de la plage.
const formatter = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0
});
const parts = formatter.formatRangeToParts(100, 200);
console.log(parts);
La sortie est un tableau d'objets, chacun avec les propriétés type, value et source.
[
{ type: "currency", value: "$", source: "startRange" },
{ type: "integer", value: "100", source: "startRange" },
{ type: "literal", value: " – ", source: "shared" },
{ type: "currency", value: "$", source: "endRange" },
{ type: "integer", value: "200", source: "endRange" }
]
La propriété type identifie ce que la partie représente : symbole monétaire, entier, séparateur décimal ou texte littéral. La propriété value contient le texte formaté. La propriété source indique si la partie appartient à la valeur de début, à la valeur de fin ou est partagée entre elles.
Vous pouvez utiliser ces parties pour créer du HTML personnalisé avec différents styles pour différents composants.
const formatter = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0
});
const parts = formatter.formatRangeToParts(100, 200);
let html = "";
parts.forEach(part => {
if (part.type === "currency") {
html += `<span class="currency-symbol">${part.value}</span>`;
} else if (part.type === "integer") {
html += `<span class="amount">${part.value}</span>`;
} else if (part.type === "literal") {
html += `<span class="separator">${part.value}</span>`;
} else {
html += part.value;
}
});
console.log(html);
// Output: <span class="currency-symbol">$</span><span class="amount">100</span><span class="separator"> – </span><span class="currency-symbol">$</span><span class="amount">200</span>
Cette technique vous permet d'appliquer des classes CSS, d'ajouter des infobulles ou d'implémenter d'autres comportements personnalisés tout en préservant le formatage correct spécifique à la locale.
Gestion des cas limites avec formatRange
La méthode formatRange() inclut la gestion des erreurs pour les entrées invalides. Si l'un des paramètres est undefined, une TypeError est levée. Si l'un des paramètres est NaN ou ne peut pas être converti en nombre, une RangeError est levée.
const formatter = new Intl.NumberFormat("en-US");
try {
console.log(formatter.formatRange(100, undefined));
} catch (error) {
console.log(error.name);
// Output: "TypeError"
}
try {
console.log(formatter.formatRange(NaN, 200));
} catch (error) {
console.log(error.name);
// Output: "RangeError"
}
Lorsque vous travaillez avec des entrées utilisateur ou des données provenant de sources externes, validez que les valeurs sont des nombres valides avant de les transmettre à formatRange().
La méthode accepte des nombres, des valeurs BigInt ou des chaînes de caractères représentant des nombres valides.
const formatter = new Intl.NumberFormat("en-US");
console.log(formatter.formatRange(100, 200));
// Output: "100–200"
console.log(formatter.formatRange(100n, 200n));
// Output: "100–200"
console.log(formatter.formatRange("100", "200"));
// Output: "100–200"
Les entrées sous forme de chaînes de caractères sont analysées comme des nombres, préservant la précision sans problèmes de conversion en virgule flottante.
Quand utiliser formatRange plutôt que le formatage manuel
Utilisez formatRange() lors de l'affichage de plages de valeurs aux utilisateurs. Cela s'applique aux plages de prix, aux plages de quantités, aux plages de mesures, aux numéros de page ou à toute autre valeur délimitée. La méthode garantit un formatage correct spécifique à la locale sans nécessiter l'implémentation d'une logique de séparateur.
Évitez formatRange() lorsque vous devez afficher plusieurs valeurs distinctes qui ne sont pas sémantiquement liées en tant que plage. Par exemple, afficher une liste de prix comme « 100 $, 150 $, 200 $ » devrait utiliser des appels format() réguliers pour chaque valeur plutôt que de les traiter comme des plages.
Évitez également formatRange() lorsque la relation entre les valeurs n'est pas une plage numérique. Si vous affichez une comparaison ou une différence, utilisez le formatage approprié pour ce contexte plutôt que le formatage de plage.