64

From:

http://docs.python.org/py3k/library/datetime.html#timedelta-objects

A timedelta object represents a duration, the difference between two dates or times.

So why i get error with this:

>>> from datetime import datetime, timedelta, time
>>> datetime.now() + timedelta(hours=12)
datetime.datetime(2012, 9, 17, 6, 24, 9, 635862)
>>> datetime.now().date() + timedelta(hours=12)
datetime.date(2012, 9, 16)

>>> datetime.now().time() + timedelta(hours=12)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'datetime.time' and 'datetime.timedelta'
xliiv
  • 5,399
  • 5
  • 29
  • 35

7 Answers7

89

datetime.time objects do not support addition with datetime.timedeltas.

There is one natural definition though, clock arithmetic. You could compute it like this:

import datetime as dt
now = dt.datetime.now()
delta = dt.timedelta(hours = 12)
t = now.time()
print(t)
# 12:39:11.039864

print((dt.datetime.combine(dt.date(1,1,1),t) + delta).time())
# 00:39:11.039864

dt.datetime.combine(...) lifts the datetime.time t to a datetime.datetime object, the delta is then added, and the result is dropped back down to a datetime.time object.

unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
  • 26
    It's a lot of work. I only want to calculate a time shift, python :). however it's solution, thanks. – xliiv Sep 16 '12 at 16:50
  • One thing to note here is that if `t` is smaller than `delta`, then, you will end up with `dt.date(1,1,0)`, which is an `OverflowError: date value out of range `. One way to approach this is to increase values in `dt.date(...)`. But this is still an issue one has to be careful with. – Akavall Aug 25 '15 at 16:24
  • 1
    this is an old post, what was the Python version back then? Probably 2. I'm using Python 3 and having the same issue. The really disappointing fact is that I tried it without that whole workaround on the console and it works perfectly, then put it in my code and it completely fails. This is really very very sad. Anyway the stated workaround works. – DanDan Nov 22 '18 at 15:12
19

All the solutions above are too complicated, OP had already shown that we can do calculation between datetime.datetime and datetime.timedelta, so why not just do:

(datetime.now() + timedelta(hours=12)).time()

ssword
  • 905
  • 10
  • 13
  • your way shows a datetime.datetime object. he has a datetime.time object – jon rios May 25 '21 at 00:08
  • This gives a different result: `datetime.datetime(2012, 9, 17, 6, 24, 9, 635862)` instead of `datetime.date(2012, 9, 16, 12)` – user2561747 Jun 24 '21 at 01:01
  • 2
    @jonrios the calculation inside the parenthesis gives a `datetime.datetime` object, but then `.time()` will output a `datetime.time` object – ssword Mar 07 '22 at 10:08
5

Here is a function that adds a timedelta to a time:

def time_plus(time, timedelta):
    start = datetime.datetime(
        2000, 1, 1,
        hour=time.hour, minute=time.minute, second=time.second)
    end = start + timedelta
    return end.time()

This will provide the expected result so long as you don't add times in a way that crosses a midnight boundary.

David Foster
  • 6,931
  • 4
  • 41
  • 42
3

How would this work? datetime.datetime.now().time() returns only hours, minutes, seconds and so on, there is no date information what .time() returns, only time.

Then, what should 18:00:00 + 8 hours return?
There's not answer to that question, and that's why you can't add a time and a timedelta.

In other words:

18:28:44, Sep. 16, 2012 + 8 hours #makes sense: it's 2:28:44, Sep. 17, 2012
18:28:44 + 8 hours # Doesn't make sense.
falsePockets
  • 3,826
  • 4
  • 18
  • 37
Thomas Orozco
  • 53,284
  • 11
  • 113
  • 116
  • 5
    While your general point is correct, 6pm + 5 hours = 11pm, so that is a bad example, and `.time()` doesn't return a timestamp -- a timestamp often includes enough information to derive a date, a `datetime.time` object does not. – agf Sep 16 '12 at 16:30
  • @agf, yes, I was editing my post actually : ). I'll also change the use of timestamp! – Thomas Orozco Sep 16 '12 at 16:32
  • Ok, i understand explanation i'm gonna used to it. call me a stupid, but in my reasoning adding hours to only date should raise exception in any of both:) however it's not compact in this form. I think adding time to time within a one day (24hours) could be possible. How can i achieve that in current state, like add 2h33m to now()? – xliiv Sep 16 '12 at 16:44
  • @xliiv unubtu's answer will give you this : ) – Thomas Orozco Sep 16 '12 at 16:48
0

A datetime.time object can be split into separate integer components that you can add to. No need for timedelta eg:

from datetime import datetime, time
    time_now = datetime.now().time()
    twelve_hours_time =  time(time_now.hour + 12, time_now.minute)
Martin Jones
  • 177
  • 1
  • 4
  • 4
    This would risk pushing the hour component >23 or the minute >59 and then you'll get a `ValueError`. It's easiest to just use datetime instead of time when doing addition. I've had use cases where I just made a dummy `datetime.datetime(1, 1, 1, hour, minute)` do the timedelta addition and then convert to time. – Brian Jul 30 '18 at 23:44
0
from datetime import datetime, date, timedelta, time    
result = datetime.combine(date.today(), test_time) + timedelta(minutes=int(gap))
print(result.time())

Note:minutes should be int;

Shaiful Islam
  • 335
  • 2
  • 12
  • Code-only answers are discouraged on Stack Overflow. Please provide a description of how your answer solves the problem, provide references where appropriate and explain how your solution is different from the other answers already provided. – DaveL17 Oct 10 '22 at 15:40
0

I see a different approach in one of the python's forum, hope this might be helpful to others if the accepted answer is not working, I see the newer python version might not work with accepted answer.

from datetime import datetime, timedelta, time

d = datetime(2021, 1, 1, 7, 0)
new_date = d + timedelta(hours=7)

print(d)

#2021-01-01 07:00:00

#To print only time

print((d + timedelta(hours=7)).time())

credits: https://python-forum.io/thread-32268.html