Wie man Bereiche wie 3-5 oder 100-200 formatiert
Verwenden Sie JavaScript, um Zahlenbereiche mit lokalisierungsgerechter Formatierung anzuzeigen
Einführung
Zahlenbereiche erscheinen in Benutzeroberflächen an verschiedenen Stellen. Preisspannen werden als 100-200 € angezeigt, Seitenzahlen als 1-10 und Mengenangaben als 3-5 Artikel. Diese Bereiche vermitteln, dass ein Wert zwischen zwei Endpunkten liegt und bieten Benutzern eingegrenzte Informationen anstelle einer einzelnen präzisen Zahl.
Wenn Sie den Trennzeichen zwischen Bereichswerten fest codieren, gehen Sie davon aus, dass alle Benutzer denselben typografischen Konventionen folgen. Englischsprachige verwenden typischerweise Bindestriche oder Halbgeviertstriche für Bereiche, aber andere Sprachen verwenden unterschiedliche Symbole oder Wörter. Im Deutschen wird "bis" zwischen Zahlen verwendet, während einige Sprachen Leerzeichen um Trennzeichen setzen.
JavaScript bietet die Methode formatRange() in Intl.NumberFormat, um die Bereichsformatierung automatisch zu handhaben. Diese Methode wendet lokalisierungsspezifische Konventionen sowohl auf die Zahlen als auch auf das Trennzeichen an und stellt sicher, dass Bereiche für Benutzer weltweit korrekt angezeigt werden.
Warum Zahlenbereiche eine lokalisierungsspezifische Formatierung benötigen
Verschiedene Kulturen haben unterschiedliche Konventionen zur Darstellung von Bereichen entwickelt. Diese Konventionen betreffen sowohl das Trennzeichen als auch die Leerzeichen darum herum.
Im amerikanischen Englisch verwenden Bereiche typischerweise einen Halbgeviertstrich ohne Leerzeichen: 3-5, 100-200. In einigen Stilrichtlinien erscheinen Leerzeichen um den Strich: 3 - 5. Die genaue Konvention variiert je nach Kontext und Publikationsstandards.
Im Deutschen werden Bereiche oft mit "bis" als Trennzeichen dargestellt: 3 bis 5, 100 bis 200. Dieser wortbasierte Ansatz macht die Bereichsbeziehung explizit, anstatt sich auf Interpunktion zu verlassen.
Im Spanischen können Bereiche wie im Englischen mit einem Strich oder mit dem Wort "a" dargestellt werden: 3-5 oder 3 a 5. Die Wahl hängt von der spezifischen spanischsprachigen Region und dem Kontext ab.
Bei der Formatierung von Bereichen, die Währungen oder Einheiten enthalten, steigt die Komplexität. Eine Preisspanne könnte im amerikanischen Englisch als $100-$200 angezeigt werden, aber im Deutschen als 100 €-200 € oder als 100-200 €, wobei das Symbol nur einmal erscheint. Verschiedene Lokalisierungen platzieren Währungssymbole unterschiedlich und behandeln Wiederholungen unterschiedlich.
Manuelle Bereichsformatierung erfordert Kenntnis dieser Konventionen und die Implementierung lokalisierungsspezifischer Logik. Die Intl-API kapselt dieses Wissen und wendet die entsprechende Formatierung basierend auf der Lokalisierung an.
Verwendung von formatRange zur Formatierung von Zahlenbereichen
Die Methode formatRange() akzeptiert zwei Zahlen und gibt eine formatierte Zeichenfolge zurück, die den Bereich darstellt. Erstellen Sie eine Intl.NumberFormat-Instanz mit Ihrem gewünschten Gebietsschema und Optionen, und rufen Sie dann formatRange() mit den Start- und Endwerten auf.
const formatter = new Intl.NumberFormat("en-US");
console.log(formatter.formatRange(3, 5));
// Ausgabe: "3–5"
console.log(formatter.formatRange(100, 200));
// Ausgabe: "100–200"
console.log(formatter.formatRange(1000, 5000));
// Ausgabe: "1,000–5,000"
Der Formatierer wendet Tausendertrennzeichen auf beide Zahlen im Bereich an und verwendet ein geeignetes Trennzeichen zwischen ihnen. Für US-Englisch ist dies ein Halbgeviertstrich ohne Leerzeichen.
Sie können denselben Bereich für verschiedene Gebietsschemas formatieren, indem Sie die Gebietsschema-ID ändern.
const usFormatter = new Intl.NumberFormat("en-US");
console.log(usFormatter.formatRange(100, 200));
// Ausgabe: "100–200"
const deFormatter = new Intl.NumberFormat("de-DE");
console.log(deFormatter.formatRange(100, 200));
// Ausgabe: "100–200"
const esFormatter = new Intl.NumberFormat("es-ES");
console.log(esFormatter.formatRange(100, 200));
// Ausgabe: "100-200"
Jedes Gebietsschema wendet seine eigenen Konventionen für das Trennzeichen und die Abstände an. Die API behandelt diese Details automatisch basierend auf den typografischen Standards des Gebietsschemas.
Formatierung von Währungsbereichen
Die Bereichsformatierung funktioniert mit allen Zahlenformatierungsoptionen, einschließlich Währungen. Bei der Formatierung von Währungsbereichen behandelt der Formatierer sowohl die Platzierung des Währungssymbols als auch das Bereichstrennzeichen.
const formatter = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0
});
console.log(formatter.formatRange(100, 200));
// Ausgabe: "$100 – $200"
console.log(formatter.formatRange(1000, 5000));
// Ausgabe: "$1,000 – $5,000"
Der Formatierer platziert das Währungssymbol vor jeder Zahl im Bereich. Dies macht deutlich, dass beide Werte Währungsbeträge darstellen.
Verschiedene Gebietsschemas platzieren Währungssymbole unterschiedlich.
const usFormatter = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0
});
console.log(usFormatter.formatRange(100, 200));
// Ausgabe: "$100 – $200"
const deFormatter = new Intl.NumberFormat("de-DE", {
style: "currency",
currency: "EUR",
maximumFractionDigits: 0
});
console.log(deFormatter.formatRange(100, 200));
// Ausgabe: "100–200 €"
Der deutsche Formatierer platziert das Euro-Symbol nach dem Bereich und nicht vor jeder Zahl. Dies entspricht den deutschen typografischen Konventionen für Währungsbereiche.
Was passiert, wenn Bereichswerte ungefähr gleich sind
Wenn die Start- und Endwerte nach der Formatierung auf die gleiche Zahl gerundet werden, komprimiert der Formatierer den Bereich und fügt möglicherweise ein Näherungssymbol hinzu.
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"
Das dritte Beispiel zeigt zwei Werte, die auf die gleiche ganze Zahl gerundet werden. Anstatt "$100 – $100" anzuzeigen, was keine Bereichsinformationen vermittelt, gibt der Formatierer "~$100" aus. Das Tilde-Symbol zeigt an, dass der Wert ungefähr ist.
Dieses Verhalten tritt auf, wenn Formatierungsoptionen dazu führen, dass Start- und Endwerte identisch erscheinen.
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"
Der Formatierer fügt das Näherungssymbol nur bei Bedarf ein. Wenn die Werte auf unterschiedliche Zahlen gerundet werden, werden sie als Standardbereich angezeigt.
Formatierung von Bereichen mit Dezimalstellen
Die Bereichsformatierung behält die Dezimalstelleneinstellungen aus den Formatiereroptionen bei. Sie können die Präzision für beide Werte im Bereich steuern.
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"
Der Formatierer wendet die Dezimalstelleneinstellungen auf beide Zahlen im Bereich an. Dies gewährleistet eine konsistente Präzision über die gesamte Bereichsanzeige.
Sie können die Dezimalformatierung mit Währungs- oder anderen Stilen kombinieren.
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"
Formatierung von Zahlenbereichen in verschiedenen Sprachen
Die Bereichsformatierung passt sich den Konventionen jeder Sprache für Zahlen, Trennzeichen und Abstände an.
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"
Englisch verwendet Kommas als Tausendertrennzeichen und einen Halbgeviertstrich für den Bereich. Deutsch verwendet Punkte für Tausender und einen Halbgeviertstrich. Französisch verwendet Leerzeichen für Tausender und einen Halbgeviertstrich. Japanisch verwendet Kommas für Tausender und einen Wellenstrich (~) für den Bereich.
Diese Unterschiede erstrecken sich auch auf die Währungsformatierung.
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"
Jede Sprache wendet ihre eigenen Regeln für die Platzierung von Währungssymbolen, Dezimaltrennzeichen und Bereichstrennzeichen an. Die API behandelt all diese Variationen automatisch.
Kombination von formatRange mit kompakter Notation
Die Bereichsformatierung funktioniert mit kompakter Notation und ermöglicht die Anzeige von Bereichen wie 1K-5K oder 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"
Der Formatierer wendet die kompakte Notation auf beide Werte im Bereich an. Dies hält die Ausgabe präzise und vermittelt dennoch die Bereichsinformationen.
Wenn der Bereich verschiedene Größenordnungen umfasst, behandelt der Formatierer jeden Wert entsprechend.
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"
Der Startwert verwendet möglicherweise keine kompakte Notation, während der Endwert dies tut, oder sie verwenden unterschiedliche Größenindikatoren. Der Formatierer trifft diese Entscheidungen basierend auf der Größe jedes Wertes.
Verwendung von formatRangeToParts für benutzerdefinierte Formatierung
Die Methode formatRangeToParts() gibt ein Array von Objekten zurück, die die Teile des formatierten Bereichs darstellen. Dies ermöglicht es, einzelne Komponenten des Bereichs zu formatieren oder zu manipulieren.
const formatter = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0
});
const parts = formatter.formatRangeToParts(100, 200);
console.log(parts);
Die Ausgabe ist ein Array von Objekten, jedes mit den Eigenschaften type, value und 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" }
]
Die Eigenschaft type identifiziert, was der Teil darstellt: Währungssymbol, Ganzzahl, Dezimaltrennzeichen oder Literaltext. Die Eigenschaft value enthält den formatierten Text. Die Eigenschaft source gibt an, ob der Teil zum Startwert, Endwert gehört oder zwischen ihnen geteilt wird.
Sie können diese Teile verwenden, um benutzerdefiniertes HTML mit unterschiedlicher Formatierung für verschiedene Komponenten zu erstellen.
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>
Diese Technik ermöglicht es, CSS-Klassen anzuwenden, Tooltips hinzuzufügen oder andere benutzerdefinierte Verhaltensweisen zu implementieren, während die korrekte lokalisierte Formatierung beibehalten wird.
Umgang mit Grenzfällen mit formatRange
Die Methode formatRange() enthält eine Fehlerbehandlung für ungültige Eingaben. Wenn einer der Parameter undefined ist, wird ein TypeError ausgelöst. Wenn einer der Parameter NaN ist oder nicht in eine Zahl umgewandelt werden kann, wird ein RangeError ausgelöst.
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"
}
Bei der Arbeit mit Benutzereingaben oder Daten aus externen Quellen sollten Sie überprüfen, ob die Werte gültige Zahlen sind, bevor Sie sie an formatRange() übergeben.
Die Methode akzeptiert Zahlen, BigInt-Werte oder Strings, die gültige Zahlen darstellen.
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"
String-Eingaben werden als Zahlen geparst, wobei die Präzision ohne Probleme bei der Umwandlung in Fließkommazahlen erhalten bleibt.
Wann formatRange vs. manuelle Formatierung verwenden
Verwenden Sie formatRange(), wenn Sie Bereiche für Benutzer anzeigen. Dies gilt für Preisbereiche, Mengenbereiche, Messbereiche, Seitenzahlen oder andere begrenzte Werte. Die Methode gewährleistet eine korrekte, regionsspezifische Formatierung, ohne dass Sie eine eigene Trennzeichenlogik implementieren müssen.
Vermeiden Sie formatRange(), wenn Sie mehrere separate Werte anzeigen müssen, die semantisch nicht als Bereich zusammengehören. Wenn Sie beispielsweise eine Liste von Preisen wie "100 €, 150 €, 200 €" anzeigen möchten, sollten Sie für jeden Wert reguläre format()-Aufrufe verwenden, anstatt sie als Bereiche zu behandeln.
Vermeiden Sie formatRange() auch, wenn die Beziehung zwischen Werten kein numerischer Bereich ist. Wenn Sie einen Vergleich oder einen Unterschied anzeigen, verwenden Sie eine für diesen Kontext geeignete Formatierung anstelle einer Bereichsformatierung.