aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport')
-rw-r--r--activesupport/CHANGELOG2
-rw-r--r--activesupport/lib/active_support/core_ext/date/calculations.rb18
-rw-r--r--activesupport/test/core_ext/date_ext_test.rb27
3 files changed, 47 insertions, 0 deletions
diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG
index 3061bcef4f..1e01cfc45f 100644
--- a/activesupport/CHANGELOG
+++ b/activesupport/CHANGELOG
@@ -1,5 +1,7 @@
*Rails 3.0.0 [beta 4/release candidate] (unreleased)*
+* Backports Date#>> from 1.9 so that calculations do the right thing around the calendar reform. [fxn]
+
* Date#to_time handles properly years in the range 0..138. [fxn]
* Deprecate {{}} as interpolation syntax for I18n in favor of %{} [José Valim]
diff --git a/activesupport/lib/active_support/core_ext/date/calculations.rb b/activesupport/lib/active_support/core_ext/date/calculations.rb
index fef49e1003..2612dca93a 100644
--- a/activesupport/lib/active_support/core_ext/date/calculations.rb
+++ b/activesupport/lib/active_support/core_ext/date/calculations.rb
@@ -4,6 +4,24 @@ require 'active_support/core_ext/time/zones'
require 'active_support/core_ext/object/acts_like'
class Date
+ if RUBY_VERSION < '1.9'
+ undef :>>
+
+ # Backported from 1.9. The one in 1.8 leads to incorrect next_month and
+ # friends for dates where the calendar reform is involved. It additionally
+ # prevents an infinite loop fixed in r27013.
+ def >>(n)
+ y, m = (year * 12 + (mon - 1) + n).divmod(12)
+ m, = (m + 1) .divmod(1)
+ d = mday
+ until jd2 = self.class.valid_civil?(y, m, d, start)
+ d -= 1
+ raise ArgumentError, 'invalid date' unless d > 0
+ end
+ self + (jd2 - jd)
+ end
+ end
+
class << self
# Returns a new Date representing the date 1 day ago (i.e. yesterday's date).
def yesterday
diff --git a/activesupport/test/core_ext/date_ext_test.rb b/activesupport/test/core_ext/date_ext_test.rb
index d5f3eed8c1..e70fc729ce 100644
--- a/activesupport/test/core_ext/date_ext_test.rb
+++ b/activesupport/test/core_ext/date_ext_test.rb
@@ -145,6 +145,10 @@ class DateExtCalculationsTest < Test::Unit::TestCase
assert_equal Date.new(1999,2,28), Date.new(2000,2,29).last_year
end
+ def test_last_year_in_calendar_reform
+ assert_equal Date.new(1582,10,4), Date.new(1583,10,14).last_year
+ end
+
def test_next_year
assert_equal Date.new(2006,6,5), Date.new(2005,6,5).next_year
end
@@ -153,16 +157,28 @@ class DateExtCalculationsTest < Test::Unit::TestCase
assert_equal Date.new(2001,2,28), Date.new(2000,2,29).next_year
end
+ def test_next_year_in_calendar_reform
+ assert_equal Date.new(1582,10,4), Date.new(1581,10,10).next_year
+ end
+
def test_yesterday
assert_equal Date.new(2005,2,21), Date.new(2005,2,22).yesterday
assert_equal Date.new(2005,2,28), Date.new(2005,3,2).yesterday.yesterday
end
+ def test_yesterday_in_calendar_reform
+ assert_equal Date.new(1582,10,4), Date.new(1582,10,15).yesterday
+ end
+
def test_tomorrow
assert_equal Date.new(2005,2,23), Date.new(2005,2,22).tomorrow
assert_equal Date.new(2005,3,2), Date.new(2005,2,28).tomorrow.tomorrow
end
+ def test_tomorrow_in_calendar_reform
+ assert_equal Date.new(1582,10,15), Date.new(1582,10,4).tomorrow
+ end
+
def test_advance
assert_equal Date.new(2006,2,28), Date.new(2005,2,28).advance(:years => 1)
assert_equal Date.new(2005,6,28), Date.new(2005,2,28).advance(:months => 4)
@@ -174,6 +190,17 @@ class DateExtCalculationsTest < Test::Unit::TestCase
assert_equal Date.new(2005,2,28), Date.new(2004,2,29).advance(:years => 1) #leap day plus one year
end
+ def test_advance_calendar_reform
+ assert_equal Date.new(1582,10,15), Date.new(1582,10,4).advance(:days => 1)
+ assert_equal Date.new(1582,10,4), Date.new(1582,10,15).advance(:days => -1)
+ 5.upto(14) do |day|
+ assert_equal Date.new(1582,10,4), Date.new(1582,9,day).advance(:months => 1)
+ assert_equal Date.new(1582,10,4), Date.new(1582,11,day).advance(:months => -1)
+ assert_equal Date.new(1582,10,4), Date.new(1581,10,day).advance(:years => 1)
+ assert_equal Date.new(1582,10,4), Date.new(1583,10,day).advance(:years => -1)
+ end
+ end
+
def test_next_week
assert_equal Date.new(2005,2,28), Date.new(2005,2,22).next_week
assert_equal Date.new(2005,3,4), Date.new(2005,2,22).next_week(:friday)