Plus précisément, compte tenu du fuseau horaire de mon serveur (perspective de l'heure système) et d'une entrée de fuseau horaire, comment puis-je calculer l'heure système comme si elle se trouvait dans ce nouveau fuseau horaire (indépendamment de l'heure d'été, etc.)?
import datetime
current_time = datetime.datetime.now() #system time
server_timezone = "US/Eastern"
new_timezone = "US/Pacific"
current_time_in_new_timezone = ???
Si vous connaissez votre fuseau horaire d'origine et le nouveau fuseau horaire dans lequel vous souhaitez le convertir, utilisez d'abord pytz.localize
Pour gérer toute localisation (par exemple pour l'heure d'été, etc.), puis utilisez pytz.timezone
Pour créer des objets de fuseau horaire , et enfin utilisez datetime.astimezone(timezone)
pour un calcul facile. Par exemple:
import datetime
import pytz # new import
my_timestamp = datetime.datetime.now() # some timestamp
old_timezone = pytz.timezone("US/Eastern")
new_timezone = pytz.timezone("US/Pacific")
# returns datetime in the new timezone
my_timestamp_in_new_timezone = old_timezone.localize(my_timestamp).astimezone(new_timezone)
Et bien sûr, si tout ce que vous voulez, c'est l'heure actuelle dans un fuseau horaire spécifique, vous pouvez passer ce fuseau horaire directement dans datetime.now () pour obtenir l'horodatage. Comme ça:
datetime.datetime.now(new_timezone)
Maintenant, avec tout cela, je recommande fortement de stocker tous vos horodatages en UTC en tant que norme système, et d'éviter tout le problème DST. Pour le contexte à ce sujet, voir: http://lucumr.pocoo.org/2011/7/15/eppur-si-muove/
Et pour savoir à quel point il est difficile de gérer les calculs de temps en général: http://yourcalendricalfallacyis.com
Comment convertissez-vous datetime/timestamp d'un fuseau horaire à un autre fuseau horaire?
Il y a deux étapes:
Créez un objet datetime conscient à partir de l'heure système et du fuseau horaire par exemple, pour obtenir l'heure système actuelle dans le fuseau horaire donné:
#!/usr/bin/env python
from datetime import datetime
import pytz
server_timezone = pytz.timezone("US/Eastern")
server_time = datetime.now(server_timezone) # you could pass *tz* directly
Remarque: datetime.now(server_timezone)
fonctionne même pendant les périodes ambiguës par exemple, pendant les transitions DST tandis que server_timezone.localize(datetime.now())
peut échouer (50% de chances).
Si vous êtes sûr que votre heure d'entrée existe dans le fuseau horaire du serveur et qu'elle est unique, vous pouvez passer is_dst=None
Pour affirmer que:
server_time = server_timezone.localize(naive_time, is_dst=None)
Il déclenche une exception pour les heures non valides.
S'il est acceptable d'ignorer jusqu'à une erreur de jour (bien que généralement une erreur due à l'heure d'été soit d'environ une heure ), vous pouvez alors supprimer le paramètre is_dst
:
server_time = server_timezone.normalize(server_timezone.localize(naive_time))
.normalize()
est appelée pour ajuster les temps non existants (heure locale dans l'intervalle, lors des transitions "spring forward"). Si les règles de fuseau horaire n'ont pas changé; votre serveur ne doit pas générer d'heures inexistantes. Voir "Puis-je toujours définir is_dst = True?"
Convertissez un objet datetime conscient en fuseau horaire cible tz
:
tz = pytz.timezone("US/Pacific")
server_time_in_new_timezone = server_time.astimezone(tz)