Tidssone er et vanskelig problem. DST er enda et vanskeligere problem. Jeg fant meg selv å gå inn i problemer og problemer da jeg begynte å bruke datetime i Python riktig. Så jeg bestemmer meg for å skrive en blogg for å dele min erfaring.
«Naiv» Og «Klar»
det første du må vite er At I Python er det to typer datetime: offset-naiv og offset-klar. Offset naive betyr at datetime har ingen tidssone informasjon. Det kan være veldig feil utsatt hvis du er ny Til Python. Hvis du blander en naiv datetime og klar datetime, vil du få en feil. Og Python har ikke innebygd tidssone støtte, må du bruke pytz, en modul for tidssone informasjon.
import pytz
from datetime import datetimetznaive_datetime = datetime(2018, 1, 1, 12, 0)
tzaware_datetime = datetime(2018, 1, 1, 12, 0, tzinfo=pytz.utc)# this will raise an error
tznaive_datetime == tzaware_datetime
for å unngå denne typen problem må du sørge for at datetime-objektene dine alltid er offset-naive eller alltid offset-aware. Men vi kan ikke unngå å håndtere tidssone, så min beste praksis er å alltid jobbe med offset-aware datetime.
Python standard er naiv datetime. now()
returnerer naiv datetime i din lokale tidssone, og utcnow()
returnerer også en naiv datetime, selv om funksjonen allerede angir UTC-tidssonen! Du trenger pytz
modulen og også tzlocal
modulen for å få ting riktig. Nedenfor er hvordan jeg får tid med riktig tidssone.
import datetime
import pytz
import tzlocaldef utcnow():
return pytz.utc.localize(datetime.utcnow())def now():
return tzlocal.get_localzone().localize(datetime.now())
Parsing datetime med tidssone
Oppdatering: Dette er bare er et problem I Python 2
En annen overraskelse er python strptime
parser fungerer ikke med tidssone. Koden nedenfor vil bare mislykkes.
>>> from datetime import datetime
>>> datetime.strptime('2017-11-15T12:00:00-0700', '%Y-%m-%dT%H:%M:%S%z')ValueError: 'z' is a bad directive in format '%Y-%m-%dT%H:%m:%S%z'
for å analysere datetime med tidssone, trenger du en annen modul python-dateutil
. Denne modulen gir en parser som vil fungere med tidssone. Nå kan du analysere datetime med tidssone!
>>> from dateutil import parser
>>> parser.parse('2017-11-15T12:00:00-07')datetime.datetime(2017, 11, 15, 12, 0, tzinfo=tzoffset(None, -25200))
Timedelta og SOMMERTID
det siste du må være forsiktig når du manipulerer offset-aware datetime. pytz
vil hjelpe deg å fortelle om en dato er UNDER DST innflytelse ved å sjekke dst()
metode.
>>> import pytz
>>> pst = pytz.timezone("US/Pacific")
>>> pst.localize(datetime(2017, 10, 1)).dst()
datetime.timedelta(0, 3600)
>>> pst.localize(datetime(2017, 12, 1)).dst()
datetime.timedelta(0)
MERK: SOMMERTID for 2017 endte På 5 November. Så noen dato etter 5. November vil ha timedelta(0)
men dst()
informasjonen oppdateres ikke når du manipulerer datetime
>>> (pst.localize(datetime(2017, 10, 1)) + timedelta(days=60)).dst()
datetime.timedelta(0, 3600)
det du egentlig kan gjøre er å konvertere tilbake til naiv-offset datetime, og bruk deretter deltaet…
pst.localize(yourdate.replace(tzinfo=None) + td).dst()
Sammendrag
Arbeide Med Datetime I Python er utsatt for feil. Det er fordi Python ikke støtter godt datetime og tidssone. Du må bruke mange tilleggsmoduler. Men det er faktisk en sølvkule, kan du bare bruke pil. Denne modulen gir en erstatning for python datetime-modulen, og den er alltid offset-aware, og det loser ogsa alle problemer som jeg nevner ovenfor. Det eneste jeg kan være bekymret er integrasjonen med andre eksterne applikasjoner som Spark.
Legg igjen en kommentar