Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Negative amounts of time result in a day from naturaldelta #171

Closed
couling opened this issue Feb 21, 2024 · 2 comments · Fixed by #173
Closed

Negative amounts of time result in a day from naturaldelta #171

couling opened this issue Feb 21, 2024 · 2 comments · Fixed by #173
Labels
bug Something isn't working

Comments

@couling
Copy link

couling commented Feb 21, 2024

What did you do?

from humanize import naturaldelta
from datetime import datetime

print(naturaldelta(datetime.now() - datetime.now()))

What did you expect to happen?

a moment

Or some reasonable representation of the tiny amount of time between two consecutive now() calls.

What actually happened?

a day

What versions are you using?

  • OS: Macos
  • Python: 3.10
  • Humanize: 4.9.0
@couling couling changed the title Tiny negative amounts of time result in a day Tiny negative amounts of time result in a day from naturaldelta Feb 21, 2024
@hugovk hugovk added the bug Something isn't working label Feb 21, 2024
@hugovk
Copy link
Member

hugovk commented Feb 21, 2024

Hmm, this is because, when we get the delta between them both here:

if isinstance(value, dt.timedelta):
delta = value

It's really something like:

delta=datetime.timedelta(days=-1, seconds=86399, microseconds=999999)

This looks quite strange, and the docs explain:

String representations of timedelta objects are normalized similarly to their internal representation. This leads to somewhat unusual results for negative timedeltas. For example:

>>> timedelta(hours=-5)
datetime.timedelta(days=-1, seconds=68400)
>>> print(_)
-1 day, 19:00:00

However, we're assuming this oddness doesn't happen and find the absolute values of some delta components:

seconds = abs(delta.seconds)
days = abs(delta.days)

When we do abs(day), it must be because we don't really care if the delta as a whole is positive or negative. We assume all components have the same sign. But we fall into this oddness trap.

And then days < 1 is false:

if not years and days < 1:

And abs(delta.days) == days == 1 is true, so return "a day":

elif years == 0:
if days == 1:
return _("a day")

Really, we should have gone into the first if.

I think doing delta = abs(delta) instead of, or just before, the other abs calls might fix it.

@couling
Copy link
Author

couling commented Feb 22, 2024

abs certainly helped in the examples I found:

print(naturaldelta(abs(datetime.now() - datetime.now())))

That seemed to be a valid work-around for the time being.

@hugovk hugovk changed the title Tiny negative amounts of time result in a day from naturaldelta Negative amounts of time result in a day from naturaldelta Feb 25, 2024
@hugovk hugovk closed this as completed in 218a86e Feb 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants