Intl.DurationFormat API
Formatieren Sie Zeitdauern in JavaScript mit automatischer Lokalisierung
Einführung
Wenn Sie anzeigen, wie lange etwas dauert, müssen Sie Zeitdauerwerte für Benutzer formatieren. Ein Videoplayer zeigt die Laufzeit an, eine Flugbuchung zeigt die Reisezeit, eine Fitness-App zeigt die Trainingsdauer. Ohne Lokalisierung könnten Sie Code wie diesen schreiben:
const hours = 1;
const minutes = 46;
const seconds = 40;
const duration = `${hours}h ${minutes}m ${seconds}s`;
Dies erzeugt "1h 46m 40s" für alle Benutzer unabhängig von der Sprache. Französische Benutzer sehen "1h 46m 40s", wenn sie "1 h 46 min 40 s" erwarten. Deutsche Benutzer sehen dieselben englischen Abkürzungen. Spanische Benutzer erhalten keine "y"-Konjunktion zwischen den Einheiten.
Die Intl.DurationFormat-API löst dieses Problem. Sie formatiert Zeitdauern gemäß der Sprache und kulturellen Konventionen des Benutzers ohne externe Bibliotheken oder manuellen String-Aufbau.
const duration = { hours: 1, minutes: 46, seconds: 40 };
new Intl.DurationFormat('fr-FR', { style: 'short' }).format(duration);
// "1 h, 46 min et 40 s"
Der Formatierer behandelt automatisch Abkürzungen, Konjunktionen, Wortreihenfolge und Abstände für jede Locale.
Was sind Zeitdauern
Eine Zeitdauer repräsentiert eine Zeitspanne, nicht einen Zeitpunkt. Daten und Uhrzeiten markieren, wann etwas passiert. Zeitdauern messen, wie lange etwas dauert.
Dieser Unterschied ist wichtig für die Formatierung. Daten beinhalten Kalender, Zeitzonen und historische Regeln. Zeitdauern sind einfacher: Sie messen die verstrichene Zeit in Standardeinheiten ohne Kalenderkontext.
Die Intl.DurationFormat-API behandelt Zeitdauern. Die Intl.DateTimeFormat-API behandelt Daten und Uhrzeiten. Verwenden Sie das richtige Werkzeug für jede Aufgabe.
Einen Zeitdauer-Formatierer erstellen
Der Konstruktor nimmt eine Locale und ein Options-Objekt entgegen. Die Locale bestimmt die Ausgabesprache. Die Optionen steuern den Formatierungsstil und die Anzeige der Einheiten.
const formatter = new Intl.DurationFormat('en', { style: 'long' });
Rufen Sie format() mit einem Zeitdauer-Objekt auf. Das Objekt enthält numerische Eigenschaften für Zeiteinheiten. Schließen Sie nur die Einheiten ein, die Sie anzeigen möchten.
const duration = { hours: 2, minutes: 30 };
formatter.format(duration);
// "2 hours and 30 minutes"
Die API unterstützt diese Zeiteinheiten: years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds. Verwenden Sie die Einheiten, die zu Ihren Daten passen.
Wählen Sie einen Formatierungsstil
Die Option style steuert die Ausgabedichte. Vier Stile sind verfügbar: long, short, narrow und digital.
Der lange Stil verwendet vollständige Wörter. Verwenden Sie diesen für Fließtext und Barrierefreiheit.
const duration = { hours: 1, minutes: 46, seconds: 40 };
new Intl.DurationFormat('en', { style: 'long' }).format(duration);
// "1 hour, 46 minutes and 40 seconds"
Der kurze Stil verwendet gängige Abkürzungen. Verwenden Sie diesen, wenn der Platz begrenzt ist, aber die Lesbarkeit wichtig ist.
new Intl.DurationFormat('en', { style: 'short' }).format(duration);
// "1 hr, 46 min and 40 sec"
Der schmale Stil verwendet minimale Zeichen. Verwenden Sie diesen für kompakte Anzeigen wie mobile Benutzeroberflächen.
new Intl.DurationFormat('en', { style: 'narrow' }).format(duration);
// "1h 46m 40s"
Der digitale Stil erzeugt eine timer-ähnliche Ausgabe mit Doppelpunkten. Verwenden Sie diesen für Mediaplayer und Countdown-Anzeigen.
new Intl.DurationFormat('en', { style: 'digital' }).format(duration);
// "1:46:40"
Lokalisierung über verschiedene Sprachen hinweg
Die gleiche Dauer wird in jeder Sprache unterschiedlich formatiert. Die API übernimmt automatisch die gesamte Lokalisierung.
const duration = { hours: 1, minutes: 46, seconds: 40 };
new Intl.DurationFormat('en', { style: 'long' }).format(duration);
// "1 hour, 46 minutes and 40 seconds"
new Intl.DurationFormat('fr', { style: 'long' }).format(duration);
// "1 heure, 46 minutes et 40 secondes"
new Intl.DurationFormat('de', { style: 'long' }).format(duration);
// "1 Stunde, 46 Minuten und 40 Sekunden"
new Intl.DurationFormat('es', { style: 'long' }).format(duration);
// "1 hora, 46 minutos y 40 segundos"
new Intl.DurationFormat('ja', { style: 'long' }).format(duration);
// "1時間46分40秒"
Beachten Sie, wie jede Locale unterschiedliche Wörter, Abkürzungen und Konjunktionen verwendet. Französisch verwendet "et", Deutsch verwendet "und", Spanisch verwendet "y", Japanisch verwendet keine Konjunktionen. Die API kennt diese Regeln.
Kurze und schmale Stile werden ebenfalls korrekt lokalisiert.
new Intl.DurationFormat('fr', { style: 'short' }).format(duration);
// "1 h, 46 min et 40 s"
new Intl.DurationFormat('de', { style: 'narrow' }).format(duration);
// "1 Std. 46 Min. 40 Sek."
Dauer-Objekte aus Zeitberechnungen erstellen
Dauer-Objekte sind einfache JavaScript-Objekte mit Zeiteinheiten als Eigenschaften. Erstellen Sie sie aus beliebigen Zeitberechnungen.
Konvertieren Sie Millisekunden in Dauereinheiten, indem Sie durch die entsprechenden Faktoren teilen.
const milliseconds = 6400000; // 1 Stunde, 46 Minuten, 40 Sekunden
const hours = Math.floor(milliseconds / 3600000);
const minutes = Math.floor((milliseconds % 3600000) / 60000);
const seconds = Math.floor((milliseconds % 60000) / 1000);
const duration = { hours, minutes, seconds };
new Intl.DurationFormat('en', { style: 'short' }).format(duration);
// "1 hr, 46 min and 40 sec"
Berechnen Sie die Dauer zwischen zwei Datumsangaben, indem Sie die Zeitstempel subtrahieren.
const start = new Date('2025-01-01T10:00:00');
const end = new Date('2025-01-01T11:46:40');
const diffMs = end - start;
const hours = Math.floor(diffMs / 3600000);
const minutes = Math.floor((diffMs % 3600000) / 60000);
const seconds = Math.floor((diffMs % 60000) / 1000);
const duration = { hours, minutes, seconds };
Schließen Sie nur die Einheiten ein, die Sie benötigen. Lassen Sie Nullwerte weg, es sei denn, Sie möchten sie anzeigen.
const duration = { minutes: 5, seconds: 30 };
new Intl.DurationFormat('en', { style: 'long' }).format(duration);
// "5 minutes and 30 seconds"
Steuern, welche Einheiten angezeigt werden
Standardmäßig zeigt der Formatierer alle Einheiten an, die Sie im Dauer-Objekt angeben. Steuern Sie die Anzeige der Einheiten mit dem Options-Objekt.
Legen Sie den Anzeigestil für jede Einheit individuell fest. Optionen sind long, short, narrow, numeric und 2-digit.
const duration = { hours: 1, minutes: 5, seconds: 3 };
new Intl.DurationFormat('en', {
hours: 'long',
minutes: 'numeric',
seconds: '2-digit'
}).format(duration);
// "1 hour, 5:03"
Der Stil numeric zeigt die Zahl ohne Beschriftungen an. Der Stil 2-digit fügt eine Nullauffüllung hinzu. Verwenden Sie diese für kompakte Anzeigen, die Text und Zahlen mischen.
Blenden Sie Einheiten aus, indem Sie sie sowohl aus dem Dauer-Objekt als auch aus den Optionen weglassen.
const duration = { hours: 2, minutes: 30 };
new Intl.DurationFormat('en', { style: 'short' }).format(duration);
// "2 hr and 30 min"
Der digitale Stil erfordert, dass alle Einheiten von der größten bis zur kleinsten vorhanden oder explizit konfiguriert sind.
const duration = { minutes: 5, seconds: 30 };
new Intl.DurationFormat('en', { style: 'digital' }).format(duration);
// "5:30"
Formatierung von Videoplayer-Laufzeiten
Videoplayer zeigen die Laufzeit in den Steuerungselementen an. Verwenden Sie den schmalen oder digitalen Stil für eine kompakte Anzeige.
function formatVideoDuration(seconds) {
const hours = Math.floor(seconds / 3600);
const minutes = Math.floor((seconds % 3600) / 60);
const secs = Math.floor(seconds % 60);
const duration = hours > 0
? { hours, minutes, seconds: secs }
: { minutes, seconds: secs };
const locale = navigator.language;
return new Intl.DurationFormat(locale, { style: 'digital' }).format(duration);
}
formatVideoDuration(6400); // "1:46:40"
formatVideoDuration(330); // "5:30"
Dies behandelt sowohl kurze als auch lange Videos, indem Stunden bedingt einbezogen werden.
Formatierung von Flug- und Reisezeiten
Reisebuchungsschnittstellen zeigen die Reisedauer an. Verwenden Sie den kurzen Stil für bessere Lesbarkeit bei begrenztem Platz.
function formatFlightDuration(departureDate, arrivalDate, locale) {
const diffMs = arrivalDate - departureDate;
const hours = Math.floor(diffMs / 3600000);
const minutes = Math.floor((diffMs % 3600000) / 60000);
const duration = { hours, minutes };
return new Intl.DurationFormat(locale, { style: 'short' }).format(duration);
}
const departure = new Date('2025-06-15T10:30:00');
const arrival = new Date('2025-06-15T18:45:00');
formatFlightDuration(departure, arrival, 'en');
// "8 hr and 15 min"
formatFlightDuration(departure, arrival, 'fr');
// "8 h et 15 min"
Formatierung von Trainings- und Aktivitätsdauern
Fitness-Apps verfolgen die Trainingsdauer. Verwenden Sie den langen Stil für Sitzungszusammenfassungen und den schmalen Stil für Listenansichten.
function formatWorkoutDuration(startTime, endTime, locale) {
const diffMs = endTime - startTime;
const hours = Math.floor(diffMs / 3600000);
const minutes = Math.floor((diffMs % 3600000) / 60000);
const duration = hours > 0
? { hours, minutes }
: { minutes };
return new Intl.DurationFormat(locale, { style: 'long' }).format(duration);
}
const workoutStart = new Date('2025-06-15T07:00:00');
const workoutEnd = new Date('2025-06-15T08:15:00');
formatWorkoutDuration(workoutStart, workoutEnd, 'en');
// "1 hour and 15 minutes"
Formatierte Teile für benutzerdefinierte Anzeige erhalten
Die Methode formatToParts() gibt ein Array von Objekten zurück, die jeweils einen Teil der formatierten Ausgabe darstellen. Verwenden Sie dies, um einzelne Teile zu gestalten oder benutzerdefinierte Layouts zu erstellen.
const duration = { hours: 1, minutes: 46, seconds: 40 };
const parts = new Intl.DurationFormat('en', { style: 'long' }).formatToParts(duration);
Jeder Teil hat einen type und einen value. Typen umfassen hour, minute, second, literal und Einheitsbezeichnungen wie hourUnit, minuteUnit.
[
{ type: "integer", value: "1" },
{ type: "literal", value: " " },
{ type: "unit", value: "hour" },
{ type: "literal", value: ", " },
{ type: "integer", value: "46" },
{ type: "literal", value: " " },
{ type: "unit", value: "minutes" },
{ type: "literal", value: " and " },
{ type: "integer", value: "40" },
{ type: "literal", value: " " },
{ type: "unit", value: "seconds" }
]
Iterieren Sie über die Teile, um benutzerdefinierte Formatierungen anzuwenden.
function StyledDuration({ duration }) {
const parts = new Intl.DurationFormat('en', { style: 'long' }).formatToParts(duration);
return parts.map((part, i) => {
if (part.type === 'integer') {
return <strong key={i}>{part.value}</strong>;
}
return <span key={i}>{part.value}</span>;
});
}
Formatter-Instanzen für bessere Performance wiederverwenden
Die Erstellung eines neuen Formatters für jede Dauer verursacht Overhead. Erstellen Sie den Formatter einmal und verwenden Sie ihn wieder.
const formatter = new Intl.DurationFormat('en', { style: 'short' });
const durations = [
{ hours: 1, minutes: 30 },
{ hours: 2, minutes: 15 },
{ hours: 0, minutes: 45 }
];
durations.map(d => formatter.format(d));
// ["1 hr and 30 min", "2 hr and 15 min", "45 min"]
Dieses Muster verbessert die Performance beim Formatieren vieler Zeitdauern in Schleifen oder Renderings.
Migration von manueller String-Erstellung
Ersetzen Sie manuelle String-Verkettung durch die API. Dies reduziert Code und fügt Lokalisierung hinzu.
Vorher:
function formatDuration(hours, minutes) {
if (hours > 0 && minutes > 0) {
return `${hours}h ${minutes}m`;
} else if (hours > 0) {
return `${hours}h`;
} else {
return `${minutes}m`;
}
}
Nachher:
function formatDuration(hours, minutes, locale) {
const duration = {};
if (hours > 0) duration.hours = hours;
if (minutes > 0) duration.minutes = minutes;
return new Intl.DurationFormat(locale, { style: 'narrow' }).format(duration);
}
Die API-Version verarbeitet automatisch die gesamte bedingte Logik und unterstützt mehrere Sprachen.
Migration von Bibliotheken
Bibliotheken wie Moment.js und date-fns bieten Dauerformatierung, erhöhen jedoch die Bundle-Größe. Die native API eliminiert diese Abhängigkeit.
Ersetzen Sie die Moment.js-Dauerformatierung:
// Vorher: Moment.js
const duration = moment.duration(6400, 'seconds');
const formatted = duration.hours() + 'h ' + duration.minutes() + 'm';
// Nachher: Intl.DurationFormat
const duration = {
hours: Math.floor(6400 / 3600),
minutes: Math.floor((6400 % 3600) / 60)
};
new Intl.DurationFormat('en', { style: 'narrow' }).format(duration);
Ersetzen Sie die date-fns-Dauerformatierung:
// Vorher: date-fns
import { formatDuration, intervalToDuration } from 'date-fns';
const duration = intervalToDuration({ start: 0, end: 6400000 });
const formatted = formatDuration(duration);
// Nachher: Intl.DurationFormat
const ms = 6400000;
const duration = {
hours: Math.floor(ms / 3600000),
minutes: Math.floor((ms % 3600000) / 60000),
seconds: Math.floor((ms % 60000) / 1000)
};
new Intl.DurationFormat('en', { style: 'long' }).format(duration);
Die native API bietet die gleiche Funktionalität ohne Abhängigkeiten.
Browser-Unterstützung und Polyfills
Die Intl.DurationFormat-API wurde im März 2025 zur Baseline. Sie funktioniert in den neuesten Versionen von Chrome, Edge, Firefox und Safari.
Überprüfen Sie die Unterstützung vor der Verwendung:
if (typeof Intl.DurationFormat !== 'undefined') {
const formatter = new Intl.DurationFormat('en', { style: 'short' });
return formatter.format(duration);
} else {
// Fallback für ältere Browser
return `${duration.hours}h ${duration.minutes}m`;
}
Für breitere Unterstützung verwenden Sie ein Polyfill. Das FormatJS-Projekt bietet @formatjs/intl-durationformat.
npm install @formatjs/intl-durationformat
Importieren und polyfill bei Bedarf:
if (!Intl.DurationFormat) {
await import('@formatjs/intl-durationformat/polyfill');
}
Das Polyfill fügt etwa 15KB gzipped hinzu. Laden Sie es bedingt, um Overhead für moderne Browser zu vermeiden.
Wann DurationFormat verwenden
Verwenden Sie Intl.DurationFormat zur Anzeige von verstrichener Zeit, verbleibender Zeit oder Zeitdauermessungen. Dies umfasst Video-Player, Timer, Countdowns, Tracking-Apps, Reisebuchungen und Anzeigen von Sitzungsdauern.
Verwenden Sie es nicht für Datumsangaben, Uhrzeiten oder Zeitstempel. Verwenden Sie dafür Intl.DateTimeFormat. Verwenden Sie es nicht für relative Zeitausdrücke wie "vor 2 Stunden". Verwenden Sie dafür Intl.RelativeTimeFormat.
Die API formatiert Zeitdauern, keine Zeitberechnungen. Sie müssen die Zeitdauerwerte selbst aus Datumsangaben, Zeitstempeln oder anderen Quellen berechnen. Der Formatierer übernimmt nur die Anzeige.