aikavyöhyke on kova ongelma. DST on vielä vaikeampi ongelma. Löysin itseni kävely ongelmia ja ongelmia, kun aloin käyttää datetime Python oikein. Joten päätän kirjoittaa blogin jakaa kokemukseni.

”naiivi”ja” tietoinen ”

ensimmäinen tieto on, että Pythonissa on kahdenlaisia datetime: offset-naiivi ja offset-aware. Offset naiivi tarkoittaa, että datetime ei ole aikavyöhyke tietoa. Se voi olla hyvin virhealtis, jos olet uusi Python. Jos sekoitat naiivi datetime ja tietoinen datetime, saat virheen. Ja Python ei ole sisäänrakennettu aikavyöhyke tuki, sinun täytyy käyttää pytz, moduuli aikavyöhyke tietoja.

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

tällaisen ongelman välttämiseksi sinun on varmistettava, että datetime-kohteesi ovat aina offset-naiiveja tai aina offset-tietoisia. Mutta emme voi välttää aikavyöhykettä, joten minun paras käytäntö on aina työskennellä offset-tietoinen aikavyöhyke.

Python-oletus on naiivi datetime. now() palauttaa naiivin aikavyöhykkeen paikallisella aikavyöhykkeellä, ja utcnow() palauttaa myös naiivin aikavyöhykkeen, vaikka funktio jo ilmaisee UTC-aikavyöhykkeen! Tarvitset pytz moduulin ja myös tzlocal moduulin saadaksesi asiat kuntoon. Alla on, miten saan aikaa oikealla aikavyöhykkeellä.

import datetime
import pytz
import tzlocaldef utcnow():
return pytz.utc.localize(datetime.utcnow())def now():
return tzlocal.get_localzone().localize(datetime.now())

jäsennetään aikavyöhykkeellä

päivitys: Tämä on vain ongelma Python 2: ssa

toinen yllätys on python strptime jäsennin ei toimi aikavyöhykkeellä. Alla oleva koodi vain epäonnistuu.

>>> 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'

tulkitaksesi aikavyöhykkeellä aikavyöhykkeen, tarvitset toisen moduulin python-dateutil . Tämä moduuli tarjoaa jäsennin, joka toimii aikavyöhykkeellä. Nyt voit jäsentää datetime kanssa aikavyöhyke!

>>> from dateutil import parser
>>> parser.parse('2017-11-15T12:00:00-07')datetime.datetime(2017, 11, 15, 12, 0, tzinfo=tzoffset(None, -25200))

Timedelta ja DST

the last thing you need to be careful what manipulating offset-aware datetime. pytz avulla voit tarkistaa dst() – menetelmän avulla, onko jokin päivämäärä DST: n vaikutuksen alainen.

>>> 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)

Huom: vuoden 2017 DST päättyi 5.marraskuuta. Joten mikä tahansa päivämäärä 5. marraskuuta jälkeen on timedelta(0)

, mutta dst() tietoja ei päivitetä, kun manipuloit aikaleimaa

>>> (pst.localize(datetime(2017, 10, 1)) + timedelta(days=60)).dst()
datetime.timedelta(0, 3600)

mitä voit todella tehdä on muuntaa takaisin naiivi-offset aikaleima, sitten soveltaa delta…

pst.localize(yourdate.replace(tzinfo=None) + td).dst()

Yhteenveto

työskentely Datetimen kanssa Pythonissa on virhealtista. Se johtuu siitä, että Python ei tue hyvin datetime ja aikavyöhyke. Sinun täytyy käyttää paljon lisämoduuleja. Kuitenkin, on todella Hopea luoti, voit vain käyttää nuolta. Tämä moduuli tarjoaa korvaavan python datetime moduuli, ja se on aina offset-tietoinen, ja se myös ratkaisee kaikki ongelmat, jotka mainitsen edellä. Ainoa asia, jota saatan olla huolissani, on integrointi muihin ulkoisiin sovelluksiin, kuten Sparkiin.