Apptiva Logo

Warum JavaScript Date oft nicht passt

Um in JavaScript ein Datum abzubilden, verwenden wir oft das Objekt Date. Es ist Bestandteil der Spezifikation und daher überall einsatzbereit. Es gibt da aber so ein paar Probleme…

Publiziert am von Roman Schaller

Ein Datum und insbesondere die Uhrzeit ist ein recht komplexes Konstrukt. Auch wenn es auf den ersten Blick nicht so aussieht. Bei Zeitangaben fragt sich immer, was man wirklich braucht. Manchmal reicht nur ein Datum, manchmal nur die Uhrzeit und manchmal braucht es beides. Wenn die Zeit involviert ist, sollte man sich auch über Zeitzonen Gedanken machen. Das Date-Objekt von JavaScript kann nur ein Datum mit Uhrzeit und Zeitzone. Entspricht dies nicht meinen Anforderungen, ist es im Prinzip das falsche Konstrukt für die Aufgabe.

Was kann schon passieren, wenn ich trotzdem Date verwende?

Je nach dem, in welcher Zeitzone du ein Date erstellst, kann das Resultat recht verwirrend sein:

newDate('01.01.2023').toISOString() // -> '2022-12-31T23:00:00.000Z'

Eigentlich wollten wir nur ein Datum. Wir kriegen aber ein Datum mit Uhrzeit und Zeitzone. Je nach dem, wie wir das Datum jetzt weiterverarbeiten, sind wir plötzlich einen Tag verschoben.

Das Date-Objekt geht beim Parsen immer davon aus, dass das Datum in UTC ist, sofern wir nichts anderes angeben.

Noch lustiger wird es, wenn wir mit diesem Datum jetzt weiterfahren:

const myDate = newDate('01.01.2023');
myDate.getYear(); // -> 123
myDate.getFullYear(); // -> 2023
myDate.getMonth(); // -> 0
myDate.getDay(); // -> 0
myDate.getDate(); // -> 1

getYear hat offensichtlich noch das Jahr-2000-Problem und wurde durch getFullYear ersetzt.

getMonth ist 0-Basiert. Das heisst, Januar wird als 0 dargestellt.

getDay gibt den Wochentag-Index zurück. 0 steht immer für Sonntag. Auch wenn in unseren Breitengraden die Woche am Montag beginnt.

getDate liefert nun wieder den erwarteten Tag im Monat. Allerdings im Gegensatz zum Monat nicht 0-Basiert.

Das sind schon einige Stolpersteine, über die man fallen kann. Aber es gibt noch mehr. Schickt man ein Date in einem JSON über die Leitung, wird dieses in einen ISO-String verwandelt. Auf der anderen Seite kommt aber nicht wieder ein Date an, sondern eben dieser ISO-String, der dann wieder mit Date geparsed werden muss.

Was tun, wenn man nur ein Datum oder eine Uhrzeit braucht?

Um all diesen Schwierigkeiten aus dem Weg zu gehen, verwende ich manchmal einfach Strings und verarbeite sie dann mit entsprechenden Libraries wie dayjs oder date-fns.

Praktisch: Ein String im ISO-Format ohne Zeitzone lässt sich wie das Datum selbst mit Vergleichsoperatoren verwenden.

Hilfe naht

Sucht man die Dokumentation von Date bei Mozilla auf steht schon im zweiten Absatz:

Note: TC39 is working on Temporal, a new Date/Time API. Read more about it on the Igalia blog. It is not yet ready for production use!

Das neue API kann PlainDate, PlainTime, PlainDateTime, ZonedDateTime und vieles mehr. Ich denke, das wird uns einiges an Ärger ersparen.