2

我得到以下代码

    timestamp = datetime.utcfromtimestamp(float(timestamp))
    now = datetime.utcnow()

    if now < timestamp:
        return False

有时,它会返回False。但只是有时。

就在print条件检查中给了我这个:

now 2013-02-28 18:02:57.015817
timestamp 2013-02-28 18:02:57.020000

因此,时间戳似乎正在播放“回到未来”几毫秒。

时间戳是从(datetime.utcnow() - datetime(1970, 1, 1)).total_seconds()先前调用中的 a 生成的。

我在最近的 Ubuntu 上的 Django 项目中得到了 py.test 运行的单元测试结果。

我目前的解决方案是将所有内容都设置为时间戳,调整毫秒并进行比较。我可以这样做。我只是想知道为什么会这样?

4

4 回答 4

2

猜测一下:adatetime是精确的,并将微秒数存储为一个单独的整数。但是 afloat是模糊的;它存储为二进制分数,您可能会得到轻微的四舍五入。

但是您不应该使用它total_seconds来转换为时间戳。改为这样做:

import calendar
timestamp = calendar.timegm(datetime.utcnow().timetuple())

无论如何,这将很方便地只返回一个整数。

于 2013-02-28T18:18:38.303 回答
0

核心原因是float -> str您的问题中未显示的转换(时间戳到字符串)。例子:

from datetime import datetime
from itertools import count


def main():
    for i in count():
        timestamp = (datetime.utcnow() - datetime(1970, 1, 1)).total_seconds()
        s_timestamp = str(timestamp)
        dt_from_str = datetime.utcfromtimestamp(float(s_timestamp))
        now = datetime.utcnow()
        if now < dt_from_str:
            dt = datetime.utcfromtimestamp(timestamp)
            for o in [now, dt_from_str, dt, timestamp, s_timestamp, i]:
                print(repr(o))
            break

main()

输出:

datetime.datetime(2013, 3, 17, 15, 52, 38, 355006)
datetime.datetime(2013, 3, 17, 15, 52, 38, 360000)
datetime.datetime(2013, 3, 17, 15, 52, 38, 355003)
1363535558.355003
'1363535558.36'
688

请注意,dt( datetime(2013, 3, 17, 15, 52, 38, 355003)) 应该小于now( datetime(2013, 3, 17, 15, 52, 38, 355006)),并且四舍五入发生在str(timestamp)表达式 ( '1363535558.36') 中。

于 2013-03-17T15:54:17.917 回答
0

你正在timestampfloat- 这个舍入操作偶尔向上舍入,所以你打了now < timestamp条件?

于 2013-02-28T18:19:05.820 回答
0

编辑:其他人在从浮点数投射日期时谈论舍入问题可能有正确的答案。

我怀疑问题是您在代码中混淆了变量名范围。代替:

timestamp = (datetime.utcnow() - datetime(1970, 1, 1)).total_seconds()
timestamp = datetime.utcfromtimestamp(float(timestamp ))
now = datetime.utcnow()

尝试重构为这样的东西:

ts = (datetime.utcnow() - datetime(1970, 1, 1)).total_seconds()
timestamp = datetime.utcfromtimestamp(float(ts))
now = datetime.utcnow()

看看会发生什么。确实没有充分的理由进行timestamp这样的不同转换,并且更容易准确地调试这种方式正在发生的事情。

于 2013-02-28T18:21:45.257 回答