Intl.DurationFormat API

Zeitdauern in JavaScript mit automatischer Lokalisierung formatieren

Einführung

Wenn Sie anzeigen, wie lange etwas dauert, müssen Sie Dauerwerte für Benutzer formatieren. Ein Videoplayer zeigt die Laufzeit an, eine Flugbuchung zeigt die Reisezeit an, eine Fitness-App zeigt die Trainingsdauer an. 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 dies. Sie formatiert Zeitdauern entsprechend der Sprache und den kulturellen Konventionen des Benutzers ohne externe Bibliotheken oder manuelle String-Erstellung.

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 Formatter verarbeitet automatisch Abkürzungen, Konjunktionen, Wortreihenfolge und Abstände für jede Locale.

Was sind Dauern

Eine Dauer stellt eine Zeitspanne dar, keinen Zeitpunkt. Daten und Zeiten markieren, wann etwas geschieht. Dauern messen, wie lange etwas dauert.

Diese Unterscheidung ist wichtig für die Formatierung. Daten beinhalten Kalender, Zeitzonen und historische Regeln. Dauern sind einfacher: Sie messen verstrichene Zeit in Standardeinheiten ohne Kalenderkontext.

Die Intl.DurationFormat API verarbeitet Dauern. Die Intl.DateTimeFormat API verarbeitet Daten und Zeiten. Verwenden Sie das richtige Werkzeug für jede Aufgabe.

Einen Dauer-Formatter erstellen

Der Konstruktor nimmt eine Locale und ein Options-Objekt entgegen. Die Locale bestimmt die Ausgabesprache. Die Optionen steuern den Formatierungsstil und die Einheitenanzeige.

const formatter = new Intl.DurationFormat('en', { style: 'long' });

Rufen Sie format() mit einem Dauer-Objekt auf. Das Objekt enthält numerische Eigenschaften für Zeiteinheiten. Fügen 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 bleibt.

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 Media-Player und Countdown-Anzeigen.

new Intl.DurationFormat('en', { style: 'digital' }).format(duration);
// "1:46:40"

Lokalisierung über Sprachen hinweg

Dieselbe Dauer wird in jeder Sprache unterschiedlich formatiert. Die API übernimmt die gesamte Lokalisierung automatisch.

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

Erstellen Sie Duration-Objekte aus Zeitberechnungen

Duration-Objekte sind einfache JavaScript-Objekte mit Zeiteinheiten-Properties. Erstellen Sie sie aus beliebigen Zeitberechnungen.

Konvertieren Sie Millisekunden in Duration-Einheiten, indem Sie durch die entsprechenden Faktoren dividieren.

const milliseconds = 6400000; // 1 hour, 46 minutes, 40 seconds
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 aus zwei Daten, indem Sie 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 };

Fügen Sie nur die Einheiten hinzu, die Sie benötigen. Lassen Sie Nullwerte weg, es sei denn, Sie möchten, dass sie angezeigt werden.

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 Formatter alle Einheiten an, die Sie im Duration-Objekt angeben. Steuern Sie die Anzeige der Einheiten mit dem Options-Objekt.

Geben Sie den Anzeigestil für jede Einheit einzeln an. Die 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 Nullen zum Auffüllen hinzu. Verwenden Sie diese für kompakte Anzeigen, die Text und Zahlen mischen.

Blenden Sie Einheiten aus, indem Sie sie sowohl aus dem Duration-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"

Videoplayer-Dauern formatieren

Videoplayer zeigen die Dauer in den Steuerelementen 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.

Flug- und Reisezeiten formatieren

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"

Trainings- und Aktivitätsdauern formatieren

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 abrufen

Die Methode formatToParts() gibt ein Array von Objekten zurück, die jedes Element der formatierten Ausgabe darstellen. Verwenden Sie dies, um einzelne Teile zu stylen 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. Zu den Typen gehören hour, minute, second, literal und Einheitenbeschriftungen 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 benutzerdefiniertes Styling 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

Das Erstellen 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 Dauern in Schleifen oder Renders.

Migration von manueller String-Erstellung

Ersetzen Sie manuelle String-Konkatenation 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 übernimmt die gesamte bedingte Logik automatisch und unterstützt mehrere Sprachen.

Migration von Bibliotheken

Bibliotheken wie Moment.js und date-fns bieten Dauerformatierung, erhöhen aber die Bundle-Größe. Die native API eliminiert diese Abhängigkeit.

Ersetzen Sie Moment.js-Dauerformatierung:

// Before: Moment.js
const duration = moment.duration(6400, 'seconds');
const formatted = duration.hours() + 'h ' + duration.minutes() + 'm';

// After: 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 date-fns-Dauerformatierung:

// Before: date-fns
import { formatDuration, intervalToDuration } from 'date-fns';
const duration = intervalToDuration({ start: 0, end: 6400000 });
const formatted = formatDuration(duration);

// After: 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.

Prü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 for older browsers
  return `${duration.hours}h ${duration.minutes}m`;
}

Für eine breitere Unterstützung verwenden Sie ein Polyfill. Das FormatJS-Projekt stellt @formatjs/intl-durationformat bereit.

npm install @formatjs/intl-durationformat

Importieren Sie das Polyfill und wenden Sie es bei Bedarf an:

if (!Intl.DurationFormat) {
  await import('@formatjs/intl-durationformat/polyfill');
}

Das Polyfill fügt etwa 15 KB (gzipped) hinzu. Laden Sie es bedingt, um Overhead für moderne Browser zu vermeiden.

Wann DurationFormat verwendet werden sollte

Verwenden Sie Intl.DurationFormat, wenn Sie verstrichene Zeit, verbleibende Zeit oder Dauermessungen anzeigen. Dies umfasst Videoplayer, Timer, Countdowns, Tracking-Apps, Reisebuchungen und Anzeigen der Sitzungsdauer.

Verwenden Sie es nicht für Daten, 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 Dauern, nicht Zeitberechnungen. Sie müssen die Dauerwerte selbst aus Daten, Zeitstempeln oder anderen Quellen berechnen. Der Formatter übernimmt nur die Anzeige.