Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Missing datetime.timedelta.to_seconds() -> float in Python?

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 ;-).

like image 253
cdleary Avatar asked Jul 05 '09 03:07

cdleary


People also ask

How do you convert Timedelta to float?

How do you convert Timedelta to float? from datetime import timedelta,datetime x1= timedelta(seconds=40, minutes=40, hours=5) x2= timedelta( seconds=50, minutes=20, hours=4) x3=x1-x2 x5 = x3.

What is datetime Timedelta in Python?

timedelta Objects. A timedelta object represents a duration, the difference between two dates or times. class datetime. timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)


2 Answers

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.

like image 98
Alex Martelli Avatar answered Oct 21 '22 22:10

Alex Martelli


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:

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

Watch out for round-off; add the smallest non-zero numbers first:

return timedelta.seconds + timedelta.microseconds / 1E6 + timedelta.days * 86400
like image 39
John Machin Avatar answered Oct 21 '22 21:10

John Machin