lokale Zeit mit std::chrono?
-
Hallo Leute,
ich habe folgenden abgespeckten Code, den ich gerne ändern möchte:
#include <iostream> #include <string> std::string currentDateTime() { time_t now = time(0); struct tm tstruct; char buf[80]; tstruct = *localtime(&now); strftime(buf, sizeof(buf), "%d.%m.%Y - %H:%M:%S", &tstruct); return buf; }
Es ist eine einfache Funktion, die mir das aktuelle Datum und Uhrzeit zurückgibt. Ich benötige jetzt allerdings Zeitdaten mit höherer Auflösung (<1 ms), daher wollte ich den Inhalt durch std::chrono ersetzen.
Habe mal folgendes Zwischenergebnis (quick-and-dirty-Version):
#include <iostream> #include <string> #include <sstream> #include <chrono> std::string currentDateTime2() { auto time = std::chrono::high_resolution_clock::now().time_since_epoch(); auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(time).count(); auto us = std::chrono::duration_cast<std::chrono::microseconds>(time).count(); auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(time).count(); auto s = std::chrono::duration_cast<std::chrono::seconds>(time).count(); int time_ns = ns % 1000; int time_us = us % 1000; int time_ms = ms % 1000; int time_s = s % 60; int time_m = (s/60) % 60; int time_h = (s/3600) % 24; int date_d = 0; //? int date_m = 0; //? int date_y = 0; //? stringstream ss; ss << std::setw(2) << std::setfill('0') << date_d << "."; // tag ss << std::setw(2) << std::setfill('0') << date_m << "."; // monat ss << std::setw(4) << std::setfill('0') << date_y << " - "; // jahr ss << std::setw(2) << std::setfill('0') << time_h << ":"; // stunde ss << std::setw(2) << std::setfill('0') << time_m << ":"; // minute ss << std::setw(2) << std::setfill('0') << time_s << "."; // sekunde ss << std::setw(3) << std::setfill('0') << time_ms; // millisek. ss << std::setw(3) << std::setfill('0') << time_us; // mikrosek. ss << std::setw(3) << std::setfill('0') << time_ns; // nanosek. //std::cout << ss.str() << endl << endl; return ss.str(); }
Das Problem ist, dass die Zeit in UTC ausgegeben wird. Kann man mit std::chrono irgendwie die lokale Uhrzeit beziehen?
Noch so nebenbei gefragt... gibt es eine einfache Möglichkeit das Datum aus dem Zeitstempel (now().time_since_epoch()) zu ermitteln oder muss ich das von Hand berechnen?
viele Grüße,
Martin
-
std::ctime?
-
Schau dir dazu am besten mal die Vorträge von Howard Hinnant an (-> youtube).
Insbesondere ist sein date.h-Header auch ziemlich gut.
https://github.com/HowardHinnant/date/blob/master/date.h
-
danke. isch schau mir das mal näher an
-
habe noch eine Möglichkeit gefunden:
#include <iostream> #include <string> #include <sstream> #include <chrono> std::string currentDateTime(bool useLocaleTime) { auto timeNow = std::chrono::high_resolution_clock::now(); auto timeNowEpoch = timeNow.time_since_epoch(); time_t time = std::chrono::high_resolution_clock::to_time_t(timeNow); struct tm tstruct; if (useLocaleTime == true) { tstruct = *localtime(&time); // use locale time } else { tstruct = *gmtime(&time); // use UTC time } int time_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(timeNowEpoch).count() % 1000; int time_us = std::chrono::duration_cast<std::chrono::microseconds>(timeNowEpoch).count() % 1000; int time_ms = std::chrono::duration_cast<std::chrono::milliseconds>(timeNowEpoch).count() % 1000; int time_s = tstruct.tm_sec; int time_m = tstruct.tm_min; int time_h = tstruct.tm_hour; int date_d = tstruct.tm_mday; int date_m = tstruct.tm_mon + 1; int date_y = tstruct.tm_year + 1900; stringstream ss; ss << std::setw(2) << std::setfill('0') << date_d << "."; // day ss << std::setw(2) << std::setfill('0') << date_m << "."; // month ss << std::setw(4) << std::setfill('0') << date_y << " - "; // year ss << std::setw(2) << std::setfill('0') << time_h << ":"; // hour ss << std::setw(2) << std::setfill('0') << time_m << ":"; // minute ss << std::setw(2) << std::setfill('0') << time_s << "."; // second ss << std::setw(3) << std::setfill('0') << time_ms; // millisecond ss << std::setw(3) << std::setfill('0') << time_us; // microsecond ss << std::setw(3) << std::setfill('0') << time_ns; // nanosecond return ss.str(); }
Beispielausgabe: 13.12.2016 - 16:04:50.597401801
ggf. hilft es noch jemanden
-
Für eine Uhr, welche die Uhrzeit misst, nimm
system_clock
. Für eine Stoppuhr nimmsteady_clock
. Mir fällt kein portabler Anwendungfall fürhigh_resolution_clock
ein. Du möchtest hier also einesystem_clock
verwenden.
-
ok danke
-
Biolunar schrieb:
Mir fällt kein portabler Anwendungfall für
high_resolution_clock
ein.Höher auflösende Stoppuhr?
-
Es kann sein, dass die high_resolution_clock nicht monoton ist, das heißt die Differenz zwischen zwei Aufrufen kann negativ sein. Schlecht für eine Stoppuhr. Und wenn diese clock nun monoton ist, ist sie ungeeignet für eine Wanduhr, da Systemzeitumstellung nicht erfasst werden können. Generell weiß man auch nicht, ob eine andere Uhr als system_clock mit der Systemzeit gemessen wird.
Man könnte allerdings zur Kompilierzeit feststellen, ob high_resolution_clock monoton ist und sie dann als Stoppuhr verwenden.