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

sim*_*ack 11 python datetime rounding

在python 2中,我们有:

>>> datetime.datetime.utcfromtimestamp(1000000000005.0/1000.0)
datetime.datetime(2001, 9, 9, 1, 46, 40, 5000)
Run Code Online (Sandbox Code Playgroud)

但是在python 3中,我们有:

>>> datetime.datetime.utcfromtimestamp(1000000000005.0/1000.0)
datetime.datetime(2001, 9, 9, 1, 46, 40, 4999)
Run Code Online (Sandbox Code Playgroud)

造成这种奇怪的舍入行为的原因是什么呢?是不是1000000000005.0仍然在有几位数的双打范围内?

Zac*_*tes 0

下面我基本上已经包含了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)
Run Code Online (Sandbox Code Playgroud)

在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)
Run Code Online (Sandbox Code Playgroud)

(输入的1000000000005.0/1000.0计算结果为1000000000.005。)

在我的独立版本中:

Python 2 使用模运算符%来确定输入是整数还是分数。然后该语句(t % 1.0) * 1000000将分数(在我们的例子中0.004999995231628418)乘以1000000。返回值4999.995231628418,向下舍入为4999by int

Python 3 用于divmod返回整数 ( t)1000000000.0和分数 ( frac) 0.005。它不返回 this,而是返回tas1000000000fracas 0.004999995231628418us然后使用进行计算frac * 1e6。这是将您的结果乘以0.0049999952316284181000000然后4999.995231628418向下舍入为4999by int

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