ruby 36 lines · 7 steps

Turning seconds into human-readable durations in Ruby

A module that converts a raw second count into phrases like "2 hours and 5 minutes ago" by greedily peeling off the largest units.

Explained by highlit
1module DurationFormatter
2 UNITS = [
3 ['week', 604_800],
4 ['day', 86_400],
5 ['hour', 3_600],
6 ['minute', 60],
7 ['second', 1]
8 ].freeze
9 
10 module_function
11 
12 def humanize(seconds, max_parts: 2)
13 seconds = seconds.round
14 return 'just now' if seconds.zero?
15 
16 sign = seconds.negative? ? 'ago' : nil
17 remaining = seconds.abs
18 parts = []
19 
20 UNITS.each do |name, size|
21 next if remaining < size
22 
23 count = remaining / size
24 remaining %= size
25 parts << pluralize(count, name)
26 break if parts.size == max_parts
27 end
28 
29 phrase = parts.join(' and ')
30 sign ? "#{phrase} #{sign}" : phrase
31 end
32 
33 def pluralize(count, unit)
34 "#{count} #{unit}#{'s' unless count == 1}"
35 end
36end
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Ordering units from largest to smallest lets a single pass greedily decompose a quantity.
  2. 2Integer division and modulo together split a remainder into a count and what's left over.
  3. 3Capturing the sign early and reapplying it at the end keeps the core loop working on a clean absolute value.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Turning seconds into human-readable durations in Ruby — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code