Una forma de formatearlo es:
printf("%lld.%.9ld", (long long)ts.tv_sec, ts.tv_nsec);
Lo siguiente devolverá una marca de tiempo UTC compatible con ISO8601 y RFC3339, incluidos los nanosegundos.
Utiliza strftime()
, que funciona con struct timespec
tan bien como con struct timeval
porque lo único que le importa es la cantidad de segundos, que ambos brindan. Luego se agregan nanosegundos (¡cuidado de rellenar con ceros!) así como el sufijo UTC 'Z'.
Salida de ejemplo:2021-01-19T04:50:01.435561072Z
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
int utc_system_timestamp(char[]);
int main(void) {
char buf[31];
utc_system_timestamp(buf);
printf("%s\n", buf);
}
// Allocate exactly 31 bytes for buf
int utc_system_timestamp(char buf[]) {
const int bufsize = 31;
const int tmpsize = 21;
struct timespec now;
struct tm tm;
int retval = clock_gettime(CLOCK_REALTIME, &now);
gmtime_r(&now.tv_sec, &tm);
strftime(buf, tmpsize, "%Y-%m-%dT%H:%M:%S.", &tm);
sprintf(buf + tmpsize -1, "%09luZ", now.tv_nsec);
return retval;
}
Ejemplo de línea de comando GCC (tenga en cuenta el -lrt
):
gcc foo.c -o foo -lrt
Quería hacer la misma pregunta. Aquí está mi solución actual para obtener una cadena como esta:2013-02-07 09:24:40.749355372
No estoy seguro de si existe una solución más directa que esta, pero al menos el formato de cadena se puede configurar libremente con este enfoque.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define NANO 1000000000L
// buf needs to store 30 characters
int timespec2str(char *buf, uint len, struct timespec *ts) {
int ret;
struct tm t;
tzset();
if (localtime_r(&(ts->tv_sec), &t) == NULL)
return 1;
ret = strftime(buf, len, "%F %T", &t);
if (ret == 0)
return 2;
len -= ret - 1;
ret = snprintf(&buf[strlen(buf)], len, ".%09ld", ts->tv_nsec);
if (ret >= len)
return 3;
return 0;
}
int main(int argc, char **argv) {
clockid_t clk_id = CLOCK_REALTIME;
const uint TIME_FMT = strlen("2012-12-31 12:59:59.123456789") + 1;
char timestr[TIME_FMT];
struct timespec ts, res;
clock_getres(clk_id, &res);
clock_gettime(clk_id, &ts);
if (timespec2str(timestr, sizeof(timestr), &ts) != 0) {
printf("timespec2str failed!\n");
return EXIT_FAILURE;
} else {
unsigned long resol = res.tv_sec * NANO + res.tv_nsec;
printf("CLOCK_REALTIME: res=%ld ns, time=%s\n", resol, timestr);
return EXIT_SUCCESS;
}
}
salida:
gcc mwe.c -lrt
$ ./a.out
CLOCK_REALTIME: res=1 ns, time=2013-02-07 13:41:17.994326501