Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 109 lines (92 sloc) 2.994 kb
49752e6 @jeremy Duration requires BasicObject in case it's autoloaded early
jeremy authored
1 require 'active_support/basic_object'
f28bd95 @jeremy Fix dependencies revealed by testing in isolation
jeremy authored
2 require 'active_support/core_ext/array/conversions'
f15313c @fxn duration.rb needs active_support/core_ext/object/acts_like
fxn authored
3 require 'active_support/core_ext/object/acts_like'
49752e6 @jeremy Duration requires BasicObject in case it's autoloaded early
jeremy authored
4
276c9f2 @NZKoz Make 1.months and friends accurate by introducing a Duration class. #68...
NZKoz authored
5 module ActiveSupport
b451de0 @spastorino Deletes trailing whitespaces (over text files only find * -type f -exec ...
spastorino authored
6 # Provides accurate date and time measurements using Date#advance and
8429e7b @neerajdotname making comments sentence more concise
neerajdotname authored
7 # Time#advance, respectively. It mainly supports the methods on Numeric.
276c9f2 @NZKoz Make 1.months and friends accurate by introducing a Duration class. #68...
NZKoz authored
8 #
d71d5ba @frodsan update AS docs [ci skip]
frodsan authored
9 # 1.month.ago # equivalent to Time.now.advance(months: -1)
34b5767 @jeremy Introduce BasicObject as Builder::BlankSlate for Ruby 1.9 forward compat...
jeremy authored
10 class Duration < BasicObject
276c9f2 @NZKoz Make 1.months and friends accurate by introducing a Duration class. #68...
NZKoz authored
11 attr_accessor :value, :parts
887870f @jeremy Ruby 1.9 compat: define Duration#== [chuyeow]
jeremy authored
12
276c9f2 @NZKoz Make 1.months and friends accurate by introducing a Duration class. #68...
NZKoz authored
13 def initialize(value, parts) #:nodoc:
14 @value, @parts = value, parts
15 end
887870f @jeremy Ruby 1.9 compat: define Duration#== [chuyeow]
jeremy authored
16
276c9f2 @NZKoz Make 1.months and friends accurate by introducing a Duration class. #68...
NZKoz authored
17 # Adds another Duration or a Numeric to this Duration. Numeric values
18 # are treated as seconds.
19 def +(other)
20 if Duration === other
21 Duration.new(value + other.value, @parts + other.parts)
22 else
23 Duration.new(value + other, @parts + [[:seconds, other]])
24 end
25 end
887870f @jeremy Ruby 1.9 compat: define Duration#== [chuyeow]
jeremy authored
26
276c9f2 @NZKoz Make 1.months and friends accurate by introducing a Duration class. #68...
NZKoz authored
27 # Subtracts another Duration or a Numeric from this Duration. Numeric
28 # values are treated as seconds.
29 def -(other)
30 self + (-other)
31 end
887870f @jeremy Ruby 1.9 compat: define Duration#== [chuyeow]
jeremy authored
32
276c9f2 @NZKoz Make 1.months and friends accurate by introducing a Duration class. #68...
NZKoz authored
33 def -@ #:nodoc:
34 Duration.new(-value, parts.map { |type,number| [type, -number] })
35 end
887870f @jeremy Ruby 1.9 compat: define Duration#== [chuyeow]
jeremy authored
36
276c9f2 @NZKoz Make 1.months and friends accurate by introducing a Duration class. #68...
NZKoz authored
37 def is_a?(klass) #:nodoc:
a323b83 @jeremy Remove unneeded reliance on super -> method_missing quirk
jeremy authored
38 Duration == klass || value.is_a?(klass)
276c9f2 @NZKoz Make 1.months and friends accurate by introducing a Duration class. #68...
NZKoz authored
39 end
cc45a10 @neerajdotname 1.day should respond_to kind_of too
neerajdotname authored
40 alias :kind_of? :is_a?
887870f @jeremy Ruby 1.9 compat: define Duration#== [chuyeow]
jeremy authored
41
d71d5ba @frodsan update AS docs [ci skip]
frodsan authored
42 # Returns +true+ if +other+ is also a Duration instance with the
43 # same +value+, or if <tt>other == value</tt>.
887870f @jeremy Ruby 1.9 compat: define Duration#== [chuyeow]
jeremy authored
44 def ==(other)
45 if Duration === other
46 other.value == value
47 else
48 other == value
49 end
50 end
51
276c9f2 @NZKoz Make 1.months and friends accurate by introducing a Duration class. #68...
NZKoz authored
52 def self.===(other) #:nodoc:
a323b83 @jeremy Remove unneeded reliance on super -> method_missing quirk
jeremy authored
53 other.is_a?(Duration)
ee85f15 @jeremy Qualify constant lookup in BasicObject
jeremy authored
54 rescue ::NoMethodError
a323b83 @jeremy Remove unneeded reliance on super -> method_missing quirk
jeremy authored
55 false
276c9f2 @NZKoz Make 1.months and friends accurate by introducing a Duration class. #68...
NZKoz authored
56 end
887870f @jeremy Ruby 1.9 compat: define Duration#== [chuyeow]
jeremy authored
57
276c9f2 @NZKoz Make 1.months and friends accurate by introducing a Duration class. #68...
NZKoz authored
58 # Calculates a new Time or Date that is as far in the future
59 # as this Duration represents.
32b82e4 @gbuesing Duration #since and #ago with no argument (e.g., 5.days.ago) return Time...
gbuesing authored
60 def since(time = ::Time.current)
276c9f2 @NZKoz Make 1.months and friends accurate by introducing a Duration class. #68...
NZKoz authored
61 sum(1, time)
62 end
63 alias :from_now :since
887870f @jeremy Ruby 1.9 compat: define Duration#== [chuyeow]
jeremy authored
64
276c9f2 @NZKoz Make 1.months and friends accurate by introducing a Duration class. #68...
NZKoz authored
65 # Calculates a new Time or Date that is as far in the past
66 # as this Duration represents.
32b82e4 @gbuesing Duration #since and #ago with no argument (e.g., 5.days.ago) return Time...
gbuesing authored
67 def ago(time = ::Time.current)
276c9f2 @NZKoz Make 1.months and friends accurate by introducing a Duration class. #68...
NZKoz authored
68 sum(-1, time)
69 end
70 alias :until :ago
887870f @jeremy Ruby 1.9 compat: define Duration#== [chuyeow]
jeremy authored
71
276c9f2 @NZKoz Make 1.months and friends accurate by introducing a Duration class. #68...
NZKoz authored
72 def inspect #:nodoc:
3a91d44 @tenderlove let ruby decompose the tuples in the iterator
tenderlove authored
73 consolidated = parts.inject(::Hash.new(0)) { |h,(l,r)| h[l] += r; h }
ab2d6ab @levinalex make #inspect if zero length duration return '0 seconds' instead of empt...
levinalex authored
74 parts = [:years, :months, :days, :minutes, :seconds].map do |length|
276c9f2 @NZKoz Make 1.months and friends accurate by introducing a Duration class. #68...
NZKoz authored
75 n = consolidated[length]
76 "#{n} #{n == 1 ? length.to_s.singularize : length.to_s}" if n.nonzero?
ab2d6ab @levinalex make #inspect if zero length duration return '0 seconds' instead of empt...
levinalex authored
77 end.compact
78 parts = ["0 seconds"] if parts.empty?
79 parts.to_sentence(:locale => :en)
276c9f2 @NZKoz Make 1.months and friends accurate by introducing a Duration class. #68...
NZKoz authored
80 end
887870f @jeremy Ruby 1.9 compat: define Duration#== [chuyeow]
jeremy authored
81
0ac66ca @lifo Fix Duration#to_json
lifo authored
82 def as_json(options = nil) #:nodoc:
83 to_i
84 end
85
276c9f2 @NZKoz Make 1.months and friends accurate by introducing a Duration class. #68...
NZKoz authored
86 protected
887870f @jeremy Ruby 1.9 compat: define Duration#== [chuyeow]
jeremy authored
87
32b82e4 @gbuesing Duration #since and #ago with no argument (e.g., 5.days.ago) return Time...
gbuesing authored
88 def sum(sign, time = ::Time.current) #:nodoc:
887870f @jeremy Ruby 1.9 compat: define Duration#== [chuyeow]
jeremy authored
89 parts.inject(time) do |t,(type,number)|
90 if t.acts_like?(:time) || t.acts_like?(:date)
91 if type == :seconds
92 t.since(sign * number)
93 else
94 t.advance(type => sign * number)
95 end
276c9f2 @NZKoz Make 1.months and friends accurate by introducing a Duration class. #68...
NZKoz authored
96 else
ff47ba9 @jeremy Ruby 1.9 compat: add #raise to AS::BasicObject, fixup Duration argument ...
jeremy authored
97 raise ::ArgumentError, "expected a time or date, got #{time.inspect}"
276c9f2 @NZKoz Make 1.months and friends accurate by introducing a Duration class. #68...
NZKoz authored
98 end
99 end
100 end
887870f @jeremy Ruby 1.9 compat: define Duration#== [chuyeow]
jeremy authored
101
276c9f2 @NZKoz Make 1.months and friends accurate by introducing a Duration class. #68...
NZKoz authored
102 private
887870f @jeremy Ruby 1.9 compat: define Duration#== [chuyeow]
jeremy authored
103
104 def method_missing(method, *args, &block) #:nodoc:
57693d1 @krekoten Make ActiveSupport::Duration#method_missing delegate blocks to value [#5...
krekoten authored
105 value.send(method, *args, &block)
887870f @jeremy Ruby 1.9 compat: define Duration#== [chuyeow]
jeremy authored
106 end
276c9f2 @NZKoz Make 1.months and friends accurate by introducing a Duration class. #68...
NZKoz authored
107 end
34b5767 @jeremy Introduce BasicObject as Builder::BlankSlate for Ruby 1.9 forward compat...
jeremy authored
108 end
Something went wrong with that request. Please try again.