Intl.DateTimeFormat API

Formatieren Sie Daten und Uhrzeiten für jede Sprache ohne externe Bibliotheken

Einführung

Datumsangaben werden weltweit unterschiedlich dargestellt. Der 15. Januar 2024 erscheint in den Vereinigten Staaten als 1/15/2024, im Vereinigten Königreich als 15/1/2024 und in Japan als 2024/1/15. Auch Zeitformate variieren. Amerikaner verwenden 12-Stunden-Uhren mit AM und PM, während der Großteil der Welt 24-Stunden-Zeit verwendet.

Die manuelle Erstellung von Datumsformatierungslogik für verschiedene Sprachen ist komplex und fehleranfällig. Sie müssen Tag- und Monatsreihenfolge, Trennzeichen, Zeitformate, Zeitzonenkonvertierungen und Sonderfälle wie nicht-gregorianische Kalender handhaben.

Die Intl.DateTimeFormat API löst dieses Problem. Sie bietet integrierte, sprachbewusste Datums- und Zeitformatierung in allen modernen Browsern. Keine externen Bibliotheken erforderlich.

Grundlegende Verwendung

Der einfachste Weg, ein Datum zu formatieren, besteht darin, eine Intl.DateTimeFormat Instanz zu erstellen und deren format() Methode aufzurufen.

const date = new Date(2024, 0, 15, 14, 30);

const formatter = new Intl.DateTimeFormat("en-US");
formatter.format(date);
// "1/15/2024"

Ändern Sie die Sprache, um verschiedene Formatierungskonventionen zu sehen.

const ukFormatter = new Intl.DateTimeFormat("en-GB");
ukFormatter.format(date);
// "15/01/2024"

const japanFormatter = new Intl.DateTimeFormat("ja-JP");
japanFormatter.format(date);
// "2024/1/15"

Dasselbe Datum, auf drei verschiedene Arten formatiert, basierend auf lokalen Konventionen.

Sprachen verstehen

Eine Sprache ist eine Zeichenkette, die eine Sprache und regionale Präferenzen identifiziert. Das Format folgt dem BCP 47 Standard: Sprachcode, optional gefolgt von einem Regionscode.

Gängige Sprachmuster:

"en"      // English (generic)
"en-US"   // English (United States)
"en-GB"   // English (United Kingdom)
"es"      // Spanish (generic)
"es-MX"   // Spanish (Mexico)
"es-ES"   // Spanish (Spain)
"zh-CN"   // Chinese (China, Simplified)
"zh-TW"   // Chinese (Taiwan, Traditional)

Wenn Sie den Sprachparameter weglassen, verwendet der Browser die Standardsprache des Benutzers.

const formatter = new Intl.DateTimeFormat();
formatter.format(date);
// Output varies based on user's browser locale

Sie können auch ein Array von Sprachen angeben. Der Browser verwendet die erste unterstützte Sprache.

const formatter = new Intl.DateTimeFormat(["es-MX", "es", "en"]);
// Uses Spanish (Mexico) if available, falls back to generic Spanish, then English

Übersicht der Formatierungsoptionen

Der Intl.DateTimeFormat Konstruktor akzeptiert ein Optionsobjekt, das steuert, was in der formatierten Ausgabe erscheint. Es gibt zwei Ansätze zur Formatierung.

Der erste Ansatz verwendet Style-Shortcuts. Diese bieten eine schnelle, konventionelle Formatierung.

const formatter = new Intl.DateTimeFormat("en-US", {
  dateStyle: "full",
  timeStyle: "short"
});

formatter.format(date);
// "Monday, January 15, 2024 at 2:30 PM"

Der zweite Ansatz verwendet Component-Optionen. Diese ermöglichen eine granulare Kontrolle über jeden Teil des Datums.

const formatter = new Intl.DateTimeFormat("en-US", {
  year: "numeric",
  month: "long",
  day: "numeric",
  hour: "numeric",
  minute: "numeric"
});

formatter.format(date);
// "January 15, 2024 at 2:30 PM"

Sie können Style-Shortcuts nicht mit Component-Optionen mischen. Wählen Sie einen Ansatz pro Formatter.

Style-Shortcuts

Die Optionen dateStyle und timeStyle bieten vier vordefinierte Formatierungsebenen.

Die Option dateStyle formatiert den Datumsteil.

const date = new Date(2024, 0, 15);

const full = new Intl.DateTimeFormat("en-US", { dateStyle: "full" });
full.format(date);
// "Monday, January 15, 2024"

const long = new Intl.DateTimeFormat("en-US", { dateStyle: "long" });
long.format(date);
// "January 15, 2024"

const medium = new Intl.DateTimeFormat("en-US", { dateStyle: "medium" });
medium.format(date);
// "Jan 15, 2024"

const short = new Intl.DateTimeFormat("en-US", { dateStyle: "short" });
short.format(date);
// "1/15/24"

Die Option timeStyle formatiert den Zeitteil.

const date = new Date(2024, 0, 15, 14, 30, 45);

const full = new Intl.DateTimeFormat("en-US", { timeStyle: "full" });
full.format(date);
// "2:30:45 PM Eastern Standard Time"

const long = new Intl.DateTimeFormat("en-US", { timeStyle: "long" });
long.format(date);
// "2:30:45 PM EST"

const medium = new Intl.DateTimeFormat("en-US", { timeStyle: "medium" });
medium.format(date);
// "2:30:45 PM"

const short = new Intl.DateTimeFormat("en-US", { timeStyle: "short" });
short.format(date);
// "2:30 PM"

Kombinieren Sie beide Optionen, um Datum und Uhrzeit zusammen zu formatieren.

const formatter = new Intl.DateTimeFormat("en-US", {
  dateStyle: "medium",
  timeStyle: "short"
});

formatter.format(date);
// "Jan 15, 2024, 2:30 PM"

Style-Shortcuts passen sich automatisch an die Konventionen der Locale an.

const usFormatter = new Intl.DateTimeFormat("en-US", {
  dateStyle: "short",
  timeStyle: "short"
});
usFormatter.format(date);
// "1/15/24, 2:30 PM"

const deFormatter = new Intl.DateTimeFormat("de-DE", {
  dateStyle: "short",
  timeStyle: "short"
});
deFormatter.format(date);
// "15.1.24, 14:30"

Das deutsche Format verwendet Punkte als Trennzeichen, kehrt die Reihenfolge von Tag und Monat um und zeigt die 24-Stunden-Zeit an. Das amerikanische Format verwendet Schrägstriche, die Monat-zuerst-Reihenfolge und die 12-Stunden-Zeit mit AM/PM. Gleiche Optionen, unterschiedliche Ausgabe basierend auf der Locale.

Component-Optionen

Component-Optionen bieten präzise Kontrolle darüber, was angezeigt wird und wie. Jede Option spezifiziert einen Teil des Datums oder der Uhrzeit.

Die Option year zeigt das Jahr an.

const formatter = new Intl.DateTimeFormat("en-US", { year: "numeric" });
formatter.format(date);
// "2024"

const twoDigit = new Intl.DateTimeFormat("en-US", { year: "2-digit" });
twoDigit.format(date);
// "24"

Die Option month zeigt den Monat in verschiedenen Formaten an.

const numeric = new Intl.DateTimeFormat("en-US", { month: "numeric" });
numeric.format(date);
// "1"

const twoDigit = new Intl.DateTimeFormat("en-US", { month: "2-digit" });
twoDigit.format(date);
// "01"

const long = new Intl.DateTimeFormat("en-US", { month: "long" });
long.format(date);
// "January"

const short = new Intl.DateTimeFormat("en-US", { month: "short" });
short.format(date);
// "Jan"

const narrow = new Intl.DateTimeFormat("en-US", { month: "narrow" });
narrow.format(date);
// "J"

Die Option day zeigt den Tag des Monats an.

const formatter = new Intl.DateTimeFormat("en-US", { day: "numeric" });
formatter.format(date);
// "15"

const twoDigit = new Intl.DateTimeFormat("en-US", { day: "2-digit" });
twoDigit.format(date);
// "15"

Die Option weekday zeigt den Wochentag an.

const long = new Intl.DateTimeFormat("en-US", { weekday: "long" });
long.format(date);
// "Monday"

const short = new Intl.DateTimeFormat("en-US", { weekday: "short" });
short.format(date);
// "Mon"

const narrow = new Intl.DateTimeFormat("en-US", { weekday: "narrow" });
narrow.format(date);
// "M"

Kombinieren Sie mehrere Komponentenoptionen, um benutzerdefinierte Datumsformate zu erstellen.

const formatter = new Intl.DateTimeFormat("en-US", {
  weekday: "long",
  year: "numeric",
  month: "long",
  day: "numeric"
});

formatter.format(date);
// "Monday, January 15, 2024"

Der Browser übernimmt Abstände und Interpunktion basierend auf den Konventionen des Gebietsschemas.

Zeitformatierung

Zeitkomponentenoptionen steuern die Anzeige von Stunde, Minute und Sekunde.

const date = new Date(2024, 0, 15, 14, 30, 45);

const formatter = new Intl.DateTimeFormat("en-US", {
  hour: "numeric",
  minute: "numeric",
  second: "numeric"
});

formatter.format(date);
// "2:30:45 PM"

Die Option hour12 steuert die Anzeige im 12-Stunden- oder 24-Stunden-Format.

const hour12 = new Intl.DateTimeFormat("en-US", {
  hour: "numeric",
  minute: "numeric",
  hour12: true
});
hour12.format(date);
// "2:30 PM"

const hour24 = new Intl.DateTimeFormat("en-US", {
  hour: "numeric",
  minute: "numeric",
  hour12: false
});
hour24.format(date);
// "14:30"

Die Option hourCycle bietet eine präzisere Kontrolle über die Stundenanzeige. Es existieren vier Optionen.

// h11: 0-11
const h11 = new Intl.DateTimeFormat("en-US", {
  hour: "numeric",
  hourCycle: "h11"
});
h11.format(new Date(2024, 0, 15, 0, 30));
// "0:30 AM"

// h12: 1-12
const h12 = new Intl.DateTimeFormat("en-US", {
  hour: "numeric",
  hourCycle: "h12"
});
h12.format(new Date(2024, 0, 15, 0, 30));
// "12:30 AM"

// h23: 0-23
const h23 = new Intl.DateTimeFormat("en-US", {
  hour: "numeric",
  hourCycle: "h23"
});
h23.format(new Date(2024, 0, 15, 0, 30));
// "0:30"

// h24: 1-24
const h24 = new Intl.DateTimeFormat("en-US", {
  hour: "numeric",
  hourCycle: "h24"
});
h24.format(new Date(2024, 0, 15, 0, 30));
// "24:30"

Der Unterschied ist um Mitternacht relevant. Der Zyklus h11 verwendet 0, während h12 12 verwendet. Ebenso verwendet h23 0, während h24 24 verwendet.

Die Option dayPeriod fügt beschreibende Periodenmarkierungen für die 12-Stunden-Zeit hinzu.

const morning = new Date(2024, 0, 15, 10, 30);
const afternoon = new Date(2024, 0, 15, 14, 30);
const night = new Date(2024, 0, 15, 22, 30);

const formatter = new Intl.DateTimeFormat("en-US", {
  hour: "numeric",
  minute: "numeric",
  dayPeriod: "long"
});

formatter.format(morning);
// "10:30 in the morning"

formatter.format(afternoon);
// "2:30 in the afternoon"

formatter.format(night);
// "10:30 at night"

Die Option dayPeriod funktioniert nur mit 12-Stunden-Zeitformaten.

Die Option fractionalSecondDigits zeigt Subsekundenpräzision an.

const date = new Date(2024, 0, 15, 14, 30, 45, 123);

const oneDigit = new Intl.DateTimeFormat("en-US", {
  hour: "numeric",
  minute: "numeric",
  second: "numeric",
  fractionalSecondDigits: 1
});
oneDigit.format(date);
// "2:30:45.1 PM"

const threeDigits = new Intl.DateTimeFormat("en-US", {
  hour: "numeric",
  minute: "numeric",
  second: "numeric",
  fractionalSecondDigits: 3
});
threeDigits.format(date);
// "2:30:45.123 PM"

Sie können eine, zwei oder drei Dezimalstellen angeben.

Zeitzonenbehandlung

Die Option timeZone konvertiert Daten in bestimmte Zeitzonen.

const date = new Date("2024-01-15T14:30:00Z"); // UTC time

const newYork = new Intl.DateTimeFormat("en-US", {
  timeZone: "America/New_York",
  dateStyle: "full",
  timeStyle: "long"
});
newYork.format(date);
// "Monday, January 15, 2024 at 9:30:00 AM EST"

const tokyo = new Intl.DateTimeFormat("ja-JP", {
  timeZone: "Asia/Tokyo",
  dateStyle: "full",
  timeStyle: "long"
});
tokyo.format(date);
// "2024年1月15日月曜日 23:30:00 日本標準時"

const london = new Intl.DateTimeFormat("en-GB", {
  timeZone: "Europe/London",
  dateStyle: "full",
  timeStyle: "long"
});
london.format(date);
// "Monday, 15 January 2024 at 14:30:00 GMT"

Derselbe Zeitpunkt wird je nach Zeitzone unterschiedlich angezeigt. Verwenden Sie IANA-Zeitzonenbezeichner wie America/New_York, Europe/London oder Asia/Tokyo.

Die Option timeZoneName zeigt den Zeitzonennamen an.

const formatter = new Intl.DateTimeFormat("en-US", {
  hour: "numeric",
  minute: "numeric",
  timeZone: "America/New_York",
  timeZoneName: "short"
});
formatter.format(date);
// "9:30 AM EST"

const long = new Intl.DateTimeFormat("en-US", {
  hour: "numeric",
  minute: "numeric",
  timeZone: "America/New_York",
  timeZoneName: "long"
});
long.format(date);
// "9:30 AM Eastern Standard Time"

const shortOffset = new Intl.DateTimeFormat("en-US", {
  hour: "numeric",
  minute: "numeric",
  timeZone: "America/New_York",
  timeZoneName: "shortOffset"
});
shortOffset.format(date);
// "9:30 AM GMT-5"

const longOffset = new Intl.DateTimeFormat("en-US", {
  hour: "numeric",
  minute: "numeric",
  timeZone: "America/New_York",
  timeZoneName: "longOffset"
});
longOffset.format(date);
// "9:30 AM GMT-05:00"

Verschiedene Werte für timeZoneName bieten unterschiedliche Detailstufen.

Kalendersysteme und Zahlensysteme

Die Option calendar unterstützt nicht-gregorianische Kalender.

const date = new Date(2024, 0, 15);

const gregorian = new Intl.DateTimeFormat("en-US", {
  calendar: "gregory",
  year: "numeric",
  month: "long",
  day: "numeric"
});
gregorian.format(date);
// "January 15, 2024"

const japanese = new Intl.DateTimeFormat("ja-JP", {
  calendar: "japanese",
  year: "numeric",
  month: "long",
  day: "numeric"
});
japanese.format(date);
// "令和6年1月15日"

const islamic = new Intl.DateTimeFormat("ar-SA", {
  calendar: "islamic",
  year: "numeric",
  month: "long",
  day: "numeric"
});
islamic.format(date);
// "٦ رجب ١٤٤٥"

const chinese = new Intl.DateTimeFormat("zh-CN", {
  calendar: "chinese",
  year: "numeric",
  month: "long",
  day: "numeric"
});
chinese.format(date);
// "2023甲辰年腊月初五"

Dasselbe Datum wird in verschiedene Kalendersysteme konvertiert. Verfügbare Kalender umfassen gregory, japanese, islamic, islamic-umalqura, islamic-tbla, islamic-civil, islamic-rgsa, chinese, hebrew, indian, persian und weitere.

Die Option numberingSystem zeigt Ziffern in verschiedenen Schriftsystemen an.

const date = new Date(2024, 0, 15);

const western = new Intl.DateTimeFormat("en-US", {
  numberingSystem: "latn",
  year: "numeric",
  month: "numeric",
  day: "numeric"
});
western.format(date);
// "1/15/2024"

const arabic = new Intl.DateTimeFormat("en-US", {
  numberingSystem: "arab",
  year: "numeric",
  month: "numeric",
  day: "numeric"
});
arabic.format(date);
// "١‏/١٥‏/٢٠٢٤"

const devanagari = new Intl.DateTimeFormat("en-US", {
  numberingSystem: "deva",
  year: "numeric",
  month: "numeric",
  day: "numeric"
});
devanagari.format(date);
// "१/१५/२०२४"

const bengali = new Intl.DateTimeFormat("en-US", {
  numberingSystem: "beng",
  year: "numeric",
  month: "numeric",
  day: "numeric"
});
bengali.format(date);
// "১/১৫/২০২৪"

Verfügbare Zahlensysteme umfassen latn (westliche Ziffern), arab (arabisch-indische Ziffern), arabext (erweiterte arabisch-indische Ziffern), beng (bengalische Ziffern), deva (Devanagari-Ziffern) und viele weitere.

Formatierung von Datumsbereichen

Die Methode formatRange() formatiert einen Datumsbereich mit intelligenter Auslassung redundanter Informationen.

const start = new Date(2024, 0, 15);
const end = new Date(2024, 0, 20);

const formatter = new Intl.DateTimeFormat("en-US", {
  year: "numeric",
  month: "long",
  day: "numeric"
});

formatter.formatRange(start, end);
// "January 15 – 20, 2024"

Der Formatter lässt wiederholte Informationen aus. Beide Daten liegen im Januar 2024, daher wird Monat und Jahr nur einmal ausgegeben.

Wenn der Bereich verschiedene Monate umfasst, werden beide angezeigt.

const start = new Date(2024, 0, 15);
const end = new Date(2024, 1, 20);

formatter.formatRange(start, end);
// "January 15 – February 20, 2024"

Wenn der Bereich verschiedene Jahre umfasst, werden alle Informationen angezeigt.

const start = new Date(2024, 0, 15);
const end = new Date(2025, 1, 20);

formatter.formatRange(start, end);
// "January 15, 2024 – February 20, 2025"

Die Methode formatRange() funktioniert auch mit Zeitbereichen.

const start = new Date(2024, 0, 15, 14, 30);
const end = new Date(2024, 0, 15, 16, 45);

const formatter = new Intl.DateTimeFormat("en-US", {
  month: "long",
  day: "numeric",
  hour: "numeric",
  minute: "numeric"
});

formatter.formatRange(start, end);
// "January 15, 2:30 – 4:45 PM"

Das Datum wird nur einmal angezeigt, da beide Zeiten am selben Tag liegen.

Zugriff auf formatierte Teile

Die Methode formatToParts() gibt ein Array von Objekten zurück, die jeden Teil des formatierten Datums repräsentieren. Dies ermöglicht benutzerdefinierte Formatierungslogik.

const date = new Date(2024, 0, 15, 14, 30);

const formatter = new Intl.DateTimeFormat("en-US", {
  year: "numeric",
  month: "long",
  day: "numeric",
  hour: "numeric",
  minute: "numeric"
});

const parts = formatter.formatToParts(date);

Jedes Objekt im Array verfügt über eine Eigenschaft type und value.

[
  { type: "month", value: "January" },
  { type: "literal", value: " " },
  { type: "day", value: "15" },
  { type: "literal", value: ", " },
  { type: "year", value: "2024" },
  { type: "literal", value: " at " },
  { type: "hour", value: "2" },
  { type: "literal", value: ":" },
  { type: "minute", value: "30" },
  { type: "literal", value: " " },
  { type: "dayPeriod", value: "PM" }
]

Sie können diese Teile filtern und manipulieren, um benutzerdefinierte Formate zu erstellen.

const dateParts = parts.filter(part =>
  ["month", "day", "year"].includes(part.type)
);

const dateString = dateParts.map(part => part.value).join("/");
// "January/15/2024"

Die Methode formatRangeToParts() bietet die gleiche Funktionalität für Datumsbereiche.

const start = new Date(2024, 0, 15);
const end = new Date(2024, 0, 20);

const formatter = new Intl.DateTimeFormat("en-US", {
  year: "numeric",
  month: "long",
  day: "numeric"
});

const parts = formatter.formatRangeToParts(start, end);

Jedes Part-Objekt enthält eine Eigenschaft source, die angibt, ob es vom Start- oder Enddatum stammt.

[
  { type: "month", value: "January", source: "startRange" },
  { type: "literal", value: " ", source: "startRange" },
  { type: "day", value: "15", source: "startRange" },
  { type: "literal", value: " – ", source: "shared" },
  { type: "day", value: "20", source: "endRange" },
  { type: "literal", value: ", ", source: "shared" },
  { type: "year", value: "2024", source: "shared" }
]

Best practices

Verwenden Sie Formatter-Instanzen wieder, wenn Sie mehrere Daten mit denselben Optionen formatieren. Das Erstellen eines Formatters umfasst Locale-Verhandlung und Options-Auflösung, was einen geringen Performance-Overhead verursacht.

// Less efficient
dates.forEach(date => {
  const formatted = new Intl.DateTimeFormat("en-US").format(date);
  console.log(formatted);
});

// More efficient
const formatter = new Intl.DateTimeFormat("en-US");
dates.forEach(date => {
  const formatted = formatter.format(date);
  console.log(formatted);
});

Verwenden Sie nach Möglichkeit die Browser-Locale des Benutzers, indem Sie den Locale-Parameter weglassen. Dies respektiert die Benutzerpräferenzen.

const formatter = new Intl.DateTimeFormat();
// Uses browser locale automatically

Geben Sie Fallback-Locales an, wenn Sie bestimmte Regionen ansprechen. Wenn die bevorzugte Locale nicht verfügbar ist, verwendet der Browser die nächste Option.

const formatter = new Intl.DateTimeFormat(["fr-CA", "fr", "en"]);
// Prefers French (Canada), falls back to French, then English

Verwenden Sie Style-Shortcuts für gängige Datums- und Zeitanzeigen. Sie passen sich automatisch an Locale-Konventionen an und erfordern weniger Konfiguration.

const formatter = new Intl.DateTimeFormat("en-US", {
  dateStyle: "medium",
  timeStyle: "short"
});

Verwenden Sie Component-Optionen, wenn Sie präzise Kontrolle über das Ausgabeformat benötigen.

const formatter = new Intl.DateTimeFormat("en-US", {
  weekday: "long",
  year: "numeric",
  month: "long",
  day: "numeric"
});

Geben Sie immer eine Zeitzone an, wenn Sie Zeiten für Remote-Benutzer oder geplante Events anzeigen. Ohne Zeitzone werden Daten in der lokalen Zeitzone des Benutzers formatiert, was möglicherweise nicht Ihrer Absicht entspricht.

const formatter = new Intl.DateTimeFormat("en-US", {
  timeZone: "America/New_York",
  dateStyle: "full",
  timeStyle: "long"
});

Verwenden Sie formatRange() für Datumsbereiche, anstatt jedes Datum separat zu formatieren und zu verketten. Die Methode behandelt intelligente Auslassung redundanter Informationen.

// Less clear
const startFormatted = formatter.format(start);
const endFormatted = formatter.format(end);
const range = `${startFormatted} to ${endFormatted}`;

// Better
const range = formatter.formatRange(start, end);

Überprüfen Sie die Browser-Kompatibilität für erweiterte Features wie dayPeriod, fractionalSecondDigits und bestimmte timeZoneName-Werte. Alle modernen Browser unterstützen die Kernfunktionalität, aber neuere Optionen erfordern möglicherweise Fallbacks für ältere Browser.