Unix-Zeitstempel sind eines der wichtigsten Datenformate in der Programmierung – sie erscheinen in Datenbankeinträgen, API-Antworten, Protokolldateien, Dateisystem-Metadaten, Authentifizierungstokens und unzähligen anderen Stellen. Das Format ist elegant und einfach: eine einzelne Ganzzahl, die Sekunden (oder Millisekunden, Mikrosekunden oder Nanosekunden) seit dem 1. Januar 1970 darstellt. Dennoch ist die korrekte Arbeit mit Zeitstempeln aufgrund der Zeitzonenbehandlung, Präzisionsunterschieden zwischen Systemen und Sommerzeit-Randfällen überraschend schwierig. In den folgenden Abschnitten wird erklärt, was die Unix-Zeit ist und warum sie existiert, wie man Zeitzonen bei der Konvertierung richtig handhabt und welche häufigen Fehler Entwickler auch nach jahrelanger Erfahrung bemerken.
Was Unix-Zeit ist und warum sie existiert
Unix-Zeit, auch Epochenzeit oder POSIX-Zeit genannt, ist die Anzahl der Sekunden, die seit dem 1. Januar 1970 um 00:00:00 UTC vergangen sind – ein Referenzpunkt, der als Unix-Epoche bezeichnet wird. Negative Werte stellen Daten vor dieser Epoche dar, positive Werte stellen Daten danach dar. Das Format entstand in den frühen 1970er Jahren, als Unix-Systeme eine kompakte, zeitzonenunabhängige Möglichkeit zum Speichern von Zeitstempeln in Dateisystem-Metadaten und Protokolldatensätzen benötigten. Eine einzelne 32-Bit-Ganzzahl mit Vorzeichen könnte Datumsangaben von 1901 bis 2038 darstellen, was zur Entwurfszeit ausreichend erschien, aber das berühmte Jahr-2038-Problem verursacht, wenn dieser Bereich abläuft. Moderne Systeme verwenden 64-Bit-Ganzzahlen, wodurch der Ablauf auf das Jahr 292 Milliarden verschoben wird. Die Eleganz der Unix-Zeit besteht darin, dass sie keine Zeitzone, keine Sommerzeit, keine Schaltsekunden (offiziell – die meisten Implementierungen verschmieren einfach die seltenen Schaltsekunden) und keine Kalenderkomplexität hat. Es ist ein monoton steigender Zähler, der einen bestimmten Moment eindeutig identifiziert. Zeitzonen, Kalenderdaten und für Menschen lesbare Formate werden zur Anzeigezeit überlagert. Dies macht die Unix-Zeit zum bevorzugten Format für Vergleiche („if (tokenExpiresAt < now)“), Sortieren und Speichern von Zeitstempeln in Datenbanken über verteilte Systeme hinweg, die Zeitzonen umfassen. Für Menschen lesbare Formate wie „2024-04-21 11:58:41“ werden nur dann aus dem gespeicherten Unix-Wert abgeleitet, wenn sie einem Benutzer angezeigt werden.
Umgang mit Zeitzonen – Der subtile Teil
Ein Unix-Zeitstempel selbst hat keine Zeitzone – er repräsentiert einen bestimmten Moment in absoluter Zeit. Wenn Sie in eine für Menschen lesbare Form konvertieren, wählen Sie eine Zeitzone für die Anzeige aus, und derselbe Zeitstempel erzeugt unterschiedliche Ortszeiten in verschiedenen Zonen. Beispielsweise ist 1713711521 Sekunden nach der Epoche 15:58:41 UTC, aber derselbe Zeitpunkt ist 11:58:41 EDT (Amerika/New_York, UTC-4), 08:58:41 PDT (Amerika/Los_Angeles, UTC-7), 00:58:41 JST am nächsten Tag (Asien/Tokio, UTC+9) und unzählige andere Ortszeiten rund um den Globus. Um dies in der Praxis richtig umzusetzen, sind IANA-Zeitzonennamen wie „America/New_York“ anstelle fester Offsets wie „UTC-05:00“ erforderlich, da IANA-Namen den vollständigen DST-Verlauf kodieren. Die Aussage „15.00 Uhr EST am 15. Juli 2024“ ist eigentlich mehrdeutig, da Eastern Time die Sommerzeit einhält und die Juli-Daten in EDT (UTC-4) und nicht in EST (UTC-5) angegeben sind. IANA-Zeitzonen lösen diese Mehrdeutigkeit automatisch auf – die Intl API des Browsers und serverseitige Bibliotheken wie pytz, moment-timezone und Javas ZoneId nutzen alle die IANA-Datenbank und verarbeiten historische Sommerzeitübergänge korrekt. Dieser Konverter verwendet das integrierte Intl.DateTimeFormat des Browsers mit vollständiger IANA-Zeitzonenunterstützung, was bedeutet, dass er korrekte Ortszeiten für jede gültige Zone erzeugt, einschließlich historischer Daten, die bis ins Jahr 1970 oder früher zurückreichen.
Die häufigsten Fehler, die selbst erfahrene Entwickler befallen
Eine Handvoll Zeitstempelfehler treten so oft auf, dass es sich lohnt, sie als Checkliste zu verinnerlichen. Erstens, Verwirrung zwischen Sekunden und Millisekunden: Das Datumsobjekt von JavaScript arbeitet in Millisekunden, während time.time() von Python in Sekunden arbeitet, und wenn Sie diese versehentlich mischen, werden Ihre Daten mit 1000 multipliziert oder dividiert. Überprüfen Sie die Größe: 10-stellige Zahlen sind Sekunden, 13-stellige Zahlen sind Millisekunden, 16-stellige Zahlen sind Mikrosekunden. Zweitens die Zeitzonenannahme beim Parsen: Die Zeichenfolge „2024-04-21 11:58:41“ hat keine Zeitzone und verschiedene Parser gehen standardmäßig von unterschiedlichen Annahmen aus. Der Date-Konstruktor von JavaScript behandelt es als Ortszeit; Pythons datetime.fromisoformat behandelt es als naiv (keine Zeitzone). Hängen Sie vor dem Parsen immer eine explizite Zeitzone an mehrdeutige Zeichenfolgen an. Drittens, Sommerzeit-Randfälle bei Frühlings- und Herbstübergängen: 2:30 Uhr am Tag des Vorwärtsspringens gibt es in den meisten US-Zeitzonen nicht (die Uhr springt von 1:59 auf 3:00), und 1:30 Uhr am Tag des Zurücksetzens gibt es zweimal. Datumsarithmetik, die Stunden über eine DST-Grenze hinweg addiert oder subtrahiert, kann zu überraschenden Ergebnissen führen, es sei denn, Sie verwenden IANA-fähige Bibliotheken. Viertens: „Jetzt“-Drift über Server hinweg: Die Serveruhren weichen um Millisekunden oder Sekunden ab, sodass Token, die auf einem Server generiert und auf einem anderen validiert werden, ein Toleranzfenster benötigen. Fünftens: Schaltsekunden: Sie sind in der Praxis selten relevant, da sie von den meisten Systemen verwischt werden, sind aber für präzise wissenschaftliche oder finanzielle Anwendungen von entscheidender Bedeutung. Dieser Konverter umgeht die meisten dieser Probleme, indem er die bewährten Intl-APIs des Browsers verwendet. Die zugrunde liegenden Konzepte sind jedoch immer noch wichtig, wenn Code geschrieben wird, der konvertierte Werte verwendet.