Formatting ActiveSupport::Duration Objects in Rails

Formatting ActiveSupport::Duration Objects in Rails


rails activesupport helpers
Last updated on

Rails’ ActiveSupport::Duration objects don’t include a straightforward way to output clean, human-readable strings. By default, you’re left with #inspect, which is limited and lost locale support after Rails 5.1.


A Manual Helper

You could roll your own helper in a view:

def duration_as_sentence(duration)
  parts = duration.parts
  units = [:days, :hours, :minutes]
  map   = {
    days:    { one: :d },
    hours:   { one: :h, other: :hrs },
    minutes: { one: :m, other: :mins }
  }

  parts.
    sort_by { |unit, _| units.index(unit) }.
    map { |unit, val| "#{val} #{val == 1 ? map[unit][:one] : map[unit][:other]}" }.
    to_sentence
end

This works, but it’s limited, not very configurable, and ignores localization.


Introducing duration_in_words

To address this, I built a small gem called duration_in_words. It provides a view helper that formats ActiveSupport::Duration objects into concise, localized strings like:

include ActionView::Helpers::DurationHelper

>> duration = 2.hours
>> duration_in_words(duration)
=> "2h"

>> duration = 1.day + 2.hours + 30.minutes
>> duration_in_words(duration)
=> "1d 2h and 30m"

Formatting Options

:format option

Two formats are supported: :compact (default) and :full.

de:
  duration:
    in_words:
      format:
        compact:
          hours:
            one: '%{count}Std.'
            other: '%{count}Std.'
          minutes:
            one: '%{count}Min'
            other: '%{count}Min'
          seconds:
            one: '%{count}s'
            other: '%{count}s'
          support:
            words_connector: ' '
            two_words_connector: ' und '
            last_word_connector: ' und '

Usage:

duration = 1.day + 2.hours + 30.minutes

duration_in_words(duration, locale: :de)
# => "1T 2Std. und 30s"

duration_in_words(duration, format: :full, locale: :de)
# => "1 Tag, 2 Std., und 30 Sekunden"

Wrap-up

When you need to report durations in a user-friendly way, duration_in_words provides a clean, configurable, and locale-aware solution. It’s a big improvement over the default #inspect output and saves you from reinventing formatting helpers.


You might also like

© 2025 Syed Aslam