JavaScript Intl (Internationalisierungs-API)
Lerne die eingebaute JavaScript Intl API zum Formatieren von Zahlen, Währungen, Datumswerten, relativen Zeiten, Listen und Pluralformen sowie zur lokalisierungsgerechten Sortierung.
Intl ist ein eingebauter JavaScript-Namensraum für lokalisierungsgerechtes Formatieren und Vergleichen. Es muss keine Bibliothek installiert oder importiert werden — er ist in jedem modernen Browser und in Node.js enthalten. Damit lassen sich Zahlen, Währungen, Datumsangaben, relative Zeiten und Listen genau so formatieren, wie es Nutzer einer bestimmten Region erwarten, und Text lässt sich korrekt für Sprachen sortieren, bei denen eine rein englische Sortierung falsche Ergebnisse liefert.
Fast jeder Intl-Konstruktor folgt demselben Schema: Man übergibt ein Locale (oder ein Array von Fallback-Locales) und ein options-Objekt. Ein Locale ist ein BCP 47-Sprach-Tag wie 'en-US', 'de-DE', 'fr-FR' oder 'ja-JP'. Lässt man das Locale ganz weg, verwendet Intl das Standard-Locale der Laufzeitumgebung (die Spracheinstellung des Browsers oder das System-Locale in Node).
// locale + options
new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' });
// no locale → uses the runtime default
new Intl.NumberFormat();
// an array provides fallbacks: try Welsh, then fall back to English
new Intl.NumberFormat(['cy', 'en']);Intl.NumberFormat
Intl.NumberFormat formatiert Zahlen gemäß den Konventionen eines Locales. Das ist wichtig, weil Gruppierungs- und Dezimaltrennzeichen je nach Region unterschiedlich sind: Die Zahl 1234.56 wird in den USA als 1,234.56 geschrieben, in Deutschland jedoch als 1.234,56.
const n = 1234.56;
console.log(new Intl.NumberFormat('en-US').format(n)); // "1,234.56"
console.log(new Intl.NumberFormat('de-DE').format(n)); // "1.234,56"
console.log(new Intl.NumberFormat('fr-FR').format(n)); // "1 234,56"Die Option style legt fest, welche Art von Wert formatiert wird: 'decimal' (Standard), 'currency', 'percent' oder 'unit'.
Währung
Für Geldbeträge setzt man style: 'currency' und gibt die Währung mit der Option currency an (ein ISO 4217-Code wie 'USD' oder 'EUR'). Das Locale bestimmt die Position des Symbols und die Trennzeichen.
const price = 1499.9;
console.log(
new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(price)
); // "$1,499.90"
console.log(
new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(price)
); // "1.499,90 €"
console.log(
new Intl.NumberFormat('ja-JP', { style: 'currency', currency: 'JPY' }).format(price)
); // "¥1,500" (yen has no minor unit, so it is rounded)Prozent, Nachkommastellen und kompakte Schreibweise
Mit style: 'percent' wird ein Verhältnis als Prozentsatz formatiert — der Wert wird mit 100 multipliziert. Die Anzahl der Dezimalstellen lässt sich mit minimumFractionDigits und maximumFractionDigits steuern. Mit notation: 'compact' entstehen Kurzformen wie 1,2K und 3,4M.
console.log(
new Intl.NumberFormat('en-US', { style: 'percent' }).format(0.1875)
); // "19%"
console.log(
new Intl.NumberFormat('en-US', {
style: 'percent',
minimumFractionDigits: 2,
}).format(0.1875)
); // "18.75%"
console.log(
new Intl.NumberFormat('en-US', { notation: 'compact' }).format(1200000)
); // "1.2M"Einheiten
Mit style: 'unit' lassen sich Maßangaben formatieren. Die Einheit wird mit der Option unit angegeben (z. B. 'kilometer-per-hour' oder 'megabyte'), und mit unitDisplay wählt man zwischen 'short', 'long' und 'narrow'.
console.log(
new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'kilometer-per-hour',
}).format(90)
); // "90 km/h"
console.log(
new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'megabyte',
unitDisplay: 'long',
}).format(16)
); // "16 megabytes"Für weiterführende Zahlenoperationen — Rundung, Präzision und Arithmetik — siehe Numbers und JavaScript Math.
Intl.DateTimeFormat
Intl.DateTimeFormat formatiert Date-Objekte (und Zeitstempel) für ein Locale. Der schnellste Ansatz sind die Optionen dateStyle und timeStyle, die jeweils 'full', 'long', 'medium' oder 'short' akzeptieren.
Für feinere Kontrolle setzt man einzelne Komponenten wie year, month, day, hour, minute und second und fixiert die Ausgabe mit timeZone auf eine Zeitzone.
const date = new Date('2026-06-19T14:30:00Z');
const fmt = new Intl.DateTimeFormat('en-GB', {
year: 'numeric',
month: 'short',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
timeZone: 'Europe/Berlin',
});
console.log(fmt.format(date)); // "19 Jun 2026, 16:30"Zwei weitere Methoden sind besonders nützlich. .formatToParts() gibt die Ausgabe in beschriftete Einzelteile aufgeteilt zurück ({ type: 'month', value: 'Jun' } usw.), sodass sich einzelne Teile neu gestalten lassen. .formatRange(start, end) formatiert einen Datumsbereich kompakt und fasst gemeinsame Teile zusammen.
const fmt = new Intl.DateTimeFormat('en-US', { month: 'long', day: 'numeric' });
console.log(fmt.formatRange(new Date(2026, 5, 1), new Date(2026, 5, 5)));
// "June 1 – 5"Alles zum Erstellen und Bearbeiten von Datumswerten findet sich unter JavaScript Date.
Intl.RelativeTimeFormat
Intl.RelativeTimeFormat erzeugt menschlich lesbare Ausdrücke wie „vor 2 Tagen" oder „in 3 Stunden". Aufgerufen wird .format(value, unit), wobei ein negativer value in der Vergangenheit und ein positiver value in der Zukunft liegt. Die Option numeric: 'auto' erlaubt dem Formatter, Wörter wie „gestern" und „morgen" statt „vor 1 Tag" zu verwenden.
const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });
console.log(rtf.format(-1, 'day')); // "yesterday"
console.log(rtf.format(3, 'hour')); // "in 3 hours"
console.log(rtf.format(-2, 'day')); // "2 days ago"
console.log(rtf.format(1, 'week')); // "next week"Derselbe Aufruf in einem anderen Locale erzeugt native Formulierungen — new Intl.RelativeTimeFormat('fr').format(-1, 'day') liefert "il y a 1 jour".
Intl.Collator
Das Sortieren von Text ist der Bereich, in dem fehleranfälliger Code am häufigsten Probleme verursacht. JavaScripts Standard-Array.prototype.sort() vergleicht Zeichenketten anhand ihrer UTF-16-Codeeinheiten, nicht nach alphabetischen Regeln. Das bedeutet, dass Großbuchstaben vor Kleinbuchstaben und akzentuierte oder nicht-lateinische Buchstaben an unerwarteten Positionen landen.
const words = ['Zürich', 'apple', 'Banana', 'Älpler'];
console.log([...words].sort());
// ["Banana", "Zürich", "Älpler", "apple"] ← not what a reader expectsIntl.Collator behebt dies, indem es Zeichenketten so vergleicht, wie es eine bestimmte Sprache tut. Die Methode .compare hat genau die Signatur, die sort() erwartet, sodass man sie direkt übergeben kann.
Für einen einmaligen Vergleich zweier Zeichenketten kann auch String.prototype.localeCompare verwendet werden, das dieselben Locale- und Options-Argumente akzeptiert: 'ä'.localeCompare('z', 'de'). Beim Sortieren eines ganzen Arrays ist ein wiederverwendeter Intl.Collator zu bevorzugen — er ist schneller als der Aufruf von localeCompare für jedes Paar. Mehr zum Arbeiten mit Text unter Strings.
Intl.PluralRules
Verschiedene Sprachen haben unterschiedliche Pluralkategorien. Englisch hat nur zwei ('one' und 'other'), viele Sprachen haben aber mehr. Intl.PluralRules gibt an, in welche Kategorie eine Zahl fällt, damit in einer übersetzten Meldung die richtige Formulierung gewählt werden kann.
const pr = new Intl.PluralRules('en-US');
console.log(pr.select(0)); // "other"
console.log(pr.select(1)); // "one"
console.log(pr.select(5)); // "other"
function items(count) {
const word = pr.select(count) === 'one' ? 'item' : 'items';
return `${count} ${word}`;
}
console.log(items(1)); // "1 item"
console.log(items(3)); // "3 items"Intl.ListFormat
Intl.ListFormat fügt ein array von Zeichenketten zu einer natürlich klingenden Liste zusammen und setzt dabei die richtigen Trennzeichen und Konjunktionen für das Locale — einschließlich des Oxford-Kommas, wo die Sprache es verwendet.
const items = ['apples', 'bananas', 'oranges'];
const en = new Intl.ListFormat('en-US', { style: 'long', type: 'conjunction' });
console.log(en.format(items)); // "apples, bananas, and oranges"
const enOr = new Intl.ListFormat('en-US', { type: 'disjunction' });
console.log(enOr.format(items)); // "apples, bananas, or oranges"
const de = new Intl.ListFormat('de-DE', { type: 'conjunction' });
console.log(de.format(items)); // "apples, bananas und oranges"Formatter für bessere Performance wiederverwenden
Das Erstellen eines Intl-Formatters ist vergleichsweise aufwendig — er lädt und verarbeitet Locale-Daten. Jeder Formatter sollte daher einmal erstellt und wiederverwendet werden, besonders innerhalb von Schleifen oder beim Rendern von Listen. Ein neues new Intl.NumberFormat(...) für jede Zeile zu erstellen kann deutlich langsamer sein als das Formatieren selbst.
// Slow: a new formatter is built on every iteration
prices.forEach((p) =>
console.log(new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(p))
);
// Fast: build it once, reuse it
const money = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' });
prices.forEach((p) => console.log(money.format(p)));Jeder Formatter bietet außerdem .resolvedOptions(), das das nach der Aushandlung tatsächlich gewählte Locale und die gewählten Optionen zurückgibt. Das ist hilfreich beim Debuggen von Fällen, in denen die Laufzeitumgebung auf ein anderes als das angeforderte Locale zurückfällt.
Zusammenfassung
Die Intl API deckt die Formatierungs- und Vergleichsaufgaben ab, für die früher umfangreiche Drittanbieter-Bibliotheken erforderlich waren: lokalisierungsgerechte Zahlen, Währungen, Datumswerte, relative Zeiten, Pluralformen und Listen sowie korrekte Textsortierung mit Intl.Collator. Da sie in jedem modernen Browser und in Node.js eingebaut ist, hält der bevorzugte Einsatz das Bundle klein und die Ausgabe für Nutzer überall korrekt. Die eine Regel, die sich am meisten auszahlt: Jeden Formatter einmal erstellen und wiederverwenden.