GNU/Linux >> Tutoriales Linux >  >> Linux

Formato de estructura timespec

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

Linux
  1. 6 opciones avanzadas de formato tcpdump

  2. ¿Formateo de Namenode en la instalación de Hadoop?

  3. ¿Cómo podría interceptar las llamadas del sistema Linux?

  4. ¿Cómo detectar el cambio de dirección IP mediante programación en Linux?

  5. ¿API de Linux para enumerar los procesos en ejecución?

Trucos de formato para el comando de fecha de Linux

imprimir pila de llamadas en C o C++

Valores máximos para time_t (struct timespec)

Manera eficiente de encontrar task_struct por pid

Cómo convertir cadena a entero en UNIX

Manejo de memoria con struct epoll_event