Ce que je dois faire
J'ai un objet datetime non compatible avec le fuseau horaire, auquel je dois ajouter un fuseau horaire afin de pouvoir le comparer avec d'autres objets datetime sensibles au fuseau horaire. Je ne veux pas convertir l'intégralité de mon application en fuseau horaire sans être au courant de ce cas hérité.
Ce que j'ai essayé
Tout d'abord, pour illustrer le problème:
Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import datetime
>>> import pytz
>>> unaware = datetime.datetime(2011,8,15,8,15,12,0)
>>> unaware
datetime.datetime(2011, 8, 15, 8, 15, 12)
>>> aware = datetime.datetime(2011,8,15,8,15,12,0,pytz.UTC)
>>> aware
datetime.datetime(2011, 8, 15, 8, 15, 12, tzinfo=<UTC>)
>>> aware == unaware
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't compare offset-naive and offset-aware datetimes
J'ai d'abord essayé l'astimezone:
>>> unaware.astimezone(pytz.UTC)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: astimezone() cannot be applied to a naive datetime
>>>
Il n'est pas très surprenant que cela ait échoué, car il essaie en fait de faire une conversion. Remplacer semblait être un meilleur choix (selon Python: comment obtenir une valeur de datetime.today () qui est "sensible au fuseau horaire"? ):
>>> unaware.replace(tzinfo=pytz.UTC)
datetime.datetime(2011, 8, 15, 8, 15, 12, tzinfo=<UTC>)
>>> unaware == aware
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't compare offset-naive and offset-aware datetimes
>>>
Mais comme vous pouvez le voir, replace semble définir le tzinfo, mais pas rendre l'objet conscient. Je me prépare à retravailler la chaîne d'entrée pour avoir un fuseau horaire avant de l'analyser (j'utilise dateutil pour l'analyse, si cela importe), mais cela semble incroyablement délicat.
De plus, j'ai essayé cela à la fois en python 2.6 et en python 2.7, avec les mêmes résultats.
Le contexte
J'écris un analyseur pour certains fichiers de données. Il y a un ancien format que je dois prendre en charge où la chaîne de date n'a pas d'indicateur de fuseau horaire. J'ai déjà corrigé la source de données, mais je dois toujours prendre en charge le format de données hérité. Une conversion unique des données héritées n'est pas une option pour diverses raisons commerciales BS. Bien qu'en général, je n'aime pas l'idée de coder en dur un fuseau horaire par défaut, dans ce cas, cela semble être la meilleure option. Je sais avec une confiance raisonnable que toutes les anciennes données en question sont en UTC, donc je suis prêt à accepter le risque de ne pas y parvenir dans ce cas.
import datetime; datetime.datetime.now(datetime.timezone.utc)
tz
argument nommé pour être plus lisible:datetime.datetime.now(tz=datetime.timezone.utc)
unaware.replace()
retourneraitNone
s'il modifiait l'unaware
objet en place. Le REPL montre que.replace()
renvoie un nouveldatetime
objet ici.