From 20fa0d92c36681f6cffc715e08c299ff942352f4 Mon Sep 17 00:00:00 2001 From: Nick Holden Date: Tue, 6 Mar 2018 20:42:49 -0800 Subject: Add `before?` and `after?` methods to date and time classes Equality comparisons between dates and times can take some extra time to comprehend. I tend to think of a date or time as "before" or "after" another date or time, but I naturally read `<` and `>` as "less than" and "greater than." This change seeks to make date/time comparisons more human readable. --- activesupport/CHANGELOG.md | 5 +++++ .../lib/active_support/core_ext/date/calculations.rb | 2 ++ .../lib/active_support/core_ext/date_time/calculations.rb | 2 ++ .../lib/active_support/core_ext/time/calculations.rb | 2 ++ activesupport/lib/active_support/time_with_zone.rb | 2 ++ activesupport/test/core_ext/date_ext_test.rb | 12 ++++++++++++ activesupport/test/core_ext/date_time_ext_test.rb | 12 ++++++++++++ activesupport/test/core_ext/time_ext_test.rb | 12 ++++++++++++ activesupport/test/core_ext/time_with_zone_test.rb | 14 ++++++++++++++ 9 files changed, 63 insertions(+) (limited to 'activesupport') diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md index a7af51f83e..582209c2ae 100644 --- a/activesupport/CHANGELOG.md +++ b/activesupport/CHANGELOG.md @@ -1,5 +1,10 @@ ## Rails 6.0.0.alpha (Unreleased) ## +* Add `before?` and `after?` methods to `Date`, `DateTime`, + `Time`, and `TimeWithZone`. + + *Nick Holden* + * Add `:private` option to ActiveSupport's `Module#delegate` in order to delegate methods as private: diff --git a/activesupport/lib/active_support/core_ext/date/calculations.rb b/activesupport/lib/active_support/core_ext/date/calculations.rb index 1cd7acb05d..e7be5c1376 100644 --- a/activesupport/lib/active_support/core_ext/date/calculations.rb +++ b/activesupport/lib/active_support/core_ext/date/calculations.rb @@ -142,4 +142,6 @@ class Date end alias_method :compare_without_coercion, :<=> alias_method :<=>, :compare_with_coercion + alias_method :before?, :< + alias_method :after?, :> end 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 e61b23f842..eace125883 100644 --- a/activesupport/lib/active_support/core_ext/date_time/calculations.rb +++ b/activesupport/lib/active_support/core_ext/date_time/calculations.rb @@ -208,4 +208,6 @@ class DateTime super end end + alias_method :before?, :< + alias_method :after?, :> end diff --git a/activesupport/lib/active_support/core_ext/time/calculations.rb b/activesupport/lib/active_support/core_ext/time/calculations.rb index 120768dec5..0507f9e652 100644 --- a/activesupport/lib/active_support/core_ext/time/calculations.rb +++ b/activesupport/lib/active_support/core_ext/time/calculations.rb @@ -302,6 +302,8 @@ class Time end alias_method :compare_without_coercion, :<=> alias_method :<=>, :compare_with_coercion + alias_method :before?, :< + alias_method :after?, :> # Layers additional behavior on Time#eql? so that ActiveSupport::TimeWithZone instances # can be eql? to an equivalent Time diff --git a/activesupport/lib/active_support/time_with_zone.rb b/activesupport/lib/active_support/time_with_zone.rb index 20650ce714..7e71318404 100644 --- a/activesupport/lib/active_support/time_with_zone.rb +++ b/activesupport/lib/active_support/time_with_zone.rb @@ -225,6 +225,8 @@ module ActiveSupport def <=>(other) utc <=> other end + alias_method :before?, :< + alias_method :after?, :> # Returns true if the current object's time is within the specified # +min+ and +max+ time. diff --git a/activesupport/test/core_ext/date_ext_test.rb b/activesupport/test/core_ext/date_ext_test.rb index b8652884ce..8d3d575e0f 100644 --- a/activesupport/test/core_ext/date_ext_test.rb +++ b/activesupport/test/core_ext/date_ext_test.rb @@ -360,6 +360,18 @@ class DateExtCalculationsTest < ActiveSupport::TestCase end end + def test_before + assert_equal false, Date.new(2017, 3, 6).before?(Date.new(2017, 3, 5)) + assert_equal false, Date.new(2017, 3, 6).before?(Date.new(2017, 3, 6)) + assert_equal true, Date.new(2017, 3, 6).before?(Date.new(2017, 3, 7)) + end + + def test_after + assert_equal true, Date.new(2017, 3, 6).after?(Date.new(2017, 3, 5)) + assert_equal false, Date.new(2017, 3, 6).after?(Date.new(2017, 3, 6)) + assert_equal false, Date.new(2017, 3, 6).after?(Date.new(2017, 3, 7)) + end + def test_current_returns_date_today_when_zone_not_set with_env_tz "US/Central" do Time.stub(:now, Time.local(1999, 12, 31, 23)) do diff --git a/activesupport/test/core_ext/date_time_ext_test.rb b/activesupport/test/core_ext/date_time_ext_test.rb index 894fb80cba..a6124197ae 100644 --- a/activesupport/test/core_ext/date_time_ext_test.rb +++ b/activesupport/test/core_ext/date_time_ext_test.rb @@ -285,6 +285,18 @@ class DateTimeExtCalculationsTest < ActiveSupport::TestCase end end + def test_before + assert_equal false, DateTime.civil(2017, 3, 6, 12, 0, 0).before?(DateTime.civil(2017, 3, 6, 11, 59, 59)) + assert_equal false, DateTime.civil(2017, 3, 6, 12, 0, 0).before?(DateTime.civil(2017, 3, 6, 12, 0, 0)) + assert_equal true, DateTime.civil(2017, 3, 6, 12, 0, 0).before?(DateTime.civil(2017, 3, 6, 12, 00, 1)) + end + + def test_after + assert_equal true, DateTime.civil(2017, 3, 6, 12, 0, 0).after?(DateTime.civil(2017, 3, 6, 11, 59, 59)) + assert_equal false, DateTime.civil(2017, 3, 6, 12, 0, 0).after?(DateTime.civil(2017, 3, 6, 12, 0, 0)) + assert_equal false, DateTime.civil(2017, 3, 6, 12, 0, 0).after?(DateTime.civil(2017, 3, 6, 12, 00, 1)) + end + def test_current_returns_date_today_when_zone_is_not_set with_env_tz "US/Eastern" do Time.stub(:now, Time.local(1999, 12, 31, 23, 59, 59)) do diff --git a/activesupport/test/core_ext/time_ext_test.rb b/activesupport/test/core_ext/time_ext_test.rb index e1cb22fda8..0d16e51087 100644 --- a/activesupport/test/core_ext/time_ext_test.rb +++ b/activesupport/test/core_ext/time_ext_test.rb @@ -736,6 +736,18 @@ class TimeExtCalculationsTest < ActiveSupport::TestCase end end + def test_before + assert_equal false, Time.utc(2017, 3, 6, 12, 0, 0).before?(Time.utc(2017, 3, 6, 11, 59, 59)) + assert_equal false, Time.utc(2017, 3, 6, 12, 0, 0).before?(Time.utc(2017, 3, 6, 12, 0, 0)) + assert_equal true, Time.utc(2017, 3, 6, 12, 0, 0).before?(Time.utc(2017, 3, 6, 12, 00, 1)) + end + + def test_after + assert_equal true, Time.utc(2017, 3, 6, 12, 0, 0).after?(Time.utc(2017, 3, 6, 11, 59, 59)) + assert_equal false, Time.utc(2017, 3, 6, 12, 0, 0).after?(Time.utc(2017, 3, 6, 12, 0, 0)) + assert_equal false, Time.utc(2017, 3, 6, 12, 0, 0).after?(Time.utc(2017, 3, 6, 12, 00, 1)) + end + def test_acts_like_time assert_predicate Time.new, :acts_like_time? end diff --git a/activesupport/test/core_ext/time_with_zone_test.rb b/activesupport/test/core_ext/time_with_zone_test.rb index 2ea5f0921c..e650209268 100644 --- a/activesupport/test/core_ext/time_with_zone_test.rb +++ b/activesupport/test/core_ext/time_with_zone_test.rb @@ -289,6 +289,20 @@ class TimeWithZoneTest < ActiveSupport::TestCase end end + def test_before + twz = ActiveSupport::TimeWithZone.new(Time.utc(2017, 3, 6, 12, 0, 0), @time_zone) + assert_equal false, twz.before?(ActiveSupport::TimeWithZone.new(Time.utc(2017, 3, 6, 11, 59, 59), @time_zone)) + assert_equal false, twz.before?(ActiveSupport::TimeWithZone.new(Time.utc(2017, 3, 6, 12, 0, 0), @time_zone)) + assert_equal true, twz.before?(ActiveSupport::TimeWithZone.new(Time.utc(2017, 3, 6, 12, 00, 1), @time_zone)) + end + + def test_after + twz = ActiveSupport::TimeWithZone.new(Time.utc(2017, 3, 6, 12, 0, 0), @time_zone) + assert_equal true, twz.after?(ActiveSupport::TimeWithZone.new(Time.utc(2017, 3, 6, 11, 59, 59), @time_zone)) + assert_equal false, twz.after?(ActiveSupport::TimeWithZone.new(Time.utc(2017, 3, 6, 12, 0, 0), @time_zone)) + assert_equal false, twz.after?(ActiveSupport::TimeWithZone.new(Time.utc(2017, 3, 6, 12, 00, 1), @time_zone)) + end + def test_eql? assert_equal true, @twz.eql?(@twz.dup) assert_equal true, @twz.eql?(Time.utc(2000)) -- cgit v1.2.3