pytz localiser vs datetime remplacer

j'ai des problèmes bizarres avec pytz's.localiser() fonction. Parfois, il ne fait pas de réglages à la datetime localisée:

.localiser comportement:

>>> tz
<DstTzInfo 'Africa/Abidjan' LMT-1 day, 23:44:00 STD> 
>>> d
datetime.datetime(2009, 9, 2, 14, 45, 42, 91421)

>>> tz.localize(d)
datetime.datetime(2009, 9, 2, 14, 45, 42, 91421, 
                  tzinfo=<DstTzInfo 'Africa/Abidjan' GMT0:00:00 STD>)
>>> tz.normalize(tz.localize(d))
datetime.datetime(2009, 9, 2, 14, 45, 42, 91421,
                  tzinfo=<DstTzInfo 'Africa/Abidjan' GMT0:00:00 STD>)

comme vous pouvez le voir, le temps n'a pas été modifié à la suite des opérations de localisation/normalisation. Toutefois, si .remplacer est utilisé:

>>> d.replace(tzinfo=tz)
datetime.datetime(2009, 9, 2, 14, 45, 42, 91421, 
                  tzinfo=<DstTzInfo 'Africa/Abidjan' LMT-1 day, 23:44:00 STD>)
>>> tz.normalize(d.replace(tzinfo=tz))
datetime.datetime(2009, 9, 2, 15, 1, 42, 91421,
                  tzinfo=<DstTzInfo 'Africa/Abidjan' GMT0:00:00 STD>)

qui semble faire des ajustements dans datetime.

Question Est - ce qui est correct et pourquoi les autres ont tort?

37
demandé sur A-B-B 2009-09-04 18:50:11

4 réponses

localize suppose simplement que la date-time naïve que vous passez est "correcte" (sauf pour ne pas connaître le fuseau horaire!) et si juste définit le fuseau horaire, pas d'autres ajustements.

Vous pouvez (et c'est conseillé...) fonctionne en interne dans UTC (plutôt qu'avec des datetimes naïves) et utilise replace quand vous devez effectuer les entrées / sorties des datetimes de façon localisée (normalize manipuleront DST et similaires).

30
répondu Alex Martelli 2009-09-04 15:12:52

je me rends compte que je suis un peu en retard sur ce... mais voici ce que j'ai trouvé de bien travailler. Travailler en TUC comme Alex l'a déclaré:

tz = pytz.timezone('Africa/Abidjan')
now = datetime.datetime.utcnow()

puis localiser:

tzoffset = tz.utcoffset(now)
mynow = now+tzoffset

et cette méthode gère parfaitement DST

6
répondu derks 2014-05-06 08:00:49

cette classe DstTzInfo est utilisée pour les fuseaux horaires dont le décalage par rapport à UTC change à certains moments. Par exemple (comme vous le savez probablement), de nombreux endroits passent à "l'heure avancée" au début de l'été, puis reviennent à "l'heure normale" à la fin de l'été. Chaque instance de DstTzInfo ne représente qu'une de ces périodes, mais les méthodes "localize" et "normalize" vous aident à obtenir la bonne instance.

>>> tz = pytz.timezone('Africa/Abidjan')
>>> tz._utc_transition_times
[datetime.datetime(1, 1, 1, 0, 0), datetime.datetime(1912, 1, 1, 0, 16, 8)]

l'objet tz que nous sortons de pytz représente le fuseau horaire d'avant 1912:

>>> tz
<DstTzInfo 'Africa/Abidjan' LMT-1 day, 23:44:00 STD>

Maintenant, en regardant vos deux exemples, voir que lorsque vous appelez tz.localiser(d) vous ne obtenez ce fuseau horaire pré-1912 ajouté à votre naïf objet datetime. Il suppose que l'objet datetime vous donner il représente heure locale dans le fuseau horaire correct pour cette heure locale, qui est l'après-1912 fuseau.

cependant dans votre deuxième exemple en utilisant D. remplacer (tzinfo=tz), il faut votre objet datetime pour représenter l'heure dans le fuseau horaire d'avant 1912. Ce n'est probablement pas ce que tu voulais dire. Puis quand vous appelez dt.normalisez-le convertit en le fuseau horaire qui est correct pour cette valeur datetime, c'est-à-dire le fuseau horaire post-1912.

4
répondu lplatypus 2009-10-20 06:40:10

localize est la fonction correcte à utiliser pour créer des objets conscients datetime avec une valeur initiale fixe datetime. L'objet datetime aware résultant aura la valeur originale datetime. Un schéma d'usage très courant à mon avis, et que pytz pourrait mieux documenter.

replace(tzinfo = ...) est malheureusement nommé. C'est une fonction qui est aléatoire dans son comportement. Je vous conseille d'éviter d'utiliser cette fonction pour régler les temps sauf si vous aimez la douleur auto-infligée. J'ai déjà assez souffert de l'utilisation de cette fonction.

4
répondu paolov 2017-03-30 21:01:05