C++ Konvertieren eines Zeitstrings in Sekunden aus der Epoche
Lesezeit: 6 Minuten
Martin York
Ich habe einen String mit folgendem Format:
2010-11-04T23:23:01Z
Das Z zeigt an, dass die Zeit UTC ist.
Ich würde dies eher als Epochenzeit speichern, um den Vergleich zu vereinfachen.
Was ist die empfohlene Methode dafür?
Derzeit (nach einer schnellen Suche) ist der einfache Algorithmus:
1: <Convert string to struct_tm: by manually parsing string>
2: Use mktime() to convert struct_tm to epoch time.
// Problem here is that mktime uses local time not UTC time.
_mkgmtime() in meinem CRT. Ymmv.
– Hans Passant
9. November ’10 um 20:04
@Loki, wir brauchen kein Meta-Tag, um alle Dinge abzufangen, die betriebssystemneutral sind. Bitte beenden Sie die Neuerstellung des Tags.
– Charles
26. September ’12 um 0:38
@Charles: Bitte hör auf, meine Frage zu ändern. Ich hätte jedoch den Hinweis erhalten, dass die Bearbeitung meiner Meinung nach ungültig ist, nachdem ich sie zum zweiten Mal zurückgeändert habe.
– Martin York
26. September ’12 um 6:42
@Loki, und ich dachte, Sie hätten den Hinweis bekommen, dass andere Benutzer auf der Site die Notwendigkeit eines neuen generischen Catch-All-Tags für diese Frage und nur diese Frage nicht sehen. Bitte fügen Sie entweder ein Wiki-Tag hinzu und fügen Sie das Tag anderen Fragen hinzu, für die es relevant ist, oder Sie werden weiterhin sehen, dass andere Benutzer das Tag entfernen.
– Charles
26. September ’12 um 15:04
@Loki – es hilft nicht viel, dass das Tag die ganze Zeit falsch geschrieben wurde …
– Bo Person
27. September ’12 um 20:12
Martin York
Mit der C++11-Funktionalität können wir jetzt Streams verwenden, um Zeiten zu analysieren:
Die iomanip std::get_time konvertiert eine Zeichenfolge basierend auf einem Satz von Formatparametern und konvertiert sie in a struct tz Objekt.
Sie können dann verwenden std::mktime() um dies in einen Epochenwert umzuwandeln.
Dieser Code befasst sich nicht mit dem OP-Problem (ich weiß nicht, warum er ihn akzeptiert hat). std::mktime nimmt die lokale Zeitzone an und gibt die falsche Zeit aus. Es gibt 1288909381 auf meiner Maschine (GMT+01:00 zu diesem Datum), das ist 10 pm, nicht 11 pm bei UTC. Der richtige Zeitstempel wäre jedoch gewesen 1288912981.
– Zabuzard
31. Juli ’19 um 16:08
@Zabuza Würdest du nicht denken, dass der OP besser weiß, was er will als du? Wenn Sie nicht wissen, warum er es akzeptiert hat, sollten Sie das vielleicht zuerst klären, sonst Ihre Behauptung This code does not address OPs issue ist verdächtig.
– Martin York
31. Juli ’19 um 23:04
Dies ist das ISO8601-Format. Sie können verwenden strptime Funktion, um es zu parsen %FT%T%z Streit. Es ist nicht Teil des C++-Standards, obwohl Sie eine Open-Source-Implementierung davon verwenden können (Dies, zum Beispiel).
Sie können eine Funktion wie z strptime einen String in a umwandeln struct tm, anstatt es manuell zu parsen.
Steve Townsend
Es ist kein exakter Betrug, aber Sie werden die Antwort von @Cubbi von hier aus nützlich finden, wette ich. Dies setzt insbesondere die UTC-Eingabe voraus.
Boost unterstützt auch die direkte Konvertierung von ISO 8601 über boost::posix_time::from_iso_string der ruft boost::date_time::parse_iso_time, auch hier würden Sie einfach das nachgestellte ‘Z’ entfernen und die TZ als implizite UTC behandeln.
Das Problem hierbei ist, dass mktime die Ortszeit und nicht die UTC-Zeit verwendet.
Linux bietet timegm was Sie wollen (zB mktime für UTC-Zeit).
Hier ist meine Lösung, die ich gezwungen habe, nur “Zulu” (Z-Zeitzone) zu akzeptieren. Beachten Sie, dass strptime scheint die Zeitzone nicht richtig zu analysieren, obwohl glib dies anscheinend unterstützt. Deshalb werfe ich einfach eine Ausnahme aus, wenn die Zeichenfolge nicht auf ‘Z’ endet.
#include "tz.h"
#include <iostream>
#include <sstream>
int
main()
{
std::istringstream is("2010-11-04T23:23:01Z");
is.exceptions(std::ios::failbit);
date::sys_seconds tp;
date::parse(is, "%FT%TZ", tp);
std::cout << "seconds from epoch is " << tp.time_since_epoch().count() << "sn";
}
Dieses Programm gibt aus:
seconds from epoch is 1288912981s
Wenn die Analyse in irgendeiner Weise fehlschlägt, wird eine Ausnahme ausgelöst. Wenn Sie keine Ausnahmen werfen möchten, tun Sie es nicht is.exceptions(std::ios::failbit);, sondern suche stattdessen nach is.fail().
Yippie-Ki-Yay
Du könntest das nutzen boost::date_time und schreibe einen kleinen manuellen Parser (wahrscheinlich regexp-basiert) für deine Saiten.
.
4869100cookie-checkC++ Konvertieren eines Zeitstrings in Sekunden aus der Epocheyes
_mkgmtime() in meinem CRT. Ymmv.
– Hans Passant
9. November ’10 um 20:04
@Loki, wir brauchen kein Meta-Tag, um alle Dinge abzufangen, die betriebssystemneutral sind. Bitte beenden Sie die Neuerstellung des Tags.
– Charles
26. September ’12 um 0:38
@Charles: Bitte hör auf, meine Frage zu ändern. Ich hätte jedoch den Hinweis erhalten, dass die Bearbeitung meiner Meinung nach ungültig ist, nachdem ich sie zum zweiten Mal zurückgeändert habe.
– Martin York
26. September ’12 um 6:42
@Loki, und ich dachte, Sie hätten den Hinweis bekommen, dass andere Benutzer auf der Site die Notwendigkeit eines neuen generischen Catch-All-Tags für diese Frage und nur diese Frage nicht sehen. Bitte fügen Sie entweder ein Wiki-Tag hinzu und fügen Sie das Tag anderen Fragen hinzu, für die es relevant ist, oder Sie werden weiterhin sehen, dass andere Benutzer das Tag entfernen.
– Charles
26. September ’12 um 15:04
@Loki – es hilft nicht viel, dass das Tag die ganze Zeit falsch geschrieben wurde …
– Bo Person
27. September ’12 um 20:12