Pergunta

o cenário é: recebo datetime no formato "AAAA-MM-DD HH: MM: SS" com libexif. Para minimizar o custo salvar, eu quero converter a datetime para unix timestamp ou iguais que só 64bit custo ou de 32 bits. Existe alguma maneira explícita com c?

Foi útil?

Solução

Você poderia tentar uma combinação de strptime e mktime

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

Outras dicas

Converter cada parte da data / hora em um número inteiro para preencher um struct tm, em seguida, converter isso em um time_t usando mktime .

Aqui está uma solução com fio em c / code pseudo eu só cortei juntos. Boa sorte!

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)

E sobre 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

Aqui está um trecho pronto quando strptime não está disponível:

#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;
}

Ajustar o youself uma string em sscanf para o que você precisa. Para ignorar o fuso horário e converter sempre como GMT / UTC subtrair um timezone (ou _timezone) de seconds (timezone global está definido no time.h. DST já é ignorada por zerar campo tm_isdst de tm.

O Linux suporta a função getdate(), que eu acho que é mais prático do que chamar strptime() diretamente. Isso ocorre porque a função getdate() automaticamente cheques muitos formatos para você. É um equivalente a chamar strptime() com vários formatos até que as obras de função ou todos os formatos foram testados.

// 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() é semelhante ao mktime() exceto que ele ignora o local e usa UTC. Na maioria dos casos isso é o caminho certo para converter suas datas.

O arquivo datemsk.fmt iria incluir pelo menos estes dois formatos para apoiar as datas acima:

%Y-%b-%d %H:%M:%S
%b/%d/%Y %H:%M:%S

O número de formatos suportados não é limitado, embora você não pode querer ter demasiados. Vai ser um pouco lento se você tiver muitos formatos. Você também pode gerenciar dinamicamente os seus formatos e strptime() chamada em um loop.

Linux também oferece uma função getdate_r() que é thread-safe.

Homem Página: http://pubs.opengroup.org/onlinepubs/ 7908799 / XSH / getdate.html

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top