Holen Sie sich Unix-Zeitstempel mit C ++


71

Wie bekomme ich einen uintUnix-Zeitstempel in C ++? Ich habe ein bisschen gegoogelt und es scheint, dass die meisten Methoden nach komplizierteren Wegen suchen, um die Zeit darzustellen. Kann ich es nicht einfach als bekommen uint?

Antworten:


90

In C ++ 20 wurde eine Garantie eingeführt, die time_since_epochsich auf die UNIX-Epoche bezieht , und cppreference.com gibt ein Beispiel, das ich auf den relevanten Code destilliert und in Einheiten von Sekunden anstatt in Stunden geändert habe:

#include <iostream>
#include <chrono>
 
int main()
{
    const auto p1 = std::chrono::system_clock::now();
 
    std::cout << "seconds since epoch: "
              << std::chrono::duration_cast<std::chrono::seconds>(
                   p1.time_since_epoch()).count() << '\n';
}

Die Verwendung von C ++ 17 oder früher time()ist die einfachste Funktion - Sekunden seit Epoche, die für Linux und UNIX zumindest die UNIX-Epoche wäre. Linux Manpage hier .

Die oben verlinkte cppreference-Seite gibt dieses Beispiel :

#include <ctime>
#include <iostream>
 
int main()
{
    std::time_t result = std::time(nullptr);
    std::cout << std::asctime(std::localtime(&result))
              << result << " seconds since the Epoch\n";
}

4
"Epoch" ist natürlich das Unix-Eproch unter Unix und Linux, aber das ist nicht universell.
— MSalters

43
#include<iostream>
#include<ctime>

int main()
{
    std::time_t t = std::time(0);  // t is an integer type
    std::cout << t << " seconds since 01-Jan-1970\n";
    return 0;
}

1
Dies setzt voraus, dass std::time()Sie seit 1970 Sekunden haben. Dies gilt für viele Systeme (POSIX und Windows, glaube ich), wird jedoch vom Sprachstandard nicht garantiert.
— Keith Thompson

17

Der häufigste Rat ist falsch, man kann sich nicht einfach darauf verlassen time(). Das ist für eine relative Timing verwendet: ISO C ++ nicht spezifiziert , dass 1970-01-01T00:00Zisttime_t(0)

Schlimmer ist, dass man es auch nicht leicht herausfinden kann. Sicher, Sie können das Kalenderdatum von time_t(0)mit finden gmtime, aber was werden Sie tun, wenn das so ist 2000-01-01T00:00Z? Wie viele Sekunden waren zwischen 1970-01-01T00:00Zund 2000-01-01T00:00Z? Aufgrund von Schaltsekunden ist es sicherlich kein Vielfaches von 60.


1
"Wie bekomme ich einen Uint-Unix-Zeitstempel in C ++?" - wie gesagt - Sie können gmtime()später anrufen , um eine lesbare Darstellung dessen zu erhalten, was dieser Zeitstempel codiert. Welche in der Frage angeforderte Funktionalität time()wird unabhängig vom Referenzdatum oder der Eignung für Intervallberechnungen nicht erfüllt ?
— Tony Delroy

3
Um einen UNIX- Zeitstempel auf einem Nicht-UNIX-System zu erhalten, müssen Sie den Unterschied (in Sekunden) zwischen der lokalen Epoche und kennen 1970-01-01T00:00Z. Es gibt einfach keine Methode, die das macht.
— MSalters

Aus irgendeinem Grund hatte ich den Eindruck, dass die Frage nach Code auf einem UNIX-Computer (oder Linux usw.) lautete, aber jetzt sehe ich, woher Sie kommen. Neugierig: Haben Sie ein System gefunden, bei dem time_t (0) nicht 1970-01-01T00: 00Z war? Es wäre nur ein paar Minuten Arbeit, um einen Offset auf einem bestimmten System zu berechnen (nehmen Sie die Nicht-UNIX-Zeit_t (0) und erhalten Sie eine Zeit_t dafür auf einem UNIX-System), aber danke, dass Sie Ihr Anliegen erklärt haben.
— Tony Delroy

6
Für VS seine UNIX-Zeit; MSDN-Status: Die Zeitfunktion gibt die Anzahl der Sekunden zurück, die seit Mitternacht (00:00:00), 1. Januar 1970, koordinierte Weltzeit (UTC), gemäß der Systemuhr vergangen sind. msdn.microsoft.com/en-us/library/1f4c8f33.aspx
— Oliver

2
@ TonyD: IBM Systeme sind anscheinend eine Ausnahme. Keine wirkliche Überraschung, da sie lange vor dem 1.1.1970 im Computergeschäft tätig waren.
— MSalters

8

Da dies das erste Ergebnis bei Google ist und es noch keine C ++ 20-Antwort gibt, gehen Sie wie folgt vor, um std :: chrono zu verwenden:

#include <chrono>

//...

using namespace std::chrono;
int64_t timestamp = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();

In Versionen von C ++ vor 20 ist die Epoche von system_clock als Unix-Epoche eine De-facto-Konvention, die jedoch nicht standardisiert ist. Wenn Sie nicht mit C ++ 20 arbeiten, erfolgt die Verwendung auf eigenes Risiko.


3
Die Epoche wird offiziell in C ++ 20 anerkannt: eel.is/c++draft/time.clock.system.overview
— Howard Hinnant

6
#include <iostream>
#include <sys/time.h>

using namespace std;

int main ()
{
  unsigned long int sec= time(NULL);
  cout<<sec<<endl;
}

time()Gibt ein Ergebnis vom Typ zurück time_t, das im Prinzip entweder vorzeichenbehaftet, vorzeichenlos oder sogar Gleitkomma sein kann. Warum das Ergebnis in a speichern long int? Und warum <sys/time.h>eher als den Standard verwenden <time.h>?
— Keith Thompson

Ich verstehe, aber ich denke, in jedem posix-kompatiblen Betriebssystem sind beide time.h & sys / time.h vorhanden. Sie haben auch völlig Recht, dass time_t auch ein negativer Wert sein kann, da er als Sekunden dargestellt wird, die vom 1970-01-01T00: 00Z vergangen sind.
— Anijhaw


4

Ich habe eine globale Definition mit weiteren Informationen erstellt:

#include <iostream>
#include <ctime>
#include <iomanip>

#define __FILENAME__ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__)    // only show filename and not it's path (less clutter)
#define INFO std::cout << std::put_time(std::localtime(&time_now), "%y-%m-%d %OH:%OM:%OS") << " [INFO] " << __FILENAME__ << "(" << __FUNCTION__ << ":" << __LINE__ << ") >> "
#define ERROR std::cout << std::put_time(std::localtime(&time_now), "%y-%m-%d %OH:%OM:%OS") << " [ERROR] " << __FILENAME__ << "(" << __FUNCTION__ << ":" << __LINE__ << ") >> "

static std::time_t time_now = std::time(nullptr);

Verwenden Sie es so:

INFO << "Hello world" << std::endl;
ERROR << "Goodbye world" << std::endl;

Beispielausgabe:

16-06-23 21:33:19 [INFO] main.cpp(main:6) >> Hello world
16-06-23 21:33:19 [ERROR] main.cpp(main:7) >> Goodbye world

Fügen Sie diese Zeilen in Ihre Header-Datei ein. Ich finde das sehr nützlich zum Debuggen usw.


Warum #defineund nicht eine Funktion? Funktion wäre flexibler,
— überladbarer

3
@Troyseph Weil dann __FILE__``__FUNCTION__``__LINE__ nicht wie vorgesehen funktionieren würde. Dies ist ein Makro.
— Xinthose

1
Fair genug! Schade, dass es keine modernere Alternative gibt =]
— Troyseph
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.