From 8ce8b4973c473de3215cfe07e2b5e4f80f0379aa Mon Sep 17 00:00:00 2001 From: Dan Barry Date: Sun, 12 Oct 2008 20:36:26 -0500 Subject: [PATCH] Date.durations_between: Date.days_between, Date.weeks_between, Date.months_between, Date.years_between --- .../active_support/core_ext/date/calculations.rb | 25 +++++++++++ activesupport/test/core_ext/date_ext_test.rb | 44 ++++++++++++++++++++ 2 files changed, 69 insertions(+), 0 deletions(-) diff --git a/activesupport/lib/active_support/core_ext/date/calculations.rb b/activesupport/lib/active_support/core_ext/date/calculations.rb index 43d70c7..d188405 100644 --- a/activesupport/lib/active_support/core_ext/date/calculations.rb +++ b/activesupport/lib/active_support/core_ext/date/calculations.rb @@ -30,6 +30,31 @@ module ActiveSupport #:nodoc: def current ::Time.zone_default ? ::Time.zone.today : ::Date.today end + + def durations_between(start, finish, duration) + return durations_between(finish, start, duration) if start > finish + count = 0 + while ((start += duration) <= finish) + count += 1 + end + count + ((finish - (start - duration)) / (finish + duration - finish)) + end + + def days_between(start, finish) + durations_between(start, finish, 1.day) + end + + def weeks_between(start, finish) + durations_between(start, finish, 1.week) + end + + def months_between(start, finish) + durations_between(start, finish, 1.month) + end + + def years_between(start, finish) + durations_between(start, finish, 1.year) + end end # Tells whether the Date object's date lies in the past diff --git a/activesupport/test/core_ext/date_ext_test.rb b/activesupport/test/core_ext/date_ext_test.rb index b53c754..a5fad46 100644 --- a/activesupport/test/core_ext/date_ext_test.rb +++ b/activesupport/test/core_ext/date_ext_test.rb @@ -256,6 +256,50 @@ class DateExtCalculationsTest < Test::Unit::TestCase end end + def test_durations_between + assert_equal 2, Date.durations_between(Date.new(1999, 12, 29), Date.new(1999, 12, 31), 1.day) + end + + def test_durations_between_wrapping + assert_equal 1, Date.durations_between(Date.new(1999, 12, 31), Date.new(2000, 1, 1), 1.day) + end + + def test_durations_between_fractions + assert_equal 1.25, Date.durations_between(Date.new(1999, 12, 25), Date.new(1999, 12, 30), 4.days) + end + + def test_days_between + assert_equal 2, Date.days_between(Date.new(1999, 12, 29), Date.new(1999, 12, 31)) + end + + def test_days_between_wrapping + assert_equal 3, Date.days_between(Date.new(1999, 12, 30), Date.new(2000, 1, 2)) + end + + def test_weeks_between + assert_equal 2, Date.weeks_between(Date.new(1999, 12, 5), Date.new(1999, 12, 19)) + end + + def test_months_between + assert_equal 2, Date.months_between(Date.new(1999, 10, 1), Date.new(1999, 12, 1)) + end + + def test_months_between_wrapping + assert_equal 4, Date.months_between(Date.new(1999, 10, 1), Date.new(2000, 2, 1)) + end + + def test_months_between_fractions + assert_equal 1.5, Date.months_between(Date.new(1999, 10, 15), Date.new(1999, 11, 30)) + end + + def test_years_between + assert_equal 2, Date.years_between(Date.new(1999, 12, 31), Date.new(2001, 12, 31)) + end + + def test_years_between_fractions + assert_equal 1.2, Date.years_between(Date.new(1999, 6, 1), Date.new(2000, 8, 13)) + end + protected def with_env_tz(new_tz = 'US/Eastern') old_tz, ENV['TZ'] = ENV['TZ'], new_tz -- 1.5.4.2