使用时间戳与使用timedelta的时间添加之间的差异?

时间:2018-05-13 21:52:42

标签: python datetime timedelta

我正在研究Exercism.io gigasecond问题:

“计算有人活了10 ^ 9秒的时刻。”

我的方法是将日期时间输入转换为时间戳,添加10 ** 9,然后转换回来。我的答案非常接近,但测试套件(由Exercism提供)失败了,因为小时arg关闭了一个。所有其他args都是正确的。

经过一番搜索,我找到了一个使用timedelta的答案;答案的结构几乎与我的相同,但它会产生完整正确的答案。

我的问题是,为什么这两种方法的输出有差异?如下所示,只有当小时的输入arg为默认值0时才会出现问题。

代码:

def add_gigasecond(birth_date):
    gigadate = birth_date.timestamp() + 10**9
    print(datetime.fromtimestamp(gigadate).__repr__())

    gigadate = birth_date + timedelta(seconds=10**9)
    print(gigadate.__repr__())

输入:

tests = [datetime(2011, 4, 25),
         datetime(1977, 6, 13),
         datetime(1959, 7, 19),
         datetime(2015, 1, 24, 22, 0, 0),
         datetime(2015, 1, 24, 23, 59, 59),]

结果:

test 1
datetime.datetime(2043, 1, 1, 0, 46, 40)
datetime.datetime(2043, 1, 1, 1, 46, 40)

test 2
datetime.datetime(2009, 2, 19, 0, 46, 40)
datetime.datetime(2009, 2, 19, 1, 46, 40)

test 3
datetime.datetime(1991, 3, 27, 0, 46, 40)
datetime.datetime(1991, 3, 27, 1, 46, 40)

test 4
datetime.datetime(2046, 10, 2, 23, 46, 40)
datetime.datetime(2046, 10, 2, 23, 46, 40)

test 5
datetime.datetime(2046, 10, 3, 1, 46, 39)
datetime.datetime(2046, 10, 3, 1, 46, 39)

正如您所看到的,对于指定年,月,日的所有输入,每个测试中的最佳答案(使用时间戳)为1。当输入中包含小时,分钟,秒和微秒args时,可以获得正确的答案。

2 个答案:

答案 0 :(得分:3)

夏令时

一些侦探工作可以解释这些问题。对于此次调查,我会在您的列表中选择第一个日期,即2011年4月25日。

from datetime import datetime, timedelta

def add_seconds(birth_date, n):
    x = datetime.fromtimestamp(birth_date.timestamp() + n)
    y = birth_date + timedelta(seconds=n)
    return (x, y)

for i in range(365):
    ts, td = add_seconds(datetime(2011, 4, 25), i*60**2*24)  # add i days via seconds
    if ts-td:  # test for difference in timestamp vs timedelta methods
        print(i, ts, td)
        break

结果:

189 2011-10-30 23:00:00 2011-10-31 00:00:00

如您所见,10月30日存在差异。这是for many countries,是我们看到夏令时调整的第二个日期。

更新:此处提出类似问题:Difference between evaluating timestamp and total_seconds。造成差异的根本原因是datetime.timedelta没有考虑DST,而timestamp确实考虑到了这一点。

答案 1 :(得分:1)

这很可能是由时区问题引起的。我怀疑当你转换为时间戳并回到日期时间时,时区信息会丢失。