Signatur
Beschreibung
startOfDay() liefert den ersten tatsächlich existierenden Zeitpunkt des Datums der Instanz – in derselben Zeitzone und mit demselben Kalender. Das Ergebnis ist ein neues, unveränderliches Temporal.ZonedDateTime. Das Originalobjekt bleibt unverändert.
Meistens ist das 00:00:00 Uhr. Es gibt aber Zeitzonen, in denen die Sommerzeit genau um Mitternacht beginnt, z. B. früher America/Sao_Paulo oder heute noch America/Havana. Dort gibt es 00:00 Uhr an diesem Tag gar nicht, und der Tag beginnt erst um 01:00 Uhr. startOfDay() berücksichtigt das automatisch. Deshalb ist die Methode zuverlässiger als zdt.with({ hour: 0, minute: 0, … }) oder zdt.round({ smallestUnit: "day", roundingMode: "floor" }), wenn du wirklich den Tagesanfang meinst.
Typische Einsätze:
- Tagesgrenzen für Abfragen berechnen, etwa „alle Buchungen von heute“ als halboffenes Intervall
[startOfDay, nächster startOfDay). - Die seit Tagesbeginn vergangene echte Zeit ermitteln.
- Termine in Kalender-Ansichten nach Tagen gruppieren.
Rückgabewert
Temporal.ZonedDateTime für den ersten Moment des Kalendertags. Zeitzone und Kalender bleiben gleich. Die Uhrzeit ist meist 00:00, bei einem Sommerzeitbeginn um Mitternacht aber später.Beispiele
Tagesbeginn eines Zeitpunkts ermitteln
const termin = Temporal.ZonedDateTime.from("2024-03-15T14:30:00+01:00[Europe/Berlin]");
const beginn = termin.startOfDay();
console.log(beginn.toString());
console.log(termin.toString()); // Original bleibt unverändert
Sonderfall: Sommerzeitbeginn um Mitternacht
// In São Paulo begann die Sommerzeit am 18.10.2015 um 00:00 Uhr –
// die Uhr sprang direkt auf 01:00 Uhr.
const zdt = Temporal.ZonedDateTime.from({
timeZone: "America/Sao_Paulo",
year: 2015, month: 10, day: 18, hour: 12
});
console.log(zdt.startOfDay().toString());
console.log(zdt.hoursInDay);
Seit Tagesbeginn vergangene echte Zeit (Tag der Zeitumstellung)
// Am 31.03.2024 wurde in Berlin um 02:00 auf 03:00 vorgestellt
const jetzt = Temporal.ZonedDateTime.from("2024-03-31T14:30:00+02:00[Europe/Berlin]");
const vergangen = jetzt.since(jetzt.startOfDay());
console.log(vergangen.toString());
console.log(`${vergangen.total("minutes")} Minuten seit Tagesbeginn`);
Tagesintervall für eine Datenbankabfrage
const heuteGrenzen = (timeZone) => {
const beginn = Temporal.Now.zonedDateTimeISO(timeZone).startOfDay();
const ende = beginn.add({ days: 1 }).startOfDay(); // exklusive Obergrenze
return {
von: beginn.toInstant().toString(),
bis: ende.toInstant().toString(),
stunden: beginn.until(ende).total("hours")
};
};
console.log(heuteGrenzen("Europe/Berlin"));
// Wichtig · Fallstricke
- Nicht immer Mitternacht: Gehe nicht davon aus, dass
startOfDay().hour === 0gilt. Beginnt die Sommerzeit um Mitternacht, ist die Uhrzeit später, z. B. 01:00. - Tagesende: Es gibt kein
endOfDay(). Nimm als exklusive Obergrenze den Tagesbeginn des Folgetags:zdt.add({ days: 1 }).startOfDay(). Vermeide „23:59:59.999…“ – damit fallen Randwerte heraus, und es bricht an Tagen mit Zeitumstellung. - Tageslänge: Ein Tag ist nicht immer 24 Stunden lang. Mit
hoursInDayoderstart.until(nextStart)bekommst du die tatsächliche Länge, z. B. 23 oder 25 Stunden. - Gleichwertige Alternative:
zdt.toPlainDate().toZonedDateTime(zdt.timeZoneId)liefert dasselbe Ergebnis.startOfDay()ist aber kürzer und drückt die Absicht klarer aus. - Unveränderlichkeit: Die Methode ändert das Objekt nicht, sondern gibt immer eine neue Instanz zurück.
- Kompatibilität: Temporal ist noch nicht Baseline. Es wird ab Firefox 139 und Chrome/Edge 144 unterstützt, Safari unterstützt es noch nicht. Für ältere Umgebungen und Node.js ohne Temporal gibt es den Polyfill
@js-temporal/polyfillodertemporal-polyfill.