Given the datetime.time value in Python, is there a standard way to add integer seconds to it, such as 11:34:59 + 3 = 11:35:02?
These obvious ideas don't work:
>>> datetime.time(11, 34, 59) + 3 TypeError: unsupported operand type(s) for +: 'datetime.time' and 'int' >>> datetime.time(11, 34, 59) + datetime.timedelta(0, 3) TypeError: unsupported operand type(s) for +: 'datetime.time' and 'datetime.timedelta' >>> datetime.time(11, 34, 59) + datetime.time(0, 0, 3) TypeError: unsupported operand type(s) for +: 'datetime.time' and 'datetime.time'
Finally, I wrote a function like this:
def add_secs_to_time(timeval, secs_to_add): secs = timeval.hour * 3600 + timeval.minute * 60 + timeval.second secs += secs_to_add return datetime.time(secs // 3600, (secs % 3600) // 60, secs % 60)
I can't help thinking that I lack a simpler way to do it.
Try adding datetime.datetime to datetime.timedelta. If you only need the time part, you can call the time() method on the generated datetime.datetime object to get it.
You can match the full datetime variable with timedelta, provide a virtual date, and then use time to get the time value.
import datetime a = datetime.datetime(100,1,1,11,34,59) b = a + datetime.timedelta(0,3) # days, seconds, then other fields. print a.time() print b.time()
Two values are obtained, three seconds apart:
You can also choose more readable
b = a + datetime.timedelta(seconds=3)
If you are so inclined.
If you are looking for a function that can perform this operation, you can use addSecs below:
import datetime def addSecs(tm, secs): fulldate = datetime.datetime(100, 1, 1, tm.hour, tm.minute, tm.second) fulldate = fulldate + datetime.timedelta(seconds=secs) return fulldate.time() a = datetime.datetime.now().time() b = addSecs(a, 300) print a print b
One thing that may increase sharpness to override the default value (seconds)
>>> b = a + datetime.timedelta(seconds=3000) >>> b datetime.datetime(1, 1, 1, 12, 24, 59)
Thank @Pax Diablo, @ bvmou and @ Arachnid recommend using the full date time throughout the process. If I have to accept the datetime.time object from an external source, then this seems to be an alternative to the add_secs_to_time() function:
def add_secs_to_time(timeval, secs_to_add): dummy_date = datetime.date(1, 1, 1) full_datetime = datetime.datetime.combine(dummy_date, timeval) added_datetime = full_datetime + datetime.timedelta(seconds=secs_to_add) return added_datetime.time()
This verbose code can be compressed in the following form:
(datetime.datetime.combine(datetime.date(1, 1, 1), timeval) + datetime.timedelta(seconds=secs_to_add)).time()
But I think I'll wrap it in a function to make sure the code is clear.
As others have said, you can use the full datetime object throughout the process:
sometime = get_some_time() # the time to which you want to add 3 seconds later = (datetime.combine(date.today(), sometime) + timedelta(seconds=3)).time()
However, I think it's worth explaining why a full datetime object is needed. Consider what happens if I add two hours at 11 p.m. What is the right behavior? There is an exception, because your time can't exceed 11:59 p.m? Should it rewind?
Different programmers expect different things, so any result they choose will surprise many people. What's worse is that the code that the programmer originally wrote works when it was first tested, and then destroys the code later by doing something unexpected. This is terrible, which is why you are not allowed to add a timedelta object to a time object.