Jak uzyskać bieżący czas w systemie Linux w milisekundach?
86
Można to osiągnąć za pomocą funkcji POSIXclock_gettime
.
W aktualnej wersji POSIX gettimeofday
jest oznaczony jako przestarzały . Oznacza to, że może zostać usunięty z przyszłej wersji specyfikacji. Zachęcamy autorów aplikacji do używania clock_gettime
funkcji zamiast gettimeofday
.
Oto przykład użycia clock_gettime
:
#define _POSIX_C_SOURCE 200809L
#include <inttypes.h>
#include <math.h>
#include <stdio.h>
#include <time.h>
void print_current_time_with_ms (void)
{
long ms; // Milliseconds
time_t s; // Seconds
struct timespec spec;
clock_gettime(CLOCK_REALTIME, &spec);
s = spec.tv_sec;
ms = round(spec.tv_nsec / 1.0e6); // Convert nanoseconds to milliseconds
if (ms > 999) {
s++;
ms = 0;
}
printf("Current time: %"PRIdMAX".%03ld seconds since the Epoch\n",
(intmax_t)s, ms);
}
Jeśli Twoim celem jest pomiar czasu, który upłynął, a Twój system obsługuje opcję „zegara monotonicznego”, powinieneś rozważyć użycie CLOCK_MONOTONIC
zamiast CLOCK_REALTIME
.
gcc
poleceniu.s
kiedy to nastąpi. Prawdopodobnie rzadkie zdarzenie, ale dodatkowa cyfra może powodować problemy.Musisz zrobić coś takiego:
struct timeval tv; gettimeofday(&tv, NULL); double time_in_mill = (tv.tv_sec) * 1000 + (tv.tv_usec) / 1000 ; // convert tv_sec & tv_usec to millisecond
źródło
Poniżej znajduje się funkcja util do pobierania aktualnego znacznika czasu w milisekundach:
#include <sys/time.h> long long current_timestamp() { struct timeval te; gettimeofday(&te, NULL); // get current time long long milliseconds = te.tv_sec*1000LL + te.tv_usec/1000; // calculate milliseconds // printf("milliseconds: %lld\n", milliseconds); return milliseconds; }
O strefie czasowej :
@Update - strefa czasowa
Ponieważ
long
reprezentacja czasu nie jest związana z samą strefą czasową ani nie ma przez nią wpływu, więc ustawienietz
parametru gettimeofday () nie jest konieczne, ponieważ nie będzie miało żadnego znaczenia.I według człowieka stronie
gettimeofday()
, wykorzystanietimezone
struktury jest przestarzały, więctz
argument powinien być zazwyczaj określone jako NULL, szczegóły proszę sprawdzić na stronie man.źródło
tz
parametrgettimeofday()
as&(struct timezone tz = {480, 0})
, nie otrzymam żadnego ostrzeżenia i nie ma to żadnego wpływu na wynik, to ma sens, ponieważlong
reprezentacja czasu nie ma znaczenia ani nie ma wpływu według samej strefy czasowej, prawda?NULL
jest tylko rozsądna wartość do przekazania. Uważam, że testowanie jest zawsze dobrym podejściem do udowodnienia rzeczy.Użyj,
gettimeofday()
aby uzyskać czas w sekundach i mikrosekundach. Łączenie i zaokrąglanie do milisekund pozostaje jako ćwiczenie.źródło
C11
timespec_get
Powraca do nanosekund, zaokrąglając do rozdzielczości implementacji.
Jest już zaimplementowany w Ubuntu 15.10. API wygląda tak samo jak POSIX
clock_gettime
.#include <time.h> struct timespec ts; timespec_get(&ts, TIME_UTC); struct timespec { time_t tv_sec; /* seconds */ long tv_nsec; /* nanoseconds */ };
Więcej szczegółów tutaj: https://stackoverflow.com/a/36095407/895245
źródło
Pochodzący z odpowiedzi POSIX Dana Mouldinga, to powinno działać:
#include <time.h> #include <math.h> long millis(){ struct timespec _t; clock_gettime(CLOCK_REALTIME, &_t); return _t.tv_sec*1000 + lround(_t.tv_nsec/1.0e6); }
Również, jak wskazał David Guyon: skompiluj z -lm
źródło