Wie du die Ortszeit eines Benutzers vor dem Speichern in UTC umwandelst

Entwickler
scheduling

Ein Benutzer bucht ein Meeting für „15 Uhr am Freitag.” Was in deine Datenbank geschrieben wird, hängt von einer Frage ab: Hast du die Ortszeit vor dem Speichern in UTC konvertiert?

Wenn nicht, hast du 2026-06-20 15:00:00 ohne Zeitzonenkontext gespeichert. Wenn du es abrufst und einem anderen Benutzer anzeigst – oder demselben Benutzer nach einer DST-Umstellung – wird die Zeit falsch sein.

Die Regel: immer UTC speichern. Immer aus der IANA-Zeitzone des Benutzers am Eingabepunkt konvertieren. Niemals einen festen Offset speichern.

Der korrekte Eingabe-Flow

Benutzer wählt: Freitag, 20. Juni, 15:00 Uhr
Zeitzone des Benutzers: America/New_York (aus Browser oder Profil)

Konvertierung bei Eingabe:
  2026-06-20T15:00:00 America/New_York
  → 2026-06-20T19:00:00Z  (UTC, da EDT = UTC−4 im Juni)

Speichern: 2026-06-20T19:00:00Z

Beim Abrufen zurück in die Ortszeit des Benutzers konvertieren:

2026-06-20T19:00:00Z → 15:00 Uhr America/New_York ✓
2026-06-20T19:00:00Z → 20:00 Uhr Europe/London ✓  (für einen anderen Teilnehmer)

Die Zeitzone des Benutzers ermitteln

Im Browser:

const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
// → "America/New_York"

Schicke das zusammen mit dem Datums-String an dein Backend. Vertraue dem nicht blind – lass Benutzer es in ihrem Profil bestätigen oder überschreiben. Manche Geräte melden falsche Zonen.

Node.js mit date-fns-tz:

import { fromZonedTime } from "date-fns-tz";

const localDateString = "2026-06-20T15:00:00"; // aus Benutzereingabe
const timeZone = "America/New_York"; // aus Browser/Profil

const utcDate = fromZonedTime(localDateString, timeZone);
// utcDate ist ein JS-Date-Objekt, das 2026-06-20T19:00:00Z repräsentiert

Python (mit zoneinfo, Python 3.9+):

from datetime import datetime
from zoneinfo import ZoneInfo

local_dt = datetime(2026, 6, 20, 15, 0, 0, tzinfo=ZoneInfo("America/New_York"))
utc_dt = local_dt.astimezone(ZoneInfo("UTC"))
# utc_dt → 2026-06-20 19:00:00+00:00

Die DST-Ambiguitätsfalle

In der Nacht, in der die Uhren zurückgestellt werden, tritt 1:30 Uhr America/New_York zweimal auf – einmal vor der Umstellung und einmal danach. Wenn ein Benutzer eine Zeit in dieser wiederholten Stunde wählt, lässt sich nicht wissen, welche Variante gemeint ist.

Die meisten Bibliotheken wählen standardmäßig das frühere (Vor-Umstellungs-)Vorkommen. Mache das in deinem Code explizit, anstatt auf den Standard zu vertrauen. Für Scheduling-Tools ist die sauberste Lösung, in der zweideutigen Stunde an DST-Übergangsnächten keine Slots anzubieten – oder sie zu markieren und den Benutzer um Bestätigung zu bitten.

Was zu speichern ist

  • Ein UTC-Timestamp (TIMESTAMP WITH TIME ZONE in PostgreSQL, UTC ISO 8601 oder Unix-Epoch)
  • Der IANA-Zonen-String des Benutzers (America/New_York) neben dem Event, für die Anzeige
  • Nicht: ein reines lokales Datum/Uhrzeit ohne Zone oder ein numerischer Offset wie −04:00

Die IANA-Zone ist für die Anzeige. Der UTC-Timestamp ist für Vergleiche, Sortierung und Kalenderarithmetik.

Buy me a coffe