Pergunta

Continuando Minha tentativa de criar uma classe DateTime , Estou tentando armazenar o tempo "Epoch" na minha função:

void DateTime::processComponents(int month, int day, int year, 
                                 int hour, int minute, int second) {
    struct tm time;
    time.tm_hour = hour;
    time.tm_min = minute;
    time.tm_sec = second;
    time.tm_mday = day;
    time.tm_mon = month;
    time.tm_year = year - 1900;
    ticks_ = mktime(&time);

    processTm(time);
}

void DateTime::processTm(struct tm time) {
    second_ = time.tm_sec;
    minute_ = time.tm_min;
    hour_ = time.tm_hour;
    weekday_ = time.tm_wday;
    monthday_ = time.tm_mday;
    yearday_ = time.tm_yday;
    month_ = time.tm_mon;
    year_ = time.tm_year + 1900;
}

Para uma data arbitrária, processComponents(5,5,1990,1,23,45) (6 de junho de 1990 1:23:45), ele define todos os valores corretamente e como esperado.

No entanto, após mais testes, acho isso para processComponents(0,0,1970,0,0,0) (1 de janeiro de 1970, 12:00:00), mktime(&time) causas time Para ser estragado:

time.tm_mon  = 11;
time.tm_mday = 30;
time.tm_year = 69;
time.tm_hour = 23;
time.tm_min  = 0;
time.tm_sec  = 0;

time.tm_isdst  = 0;
time.tm_gmtoff = -18000;
time.tm_zone   = "EST";
time.tm_wday   = 2;
time.tm_yday   = 363;

Traduzindo para uma data de 31 de dezembro de 1969 23:00:00.

Eu posso verificar isso mktime() é responsável, porque, ao comentar essa linha, ele relata a data e a hora corretamente em 1º de janeiro de 1970 12:00:00.

Por que é mktime() Apenas bagunçando a época? E como devo consertar / alternar isso?

Obrigado!

Foi útil?

Solução

Você está passando 0 como o day parâmetro e colocando isso em time.tm_mday. Aquele componente (e somente esse componente) de struct tm é baseado em 1, não baseado em 0.

Não me pergunte o porquê.

Para especificar 01 de janeiro de 1970, 12:00:00, você gostaria de chamar assim:

processComponents(0,1,1970,0,0,0);

E como SDTOM mencionado, você vai querer ter certeza de que tm_isdst está definido adequadamente - 0 para não em vigor, positivo para efeitos e negativo para você não sabe (nesse caso mktime() deve tentar adivinhar).

Só para avisar, quando eu passar a data que você tem (0 de janeiro de 1970: 00:00:00) para mktime() No MSVC 9, ele retorna um erro (o passado em struct tm é intocado e o devolvido time_t o valor é -1).

Outras dicas

Como está desligado por uma hora, eu esperaria o horário de verão. O valor do tempo.tm_isdst está sendo definido em algum lugar? Se você não estiver configurando, pode estar sendo definido aleatoriamente como 1 ou 0, o que afetaria seus resultados.

Passando todos os zeros para mktime() é interpretado como "Sun Jan 0 00:00:00 1900". Com base nisso, é preciso haver alguns ajustes ...

// the input is local time
// the output is seconds since the epoch
// The epoch is Jan 1, 1970 @ 0:00 GMT
time_t mktime_wrapper( int month, int day, int year,
                       int hour=0, int min=0, int sec=0, bool isDST=-1
                     )
   {
   tm t;
   t.tm_sec=sec, t.tm_min=min, t.tm_hour=hour, t.tm_isdst=isDST;
   t.tm_mday=day, t.tm_mon=month-1, t.tm_year=year-1900;
   return mktime( &t );
   }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top