Class: ActiveSupport::Duration
- Defined in:
- lib/active_support/duration.rb,
lib/active_support/duration/iso8601_parser.rb,
lib/active_support/duration/iso8601_serializer.rb
Overview
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)
Defined Under Namespace
Classes: ISO8601Parser, ISO8601Serializer
Constant Summary collapse
- SECONDS_PER_MINUTE =
60
- SECONDS_PER_HOUR =
3600
- SECONDS_PER_DAY =
86400
- SECONDS_PER_WEEK =
604800
- SECONDS_PER_MONTH =
30 days
2592000
- SECONDS_PER_YEAR =
length of a julian year (365.2425 days)
31557600
- 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
Instance Attribute Summary collapse
-
#parts ⇒ Object
Returns the value of attribute parts.
-
#value ⇒ Object
Returns the value of attribute value.
Class Method Summary collapse
-
.===(other) ⇒ Object
:nodoc:.
-
.days(value) ⇒ Object
:nodoc:.
-
.hours(value) ⇒ Object
:nodoc:.
-
.minutes(value) ⇒ Object
:nodoc:.
-
.months(value) ⇒ Object
:nodoc:.
-
.parse(iso8601duration) ⇒ Object
Creates a new Duration from string formatted according to ISO 8601 Duration.
-
.seconds(value) ⇒ Object
:nodoc:.
-
.weeks(value) ⇒ Object
:nodoc:.
-
.years(value) ⇒ Object
:nodoc:.
Instance Method Summary collapse
-
#+(other) ⇒ Object
Adds another Duration or a Numeric to this Duration.
-
#-(other) ⇒ Object
Subtracts another Duration or a Numeric from this Duration.
-
#-@ ⇒ Object
:nodoc:.
-
#==(other) ⇒ Object
Returns
true
ifother
is also a Duration instance with the samevalue
, or ifother == value
. -
#ago(time = ::Time.current) ⇒ Object
(also: #until)
Calculates a new Time or Date that is as far in the past as this Duration represents.
-
#as_json(options = nil) ⇒ Object
:nodoc:.
-
#eql?(other) ⇒ Boolean
Returns
true
ifother
is also a Duration instance, which has the same parts as this one. - #hash ⇒ Object
-
#initialize(value, parts) ⇒ Duration
constructor
:nodoc:.
-
#inspect ⇒ Object
:nodoc:.
-
#instance_of?(klass) ⇒ Boolean
:nodoc:.
-
#is_a?(klass) ⇒ Boolean
(also: #kind_of?)
:nodoc:.
-
#iso8601(precision: nil) ⇒ Object
Build ISO 8601 Duration string for this duration.
-
#respond_to_missing?(method, include_private = false) ⇒ Boolean
:nodoc:.
-
#since(time = ::Time.current) ⇒ Object
(also: #from_now)
Calculates a new Time or Date that is as far in the future as this Duration represents.
-
#to_i ⇒ Object
Returns the number of seconds that this Duration represents.
-
#to_s ⇒ Object
Returns the amount of seconds a duration covers as a string.
Constructor Details
#initialize(value, parts) ⇒ Duration
:nodoc:
86 87 88 |
# File 'lib/active_support/duration.rb', line 86 def initialize(value, parts) #:nodoc: @value, @parts = value, parts end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args, &block) ⇒ Object (private)
:nodoc:
231 232 233 |
# File 'lib/active_support/duration.rb', line 231 def method_missing(method, *args, &block) #:nodoc: value.send(method, *args, &block) end |
Instance Attribute Details
#parts ⇒ Object
Returns the value of attribute parts.
27 28 29 |
# File 'lib/active_support/duration.rb', line 27 def parts @parts end |
#value ⇒ Object
Returns the value of attribute value.
27 28 29 |
# File 'lib/active_support/duration.rb', line 27 def value @value end |
Class Method Details
.===(other) ⇒ Object
:nodoc:
43 44 45 46 47 |
# File 'lib/active_support/duration.rb', line 43 def ===(other) #:nodoc: other.is_a?(Duration) rescue ::NoMethodError false end |
.days(value) ⇒ Object
:nodoc:
61 62 63 |
# File 'lib/active_support/duration.rb', line 61 def days(value) #:nodoc: new(value * SECONDS_PER_DAY, [[:days, value]]) end |
.hours(value) ⇒ Object
:nodoc:
57 58 59 |
# File 'lib/active_support/duration.rb', line 57 def hours(value) #:nodoc: new(value * SECONDS_PER_HOUR, [[:hours, value]]) end |
.minutes(value) ⇒ Object
:nodoc:
53 54 55 |
# File 'lib/active_support/duration.rb', line 53 def minutes(value) #:nodoc: new(value * SECONDS_PER_MINUTE, [[:minutes, value]]) end |
.months(value) ⇒ Object
:nodoc:
69 70 71 |
# File 'lib/active_support/duration.rb', line 69 def months(value) #:nodoc: new(value * SECONDS_PER_MONTH, [[:months, value]]) end |
.parse(iso8601duration) ⇒ Object
Creates a new Duration from string formatted according to ISO 8601 Duration.
See ISO 8601 for more information. This method allows negative parts to be present in pattern. If invalid string is provided, it will raise ActiveSupport::Duration::ISO8601Parser::ParsingError
.
38 39 40 41 |
# File 'lib/active_support/duration.rb', line 38 def parse(iso8601duration) parts = ISO8601Parser.new(iso8601duration).parse! new(calculate_total_seconds(parts), parts) end |
.seconds(value) ⇒ Object
:nodoc:
49 50 51 |
# File 'lib/active_support/duration.rb', line 49 def seconds(value) #:nodoc: new(value, [[:seconds, value]]) end |
.weeks(value) ⇒ Object
:nodoc:
65 66 67 |
# File 'lib/active_support/duration.rb', line 65 def weeks(value) #:nodoc: new(value * SECONDS_PER_WEEK, [[:weeks, value]]) end |
.years(value) ⇒ Object
:nodoc:
73 74 75 |
# File 'lib/active_support/duration.rb', line 73 def years(value) #:nodoc: new(value * SECONDS_PER_YEAR, [[:years, value]]) end |
Instance Method Details
#+(other) ⇒ Object
Adds another Duration or a Numeric to this Duration. Numeric values are treated as seconds.
92 93 94 95 96 97 98 |
# File 'lib/active_support/duration.rb', line 92 def +(other) if Duration === other Duration.new(value + other.value, @parts + other.parts) else Duration.new(value + other, @parts + [[:seconds, other]]) end end |
#-(other) ⇒ Object
Subtracts another Duration or a Numeric from this Duration. Numeric values are treated as seconds.
102 103 104 |
# File 'lib/active_support/duration.rb', line 102 def -(other) self + (-other) end |
#-@ ⇒ Object
:nodoc:
106 107 108 |
# File 'lib/active_support/duration.rb', line 106 def -@ #:nodoc: Duration.new(-value, parts.map { |type,number| [type, -number] }) end |
#==(other) ⇒ Object
Returns true
if other
is also a Duration instance with the same value
, or if other == value
.
121 122 123 124 125 126 127 |
# File 'lib/active_support/duration.rb', line 121 def ==(other) if Duration === other other.value == value else other == value end end |
#ago(time = ::Time.current) ⇒ Object Also known as: until
Calculates a new Time or Date that is as far in the past as this Duration represents.
180 181 182 |
# File 'lib/active_support/duration.rb', line 180 def ago(time = ::Time.current) sum(-1, time) end |
#as_json(options = nil) ⇒ Object
:nodoc:
193 194 195 |
# File 'lib/active_support/duration.rb', line 193 def as_json( = nil) #:nodoc: to_i end |
#eql?(other) ⇒ Boolean
Returns true
if other
is also a Duration instance, which has the same parts as this one.
163 164 165 |
# File 'lib/active_support/duration.rb', line 163 def eql?(other) Duration === other && other.value.eql?(value) end |
#hash ⇒ Object
167 168 169 |
# File 'lib/active_support/duration.rb', line 167 def hash @value.hash end |
#inspect ⇒ Object
:nodoc:
185 186 187 188 189 190 191 |
# File 'lib/active_support/duration.rb', line 185 def inspect #:nodoc: parts. 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) end |
#instance_of?(klass) ⇒ Boolean
:nodoc:
115 116 117 |
# File 'lib/active_support/duration.rb', line 115 def instance_of?(klass) # :nodoc: Duration == klass || value.instance_of?(klass) end |
#is_a?(klass) ⇒ Boolean Also known as: kind_of?
:nodoc:
110 111 112 |
# File 'lib/active_support/duration.rb', line 110 def is_a?(klass) #:nodoc: Duration == klass || value.is_a?(klass) end |
#iso8601(precision: nil) ⇒ Object
Build ISO 8601 Duration string for this duration. The precision
parameter can be used to limit seconds’ precision of duration.
203 204 205 |
# File 'lib/active_support/duration.rb', line 203 def iso8601(precision: nil) ISO8601Serializer.new(self, precision: precision).serialize end |
#respond_to_missing?(method, include_private = false) ⇒ Boolean
:nodoc:
197 198 199 |
# File 'lib/active_support/duration.rb', line 197 def respond_to_missing?(method, include_private=false) #:nodoc: @value.respond_to?(method, include_private) end |
#since(time = ::Time.current) ⇒ Object Also known as: from_now
Calculates a new Time or Date that is as far in the future as this Duration represents.
173 174 175 |
# File 'lib/active_support/duration.rb', line 173 def since(time = ::Time.current) sum(1, time) end |
#to_i ⇒ Object
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 30 days and years are 365.25 days:
# equivalent to 30.days.to_i
1.month.to_i # => 2592000
# equivalent to 365.25.days.to_i
1.year.to_i # => 31557600
In such cases, Ruby’s core Date and Time should be used for precision date and time arithmetic.
157 158 159 |
# File 'lib/active_support/duration.rb', line 157 def to_i @value.to_i end |
#to_s ⇒ Object
Returns the amount of seconds a duration covers as a string. For more information check to_i method.
1.day.to_s # => "86400"
133 134 135 |
# File 'lib/active_support/duration.rb', line 133 def to_s @value.to_s end |