geo*_*opy 5 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__())
Run Code Online (Sandbox Code Playgroud)
输入:
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),]
Run Code Online (Sandbox Code Playgroud)
结果:
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)
Run Code Online (Sandbox Code Playgroud)
如您所见,对于指定年,月,日的所有输入,每个测试中的最佳答案(使用时间戳)偏差为1.当输入中包含小时,分钟,秒和微秒args时,可以获得正确的答案.
夏令时
一些侦探工作可以阐明这些问题。对于本次调查,我选择列表中的第一个日期,即 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
Run Code Online (Sandbox Code Playgroud)
结果:
189 2011-10-30 23:00:00 2011-10-31 00:00:00
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,10 月 30 日正好存在差异。对于许多国家/地区来说,这是一年中我们看到夏令时调整的第二个日期。
更新:这里提出了类似的问题:评估时间戳和total_seconds之间的差异。造成差异的根本原因是datetime.timedelta没有考虑 DST,而timestamp确实考虑了 DST。
| 归档时间: |
|
| 查看次数: |
177 次 |
| 最近记录: |