2016-04-17 5 views
2

Ich habe ein Programm geschrieben, das iso 8601 Strings in std::chrono::system_clock::time_point konvertieren sollte. Aber es hat manchmal ein indeterministisches Verhalten. Wenn Sie das Programm mehrmals ausführen, unterscheiden sich die geparsten Zeitstempel um 1 Stunde.Zeitumwandlungen nicht deterministisch

Soweit ich weiß, wenn Sie Datumstrings (iso 8601) in std::chrono::system_clock Typen konvertieren möchten, benötigen Sie derzeit einige Funktionen von ctime (dh, dass Sie c-Funktionen verwenden müssen), wenn Sie nicht ' Ich möchte externe Bibliotheken verwenden.

Also habe ich strptime(), mktime() und std :: tm_t verwendet. Hier

ist die MWE:

#include <chrono> 
#include <ctime> 
#include <iostream> 
#include <sstream> 

int main(void) { 
    std::tm t; 
    strptime("2016-01-01T00:00:00", "%Y-%m-%dT%H:%M:%S", &t); 
    auto time = mktime(&t); 
    std::cout << "UNIX-seconds: " << time << std::endl; 
    //std::cout << "tm-hours: " << t.tm_hour << ", UNIX-seconds: " << time << std::endl; 
    auto tp = std::chrono::system_clock::from_time_t(time); 
    { 
     std::stringstream ss; 
     std::chrono::system_clock::to_time_t(tp); 
    } 
} 

Wenn Sie es mit g ++ kompiliert --std = C++ 14 main.cpp

-o und es mehrmals ausgeführt, erhalte ich eine von die folgenden 2 Ausgänge:

UNIX-seconds: 1451599200 

oder

UNIX-seconds: 1451602800 

Aber ich weiß derzeit nicht, warum ich manchmal die erste und manchmal die zweite bekomme.

Wenn Sie die Kommentarzeile Kommentar-, das indeterministischen Verhalten geht weg und ich erhalte die folgende Zeile ein:

tm-hours: 0, UNIX-seconds: 1451602800 

Was kann ich tun, deterministisches Verhalten zu bekommen?

Ich habe debian 8, g ++ v4.9 und mein PC ist in der Zeitzone Europa/Wien.

+0

Ein Teil der C-Funktionalität ist in ['std :: get_time'] (http://en.cppreference.com/w/cpp/io/manip/get_time) eingeschlossen, falls Sie es leichter haben sollten. 'strptime' und' mktime' sind keine Standard-FWIW (nur POSIX). – chris

+0

Ja, ich weiß, aber std :: get_time hat den Nachteil, dass es g ++ v5.0 oder höher benötigt, momentan wird 4.9 nicht unterstützt ... – byteunit

+0

Ah ich habe vergessen welche Version es endlich implementiert hat. – chris

Antwort

3

mktime respektiert tm_isdst Mitglied von std::tm. strptime ändert dieses Flag nicht und es behält seinen vorherigen Wert bei. Da std::tm POD ist, wird tm_isdst nicht standardmäßig mit der Konstruktion initialisiert, Sie müssen es also manuell initialisieren, sonst erhalten Sie einen unbestimmten Wert.

+0

wow, danke, das hat sehr geholfen. Woher haben Sie diese Information? Ich kann es nicht in den Manpages finden. – byteunit