¿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, gettimeofdayestá 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_gettimefunció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_MONOTONIClugar de CLOCK_REALTIME.
gcccomando.
scuando 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 longrepresentación del tiempo no es relevante ni se ve afectada por la zona horaria en sí, tzno 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 timezoneestructura es obsoleto, por lo que el tzargumento normalmente debe especificarse como NULL; para obtener más detalles, consulte la página de manual.
tzpará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 longrepresentación del tiempo no es relevante ni se efectúa por zona horaria en sí, ¿verdad?
NULLpasa 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