Estou tendo problemas para formatar um datetime.timedelta
objeto.
Aqui está o que estou tentando fazer: Eu tenho uma lista de objetos e um dos membros da classe do objeto é um objeto timedelta que mostra a duração de um evento. Gostaria de exibir essa duração no formato de horas: minutos.
Eu tentei uma variedade de métodos para fazer isso e estou tendo dificuldades. Minha abordagem atual é adicionar métodos à classe para meus objetos que retornam horas e minutos. Posso obter as horas dividindo o timedelta.seconds por 3600 e arredondando-o. Estou tendo problemas para obter os segundos restantes e converter isso em minutos.
A propósito, estou usando o Google AppEngine com Django Templates para apresentação.
datetime.utcfromtimestamp()
. Veja minha resposta abaixo.__str__
detimedelta
é bastante decente, em oposição a__repr__
(isto é - para humanos!). Por exemplo:datetime.timedelta(minutes=6, seconds=41) * 2618 / 48
dádatetime.timedelta(seconds=21871, microseconds=208333)
, masstr(datetime.timedelta(minutes=6, seconds=41) * 2618 / 48)
dá o'6:04:31.208333'
que é razoavelmente bom de ler.Respostas:
Você pode apenas converter o timedelta em uma string com str (). Aqui está um exemplo:
fonte
print 'some thing ' + str(delta)
ConvertDuration=datetime.timedelta(milliseconds=int(254459))
, basta usar split para tirar os microssegundos de folga. De 0: 03: 43.765000 Eu consigo 0:03:43 simplesmente executandoTotalDuration=str(ConvertDuration).split('.', 2)[0]
Como você sabe, você pode obter o total_seconds de um objeto timedelta acessando o
.seconds
atributoPython fornece a função interna
divmod()
que permite:ou você pode converter para horas e o restante usando uma combinação de módulo e subtração:
fonte
abs(s)
.'%d:%02d:%02d'
para ter zeros à esquerda na string de saída..seconds
se a diferença puder ser negativa ou superior a 24 horas (o.seconds
atributo ignora.days
). Use.total_seconds()
ou seu analógico.Passar o
timedelta
objeto para astr()
função chama o mesmo código de formatação usado se simplesmente digitarmosprint td
. Como você não deseja os segundos, podemos dividir a sequência por dois pontos (3 partes) e juntá-la novamente apenas com as 2 primeiras partes.fonte
str(my_timedelta)
funciona mal para números negativosfonte
if seconds > period_seconds:
paraif seconds >= period_seconds:
no entanto.Eu pessoalmente uso a
humanize
biblioteca para isso:Obviamente, isso não fornece exatamente a resposta que você estava procurando (que é, de fato,
str(timeA - timeB)
mas eu descobri que, depois que você passa algumas horas, a tela fica rapidamente ilegível.humanize
Tem suporte para valores muito maiores que são legível por humanos e também está bem localizada.É inspirado no
contrib.humanize
módulo do Django , aparentemente, então, como você está usando o Django, você provavelmente deveria usá-lo.fonte
naturaltime
é o que você quer usar.Ele já possui um objeto timedelta, por que não usar seu método interno total_seconds () para convertê-lo em segundos e usar divmod () para obter horas e minutos?
Isso funciona independentemente do delta de tempo ter dias ou anos.
fonte
Aqui está uma função de uso geral para converter um
timedelta
objeto ou um número regular (na forma de segundos ou minutos, etc.) em uma sequência bem formatada. Tomei resposta fantástica de mpounsett sobre uma questão duplicado, fez dele um pouco mais flexível, melhor legibilidade e documentação adicional.Você descobrirá que é a resposta mais flexível aqui até agora, pois permite:
Função:
Demo:
fonte
Sei que essa é uma pergunta antiga respondida, mas uso
datetime.utcfromtimestamp()
para isso. Leva o número de segundos e retorna umdatetime
que pode ser formatado como qualquer outrodatetime
.Contanto que você permaneça nos intervalos legais para os períodos de tempo, isso deve funcionar, ou seja, não retorna 1234: 35, pois as horas são <= 23.
fonte
print timedelta(seconds=end - begin)
lugar..zfill(8)
se você precisar.O interlocutor deseja um formato melhor do que o típico:
Então, realmente existem dois formatos, um em que os dias são 0 e são deixados de fora, e outro em que há o texto "n days, h: m: s". Mas, os segundos podem ter frações e não há zeros à esquerda nas impressões, portanto, as colunas ficam confusas.
Aqui está minha rotina, se você gosta:
isso retorna a saída como dd: hh: mm: ss formato:
Pensei em adicionar anos a isso, mas isso é deixado como um exercício para o leitor, pois a saída é segura em mais de 1 ano:
fonte
Eu consideraria seriamente a abordagem de Occam's Razor aqui:
Isso retorna uma string sem os microssegundos
Se você deseja gerar novamente o objeto datetime.timedelta, faça o seguinte:
2 anos depois, adoro esse idioma!
fonte
Meus
datetime.timedelta
objetos foram maiores que um dia. Então, aqui está outro problema. Toda a discussão acima assume menos de um dia. Atimedelta
é na verdade uma tupla de dias, segundos e microssegundos. A discussão acima deve usartd.seconds
como joe, mas se você tiver dias, NÃO será incluído no valor de segundos.Estou tendo um período de tempo entre duas datas e a impressão de dias e horas.
fonte
Eu usei a
humanfriendly
biblioteca python para fazer isso, funciona muito bem.Disponível em https://pypi.org/project/humanfriendly/
fonte
Seguindo o valor de exemplo de Joe acima, eu usaria o operador aritmético de módulo, assim:
Observe que a divisão inteira no Python é arredondada por padrão; se você quiser ser mais explícito, use math.floor () ou math.ceil () conforme apropriado.
fonte
td.total_seconds()
vez de.seconds
fazê-lo funcionar por intervalos> 1 dia.fonte
timedelta
objeto tem os camposdays
,seconds
emicroseconds
pela documentação.Eu tive um problema semelhante com a saída do cálculo de horas extras no trabalho. O valor sempre deve aparecer em HH: MM, mesmo quando for maior que um dia e o valor puder ficar negativo. Combinei algumas das soluções mostradas e talvez alguém ache essa solução útil. Percebi que, se o valor timedelta for negativo, a maioria das soluções mostradas com o método divmod não funcionará imediatamente:
timedelta para HH: MM string:
fonte
fonte
Um filtro de modelo direto para esse problema. A função interna int () nunca é arredondada. F-Strings (ie f '') requerem python 3.6.
fonte
Isso produzirá:
fonte
Por favor, verifique esta função - ele converte o objeto timedelta na string 'HH: MM: SS'
fonte
Um forro. Como o timedeltas não oferece o tempo de espera do horário de hora de datetime, traga o timedelta de volta para um horário de data e use stftime.
Isso pode não apenas atingir o formato solicitado pelo OP Horas: minutos, agora você pode aproveitar todo o poder de formatação do tempo de transmissão da data e hora, caso seus requisitos mudem para outra representação.
Isso também resolve o aborrecimento que timedeltas são formatados em strings como H: MM: SS em vez de HH: MM: SS, o que me leva a esse problema e à solução que compartilhei.
fonte
Se você já possui um objeto timedelta, basta convertê-lo em string. Remova os três últimos caracteres da sequência e imprima. Isso truncará a parte dos segundos e imprimirá o restante no formato Horas: Minutos.
fonte
print t.split('.')[0]
Se você tem
IPython
em seus pacotes (você deveria), ele tem (até agora, de qualquer maneira) um formatador muito bom por durações (em segundos flutuantes). Isso é usado em vários lugares, por exemplo, pela%%time
magia da célula. Gosto do formato que produz por breves períodos:fonte
Então para:
retorna:
fonte
Obrigado a todos por sua ajuda. Peguei muitas de suas idéias e as reuni, deixe-me saber o que você pensa.
Adicionei dois métodos à classe como este:
No meu django eu usei isso (sum é o objeto e está em um dicionário):
fonte