Intl.DateTimeFormat API

Formatieren Sie Datums- und Zeitangaben für jede Sprachregion ohne externe Bibliotheken

Einführung

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

Manuelle Datumsformatierungslogik für verschiedene Sprachräume zu erstellen ist komplex und fehleranfällig. Man muss die Reihenfolge von Tag und Monat, Trennzeichen, Zeitformate, Zeitzonenumrechnungen und Sonderfälle wie nicht-gregorianische Kalender berücksichtigen.

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

Grundlegende Verwendung

Die einfachste Methode zur Formatierung eines Datums 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 den Sprachraum, 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.

Sprachräume verstehen

Ein Sprachraum (Locale) ist ein String, der eine Sprache und regionale Präferenzen identifiziert. Das Format folgt dem BCP 47-Standard: Sprachcode, optional gefolgt von einem Regionscode.

Gängige Locale-Muster:

"en"      // Englisch (generisch)
"en-US"   // Englisch (Vereinigte Staaten)
"en-GB"   // Englisch (Vereinigtes Königreich)
"es"      // Spanisch (generisch)
"es-MX"   // Spanisch (Mexiko)
"es-ES"   // Spanisch (Spanien)
"zh-CN"   // Chinesisch (China, vereinfacht)
"zh-TW"   // Chinesisch (Taiwan, traditionell)

Wenn Sie den Locale-Parameter weglassen, verwendet der Browser den Standard-Sprachraum des Benutzers.

const formatter = new Intl.DateTimeFormat();
formatter.format(date);
// Ausgabe variiert je nach Browser-Sprachraum des Benutzers

Sie können auch ein Array von Sprachräumen angeben. Der Browser verwendet den ersten unterstützten Sprachraum.

const formatter = new Intl.DateTimeFormat(["es-MX", "es", "en"]);
// Verwendet Spanisch (Mexiko) wenn verfügbar, fällt zurück auf generisches Spanisch, dann Englisch

Übersicht der Formatierungsoptionen

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

Der erste Ansatz verwendet Stil-Shortcuts. Diese bieten 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 Komponenten-Optionen. Diese geben 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 Stil-Shortcuts nicht mit Komponenten-Optionen mischen. Wählen Sie einen Ansatz pro Formatter.

Stil-Shortcuts

Die Optionen dateStyle und timeStyle bieten vier voreingestellte Formatierungsstufen.

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"

Stil-Shortcuts passen sich automatisch an lokale Konventionen 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, eine Monat-zuerst-Anordnung und 12-Stunden-Zeit mit AM/PM. Gleiche Optionen, unterschiedliche Ausgabe basierend auf dem Gebietsschema.

Komponentenoptionen

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

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 die Abstände und Interpunktion basierend auf den Konventionen der Locale.

Zeitformatierung

Zeitkomponentenoptionen steuern die Anzeige von Stunden, Minuten und Sekunden.

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- versus 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 feinere Kontrolle über die Stundenanzeige. Es gibt 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 h11-Zyklus verwendet 0, während h12 die 12 verwendet. Ähnlich verwendet h23 die 0, während h24 die 24 verwendet.

Die Option dayPeriod fügt beschreibende Zeitraummarkierungen für das 12-Stunden-Format 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 Subsekunden-Prä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 Nachkommastellen angeben.

Zeitzonen-Handhabung

Die Option timeZone konvertiert Datumsangaben in spezifische Zeitzonen.

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

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"

Der gleiche 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 Namen der Zeitzone 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 timeZoneName-Werte bieten unterschiedliche Detailgrade.

Kalendersysteme und Nummerierungssysteme

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甲辰年腊月初五"

Das gleiche Datum wird in verschiedene Kalendersysteme umgerechnet. Verfügbare Kalender umfassen gregory, japanese, islamic, islamic-umalqura, islamic-tbla, islamic-civil, islamic-rgsa, chinese, hebrew, indian, persian und andere.

Die Option numberingSystem zeigt Ziffern in verschiedenen Schriften 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 Nummerierungssysteme umfassen latn (westliche Ziffern), arab (arabisch-indische Ziffern), arabext (erweiterte arabisch-indische Ziffern), beng (bengalische Ziffern), deva (Devanagari-Ziffern) und viele andere.

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 Formatierer lässt wiederholte Informationen aus. Beide Daten sind im Januar 2024, daher enthält die Ausgabe den Monat und das Jahr nur einmal.

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 stattfinden.

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 hat 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 Teil-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 Datumsangaben mit denselben Optionen formatieren. Das Erstellen eines Formatters beinhaltet Locale-Verhandlung und Optionsauflösung, was einen kleinen Performance-Aufwand verursacht.

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

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

Verwenden Sie wenn möglich die Browser-Locale des Benutzers, indem Sie den Locale-Parameter weglassen. Dies respektiert die Benutzereinstellungen.

const formatter = new Intl.DateTimeFormat();
// Verwendet automatisch die Browser-Locale

Stellen Sie Fallback-Locales bereit, 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"]);
// Bevorzugt Französisch (Kanada), fällt zurück auf Französisch, dann Englisch

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 Komponenten-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 entfernte Benutzer oder für geplante Ereignisse anzeigen. Ohne Zeitzone werden Datumsangaben 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 intelligentes Weglassen redundanter Informationen.

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

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

Überprüfen Sie die Browser-Kompatibilität für erweiterte Funktionen 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.