Solucionado (ver solução)
Solucionado
(ver solução)
5
respostas

Comportamento estranho do datetime na subtração

No curso, a subtração chegou a zero (0:00:00), mas o meu código está dando um valor diferente.

Código em Python:

from datetime import datetime, timedelta

today = datetime.today()
tomorrow = datetime.today()
print(today)
print(tomorrow)
print(today - tomorrow)

Resultado:

2021-01-18 23:00:13.378847
2021-01-18 23:00:13.378908
-1 day, 23:59:59.999939
  • Python: 3.9.1
  • PyCharm Community: 2020.3.2

O resultado apareceu tanto no Google Colab quanto no mey PyCharm. Qual pode ser o motivo disso?

5 respostas

Eu acho engraçado que eu troquei a ordem da operação, e o resultado faz sentido com os valores:

print(tomorrow - today)
# 2021-01-18 23:13:04.530599
# 2021-01-18 23:13:04.530629
# 0:00:00.000030

Não mostra days de diferença, e nem que está em 23.59.

Como esse resultado faz sentido, mudando o lado da operação, eu esperaria ver - 0:00:00.000030. Por estar só X tempo atrás.

O resultado anterior faz parecer que tem quase 2 dias de diferença entre eles >.< ( -1 day, 23:59:59.999939)

solução!

Bom dia, Klaus!

O que acontece é que o método today() do datetime pega o horário no exato momento em que a linha roda. Então o today pegou um valor e o tomorrow pegou outro valor milésimos de segundos após o today, visto que essa linha rodou em sequência à anterior. Portanto, devido a precisão destes números, o resultado nunca será 0.

E por que a subtração do primeiro caso deu -1 day, 23:59:59.999939 e a segunda deu 0:00:00.000030?

Um datetime possui um padrão de representação. Ele consegue representar dias negativos, meses negativos e anos negativos, porém nunca representa tempo negativo. Desta forma, quando há uma operação que resulte num datetime com tempo negativo, essa biblioteca gera o complemento do tempo e joga o negativo para as datas.

No primeiro caso, a operação "2021-01-18 23:00:13.378847" - "2021-01-18 23:00:13.378908" resultaria em 0 days -00:00:00061. Porém, como ele não representa horas negativas, ele subtrai 1 ao número de dias e soma 24h nas horas (uma operação que não muda o valor final, visto que 24h - 1 dia = 0). Desta forma, o resultado é o que vemos, -1 day, 23:59:59.999939. A leitura correta deste valor é menos 1 dia e mais 23:59:59.999939 horas. Se você transformar o -1 dia em -24 horas, verá que a soma dos dois valores resultará em exatamente 0 days -00:00:00061, nosso valor inicial!

Tendo isso em mente, o resultado do segundo caso (invertendo a ordem da subtração) começa a fazer sentido também. Como a subtração agora resulta em um tempo positivo, o resultado é simplesmente mostrado no formato de tempo, sem ter um complemento de datas 0:00:00.000030.

Espero ter ajudado! Essa questão pode ser bem confusa se não tiver esse conhecimento do funcionamento do datetime, mas depois que você tem essa noção acaba ficando mais simples de entender. Qualquer dúvida a mais pode mandar ai!

Boa tarde Gian.

Muito obrigado. Me ajudou muito. Agora entendi porque ele é representado dessa forma.

Quando tem esses casos, quais são as soluções que a comunidade dá? Usam uma biblioteca, ou a linguágem em si já preve esses casos e já tem formas de lidar com esses dados?

É uma boa pergunta. Eu não tenho certeza, acho que depende muito de cada caso. O que eu acho que eu faria seria fazer uma verificação se a subtração resultaria num tempo negativo e usaria módulo, adicionando eu mesmo na representação o símbolo de negativo. Mas eu realmente não sei dizer qual a melhor prática, hahaha.

Ah, tranquilo hehe. Então devo continuar a busca depois.