Le module datetime de Python est fréquemment utilisé dans mon travail quotidien, et voici quelques gotchas liés aux fuseaux horaires lors de la conversion d’une datetime en un time/epoch Unix, qui est le nombre de secondes qui se sont écoulées depuis le jeudi 1 janvier 1970 00:00:00 UTC.
LeUTC (Universal Time Coordinated) est utile lorsqu’on a affaire à des ordinateurs situés dans différents fuseaux horaires. De plus, certaines heures locales varient, par exemple, la Californie utilise le PDT (Pacific Daylight Time, 7 heures derrière UTC) en été et le PST (Pacific Standard Time, 8 heures derrière UTC) en hiver.
Prenez le 13 septembre 2020 12:26:40 UTC par exemple, la conversion en heure Unix est assez simple:
$ date --date="Sep 13 12:26:40 UTC 2020" +%s
1600000000$ date -d @1600000000 -u
Sun Sep 13 12:26:40 UTC 2020
Il ne semble pas y avoir de moyen facile dans Python2 pour le faire. Donc soit nous devons suivre la définition de l’UTC et faire quelques calculs, soit utiliser la fonction strftime()
de la bibliothèque C et faire attention au fuseau horaire.
# 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
C’est bien jusque là, qu’en est-il de 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
Le temps d’époque n’est pas correct car strftime()
dépend de la variable d’environnement TZ.
# Setting environment variable TZ to UTC
$ TZ=UTC python epoch2.py
1600000000
Avec TZ=UTC
le résultat est correct. Ce paramètre est délicat car la logique de conversion peut être profondément imbriquée à l’intérieur d’un programme massif sur un autre ordinateur, et TZ
la valeur peut être n’importe quoi. Python 3 fournit une manière plus propre.
# 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
Eh bien, une raison de plus pour passer à Python 3 😉
.