lib/active_support/duration.rb in activesupport-6.0.2.2 vs lib/active_support/duration.rb in activesupport-6.0.3.rc1
- old
+ new
@@ -180,38 +180,37 @@
# ActiveSupport::Duration.build(31556952).parts # => {:years=>1}
# ActiveSupport::Duration.build(2716146).parts # => {:months=>1, :days=>1}
#
def build(value)
parts = {}
- remainder = value.to_f
+ remainder = value.round(9)
PARTS.each do |part|
unless part == :seconds
part_in_seconds = PARTS_IN_SECONDS[part]
parts[part] = remainder.div(part_in_seconds)
- remainder = (remainder % part_in_seconds).round(9)
+ remainder %= part_in_seconds
end
- end
+ end unless value == 0
parts[:seconds] = remainder
new(value, parts)
end
private
-
def calculate_total_seconds(parts)
parts.inject(0) do |total, (part, value)|
total + value * PARTS_IN_SECONDS[part]
end
end
end
def initialize(value, parts) #:nodoc:
@value, @parts = value, parts.to_h
@parts.default = 0
- @parts.reject! { |k, v| v.zero? }
+ @parts.reject! { |k, v| v.zero? } unless value == 0
end
def coerce(other) #:nodoc:
case other
when Scalar
@@ -370,11 +369,11 @@
end
alias :until :ago
alias :before :ago
def inspect #:nodoc:
- return "0 seconds" if parts.empty?
+ return "#{value} seconds" if parts.empty?
parts.
sort_by { |unit, _ | PARTS.index(unit) }.
map { |unit, val| "#{val} #{val == 1 ? unit.to_s.chop : unit.to_s}" }.
to_sentence(locale: ::I18n.default_locale)
@@ -397,24 +396,27 @@
def iso8601(precision: nil)
ISO8601Serializer.new(self, precision: precision).serialize
end
private
-
def sum(sign, time = ::Time.current)
- parts.inject(time) do |t, (type, number)|
- if t.acts_like?(:time) || t.acts_like?(:date)
+ unless time.acts_like?(:time) || time.acts_like?(:date)
+ raise ::ArgumentError, "expected a time or date, got #{time.inspect}"
+ end
+
+ if parts.empty?
+ time.since(sign * value)
+ else
+ parts.inject(time) do |t, (type, number)|
if type == :seconds
t.since(sign * number)
elsif type == :minutes
t.since(sign * number * 60)
elsif type == :hours
t.since(sign * number * 3600)
else
t.advance(type => sign * number)
end
- else
- raise ::ArgumentError, "expected a time or date, got #{time.inspect}"
end
end
end
def respond_to_missing?(method, _)