class ActiveSupport::Duration

1.month.ago # equivalent to Time.now.advance(:months => -1)
Example:
Time#advance, respectively. It mainly supports the methods on Numeric.
Provides accurate date and time measurements using Date#advance and

def self.===(other) #:nodoc:

:nodoc:
def self.===(other) #:nodoc:
  other.is_a?(Duration)
rescue ::NoMethodError
  false
end

def +(other)

are treated as seconds.
Adds another Duration or a Numeric to this Duration. Numeric values
def +(other)
  if Duration === other
    Duration.new(value + other.value, @parts + other.parts)
  else
    Duration.new(value + other, @parts + [[:seconds, other]])
  end
end

def -(other)

values are treated as seconds.
Subtracts another Duration or a Numeric from this Duration. Numeric
def -(other)
  self + (-other)
end

def -@ #:nodoc:

:nodoc:
def -@ #:nodoc:
  Duration.new(-value, parts.map { |type,number| [type, -number] })
end

def ==(other)

same value, or if other == value.
Returns true if other is also a Duration instance with the
def ==(other)
  if Duration === other
    other.value == value
  else
    other == value
  end
end

def ago(time = ::Time.current)

as this Duration represents.
Calculates a new Time or Date that is as far in the past
def ago(time = ::Time.current)
  sum(-1, time)
end

def as_json(options = nil) #:nodoc:

:nodoc:
def as_json(options = nil) #:nodoc:
  to_i
end

def initialize(value, parts) #:nodoc:

:nodoc:
def initialize(value, parts) #:nodoc:
  @value, @parts = value, parts
end

def inspect #:nodoc:

:nodoc:
def inspect #:nodoc:
  consolidated = parts.inject(::Hash.new(0)) { |h,part| h[part.first] += part.last; h }
  parts = [:years, :months, :days, :minutes, :seconds].map do |length|
    n = consolidated[length]
    "#{n} #{n == 1 ? length.to_s.singularize : length.to_s}" if n.nonzero?
  end.compact
  parts = ["0 seconds"] if parts.empty?
  parts.to_sentence(:locale => :en)
end

def is_a?(klass) #:nodoc:

:nodoc:
def is_a?(klass) #:nodoc:
  Duration == klass || value.is_a?(klass)
end

def method_missing(method, *args, &block) #:nodoc:

:nodoc:
def method_missing(method, *args, &block) #:nodoc:
  value.send(method, *args, &block)
end

def since(time = ::Time.current)

as this Duration represents.
Calculates a new Time or Date that is as far in the future
def since(time = ::Time.current)
  sum(1, time)
end

def sum(sign, time = ::Time.current) #:nodoc:

:nodoc:
def sum(sign, time = ::Time.current) #:nodoc:
  parts.inject(time) do |t,(type,number)|
    if t.acts_like?(:time) || t.acts_like?(:date)
      if type == :seconds
        t.since(sign * number)
      else
        t.advance(type => sign * number)
      end
    else
      raise ::ArgumentError, "expected a time or date, got #{time.inspect}"
    end
  end
end