Cómo imprimir la hora en formato: 2009-08-10 18:17:54.811

7 minutos de lectura

avatar de usuario
Dominic Bou Samra

¿Cuál es el mejor método para imprimir la hora en C en el formato 2009‐08‐10 
18:17:54.811?

avatar de usuario
hamid nazari

Utilizar strftime().

#include <stdio.h>
#include <time.h>

int main()
{
    time_t timer;
    char buffer[26];
    struct tm* tm_info;

    timer = time(NULL);
    tm_info = localtime(&timer);

    strftime(buffer, 26, "%Y-%m-%d %H:%M:%S", tm_info);
    puts(buffer);
 
    return 0;
}

Para la parte de los milisegundos, eche un vistazo a esta pregunta. ¿Cómo medir el tiempo en milisegundos usando ANSI C?

  • Es una respuesta aún mejor ahora, y accesorios para buscar cómo manejar la parte de milisegundos. Sin embargo, creo que su búfer ahora es un poco más largo de lo necesario.

    – JackKelly

    9 de septiembre de 2010 a las 3:56

  • Es mejor ser más largo que más corto 🙂

    – pax diablo

    9 de septiembre de 2010 a las 4:12

  • Excelente respuesta. Podía hacer todo tipo de cosas en PHP, pero sabía que ya estaba todo en C. GRACIAS.

    – Vijay Kumar Kanta

    23 de enero de 2014 a las 12:43

  • Quizás la línea time(&timer) debería ser más bien timer = time(NULL);al menos para Linux. The tloc argument is obsolescent and should always be NULL in new code. When tloc is NULL, the call cannot fail.

    – Antonin Décimo

    28 de noviembre de 2016 a las 16:39


  • La respuesta es definitivamente incorrecta en al menos un caso (Linux) ya que “struct tm” utilizada por localtime() no contiene ninguna información de tiempo por debajo de los segundos. En cambio, “struct timeval” utilizado por gettimeofday() tiene microsegundos que, divididos por 1000, darán los milisegundos. ¡Todos esos votos a favor son realmente incorrectos y engañosos! A menos que alguien informe bajo qué arquitectura obtiene detalles de tiempo debajo del segundo con “struct tm”.

    – EnzoR

    28 de septiembre de 2017 a las 10:10


Las respuestas anteriores no responden completamente la pregunta (específicamente la parte de milisegundos). Mi solución a esto es usar gettimeofday antes de strftime. Tenga en cuenta el cuidado de evitar el redondeo de milisegundos a “1000”. Esto se basa en la respuesta de Hamid Nazari.

#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include <math.h>

int main() {
  char buffer[26];
  int millisec;
  struct tm* tm_info;
  struct timeval tv;

  gettimeofday(&tv, NULL);

  millisec = lrint(tv.tv_usec/1000.0); // Round to nearest millisec
  if (millisec>=1000) { // Allow for rounding up to nearest second
    millisec -=1000;
    tv.tv_sec++;
  }

  tm_info = localtime(&tv.tv_sec);

  strftime(buffer, 26, "%Y:%m:%d %H:%M:%S", tm_info);
  printf("%s.%03d\n", buffer, millisec);

  return 0;
}

  • gettimeofday no está disponible en las implementaciones de Windows

    – Mendes

    30 de junio de 2016 a las 22:17

  • Agregue las opciones ‘-lm’ cuando lo construya.

    – signo del cielo

    3 de agosto de 2016 a las 8:41


  • Creo que ese amortiguador[24] es suficiente, la razón es la siguiente, AAAA:MM:DD HH:MM:SS.mmm + ‘\0’, es 24.

    – signo del cielo

    3 de agosto de 2016 a las 8:47


  • @Mendes, ¿por qué mencionar Windows? La pregunta es sobre el lenguaje C simple. ¡Esta es una mejor respuesta (aunque no la correcta), a pesar de todos esos votos a favor incorrectos!

    – EnzoR

    28 de septiembre de 2017 a las 10:13


  • user3624334: No, no entiendes el código. Solo hay una solicitud de tiempo. Supongo que te refieres a la llamada de hora local: simplemente reformatea la salida de gettimeofday.

    – Chris

    25 de noviembre de 2019 a las 21:49

avatar de usuario
paxdiablo

time.h define un strftime función que le puede dar una representación textual de un time_t usando algo como:

#include <stdio.h>
#include <time.h>
int main (void) {
    char buff[100];
    time_t now = time (0);
    strftime (buff, 100, "%Y-%m-%d %H:%M:%S.000", localtime (&now));
    printf ("%s\n", buff);
    return 0;
}

pero eso no le dará una resolución inferior a un segundo ya que no está disponible en un time_t. Produce:

2010-09-09 10:08:34.000

Si está realmente limitado por las especificaciones y no quiere el espacio entre el día y la hora, simplemente elimínelo de la cadena de formato.

  • +1 por el truco conveniente para llenar la pantalla al milisegundo. Una vez tuve un cliente que quería que hiciera eso, pero con dígitos distintos de cero, por lo que parecía que había un significado allí. Lo convencí de que no lo hiciera, pero acepté poner ceros.

    – R. Berteig

    9 de septiembre de 2010 a las 7:22

  • Un amigo mío (no yo, por supuesto) una vez usó un truco similar: mantuvieron estáticas que contenían el último segundo y el “milisegundo”. Donde el segundo no había cambiado desde la última vez, simplemente agregaron un valor aleatorio entre 1 y 200 a milisegundos (asegurándose de que no pasara de 999, por supuesto; el máximo real para el rand() siempre fue el mínimo de 200 y la mitad de la distancia a 999). Donde el segundo cambió, simplemente establecieron milisegundos en 0 antes del agregado. Bonitos milisegundos aparentemente aleatorios pero correctamente secuenciados y el cliente no se dio cuenta 🙂

    – pax diablo

    9 de septiembre de 2010 a las 7:29


El siguiente código se imprime con una precisión de microsegundos. Todo lo que tenemos que hacer es usar gettimeofday y strftime en tv_sec y anexar tv_usec a la cadena construida.

#include <stdio.h>
#include <time.h>
#include <sys/time.h>
int main(void) {
    struct timeval tmnow;
    struct tm *tm;
    char buf[30], usec_buf[6];
    gettimeofday(&tmnow, NULL);
    tm = localtime(&tmnow.tv_sec);
    strftime(buf,30,"%Y:%m:%dT%H:%M:%S", tm);
    strcat(buf,".");
    sprintf(usec_buf,"%dZ",(int)tmnow.tv_usec);
    strcat(buf,usec_buf);
    printf("%s",buf);
    return 0;
}

truco:

    int time_len = 0, n;
    struct tm *tm_info;
    struct timeval tv;

    gettimeofday(&tv, NULL);
    tm_info = localtime(&tv.tv_sec);
    time_len+=strftime(log_buff, sizeof log_buff, "%y%m%d %H:%M:%S", tm_info);
    time_len+=snprintf(log_buff+time_len,sizeof log_buff-time_len,".%03ld ",tv.tv_usec/1000);

  • Explique por qué esto funciona. y qué está pasando exactamente.

    – Raj Kamal

    10 de marzo de 2020 a las 11:51

  • Todo lo mismo que los ejemplos anteriores, pero solo de manera más efectiva. ` time_len+=snprintf(log_buff+time_len,sizeof log_buff-time_len,”log var is=%s”,logvar); int ret = escribir (log_fd, log_buff, time_len); `

    – Андрей Мельников

    12 de marzo de 2020 a las 11:17


  • ¿De dónde importo gettimeofday?

    – Andrei

    3 de junio de 2020 a las 18:45

podrías usar strftimepero struct tm no tiene resolución para partes de segundos. No estoy seguro de si eso es absolutamente necesario para sus propósitos.

struct tm tm;
/* Set tm to the correct time */
char s[20]; /* strlen("2009-08-10 18:17:54") + 1 */
strftime(s, 20, "%F %H:%M:%S", &tm);

  • Explique por qué esto funciona. y qué está pasando exactamente.

    – Raj Kamal

    10 de marzo de 2020 a las 11:51

  • Todo lo mismo que los ejemplos anteriores, pero solo de manera más efectiva. ` time_len+=snprintf(log_buff+time_len,sizeof log_buff-time_len,”log var is=%s”,logvar); int ret = escribir (log_fd, log_buff, time_len); `

    – Андрей Мельников

    12 de marzo de 2020 a las 11:17


  • ¿De dónde importo gettimeofday?

    – Andrei

    3 de junio de 2020 a las 18:45

Ninguna de las soluciones en esta página funcionó para mí, las mezclé y las hice funcionar con Windows y Visual Studio 2019, así es como:

#include <Windows.h>
#include <time.h> 
#include <chrono>

static int gettimeofday(struct timeval* tp, struct timezone* tzp) {
    namespace sc = std::chrono;
    sc::system_clock::duration d = sc::system_clock::now().time_since_epoch();
    sc::seconds s = sc::duration_cast<sc::seconds>(d);
    tp->tv_sec = s.count();
    tp->tv_usec = sc::duration_cast<sc::microseconds>(d - s).count();
    return 0;
}

static char* getFormattedTime() {
    static char buffer[26];

    // For Miliseconds
    int millisec;
    struct tm* tm_info;
    struct timeval tv;

    // For Time
    time_t rawtime;
    struct tm* timeinfo;

    gettimeofday(&tv, NULL);

    millisec = lrint(tv.tv_usec / 1000.0);
    if (millisec >= 1000) 
    {
        millisec -= 1000;
        tv.tv_sec++;
    }

    time(&rawtime);
    timeinfo = localtime(&rawtime);

    strftime(buffer, 26, "%Y:%m:%d %H:%M:%S", timeinfo);
    sprintf_s(buffer, 26, "%s.%03d", buffer, millisec);

    return buffer;
}

resultado :

2020:08:02 06:41:59.107

2020:08:02 06:41:59.196

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad