Datetime to Unix time/epoch in Python 2 / 3

Il modulo datetime di Python è usato frequentemente nel mio lavoro quotidiano, e qui ci sono alcuni intoppi legati al fuso orario quando si converte un datetime in un Unix time/epoch, che è il numero di secondi che sono trascorsi da giovedì, 1970 gennaio 1 00:00:00 UTC.

UTC (Universal Time Coordinated) è utile quando si ha a che fare con computer in diversi fusi orari. Inoltre, alcuni fusi orari locali variano, ad esempio, la California usa PDT (Pacific Daylight Time, 7 ore dietro UTC) in estate e PST (Pacific Standard Time, 8 ore dietro UTC) in inverno.

Prendiamo il 13 settembre 2020 12:26:40 UTC per esempio, convertirlo in tempo Unix è abbastanza semplice:

$ date --date="Sep 13 12:26:40 UTC 2020" +%s
1600000000$ date -d @1600000000 -u
Sun Sep 13 12:26:40 UTC 2020

Non sembra esserci un modo semplice in Python2 per farlo. Quindi o dobbiamo seguire la definizione UTC e fare un po’ di matematica, o usare la funzione strftime() della libreria C e stare attenti al fuso orario.

# 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

Fin qui tutto bene, che dire di 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

Il tempo epocale non è corretto perché strftime() dipende dalla variabile ambientale TZ.

# Setting environment variable TZ to UTC 
$ TZ=UTC python epoch2.py
1600000000

Con TZ=UTC il risultato è corretto. Questa impostazione è complicata poiché la logica di conversione può essere profondamente annidata all’interno di un programma massiccio su un altro computer, e il valore TZ può essere qualsiasi cosa. Python 3 fornisce un modo più pulito.

# 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

Bene, una ragione in più per passare a Python 3 😉

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *