Start · Sprachen · JavaScript · Referenz · Temporal.Duration.prototype.valueOf()

Temporal.Duration.prototype.valueOf()

Methode

Wirft immer einen <code>TypeError</code>, damit <code>Temporal.Duration</code>-Objekte nicht versehentlich in Zahlen oder Strings umgewandelt und mit <code>&lt;</code>, <code>&gt;</code> oder <code>-</code> verrechnet werden.

seit JavaScript ES2026 (Temporal); Firefox 139+, Chrome 144+; Safa Kategorie: method-property

Signatur

Temporal.Duration.prototype.valueOf()

Beschreibung

Temporal.Duration.prototype.valueOf() gibt nie etwas zurück, sondern wirft bei jedem Aufruf einen TypeError. Das ist so gewollt. Bei einem Vergleich wie d1 > d2 oder einer Rechnung wie d1 - d2 ruft JavaScript intern valueOf() auf. Ohne diese Sperre käme dabei stillschweigend ein falsches Ergebnis heraus, zum Beispiel NaN oder ein Vergleich von Strings.

Eine Dauer lässt sich nicht eindeutig als eine einzige Zahl ausdrücken. Wie lang „1 Monat“ ist, hängt vom Bezugsdatum ab (28 bis 31 Tage), und ein Tag kann bei der Zeitumstellung 23 oder 25 Stunden haben. Deshalb erzwingt Temporal ausdrückliche Operationen:

  • Vergleichen: Temporal.Duration.compare(a, b, { relativeTo })
  • In eine Zahl umrechnen: duration.total({ unit: "seconds" })
  • Als Text ausgeben: duration.toString(), toJSON() oder toLocaleString()
  • Rechnen: duration.add(), subtract() und negated()

Template-Literale und String(duration) funktionieren trotzdem. Bei der Umwandlung in einen String ruft JavaScript zuerst toString() auf und kommt gar nicht bis zu valueOf(). Der +-Operator verwendet dagegen den Hinweis „default“, versucht also zuerst valueOf() und wirft deshalb einen Fehler.

Rückgabewert

Typ
never
Beschreibung
Gibt nie etwas zurück, sondern wirft immer einen TypeError.

Beispiele

Vergleichsoperatoren lösen einen TypeError aus

const a = Temporal.Duration.from({ hours: 2 });
const b = Temporal.Duration.from({ minutes: 90 });

try {
  console.log(a > b);
} catch (err) {
  console.log(err instanceof TypeError);
}
true

Richtig vergleichen mit Temporal.Duration.compare()

const a = Temporal.Duration.from({ hours: 2 });
const b = Temporal.Duration.from({ minutes: 90 });

// -1: a ist kürzer, 0: gleich lang, 1: a ist länger
console.log(Temporal.Duration.compare(a, b));

// Bei Kalendereinheiten (Monate, Jahre) ist relativeTo Pflicht
const m = Temporal.Duration.from({ months: 1 });
const d = Temporal.Duration.from({ days: 30 });
console.log(Temporal.Duration.compare(m, d, { relativeTo: Temporal.PlainDate.from("2024-02-01") }));
1 -1

Dauern sortieren und in Zahlen umrechnen

const laufzeiten = [
  Temporal.Duration.from({ minutes: 45 }),
  Temporal.Duration.from({ hours: 1, minutes: 5 }),
  Temporal.Duration.from({ seconds: 1800 }),
];

// Die Vergleichsfunktion (a, b) => a - b würde einen TypeError werfen
laufzeiten.sort(Temporal.Duration.compare);
console.log(laufzeiten.map((d) => d.toString()));

// Ausdrücklich in eine Einheit umrechnen
const minuten = laufzeiten.map((d) => d.total({ unit: "minutes" }));
console.log(minuten);
["PT1800S", "PT45M", "PT1H5M"] [30, 45, 65]

Umwandlung in einen String funktioniert, + nicht

const dauer = Temporal.Duration.from({ hours: 1, minutes: 30 });

console.log(`Dauer: ${dauer}`);   // ruft toString() auf
console.log(String(dauer));

try {
  console.log("Dauer: " + dauer); // Hinweis "default" → valueOf()
} catch (err) {
  console.log(err.name);
}
Dauer: PT1H30M PT1H30M TypeError

// Wichtig · Fallstricke

  • Sortier-Falle: Die Vergleichsfunktion arr.sort((a, b) => a - b) wirft bei Duration-Objekten einen Fehler. Nutze stattdessen arr.sort(Temporal.Duration.compare). Enthalten die Dauern Jahre, Monate oder Wochen, musst du relativeTo angeben, zum Beispiel (a, b) => Temporal.Duration.compare(a, b, { relativeTo }).
  • + und ==: Auch "x" + duration und duration == "PT1H" werfen einen Fehler. Nutze Template-Literale oder rufe toString() ausdrücklich auf.
  • Gleichheit: === vergleicht nur, ob es dasselbe Objekt ist, nicht ob die Werte gleich sind. Für einen Wertvergleich nimm Temporal.Duration.compare(a, b) === 0. Beachte dabei: PT60M und PT1H gelten dort als gleich, obwohl ihre String-Darstellung verschieden ist.
  • JSON: JSON.stringify() nutzt toJSON() und liefert den ISO-8601-String, z. B. "PT1H30M".
  • Kompatibilität: Temporal gehört zum Standard ES2026. Es läuft in Firefox 139+ und Chrome/Edge 144+. Safari und ältere Node.js-Versionen brauchen einen Polyfill wie @js-temporal/polyfill oder temporal-polyfill.
  • Dasselbe Verhalten haben alle Temporal-Typen, etwa Temporal.Instant, PlainDate und ZonedDateTime.