Zum Inhalt springen
Server: …♫ Spotify: gerade nichts an
Gelsenkirchen ·
Notiz · Sommerfrische · August 2026

Einen Tag zu früh.

Ein Kalendertag ist kein Zeitpunkt

Im Urlaubsplaner malt man Tage in einen Kalender. Jeder Tag ist ein String yyyy-mm-dd, gemeint ist der Kalendertag — keine Uhrzeit, keine Zone. Erzeugt man dafür ein lokales Mitternachtsdatum und serialisiert es mit toISOString(), landet man in Berlin einen Tag davor.

Die Unterscheidung klingt klein, betrifft aber die ganze Planung. Wenn jemand den 12. Juli auswählt, ist genau dieses Kalenderfeld gemeint. Es soll nicht abhängig vom Standort des Browsers einen anderen Tag bezeichnen. Eine Uhrzeit auf einer globalen Zeitachse würde hier zusätzliche Bedeutung einführen, die die Auswahl gar nicht hat.

new Date(2026, 6, 12)       // 12. Juli, lokal

.toISOString().slice(0,10)  → 2026-07-11   ✗
iso(d) aus lib/dates.ts     → 2026-07-12   ✓

Eine gemeinsame Grenze für Datumswerte

In diesem Beispiel gilt in Berlin Sommerzeit: toISOString() rechnet auf UTC zurück, aus Mitternacht wird der Vortag um 22 Uhr. Also gibt es keine Date-Objekte quer durch die App, sondern Helfer, die Strings in lokaler Zeit addieren und formatieren. Ein Urlaub, der einen Tag früher anfängt als angemalt, wäre der Bug, den keiner meldet und alle merken.

Denkbar wäre, alle Operationen konsequent mit UTC durchzuführen. Dann müssten auch das Erzeugen, Addieren und Auslesen dieser Werte durchgehend dazu passen. Im bestehenden Kalender folgt die Lösung stattdessen der lokalen Darstellung: parseISO() zerlegt Jahr, Monat und Tag und erzeugt daraus ein lokales Datum.iso() liest dieselben lokalen Bestandteile wieder aus.addDays() verbindet beide Schritte und liefert erneut einen Datumsstring zurück.

Die Kosten liegen in der Konsequenz

Ein paar zentrale Helfer sind überschaubar. Entscheidend ist, dass Kalender, Auswertung und Beschriftungen dieselbe Bedeutung verwenden. Ein beiläufiges toISOString() an einer neuen Stelle kann die Verschiebung wieder einführen. Der kürzeste Ausdruck ist deshalb nicht automatisch der richtige: An der Grenze zwischen Anzeige und gespeicherten Werten muss er zum Datenmodell passen.

Auch Sommerzeitwechsel bleiben ein Prüfpunkt. Einen Kalendertag weiterzugehen ist nicht in jeder Zeitzone dasselbe wie exakt 24 Stunden zu addieren. Die Helfer halten diese Fragen an einer Stelle, statt sie auf einzelne Komponenten zu verteilen. Der Gewinn ist keine ausgefeilte Datumsarchitektur, sondern eine verlässliche Zusage: Der ausgewählte Tag bleibt der ausgewählte Tag.

← Alle Notizen