缺少 datetime.timedelta.to_seconds() -> Python 中的浮动?
我知道出于效率原因,秒和微秒可能会在 datetime.timedelta
中单独表示,但我只是编写了这个简单的函数:
def to_seconds_float(timedelta):
"""Calculate floating point representation of combined
seconds/microseconds attributes in :param:`timedelta`.
:raise ValueError: If :param:`timedelta.days` is truthy.
>>> to_seconds_float(datetime.timedelta(seconds=1, milliseconds=500))
1.5
>>> too_big = datetime.timedelta(days=1, seconds=12)
>>> to_seconds_float(too_big) # doctest: +ELLIPSIS
Traceback (most recent call last):
...
ValueError: ('Must not have days', datetime.timedelta(1, 12))
"""
if timedelta.days:
raise ValueError('Must not have days', timedelta)
return timedelta.seconds + timedelta.microseconds / 1E6
这对于向 time.sleep< 传递值之类的事情很有用/code> 或
select.select
。 为什么datetime.timedelta
接口中没有类似的东西?我可能会遗漏一些极端情况。 时间表示似乎有很多不明显的极端情况......
我拒绝了几天以在一定精度上进行合理的尝试(我懒得实际计算出数学ATM,所以这似乎是一个合理的妥协; -)。
I understand that seconds and microseconds are probably represented separately in datetime.timedelta
for efficiency reasons, but I just wrote this simple function:
def to_seconds_float(timedelta):
"""Calculate floating point representation of combined
seconds/microseconds attributes in :param:`timedelta`.
:raise ValueError: If :param:`timedelta.days` is truthy.
>>> to_seconds_float(datetime.timedelta(seconds=1, milliseconds=500))
1.5
>>> too_big = datetime.timedelta(days=1, seconds=12)
>>> to_seconds_float(too_big) # doctest: +ELLIPSIS
Traceback (most recent call last):
...
ValueError: ('Must not have days', datetime.timedelta(1, 12))
"""
if timedelta.days:
raise ValueError('Must not have days', timedelta)
return timedelta.seconds + timedelta.microseconds / 1E6
This is useful for things like passing a value to time.sleep
or select.select
. Why isn't something like this part of the datetime.timedelta
interface? I may be missing some corner case. Time representation seems to have so many non-obvious corner cases...
I rejected days right out to have a reasonable shot at some precision (I'm too lazy to actually work out the math ATM, so this seems like a reasonable compromise ;-).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Python 浮点数大约有 15 位有效数字,因此秒数最多为 86400(小数点左边 5 位数字),微秒需要 6 位数字,您可以很好地包括天数(最多几年的价值)而不会丢失精确。
一个好的口头禅是“pi 秒是一个纳世纪”——大约每 100 年 3.14E9 秒,即每年 3E7,因此每年 3E13 微秒。 这个咒语很好,因为它很容易记住,尽管它确实需要你事后做一些心算(但是,就像菠菜一样,它对你有好处——让你保持敏捷和警觉!-)。
datetime
的设计理念有些简约,因此它省略了许多可能归结为简单算术表达式的辅助方法也就不足为奇了。A Python float has about 15 significant digits, so with seconds being up to 86400 (5 digits to the left of the decimal point) and microseconds needing 6 digits, you could well include the days (up to several years' worth) without loss of precision.
A good mantra is "pi seconds is a nanocentury" -- about 3.14E9 seconds per 100 years, i.e. 3E7 per year, so 3E13 microseconds per year. The mantra is good because it's memorable, even though it does require you to do a little mental arithmetic afterwards (but, like spinach, it's GOOD for you -- keeps you nimble and alert!-).
The design philosophy of
datetime
is somewhat minimalist, so it's not surprising it omits many possible helper methods that boil down to simple arithmetic expressions.您对精度的关注是错误的。 这是一个简单的两行代码,用于粗略计算您可以将 IEEE754 64 位浮点数中 53 位精度的剩余部分压缩为多少年:
注意四舍五入; 首先添加最小的非零数:
Your concern for precision is misplaced. Here's a simple two-liner to calculate roughly how many YEARS you can squeeze into what's left of the 53 bits of precsion in an IEEE754 64-bit float:
Watch out for round-off; add the smallest non-zero numbers first: