Wie man einzelne Teile eines formatierten Datums in JavaScript erhält
Verwenden Sie formatToParts(), um auf jeden Bestandteil eines nach Locale formatierten Datums separat zuzugreifen
Einführung
Die Methode format() gibt einen vollständig formatierten String zurück, wie "15. Januar 2025" oder "15.01.2025". Dies funktioniert gut für einfache Anzeigen, aber Sie können einzelne Teile nicht unterschiedlich gestalten. Sie können den Monatsnamen nicht fett formatieren, das Jahr in einer anderen Farbe darstellen oder benutzerdefinierte Formatierungen auf bestimmte Komponenten anwenden.
JavaScript bietet die Methode formatToParts(), um dieses Problem zu lösen. Anstatt einen einzelnen String zurückzugeben, gibt sie ein Array von Objekten zurück, wobei jedes Objekt einen Teil des formatierten Datums repräsentiert. Jeder Teil hat einen Typ wie month, day oder year und einen Wert wie Januar, 15 oder 2025. Sie können diese Teile dann verarbeiten, um benutzerdefinierte Formatierungen anzuwenden, komplexe Layouts zu erstellen oder formatierte Daten in umfangreiche Benutzeroberflächen zu integrieren.
Warum formatierte Strings schwer anzupassen sind
Wenn Sie einen formatierten String wie "15. Januar 2025" erhalten, können Sie nicht einfach erkennen, wo der Monat endet und der Tag beginnt. Verschiedene Spracheinstellungen ordnen die Komponenten in unterschiedlichen Reihenfolgen an. Einige Spracheinstellungen verwenden unterschiedliche Trennzeichen. Das zuverlässige Parsen dieser Strings erfordert komplexe Logik, die die Formatierungsregeln dupliziert, die bereits in der Intl-API implementiert sind.
Stellen Sie sich eine Kalenderanwendung vor, die Daten mit dem Monatsnamen in Fettdruck anzeigt. Mit format() müssten Sie:
- Erkennen, welche Zeichen den Monatsnamen darstellen
- Leerzeichen und Interpunktion zwischen den Komponenten berücksichtigen
- Verschiedene Monatsformate in verschiedenen Spracheinstellungen behandeln
- Den String sorgfältig parsen, um das Datum nicht zu beschädigen
Dieser Ansatz ist fehleranfällig und störungsanfällig. Jede Änderung an den Formatierungsregeln der Spracheinstellung bricht Ihre Parsing-Logik.
Die Methode formatToParts() beseitigt dieses Problem, indem sie die Komponenten separat bereitstellt. Sie erhalten strukturierte Daten, die Ihnen genau mitteilen, welcher Teil welcher ist, unabhängig von der Spracheinstellung.
Verwendung von formatToParts zum Abrufen von Datumskomponenten
Die Methode formatToParts() funktioniert identisch zu format(), mit Ausnahme des Rückgabewerts. Sie erstellen einen Formatierer mit denselben Optionen und rufen dann formatToParts() anstelle von format() auf.
const formatter = new Intl.DateTimeFormat("en-US", {
year: "numeric",
month: "long",
day: "numeric"
});
const date = new Date(2025, 0, 15);
const parts = formatter.formatToParts(date);
console.log(parts);
Dies gibt ein Array von Objekten aus:
[
{ type: "month", value: "January" },
{ type: "literal", value: " " },
{ type: "day", value: "15" },
{ type: "literal", value: ", " },
{ type: "year", value: "2025" }
]
Jedes Objekt enthält eine type-Eigenschaft, die angibt, was der Teil darstellt, und eine value-Eigenschaft, die den tatsächlichen String enthält. Die Teile erscheinen in derselben Reihenfolge wie in der formatierten Ausgabe.
Sie können dies überprüfen, indem Sie alle Werte zusammenfügen:
const formatted = parts.map(part => part.value).join("");
console.log(formatted);
// Ausgabe: "January 15, 2025"
Die verketteten Teile erzeugen genau dieselbe Ausgabe wie der Aufruf von format().
Verständnis der Teiltypen
Die Eigenschaft type identifiziert jede Komponente. Verschiedene Formatierungsoptionen erzeugen verschiedene Teiltypen.
Für grundlegende Datumsformatierung:
const formatter = new Intl.DateTimeFormat("en-US", {
year: "numeric",
month: "long",
day: "numeric"
});
const date = new Date(2025, 0, 15);
const parts = formatter.formatToParts(date);
console.log(parts);
// [
// { type: "month", value: "January" },
// { type: "literal", value: " " },
// { type: "day", value: "15" },
// { type: "literal", value: ", " },
// { type: "year", value: "2025" }
// ]
Der Typ month repräsentiert den Monatsnamen oder die Monatsnummer. Der Typ day repräsentiert den Tag des Monats. Der Typ year repräsentiert das Jahr. Der Typ literal repräsentiert Leerzeichen, Interpunktion oder anderen Text, der vom Formatierer eingefügt wird.
Für Daten mit Wochentagen:
const formatter = new Intl.DateTimeFormat("en-US", {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric"
});
const date = new Date(2025, 0, 15);
const parts = formatter.formatToParts(date);
console.log(parts);
// [
// { type: "weekday", value: "Wednesday" },
// { type: "literal", value: ", " },
// { type: "month", value: "January" },
// { type: "literal", value: " " },
// { type: "day", value: "15" },
// { type: "literal", value: ", " },
// { type: "year", value: "2025" }
// ]
Der Typ weekday repräsentiert den Wochentag.
Für Daten mit Uhrzeiten:
const formatter = new Intl.DateTimeFormat("en-US", {
year: "numeric",
month: "long",
day: "numeric",
hour: "numeric",
minute: "numeric",
second: "numeric"
});
const date = new Date(2025, 0, 15, 14, 30, 45);
const parts = formatter.formatToParts(date);
console.log(parts);
// [
// { type: "month", value: "January" },
// { type: "literal", value: " " },
// { type: "day", value: "15" },
// { type: "literal", value: ", " },
// { type: "year", value: "2025" },
// { type: "literal", value: " at " },
// { type: "hour", value: "2" },
// { type: "literal", value: ":" },
// { type: "minute", value: "30" },
// { type: "literal", value: ":" },
// { type: "second", value: "45" },
// { type: "literal", value: " " },
// { type: "dayPeriod", value: "PM" }
// ]
Die Typen hour, minute und second repräsentieren Zeitkomponenten. Der Typ dayPeriod repräsentiert AM oder PM im 12-Stunden-Format.
Anwendung benutzerdefinierter Formatierung auf Datumsteile
Der primäre Anwendungsfall für formatToParts() ist die Anwendung verschiedener Stile auf unterschiedliche Komponenten. Sie können das Parts-Array verarbeiten, um bestimmte Typen in HTML-Elemente einzuschließen.
Den Monatsnamen fett formatieren:
const formatter = new Intl.DateTimeFormat("en-US", {
year: "numeric",
month: "long",
day: "numeric"
});
const date = new Date(2025, 0, 15);
const parts = formatter.formatToParts(date);
const html = parts
.map(part => {
if (part.type === "month") {
return `<strong>${part.value}</strong>`;
}
return part.value;
})
.join("");
console.log(html);
// Ausgabe: "<strong>January</strong> 15, 2025"
Dieser Ansatz funktioniert für jede Auszeichnungssprache. Sie können HTML, JSX oder jedes andere Format generieren, indem Sie das Parts-Array verarbeiten.
Das Jahr anders formatieren:
const formatter = new Intl.DateTimeFormat("en-US", {
year: "numeric",
month: "long",
day: "numeric"
});
const date = new Date(2025, 0, 15);
const parts = formatter.formatToParts(date);
const html = parts
.map(part => {
if (part.type === "year") {
return `<span class="text-gray-500">${part.value}</span>`;
}
return part.value;
})
.join("");
console.log(html);
// Ausgabe: "January 15, <span class="text-gray-500">2025</span>"
Dieses Muster ist üblich bei Kalenderanzeigen, bei denen verschiedene Komponenten unterschiedliche visuelle Betonung benötigen.
Erstellung benutzerdefinierter Datumsanzeigen mit mehreren Stilen
Komplexe Benutzeroberflächen kombinieren oft mehrere Formatierungsregeln. Sie können verschiedene Klassen oder Elemente gleichzeitig auf verschiedene Teiletypen anwenden.
const formatter = new Intl.DateTimeFormat("en-US", {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric"
});
const date = new Date(2025, 0, 15);
const parts = formatter.formatToParts(date);
const html = parts
.map(part => {
switch (part.type) {
case "weekday":
return `<span class="weekday">${part.value}</span>`;
case "month":
return `<span class="month">${part.value}</span>`;
case "day":
return `<span class="day">${part.value}</span>`;
case "year":
return `<span class="year">${part.value}</span>`;
case "literal":
return `<span class="literal">${part.value}</span>`;
default:
return part.value;
}
})
.join("");
console.log(html);
// Ausgabe: "<span class="weekday">Wednesday</span><span class="literal">, </span><span class="month">January</span><span class="literal"> </span><span class="day">15</span><span class="literal">, </span><span class="year">2025</span>"
Diese granulare Kontrolle ermöglicht eine präzise Formatierung für jede Komponente. Sie können dann CSS verwenden, um jede Klasse unterschiedlich zu gestalten.
Erstellen benutzerdefinierter Datumslayouts
Sie können Datumskomponenten in benutzerdefinierte Layouts umordnen, die sich vom Standardformat des Gebietsschemas unterscheiden. Extrahieren Sie bestimmte Teile und setzen Sie sie in beliebiger Reihenfolge zusammen.
const formatter = new Intl.DateTimeFormat("en-US", {
year: "numeric",
month: "long",
day: "numeric"
});
const date = new Date(2025, 0, 15);
const parts = formatter.formatToParts(date);
const day = parts.find(p => p.type === "day").value;
const month = parts.find(p => p.type === "month").value;
const year = parts.find(p => p.type === "year").value;
const customLayout = `
<div class="date-card">
<div class="day-large">${day}</div>
<div class="month-small">${month}</div>
<div class="year-small">${year}</div>
</div>
`;
console.log(customLayout);
Dies erstellt ein vertikales Kartenlayout mit dem Tag, der prominent angezeigt wird, gefolgt von Monat und Jahr. Die Komponenten bleiben ordnungsgemäß lokalisiert, auch wenn das Layout vom Standardformat abweicht.
Alle verfügbaren Teiltypen
Die Eigenschaft type kann je nach verwendeten Formatierungsoptionen folgende Werte haben:
weekday: Wochentag wie Montag oder Moera: Zeitraumindikator wie v. Chr., n. Chr. oder v.u.Z.year: Jahr wie 2025month: Monatsname oder -nummer wie Januar oder 01day: Tag des Monats wie 15dayPeriod: AM oder PM oder andere gebietsschemaspezifische Tagesabschnittehour: Stunde wie 14 oder 2minute: Minute wie 30second: Sekunde wie 45fractionalSecond: Millisekunden oder andere SekundenbruchteiletimeZoneName: Zeitzonenname wie MEZ oder Mitteleuropäische Zeitliteral: Leerzeichen, Interpunktion oder anderer Text, der durch Formatierung hinzugefügt wirdrelatedYear: Gregorianisches Jahr in alternativen KalendersystemenyearName: Benanntes Jahr in einigen Kalendersystemenunknown: Nicht erkannte Token
Nicht jede Formatierungsoption erzeugt jeden Teiltyp. Die Teile, die Sie erhalten, hängen vom Datumswert und der Formatter-Konfiguration ab.
Daten mit Zeitraumindikator:
const formatter = new Intl.DateTimeFormat("en-US", {
year: "numeric",
era: "short"
});
const date = new Date(-100, 0, 1);
const parts = formatter.formatToParts(date);
console.log(parts);
// [
// { type: "year", value: "101" },
// { type: "literal", value: " " },
// { type: "era", value: "BC" }
// ]
Daten mit Zeitzonen:
const formatter = new Intl.DateTimeFormat("en-US", {
year: "numeric",
month: "long",
day: "numeric",
hour: "numeric",
minute: "numeric",
timeZoneName: "short"
});
const date = new Date(2025, 0, 15, 14, 30);
const parts = formatter.formatToParts(date);
console.log(parts);
// Parts will include { type: "timeZoneName", value: "PST" } or similar
Daten mit Sekundenbruchteilen:
const formatter = new Intl.DateTimeFormat("en-US", {
hour: "numeric",
minute: "numeric",
second: "numeric",
fractionalSecondDigits: 3
});
const date = new Date(2025, 0, 15, 14, 30, 45, 123);
const parts = formatter.formatToParts(date);
// Parts will include { type: "fractionalSecond", value: "123" }
Datumskomponenten bedingt hervorheben
Einige Anwendungen heben bestimmte Datumskomponenten basierend auf Geschäftslogik hervor. Mit formatToParts() können Sie Styling basierend auf dem Datumswert anwenden und dabei die korrekte Formatierung beibehalten.
const formatter = new Intl.DateTimeFormat("en-US", {
year: "numeric",
month: "long",
day: "numeric"
});
function formatDateWithHighlight(date) {
const parts = formatter.formatToParts(date);
const isWeekend = date.getDay() === 0 || date.getDay() === 6;
const html = parts
.map(part => {
if (part.type === "day" && isWeekend) {
return `<span class="text-blue-600 font-bold">${part.value}</span>`;
}
return part.value;
})
.join("");
return html;
}
const saturday = new Date(2025, 0, 18);
console.log(formatDateWithHighlight(saturday));
// Output: "January <span class="text-blue-600 font-bold">18</span>, 2025"
const monday = new Date(2025, 0, 13);
console.log(formatDateWithHighlight(monday));
// Output: "January 13, 2025"
Das Datum erhält die korrekte Formatierung für die Locale, während bedingtes Styling basierend auf der Geschäftslogik angewendet wird.
Barrierefreie Datumsanzeigen erstellen
Sie können formatToParts() verwenden, um formatierten Datumsangaben Barrierefreiheitsattribute hinzuzufügen. Dies hilft Screenreadern, Werte korrekt anzukündigen.
const formatter = new Intl.DateTimeFormat("en-US", {
year: "numeric",
month: "long",
day: "numeric"
});
function formatAccessibleDate(date) {
const parts = formatter.formatToParts(date);
const formatted = parts.map(part => part.value).join("");
const isoDate = date.toISOString().split('T')[0];
return `<time datetime="${isoDate}">${formatted}</time>`;
}
const date = new Date(2025, 0, 15);
console.log(formatAccessibleDate(date));
// Output: "<time datetime="2025-01-15">January 15, 2025</time>"
Dies stellt sicher, dass Screenreader das Datum korrekt ankündigen können, während die Anzeige die lokalisierte formatierte Version zeigt.
Wie Teile die lokalisierte Formatierung bewahren
Das Parts-Array behält automatisch die lokalisierten Formatierungsregeln bei. Verschiedene Locales platzieren Komponenten in unterschiedlichen Reihenfolgen und verwenden unterschiedliche Formate, aber formatToParts() behandelt diese Unterschiede.
const usFormatter = new Intl.DateTimeFormat("en-US", {
year: "numeric",
month: "long",
day: "numeric"
});
const date = new Date(2025, 0, 15);
console.log(usFormatter.formatToParts(date));
// [
// { type: "month", value: "January" },
// { type: "literal", value: " " },
// { type: "day", value: "15" },
// { type: "literal", value: ", " },
// { type: "year", value: "2025" }
// ]
const ukFormatter = new Intl.DateTimeFormat("en-GB", {
year: "numeric",
month: "long",
day: "numeric"
});
console.log(ukFormatter.formatToParts(date));
// [
// { type: "day", value: "15" },
// { type: "literal", value: " " },
// { type: "month", value: "January" },
// { type: "literal", value: " " },
// { type: "year", value: "2025" }
// ]
Die britische Formatierung stellt den Tag vor dem Monat dar. Ihr Styling-Code verarbeitet das Parts-Array auf die gleiche Weise unabhängig von der Locale, und die Formatierung passt sich automatisch an.
const jpFormatter = new Intl.DateTimeFormat("ja-JP", {
year: "numeric",
month: "long",
day: "numeric"
});
console.log(jpFormatter.formatToParts(date));
// [
// { type: "year", value: "2025" },
// { type: "literal", value: "年" },
// { type: "month", value: "1月" },
// { type: "day", value: "15" },
// { type: "literal", value: "日" }
// ]
Die japanische Formatierung verwendet eine andere Reihenfolge und enthält Zeichenliterale wie 年 (Jahr) und 日 (Tag). Das Parts-Array spiegelt diese lokalisierten Konventionen automatisch wider.
Kombination von formatToParts mit Framework-Komponenten
Moderne Frameworks wie React können formatToParts() nutzen, um Komponenten effizient zu erstellen.
function DateDisplay({ date, locale, options }) {
const formatter = new Intl.DateTimeFormat(locale, options);
const parts = formatter.formatToParts(date);
return (
<span className="date-display">
{parts.map((part, index) => {
if (part.type === "month") {
return <strong key={index}>{part.value}</strong>;
}
if (part.type === "year") {
return <span key={index} className="text-sm text-gray-500">{part.value}</span>;
}
return <span key={index}>{part.value}</span>;
})}
</span>
);
}
Diese Komponente wendet unterschiedliche Formatierungen auf verschiedene Teile an und behält dabei die korrekte Formatierung für jede Locale bei.
Wann formatToParts versus format verwenden
Verwenden Sie format(), wenn Sie eine einfache formatierte Zeichenfolge ohne Anpassungen benötigen. Dies ist der häufigste Fall für die meisten Datumsanzeigen.
Verwenden Sie formatToParts(), wenn Sie:
- Unterschiedliche Formatierungen auf verschiedene Teile des Datums anwenden möchten
- HTML oder JSX mit formatierten Datumsangaben erstellen möchten
- Attribute oder Metadaten zu bestimmten Komponenten hinzufügen möchten
- Datumskomponenten in benutzerdefinierte Layouts umordnen möchten
- Formatierte Datumsangaben in komplexe Layouts integrieren möchten
- Formatierte Ausgaben programmatisch verarbeiten möchten
Die Methode formatToParts() hat einen etwas höheren Overhead als format(), da sie ein Array von Objekten anstelle einer einzelnen Zeichenfolge erstellt. Dieser Unterschied ist für typische Anwendungen vernachlässigbar, aber wenn Sie Tausende von Datumsangaben pro Sekunde formatieren, bietet format() eine bessere Leistung.
Für die meisten Anwendungen sollten Sie die Wahl eher auf Basis Ihrer Formatierungsanforderungen als aufgrund von Leistungsbedenken treffen. Wenn Sie die Ausgabe nicht anpassen müssen, verwenden Sie format(). Wenn Sie benutzerdefinierte Formatierungen oder Markup benötigen, verwenden Sie formatToParts().