Comment convertir datetime en timestamp Unix en c?
Question
le scénario est le suivant: l’heure et la date sont au format "AAAA-MM-JJ HH: MM: SS" avec libexif. Pour minimiser les coûts d’économie, je souhaite convertir la date / heure en un horodatage Unix ou similaire, qui ne coûte que 64 bits ou 32 bits. Y at-il un moyen explicite avec c?
Autres conseils
Convertissez chaque partie de la date / heure en un entier pour remplir un struct tm
, puis convertissez-la en un time_t
en utilisant mktime .
Voici une solution câblée dans c / pseudo-code que je viens de pirater ensemble. Bonne chance!
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)
Qu'en est-il de 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
Voici un extrait prêt lorsque strptime n'est pas 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;
}
Ajustez vous-même une chaîne dans sscanf à ce dont vous avez besoin. Pour ignorer le fuseau horaire et convertir toujours au format GMT / UTC, soustrayez un fuseau horaire
(ou _timezone
) à secondes
( timezone
global est défini dans time.h. DST est déjà ignoré en mettant à zéro le champ tm_isdst
du champ tm
.
Linux prend en charge la fonction getdate ()
, qui, à mon avis, est plus pratique que d'appeler directement strptime ()
. En effet, la fonction getdate ()
vérifie automatiquement de nombreux formats pour vous. C'est l'équivalent d'appeler strptime ()
avec différents formats jusqu'à ce que la fonction fonctionne ou que tous les formats aient été testés.
// 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));
Remarque: timegm ()
est similaire à mktime ()
, à la différence près qu'il ignore les paramètres régionaux et utilise le code UTC. Dans la plupart des cas, c’est le bon moyen de convertir vos dates.
Le fichier datemsk.fmt inclurait au moins ces deux formats pour prendre en charge les dates ci-dessus:
%Y-%b-%d %H:%M:%S
%b/%d/%Y %H:%M:%S
Le nombre de formats pris en charge n'est pas limité, même si vous ne souhaitez pas en avoir trop. Si vous avez trop de formats, ça va être plutôt lent. Vous pouvez également gérer dynamiquement vos formats et appeler strptime ()
en boucle.
Linux propose également une fonction getdate_r ()
qui est thread-safe.
Man Page: http://pubs.opengroup.org/onlinepubs/ 7908799 / xsh / getdate.html