Use timedelta para cambiar entre zonas horarias. Todo lo que necesita es el desplazamiento en horas entre zonas horarias. No tiene que jugar con los límites de los 6 elementos de un objeto de fecha y hora. timedelta maneja los años bisiestos, los siglos bisiestos, etc., también, con facilidad. Primero debes
from datetime import datetime, timedelta
Entonces, si offset
es la zona horaria delta en horas:
timeout = timein + timedelta(hours = offset)
donde timein y timeout son objetos datetime. p.ej
timein + timedelta(hours = -8)
convierte de GMT a PST.
Entonces, ¿cómo determinarlo offset
? Aquí hay una función simple, siempre que solo tenga algunas posibilidades de conversión sin usar objetos de fecha y hora que sean "conscientes" de la zona horaria, lo que algunas otras respuestas hacen muy bien. Un poco manual, pero a veces la claridad es mejor.
def change_timezone(timein, timezone, timezone_out):
'''
changes timezone between predefined timezone offsets to GMT
timein - datetime object
timezone - 'PST', 'PDT', 'GMT' (can add more as needed)
timezone_out - 'PST', 'PDT', 'GMT' (can add more as needed)
'''
# simple table lookup
tz_offset = {'PST': {'GMT': 8, 'PDT': 1, 'PST': 0}, \
'GMT': {'PST': -8, 'PDT': -7, 'GMT': 0}, \
'PDT': {'GMT': 7, 'PST': -1, 'PDT': 0}}
try:
offset = tz_offset[timezone][timezone_out]
except:
msg = 'Input timezone=' + timezone + ' OR output time zone=' + \
timezone_out + ' not recognized'
raise DateTimeError(msg)
return timein + timedelta(hours = offset)
Después de mirar las numerosas respuestas y jugar con el código más ajustado que se me ocurre (por ahora) parece mejor que todas las aplicaciones, donde el tiempo es importante y se deben tener en cuenta las zonas horarias mixtas, deben hacer un esfuerzo real para hacer todos los objetos de fecha y hora "consciente". Entonces parece que la respuesta más simple es:
timeout = timein.astimezone(pytz.timezone("GMT"))
para convertir a GMT por ejemplo. Por supuesto, para convertir a / desde cualquier otra zona horaria que desee, local o de otro tipo, simplemente use la cadena de zona horaria apropiada que Pytz entiende (de pytz.all_timezones). El horario de verano también se tiene en cuenta.