What is the standard way to add N seconds to datetime.time in Python?

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.

Of

#1 building

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.

#2 building

You can match the full datetime variable with timedelta, provide a virtual date, and then use time to get the time value.

For example:

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:

11:34:59
11:35:02

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

Output:

 09:11:55.775695
 09:16:55

#3 building

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)

#4 building

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.

#5 building

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.

Tags: Python

Posted on Tue, 10 Mar 2020 01:35:40 -0400 by Ambush Commander