Signatur
Beschreibung
Temporal.Instant.prototype.valueOf() ist absichtlich so gebaut, dass sie immer einen TypeError wirft. JavaScript ruft valueOf() automatisch auf, wenn ein Objekt in einen primitiven Wert umgewandelt werden soll, etwa bei a < b, a - b oder +a. Bei Date liefert das den Zeitstempel in Millisekunden. Bei Temporal.Instant wird dieses Verhalten bewusst unterbunden.
Der Grund: Ein Temporal.Instant hat Nanosekunden-Genauigkeit und speichert seinen Wert intern als BigInt. Eine implizite Umwandlung in eine number würde Genauigkeit verlieren. Außerdem würde ein Vergleich über Zeichenketten (z. B. mit toString()) für Instants zu subtilen Fehlern führen. Deshalb verlangt Temporal explizite Operationen.
Statt der impliziten Umwandlung verwendest du:
Temporal.Instant.compare(a, b)zum Vergleichen und Sortieren,a.equals(b)zum Prüfen auf Gleichheit,a.since(b)bzw.a.until(b)für Zeitdifferenzen,a.epochMillisecondsodera.epochNanoseconds, wenn du wirklich einen Zahlenwert brauchst.
Die Methode wird praktisch nie direkt aufgerufen. Sie ist vor allem dazu da, Fehler früh und laut sichtbar zu machen, statt stillschweigend falsche Ergebnisse zu liefern.
Rückgabewert
TypeError.Beispiele
Vergleichsoperator löst TypeError aus
const a = Temporal.Instant.from('2024-03-01T10:00:00Z');
const b = Temporal.Instant.from('2024-03-01T12:00:00Z');
try {
console.log(a < b); // ruft intern valueOf() auf
} catch (err) {
console.log(err instanceof TypeError, err.name);
}
Richtig vergleichen und sortieren mit Temporal.Instant.compare()
const events = [
Temporal.Instant.from('2024-05-10T08:30:00Z'),
Temporal.Instant.from('2024-01-02T17:00:00Z'),
Temporal.Instant.from('2024-03-15T12:00:00Z'),
];
events.sort(Temporal.Instant.compare);
console.log(events.map((i) => i.toString()));
const [first, second] = events;
console.log(Temporal.Instant.compare(first, second) < 0); // first liegt früher
console.log(first.equals(second));
Differenz berechnen statt subtrahieren
const start = Temporal.Instant.from('2024-06-01T09:00:00Z');
const end = Temporal.Instant.from('2024-06-01T10:45:30Z');
// Falsch: end - start -> TypeError
const dauer = end.since(start, { largestUnit: 'hour' });
console.log(dauer.toString());
// Falls ein Zahlenwert nötig ist, explizit umwandeln:
const diffMs = end.epochMilliseconds - start.epochMilliseconds;
console.log(diffMs);
Direkter Aufruf von valueOf()
const now = Temporal.Now.instant();
try {
now.valueOf();
} catch (err) {
console.log(err.constructor.name);
}
// Wichtig · Fallstricke
Fallstrick bei der Migration von Date: Code wie a < b, b - a, +instant oder Math.max(a, b) funktioniert mit Date, wirft mit Temporal.Instant aber einen TypeError. Ersetze solche Stellen durch Temporal.Instant.compare(), equals(), since()/until() oder durch epochMilliseconds.
Achtung bei == und ===: Diese Operatoren rufen bei zwei Objekten kein valueOf() auf. Sie vergleichen nur die Referenzen und liefern daher auch bei gleichem Zeitpunkt false, ohne einen Fehler zu werfen. Für die Gleichheit immer equals() verwenden.
Template-Literale und String() funktionieren weiterhin, weil dabei toString() aufgerufen wird und nicht valueOf().
Kompatibilität: Temporal ist erst seit Kurzem in Browsern verfügbar (Firefox 139+, Chrome 144+). Safari und ältere Node.js-Versionen unterstützen es noch nicht vollständig. Für produktiven Einsatz empfiehlt sich ein Polyfill wie @js-temporal/polyfill oder temporal-polyfill.