convert - unix stamp to date
¿Cómo convertir datetime a sello de tiempo Unix en c? (6)
el escenario es: Obtengo fecha y hora en formato "YYYY-MM-DD HH: MM: SS" con libexif. Para minimizar el costo de ahorro, quiero convertir la fecha y hora a la marca de tiempo de Unix o similar, que solo cuesta 64 bits o 32 bits. ¿Hay alguna forma explícita con c?
¿Qué pasa con sscanf?
struct tm tmVar;
char *strVar = "YYYY-MM-DD HH:MM:SS";
time_t timeVar;
if(sscanf(strVar, "%d-%d-%d %d:%d:%d", &tm.tm_year, /* the other fields */)==6)
timeVar = mktime(&tmVar);
else
// bad format
Aquí hay un fragmento de código listo cuando Strptime no está disponible:
#include <stddef.h>
#include <time.h>
#include <stdio.h>
time_t string_to_seconds(const char *timestamp_str)
{
struct tm tm;
time_t seconds;
int r;
if (timestamp_str == NULL) {
printf("null argument/n");
return (time_t)-1;
}
r = sscanf(timestamp_str, "%d-%d-%d %d:%d:%d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec);
if (r != 6) {
printf("expected %d numbers scanned in %s/n", r, timestamp_str);
return (time_t)-1;
}
tm.tm_year -= 1900;
tm.tm_mon -= 1;
tm.tm_isdst = 0;
seconds = mktime(&tm);
if (seconds == (time_t)-1) {
printf("reading time from %s failed/n", timestamp_str);
}
return seconds;
}
Ajústese una cadena en sscanf a lo que necesite. Para ignorar el huso horario y convertir siempre como GMT / UTC, reste un timezone
(o _timezone
) en seconds
(el timezone
global se define en time.h. DST ya se ignora al poner a cero el campo tm_isdst
de tm
.
Aquí hay una solución cableada en c / pseudo código que acabo de piratear. ¡Buena suerte!
char * runner = NULL;
char *string_orig = "YYYY-MM-DD HH:MM:SS";
time_t time = 0;
struct tm tmp;
use strstr(string_orig, "-") and atoi foreach
tmp->tm_year ..
tmp->tm_mon ..
tmp->tm_mday ..
tmp->tm_hour ..
tmp->tm_min ..
tmp->tm_sec ..
with *runner as help
time = mktime(&tm)
Convierta cada parte de la fecha / hora en un entero para completar una struct tm
, luego convierta eso en time_t
usando mktime .
Linux admite la función getdate()
, que creo que es más práctica que llamar directamente a strptime()
. Esto se debe a que la función getdate()
verifica automáticamente muchos formatos para usted. Es equivalente a llamar a strptime()
con varios formatos hasta que la función funcione o se hayan probado todos los formatos.
// setenv() should be called only once
setenv("DATEMSK", "/usr/share/myprog/datemsk.fmt", 0);
// convert a date
struct tm * t1(getdate("2018-03-31 14:35:46"));
if(t1 == nullptr) ...handle error...
time_t date1(timegm(t1));
// convert another date
struct tm * t2(getdate("03/31/2018 14:35:46"));
if(t2 == nullptr) ...handle error...
time_t date2(timegm(t2));
Nota: timegm()
es similar a mktime()
excepto que ignora la configuración regional y usa UTC. En la mayoría de los casos, esa es la forma correcta de convertir tus fechas.
El archivo datemsk.fmt incluiría al menos estos dos formatos para admitir las fechas anteriores:
%Y-%b-%d %H:%M:%S
%b/%d/%Y %H:%M:%S
El número de formatos admitidos no está limitado, aunque es posible que no desee tener demasiados. Va a ser bastante lento si tiene demasiados formatos. También puede administrar dinámicamente sus formatos y llamar a strptime()
en un bucle.
Linux también ofrece una función getdate_r()
que es segura para subprocesos.
Página de http://pubs.opengroup.org/onlinepubs/7908799/xsh/getdate.html : http://pubs.opengroup.org/onlinepubs/7908799/xsh/getdate.html