ActiveSupport Duration

When needing to dynamically add or subtract different times and units from a DateTime, you might need to create a Duration. Below you will find short code snippets highlighting how.

Adding Seconds

Let’s consider adding 100 seconds to a date.

total_seconds = 100

date = DateTime.parse('2010-02-01')
 =>  Mon, 01 Feb 2010 00:00:00 +0000

Adding the integer will use the unit days not seconds.

date + total_seconds
 => Mon, 01 Feb 2010 00:01:40 +0000

A common rails idiom is to use the class Numeric’s instance method seconds.

date + total_seconds.seconds
 => Mon, 01 Feb 2010 00:01:40 +0000

If you trace the source code (rails 5.2.1) you will find that .seconds calls the class method seconds on ActiveSupport::Duration. That class method does the following:

def self.seconds(value)
  new(value, [[:seconds, value]])
end

In Short

Instead of using #seconds or #days via the Numeric class, you can create a duration by instantiating ActiveSupport::Duration.

ActiveSupport::Duration.new(100, [[:seconds, 100]])
 => 100 seconds
ActiveSupport::Duration.new(100, { seconds: 100 })
=> 100 seconds
ActiveSupport::Duration.new(5, { months: 5, days: 2 })
=> 5 months and 2 days
ActiveSupport::Duration.new(5, { months: 5, seconds: 4, years: 3, days: 2 })
=> 3 years, 5 months, 2 days, and 4 seconds

Found this useful? Have a suggestion? Get in touch at blog@hocnest.com.