python 2 和 3 之间日期时间舍入的奇怪行为

Strange behavior of datetime rounding between python 2 & 3

提问人:simonzack 提问时间:1/23/2015 最后编辑:simonzack 更新时间:1/27/2015 访问量:224

问:

在 python 2 中,我们有:

>>> datetime.datetime.utcfromtimestamp(1000000000005.0/1000.0)
datetime.datetime(2001, 9, 9, 1, 46, 40, 5000)

但是在 python 3 中,我们有:

>>> datetime.datetime.utcfromtimestamp(1000000000005.0/1000.0)
datetime.datetime(2001, 9, 9, 1, 46, 40, 4999)

这种奇怪的四舍五入行为的原因是什么,它是故意的吗?不是还在只有几位数的双打范围内吗?1000000000005.0

python 日期时间 舍入

评论

0赞 dmg 1/23/2015
有趣的发现。你能发布你的操作系统python sys.version吗?
5赞 Armin Rigo 1/23/2015
比较来源,似乎在 Python 2 中它四舍五入到最接近的微秒,而在 Python 3 中它总是向下舍入。这意味着内部发生的任何计算错误,无论多么小,都有可能将数字向下舍入近一微秒,就像这里发生的那样。我不知道这是故意的还是一个错误。
1赞 jfs 1/23/2015
@ArminRigo:你是说datetime_from_timestamp()中的_PyTime_ROUND_DOWN吗?在此处将其更改为生产。_PyTime_ROUND_UP5000
1赞 pingz 1/23/2015
我不确定,但在我看来,他们有很多四舍五入的论据。v3.4 更改了行为。bugs.python.org/issue8860
1赞 hft 1/24/2015
这不仅仅是 2 对 3 的差异。python2.7.8 和 python3.2.5 之间没有区别,两者都返回 datetime.datetime(2001,9,9,1,46,40,5000)。我正在使用 cygwin。

答:

0赞 Zach Gates 1/27/2015 #1

下面我基本上包括了(我稍微修改为独立)。utcfromtimestamp

在 Python 2 中:

import time, datetime
def utcfromtimestamp(t):
    y, m, d, hh, mm, ss, weekday, jday, dst = time.gmtime(t)
    us = int((t % 1.0) * 1000000)
    ss = min(ss, 59)
    return datetime.datetime(y, m, d, hh, mm, ss, us)

在 Python 3 中:

import time, datetime
def utcfromtimestamp(t):
    t, frac = divmod(t, 1.0)
    us = int(frac * 1e6)
    if us == 1000000:
        t += 1
        us = 0
    y, m, d, hh, mm, ss, weekday, jday, dst = time.gmtime(t)
    ss = min(ss, 59)
    return datetime.datetime(y, m, d, hh, mm, ss, us)

(输入计算为 。1000000000005.0/1000.01000000000.005

在我的独立版本中:

Python 2 使用模运算符来确定输入是整数还是分数。 然后,该语句将分数(在我们的例子中)乘以 。这将返回 ,四舍五入为 。%(t % 1.0) * 10000000.00499999523162841810000004999.9952316284184999int

Python 3 用于返回整数 () 和分数 ()。 它不是返回这个,而是返回 和 as 。 然后,它开始使用 进行计算。这是将 ur 乘以 得到 ,四舍五入为 。divmodt1000000000.0frac0.005t1000000000frac0.004999995231628418usfrac * 1e60.00499999523162841810000004999.9952316284184999int

使用的方法没有真正的区别。两者都是准确的,并返回相同的结果。我的结论是,Python 2 正在向上舍入微秒,而 Python 3 正在向下舍入它们。