¿Cuál es la forma estándar de agregar N segundos a datetime.time en Python?

Dado un valor de datetime.time en Python, ¿hay una forma estándar de agregarle un número entero de segundos, de modo que 11:34:59 + 3 = 11:35:02 , por ejemplo?

Estas ideas obvias no funcionan:

 >>> 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' 

Al final he escrito funciones como esta:

 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) 

No puedo dejar de pensar que me estoy perdiendo una forma más fácil de hacer esto.

Relacionado

  • Tiempo de Python + Timedelta equivalente

Puede usar variables de datetime completas con timedelta , y al proporcionar una fecha ficticia y luego usar la time para obtener el valor del tiempo.

Por ejemplo:

 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() 

resulta en los dos valores, separados por tres segundos:

 11:34:59 11:35:02 

También puedes optar por la más legible.

 b = a + datetime.timedelta(seconds=3) 

si eres tan inclinado


Si está buscando una función que pueda hacer esto, puede consultar el uso de addSecs continuación:

 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 

Esto produce:

  09:11:55.775695 09:16:55 

Como han dicho otros aquí, puede usar objetos de fecha y hora completos en todo:

 sometime = get_some_time() # the time to which you want to add 3 seconds later = (datetime.combine(date.today(), sometime) + timedelta(seconds=3)).time() 

Sin embargo, creo que vale la pena explicar por qué se requieren objetos de fecha y hora completos. Considere qué pasaría si añadiera 2 horas a las 11 pm. ¿Cuál es el comportamiento correcto? ¿Una excepción, porque no puedes tener un tiempo mayor a las 11:59 pm? ¿Debería envolverse de nuevo?

Los diferentes progtwigdores esperarán cosas diferentes, por lo que cualquier resultado que escojan sorprendería a mucha gente. Peor aún, los progtwigdores escribirían un código que funcionara bien cuando lo probaron inicialmente, y luego lo romperían haciendo algo inesperado. Esto es muy malo, por lo que no se le permite agregar objetos timedelta a los objetos de tiempo.

Una pequeña cosa, podría agregar claridad para anular el valor predeterminado en segundos

 >>> b = a + datetime.timedelta(seconds=3000) >>> b datetime.datetime(1, 1, 1, 12, 24, 59) 

Gracias a @Pax Diablo, @bvmou y @Arachnid por la sugerencia de usar fechas completas a lo largo. Si tengo que aceptar objetos datetime.time de una fuente externa, entonces esta parece ser una función add_secs_to_time() alternativa:

 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() 

Este código detallado se puede comprimir en esta sola línea:

 (datetime.datetime.combine(datetime.date(1, 1, 1), timeval) + datetime.timedelta(seconds=secs_to_add)).time() 

pero creo que me gustaría envolver eso en una función para la claridad del código de todos modos.

Si vale la pena agregar otro archivo / dependencia a tu proyecto, acabo de escribir una pequeña clase que extiende datetime.time con la capacidad de hacer aritmética. Cuando pasas de la medianoche, se envuelve alrededor de cero. Ahora, “a qué hora será, dentro de 24 horas” tiene muchos casos en las esquinas, incluidos el horario de verano, los segundos de salto, los cambios históricos en la zona horaria, etc. Pero a veces realmente necesitas el caso simple, y eso es lo que hará esto.

Tu ejemplo estaría escrito:

 >>> import datetime >>> import nptime >>> nptime.nptime(11, 34, 59) + datetime.timedelta(0, 3) nptime(11, 35, 2) 

nptime hereda de datetime.time , por lo que cualquiera de esos métodos también debería ser utilizable.

Está disponible desde PyPi como nptime (“tiempo no pedante”), o en GitHub: https://github.com/tgs/nptime

No puede simplemente agregar un número a datetime porque no está claro qué unidad se utiliza: segundos, horas, semanas …

Hay clases de timedelta para manipulaciones con fecha y hora. datetime menos datetime da timedelta , datetime más timedelta da datetime , dos objetos datetime no se pueden agregar, aunque dos timedelta pueden.

Cree el objeto timedelta con la cantidad de segundos que desea agregar y agréguelo al objeto datetime :

 >>> from datetime import datetime, timedelta >>> t = datetime.now() + timedelta(seconds=3000) >>> print(t) datetime.datetime(2018, 1, 17, 21, 47, 13, 90244) 

Hay el mismo concepto en C ++: std::chrono::duration .

Intente agregar un datetime.datetime a un datetime.timedelta . Si solo desea la parte de tiempo, puede llamar al método time() en el objeto datetime.datetime resultante para obtenerlo.

Para completar, esta es la forma de hacerlo con la arrow (mejores fechas y horas para Python):

 sometime = arrow.now() abitlater = sometime.shift(seconds=3)