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.