Taking a page from @Tadman's answer, I suggest the following.
def doit(duration)
hr, min = (duration/60).divmod(60)
case
when hr == 0 then "#{min} m"
when min == 0 then "#{hr} h"
else "#{hr} h, #{min} m"
end
end
doit 63000 #=> "17 h 30 m"
doit 28800 #=> "8 h"
doit 1800 #=> "30 m"
doit 0 #=> "0 m"
See Integer#divmod (which references Numeric#divmod). For example,
(63000/60).divmod(60) #=> [17, 1800]
#=> [17, 30]
I'll leave my origin answer below for anyone wanting to practice the construction of regular expressions, but I cannot recommend its use in practice, or for that matter, the use of a regular expression generally (or conversion to a Time object).
def doit(duration)
hrs, secs = duration.divmod(3600)
("%d h %d m" % [hrs, secs/60]).gsub(/\A0 h |(?<=h) 0 m\z/, '')
end
doit 63000 #=> "17 h 30 m"
doit 28800 #=> "8 h"
doit 1800 #=> "30 m"
doit 0 #=> ""
I will explain the regular expression below.
Notice that doit 0 above returns an empty string. If it is desired that "0 m" be returned in that case the regular expression can be modified as follows.
def doit(duration)
hrs, secs = duration.divmod(3600)
("%d h %d m" % [hrs, secs/60]).gsub(/\A0 h |(?<=h)(?<!\A0 h) 0 m\z/, '')
end
doit 63000 #=> "17 h 30 m"
doit 28800 #=> "8 h"
doit 1800 #=> "30 m"
doit 0 #=> "0 m"
The second regular expression can be written in free-spacing mode to make it self-documenting.
/
\A # match beginning of string
0[ ]h[ ] # match '0 h '
| # or
(?<=h) # use postive lookbehind to assert the current match is preceded by 'h'
(?<!\A0 h) # use negative lookbehind to assert the current match not preceded by
# '0 h' at the beginning of the string
0[ ]m # match '0 m'
\z # invoke free-spacing regex definition mode
The first regular espression above differs from this one only that it does not contain the negative lookbehind.
When using free-spacing mode the regex engine removes all whitespace outside comments before parsing the expression. Spaces that are part of the expression must therefore be protected. I've done that be put each space in a character class. The are other ways to do that, one being to escape spaces (\ ).