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.rb33
1 files changed, 19 insertions, 14 deletions
diff --git a/activesupport/lib/active_support/duration.rb b/activesupport/lib/active_support/duration.rb
index 6ec0c3a70a..c9e8c8fdc4 100644
--- a/activesupport/lib/active_support/duration.rb
+++ b/activesupport/lib/active_support/duration.rb
@@ -7,22 +7,30 @@ module ActiveSupport
#
# 1.month.ago # equivalent to Time.now.advance(months: -1)
class Duration
+ EPOCH = ::Time.utc(2000)
+
attr_accessor :value, :parts
autoload :ISO8601Parser, "active_support/duration/iso8601_parser"
autoload :ISO8601Serializer, "active_support/duration/iso8601_serializer"
def initialize(value, parts) #:nodoc:
- @value, @parts = value, parts
+ @value, @parts = value, parts.to_h
+ @parts.default = 0
end
# Adds another Duration or a Numeric to this Duration. Numeric values
# are treated as seconds.
def +(other)
if Duration === other
- Duration.new(value + other.value, @parts + other.parts)
+ parts = @parts.dup
+ other.parts.each do |(key, value)|
+ parts[key] += value
+ end
+ Duration.new(value + other.value, parts)
else
- Duration.new(value + other, @parts + [[:seconds, other]])
+ seconds = @parts[:seconds] + other
+ Duration.new(value + other, @parts.merge(seconds: seconds))
end
end
@@ -33,7 +41,7 @@ module ActiveSupport
end
def -@ #:nodoc:
- Duration.new(-value, parts.map { |type,number| [type, -number] })
+ Duration.new(-value, parts.map { |type, number| [type, -number] })
end
def is_a?(klass) #:nodoc:
@@ -119,7 +127,7 @@ module ActiveSupport
def inspect #:nodoc:
parts.
- reduce(::Hash.new(0)) { |h,(l,r)| h[l] += r; h }.
+ reduce(::Hash.new(0)) { |h, (l, r)| h[l] += r; h }.
sort_by { |unit, _ | [:years, :months, :weeks, :days, :hours, :minutes, :seconds].index(unit) }.
map { |unit, val| "#{val} #{val == 1 ? unit.to_s.chop : unit.to_s}" }.
to_sentence(locale: ::I18n.default_locale)
@@ -129,7 +137,7 @@ module ActiveSupport
to_i
end
- def respond_to_missing?(method, include_private=false) #:nodoc:
+ def respond_to_missing?(method, include_private = false) #:nodoc:
@value.respond_to?(method, include_private)
end
@@ -140,8 +148,7 @@ module ActiveSupport
# If invalid string is provided, it will raise +ActiveSupport::Duration::ISO8601Parser::ParsingError+.
def self.parse(iso8601duration)
parts = ISO8601Parser.new(iso8601duration).parse!
- time = ::Time.current
- new(time.advance(parts) - time, parts)
+ new(EPOCH.advance(parts) - EPOCH, parts)
end
# Build ISO 8601 Duration string for this duration.
@@ -152,10 +159,10 @@ module ActiveSupport
delegate :<=>, to: :value
- protected
+ private
- def sum(sign, time = ::Time.current) #:nodoc:
- parts.inject(time) do |t,(type,number)|
+ def sum(sign, time = ::Time.current)
+ parts.inject(time) do |t, (type, number)|
if t.acts_like?(:time) || t.acts_like?(:date)
if type == :seconds
t.since(sign * number)
@@ -172,9 +179,7 @@ module ActiveSupport
end
end
- private
-
- def method_missing(method, *args, &block) #:nodoc:
+ def method_missing(method, *args, &block)
value.send(method, *args, &block)
end
end