Inhaltsverzeichnis

Zeit-Funktionen

Überblick:

:!: UTC (Universal Time Coordinated) ist identisch mit GMT (Greenwich Mean Time).

Datentypen:

Je nach OS verfügbare Funktionen (Quelle: http://nadeausoftware.com/articles/2012/04/c_c_tip_how_measure_elapsed_real_time_benchmarking):

AIX BSD HP-UX Linux OSX SolarisWindows
time() X X X X X X
clock_gettime() X X X X X
gethrtime() X X
gettimeofday() X X X X X X
mach_absolute_time() X
GetSystemTimeAsFileTime()
GetSystemTimePreciseAsFileTime()
X

Je nach OS verfügbare Clock-IDs:

Clock-ID AIX BSD HP-UX Linux SolarisHinweis
CLOCK_REALTIME X X X X X Reports a settable (by root) time that can be mapped to the current real-world date and time. The value is the elapsed time since "the Epoch", which is usually Jan 1st, 1970 at midnight GMT (this may vary among OSes and should not be counted on). CLOCK_REALTIME is the system time used for human time display, so it's subject to corrections whenever the system checks a time server or the system administrator updates the clock. If such adjustments are made during benchmarking, then the elapsed time between two queries of CLOCK_REALTIME will be wrong. One of the other clocks should be used instead, if available.
CLOCK_MONOTONIC X X X X Reports an unsettable time that counts upwards starting at an unspecified time zero in the past that's typically the system's boot time. The time from CLOCK_MONOTONIC cannot be mapped to the current real-world date and time, but it's the right tool for benchmarking where we only need to find the elapsed time of an algorithm.
CLOCK_MONOTONIC_PRECISE X Is a variant of CLOCK_MONOTONIC that aims at providing a more precise time.
CLOCK_MONOTONIC_RAW X (Linux 2.6.28 or later) Is a variant of CLOCK_MONOTONIC that aims for sa more precise time by accessing the underlying "raw" hardware-based time.
CLOCK_HIGHRES X Is equivalent to CLOCK_MONOTONIC and aims at returning a high-resolution time. The returned value is also available from gethrtime().

Deklarationen, Beschreibungen und Beispiele:

time()

Deklaration in <time.h>

time_t time(time_t *ptr_TimeVar);

FIXME

localtime() und gmtime()

struct tm *localtime(const time_t *ptr_TimeVar);
struct tm *gmtime(const time_t *ptr_TimeVar);

Beide Funktionen liefern als Rückgabewert einen Pointer auf "ptr_TimeVar" vom Typ "struct tm".

Die Funktion localtime() wandelt die Kalenderzeit in die lokale Ortszeit um (unter der Berücksichtigung von Sommer- und Winterzeit), gmtime() dagegen - in die UTC-Zeit.

mktime()

time_t mktime(struct tm *ptr_TimeVar);

Auf diese Weise wird eine Zeit im "struct tm"-Format wieder in eine Zeit im "time_t"-Format umgewandelt ("tm_yday" und "tm_wday" in "ptr_TimeVar" werden ignoriert). Der zulässige Bereich für die Kalenderzeit liegt zwischen dem 01.01.1970, 00:00:00 Uhr, und dem 19.01.2038, 03:14:07 Uhr. Ist die Kalenderzeit nicht darstellbar, gibt diese Funktion –1 zurück. Befinden sich die Felder "tm_sec", "tm_min", "tm_hour", "tm_mday" und "tm_mon" nicht im korrekten Bereich, werden diese angepasst.

difftime()

double difftime(time_t zeit_nachher, time_t zeit_vorher);

Die difftime() liefert die Differenz von "zeit_nachher" minus "zeit_vorher" (in Sekunden) zurück (als double-Wert!).

clock()

clock_t clock(void);

Die clock() liefert die verbrauchte CPU-Zeit (:!: nicht in Sekunden!) seit dem Programmstart zurück (-1 im Fehlerfall). Um die CPU-Zeit in Sekunden zu berechnen, muss man der Rückgabewert durch CLOCKS_PER_SEC teilen.

Beispiel: "class timeutils"

Klasse, um die (aktuelle) Zeit in verschiedenen Formaten auszugeben:

timeutils.h

namespace utils
{
	struct timeformats
	{
		static const char* FMT_ISO_DATE;		// Equivalent to "%Y-%m-%d" (the ISO 8601 date format).
		static const char* FMT_ISO_TIME;		// Equivalent to "%H:%M".
		static const char* FMT_ISO_TIME_SEC;		// Equivalent to "%H:%M:%S" (the ISO 8601 time format).
		static const char* FMT_ISO_DATE_TIME_SEC;	// FMT_ISO_DATE + FMT_ISO_TIME_SEC.
		static const char* FMT_FILENAME_DATE;		// Equivalent to "%Y%m%d".
		static const char* FMT_FILENAME_TIME;		// Equivalent to "%H%M%S".
		static const char* FMT_TIME_SEC_MS;		// Equivalent to "%H:%M:%S.%ffff" (the ISO 8601 time format) + milliseconds.
		static const char* FMT_STOPWATCH_TIME;		// Custom format "%k".
		static const char* FMT_DATE_TIME_SEC_MS;	// FMT_ISO_DATE + FMT_ISO_TIME_SEC + ".%ffff".
	}; // struct timeformats
 
	class timeutils	// Helper rund um Zeitangaben.
	{
	public:
		timeutils() = delete;
		~timeutils() = delete;
 
	public:
		static std::time_t now();						// now() liefert die Zeit sekundengenau (alterantiv hires_time() verwenden.
		static string to_string(const std::time_t& time, const string& format);	// Formatiert nach http://en.cppreference.com/w/cpp/chrono/c/strftime".
	}; // class timeutils
 
	// --- Inlines: ---
	inline	std::time_t timeutils::now() { return std::time(nullptr); }
} // namespace utils

timeutils.cpp

namespace utils
{
	// Hinweis: %F, %R, %T werden von VS2012 nicht unterstützt.
	const char* timeformats::FMT_ISO_DATE = "%Y-%m-%d";				// Equivalent to "%Y-%m-%d" (the ISO 8601 date format).
	const char* timeformats::FMT_ISO_TIME = "%H:%M";				// Equivalent to "%H:%M".
	const char* timeformats::FMT_ISO_TIME_SEC = "%H:%M:%S";				// Equivalent to "%H:%M:%S" (the ISO 8601 time format).
	const char* timeformats::FMT_ISO_DATE_TIME_SEC = "%Y-%m-%d %H:%M:%S";		// FMT_ISO_DATE + FMT_ISO_TIME_SEC.
	const char* timeformats::FMT_FILENAME_DATE = "%Y%m%d";				// Equivalent to "%Y%m%d".
	const char* timeformats::FMT_FILENAME_TIME = "%H%M%S";				// Equivalent to "%H%M%S".
	const char* timeformats::FMT_TIME_SEC_MS = "%H:%M:%S.%ffff";			// Equivalent to "%H:%M:%S.%ffff" (the ISO 8601 time format) + milliseconds.
	const char* timeformats::FMT_STOPWATCH_TIME = "%k";				// Custom format "%k".
	const char* timeformats::FMT_DATE_TIME_SEC_MS = "%Y-%m-%d %H:%M:%S.%ffff";	// FMT_ISO_DATE + FMT_ISO_TIME_SEC + ".%ffff".
 
	string timeutils::to_string(std::time_t const& time, string const& format)	// Formatiert nach "http://en.cppreference.com/w/cpp/chrono/c/strftime".
	{
		char buffer[256];
		struct tm tm_struct;
 
#ifdef OS_WINDOWS
		localtime_s(&tm_struct, &time);
#else
		localtime_r(&time, &tm_struct);
#endif
		if (std::strftime(buffer, sizeof(buffer), format.c_str(), &tm_struct))
			return buffer;
		return string();
	} // timeutils::to_string()
} // namespace utils

Weitere Beispiele

// IN ARBEIT
void testFunktion()
{
	time_t t = time(NULL);
	struct tm tm;
 
#ifdef OS_WINDOWS
	localtime_s(&tm, &t);
#else // Unix, Linux
	localtime_r(&t, &tm);
#endif
 
	printf("Jahr  = %d\n", tm.tm_year + 1900);
	printf("Monat = %d\n", tm.tm_mon + 1);
	printf("Tag   = %d\n", tm.tm_mday);
}
// NICHT FERTIG

:!: Zu beachten, daß Ergebniss, das die Funktionen localtime(), localtime_s(), localtime_r() liefern, von dem Wert der Environment Variable "TZ" abhängt. Hier beispielsweise die Einstellung für die mitteleuropäische Sommerzeit:

export TZ=MESZ

Ein Blogpost erklärt, warum das Setzen der Timezone-Variable TZ tausende von Syscalls erspart: https://blog.packagecloud.io/eng/2017/02/21/set-environment-variable-save-thousands-of-system-calls/

Weitere Infos hier: http://blog.quasardb.net/a-portable-high-resolution-timestamp-in-c/
…oder hier: http://nadeausoftware.com/articles/2012/04/c_c_tip_how_measure_elapsed_real_time_benchmarking - :!: Sehr ausführliche Analyse!

Fortgeschrittene Funktionen in der Zeitbibliothek von C++11: http://www.linux-magazin.de/Ausgaben/2016/06/C-11


Stand: 23.01.2020
: Jürgen Kreick

EOF