Start · Sprachen · JavaScript · Referenz · Intl.DateTimeFormat.prototype.formatRangeToParts()

Intl.DateTimeFormat.prototype.formatRangeToParts()

Methode

Formatiert einen Datumsbereich wie <code>formatRange()</code>, gibt das Ergebnis aber als Array einzelner Teile mit <code>type</code>, <code>value</code> und <code>source</code> zurück.

seit JavaScript ES2021 (ECMA-402 8. Ausgabe) · Baseline seit 2021: Kategorie: method-property

Signatur

Intl.DateTimeFormat.prototype.formatRangeToParts(startDate, endDate)

Beschreibung

formatRangeToParts() ist das Gegenstück zu formatRange(), so wie formatToParts() das Gegenstück zu format() ist. Statt eines fertigen Strings wie "10:00 – 11:00 AM" erhältst du ein Array von Objekten. Jedes Objekt steht für einen Teil des formatierten Bereichs, z. B. Stunde, Minute, Trennzeichen oder Tageszeit (AM/PM).

Jedes Teil-Objekt hat drei Eigenschaften:

  • type: die Art des Teils, z. B. "day", "month", "year", "hour", "minute", "second", "weekday", "dayPeriod", "timeZoneName", "era", "fractionalSecond" oder "literal" für feste Zeichen wie Trenner und Leerzeichen.
  • value: der formatierte Text dieses Teils als String.
  • source: woher der Teil stammt. "startRange" gehört zum Startdatum, "endRange" zum Enddatum, und "shared" kennzeichnet Teile, die beide gemeinsam haben (etwa der Bereichstrenner oder ein gemeinsamer Monat bzw. ein gemeinsames Jahr).

Das ist praktisch, wenn du einen Datumsbereich eigen gestalten willst: Start- und Enddatum unterschiedlich hervorheben, den Trenner austauschen oder einzelne Teile in eigenes Markup setzen, z. B. für Kalender-Widgets, Buchungsformulare oder Veranstaltungslisten. Die sprachabhängige Reihenfolge und das Zusammenfassen gemeinsamer Teile übernimmt dabei weiterhin die Intl-API.

Unterscheiden sich die beiden Daten bei der gewählten Genauigkeit nicht (z. B. gleicher Tag, obwohl nur Tag/Monat/Jahr angezeigt werden), entspricht das Ergebnis dem von formatToParts(). Dann haben alle Teile source: "shared".

Parameter

Name Typ Default Beschreibung
$startDate Pflicht Date | number | Temporal.PlainDateTime | Temporal.PlainDate | Temporal.PlainTime | Temporal.PlainYearMonth | Temporal.PlainMonthDay | Temporal.Instant Beginn des Bereichs. Ein Date-Objekt oder ein Zeitstempel in Millisekunden. In Umgebungen mit Temporal-Unterstützung auch passende Temporal-Objekte.
$endDate Pflicht Date | number | Temporal.* Ende des Bereichs. Muss vom selben Typ sein wie startDate (bei Temporal-Objekten Pflicht, sonst TypeError).

Rückgabewert

Typ
Array<{ type: string, value: string, source: "startRange" | "endRange" | "shared" }>
Beschreibung
Ein Array mit den formatierten Teilen in Anzeigereihenfolge. Hängt man alle value-Werte aneinander, erhält man genau den String von formatRange().

Beispiele

Zeitbereich in Teile zerlegen

const start = new Date(Date.UTC(2007, 0, 10, 10, 0, 0));
const end = new Date(Date.UTC(2007, 0, 10, 11, 0, 0));

const fmt = new Intl.DateTimeFormat('en-US', {
  hour: 'numeric',
  minute: 'numeric',
  timeZone: 'UTC',
});

console.log(fmt.formatRange(start, end));
console.table(fmt.formatRangeToParts(start, end));
10:00 – 11:00 AM [ { type: 'hour', value: '10', source: 'startRange' }, { type: 'literal', value: ':', source: 'startRange' }, { type: 'minute', value: '00', source: 'startRange' }, { type: 'literal', value: ' – ', source: 'shared' }, { type: 'hour', value: '11', source: 'endRange' }, { type: 'literal', value: ':', source: 'endRange' }, { type: 'minute', value: '00', source: 'endRange' }, { type: 'literal', value: ' ', source: 'shared' }, { type: 'dayPeriod', value: 'AM', source: 'shared' } ]

Start und Ende im Buchungs-Widget unterschiedlich hervorheben

const escapeHtml = (s) =>
  s.replace(/[&<>"']/g, (c) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[c]));

const fmt = new Intl.DateTimeFormat('de-DE', {
  day: 'numeric',
  month: 'long',
  year: 'numeric',
});

const anreise = new Date(2024, 6, 12);
const abreise = new Date(2024, 6, 19);

const html = fmt
  .formatRangeToParts(anreise, abreise)
  .map(({ value, source }) =>
    source === 'shared'
      ? escapeHtml(value)
      : `<span class="${source}">${escapeHtml(value)}</span>`
  )
  .join('');

document.querySelector('#zeitraum').innerHTML = html;
console.log(fmt.formatRange(anreise, abreise));
12.–19. Juli 2024

Teile nach Herkunft gruppieren und gegen formatRange() prüfen

const fmt = new Intl.DateTimeFormat('de-DE', { dateStyle: 'medium' });
const start = new Date(2024, 2, 28);
const end = new Date(2024, 3, 2);

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

const gruppiert = Object.groupBy(parts, (p) => p.source);
const text = (arr = []) => arr.map((p) => p.value).join('');

console.log('Start:', text(gruppiert.startRange));
console.log('Ende:', text(gruppiert.endRange));

// Zusammengesetzt ergibt sich exakt der formatRange()-String
console.log(parts.map((p) => p.value).join('') === fmt.formatRange(start, end));
Start: 28.03. Ende: 02.04. true

Gleiches Datum: alle Teile sind "shared"

const fmt = new Intl.DateTimeFormat('de-DE', { dateStyle: 'long' });
const morgens = new Date(2024, 4, 1, 8, 0);
const abends = new Date(2024, 4, 1, 20, 0);

// Uhrzeit wird nicht angezeigt, also gleicher Wert
const parts = fmt.formatRangeToParts(morgens, abends);
console.log(parts.every((p) => p.source === 'shared'));
console.log(fmt.formatRange(morgens, abends));
true 1. Mai 2024