Dateutil 解析错误 python returns 错误值

Dateutil parse bug in python returns the wrong value

我研究了很多可能的方法来解析 python 次。 Using parse seems link the only method that should work. While trying to use datetime.strptime causes an error because %z does not work with python 2.7。但是使用 parse.parse 会错误地识别时区。

我解析了 Fri Nov 9 09:04:02 2012 -0500Fri Nov 9 09:04:02 2012 -0800 并得到了完全相同的 unix 时间戳。 1352480642

这是我运行测试的代码。

#!/usr/bin/python
import time
from dateutil import parser

def get_timestamp(time_string):
    timing = parser.parse(time_string)
    return time.mktime(timing.timetuple())

test_time1 = "Fri Nov 9 09:04:02 2012 -0500"
test_time2 = "Fri Nov 9 09:04:02 2012 -0800"
print get_timestamp(test_time1)
print get_timestamp(test_time2)

输出

1352480642.0
1352480642.0

预期输出

1352469842.0
1352480642.0

这与解析器无关,您会在 mktime() 中看到相同的行为,因为 datetime.timetuple() 没有任何时区偏移信息,并且 mktime()localtime 的倒数。您可以通过在调用 timetuple():

之前将其转换为 localtime 来更正此问题
from time import mktime
from datetime import datetime
from dateutil import tz

dt_base = datetime(2012, 11, 9, 9, 4, 2)

dt_est = dt_base.replace(tzinfo=tz.tzoffset('EST', -5 * 3600))
dt_pst = dt_base.replace(tzinfo=tz.tzoffset('PST', -8 * 3600))

def print_mktime(dt):
    print(mktime(dt.timetuple()))

# Run in UTC
print_mktime(dt_est)   # 1352469842.0
print_mktime(dt_pst)   # 1352469842.0

# Convert to local time zone first first
print_mktime(dt_est.astimezone(tz.tzlocal())) # 1352469842.0
print_mktime(dt_pst.astimezone(tz.tzlocal())) # 1352480642.0

请注意,documentation for time() (python 2.x docs) 上有一个图表告诉您如何在这些表示之间进行转换:

From                        To                           Use
---------------------------------------------------------------------------
seconds since the epoch   | struct_time in UTC        |  gmtime()
seconds since the epoch   | struct_time in local time |  localtime()
struct_time in UTC        | seconds since the epoch   |  calendar.timegm()
struct_time in local time | seconds since the epoch   |  mktime()

我个人的偏好是将解析的日期转换为 UTC,在这种情况下 calendar.timegm() 将是合适的函数:

from calendar import timegm
def print_timegm(dt):
    print(timegm(dt.timetuple()))

print_timegm(dt_est.astimezone(tz.tzutc())) # 1352469842.0
print_timegm(dt_pst.astimezone(tz.tzutc())) # 1352480642.0