Active Support Duration
Provides accurate date and time measurements using Date#advance
and Time#advance
, respectively. It mainly supports the methods on Numeric
.
1.month.ago # equivalent to Time.now.advance(months: -1)
- #
- A
- B
- E
- F
- H
- I
- P
- S
- T
- U
Constants
PARTS | = | [:years, :months, :weeks, :days, :hours, :minutes, :seconds].freeze |
PARTS_IN_SECONDS | = | { seconds: 1, minutes: SECONDS_PER_MINUTE, hours: SECONDS_PER_HOUR, days: SECONDS_PER_DAY, weeks: SECONDS_PER_WEEK, months: SECONDS_PER_MONTH, years: SECONDS_PER_YEAR }.freeze |
SECONDS_PER_DAY | = | 86400 |
SECONDS_PER_HOUR | = | 3600 |
SECONDS_PER_MINUTE | = | 60 |
SECONDS_PER_MONTH | = | 2629746 |
SECONDS_PER_WEEK | = | 604800 |
SECONDS_PER_YEAR | = | 31556952 |
VARIABLE_PARTS | = | [:years, :months, :weeks, :days].freeze |
Attributes
[R] | value |
Class Public methods
build(value) Link
Creates a new Duration
from a seconds value that is converted to the individual parts:
ActiveSupport::Duration.build(31556952).parts # => {:years=>1}
ActiveSupport::Duration.build(2716146).parts # => {:months=>1, :days=>1}
# File activesupport/lib/active_support/duration.rb, line 189 def build(value) unless value.is_a?(::Numeric) raise TypeError, "can't build an #{self.name} from a #{value.class.name}" end parts = {} remainder_sign = value <=> 0 remainder = value.round(9).abs variable = false PARTS.each do |part| unless part == :seconds part_in_seconds = PARTS_IN_SECONDS[part] parts[part] = remainder.div(part_in_seconds) * remainder_sign remainder %= part_in_seconds unless parts[part].zero? variable ||= VARIABLE_PARTS.include?(part) end end end unless value == 0 parts[:seconds] = remainder * remainder_sign new(value, parts, variable) end
parse(iso8601duration) Link
Instance Public methods
%(other) Link
*(other) Link
# File activesupport/lib/active_support/duration.rb, line 287 def *(other) if Scalar === other || Duration === other Duration.new(value * other.value, @parts.transform_values { |number| number * other.value }, @variable || other.variable?) elsif Numeric === other Duration.new(value * other, @parts.transform_values { |number| number * other }, @variable) else raise_type_error(other) end end
+(other) Link
# File activesupport/lib/active_support/duration.rb, line 268 def +(other) if Duration === other parts = @parts.merge(other._parts) do |_key, value, other_value| value + other_value end Duration.new(value + other.value, parts, @variable || other.variable?) else seconds = @parts.fetch(:seconds, 0) + other Duration.new(value + other, @parts.merge(seconds: seconds), @variable) end end
-(other) Link
/(other) Link
# File activesupport/lib/active_support/duration.rb, line 298 def /(other) if Scalar === other Duration.new(value / other.value, @parts.transform_values { |number| number / other.value }, @variable) elsif Duration === other value / other.value elsif Numeric === other Duration.new(value / other, @parts.transform_values { |number| number / other }, @variable) else raise_type_error(other) end end
<=>(other) Link
==(other) Link
Returns true
if other
is also a Duration
instance with the same value
, or if other == value
.
ago(time = ::Time.current) Link
eql?(other) Link
Returns true
if other
is also a Duration
instance, which has the same parts as this one.
hash() Link
in_days() Link
Returns the amount of days a duration covers as a float
12.hours.in_days # => 0.5
in_hours() Link
Returns the amount of hours a duration covers as a float
1.day.in_hours # => 24.0
in_minutes() Link
Returns the amount of minutes a duration covers as a float
1.day.in_minutes # => 1440.0
in_months() Link
Returns the amount of months a duration covers as a float
9.weeks.in_months # => 2.07
in_weeks() Link
Returns the amount of weeks a duration covers as a float
2.months.in_weeks # => 8.696
in_years() Link
Returns the amount of years a duration covers as a float
30.days.in_years # => 0.082
iso8601(precision: nil) Link
Build ISO 8601 Duration
string for this duration. The precision
parameter can be used to limit seconds’ precision of duration.
parts() Link
Returns a copy of the parts hash that defines the duration.
5.minutes.parts # => {:minutes=>5}
3.years.parts # => {:years=>3}
since(time = ::Time.current) Link
to_i() Link
Returns the number of seconds that this Duration
represents.
1.minute.to_i # => 60
1.hour.to_i # => 3600
1.day.to_i # => 86400
Note that this conversion makes some assumptions about the duration of some periods, e.g. months are always 1/12 of year and years are 365.2425 days:
# equivalent to (1.year / 12).to_i
1.month.to_i # => 2629746
# equivalent to 365.2425.days.to_i
1.year.to_i # => 31556952
In such cases, Ruby’s core Date and Time should be used for precision date and time arithmetic.