aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib/active_support/duration.rb
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport/lib/active_support/duration.rb')
-rw-r--r--activesupport/lib/active_support/duration.rb60
1 files changed, 35 insertions, 25 deletions
diff --git a/activesupport/lib/active_support/duration.rb b/activesupport/lib/active_support/duration.rb
index fd9b505c2f..cbee4fd0ca 100644
--- a/activesupport/lib/active_support/duration.rb
+++ b/activesupport/lib/active_support/duration.rb
@@ -6,11 +6,11 @@ module ActiveSupport
# 1.month.ago # equivalent to Time.now.advance(:months => -1)
class Duration < BasicObject
attr_accessor :value, :parts
-
+
def initialize(value, parts) #:nodoc:
@value, @parts = value, parts
end
-
+
# Adds another Duration or a Numeric to this Duration. Numeric values
# are treated as seconds.
def +(other)
@@ -20,39 +20,49 @@ module ActiveSupport
Duration.new(value + other, @parts + [[:seconds, other]])
end
end
-
+
# Subtracts another Duration or a Numeric from this Duration. Numeric
# values are treated as seconds.
def -(other)
self + (-other)
end
-
+
def -@ #:nodoc:
Duration.new(-value, parts.map { |type,number| [type, -number] })
end
-
+
def is_a?(klass) #:nodoc:
klass == Duration || super
end
-
+
+ # Returns true if <tt>other</tt> is also a Duration instance with the
+ # same <tt>value</tt>, or if <tt>other == value</tt>.
+ def ==(other)
+ if Duration === other
+ other.value == value
+ else
+ other == value
+ end
+ end
+
def self.===(other) #:nodoc:
other.is_a?(Duration) rescue super
end
-
+
# Calculates a new Time or Date that is as far in the future
# as this Duration represents.
def since(time = ::Time.now)
sum(1, time)
end
alias :from_now :since
-
+
# Calculates a new Time or Date that is as far in the past
# as this Duration represents.
def ago(time = ::Time.now)
sum(-1, time)
end
alias :until :ago
-
+
def inspect #:nodoc:
consolidated = parts.inject(Hash.new(0)) { |h,part| h[part.first] += part.last; h }
[:years, :months, :days, :minutes, :seconds].map do |length|
@@ -60,27 +70,27 @@ module ActiveSupport
"#{n} #{n == 1 ? length.to_s.singularize : length.to_s}" if n.nonzero?
end.compact.to_sentence
end
-
+
protected
-
- def sum(sign, time = ::Time.now) #:nodoc:
- parts.inject(time) do |t,(type,number)|
- if t.acts_like?(:time) || t.acts_like?(:date)
- if type == :seconds
- t.since(sign * number)
+
+ def sum(sign, time = ::Time.now) #: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
- t.advance(type => sign * number)
+ raise ArgumentError, "expected a time or date, got #{time.inspect}"
end
- else
- raise ArgumentError, "expected a time or date, got #{time.inspect}"
end
end
- end
-
+
private
-
- def method_missing(method, *args, &block) #:nodoc:
- value.send(method, *args)
- end
+
+ def method_missing(method, *args, &block) #:nodoc:
+ value.send(method, *args)
+ end
end
end