Python的datetime strptime()在不同机器间不一致

5 投票
2 回答
1408 浏览
提问于 2025-04-20 23:13

我遇到问题了。我写的日期清理函数在我的Mac上使用Python 2.7.5时能正常工作,但在我的Ubuntu服务器上用2.7.6却不行。

Python 2.7.5 (default, Mar  9 2014, 22:15:05) 
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from datetime import datetime
>>> date = datetime.strptime('2013-08-15 10:23:05 PDT', '%Y-%m-%d %H:%M:%S %Z')
>>> print(date)
2013-08-15 10:23:05

为什么在Ubuntu的2.7.6上这个不行呢?

Python 2.7.6 (default, Mar 22 2014, 22:59:56) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from datetime import datetime
>>> date = datetime.strptime('2013-08-15 10:23:05 PDT', '%Y-%m-%d %H:%M:%S %Z')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/_strptime.py", line 325, in _strptime
    (data_string, format))
ValueError: time data '2013-08-15 10:23:05 PDT' does not match format '%Y-%m-%d %H:%M:%S %Z'

补充:我尝试使用小写的%z来设置时区偏移,但还是出现了错误(虽然是不同的错误):

>>> date = datetime.strptime('2013-08-15 10:23:05 -0700', '%Y-%m-%d %H:%M:%S %z')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/_strptime.py", line 317, in _strptime
    (bad_directive, format))
ValueError: 'z' is a bad directive in format '%Y-%m-%d %H:%M:%S %z'

2 个回答

3

%Z 只会接受 GMT、UTC 以及在 time.tzname 中列出的时间区域,因为时间区域的功能是和平台相关的,具体情况可以在 这里 找到:

%Z 指令的支持是基于 tzname 中的值以及是否是夏令时。因此,这个功能是和平台相关的,除了 UTC 和 GMT 这两个总是被认可的(它们被认为是非夏令时的时间区域)。

所以你可以通过运行以下代码来找出你的平台支持哪些时间区域:

import time
time.tzname

我得到的结果是:

('PST', 'PDT')

因此,最好的办法可能是提前将你的时间转换为一个默认允许的时间区域。

5

时区缩写是有歧义的。比如说,EST可以指美国的东部标准时间,也可以指澳大利亚的东部夏令时间。

因此,包含时区缩写的日期时间字符串不能可靠地转换成带时区的日期时间对象。

strptime中的'%Z'格式只会匹配UTC、GMT或在time.tzname中列出的时区缩写,而这些是依赖于机器的本地设置的。

如果你能把日期时间字符串改成包含UTC偏移量的格式,那么你可以使用dateutil来将这些字符串解析成带时区的日期时间对象:

import dateutil
import dateutil.parser as DP
date = DP.parse('2013-08-15 10:23:05 -0700')
print(repr(date))
# datetime.datetime(2013, 8, 15, 10, 23, 5, tzinfo=tzoffset(None, -25200))

撰写回答