Changeset 5940
- Timestamp:
- 01/15/07 06:54:50 (2 years ago)
- Files:
-
- trunk/activesupport/CHANGELOG (modified) (1 diff)
- trunk/activesupport/lib/active_support.rb (modified) (1 diff)
- trunk/activesupport/lib/active_support/core_ext/date.rb (modified) (1 diff)
- trunk/activesupport/lib/active_support/core_ext/date/calculations.rb (added)
- trunk/activesupport/lib/active_support/core_ext/numeric/time.rb (modified) (2 diffs)
- trunk/activesupport/lib/active_support/core_ext/time/calculations.rb (modified) (2 diffs)
- trunk/activesupport/lib/active_support/duration.rb (added)
- trunk/activesupport/test/core_ext/duration_test.rb (added)
- trunk/activesupport/test/core_ext/numeric_ext_test.rb (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/activesupport/CHANGELOG
r5924 r5940 1 1 *SVN* 2 3 * Make 1.months and friends accurate by introducing a Duration class. #6835 [eventualbuddha] 2 4 3 5 * Document Inflector.ordinalize and merge docs from String inflections. #7023 [smeade] trunk/activesupport/lib/active_support.rb
r5223 r5940 39 39 40 40 require 'active_support/values/time_zone' 41 require 'active_support/duration' 41 42 42 43 require 'active_support/json' trunk/activesupport/lib/active_support/core_ext/date.rb
r738 r5940 1 1 require 'date' 2 require File.dirname(__FILE__) + '/date/calculations' 2 3 require File.dirname(__FILE__) + '/date/conversions' 3 4 4 5 class Date#:nodoc: 6 include ActiveSupport::CoreExtensions::Date::Calculations 5 7 include ActiveSupport::CoreExtensions::Date::Conversions 6 8 end trunk/activesupport/lib/active_support/core_ext/numeric/time.rb
r4029 r5940 4 4 # Enables the use of time calculations and declarations, like 45.minutes + 2.hours + 4.years. 5 5 # 6 # If you need precise date calculations that doesn't just treat months as 30 days, then have 7 # a look at Time#advance. 6 # These methods use Time#advance for precise date calculations when using from_now, ago, etc. 7 # as well as adding or subtracting their results from a Time object. For example: 8 # 9 # # equivalent to Time.now.advance(:months => 1) 10 # 1.month.from_now 11 # 12 # # equivalent to Time.now.advance(:years => 2) 13 # 2.years.from_now 14 # 15 # # equivalent to Time.now.advance(:months => 4, :years => 5) 16 # (4.months + 5.years).from_now 8 17 # 9 # Some of these methods are approximations, Ruby's core 18 # While these methods provide precise calculation when used as in the examples above, care 19 # should be taken to note that this is not true if the result of `months', `years', etc is 20 # converted before use: 21 # 22 # # equivalent to 30.days.to_i.from_now 23 # 1.month.to_i.from_now 24 # 25 # # equivalent to 365.25.days.to_f.from_now 26 # 1.year.to_f.from_now 27 # 28 # In such cases, Ruby's core 10 29 # Date[http://stdlib.rubyonrails.org/libdoc/date/rdoc/index.html] and 11 30 # Time[http://stdlib.rubyonrails.org/libdoc/time/rdoc/index.html] should be used for precision … … 13 32 module Time 14 33 def seconds 15 self34 ActiveSupport::Duration.new(self, [[:seconds, self]]) 16 35 end 17 36 alias :second :seconds 18 37 19 38 def minutes 20 self * 6039 ActiveSupport::Duration.new(self * 60, [[:seconds, self * 60]]) 21 40 end 22 41 alias :minute :minutes 23 42 24 43 def hours 25 self * 60.minutes44 ActiveSupport::Duration.new(self * 3600, [[:seconds, self * 3600]]) 26 45 end 27 46 alias :hour :hours 28 47 29 48 def days 30 self * 24.hours49 ActiveSupport::Duration.new(self * 24.hours, [[:days, self]]) 31 50 end 32 51 alias :day :days 33 52 34 53 def weeks 35 self * 7.days54 ActiveSupport::Duration.new(self * 7.days, [[:days, self * 7]]) 36 55 end 37 56 alias :week :weeks 38 57 39 58 def fortnights 40 self * 2.weeks59 ActiveSupport::Duration.new(self * 2.weeks, [[:days, self * 14]]) 41 60 end 42 61 alias :fortnight :fortnights 43 62 44 63 def months 45 self * 30.days64 ActiveSupport::Duration.new(self * 30.days, [[:months, self]]) 46 65 end 47 66 alias :month :months 48 67 49 68 def years 50 (self * 365.25.days).to_i69 ActiveSupport::Duration.new(self * 365.25.days, [[:years, self]]) 51 70 end 52 71 alias :year :years trunk/activesupport/lib/active_support/core_ext/time/calculations.rb
r5523 r5940 6 6 def self.included(base) #:nodoc: 7 7 base.extend(ClassMethods) 8 9 base.send(:alias_method, :plus_without_duration, :+) 10 base.send(:alias_method, :+, :plus_with_duration) 11 base.send(:alias_method, :minus_without_duration, :-) 12 base.send(:alias_method, :-, :minus_with_duration) 8 13 end 9 14 … … 191 196 self.since(1.day) 192 197 end 198 199 def plus_with_duration(other) #:nodoc: 200 if ActiveSupport::Duration === other 201 other.since(self) 202 else 203 plus_without_duration(other) 204 end 205 end 206 207 def minus_with_duration(other) #:nodoc: 208 if ActiveSupport::Duration === other 209 other.until(self) 210 else 211 minus_without_duration(other) 212 end 213 end 193 214 end 194 215 end trunk/activesupport/test/core_ext/numeric_ext_test.rb
r4595 r5940 35 35 end 36 36 end 37 38 def test_irregular_durations 39 assert_equal @now.advance(:days => 3000), 3000.days.since(@now) 40 assert_equal @now.advance(:months => 1), 1.month.since(@now) 41 assert_equal @now.advance(:months => -1), 1.month.until(@now) 42 assert_equal @now.advance(:years => 20), 20.years.since(@now) 43 end 44 45 def test_duration_addition 46 assert_equal @now.advance(:days => 1, :months => 1), (1.day + 1.month).since(@now) 47 assert_equal @now.advance(:days => 7), (1.week + 5.seconds - 5.seconds).since(@now) 48 assert_equal @now.advance(:years => 2), (4.years - 2.years).since(@now) 49 end 50 51 def test_time_plus_duration 52 assert_equal @now + 8, @now + 8.seconds 53 assert_equal @now + 22.9, @now + 22.9.seconds 54 assert_equal @now.advance(:days => 15), @now + 15.days 55 assert_equal @now.advance(:months => 1), @now + 1.month 56 end 57 58 def test_chaining_duration_operations 59 assert_equal @now.advance(:days => 2, :months => -3), @now + 2.days - 3.months 60 assert_equal @now.advance(:days => 1, :months => 2), @now + 1.day + 2.months 61 end 62 63 def test_duration_after_convertion_is_no_longer_accurate 64 assert_equal 30.days.to_i.since(@now), 1.month.to_i.since(@now) 65 assert_equal 365.25.days.to_f.since(@now), 1.year.to_f.since(@now) 66 end 67 end 68 69 class NumericExtDateTest < Test::Unit::TestCase 70 def setup 71 @today = Date.today 72 end 73 74 def test_date_plus_duration 75 assert_equal @today + 1, @today + 1.day 76 assert_equal @today >> 1, @today + 1.month 77 assert_raises(ArgumentError) { @today + 1.second } 78 end 79 80 def test_chaining_duration_operations 81 assert_equal @today.advance(:days => 2, :months => -3), @today + 2.days - 3.months 82 assert_equal @today.advance(:days => 1, :months => 2), @today + 1.day + 2.months 83 end 37 84 end 38 85