Skip to content

Instantly share code, notes, and snippets.

@odf
Created July 27, 2011 05:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save odf/1108753 to your computer and use it in GitHub Desktop.
Save odf/1108753 to your computer and use it in GitHub Desktop.
Converts time in seconds into English.
module TimeInWords
CONVERSIONS =
[ [:seconds, :years, 31556952], # the average year in the Gregorian calendar
[:seconds, :minutes, 60],
[:minutes, :hours, 60],
[:hours, :days, 24],
[:days, :weeks, 7] ]
UNIT_NAMES =
[ [:years, "year", "years" ],
[:weeks, "week", "weeks" ],
[:days, "day", "days" ],
[:hours, "hour", "hours" ],
[:minutes, "minute", "minutes"],
[:seconds, "second", "seconds"] ]
def in_words(seconds)
units = CONVERSIONS.reduce({ :seconds => seconds }) do |data, conv|
crunch(data, *conv)
end
nonzero = UNIT_NAMES.select do |key, s, p| units[key] > 0 end
parts = nonzero.map do |key, singular, plural|
n = units[key]
"#{n} #{n == 1 ? singular : plural}"
end
case parts.length
when 0
"0 #{UNIT_NAMES.assoc(:seconds)[1]}"
when 1
parts[0]
else
"#{parts[0...-1].join ", "} and #{parts[-1]}"
end
end
private
def crunch(data, smaller_unit, larger_unit, factor)
smaller_amount = data[smaller_unit]
data.merge({
larger_unit => smaller_amount / factor,
smaller_unit => smaller_amount % factor
})
end
end
if __FILE__ == $0
include TimeInWords
puts in_words ARGV[0].to_i
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment