diff options
author | Rick Olson <technoweenie@gmail.com> | 2007-08-03 00:34:19 +0000 |
---|---|---|
committer | Rick Olson <technoweenie@gmail.com> | 2007-08-03 00:34:19 +0000 |
commit | 4b6411008675dbbfb7da4dfb6ef73c5528c196d1 (patch) | |
tree | 7c9012bb5296ffb04c9576bbc29d61f5b8a4d0da | |
parent | bbbc45156bb2f903513116036619b78065f6d7e8 (diff) | |
download | rails-4b6411008675dbbfb7da4dfb6ef73c5528c196d1.tar.gz rails-4b6411008675dbbfb7da4dfb6ef73c5528c196d1.tar.bz2 rails-4b6411008675dbbfb7da4dfb6ef73c5528c196d1.zip |
Fix Time#advance bug when trying to advance a year from leap day. Closes #8655 [gbuesing]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@7262 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
8 files changed, 23 insertions, 11 deletions
diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG index 35a7d77859..bed781d67d 100644 --- a/activesupport/CHANGELOG +++ b/activesupport/CHANGELOG @@ -1,5 +1,7 @@ *SVN* +* Fix Time#advance bug when trying to advance a year from leap day. Closes #8655 [gbuesing] + * Add support for []= on ActiveSupport::Multibyte::Chars. Closes #9142. [ewan, manfred] * Added Array#extract_options! to encapsulate the pattern of getting an options hash out of a variable number of parameters #8759 [norbert]. diff --git a/activesupport/lib/active_support/core_ext/date/calculations.rb b/activesupport/lib/active_support/core_ext/date/calculations.rb index 637c9ea02a..c28d0c876b 100644 --- a/activesupport/lib/active_support/core_ext/date/calculations.rb +++ b/activesupport/lib/active_support/core_ext/date/calculations.rb @@ -68,9 +68,10 @@ module ActiveSupport #:nodoc: # Provides precise Date calculations for years, months, and days. The +options+ parameter takes a hash with # any of these keys: :months, :days, :years. def advance(options) - d = ::Date.new(year + (options.delete(:years) || 0), month, day) - d = d >> options.delete(:months) if options[:months] - d = d + options.delete(:days) if options[:days] + d = self + d = d >> options.delete(:years) * 12 if options[:years] + d = d >> options.delete(:months) if options[:months] + d = d + options.delete(:days) if options[:days] d end @@ -78,7 +79,7 @@ module ActiveSupport #:nodoc: # # Examples: # - # Date.new(2007, 5, 12).change(:day => 1) # => Date.new(2007, 5, 12) + # Date.new(2007, 5, 12).change(:day => 1) # => Date.new(2007, 5, 1) # Date.new(2007, 5, 12).change(:year => 2005, :month => 1) # => Date.new(2005, 1, 12) def change(options) ::Date.new( diff --git a/activesupport/lib/active_support/core_ext/date_time/calculations.rb b/activesupport/lib/active_support/core_ext/date_time/calculations.rb index 8e4197d34b..e16ad55fbd 100644 --- a/activesupport/lib/active_support/core_ext/date_time/calculations.rb +++ b/activesupport/lib/active_support/core_ext/date_time/calculations.rb @@ -30,9 +30,7 @@ module ActiveSupport #:nodoc: # Uses Date to provide precise Time calculations for years, months, and days. The +options+ parameter takes a hash with # any of these keys: :months, :days, :years. def advance(options) - d = ::Date.new(year + (options.delete(:years) || 0), month, day) - d = d >> options.delete(:months) if options[:months] - d = d + options.delete(:days) if options[:days] + d = to_date.advance(options) change(options.merge(:year => d.year, :month => d.month, :day => d.day)) end diff --git a/activesupport/lib/active_support/core_ext/time/calculations.rb b/activesupport/lib/active_support/core_ext/time/calculations.rb index b6eb9b4288..507bb5f180 100644 --- a/activesupport/lib/active_support/core_ext/time/calculations.rb +++ b/activesupport/lib/active_support/core_ext/time/calculations.rb @@ -72,10 +72,8 @@ module ActiveSupport #:nodoc: # Uses Date to provide precise Time calculations for years, months, and days. The +options+ parameter takes a hash with # any of these keys: :months, :days, :years. def advance(options) - d = ::Date.new(year + (options.delete(:years) || 0), month, day) - d = d >> options.delete(:months) if options[:months] - d = d + options.delete(:days) if options[:days] - change(options.merge(:year => d.year, :month => d.month, :mday => d.day)) + d = to_date.advance(options) + change(options.merge(:year => d.year, :month => d.month, :day => d.day)) end # Returns a new Time representing the time a number of seconds ago, this is basically a wrapper around the Numeric extension diff --git a/activesupport/test/core_ext/date_ext_test.rb b/activesupport/test/core_ext/date_ext_test.rb index 8863e6a07f..4ec595d918 100644 --- a/activesupport/test/core_ext/date_ext_test.rb +++ b/activesupport/test/core_ext/date_ext_test.rb @@ -121,6 +121,7 @@ class DateExtCalculationsTest < Test::Unit::TestCase assert_equal Date.new(2005,6,28), Date.new(2005,2,28).advance(:months => 4) assert_equal Date.new(2012,9,28), Date.new(2005,2,28).advance(:years => 7, :months => 7) assert_equal Date.new(2013,10,3), Date.new(2005,2,28).advance(:years => 7, :months => 19, :days => 5) + assert_equal Date.new(2005,2,28), Date.new(2004,2,29).advance(:years => 1) #leap day plus one year end def test_next_week diff --git a/activesupport/test/core_ext/date_time_ext_test.rb b/activesupport/test/core_ext/date_time_ext_test.rb index 81e05a9f49..3c79fccdd1 100644 --- a/activesupport/test/core_ext/date_time_ext_test.rb +++ b/activesupport/test/core_ext/date_time_ext_test.rb @@ -163,6 +163,7 @@ class DateTimeExtCalculationsTest < Test::Unit::TestCase assert_equal DateTime.civil(2005,6,28,15,15,10), DateTime.civil(2005,2,28,15,15,10).advance(:months => 4) assert_equal DateTime.civil(2012,9,28,15,15,10), DateTime.civil(2005,2,28,15,15,10).advance(:years => 7, :months => 7) assert_equal DateTime.civil(2013,10,3,15,15,10), DateTime.civil(2005,2,28,15,15,10).advance(:years => 7, :months => 19, :days => 5) + assert_equal DateTime.civil(2005,2,28,15,15,10), DateTime.civil(2004,2,29,15,15,10).advance(:years => 1) #leap day plus one year end def test_next_week diff --git a/activesupport/test/core_ext/numeric_ext_test.rb b/activesupport/test/core_ext/numeric_ext_test.rb index bbbd706aa1..996b166405 100644 --- a/activesupport/test/core_ext/numeric_ext_test.rb +++ b/activesupport/test/core_ext/numeric_ext_test.rb @@ -80,6 +80,11 @@ class NumericExtTimeAndDateTimeTest < Test::Unit::TestCase assert_equal 30.days.to_i.since(@dtnow), 1.month.to_i.since(@dtnow) assert_equal 365.25.days.to_f.since(@dtnow), 1.year.to_f.since(@dtnow) end + + def test_add_one_year_to_leap_day + assert_equal Time.utc(2005,2,28,15,15,10), Time.utc(2004,2,29,15,15,10) + 1.year + assert_equal DateTime.civil(2005,2,28,15,15,10), DateTime.civil(2004,2,29,15,15,10) + 1.year + end end class NumericExtDateTest < Test::Unit::TestCase @@ -99,6 +104,10 @@ class NumericExtDateTest < Test::Unit::TestCase assert_equal @today.advance(:days => 2).advance(:months => -3), @today + 2.days - 3.months assert_equal @today.advance(:days => 1).advance(:months => 2), @today + 1.day + 2.months end + + def test_add_one_year_to_leap_day + assert_equal Date.new(2005,2,28), Date.new(2004,2,29) + 1.year + end end class NumericExtSizeTest < Test::Unit::TestCase diff --git a/activesupport/test/core_ext/time_ext_test.rb b/activesupport/test/core_ext/time_ext_test.rb index b390ae2249..8ab84baa5d 100644 --- a/activesupport/test/core_ext/time_ext_test.rb +++ b/activesupport/test/core_ext/time_ext_test.rb @@ -238,6 +238,7 @@ class TimeExtCalculationsTest < Test::Unit::TestCase assert_equal Time.local(2005,6,28,15,15,10), Time.local(2005,2,28,15,15,10).advance(:months => 4) assert_equal Time.local(2012,9,28,15,15,10), Time.local(2005,2,28,15,15,10).advance(:years => 7, :months => 7) assert_equal Time.local(2013,10,3,15,15,10), Time.local(2005,2,28,15,15,10).advance(:years => 7, :months => 19, :days => 5) + assert_equal Time.local(2005,2,28,15,15,10), Time.local(2004,2,29,15,15,10).advance(:years => 1) #leap day plus one year end def test_utc_plus @@ -245,6 +246,7 @@ class TimeExtCalculationsTest < Test::Unit::TestCase assert_equal Time.utc(2005,6,22,15,15,10), Time.utc(2005,2,22,15,15,10).advance(:months => 4) assert_equal Time.utc(2012,9,22,15,15,10), Time.utc(2005,2,22,15,15,10).advance(:years => 7, :months => 7) assert_equal Time.utc(2013,10,3,15,15,10), Time.utc(2005,2,22,15,15,10).advance(:years => 7, :months => 19, :days => 11) + assert_equal Time.utc(2005,2,28,15,15,10), Time.utc(2004,2,29,15,15,10).advance(:years => 1) #leap day plus one year end def test_next_week |