Signatur
Beschreibung
formatToParts() erzeugt dieselbe sprachabhängige Ausgabe wie Intl.RelativeTimeFormat.prototype.format(), z. B. „vor 3 Tagen“ oder „in 2 Stunden“. Statt eines fertigen Strings bekommst du aber ein Array von Objekten. Jedes Objekt steht für einen Teil des Ergebnisses. So kannst du einzelne Bestandteile getrennt gestalten oder weiterverarbeiten, ohne den String selbst zerlegen zu müssen.
Jedes Teil-Objekt hat die Eigenschaften type und value. Der Typ "literal" steht für festen Text wie "vor " oder " Tagen". Die Zahlenbestandteile tragen die Typen, die auch Intl.NumberFormat.prototype.formatToParts() liefert, also "integer", "group", "decimal", "fraction" usw. Sie haben außerdem eine Eigenschaft unit mit der Einheit in der Singularform (z. B. "day").
Typische Einsatzfälle sind das Hervorheben der Zahl in einer Oberfläche („vor 5 Minuten“), barrierefreie Auszeichnungen oder eigene Formatierungen der Zahl, bei denen die übersetzten Textteile trotzdem erhalten bleiben sollen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $value Pflicht | number | string | Numerischer Wert für die relative Zeit. Negative Werte stehen für die Vergangenheit, positive für die Zukunft. -0 und 0 werden unterschiedlich behandelt (z. B. „vor 0 Tagen“ bzw. „in 0 Tagen“). |
|
| $unit Pflicht | string | Zeiteinheit: "year", "quarter", "month", "week", "day", "hour", "minute", "second". Pluralformen ("days" usw.) werden ebenfalls akzeptiert. |
Rückgabewert
value-Eigenschaften aneinandergehängt, ergibt das genau den String von format(). Zahlenbestandteile enthalten zusätzlich unit in Singularform.Beispiele
Grundlegende Zerlegung auf Deutsch
const rtf = new Intl.RelativeTimeFormat("de");
const parts = rtf.formatToParts(-3, "day");
console.log(parts);
numeric: "auto" liefert nur ein Literal
const rtf = new Intl.RelativeTimeFormat("de", { numeric: "auto" });
console.log(rtf.formatToParts(-1, "day"));
console.log(rtf.formatToParts(2, "hour"));
Zahl in der Oberfläche hervorheben
const rtf = new Intl.RelativeTimeFormat("de");
const highlight = (value, unit) =>
rtf
.formatToParts(value, unit)
.map(({ type, value }) =>
type === "literal" ? value : `<strong>${value}</strong>`
)
.join("");
console.log(highlight(-5, "minute"));
console.log(highlight(1.5, "hour"));
Tausendertrennzeichen und Dezimalstellen erkennen
const rtf = new Intl.RelativeTimeFormat("en");
const parts = rtf.formatToParts(1000, "day");
const types = parts.map((p) => p.type);
console.log(types);
console.log(parts.map((p) => p.value).join("") === rtf.format(1000, "day"));
// Wichtig · Fallstricke
- Eine ungültige Einheit (z. B.
"decade") löst einenRangeErroraus. Ein nicht endlicher Wert wieInfinityoderNaNführt ebenfalls zu einemRangeError. - Eine Zahl kann in mehrere Teile zerfallen (
integer,group,decimal,fraction). Verlasse dich nicht darauf, dass genau eininteger-Teil vorkommt. Wenn du die ganze Zahl brauchst, fasse alle Teile mitunitzusammen. - Mit
numeric: "auto"kann das Ergebnis ganz ohne Zahlenteil sein (z. B. „gestern“, „morgen“). Das muss dein Code berücksichtigen. - Die Eigenschaft
unitsteht immer im Singular, auch wenn du"days"übergeben hast. - Den genauen Wortlaut der Literale legen die CLDR-Daten der jeweiligen Engine fest. Er kann sich zwischen Browsern und Versionen unterscheiden. Vergleiche in Tests deshalb nicht mit fest eingetragenen Strings.
- Wenn du die Teile als HTML zusammensetzt: Die Literale kommen zwar aus vertrauenswürdigen Sprachdaten, trotzdem solltest du beim Einfügen per
innerHTMLNutzereingaben generell escapen. - Kompatibilität: Chrome 71+, Firefox 70+, Safari 14+, Edge 79+, Node.js 12+ (mit vollen ICU-Daten für alle Sprachen).