datetime.datetime.utcnow()
Pourquoi est-ce que datetime
n'a pas d'information sur le fuseau horaire, étant donné qu'il s'agit explicitement d'un système UTC. datetime
?
Je m'attendrais à ce qu'il contienne tzinfo
.
datetime.datetime.utcnow()
Pourquoi est-ce que datetime
n'a pas d'information sur le fuseau horaire, étant donné qu'il s'agit explicitement d'un système UTC. datetime
?
Je m'attendrais à ce qu'il contienne tzinfo
.
Notez qu'à partir de Python 3.2, la fonction datetime
Le module contient datetime.timezone
. La documentation pour datetime.utcnow()
dit :
Une date UTC actuelle connue peut être obtenue en appelant
datetime.now
(
timezone.utc
)
.
Donc, datetime.utcnow()
ne fixe pas tzinfo
pour indiquer qu'il s'agit d'une UTC, mais datetime.now(datetime.timezone.utc)
renvoie l'heure UTC avec tzinfo
set.
Donc vous pouvez le faire :
>>> import datetime
>>> datetime.datetime.now(datetime.timezone.utc)
datetime.datetime(2014, 7, 10, 2, 43, 55, 230107, tzinfo=datetime.timezone.utc)
datetime.utcnow()
ne prend aucun argument. Il faudrait donc que ce soit datetime.now(timezone.utc)
.
datetime.now()
retournera l'heure de la machine mais datetime.utcnow()
retournera l'heure UTC actuelle.
Cela signifie qu'il ne tient pas compte du fuseau horaire, et que vous ne pouvez pas l'utiliser avec datetime.astimezone
vous pouvez lui donner un fuseau horaire comme ceci
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
vous pouvez maintenant changer de fuseau horaire
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")))
Il fonctionne pour tous les fuseaux horaires, y compris ceux qui observent l'heure d'été (DST), c'est-à-dire qu'il fonctionne pour les fuseaux horaires qui peuvent avoir des décalages utc différents à des moments différents (décalage utc non fixe). N'utilisez pas tz.localize(datetime.now())
-- il peut échouer pendant la transition vers la fin de l'heure d'été lorsque l'heure locale est ambiguë.
Mais il n'y a aucune raison pour que ce soit un fuseau horaire naïf - il est spécifié que c'est UTC. Pourquoi faut-il chercher une bibliothèque tierce pour que cela fonctionne correctement ?
Je pense que c'est peut-être une question de licence, donc pytz ne peut pas être inclus dans la stdlib.
Je suis d'accord ; pour moi, les temps "naïfs" sont complètement inutiles. Il y a une discussion sur la liste python en ce moment à propos de l'ajout de pytz à la stdlib ; le problème n'est pas la licence mais le fait que les données de fuseau horaire sont mises à jour si souvent (ce que Python lui-même ne peut pas faire). De plus, pytz n'implémente pas l'interface tzinfo de la manière attendue et vous pouvez obtenir des erreurs si vous essayez d'utiliser certains des fuseaux horaires des villes dans astimezone
. Ainsi, non seulement datetime n'a pas de fuseaux horaires natifs, mais la seule implémentation largement disponible de tzinfo n'est pas conforme à la norme supposée.
Les bibliothèques Python standard n'ont pas inclus de classes tzinfo avant Python 3.2. 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 assez peu controversée pour avoir une implémentation standard. Bien qu'il n'y ait pas d'implémentation dans la bibliothèque, il y en a une qui est donnée en exemple dans le fichier 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()
Une fois que vous avez un UTC tzinfo
vous ne pouvez toujours pas l'utiliser avec l'objet utcnow
. Pour obtenir l'heure actuelle sous la forme d'un objet datetime conscient :
from datetime import datetime
now = datetime.now(utc)
Dans Python 3.2, ils ont finalement mis en place une UTC tzinfo
dans la bibliothèque :
from datetime import datetime, timezone
now = datetime.now(timezone.utc)
Dans Python 3.9, ils ont créé tzinfo
des classes pour tous les autres fuseaux horaires. Voir PEP 615 -- Support de la base de données des fuseaux horaires de l'IANA dans la bibliothèque standard pour tous les détails.
Allez comprendre pourquoi cette classe n'a pas été fournie en premier lieu (et, plus important encore, pourquoi elle a servi à datetime
les objets créés par utcnow()
)...
L'objet fuseau horaire timezone.utc
a finalement été ajouté à Python 3.2. Pour la rétrocompatibilité, utcnow()
renvoie toujours un objet temps sans fuseau horaire, mais vous pouvez obtenir ce que vous voulez en appelant now(timezone.utc)
.
@rgove, c'est le genre de redressement des torts qui était censé être juste pour Python 3. Ils n'auraient pas dû s'inquiéter de la rétrocompatibilité. Il y a un autre exemple que j'ai lu au cours des derniers jours - l' struct
effectuerait des conversions automatiques d'Unicode à bytestring, et la décision finale a été de rompre la compatibilité avec les versions antérieures de Python 3 pour éviter qu'une mauvaise décision ne soit prise.
Le site pytz
Le module est une option, et il y en a une autre python-dateutil
qui, bien qu'il s'agisse également d'un paquet 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 avez déjà installé python-dateutil
à d'autres fins, vous pouvez utiliser son tzinfo
au lieu de 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())
Je suis plutôt d'accord pour dire que les appels à utcnow
devrait inclure les informations sur le fuseau horaire UTC. Je soupçonne que ces informations ne sont pas incluses parce que la bibliothèque native datetime utilise par défaut des dates naïves pour des raisons de compatibilité croisée.
J'utilisais l'appel datetime.datetime.utcfromtimestamp(), et j'avais besoin d'ajouter tzinfo, La deuxième solution a fonctionné pour moi : utcdt = datetime.datetime.utcfromtimestamp(1234567890).replace(dateutil.tz.tzutc())
Note : contrairement à datetime.now(pytz_tz)
qui fonctionne toujours ; datetime.now(dateutil.tz.tzlocal())
peut échouer pendant les transitions DST . PEP 495 -- Désambiguïsation de l'heure locale pourrait améliorer dateutil
à l'avenir.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
0 votes
Comment convertir un champ date au format iso normal qui est de type string en format utc ?