python-babel / babel

The official repository for Babel, the Python Internationalization Library
http://babel.pocoo.org/
BSD 3-Clause "New" or "Revised" License
1.33k stars 444 forks source link

Multiple units in `format_timedelta()` #728

Open Jackenmen opened 4 years ago

Jackenmen commented 4 years ago

Would it be possible to return more than just one unit for passed timedelta object? For example:

>>> format_timedelta(timedelta(days=2, hours=5, minutes=2, seconds=5), granularity=3)
'2 days, 5 hours, and 2 minutes'

Note: granularity is already used for something else in format_timedelta(), so that kwarg would need to be called differently, I just couldn't think of better name.

samayer12 commented 4 years ago

I'm looking at this in my free time. Looks like a solution could be an extra optional parameter in format_timedelta() within dates.py.

samayer12 commented 4 years ago

I think there's probably a good recursive solution to this. Here's my fork

samayer12 commented 4 years ago

My first crack at the problem can produce some of your desired output. Check out test_format_four_units() in test_dates.py.

However, it doesn't handle instances where the granularity is before the base case of second.

samayer12 commented 4 years ago

Alright, this commit does everything you asked for. Gotta refactor it.

samayer12 commented 4 years ago

^^^ No it definitely does not lol. Still working on my fork. Handling the case where you have granularity of seconds but say, just one week.

Aside from that, I think what I have now is a lot better.

luckydonald commented 3 years ago

I'm not sure what the original intention is, but for me it would be to simply have it actually spell out all the information we have and be exact with that.

That means, if I have a year, one week and 2 minutes, I don't wanna ignore the 2 minutes. Like a exact=True parameter would be what I'm looking for.

Jackenmen commented 3 years ago

That means, if I have a year, one week and 2 minutes, I don't wanna ignore the 2 minutes.

Right now, format_timedelta() in such case would return just 1 year, not 1 year, 1 week or 1 year, 1 week, 2 minutes. So with the use of the granularity kwarg I proposed, it would for example allow you to specify 2 to show at max two units (i.e. 1 year, 1 week).

With what you said in mind, I guess it would also make sense to allow passing some value (-1 perhaps?) which would cause it to show all units without skipping any.

xmo-odoo commented 2 years ago

I'd really like this as well, it's often annoying to have bits at or above granularity cut off in "format_timedelta".

Aside from that, I think what I have now is a lot better.

I can't say I agree with showing intermediate zero-valued steps by default.

Also sadly this is not a backwards-compatible change, so it absolutely needs an additional parameter (or additional granularity values). Especially due to the add_direction flag which most wants rounding.

What I was thinking of is:

If even more complexity / specificity is needed in the precision, it would probably need to be a richer object, possibly the combination of a count and various formatting flags (in which case the "fullest" format might be a precision flag rather than a separate format from "fuller").

luckydonald commented 2 years ago

My requirement is to always show the time as exact as possible, down to the second, but remove empty values. So basically format='fuller' as outlined above by the post before mine

zdens commented 2 years ago

IMHO, in practical use the information should be presented in the required and sufficient amount.

so there should be two options as @xmo-odoo described:

  • an additional format value (e.g. fuller) to show all non-zero steps from top (largest) to bottom (granularity) e.g. format_timedelta(timedelta(days=5, minutes=10), format='fuller') -> "5 days, 10 minutes"
  • maybe a fullest value to show all intermediates (even zero-valued), possibly even all values from top to bottom e.g. format_timedelta(timedelta(days=5, minutes=42), format='fullest') -> "5 days, 10 minutes" -> "5 days, 0 hours, 10 minutes, 0 seconds" (because granularity is seconds)
hartmutobendorf commented 8 months ago

Agree with the previous posts, is there any update on this topic?

Added a PR #1066