Der Zeitpunkt wird durch seinen Startpunkt, die sogenannte Epoche und die darauf bezogenen Zeitdauer festgelegt. Dabei enthält ein Zeitpunkt einen Zeitgeber(Clock) und eine Zeitdauer (Duration).
Zeitpunkt
Der Zeitpunkt ist eine Klassen-Template. std::chrono::time_point benötigt immer einen Zeitgeber. Die Zeitdauer leitet sich als Default-Argument von dem Zeitgeber ab.
template<
class Clock,
class Duration= typename Clock::duration
>
class time_point;
Es gibt vier besondere Zeitpunkte, die von dem Zeitgeber abhängen.
- epoch: Der Startzeitpunkt des Zeitgebers.
- now: Die aktuelle Zeit.
- min: Der minimale Zeitpunkt, den der Zeitgeber darstellen kann.
- max: Der maximale Zeitpunkt, den der Zeitgeber darstellen kann.
Diese Werte, bzw. die Genauigkeit der Werte unterscheiden sich dadurch, ob der Zeitgeber vom Typ std::system::system_clock, std::chrono::steady_clock oder std::chrono::high_resolution_clock ist.
Der C++-Standard gibt aber keine Garantie für die Genauigkeit, den Startzeitpunkt oder den gültigen Zeitbereich, den einen Zeitgeber darstellen kann. Der Startzeitpunkt von std::chrono:system_clock ist typischerweise der 1.1.1970, die sogenannte UNIX-Epoche. Weiter gilt in der Regel, dass std::chrono::high_resolution_clock eine höhere Auflösung wie std::chrono::system_clock, dass std::chrono::system_clock eine höhere Auflösung wie std::chrono::steady_clock besitzt.
Darstellung eines Zeitpunkts als Datum
Wird ein Zeitpunkt verwendet, der mit der std::chrono::system_clock parametrisiert ist, können die vier Zeitpunkte mit Hilfe der Funktion std::chrono::system_clock::to_time_t in ein Objekt vom Typ std::time_t konvertiert werden. MIt weiteren Konvertierungen dank der Funktionen std::gmtime und std::asctime stehen die Zeitpunkte als Datum in textueller Repräsentation zur Verfügung.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
// timepoint.cpp
#include <chrono>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <string>
int main(){
std::cout << std::endl;
std::chrono::time_point<std::chrono::system_clock> sysTimePoint;
std::time_t tp= std::chrono::system_clock::to_time_t(sysTimePoint);
std::string sTp= std::asctime(std::gmtime(&tp));
std::cout << "Epoch: " << sTp << std::endl;
tp= std::chrono::system_clock::to_time_t(sysTimePoint.min());
sTp= std::asctime(std::gmtime(&tp));
std::cout << "Time min: " << sTp << std::endl;
tp= std::chrono::system_clock::to_time_t(sysTimePoint.max());
sTp= std::asctime(std::gmtime(&tp));
std::cout << "Time max: " << sTp << std::endl;
sysTimePoint= std::chrono::system_clock::now();
tp= std::chrono::system_clock::to_time_t(sysTimePoint);
sTp= std::asctime(std::gmtime(&tp));
std::cout << "Time now: " << sTp << std::endl;
}
|
Schön zeigt die Ausgabe den gültigen Zeitbereich von std::chrono::system_clock. std::chrono::system_clock besitzt die UNIX-Epoche als Startpunkt und kann in Datumsbereiche zwischen 1677 und 2262 konvertiert werden.
Zeitpunkte können mit Zeitdauern verrechnet werden um neue Zeitpunkte zu erhalten. Da stellt sich mir natürlich die Frage. Was passiert, wenn ich mit meiner Berechnung aus dem Gültigkeitsbereich des Zeitgebers rausfalle?
Jenseits des gültigen Zeitbereichs
In meinem Experiment gehe ich von dem aktuellen Zeitpunkt aus und addiere 1000 Jahre hinzu bzw. ziehe 1000 Jahre ab. Der Einfachheit halber ignoriere ich Schaltjahre und nehme an, dass ein Jahr aus 365 Tagen besteht.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
// timepointAddition.cpp
#include <chrono>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <string>
using namespace std::chrono;
std::string timePointAsString(const time_point<system_clock>& timePoint){
std::time_t tp= system_clock::to_time_t(timePoint);
return std::asctime(std::gmtime(&tp));
}
int main(){
std::cout << std::endl;
time_point<system_clock> nowTimePoint= system_clock::now();
std::cout << "Now: " << timePointAsString(nowTimePoint) << std::endl;
auto thousandYears= hours(24*365*1000);
time_point<system_clock> historyTimePoint= nowTimePoint - thousandYears;
std::cout << "Now - 1000 years: " << timePointAsString(historyTimePoint) << std::endl;
time_point<system_clock> futureTimePoint= nowTimePoint + thousandYears;
std::cout << "Now + 1000 years: " << timePointAsString(futureTimePoint) << std::endl;
}
|
Der Übersichtlichkeit willen mache ich in der Zeile 9 den Namensraum std::chrono bekannt. Die Ausgabe des Programms zeigt, dass ein Überlauf der Zeitpunkte in Zeile 24 und 27 zu falschen Ergebnissen führt. So liegt der aktuelle Zeitpunkt, wenn ich von ihm 1000 Jahre abziehe, in der Zukunft. Hingegen ist der aktuelle Zeitpunkt, wenn ich zu ihm 1000 Jahre hinzufüge, in der Vergangenheit.
Wie geht's weiter?
Die Differenz zwischen zwei Zeitpunkten ist eine Zeitdauer. Zeitdauern unterstützen die Grundrechenarten und lassen sich in verschiedenen Zeittakten ausgeben. Wie? Das zeigt der nächste Artikel.
Go to Leanpub/cpplibrary "What every professional C++ programmer should know about the C++ standard library". Hole dir dein E-Book. Unterstütze meinen Blog.
Weiterlesen...