babel icon indicating copy to clipboard operation
babel copied to clipboard

Multiple units in `format_timedelta()`

Open Jackenmen opened this issue 5 years ago • 11 comments

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.

Jackenmen avatar Sep 20 '20 16:09 Jackenmen

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 avatar Oct 30 '20 03:10 samayer12

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

samayer12 avatar Oct 30 '20 04:10 samayer12

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 avatar Oct 30 '20 05:10 samayer12

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

samayer12 avatar Oct 31 '20 02:10 samayer12

^^^ 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.

samayer12 avatar Nov 02 '20 07:11 samayer12

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.

luckydonald avatar Feb 06 '21 19:02 luckydonald

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.

Jackenmen avatar Feb 06 '21 19:02 Jackenmen

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:

  • 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)
  • if desiring a level of precision e.g. more than one units but less than "everything up to granularity", an additional precision keyword could be used, which would specify how many units to display, similar to the precision in number formatting. So format_timedelta(timedelta(days=5, minutes=10), format='fullest', precision=2) => "5 days, 0 hours", and format_timedelta(timedelta(days=5, minutes=10), format='fuller', precision=2) => "5 days, 10 minutes" (the skipped 0-valued hours is ignored by the precision).

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").

xmo-odoo avatar Feb 16 '22 11:02 xmo-odoo

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

luckydonald avatar Feb 17 '22 11:02 luckydonald

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)

zdens avatar Apr 18 '22 16:04 zdens

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

Added a PR #1066

hartmutobendorf avatar Feb 21 '24 14:02 hartmutobendorf