diff --git a/activesupport/lib/active_support/core_ext/date/calculations.rb b/activesupport/lib/active_support/core_ext/date/calculations.rb
index c60e833441..86d7fa1abf 100644
--- a/activesupport/lib/active_support/core_ext/date/calculations.rb
+++ b/activesupport/lib/active_support/core_ext/date/calculations.rb
@@ -1,12 +1,13 @@
require 'date'
-require 'active_support/duration'
require 'active_support/core_ext/object/acts_like'
require 'active_support/core_ext/date/zones'
+require 'active_support/core_ext/date/operators'
require 'active_support/core_ext/time/zones'
require 'active_support/core_ext/date_and_time/calculations'
class Date
include DateAndTime::Calculations
+ prepend ActiveSupport::DateOperators
class << self
attr_accessor :beginning_of_week_default
@@ -85,26 +86,6 @@ class Date
end
alias :at_end_of_day :end_of_day
- def plus_with_duration(other) #:nodoc:
- if ActiveSupport::Duration === other
- other.since(self)
- else
- plus_without_duration(other)
- end
- end
- alias_method :plus_without_duration, :+
- alias_method :+, :plus_with_duration
-
- def minus_with_duration(other) #:nodoc:
- if ActiveSupport::Duration === other
- plus_with_duration(-other)
- else
- minus_without_duration(other)
- end
- end
- alias_method :minus_without_duration, :-
- alias_method :-, :minus_with_duration
-
# Provides precise Date calculations for years, months, and days. The +options+ parameter takes a hash with
# any of these keys: :years, :months, :weeks, :days.
def advance(options)
@@ -129,15 +110,4 @@ class Date
options.fetch(:day, day)
)
end
-
- # Allow Date to be compared with Time by converting to DateTime and relying on the <=> from there.
- def compare_with_coercion(other)
- if other.is_a?(Time)
- self.to_datetime <=> other
- else
- compare_without_coercion(other)
- end
- end
- alias_method :compare_without_coercion, :<=>
- alias_method :<=>, :compare_with_coercion
end
diff --git a/activesupport/lib/active_support/core_ext/date/operators.rb b/activesupport/lib/active_support/core_ext/date/operators.rb
new file mode 100644
index 0000000000..decf099624
--- /dev/null
+++ b/activesupport/lib/active_support/core_ext/date/operators.rb
@@ -0,0 +1,16 @@
+require 'active_support/core_ext/date_and_time/with_duration'
+
+module ActiveSupport
+ module DateOperators # :nodoc:
+ include DateAndTime::WithDuration
+
+ # Allow Date to be compared with Time by converting to DateTime and relying on the <=> from there.
+ def <=>(other)
+ if other.is_a?(Time)
+ self.to_datetime <=> other
+ else
+ super
+ end
+ end
+ end
+end
diff --git a/activesupport/lib/active_support/core_ext/date_and_time/with_duration.rb b/activesupport/lib/active_support/core_ext/date_and_time/with_duration.rb
new file mode 100644
index 0000000000..4a6c4013d5
--- /dev/null
+++ b/activesupport/lib/active_support/core_ext/date_and_time/with_duration.rb
@@ -0,0 +1,23 @@
+require 'active_support/duration'
+
+module ActiveSupport
+ module DateAndTime
+ module WithDuration #:nodoc:
+ def +(other) #:nodoc:
+ if ActiveSupport::Duration === other
+ other.since(self)
+ else
+ super
+ end
+ end
+
+ def -(other) #:nodoc:
+ if ActiveSupport::Duration === other
+ self + (-other)
+ else
+ super
+ end
+ end
+ end
+ end
+end
diff --git a/activesupport/lib/active_support/core_ext/time/calculations.rb b/activesupport/lib/active_support/core_ext/time/calculations.rb
index 1ce68ea7c7..dd99dd667a 100644
--- a/activesupport/lib/active_support/core_ext/time/calculations.rb
+++ b/activesupport/lib/active_support/core_ext/time/calculations.rb
@@ -1,11 +1,12 @@
-require 'active_support/duration'
require 'active_support/core_ext/time/conversions'
require 'active_support/time_with_zone'
require 'active_support/core_ext/time/zones'
+require 'active_support/core_ext/time/operators'
require 'active_support/core_ext/date_and_time/calculations'
class Time
include DateAndTime::Calculations
+ prepend ActiveSupport::TimeOperators
COMMON_YEAR_DAYS_IN_MONTH = [nil, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
@@ -212,60 +213,4 @@ class Time
def all_day
beginning_of_day..end_of_day
end
-
- def plus_with_duration(other) #:nodoc:
- if ActiveSupport::Duration === other
- other.since(self)
- else
- plus_without_duration(other)
- end
- end
- alias_method :plus_without_duration, :+
- alias_method :+, :plus_with_duration
-
- def minus_with_duration(other) #:nodoc:
- if ActiveSupport::Duration === other
- other.until(self)
- else
- minus_without_duration(other)
- end
- end
- alias_method :minus_without_duration, :-
- alias_method :-, :minus_with_duration
-
- # Time#- can also be used to determine the number of seconds between two Time instances.
- # We're layering on additional behavior so that ActiveSupport::TimeWithZone instances
- # are coerced into values that Time#- will recognize
- def minus_with_coercion(other)
- other = other.comparable_time if other.respond_to?(:comparable_time)
- other.is_a?(DateTime) ? to_f - other.to_f : minus_without_coercion(other)
- end
- alias_method :minus_without_coercion, :-
- alias_method :-, :minus_with_coercion
-
- # Layers additional behavior on Time#<=> so that DateTime and ActiveSupport::TimeWithZone instances
- # can be chronologically compared with a Time
- def compare_with_coercion(other)
- # we're avoiding Time#to_datetime and Time#to_time because they're expensive
- if other.class == Time
- compare_without_coercion(other)
- elsif other.is_a?(Time)
- compare_without_coercion(other.to_time)
- else
- to_datetime <=> other
- end
- end
- alias_method :compare_without_coercion, :<=>
- alias_method :<=>, :compare_with_coercion
-
- # Layers additional behavior on Time#eql? so that ActiveSupport::TimeWithZone instances
- # can be eql? to an equivalent Time
- def eql_with_coercion(other)
- # if other is an ActiveSupport::TimeWithZone, coerce a Time instance from it so we can do eql? comparison
- other = other.comparable_time if other.respond_to?(:comparable_time)
- eql_without_coercion(other)
- end
- alias_method :eql_without_coercion, :eql?
- alias_method :eql?, :eql_with_coercion
-
end
diff --git a/activesupport/lib/active_support/core_ext/time/operators.rb b/activesupport/lib/active_support/core_ext/time/operators.rb
new file mode 100644
index 0000000000..161304dcb3
--- /dev/null
+++ b/activesupport/lib/active_support/core_ext/time/operators.rb
@@ -0,0 +1,36 @@
+require 'active_support/core_ext/date_and_time/with_duration'
+
+module ActiveSupport
+ module TimeOperators # :nodoc:
+ include DateAndTime::WithDuration
+
+ # Layers additional behavior on Time#<=> so that DateTime and ActiveSupport::TimeWithZone instances
+ # can be chronologically compared with a Time
+ def <=>(other)
+ # we're avoiding Time#to_datetime and Time#to_time because they're expensive
+ if other.class == Time
+ super
+ elsif other.is_a?(Time)
+ super(other.to_time)
+ else
+ to_datetime <=> other
+ end
+ end
+
+ # Layers additional behavior on Time#eql? so that ActiveSupport::TimeWithZone instances
+ # can be eql? to an equivalent Time
+ def eql?(other)
+ # if other is an ActiveSupport::TimeWithZone, coerce a Time instance from it so we can do eql? comparison
+ other = other.comparable_time if other.respond_to?(:comparable_time)
+ super
+ end
+
+ # Time#- can also be used to determine the number of seconds between two Time instances.
+ # We're layering on additional behavior so that ActiveSupport::TimeWithZone instances
+ # are coerced into values that Time#- will recognize
+ def -(other)
+ other = other.comparable_time if other.respond_to?(:comparable_time)
+ other.is_a?(DateTime) ? to_f - other.to_f : super
+ end
+ end
+end