Jak uzyskać bieżący czas w systemie Linux w milisekundach?
Odpowiedzi:
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.
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 :
gettimeofday (), aby określić strefę czasową, używam wartości NULL , która ignoruje strefę czasową, ale w razie potrzeby możesz określić strefę czasową.
@Update - strefa czasowa
Ponieważ long
reprezentacja czasu nie jest związana z samą strefą czasową ani nie ma przez nią wpływu, więc ustawienie tz
parametru gettimeofday () nie jest konieczne, ponieważ nie będzie miało żadnego znaczenia.
I według człowieka stronie gettimeofday()
, wykorzystanie timezone
struktury jest przestarzały, więc tz
argument powinien być zazwyczaj określone jako NULL, szczegóły proszę sprawdzić na stronie man.
tz
parametr gettimeofday()
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.
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
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