Voir le code suivant:
import datetime
import pytz
fmt = '%Y-%m-%d %H:%M:%S %Z'
d = datetime.datetime.now(pytz.timezone("America/New_York"))
d_string = d.strftime(fmt)
d2 = datetime.datetime.strptime(d_string, fmt)
print d_string
print d2.strftime(fmt)
la sortie est
2013-02-07 17:42:31 EST
2013-02-07 17:42:31
Les informations de fuseau horaire se sont tout simplement perdues dans la traduction.
Si je bascule '% Z' en '% z', je reçois
ValueError: 'z' is a bad directive in format '%Y-%m-%d %H:%M:%S %z'
Je sais que je peux utiliser python-dateutil
, mais je viens juste de constater que c’est grave que je ne puisse pas obtenir cette fonctionnalité simple dans datetime et que je devrais introduire plus de dépendance?
Une partie du problème ici est que les chaînes habituellement utilisées pour représenter les fuseaux horaires ne sont pas uniques. "EST" signifie uniquement "Amérique/New_York" pour les Nord-Américains. C’est une limitation de l’API d’heure C et la solution Python permet… d’ajouter des fonctionnalités tz complètes dans une version future à tout moment maintenant, si quelqu'un souhaite écrire le PEP.
Vous pouvez formater et analyser un fuseau horaire comme décalage, mais cela perd les informations de l'heure d'été/heure d'été (par exemple, vous ne pouvez pas distinguer "America/Phoenix" de "America/Los_Angeles" en été) . Vous pouvez formater un fuseau horaire sous forme d'abréviation de 3 lettres, mais vous ne pouvez pas le réanalyser à partir de cela.
Si vous voulez quelque chose de flou et d’ambiguïté mais que vous voulez en général, vous avez besoin d’une bibliothèque tierce comme dateutil
.
Si vous voulez quelque chose qui soit sans ambiguïté, ajoutez simplement vous-même le nom de tz à la chaîne de date/heure locale et séparez-le à l'autre bout:
d = datetime.datetime.now(pytz.timezone("America/New_York"))
dtz_string = d.strftime(fmt) + ' ' + "America/New_York"
d_string, tz_string = dtz_string.rsplit(' ', 1)
d2 = datetime.datetime.strptime(d_string, fmt)
tz2 = pytz.timezone(tz_string)
print dtz_string
print d2.strftime(fmt) + ' ' + tz_string
Ou… à mi-chemin, vous utilisez déjà la bibliothèque pytz
, qui peut analyser (selon certaines règles de désambiguïsation arbitraires mais bien définies) des formats tels que "EST". Donc, si vous voulez vraiment, vous pouvez laisser le %Z
Du côté de la mise en forme, puis le retirer et l’analyser avec pytz.timezone()
avant de passer le reste à strptime
.
Malheureusement, strptime()
ne peut gérer que le fuseau horaire configuré par votre système d'exploitation, puis uniquement comme un décalage temporel. De la documentation :
La prise en charge de la directive
%Z
Est basée sur les valeurs contenues danstzname
et sur le fait quedaylight
soit vrai. Pour cette raison, il est spécifique à la plate-forme, à l'exception de la reconnaissance des heures UTC et GMT qui sont toujours connues (et considérées comme des fuseaux horaires ne respectant pas l'heure d'été).
strftime()
ne supporte pas officiellement %z
.
J'ai bien peur que vous soyez bloqué avec python-dateutil
Afin de prendre en charge l'analyse du fuseau horaire.
Voici ma réponse dans Python 2.7
from datetime import datetime
import tzlocal # pip install tzlocal
print datetime.now(tzlocal.get_localzone()).strftime("%Y-%m-%d %H:%M:%S %z")
from datetime import datetime
import pytz # pip install pytz
print datetime.now(pytz.timezone('Asia/Taipei')).strftime("%Y-%m-%d %H:%M:%S %z")
Il va imprimer quelque chose comme
2017-08-10 20:46:24 +0800