2014-11-25 7 views
5

Ich habe ein Problem mit tatsächlichen Systemzeit mit Millisekunden bekommen. Die einzige gute Methode, die ich gefunden habe, ist in Windows.h, aber ich kann es nicht verwenden. Ich soll std::chrono verwenden. Wie kann ich das machen?C++ 11 tatsächliche Systemzeit mit Millisekunden

Ich verbrachte viel Zeit damit, es zu googeln, aber ich fand nur Beispiele zweiter Genauigkeit.

Ich versuche Zeichenfolge wie folgt zu erhalten:

[2014-11-25 22:15:38:449] 
+0

Es gibt keine Standardmethode zum Drucken von Datum mit Millisekunden. Mit 'std :: chrono' denke ich, dass Sie nur einen' time_point' selbst konvertieren können. – TNA

+0

Sie müssen plattformspezifische Aufrufe verwenden, um Millisekundengenauigkeit zu erhalten. –

+3

@ThomasMatthews Ich bin ziemlich sicher, dass Chrono eine Genauigkeit von bis zu einigen Mikrosekunden ziehen kann, wenn das System es erlaubt. Versuchen Sie beispielsweise, diesen Code auszuführen: http: //en.cppreference.com/w/cpp/chrono/time_point – Alexandru

Antwort

7

Mit Code von this answer:

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

template <typename Duration> 
void print_time(tm t, Duration fraction) { 
    using namespace std::chrono; 
    std::printf("[%04u-%02u-%02u %02u:%02u:%02u.%03u]\n", t.tm_year + 1900, 
       t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, 
       static_cast<unsigned>(fraction/milliseconds(1))); 

    // VS2013's library has a bug which may require you to replace 
    // "fraction/milliseconds(1)" with 
    // "duration_cast<milliseconds>(fraction).count()" 
} 

int main() { 
    using namespace std; 
    using namespace std::chrono; 

    system_clock::time_point now = system_clock::now(); 
    system_clock::duration tp = now.time_since_epoch(); 

    tp -= duration_cast<seconds>(tp); 

    time_t tt = system_clock::to_time_t(now); 

    print_time(*gmtime(&tt), tp); 
    print_time(*localtime(&tt), tp); 
} 

Eine Sache im Auge zu behalten ist, dass die Tatsache, dass der Timer gibt Werte von Sub-Millisekunden Denominationen notwendigerweise bedeutet nicht, dass der Timer Sub-Millisekunden-Auflösung hat. Ich denke, Windows-Implementierung in VS2015 kann endlich behoben werden, aber der Timer, den sie bisher verwendet haben, um ihre Chrono-Implementierung zu unterstützen, war sensibel für die OS timeBeginPeriod() Einstellung, zeigt unterschiedliche Auflösung, und die Standardeinstellung ist glaube ich 16 Millisekunden.

Auch der obige Code geht davon aus, dass weder UTC noch Ihre lokale Zeitzone von der Epoche std::chrono::system_clock um einen Bruchteilsekundenwert versetzt sind.


Beispiel für Howard Datum Funktionen ctime zu vermeiden: http://coliru.stacked-crooked.com/a/98db840b238d3ce7

+0

Sie müssen nur die Sekunden von tp subtrahieren, da sie die Dauer in Sekunden konvertiert, wie viele sie auch sein mögen. Nur 'Sekunden s = duration_cast (tp); tp - = s; ' – Alexandru

+0

Das stimmt, die anderen Werte werden nur im Debug-Code zur Anzeige der vollen Dauer verwendet. – bames53

+3

Und wenn Sie nicht durch die C-API stapfen möchten, können Sie etwas tun: http://howardhinnant.github.io/date_algorithms.html#What%20can%20I%20do%20with%20that%20 chrono% 20 Kompatibilität? –

1

std::chrono Sie Dienstprogramme geben einen Zeitpunkt oder der verstrichenen Dauer zwischen zwei Zeitpunkten darzustellen. Es ermöglicht Ihnen, Informationen über diese Zeitintervalle zu erhalten.

Es tut nicht liefern Sie keine Kalender Informationen. Leider gibt es zu diesem Zeitpunkt keine Tools im C++ - Standard für diese. boost::date_time kann hier hilfreich sein.

3

Diese Antwort ist immer noch ein wenig C-API verwendet, sondern nur in der Funktion verwendet wird, so dass Sie es vergessen können:

template<typename T> 
void print_time(std::chrono::time_point<T> time) { 
    using namespace std; 
    using namespace std::chrono; 

    time_t curr_time = T::to_time_t(time); 
    char sRep[100]; 
    strftime(sRep,sizeof(sRep),"%Y-%m-%d %H:%M:%S",localtime(&curr_time)); 

    typename T::duration since_epoch = time.time_since_epoch(); 
    seconds s = duration_cast<seconds>(since_epoch); 
    since_epoch -= s; 
    milliseconds milli = duration_cast<milliseconds>(since_epoch); 

    cout << '[' << sRep << ":" << milli.count() << "]\n"; 
} 

Dies ist nur eine Neuschreibung des Codes, der bames53, aber unter Verwendung von strftime, um den Code ein bisschen zu verkürzen.

+0

Wenn ich mich nicht irre, ist 'strftime' unter Windows nicht verfügbar. – Everyone

0

habe bemerkt jemand, dass to_time_t die Sekunden Runden, statt Kürzen

auto now = system_clock::now(); 
time_t secs = system_clock::to_time_t(now); 
now {_MyDur={_MyRep=15107091978759765 } } 
secs = 1510709198 

so, wenn Sie auf den Millisekunden tack

auto tse = now.time_since_epoch(); 
auto now_ms = duration_cast<milliseconds>(tse); 
auto now_s = duration_cast<seconds>(tse); 
auto jst_ms = now_ms - now_s; 
DWORD msecs = jst_ms.count(); 
msecs = 875 

Sekunden 1510709197 sein sollte, aber bei now_s aussehen, es ist richtig

now_s {_MyRep=1510709197 } 
+0

Wenn Sie eine neue Frage haben, klicken Sie bitte auf die Schaltfläche [Frage stellen] (https://stackoverflow.com/questions/ask). Fügen Sie einen Link zu dieser Frage hinzu, wenn es hilft, Kontext bereitzustellen. - [Aus Bewertung] (/ review/low-quality-posts/17948180) –