# Convert time interval to mixed units without leading zeros

Let's say I have time intervals in seconds. I am looking for a method that produces the following conversions:

3660 => 1 hour 1 minute 0 seconds
1810 => 30 minutes 10 seconds (not 0 hours 30 minutes 10 seconds)

I should be able to specify the set of units(e.g. adding days or milliseconds, not just HMS).

foo[s_] := #[[;; , {1}, FirstPosition[#[[1, 1]], Except[0], {0},
Heads -> False][[1]] ;;]] & @
UnitConvert[Quantity[s, "Seconds"], MixedUnit[{"Hours", "Minutes", "Seconds"}]]

foo /@ {5000, 3000, 10}


• I have no clue what happens before the @, but that is the correct answer. Oct 3, 2018 at 0:02
• I've hit a liiitle snag. I actually did want it spelled out, rather than getting a Quantity instance in the end. Of course it's easy to add a ToString call, but when my value is less than 60, Mathematica hits the recursion limit. E.g. this produces infinite recursion: ToString[Quantity[20, MixedUnit[{"Seconds"}]]]. It seems to happen when MixedUnit is called with only 1 unit. Could this be a bug? Oct 3, 2018 at 1:06
• I've discovered that this function behaves oddly/wrong with machine precision numbers. Compare foo[600.] to UnitConvert[Quantity[600., "Seconds"], MixedUnit[{"Minutes", "Seconds"}]]. Oct 3, 2018 at 3:45
• @martixy I don't like this code either :) will try to address your comments later. Don't have time now.
– Kuba
Oct 3, 2018 at 8:20
• Getting a displayable format is fairly easy: ToString[QuantityForm[unitValue, "Abbreviation"]]. The precision problem... not so much. One option is to coerce the value to what you need. The other, simpler one is to just Round[] it, if integer precision is enough. But I don't have anything better than conditionally covering edge cases. Oct 3, 2018 at 8:38