¿Cómo obtengo la hora actual en Linux en milisegundos?
Respuestas:
Esto se puede lograr utilizando la función POSIXclock_gettime
.
En la versión actual de POSIX, gettimeofday
está marcado como obsoleto . Esto significa que puede eliminarse de una versión futura de la especificación. Se anima a los escritores de aplicaciones a utilizar la clock_gettime
función en lugar de gettimeofday
.
A continuación, se muestra un ejemplo de cómo utilizarlo 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);
}
Si su objetivo es medir el tiempo transcurrido y su sistema admite la opción "reloj monótono", debería considerar usar en CLOCK_MONOTONIC
lugar de CLOCK_REALTIME
.
gcc
comando.
s
cuando esto ocurra. Probablemente sea un evento poco común, pero el dígito extra puede causar problemas.
A continuación se muestra la función util para obtener la marca de tiempo actual en milisegundos:
#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;
}
Acerca de la zona horaria :
Soporte de gettimeofday () para especificar la zona horaria, yo uso NULL , que ignora la zona horaria, pero puede especificar una zona horaria, si es necesario.
@Update - zona horaria
Dado que la long
representación del tiempo no es relevante ni se ve afectada por la zona horaria en sí, tz
no es necesario establecer el parámetro de gettimeofday (), ya que no hará ninguna diferencia.
Y, de acuerdo con la página de manual de gettimeofday()
, el uso de la timezone
estructura es obsoleto, por lo que el tz
argumento normalmente debe especificarse como NULL; para obtener más detalles, consulte la página de manual.
tz
parámetro de gettimeofday()
as &(struct timezone tz = {480, 0})
no recibirá ninguna advertencia, y no tiene ningún efecto en el resultado, eso tiene sentido, ya que la long
representación del tiempo no es relevante ni se efectúa por zona horaria en sí, ¿verdad?
NULL
pasa el valor razonable. Y creo que las pruebas siempre son un buen enfoque para probar las cosas.
Úselo gettimeofday()
para obtener el tiempo en segundos y microsegundos. La combinación y el redondeo a milisegundos se deja como ejercicio.
C11 timespec_get
Vuelve a nanosegundos, redondeado a la resolución de la implementación.
Ya está implementado en Ubuntu 15.10. API tiene el mismo aspecto que 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 */
};
Más detalles aquí: https://stackoverflow.com/a/36095407/895245
Derivado de la respuesta POSIX de Dan Moulding, esto debería funcionar:
#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);
}
También como lo señaló David Guyon: compile con -lm