Reputation: 7197
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)
**p.s. how many times did I use the word time?!
Upvotes: 2
Views: 3029
Reputation: 25544
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.
Upvotes: 1