So formatieren Sie Bereiche wie 3-5 oder 100-200

Verwenden Sie JavaScript, um Zahlenbereiche mit gebietsschema-gerechter Formatierung anzuzeigen

Einführung

Zahlenbereiche erscheinen überall in Benutzeroberflächen. Preisspannen werden als $100-$200 angezeigt, Seitenzahlen als 1-10 und Mengenangaben als 3-5 Artikel. Diese Bereiche kommunizieren, dass ein Wert zwischen zwei Endpunkten liegt, und bieten den Benutzern begrenzte Informationen anstelle einer einzelnen präzisen Zahl.

Wenn Sie das 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. Deutsch verwendet "bis" zwischen Zahlen, während einige Sprachen Leerzeichen um Trennzeichen herum platzieren.

JavaScript bietet die formatRange()-Methode auf Intl.NumberFormat, um die Bereichsformatierung automatisch zu handhaben. Diese Methode wendet gebietsschema-spezifische Konventionen sowohl auf die Zahlen als auch auf das Trennzeichen an und stellt sicher, dass Bereiche für Benutzer auf der ganzen Welt korrekt angezeigt werden.

Warum Zahlenbereiche gebietsschema-spezifische Formatierung benötigen

Verschiedene Kulturen haben unterschiedliche Konventionen für die Darstellung von Bereichen entwickelt. Diese Konventionen betreffen sowohl das Trennzeichen als auch die Abstände darum herum.

Im US-Englisch verwenden Bereiche typischerweise einen Halbgeviertstrich ohne Leerzeichen: 3-5, 100-200. In einigen Styleguides erscheinen Leerzeichen um den Strich herum: 3 - 5. Die genaue Konvention variiert je nach Kontext und Publikationsstandards.

Im Deutschen verwenden Bereiche oft "bis" als Trennzeichen: 3 bis 5, 100 bis 200. Dieser wortbasierte Ansatz macht die Bereichsbeziehung explizit, anstatt sich auf Interpunktion zu verlassen.

Im Spanischen können Bereiche einen Strich wie im Englischen oder das Wort "a" verwenden: 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. Ein Preisbereich kann in US-Englisch als $100-$200 angezeigt werden, im Deutschen jedoch als 100 €-200 € oder als 100-200 € mit nur einmaligem Währungssymbol. Verschiedene Gebietsschemata platzieren Währungssymbole unterschiedlich und handhaben Wiederholungen unterschiedlich.

Die manuelle Bereichsformatierung erfordert die Kenntnis dieser Konventionen und die Implementierung gebietsschemaspezifischer Logik. Die Intl-API kapselt dieses Wissen und wendet die entsprechende Formatierung basierend auf dem Gebietsschema an.

Verwendung von formatRange zur Formatierung von Zahlenbereichen

Die Methode formatRange() akzeptiert zwei Zahlen und gibt eine formatierte Zeichenkette zurück, die den Bereich darstellt. Erstellen Sie eine Instanz von Intl.NumberFormat mit Ihrem gewünschten Gebietsschema und den gewünschten 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));
// Output: "3–5"

console.log(formatter.formatRange(100, 200));
// Output: "100–200"

console.log(formatter.formatRange(1000, 5000));
// Output: "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 Gebietsschemata formatieren, indem Sie die Gebietsschemakennung ändern.

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"

Jedes Gebietsschema wendet seine eigenen Konventionen für Trennzeichen und 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. Wenn Sie Währungsbereiche formatieren, 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));
// Output: "$100 – $200"

console.log(formatter.formatRange(1000, 5000));
// Output: "$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 Gebietsschemata platzieren Währungssymbole unterschiedlich.

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 €"

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 Start- und Endwert nach der Formatierung auf dieselbe Zahl gerundet werden, reduziert 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 dieselbe ganze Zahl gerundet werden. Anstatt "$100 – $100" anzuzeigen, was keine Bereichsinformation 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 Endwert 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, zeigt er sie als Standardbereich an.

Formatierung von Bereichen mit Dezimalstellen

Die Bereichsformatierung behält die Dezimalstelleneinstellungen aus den Formatiereroptionen bei. Sie können die Genauigkeit 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 Genauigkeit über die gesamte Bereichsanzeige hinweg.

Sie können 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 Locale 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 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"

Jedes Gebietsschema wendet seine eigenen Regeln für die Platzierung von Währungssymbolen, Dezimaltrennzeichen und Bereichstrennzeichen an. Die API verarbeitet all diese Variationen automatisch.

Kombination von formatRange mit kompakter Notation

Die Bereichsformatierung funktioniert mit kompakter Notation und ermöglicht es Ihnen, Bereiche wie 1K-5K oder 1M-5M anzuzeigen.

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ägnant und vermittelt dennoch die Bereichsinformationen.

Wenn der Bereich verschiedene Größenordnungen umfasst, verarbeitet 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 möglicherweise unterschiedliche Größenindikatoren. Der Formatierer trifft diese Entscheidungen basierend auf der Größe jedes Werts.

Verwendung von formatRangeToParts für benutzerdefiniertes Styling

Die Methode formatRangeToParts() gibt ein Array von Objekten zurück, die die Teile des formatierten Bereichs darstellen. Dies ermöglicht es Ihnen, einzelne Komponenten des Bereichs zu stylen 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, von denen jedes die Eigenschaften type, value und source besitzt.

[
  { 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 unterschiedlichem Styling 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 Ihnen, CSS-Klassen anzuwenden, Tooltips hinzuzufügen oder andere benutzerdefinierte Verhaltensweisen zu implementieren, während die korrekte gebietsschemaspezifische Formatierung erhalten bleibt.

Umgang mit Sonderfällen bei formatRange

Die Methode formatRange() beinhaltet 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 konvertiert 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"
}

Wenn Sie mit Benutzereingaben oder Daten aus externen Quellen arbeiten, validieren Sie, dass 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 Gleitkomma-Konvertierungsprobleme erhalten bleibt.

Wann formatRange statt manueller Formatierung verwendet werden sollte

Verwenden Sie formatRange(), wenn Sie Bereiche für Benutzer anzeigen. Dies gilt für Preisspannen, Mengenspannen, Messbereiche, Seitenzahlen oder andere begrenzte Werte. Die Methode gewährleistet korrekte locale-spezifische Formatierung, ohne dass Sie Trennzeichen-Logik implementieren müssen.

Vermeiden Sie formatRange(), wenn Sie mehrere separate Werte anzeigen müssen, die semantisch nicht als Bereich zusammenhängen. Beispielsweise sollte die Anzeige einer Liste von Preisen wie "$100, $150, $200" reguläre format()-Aufrufe für jeden Wert verwenden, anstatt sie als Bereiche zu behandeln.

Vermeiden Sie formatRange() ebenfalls, wenn die Beziehung zwischen Werten kein numerischer Bereich ist. Wenn Sie einen Vergleich oder eine Differenz anzeigen, verwenden Sie eine für diesen Kontext geeignete Formatierung anstelle der Bereichsformatierung.