python中的时间和日期时间差异触发错误

时间:2012-09-10 21:09:47

标签: python django datetime

我正在使用Django应用Pyroven并正在对其功能进行一些重大的重新设计。作为其中的一部分,我已经开始为它编写测试框架,因为目前它没有单元测试。作为后台,它使用University of Cambridge Raven service进行身份验证,并为Django提供身份验证后端以利用此服务。

我遇到的问题是测试来自Raven的WLS-Response令牌。这会形成一个!个分隔值的字符串,其中包含以下格式的时间字段:

%Y%m%dT%H%M%SZ

在我的测试代码中,我将其创建为:

raven_issue = datetime.now().strftime('%Y%m%dT%H%M%SZ')

然后将其返回到测试URL以供视图处理。问题在于验证过去这次对于响应的验证并不太远。验证它的代码使用:

def parse_time(t):
    """Converts a time of the form '20110729T123456Z' to a number of seconds
    since the epoch.
    @exception ValueError if the time is not a valid Raven time"""
    time_struct = time.strptime(t, "%Y%m%dT%H%M%SZ")
    return calendar.timegm(time_struct)

现在,当它从datetime.now()构造函数传递上面的字符串时,对此解析值的验证失败:

# Check that the issue time is not in the future or too far in the past:
if self.issue > time.time() + PYROVEN_MAX_CLOCK_SKEW:
    raise InvalidResponseError("The timestamp on the response is in the future")
if self.issue < time.time() - PYROVEN_MAX_CLOCK_SKEW - PYROVEN_TIMEOUT: 
    raise InvalidResponseError("The response has timed out")

此代码因我的测试失败,声称响应已超时。 PYROVEN_MAX_CLOCK_SKEWPYROVEN_TIMEOUT的值分别为2和10。

这引出了一个问题,即处理时间有些变化我不明白?如果我将datetime.now()生成的值放在未来2小时datetime.timedelta的情况下,将其转换为字符串并将其传递给验证,尽管时间戳在将来,但不会失败,什么时候应该。为什么这样,因为代码的逻辑读数表明它应该?

1 个答案:

答案 0 :(得分:2)

您在当地时间(由datetime.now()和GMT返回(由calendar.timegm()解析)之间感到困惑:

>>> t = datetime.now().strftime('%Y%m%dT%H%M%SZ')
>>> t
'20120910T232358Z'
>>> calendar.timegm(time.strptime(t, "%Y%m%dT%H%M%SZ"))
1347319438
>>> time.mktime(time.localtime())
1347312258.0
>>> time.mktime(time.strptime(t, "%Y%m%dT%H%M%SZ"))
1347312238.0

结论:使用time.mktime代替calendar.timegm将您的值转换为时间戳。