2015-09-03 4 views
2

Voici le code qui analyse d'abord le temps de la chaîne dans IST, puis convertit celui-ci en UTC. Donc, quand il est 16h00 en Inde, l'heure GMT/UTC est 10h30. Alors que le code suivant l'imprime à 21h30. Donc, au lieu de soustraire le décalage, il ajoute le décalage. À partir de la documentation python https://docs.python.org/2/library/datetime.html#datetime.datetime.astimezone l'exemple d'implémentation de astimezone, il apparaît qu'il ajouterait le décalage s'il est négatif mais il semble contraire à ce qu'il devrait faire. La documentation dit qu'elle ajuste l'heure de telle sorte que l'heure UTC reste la même mais dans l'heure locale passée de timezone qui est contraire à l'exemple d'implémentation.Python datetime.astimezone comportement incorrect?

from dateutil.parser import parse 
from pytz import timezone 

d = parse('Tue Sep 01 2015 16:00:00 GMT+0530') 

# Prints datetime.datetime(2015, 9, 1, 16, 0, tzinfo=tzoffset(None, -19800)) 
print d 

utc = timezone('UTC') 

# Prints datetime.datetime(2015, 9, 1, 21, 30, tzinfo=<UTC>) 
print d.astimezone(utc) 

Je ne suis pas sûr de ce qui ne va pas. Est-ce la mise en œuvre de l'astimezone ou de la documentation ou le décalage lui-même a son signe inversé?

Répondre

1

astimezone() est correct. parse() est incorrect ou l'entrée est ambiguë. parse() interprète GMT+0530 comme étant le format obsolète POSIX-style GMT+h où le signe de décalage utc est inversé. Voir Timezone offset sign reversed by Python dateutil?

Pour résoudre ce problème, utilisez le signe opposé:

>>> from dateutil.parser import parse 
>>> d = parse('Tue Sep 01 2015 16:00:00 GMT+0530') 
>>> utc = d.replace(tzinfo=None) + d.utcoffset() #NOTE: the opposite sign 
>>> utc 
datetime.datetime(2015, 9, 1, 10, 30) 

Si l'entrée peut être univoque (lorsque parse() génère des résultats corrects), alors vous ne devriez pas changer le signe de décalage utc à la main. Vous pouvez dépouiller le fuseau horaire et l'appliquer de nouveau à nouveau à la place:

>>> import pytz 
>>> tz = pytz.timezone('Asia/Kolkata') 
>>> tz.localize(parse('Tue Sep 01 2015 16:00:00 GMT+0530').replace(tzinfo=None), is_dst=None) 
datetime.datetime(2015, 9, 1, 16, 0, tzinfo=<DstTzInfo 'Asia/Kolkata' IST+5:30:00 STD>) 
>>> _.astimezone(pytz.utc) 
datetime.datetime(2015, 9, 1, 10, 30, tzinfo=<UTC>) 

Il peut échouer pour parfois ambiguës ou inexistantes (pendant les transitions DST). Si vous savez que l'entrée est au format GMT+h, utilisez le 1er exemple de code et convertissez-le manuellement en UTC.

0

L'extrait suivant fonctionne correctement.

>>> d = parse('Tue Sep 01 2014 16:00:00 GMT+0530') 
>>> ind = timezone('Asia/Kolkata') 
>>> d=d.replace(tzinfo=ind) 
>>> d 
datetime.datetime(2015, 9, 1, 16, 0, tzinfo=<DstTzInfo 'Asia/Kolkata' LMT+5:53:00 STD>) 
>>> utc = timezone('UTC') 
>>> d.astimezone(utc) 
datetime.datetime(2015, 9, 1, 10, 7, tzinfo=<UTC>) 

Ici, j'ai changé le tzinfo à utiliser au format pytz. S'assurer que tous les fuseaux horaires sont au format pytz. Cependant, je ne suis pas sûr que IST soit LMT + 5: 53: 00. Découvert que les changements de décalage au fil des ans et +5: 53 a été utilisé depuis longtemps, mais maintenant nous utilisons +5: 30. Mais franchement, je n'ai pas beaucoup d'idée à ce sujet.

+1

En raison de la politique, les fuseaux horaires changeront littéralement de mois en mois. J'ai trouvé qu'il y avait une version 2015.4 de pytz qui, je l'espère, rend IST UTC + 5: 30. Je ne peux pas arriver à la source de ce netbook, désolé. – msw

+1

@msw C'est OK. Mais dans ce cas l'Inde aurait dû changer le temps dans son horloge. Moi, en Inde aurait dû mettre à jour ma montre, je ne l'ai pas fait car il n'y avait pas d'annonce officielle du gouvernement. Si le gouvernement n'a pas annoncé, pourquoi pytz a-t-il changé cela? –

+1

Pour autant que je sache, toute l'Inde est allé à IST à l'indépendance. Il existe un http://infostore.saiglobal.com/store/Details.aspx?ProductID=1055575 standard qui serait conforme à l'UTC, mais je n'ai pas 87 $ US pour trouver la réponse. Je regarderai la source de pytz plus tard et enverrai une demande de changement si approprié. Tu as piqué ma curiosité, merci. – msw