datetime.datetime.utcnow()
Pourquoi cette datetime
n'a-t-elle aucune information de fuseau horaire étant donné qu'il s'agit explicitement d'une UV datetime
?
Je pense que cela contiendrait tzinfo
.
Cela signifie que le fuseau horaire est naïf, vous ne pouvez donc pas l'utiliser avec datetime.astimezone
vous pouvez lui donner un fuseau horaire comme celui-ci
import pytz # 3rd party: $ pip install pytz
u = datetime.utcnow()
u = u.replace(tzinfo=pytz.utc) #NOTE: it works only with a fixed utc offset
maintenant vous pouvez changer les fuseaux horaires
print(u.astimezone(pytz.timezone("America/New_York")))
Pour obtenir l'heure actuelle dans un fuseau horaire donné, vous pouvez passer tzinfo à datetime.now()
directement:
#!/usr/bin/env python
from datetime import datetime
import pytz # $ pip install pytz
print(datetime.now(pytz.timezone("America/New_York")))
Cela fonctionne pour tous les fuseaux horaires, y compris ceux qui respectent l'heure d'été, c'est-à-dire qu'ils fonctionnent avec des fuseaux horaires pouvant avoir différents décalages UTC à différents moments (décalage UTC non fixe). N'utilisez pas tz.localize(datetime.now())
- il peut échouer pendant la transition de fin DST lorsque l'heure locale est ambiguë.
Notez que depuis Python 3.2, le module datetime
contient datetime.timezone
. La documentation de datetime.utcnow()
dit:
Vous pouvez obtenir une date/heure UTC actuelle au courant en appelant
datetime.now
(
timezone.utc
)
.
Alors tu peux faire:
>>> import datetime
>>> datetime.datetime.now(datetime.timezone.utc)
datetime.datetime(2014, 7, 10, 2, 43, 55, 230107, tzinfo=datetime.timezone.utc)
Les bibliothèques Python standard n'incluent aucune classe tzinfo (mais voir pep 431 ). Je ne peux que deviner les raisons. Personnellement, j’ai pensé que c’était une erreur de ne pas inclure de classe tzinfo pour UTC, parce que celle-ci est suffisamment controversée pour avoir une implémentation standard.
Edit: Bien qu'il n'y ait pas d'implémentation dans la bibliothèque, il y en a une donnée à titre d'exemple dans la documentation tzinfo
.
from datetime import timedelta, tzinfo
ZERO = timedelta(0)
# A UTC class.
class UTC(tzinfo):
"""UTC"""
def utcoffset(self, dt):
return ZERO
def tzname(self, dt):
return "UTC"
def dst(self, dt):
return ZERO
utc = UTC()
Pour l'utiliser, pour obtenir l'heure actuelle en tant qu'objet date-heure conscient:
from datetime import datetime
now = datetime.now(utc)
Il y a datetime.timezone.utc
dans Python 3.2+:
from datetime import datetime, timezone
now = datetime.now(timezone.utc)
Le module pytz
est une option. Il existe un autre python-dateutil
, qui est également un package tiers, mais il est peut-être déjà disponible en fonction de vos autres dépendances et de votre système d'exploitation.
Je voulais juste inclure cette méthodologie à titre de référence. Si vous avez déjà installé python-dateutil
à d'autres fins, vous pouvez utiliser sa tzinfo
au lieu de la dupliquer avec pytz
import datetime
import dateutil.tz
# Get the UTC time with datetime.now:
utcdt = datetime.datetime.now(dateutil.tz.tzutc())
# Get the UTC time with datetime.utcnow:
utcdt = datetime.datetime.utcnow()
utcdt = utcdt.replace(tzinfo=dateutil.tz.tzutc())
# For fun- get the local time
localdt = datetime.datetime.now(dateutil.tz.tzlocal())
J'ai tendance à être d'accord pour dire que les appels à utcnow
devraient inclure les informations de fuseau horaire UTC. Je soupçonne que cela n’est pas inclus car la bibliothèque de date/heure native utilise par défaut des dates/heures naïves pour assurer la compatibilité croisée.
Julien Danjou a écrit un bon article expliquant pourquoi vous ne devriez jamais traiter avec les fuseaux horaires . Un extrait:
En effet, l'API Python datetime renvoie toujours des objets datetime non conscients, ce qui est très regrettable. En effet, dès que vous en aurez un objet, il n’ya aucun moyen de savoir quel est le fuseau horaire, donc ceux-ci les objets sont plutôt "inutiles" par eux-mêmes.
Hélas, même si vous pouvez utiliser utcnow()
, vous ne verrez toujours pas les informations de fuseau horaire, comme vous l'avez découvert.
Recommandations:
Utilisez toujours des objets
datetime
, c’est-à-dire avec des informations de fuseau horaire. Cette s'assure que vous pouvez les comparer directement (les objetsdatetime
conscients et non conscients ne sont pas comparables) et les renverra correctement aux utilisateurs . Utilisez pytz pour créer des objets de fuseau horaire.Utilisez ISO 8601 comme entrée et format de chaîne de sortie. Utilisez
datetime.datetime.isoformat()
pour retourner timestamps sous forme de chaîne formatée à l'aide de ce format, qui inclut le informations de fuseau horaire.Si vous devez analyser des chaînes contenant des horodatages au format ISO 8601, vous pouvez compter sur
iso8601
, qui renvoie les horodatages avec le correct informations de fuseau horaire. Cela rend les horodatages directement comparables.
Pour ajouter des informations timezone
dans Python 3.2+
import datetime
>>> d = datetime.datetime.now(tz=datetime.timezone.utc)
>>> print(d.tzinfo)
'UTC+00:00'