Zeitzonen in C++: Wie man aufhört, sich in Zeitzonen zu verwirren

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Warum Zeit eine Qual ist (und wie C++ helfen kann)

\n

Stellen Sie sich vor: Ihr Server verarbeitet Bestellungen aus New York, London und Tokio. Sie speichern den Zeitpunkt der Bestellung in UTC und zeigen dem Benutzer dann an: „Ihre Bestellung wurde um 03:15 erstellt.“ Für einen New Yorker ist das 22:15 des Vortages, für einen Londoner 04:15 Uhr morgens, und ein Tokioter wird mitten in der Nacht von einer Benachrichtigung geweckt. Ein klassisches Problem, das ein einfaches Log in ein Rätsel verwandelt.

\n

In C++ gab es lange Zeit keine vernünftige Standardunterstützung für Zeitzonen. Entwickler quälten sich entweder mit time_t und struct tm oder banden schwere Bibliotheken wie Boost.DateTime ein. Aber mit C++20 hat sich die Situation grundlegend geändert. Die Bibliothek std::chrono erhielt eine vollwertige Unterstützung für Zeitzonen. Und obwohl viele Compiler den Standard noch immer einholen, werden wir uns ansehen, wie Sie bereits heute sauberen und portablen Code für die Arbeit mit Zeitzonen in C++ schreiben können.

\n

In diesem Artikel zeige ich Ihnen, wie Sie mit C++ das Chaos der Zeitzonen in ein geordnetes System verwandeln. Sie lernen, mit std::chrono::tzdb zu arbeiten, UTC in Ortszeit umzuwandeln, die Sommerzeit zu berücksichtigen und typische Fehler zu vermeiden.

\n\n

Grundlagen: Was ist eine Zeitzone in C++ aus Sicht von chrono

\n

In C++20 ist eine Zeitzone nicht nur ein Offset in Stunden relativ zu UTC. Es ist ein vollwertiges Objekt, das die Geschichte der Zeitänderungen in einer Region kennt: wann die Uhren umgestellt wurden, wann die Sommerzeit abgeschafft wurde und welche Regeln dort gelten. All diese Informationen sind in der Zeitzonendatenbank (tzdb) gespeichert, die in die Standardbibliothek integriert ist.

\n\n

Wichtige Typen für die Arbeit mit Zeitzonen

\n

Um nicht den Überblick zu verlieren, merken Sie sich drei grundlegende Typen:

\n
    \n
  • std::chrono::time_zone — repräsentiert eine bestimmte Zeitzone (z. B. "America/New_York").
  • \n
  • std::chrono::zoned_time — eine Kombination aus „Zeitzone + Zeitpunkt“. Dies ist der bequemste Typ zum Speichern und Anzeigen von Zeiten unter Berücksichtigung der Zeitzone.
  • \n
  • std::chrono::time_zone_link — alternative Namen für Zonen (z. B. kann "US/Eastern" ein Link auf "America/New_York" sein).
  • \n
\n\n

Liste aller Zeitzonen abrufen

\n

Beginnen wir mit etwas Einfachem: Wir geben alle verfügbaren Zeitzonen aus. Dies ist nützlich, wenn Sie dem Benutzer die Auswahl seiner Zeitzone ermöglichen möchten.

\n\n
#include <iostream>\n#include <chrono>\n#include <string>\n\nint main() {\n    // Zugriff auf die Zeitzonendatenbank\n    const auto& tzdb = std::chrono::get_tzdb();\n    \n    // Namen aller Zonen ausgeben\n    std::cout << "Verfügbare Zeitzonen (" << tzdb.zones.size() << "):\\n";\n    for (const auto& zone : tzdb.zones) {\n        std::cout << zone.name() << '\\n';\n    }\n    return 0;\n}
\n\n

Beachten Sie: get_tzdb() gibt eine konstante Referenz zurück. Die Datenbank wird beim ersten Aufruf einmal geladen und zwischengespeichert. Das bedeutet, Sie können diese Funktion bedenkenlos in verschiedenen Teilen Ihres Programms aufrufen – der Overhead entsteht nur beim ersten Zugriff.

\n\n

Zeitumrechnung zwischen Zeitzonen in C++

\n

Kommen wir nun zum Wichtigsten – der Konvertierung. Angenommen, Sie haben eine Zeit in UTC und möchten sie dem Benutzer in seiner lokalen Zeitzone anzeigen. Oder umgekehrt: Der Benutzer gibt ein Datum in seiner Ortszeit ein, und Sie müssen es in UTC speichern.

\n\n

Von UTC in Ortszeit

\n

Szenario: Der Server hat den Zeitpunkt eines Ereignisses in UTC erhalten (z. B. 2024-12-01 15:30:00 UTC). Es soll für die Zone "Europe/Moscow" angezeigt werden.

\n\n
#include <iostream>\n#include <chrono>\n#include <format> // C++20 für Formatierung\n\nint main() {\n    using namespace std::chrono;\n    \n    // 1. Zeitpunkt in UTC erstellen\n    // 2024-12-01 15:30:00 UTC\n    auto tp = sys_days{December / 1 / 2024} + 15h + 30min;\n                

Blogs

Buchempfehlungen