Signatur
Beschreibung
Die Methode Date.prototype[Symbol.toPrimitive]() legt fest, wie ein Date-Objekt in einen primitiven Wert umgewandelt wird. Die JavaScript-Engine ruft sie automatisch auf, sobald ein Datum in einem Kontext steht, der einen primitiven Wert braucht, etwa bei +, -, Vergleichen, Template-Literalen oder String()/Number().
Der Parameter hint bestimmt das Ergebnis:
"string"oder"default": Zuerst wirdtoString()versucht, danachvalueOf(). Ergebnis ist ein lesbarer Datums-String."number": Zuerst wirdvalueOf()versucht, danachtoString(). Ergebnis sind die Millisekunden seit der Unix-Epoche.
Die Besonderheit von Date: Bei fast allen anderen Objekten wird der Hinweis "default" wie "number" behandelt. Date behandelt ihn dagegen wie "string". Deshalb liefert date + 1 eine String-Verkettung, date - 1 dagegen eine Zahl.
Direkt aufrufen muss man die Methode nur selten. Wer sie kennt, versteht aber, warum Datumsarithmetik mit + scheitert und warum Vergleiche wie a < b trotzdem funktionieren: Relationale Operatoren übergeben den Hinweis "number".
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $hint Pflicht | "string" | "number" | "default" | Gibt an, welcher primitive Typ gewünscht ist. "default" wird bei Date wie "string" behandelt. Jeder andere Wert (auch undefined) löst einen TypeError aus. |
Rückgabewert
"string" und "default" der Datums-String (wie bei toString()), bei "number" der Zeitstempel in Millisekunden (wie bei valueOf()). Bei einem ungültigen Datum ist das "Invalid Date" bzw. NaN.Beispiele
Direkter Aufruf mit allen drei Hinweisen
const d = new Date(Date.UTC(2024, 0, 15, 12, 0, 0));
console.log(d[Symbol.toPrimitive]('number'));
console.log(typeof d[Symbol.toPrimitive]('string'));
console.log(typeof d[Symbol.toPrimitive]('default'));
Implizite Umwandlung: + vs. - und Vergleiche
const start = new Date(Date.UTC(2024, 0, 1));
const ende = new Date(Date.UTC(2024, 0, 2));
// '-' fordert den Hinweis "number" an und liefert eine Differenz in ms
console.log(ende - start);
// '+' fordert "default" an, bei Date also einen String -> Verkettung!
console.log(typeof (start + 1000));
// Vergleiche nutzen "number"
console.log(start < ende);
// Richtig addieren: vorher in eine Zahl umwandeln
const spaeter = new Date(+start + 60 * 60 * 1000);
console.log(spaeter.toISOString());
Dauer in Tagen berechnen
const tageZwischen = (a, b) => Math.round((b - a) / 86_400_000);
const heute = new Date('2024-03-01');
const deadline = new Date('2024-03-15');
console.log(`Noch ${tageZwischen(heute, deadline)} Tage`);
Fehlerhafter Hinweis und eigenes Verhalten in einer Unterklasse
const d = new Date(0);
try {
d[Symbol.toPrimitive]('boolean');
} catch (e) {
console.log(e instanceof TypeError);
}
// Unterklasse, bei der '+' mit Zahlen rechnet
class NumDate extends Date {
[Symbol.toPrimitive](hint) {
return hint === 'string' ? this.toISOString() : this.getTime();
}
}
const n = new NumDate(0);
console.log(n + 1000);
console.log(`${n}`);
// Wichtig · Fallstricke
- Fallstrick
+:date + zahlverkettet Strings statt zu addieren. Wandle das Datum deshalb vorher mit+date,date.getTime()oderNumber(date)in eine Zahl um. - Gleichheit:
==und===vergleichen bei zweiDate-Objekten die Referenz, nicht den Zeitpunkt. Nutze stattdessena.getTime() === b.getTime(). - Ein direkter Aufruf ohne gültigen
hintlöst einenTypeErroraus. Das gilt auch, wennthiskein Objekt ist. - Die Eigenschaft ist nicht beschreibbar, aber konfigurierbar. Unterklassen können die Methode überschreiben.
- Die String-Form hängt von der lokalen Zeitzone ab. Für stabile Ausgaben eignet sich
toISOString()besser. - Kompatibilität: ab ES2015, in allen modernen Browsern und Node.js verfügbar. Der Internet Explorer unterstützt sie nicht.