El módulo datetime de Python se utiliza con frecuencia en mi trabajo diario, y aquí hay algunos inconvenientes relacionados con la zona horaria al convertir un tiempo de fecha en un tiempo/epoca de Unix, que es el número de segundos que han transcurrido desde el jueves, 1970 1 de enero 00:00:00 UTC.
UTC (Tiempo Universal Coordinado) es útil cuando se trata de ordenadores en diferentes zonas horarias. Además, algunas horas locales varían, por ejemplo, California utiliza PDT (Pacific Daylight Time, 7 horas por detrás de UTC) en verano y PST (Pacific Standard Time, 8 horas por detrás de UTC) en invierno.
Toma el 13 de septiembre de 2020 12:26:40 UTC por ejemplo, convertirlo a la hora de Unix es bastante sencillo:
$ date --date="Sep 13 12:26:40 UTC 2020" +%s
1600000000$ date -d @1600000000 -u
Sun Sep 13 12:26:40 UTC 2020
No parece haber una manera fácil en Python2 de hacer esto. Así que o bien tenemos que seguir la definición de UTC y hacer algunos cálculos, o bien utilizar la función de la biblioteca C strftime()
y tener cuidado con la zona horaria.
# save this code to epoch.py and run with Python 2.7
from datetime import datetime
from dateutil.tz import tzutcdt_2020 = datetime(2020, 9, 13, 12, 26, 40, tzinfo=tzutc())
dt_1970 = datetime(1970, 1, 1, 0, 0, 0, tzinfo=tzutc())
print int((dt_2020 - dt_1970).total_seconds())$ python epoch.py
1600000000
Hasta aquí todo bien, qué pasa con strftime()?
# save this code to epoch2.py and run with Python 2.7
from datetime import datetime
from dateutil.tz import tzutcdt_2020 = datetime(2020, 9, 13, 12, 26, 40, tzinfo=tzutc())
print dt_2020.strftime('%s')$ python epoch2.py
1600028800$ date -d -@1600028800 -u
Sun Sep 13 20:26:40 UTC 2020
El tiempo de época no es correcto porque strftime()
depende de la variable de entorno TZ.
# Setting environment variable TZ to UTC
$ TZ=UTC python epoch2.py
1600000000
Con TZ=UTC
el resultado es correcto. Esta configuración es complicada ya que la lógica de conversión puede estar profundamente anidada dentro de un programa masivo en otro ordenador, y el valor de TZ
puede ser cualquier cosa. Python 3 proporciona una forma más limpia.
# save this code to epoch3.py and run with Python 3.4
from datetime import datetime, timezonedt_2020 = datetime(2020, 9, 13, 12, 26, 40, tzinfo=timezone.utc)
print(int(dt_2020.timestamp()))$ python3 epoch3.py
1600000000
Bueno, una razón más para pasarse a Python 3 😉