Start · Sprachen · JavaScript · Referenz · Date.prototype[Symbol.toPrimitive]()

Date.prototype[Symbol.toPrimitive]()

Methode

Wandelt ein <code>Date</code>-Objekt je nach Hinweis (<code>"string"</code>, <code>"number"</code>, <code>"default"</code>) in einen String oder einen Zeitstempel um.

seit JavaScript ES2015 Kategorie: method-property

Signatur

Date.prototype[Symbol.toPrimitive](hint)

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 wird toString() versucht, danach valueOf(). Ergebnis ist ein lesbarer Datums-String.
  • "number": Zuerst wird valueOf() versucht, danach toString(). 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

Typ
string | number
Beschreibung
Bei "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'));
1705320000000 string string

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());
86400000 string true 2024-01-01T01:00:00.000Z

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`);
Noch 14 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}`);
true 1000 1970-01-01T00:00:00.000Z

// Wichtig · Fallstricke

  • Fallstrick +: date + zahl verkettet Strings statt zu addieren. Wandle das Datum deshalb vorher mit +date, date.getTime() oder Number(date) in eine Zahl um.
  • Gleichheit: == und === vergleichen bei zwei Date-Objekten die Referenz, nicht den Zeitpunkt. Nutze stattdessen a.getTime() === b.getTime().
  • Ein direkter Aufruf ohne gültigen hint löst einen TypeError aus. Das gilt auch, wenn this kein 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.