Pregunta

Dado un datetime.time valor 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)

Sin embargo, no puedo evitar pensar que me falta una manera más fácil de hacer esto.

Relacionado

¿Fue útil?

Solución

Puedes usar completo datetime variables con timedelta, y proporcionando una fecha ficticia y luego usando time para obtener simplemente 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()

da como resultado los dos valores, con tres segundos de diferencia:

11:34:59
11:35:02

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

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

si así lo deseas.


Si buscas una función que pueda hacer esto, puedes considerar usar addSecs abajo:

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

Otros consejos

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

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 lo que pasaría si agregara 2 horas a las 11 p.m.¿Cuál es el comportamiento correcto?¿Una excepción, porque no se puede tener una hora mayor a las 11:59 p. m.?¿Debería volver a dar la vuelta?

Diferentes programadores esperarán cosas diferentes, por lo que cualquier resultado que elijan sorprenderá a mucha gente.Peor aún, los programadores escribían código que funcionaba bien cuando lo probaban inicialmente y luego lo rompían al hacer algo inesperado.Esto es muy malo, por lo que no se le permite agregar objetos timedelta a objetos time.

Una pequeña cosa, podría agregar claridad al anular el valor predeterminado durante 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 utilizar fechas y horarios completos en todo momento.Si tengo que aceptar objetos datetime.time de una fuente externa, entonces esta parece ser una alternativa add_secs_to_time() función:

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 de todos modos me gustaría resumir eso en una función para aclarar el código.

Si vale la pena agregar otro archivo/dependencia a su proyecto, acabo de escribir una pequeña clase que se extiende datetime.time con capacidad para hacer aritmética.Cuando pasas la medianoche, llega a cero.Ahora, "¿Qué hora será dentro de 24 horas?" tiene muchos casos extremos, incluido el horario de verano, segundos intercalares, cambios históricos de zona horaria, etc.Pero a veces realmente necesitas el caso simple, y eso es lo que esto hará.

Su 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 poder utilizarse.

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

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

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

Crear timedelta Objeto con cuántos segundos desea agregar y agregarlo a datetime objeto:

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

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

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

Intente agregar un datetime.datetime a un datetime.timedelta.Si sólo desea la parte del tiempo, puede llamar al time() método sobre la resultante datetime.datetime objeto para conseguirlo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top