datetime.datetime.utcnow()
Pourquoi cela n'a-t-il datetime
pas d'informations de fuseau horaire étant donné qu'il s'agit explicitement d'un UTC datetime
?
Je m'attendrais à ce que cela contienne tzinfo
.
datetime.datetime.utcnow()
Pourquoi cela n'a-t-il datetime
pas d'informations de fuseau horaire étant donné qu'il s'agit explicitement d'un UTC datetime
?
Je m'attendrais à ce que cela contienne tzinfo
.
Réponses:
Cela signifie qu'il est naïf de fuseau horaire, 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 datetime.now()
directement à tzinfo :
#!/usr/bin/env python
from datetime import datetime
import pytz # $ pip install pytz
print(datetime.now(pytz.timezone("America/New_York")))
Il fonctionne pour n'importe quel fuseau horaire, y compris ceux qui observent l'heure d'été (DST), c'est-à-dire qu'il fonctionne pour les fuseaux horaires qui peuvent avoir différents décalages utc à différents moments (décalage utc non fixe). Ne pas utiliser tz.localize(datetime.now())
- il peut échouer pendant la transition de fin de l'heure d'été lorsque l'heure locale est ambiguë.
astimezone
. Ainsi, datetime n'a pas seulement de fuseaux horaires natifs, mais la seule implémentation largement disponible de tzinfo n'est pas conforme à la norme supposée.
u=datetime.now(pytz.utc)
tz.localize(datetime.now())
; utiliser à la datetime.now(tz)
place.
Notez que pour Python 3.2 et ultérieur, le datetime
module contient datetime.timezone
. La documentation de datetime.utcnow()
dit:
Un datetime UTC courant peut être obtenu en appelant .
datetime.now
(
timezone.utc
)
Vous pouvez donc faire:
>>> import datetime
>>> datetime.datetime.now(datetime.timezone.utc)
datetime.datetime(2014, 7, 10, 2, 43, 55, 230107, tzinfo=datetime.timezone.utc)
datetime.now(timezone.utc)
ou datetime.utcnow(timezone.utc)
?
datetime.utcnow()
ne prend aucun argument. Il faudrait donc que ce soit le cas datetime.now(timezone.utc)
.
datetime.now()
renverra l'heure de la machine mais datetime.utcnow()
renverra l'heure UTC réelle.
datetime.utcnow()
ne signifie pas tzinfo
qu'il s'agit de l'UTC. Mais datetime.now(datetime.timezone.utc)
retourne l'heure UTC avec tzinfo
set.
tz
objet dans le constructeur now, il retournera l'heure de ce fuseau horaire? D'accord! Merci d'avoir souligné.
Les bibliothèques Python standard n'incluent aucune classe tzinfo (mais voir pep 431 ). Je ne peux que deviner les raisons. Personnellement, je pense que c'était une erreur de ne pas inclure une classe tzinfo pour UTC, car 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 comme exemple dans la tzinfo
documentation .
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 datetime conscient:
from datetime import datetime
now = datetime.now(utc)
Il existe datetime.timezone.utc
en Python 3.2+:
from datetime import datetime, timezone
now = datetime.now(timezone.utc)
datetime
objets créés par utcnow()
) ...
timezone.utc
a finalement été ajouté à Python 3.2. Pour des raisons de compatibilité descendante, utcnow()
renvoie toujours un objet temporel sans fuseau horaire, mais vous pouvez obtenir ce que vous voulez en appelant now(timezone.utc)
.
struct
module ferait des conversions automatiques d'Unicode en bytestring, et la décision finale a été de rompre la compatibilité avec les versions antérieures de Python 3 pour empêcher une mauvaise décision d'aller de l'avant.
tzinfo
documentation de Python inclut des exemples de code pour l'implémenter, mais ils n'incluent pas cette fonctionnalité dans datetime lui-même! docs.python.org/2/library/datetime.html#datetime.tzinfo.fromutc
pytz
est une excellente ressource. Au moment où j'avais édité ma réponse pour mettre l'exemple de code, quelqu'un d'autre l'avait déjà suggéré et je ne voulais pas voler leur tonnerre.
Le pytz
module est une option, et il y en a une autre python-dateutil
qui, bien qu'il s'agisse également d'un package tiers, peut déjà être disponible en fonction de vos autres dépendances et de votre système d'exploitation.
Je voulais juste inclure cette méthodologie pour référence - si vous l'avez déjà installée python-dateutil
à d'autres fins, vous pouvez l'utiliser tzinfo
au lieu de la dupliquer avecpytz
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 à convenir que les appels à utcnow
doivent inclure les informations de fuseau horaire UTC. Je soupçonne que cela n'est pas inclus car la bibliothèque native datetime utilise par défaut des datetimes naïfs pour la compatibilité croisée.
utcdt = datetime.datetime.utcfromtimestamp(1234567890).replace(dateutil.tz.tzutc())
datetime.now(pytz_tz)
cela fonctionne toujours; datetime.now(dateutil.tz.tzlocal())
peut échouer pendant les transitions DST . PEP 495 - La désambiguïsation de l'heure locale pourrait améliorer la dateutil
situation à l'avenir.
utc_dt = datetime.fromtimestamp(1234567890, dateutil.tz.tzutc())
(remarque: dateutil
avec un décalage utc non fixe (tel que dateutil.tz.tzlocal()
) peut échouer ici , utilisez plutôt une pytz
solution basée sur ).
dateutil
pour dateutil.parser
, j'ai préféré cette solution. Il était aussi simple que: utcCurrentTime = datetime.datetime.now(tz=dateutil.tz.tzutc())
. Alto!!
Julien Danjou a écrit un bon article expliquant pourquoi vous ne devriez jamais traiter les fuseaux horaires . Un extrait:
En effet, l'API datetime Python renvoie toujours des objets datetime ignorants, ce qui est très regrettable. En effet, dès que vous obtenez un de ces objets, il n'y a aucun moyen de savoir quel est le fuseau horaire, donc ces objets sont assez "inutiles" à eux seuls.
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
datetime
objets conscients , c'est-à-dire avec des informations de fuseau horaire. Cela garantit que vous pouvez les comparer directement (lesdatetime
objets avertis et ignorants ne sont pas comparables) et les rendra correctement aux utilisateurs. Effet de levier pytz d'avoir des objets de fuseau horaire.Utilisez ISO 8601 comme format de chaîne d'entrée et de sortie. Permet
datetime.datetime.isoformat()
de renvoyer des horodatages sous forme de chaîne formatée à l'aide de ce format, qui inclut les informations de fuseau horaire.Si vous devez analyser des chaînes contenant des horodatages au format ISO 8601, vous pouvez vous en remettre à
iso8601
, qui renvoie des horodatages avec des informations de fuseau horaire correctes. Cela rend les horodatages directement comparables.
Pour ajouter des timezone
informations dans Python 3.2+
import datetime
>>> d = datetime.datetime.now(tz=datetime.timezone.utc)
>>> print(d.tzinfo)
'UTC+00:00'
AttributeError: 'module' object has no attribute 'timezone'
Python 2.7.13 (par défaut, 19 janvier 2017, 14:48:08)
from datetime import datetime
from dateutil.relativedelta import relativedelta
d = datetime.now()
date = datetime.isoformat(d).split('.')[0]
d_month = datetime.today() + relativedelta(months=1)
next_month = datetime.isoformat(d_month).split('.')[0]
Les dates UTC n'ont pas besoin d'informations de fuseau horaire car elles sont UTC, ce qui signifie par définition qu'elles n'ont pas de décalage.
pytz.utc
). Notez qu'il y a une grande différence entre une valeur dont le décalage par rapport à l'UTC est inconnue et une où elle est connue pour être 0. Ce dernier est ce qui utcnow()
devrait retourner, IMO. Cela cadrerait avec "Un objet conscient est utilisé pour représenter un moment précis qui n'est pas ouvert à l'interprétation" selon la documentation.