Python的date时间strptime()和strftime():如何保存时区信息

看下面的代码:

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) 

输出是

 2013-02-07 17:42:31 EST 2013-02-07 17:42:31 

时区信息只是在翻译中丢失了。

如果我将“%Z”切换到“%z”,我会得到

 ValueError: 'z' is a bad directive in format '%Y-%m-%d %H:%M:%S %z' 

我知道我可以使用python-dateutil ,但我只是觉得它bizzare,我不能在datetime实现这个简单的function,必须引入更多的依赖?

这里问题的一部分是通常用于表示时区的string实际上并不是唯一的。 “EST”仅代表“America / New_York”给北美人。 这是C时间API的一个限制,Python解决scheme是…现在任何时候在某个未来版本中添加完整的tzfunction,如果有人愿意写PEP的话。

可以格式化并parsing时区作为偏移量,但是会丢失夏令时/夏令时信息(例如,夏季您无法将“America / Phoenix”与“America / Los_Angeles”区分开来)。 您可以将时区格式化为3个字母的缩写,但不能从中parsing出来。

如果你想要的东西模糊不清,但通常你想要的东西,你需要像dateutil这样的第三方库。

如果你想要的东西实际上是明确的,只需将实际的tz名称附加到本地的date时间string中,然后在另一端将其拆分:

 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 

或者…在这两者之间的一半,你已经使用了pytz库,它可以parsing(根据一些任意但明确的消除歧义规则)格式,如“EST”。 所以,如果你真的想要的话,你可以把%Z放在格式化的一面,然后把它closures,然后用pytz.timezone()parsing它,然后把其余的部分传给strptime

不幸的是, strptime()只能处理你的操作系统configuration的时区,而且只能作为一个时间偏移量。 从文档 :

%Z指令的支持是基于tzname包含的值以及daylight是否为true。 因此,除了识别总是已知的UTC和GMT(被认为是非夏时制时区)以外,它是特定于平台的。

strftime()不正式支持%z

你害怕python-dateutil支持时区parsing,恐怕。

这是我在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") 

它会打印类似的东西

 2017-08-10 20:46:24 +0800