O que é a maneira padrão para adicionar N segundos para datetime.time em Python?
Pergunta
Dado um valor datetime.time
em Python, há uma maneira padrão para adicionar um número inteiro de segundos a ele, de modo que 11:34:59
+ 3 = 11:35:02
, por exemplo?
Estas ideias óbvias não funcionam:
>>> 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'
No final, eu ter funções escrito assim:
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)
Não consigo deixar de pensar que eu estou faltando uma maneira mais fácil de fazer isso embora.
Relacionados
Solução
Você pode usar variáveis ??datetime
completas com timedelta
, e fornecendo uma data fictícia em seguida, usando time
apenas para obter o valor de tempo.
Por exemplo:
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()
resultados nos dois valores, três segundos de intervalo:
11:34:59
11:35:02
Você também pode optar pelo mais legível
b = a + datetime.timedelta(seconds=3)
Se você é tão inclinado.
Se você é depois de uma função que pode fazer isso, você pode olhar em usar addSecs
abaixo:
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
Esta saídas:
09:11:55.775695
09:16:55
Outras dicas
Como outros aqui afirmaram, você pode apenas usar objetos de data e hora completos em todo o:
sometime = get_some_time() # the time to which you want to add 3 seconds
later = (datetime.combine(date.today(), sometime) + timedelta(seconds=3)).time()
No entanto, penso que vale a pena explicar por que os objetos de data e hora são requeridos. Considere o que aconteceria se eu adicionei 2 horas às 11h. Qual é o comportamento correto? Uma exceção, porque você não pode ter um tempo maior do que 11:59? Deve envolver volta ao redor?
Diferentes programadores esperam coisas diferentes, então qualquer que seja o resultado, eles escolhido seria surpresa para muita gente. Pior ainda, os programadores iria escrever código que funcionou muito bem quando testado inicialmente, e depois tê-lo quebrar mais tarde, fazendo algo inesperado. Isso é muito ruim, razão pela qual você não tem permissão para adicionar timedelta objetos para objetos de tempo.
Uma coisa pequena, pode adicionar clareza para substituir o valor padrão para segundos
>>> b = a + datetime.timedelta(seconds=3000)
>>> b
datetime.datetime(1, 1, 1, 12, 24, 59)
Graças à @Pax Diablo, @bvmou e @Arachnid para a sugestão de usar datetimes completos em todo. Se eu tenho que aceitar datetime.time objetos a partir de uma fonte externa, em seguida, esta parece ser uma função 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 detalhado código pode ser comprimido para este one-liner:
(datetime.datetime.combine(datetime.date(1, 1, 1), timeval) + datetime.timedelta(seconds=secs_to_add)).time()
mas eu acho que eu iria querer envolver-se que em uma função para a clareza do código de qualquer maneira.
Se vale a pena acrescentar outro arquivo / dependência para seu projeto, eu acabei de escrever um pequeno classe que estende datetime.time
com a capacidade de fazer contas. Quando você vai da meia-noite, que envolve em torno de zero. Agora, "O tempo é que vai ser, 24 horas a partir de agora" tem um monte de casos de canto, incluindo o horário de verão, segundo salto, mudanças de fuso horário históricos, e assim por diante. Mas às vezes você realmente precisa fazer o caso simples, e é isso que vai fazer isto.
Seu exemplo seria escrito:
>>> import datetime
>>> import nptime
>>> nptime.nptime(11, 34, 59) + datetime.timedelta(0, 3)
nptime(11, 35, 2)
herda nptime
de datetime.time
, portanto, qualquer um desses métodos deve ser utilizável, também.
Está disponível a partir PyPI como nptime
( "o tempo não pedante"), ou no GitHub: https: // github .com / tgs / nptime
Você não pode simplesmente adicionar o número a datetime
porque é claro o aparelho é utilizado: segundos, horas, semanas ...
Não é de classe timedelta
para manipulações com data e hora. datetime
menos datetime
dá timedelta
, datetime
mais timedelta
dá datetime
, dois objetos datetime
não pode ser adicionado embora dois timedelta
lata.
Criar objeto timedelta
com quantos segundos você deseja adicionar e adicioná-lo objeto datetime
:
>>> from datetime import datetime, timedelta
>>> t = datetime.now() + timedelta(seconds=3000)
>>> print(t)
datetime.datetime(2018, 1, 17, 21, 47, 13, 90244)
Há mesmo conceito em C ++:. std::chrono::duration
Para completar amor, aqui é a maneira de fazê-lo com arrow
(melhores datas e os tempos para Python):
sometime = arrow.now()
abitlater = sometime.shift(seconds=3)
Tente adicionar um datetime.datetime
a um datetime.timedelta
. Se você só quer a parte do tempo, você pode chamar o método time()
no objeto datetime.datetime
resultante para obtê-lo.