2011-09-16 13 views
5

Estoy usando la función mktime (struct tm *) en Suse 10.Comportamiento confuso de mktime en Linux?

Ahora, estoy notando un comportamiento extraño cuando el horario de verano está habilitado. Digamos que he habilitado el horario de verano para comenzar el 15 de septiembre a las 18:10 y la corrección de la luz del día es de 30 minutos. Ahora, cuando llamo a mktime con la estructura tm que tiene la fecha como 15/09 18:10 y tm_isdst se establece en 0, obtengo los mismos valores en la estructura tm solo con tm_isdst establecido en 1.

Pero, si pasa la fecha como 15 de septiembre a las 18:10 con tm_isdst establecido en 1, entonces el tiempo cambia a 17:40. Esta corrección en la estructura tm se observa por el tiempo transcurrido entre el 15 de septiembre de 18:10 a 15 de septiembre de 18:40, pero después de eso no ocurre ninguna corrección en el tiempo y la bandera de dst permanece habilitada. Incluso si paso la fecha como 16 de septiembre a las 18:10, no se produce corrección de tiempo, solo la bandera de dst permanece activada.

Estoy totalmente confundido. ¿Es este el comportamiento correcto de mktime?

Respuesta

6

Si los cambios de la hora local de 30 minutos para el horario de verano, luego una vez al año hay 30 minutos de tiempo local que ocurre dos veces (una vez con el horario de verano, y otra sin él) y otros 30 minutos que nunca ocurre (se omite cuando cambia la hora).

Por lo tanto, se especifican las horas locales dentro de los 30 minutos posteriores a la desconexión del reloj, a menos que se especifique si el horario de verano está vigente; hay dos instantes reales en el tiempo que podrían corresponderse.

Los tiempos locales dentro de los 30 minutos desde que se adelanta el reloj no son válidos; no hay instantes reales en el tiempo al que puedan corresponder (aunque la conversión aún se puede hacer suponiendo que el horario de verano esté vigente o que no esté en vigencia).

Por lo tanto, para algunas horas locales (ignorando el estado DST) podría haber más de una hora UTC correspondiente, pero para cualquier hora UTC dada solo hay una hora local posible (si los ajustes de horario de verano se tienen en cuenta adecuadamente).

Cuando llama al mktime, está convirtiendo la hora local que le asigna a time_t como si el horario de verano estuviera vigente o no, según el valor de tm_isdst. Los valores corregidos que obtiene se basan en el reverso de esta conversión, y el sistema determinará si obtiene un horario de verano o un horario de horario de verano diferente, dependiendo de su idea de si el horario de verano está vigente en el momento de la conversión. El tiempo que le diste y el momento en que regresó representan en realidad el mismo momento en el tiempo, pero con diferentes desplazamientos de UTC debido a los diferentes estados del horario de verano.

Así que sí, este es el comportamiento correcto de mktime. Se supone que debe normalizar los valores en la estructura, de acuerdo con su idea de cómo representar correctamente el tiempo que le diste.

Esto también ilustra por qué se debe tener cuidado al usar la hora local para realizar un seguimiento de los eventos reales: si el estado del horario de verano o el desplazamiento de UTC no se guardan junto con la hora, algunos valores de tiempo locales pueden ser ambiguos.

+0

No lo sé.Tal vez no está definido pasar el tiempo 18:10 (dst 0) a mktime, pero creo que lo más útil para devolver en ese caso sería 18:40 (dst 1) –

0

Consulte this answer y vea si eso ayuda. Además, ¿cuál es la compensación del huso horario del sistema? Compruebe ejecutando:

date +%z 
+1

Gracias por su respuesta. El desplazamiento del huso horario del sistema devuelve +0830. Pero, mi pregunta es por qué la corrección de tiempo ocurre solo en el momento en que se habilita el horario de verano. Por ejemplo: el horario de verano está configurado para habilitarse el 15 de septiembre a las 18:10, por lo que el problema ocurre desde ese momento durante media hora. Pero, el 16 de septiembre 18:10, el problema no sucede. ¿Por qué? – Jay

Cuestiones relacionadas