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?

Était-ce utile?

La solution

Vous pouvez essayer une combinaison de strptime et de mktime

struct tm tm;
time_t epoch;
if ( strptime(timestamp, "%Y-%m-%d %H:%M:%S", &tm) != NULL )
  epoch = mktime(&tm);
else
  // badness

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top