Zeit in C++20: Details zu der Arbeit mit Zeitzonen
Der Umgang mit Zeitzonen ist mit einigen Herausforderungen verbunden. Die Chrono-Erweiterung in C++20 helfen dabei, sie zu bewältigen.
- Rainer Grimm
Dieser Artikel ist der siebte in meiner ausfĂĽhrlichen Reise durch die Chrono-Erweiterung in C++20:
- Zeit in C++20: EinfĂĽhrung in die Chrono-Terminologie
- Zeit in C++20: EinfĂĽhrung in die Chrono-Terminologie mit Zeitdauer und Zeitpunkt
- Zeit in C++20: Neue Datentypen fĂĽr die Tageszeit und das Kalenderdatum
- Zeit in C++20: Kalendertermine erstellen
- Zeit in C++20: Kalendertermine darstellen und prĂĽfen
- Zeit in C++20: Kalenderdaten abfragen und Ordinaldaten
Zeitzonen
Eine Zeitzone ist zunächst eine Region und ihre gesamte Datumsgeschichte, wie Sommerzeit oder Schaltsekunden.
Herausforderungen
Der Umgang mit Zeitzonen bringt einige Herausforderungen mit sich:
- Winterzeit und Sommerzeit: Viele europäische Länder wie Deutschland verwenden eine sogenannte Sommerzeit und Winterzeit. Die Sommerzeit ist der Winterzeit in Deutschland eine Stunde voraus.
- Weitere Zeitzonen: Länder wie China oder die Vereinigten Staaten haben unterschiedliche Zeitzonen. In den Vereinigten Staaten liegt zum Beispiel zwischen der Hawaii Standard Time (UTC-10) und der Eastern Daylight Time (UTC-4) ein Unterschied von sechs Stunden.
- Zeitzonenunterschiede: Zeitzonenunterschiede sind oft Bruchteile von Stunden, wie 30 oder 45 Minuten. Die australische Zentralzeit ist UTC+9:30, und die australische Central Western Standard Time ist UTC+8:45.
- ZeitzonenabkĂĽrzungen sind mehrdeutig: ADT kann Arabic Daylight Time (UTC+4) oder Atlantic Daylight Time (UTC-3) sein.
Die Zeitzonenbibliothek in C++20 ist ein vollständiger Parser der IANA timezone database. Die folgende Tabelle soll einen ersten Eindruck von der neuen Funktionalität vermitteln.
Die Nutzung der Zeitzonendatenbank erfordert ein Betriebssystem. Daher führt die Verwendung der Zeitzonendatenbank auf einem eigenständigen System normalerweise zu einer Ausnahme. Die Zeitzonendatenbank wird während der Aktualisierung des Betriebssystems, beispielsweise bei einem Neustart, aktualisiert. Wenn ein System die Aktualisierung der IANA-Zeitzonendatenbank ohne Neustart unterstützt, kann man std::chrono::reload_tzdb()
verwenden. Die neue Datenbank wird atomar an den Anfang der verknĂĽpften Liste gesetzt. Aufrufe wie std::chrono::get_tzdb_list()
oder std::chrono::get_tzdb()
parsen den Anfang der Liste. Folglich erhalten die Datenbankabfragen die aktualisierten Datenbankeinträge. std::chrono::get_tzdb().version
gibt die Version der verwendeten Datenbank zurĂĽck.
Die beiden elementaren Datentypen fĂĽr Zeitzonen sind std::chrono::time_zone
und std::chrono::zoned_time.
Die möglichen Zeitzonen sind durch die IANA-Zeitzonendatenbank vordefiniert. Die Aufrufe std::chrono::current_zone()
und std::chrono::locate_zone(name)
geben einen Zeiger auf die aktuelle oder per Name angeforderte Zeitzone zurĂĽck. Der Aufruf std::chrono::locate_zone(name)
fĂĽhrt zu einer Suche nach name
in der Datenbank. Wenn die Suche erfolglos ist, wirft das System eine std::runtime_error
-Ausnahme.
std::chrono::zoned_time()
stellt eine Zeitzone in Kombination mit einem Zeitpunkt dar. Man kann einen Systemzeitpunkt oder einen lokalen Zeitpunkt als Zeitpunkt verwenden. Ein Systemzeitpunkt verwendet std::chrono::system_clock
und ein lokaler Zeitpunkt verwendet die Pseudo-Uhr std::chrono::local_t.
Mein erstes Beispiel ist ganz einfach. Es zeigt die UTC-Zeit und die Ortszeit an.
UTC-Zeit und Ortszeit
Die UTC oder Coordinated Univeral Time ist der wichtigste Zeitstandard weltweit. Ein Computer verwendet die Unix-Zeit, die eine sehr gute Annäherung an die UTC ist. Die UNIX-Zeit ist die Anzahl der Sekunden seit der Unix-Epoche. Die Unix-Epoche ist 00:00:00 UTC am 1. Januar 1970.
std::chrono::system_clock::now()
in (1) gibt im folgenden Programm localTime.cpp
die Unix-Zeit zurĂĽck.
// localTime.cpp
#include <chrono>
#include <iostream>
int main() {
std::cout << '\n';
using std::chrono::floor;
std::cout << "UTC time" << '\n'; // (1)
auto utcTime = std::chrono::system_clock::now();
std::cout << " " << utcTime << '\n';
std::cout << " " << floor<std::chrono::seconds>(utcTime)
<< '\n';
std::cout << '\n';
std::cout << "Local time" << '\n'; // (2)
auto localTime =
std::chrono::zoned_time(std::chrono::current_zone(),
utcTime);
std::cout << " " << localTime << '\n';
std::cout << " " << floor<std::chrono::seconds>
(localTime.get_local_time())
<< '\n';
auto offset = localTime.get_info().offset; // (3)
std::cout << " UTC offset: " << offset << '\n';
std::cout << '\n';
}
Ich habe dem Programm nicht allzu viel hinzuzufĂĽgen. Der Codeblock, der mit (1) beginnt, holt sich den aktuellen Zeitpunkt, schneidet ihn auf Sekunden ab und zeigt ihn an. Der Aufruf std::chrono::zoned_time
erzeugt std::chrono::zoned_time localTime
. Der folgende Aufruf localTime.get_local_time()
gibt den gespeicherten Zeitpunkt als lokale Zeit zurĂĽck. Auch dieser Zeitpunkt wird auf Sekunden abgeschnitten. localTime
(3) kann auch verwendet werden, um Informationen ĂĽber die Zeitzone zu erhalten. In diesem Fall bin ich an der Abweichung von der UTC interessiert.
Wie geht's weiter?
Mein nächster Artikel beantwortet eine wichtige Frage, wenn ich in einer anderen Zeitzone unterrichte: Wann soll ich meinen Online-Kurs beginnen? (rme)