简体   繁体   中英

TypeError: unsupported operand type(s) for -: 'datetime.time' and 'datetime.timedelta'

Python datetime does not allow subtracting timedelta from time ; I suppose that's because timedelta can span over days and time is only within 24 hrs (hh:mm:ss.ns).

Now the question is if there is a data structure similar to timedelta that allows subtraction directly from time ?

I understand that I can convert my datetime.time to datetime.timedelta to enable subtraction from another datetime.timedelta . BUT I'm trying to avoid casting time to timedelta because I'm reading times from a large file and it's expensive to cast every time to timedelta. However, it is a one time operation to simply replace timedelta with some_datastructure (if that sth exist) and subtract directly from time .

example:

t1 = datetime.time(hour=1, minute=1, second=1)
# t1 = datetime.timedelta(hours=t1.hour, minutes=t1.minute, seconds=t1.second)
t_diff = datetime.timedelta(hours=0, minutes=0, seconds=1)
print(t1-t_diff)

**ps how many time s did I use the word time ?!

a conversion to datetime.datetime instead of datetime.timedelta would be more efficient:

from random import randrange
from datetime import datetime, time, timedelta

# some random times:
N = int(1e6)
ts = [time(randrange(23),randrange(59),randrange(59),randrange(999999)) for _ in range(N)]

# to timedelta could look like
td = [timedelta(0, 0, (t.hour*60*60*1e6+t.minute*60*1e6+t.second*1e6+t.microsecond)) for t in ts]

# %timeit [timedelta(0, 0, (t.hour*60*60*1e6+t.minute*60*1e6+t.second*1e6+t.microsecond)) for t in ts]
# 856 ms ± 903 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)

# to datetime could look like
today = datetime.now().date()
dt = [datetime.combine(today, t) for t in ts]

# %timeit [datetime.combine(today, t) for t in ts]
# 201 ms ± 1.85 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

# now you'd do something with dt
ts_new = [(d + timedelta(seconds=5)).time() for d in dt]

# %timeit [(d + timedelta(seconds=5)).time() for d in dt]
# 586 ms ± 1.68 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

But still - for the 1M element example, the timeits show that we're definitely falling into the critical >1ms range. If you want to go faster, I guess you'll have to use another time format in the first place, such as for example integer (micro)seconds since midnight.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM