Benutzer-Werkzeuge

Webseiten-Werkzeuge


edv:prg:c:tipp:zeit-funktionen

Zeit-Funktionen

Überblick:

  • time() - Anzahl der Sekunden, die seit dem 01.01.1970, 00:00:00 Uhr, vergangen sind. (Evtl. das "Jahr 2038"-Problem, wenn "time_t" als "long" implementiert ist.)
  • localtime() - Umwandeln von "time_t" (das Ergebnis von "time()") in "struct tm" (als lokale Ortszeit) unter der Berücksichtigung von Sommer- und Winterzeit.
  • localtime_s()
  • localtime_r()
  • gmtime() - Wie localtime(), nur das Ergebnis ist nicht die lokale Ortszeit, sondern die UTC-Zeit.
  • mktime() - Umwandeln von "struct tm" in "time_t" (Gegenstück der Funktionen localtime() und gmtime()).
  • difftime() – Differenz zwischen zwei Zeitangaben.
  • asctime() und ctime() – Umwandeln von Zeitformaten ("struct tm" und "time_t") in einen String.
  • strftime() – Umwandeln vom Zeitformat "struct tm" in einen benutzerdefinierten String.
  • clock() - Verbrauchte CPU-Zeit für ein Programm (seit dem Programmstart).
    http://man7.org/linux/man-pages/man3/clock.3.html
  • clock_gettime() (CLOCK_MONOTONIC, CLOCK_MONOTONIC_PRECISE, CLOCK_REALTIME, CLOCK_PROCESS_CPUTIME_ID)
    http://man7.org/linux/man-pages/man2/clock_gettime.2.html
  • TZ (Environment Variable) - Zeitzone (Beispiele: "localtime", "MESZ", "UTC", etc.)
  • FIXME

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

Datentypen:

  • clock_t - Die CPU-Zeit (Ganzzahl)
  • time_t - Datums- und Zeitangaben (Ganzzahl)
  • struct tm - Enthält alle zu einer (gregorianischen) Kalenderzeit relevanten Komponenten:
    struct tm
    {
    	int tm_sec;	// Sekunden (0–59)
    	int tm_min;	// Minuten (0–59)
    	int tm_hour;	// Stunden (0–23)
    	int tm_mday;	// Monatstag (1–31)
    	int tm_mon;	// Monate (0–11; Januar = 0)
    	int tm_year;	// Jahre ab 1900
    	int tm_wday;	// Tag seit Sonntag (0–6; Sonntag = 0)
    	int tm_yday;	// Tag seit 1. Januar (0–365; 1.Januar = 0)
    	int tm_isdst;	// Winter-/Sommerzeit (Winterzeit: tm_istdst == 0; Sommerzeit: tm_isdst > 0; wenn Info nicht verfügbar: tm_isdst < 0)
    	long int tm_gmtoff;	// (nur auf Linux) Gibt die Sekunden östlich von UTC bzw. den negativen Wert westlich von UTC für die Zeitzonen an.
    	const char *tm_zone;	// (nur auf Linux) Enthält den Namen der aktuellen Zeitzone.
    };
  • struct timespec - Enthält (hoch aufgelöste) Zeit:
    struct timespec
    {
    	time_t tv_sec;	// Sekunden
    	long tv_nsec;	// Nanosekunden
    };

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

edv/prg/c/tipp/zeit-funktionen.txt · Zuletzt geändert: 2020/01/23 13:04 von 127.0.0.1

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki