Gibt es eine plattformübergreifende Möglichkeit, das aktuelle Datum und die Uhrzeit in C++ abzurufen?
std::put_time()
funktioniert nicht mit der Ausgabe von std::chrono::system_clock::now()
.
Gibt es eine plattformübergreifende Möglichkeit, das aktuelle Datum und die Uhrzeit in C++ abzurufen?
Die C++-Standardbibliothek bietet keinen geeigneten Datumstyp. C++ erbt die Strukturen und Funktionen für die Datums- und Zeitmanipulation von C, zusammen mit einer Reihe von Datums-/Zeit-Eingabe- und Ausgabefunktionen, die die Lokalisierung berücksichtigen.
// Current date/time based on current system
time_t now = time(0);
// Convert now to tm struct for local timezone
tm* localtm = localtime(&now);
cout << "The local date and time is: " << asctime(localtm) << endl;
// Convert now to tm struct for UTC
tm* gmtm = gmtime(&now);
if (gmtm != NULL) {
cout << "The UTC date and time is: " << asctime(gmtm) << endl;
}
else {
cerr << "Failed to get the UTC date and time" << endl;
return EXIT_FAILURE;
}
auto time = std::time(nullptr);
std::cout << std::put_time(std::localtime(&time), "%F %T%z"); // ISO 8601 format.
Die aktuelle Zeit wird entweder mit std::time()
ou std::chrono::system_clock::now()
(oder eine andere Uhrentyp ).
std::put_time()
(C++11) und strftime()
(C) bieten eine Vielzahl von Formatierern zur Ausgabe dieser Zeiten.
#include <iomanip>
#include <iostream>
int main() {
auto time = std::time(nullptr);
std::cout
// ISO 8601: %Y-%m-%d %H:%M:%S, e.g. 2017-07-31 00:42:00+0200.
<< std::put_time(std::gmtime(&time), "%F %T%z") << '\n'
// %m/%d/%y, e.g. 07/31/17
<< std::put_time(std::gmtime(&time), "%D");
}
Die Reihenfolge der Formatierer ist wichtig:
std::cout << std::put_time(std::gmtime(&time), "%c %A %Z") << std::endl;
// Mon Jul 31 00:00:42 2017 Monday GMT
std::cout << std::put_time(std::gmtime(&time), "%Z %c %A") << std::endl;
// GMT Mon Jul 31 00:00:42 2017 Monday
Die Formatierer von strftime()
sind ähnlich:
char output[100];
if (std::strftime(output, sizeof(output), "%F", std::gmtime(&time))) {
std::cout << output << '\n'; // %Y-%m-%d, e.g. 2017-07-31
}
Oft bedeutet der Großbuchstabe "Vollversion" und der Kleinbuchstabe eine Abkürzung (z. B. Y: 2017, y: 17).
Gebietsschemaeinstellungen verändern die Ausgabe:
#include <iomanip>
#include <iostream>
int main() {
auto time = std::time(nullptr);
std::cout << "undef: " << std::put_time(std::gmtime(&time), "%c") << '\n';
std::cout.imbue(std::locale("en_US.utf8"));
std::cout << "en_US: " << std::put_time(std::gmtime(&time), "%c") << '\n';
std::cout.imbue(std::locale("en_GB.utf8"));
std::cout << "en_GB: " << std::put_time(std::gmtime(&time), "%c") << '\n';
std::cout.imbue(std::locale("de_DE.utf8"));
std::cout << "de_DE: " << std::put_time(std::gmtime(&time), "%c") << '\n';
std::cout.imbue(std::locale("ja_JP.utf8"));
std::cout << "ja_JP: " << std::put_time(std::gmtime(&time), "%c") << '\n';
std::cout.imbue(std::locale("ru_RU.utf8"));
std::cout << "ru_RU: " << std::put_time(std::gmtime(&time), "%c");
}
Mögliche Ausgabe ( Coliru , Compiler-Explorer ):
undef: Tue Aug 1 08:29:30 2017
en_US: Tue 01 Aug 2017 08:29:30 AM GMT
en_GB: Tue 01 Aug 2017 08:29:30 GMT
de_DE: Di 01 Aug 2017 08:29:30 GMT
ja_JP: 20170801 082930
ru_RU: 01 2017 08:29:30
Ich habe die std::gmtime()
für die Umrechnung in UTC. std::localtime()
wird zur Umrechnung in die Ortszeit bereitgestellt.
Beachten Sie das asctime()
/ ctime()
die in anderen Antworten erwähnt wurden, sind jetzt als veraltet gekennzeichnet und strftime()
sollte bevorzugt werden.
Sie können verwenden std::chrono::system_clock::to_time_t()
um den Ausgang der Systemuhr zu konvertieren.
(Für Mit-Googler)
Außerdem gibt es Boost::date_time :
#include <boost/date_time/posix_time/posix_time.hpp>
boost::posix_time::ptime date_time = boost::posix_time::microsec_clock::universal_time();
Ja, und zwar mit Formatierungsregeln, die durch das aktuelle Gebietsschema vorgegeben sind:
#include <iostream>
#include <iterator>
#include <string>
class timefmt
{
public:
timefmt(std::string fmt)
: format(fmt) { }
friend std::ostream& operator <<(std::ostream &, timefmt const &);
private:
std::string format;
};
std::ostream& operator <<(std::ostream& os, timefmt const& mt)
{
std::ostream::sentry s(os);
if (s)
{
std::time_t t = std::time(0);
std::tm const* tm = std::localtime(&t);
std::ostreambuf_iterator<char> out(os);
std::use_facet<std::time_put<char>>(os.getloc())
.put(out, os, os.fill(),
tm, &mt.format[0], &mt.format[0] + mt.format.size());
}
os.width(0);
return os;
}
int main()
{
std::cout << timefmt("%c");
}
Ausgabe:
Fri Sep 6 20:33:31 2013
Dies ist, IMHO, die beste Antwort, da sie als einzige die Gebietsschema-Einstellungen berücksichtigt und mit so viel Liebe zum Detail programmiert wurde (Sie sehen nicht ostream::sentry
so oft).
@DevSolar Danke. Ich würde aber nicht sagen, dass es das Beste ist. Ich habe schon bessere Implementierungen gesehen. Aber ich denke, das reicht als Beispiel aus :)
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
3 Stimmen
Wenn Ockonal noch aktiv ist, sollte er die akzeptierte Antwort auf den C++11-Ansatz ändern. Diese Frage scheint immer noch eine Menge Ansichten zu erhalten.
2 Stimmen
C-Version: stackoverflow.com/questions/1442116/
3 Stimmen
@JSQuareD Selbst wenn ich mir diese Frage jetzt nach all der Zeit ansehe, finde ich den C-Ansatz besser, indem ich die
tm
Struktur. Gibt der C++11-Ansatz nicht einfach den Unix-Zeitstempel (Zeit seit der Epoche) aus, obwohl die Frage nach Datum und Uhrzeit lautete?5 Stimmen
Wow, diese Frage hat 1.110.886 Aufrufe! Die Leute lieben C++ wirklich!
5 Stimmen
Nein, sie hassen nur ::std::chrono. Es ist unentzifferbares Kauderwelsch.