Python datetime strptime() 和 strftime():如何保存时区信息

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14762518/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 12:21:23  来源:igfitidea点击:

Python datetime strptime() and strftime(): how to preserve the timezone information

pythondatetimepython-datetimepython-dateutil

提问by Vendetta

See the following code:

请参阅以下代码:

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)

the output is

输出是

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

The timezone information simply got lost in the translation.

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

If I switch '%Z' to '%z', I get

如果我将 '%Z' 切换为 '%z',我会得到

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

I know I can use python-dateutil, but I just found it bizzare that I can't achieve this simple feature in datetime and have to introduce more dependency?

我知道我可以使用python-dateutil,但我发现奇怪的是我无法在 datetime 中实现这个简单的功能并且必须引入更多的依赖?

采纳答案by abarnert

Part of the problem here is that the strings usually used to represent timezones are not actually unique. "EST" only means "America/New_York" to people in North America. This is a limitation in the C time API, and the Python solution is…?to add full tz features in some future version any day now, if anyone is willing to write the PEP.

这里的部分问题是通常用于表示时区的字符串实际上并不是唯一的。“EST”对北美人来说仅意味着“America/New_York”。这是 C 时间 API 中的一个限制,而 Python 解决方案是……如果有人愿意编写 PEP,那么现在随时可以在某个未来版本中添加完整的 tz 功能。

You canformat and parse a timezone as an offset, but that loses daylight savings/summer time information (e.g., you can't distinguish "America/Phoenix" from "America/Los_Angeles" in the summer). You can format a timezone as a 3-letter abbreviation, but you can't parse it back from that.

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

If you want something that's fuzzy and ambiguous but usually what you want, you need a third-party library like dateutil.

如果你想要一些模糊不清但通常是你想要的东西,你需要一个像dateutil.

If you want something that's actually unambiguous, just append the actual tz name to the local datetime string yourself, and split it back off on the other end:

如果您想要一些实际上明确的东西,只需将实际的 tz 名称附加到本地日期时间字符串,然后在另一端将其拆分:

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

Or… halfway between those two, you're already using the pytzlibrary, which can parse (according to some arbitrary but well-defined disambiguation rules) formats like "EST". So, if you really want to, you can leave the %Zin on the formatting side, then pull it off and parse it with pytz.timezone()before passing the rest to strptime.

或者……介于两者之间,您已经在使用该pytz库,它可以解析(根据一些任意但定义明确的消歧规则)格式,如“EST”。所以,如果你真的想要,你可以将%Zin 留在格式化方面,然后将其拉下来并解析它,pytz.timezone()然后再将其余部分传递给strptime.

回答by Martijn Pieters

Unfortunately, strptime()can only handle the timezone configured by your OS, and then only as a time offset, really. From the documentation:

不幸的是,strptime()只能处理您的操作系统配置的时区,然后只能作为时间偏移量,真的。从文档

Support for the %Zdirective is based on the values contained in tznameand whether daylightis true. Because of this, it is platform-specific except for recognizing UTC and GMT which are always known (and are considered to be non-daylight savings timezones).

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

strftime()doesn't officially support %z.

strftime()不正式支持%z

You are stuck with python-dateutilto support timezone parsing, I am afraid.

python-dateutil恐怕你坚持支持时区解析。

回答by Johnny

Here is my answer in Python 2.7

这是我在 Python 2.7 中的答案

Print current time with timezone

用时区打印当前时间

from datetime import datetime
import tzlocal  # pip install tzlocal

print datetime.now(tzlocal.get_localzone()).strftime("%Y-%m-%d %H:%M:%S %z")

Print current time with specific timezone

使用特定时区打印当前时间

from datetime import datetime
import pytz # pip install pytz

print datetime.now(pytz.timezone('Asia/Taipei')).strftime("%Y-%m-%d %H:%M:%S %z")

It will print something like

它会打印类似的东西

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