Comportamiento extraño de mktime ()
Pregunta
Continuando mi intento de crear una clase de fecha y hora , Estoy tratando de almacenar el tiempo de "época" en mi función:
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 una fecha arbitraria, processComponents(5,5,1990,1,23,45)
(6 de junio de 1990 1:23:45 am), establece todos los valores correctamente y como se esperaba.
Sin embargo, tras pruebas adicionales, lo encuentro para processComponents(0,0,1970,0,0,0)
(1 de enero de 1970, 12:00:00 am), mktime(&time)
causas time
Para ser jodido:
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;
Traduciendo a una fecha del 31 de diciembre de 1969 11:00:00 p.m.
Puedo verificar que mktime()
es responsable, porque al comentar esa línea, informa la fecha y la hora correctamente como el 1 de enero de 1970 12:00:00 a.m.
Por que es mktime()
¿Solo arruinando la época? ¿Y cómo debo arreglar / solucionar esto?
¡Gracias!
Solución
Estás pasando 0 como el day
parámetro y ponerlo en time.tm_mday
. Ese componente (y solo ese componente) de struct tm
está basado en 1, no basado en 0.
No me preguntes por qué.
Para especificar el 01 de enero de 1970, 12:00:00 AM querrás llamarlo así:
processComponents(0,1,1970,0,0,0);
Y como Sdtom mencionado, querrás asegurarte de que tm_isdst
se establece apropiadamente, 0 para no vigente, positivo en efecto, y negativo para usted no sabe (en cuyo caso mktime()
debería intentar adivinar).
Solo para hacerle saber, cuando paso la fecha que tiene (0 de enero de 1970, 00:00:00) mktime()
En MSVC 9 devuelve un error (el pasado en struct tm
no ha sido tocado y el regresado time_t
el valor es -1).
Otros consejos
Dado que está apagado por una hora, esperaría el tiempo de ahorro para el día. ¿El valor del tiempo.tm_isdst se está configurando en algún lugar? Si no lo está configurando, podría estar configurado aleatoriamente en 1 o 0, lo que afectaría sus resultados.
Pasando todos los ceros a mktime()
se interpreta como "Sol 0 00:00:00 1900". Según esto, debe haber algunos 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 );
}