web-dev-qa-db-fra.com

Comment ajouter un fuseau horaire dans une instance datetime naïve dans python

J'ai un datetime qui n'a aucune information de fuseau horaire. Je reçois maintenant les informations de fuseau horaire et je voudrais ajouter le fuseau horaire dans l'instance datetime existante, comment faire?

d = datetime.datetime.now()
tz = pytz.timezone('Asia/Taipei')

Comment ajouter les informations de fuseau horaire tz dans datetime a

34
waitingkuo

Utilisez tz.localize(d) pour localiser l'instance. De la documentation :

La première consiste à utiliser la méthode localize () fournie par la bibliothèque pytz. Ceci est utilisé pour localiser un datetime naïf (datetime sans information de fuseau horaire):

>>> loc_dt = eastern.localize(datetime(2002, 10, 27, 6, 0, 0))
>>> print(loc_dt.strftime(fmt))
2002-10-27 06:00:00 EST-0500

Si vous n'utilisez pas tz.localize(), mais utilisez datetime.replace(), il y a de fortes chances qu'un le décalage historique est utilisé à la place; tz.localize() choisira le bon décalage en vigueur pour la date donnée. Par exemple, les dates de début et de fin de l'heure d'été dans le fuseau horaire américain ont changé au fil du temps.

Lorsque vous essayez de localiser une valeur datetime ambiguë car elle chevauche la période de transition de l'heure d'été à l'heure d'hiver ou vice-versa, le fuseau horaire sera consulté pour voir si l'objet datetime résultant doit avoir .dst() return True ou fausses. Vous pouvez remplacer la valeur par défaut du fuseau horaire avec l'argument de mot clé is_dst Pour .localize():

dt = tz.localize(naive, is_dst=True)

ou même désactiver complètement le choix en définissant is_dst=None. Dans ce cas, ou dans les rares cas où il n'y a aucun ensemble par défaut pour un fuseau horaire, une valeur datetime ambiguë conduirait à un AmbiguousTimeError exception soulevée. L'indicateur is_dst N'est consulté que pour les valeurs datetime ambiguës et est ignoré sinon.

Pour revenir en arrière, retournez un objet sensible au fuseau horaire à un objet naïf, utilisez .replace(tzinfo=None):

naivedt = awaredt.replace(tzinfo=None)
59
Martijn Pieters

Si vous savez que votre datetime d'origine a été "mesurée" dans le fuseau horaire que vous essayez d'y ajouter, vous pouvez (mais ne devriez probablement pas) utiliser replace plutôt que localize.

# d = datetime.datetime.now()
# tz = pytz.timezone('Asia/Taipei')
d = d.replace(tzinfo=tz)

Je peux imaginer 2 fois où cela pourrait avoir du sens (la seconde m'est arrivée):

  1. Les paramètres régionaux de votre serveur sont définis sur le fuseau horaire incorrect et vous essayez de corriger une instance de datetime en lui faisant prendre conscience de ce fuseau horaire incorrect (et probablement en le localisant plus tard dans le fuseau horaire "correct" pour que les valeurs de now () correspondre à d'autres moments auxquels vous le comparez (votre montre, peut-être)
  2. Vous voulez "marquer" une instance de time ( PAS a datetime) avec un attribut de fuseau horaire (tzinfo) afin cet attribut peut être utilisé ultérieurement pour former une instance complète de datetime.
6
hobs