9

我知道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.sleepor等​​事情很有用select.select为什么界面的这一部分没有类似的东西?datetime.timedelta我可能会遗漏一些角落案例。时间表示似乎有很多不明显的极端情况......

我拒绝了几天来合理地精确地拍摄(我懒得实际计算出数学 ATM,所以这似乎是一个合理的妥协;-)。

4

2 回答 2

12

Python 浮点数大约有 15 位有效数字,因此秒数最多为 86400(小数点左侧的 5 位数字)和微秒需要 6 位数字,您可以很好地包括天数(最多数年)而不会丢失精确。

一个好的口头禅是“pi 秒是一个纳米世纪”——大约每 100 年 3.14E9 秒,即每年 3E7,因此每年 3E13 微秒。这个咒语很好,因为它令人难忘,尽管它确实需要你在之后做一些心算(但是,就像菠菜一样,它对你有好处——让你保持敏捷和警觉!-)。

的设计理念datetime有点简约,因此它省略了许多可能归结为简单算术表达式的辅助方法也就不足为奇了。

于 2009-07-05T03:35:44.367 回答
3

您对精度的关注是错误的。这是一个简单的两行代码,用于粗略计算您可以挤入 IEEE754 64 位浮点数中 53 位精度的剩余年份:

>>> import math
>>> 10 ** (math.log10(2 ** 53) - math.log10(60 * 60 * 24) - 6) / 365.25
285.42092094268787
>>>

注意四舍五入;首先添加最小的非零数:

return timedelta.seconds + timedelta.microseconds / 1E6 + timedelta.days * 86400
于 2009-07-05T07:17:38.173 回答