web-dev-qa-db-fra.com

résultats inattendus convertissant les fuseaux horaires en python

J'essaie de comprendre pourquoi j'obtiens ces résultats lors de la conversion de fuseaux horaires en UTC:

In [74]: d1 = datetime(2007, 12, 5, 6, 30,tzinfo=pytz.timezone('US/Pacific'))
In [75]: d1
Out[75]: datetime.datetime(2007, 12, 5, 6, 30, tzinfo=<DstTzInfo 'US/Pacific' LMT-1 day, **16:07:00 STD**>)
In [76]: d1.astimezone(pytz.utc)
Out[76]: datetime.datetime(2007, 12, 5, 14, 23, tzinfo=<UTC>)

Pourquoi est-ce que 6h30 est devenu 14h23? 

Par contre, si j'utilise l'approche suivante, j'obtiens le résultat attendu:

In [90]: d2 = datetime(2007, 12, 5, 6, 30)
In [91]: uspac = pytz.timezone('US/Pacific')
In [92]: d2_aware = uspac.localize(d2)
In [94]: d2_aware.astimezone(pytz.utc)
Out[94]: datetime.datetime(2007, 12, 5, 14, 30, tzinfo=<UTC>)
30
jxstanford

Extrait de la documentation partielle: http://pytz.sourceforge.net/#localized-times-and-date-arithmetic

Malheureusement, l’argument tzinfo des constructeurs de date/heure standard ‘’ ne fonctionne pas ’’ avec pytz pour de nombreux fuseaux horaires. [...] Cependant, il est sans danger pour les fuseaux horaires sans transitions à l'heure d'été, tels que UTC. [...] La façon préférée de gérer les temps est de toujours travailler en UTC, en convertissant en heure locale uniquement lors de la génération d'une sortie destinée à être lue par des humains.

25
user3834473

Ce que j'ai obtenu est juste une solution de contournement, la règle simple est Ne créez jamais de date/heure avec des informations de fuseau horaire en utilisant datetime () .

Cet exemple vous donnerait un indice pour cela. Comme vous le voyez, vous pouvez éviter la différence inattendue en effectuant une seule et unique fois une date/heure "naïve" (c'est-à-dire sans date et heure) puis la localiser (elle n'est pas appliquée lorsque vous créez une date/heure sur UTC):

import pytz
from datetime import datetime

# make Jan 1 on PDT -> UTC
pdt = pytz.timezone("America/Los_Angeles")
pdtnow1 = datetime(2014,1,1, tzinfo=pdt)
pdtnow2 = pdt.localize(datetime(2014,1,1))
pytz.utc.normalize(pdtnow1)
# > datetime.datetime(2014, 1, 1, 7, 53, tzinfo=<UTC>)
pytz.utc.normalize(pdtnow2)
# > datetime.datetime(2014, 1, 1, 8, 0, tzinfo=<UTC>)

# make Jan 1 on UTC -> PDT
utcnow1 = datetime(2014,1,1, tzinfo=pytz.utc)
utcnow2 = pytz.utc.localize(datetime(2014,1,1))
pdt.normalize(utcnow1)
# > datetime.datetime(2013, 12, 31, 16, 0, 
# > tzinfo=<DstTzInfo 'America/Los_Angeles' PST-1 day, 16:00:00 STD>)
pdt.normalize(utcnow2)
# > datetime.datetime(2013, 12, 31, 16, 0, 
# > tzinfo=<DstTzInfo 'America/Los_Angeles' PST-1 day, 16:00:00 STD>)
36
Kenial

Je reviens sur quelques questions concernant la date et l'heure pour voir si certaines des bibliothèques les plus récentes s'avèrent plus utiles dans des situations comme celle-ci (ou non). pendule est un pendule qui enregistre le fuseau horaire avec la date et l’heure, ce qui le rend particulièrement utile dans des situations comme celle-ci.

>>> import pendulum
>>> d1 = pendulum.datetime(2007,12,5,6,30, tzinfo='US/Pacific')
>>> d1
<Pendulum [2007-12-05T06:30:00-08:00]>
>>> d1.timezone
<Timezone [US/Pacific]>
>>> d1.astimezone(tz='UTC')
<Pendulum [2007-12-05T14:30:00+00:00]>

Beaucoup d'autres fonctionnalités douces aussi.

3
Bill Bell

Malheureusement, la création de dates tenant compte du fuseau horaire à l'aide de cette méthode ne fonctionne pas.

Si vous utilisez Django, ils ont une fonction utilitaire, make_aware , qui le fait correctement.

from Django.utils.timezone import make_aware
from pytz import timezone

unaware_datetime = datetime(2007, 12, 5)
local_datetime = make_aware(datetime(2007, 12, 5))
specific_datetime = make_aware(datetime(2007, 12, 5), timezone("Australia/Melbourne"))
0
Shadow

Imprimez d2_aware avant .astimezone et vous verrez PST-1 (heure standard du Pacifique) mais dans le premier exemple, vous avez LMT-1 (heure moyenne locale) - et cela peut probablement donner une différence de 7 minutes. 

Mais je ne sais pas pourquoi pytz utilise des fuseaux horaires différents.

0
furas