aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport
diff options
context:
space:
mode:
authorMatthew Draper <matthew@trebex.net>2014-06-05 16:23:47 +0930
committerMatthew Draper <matthew@trebex.net>2014-06-05 16:23:47 +0930
commitb2d070ddf6b79bf3ce0e8508c6872fc0d7e4b2e3 (patch)
treed6988c7cf09b9915644c42fb1adb8be7fc591d25 /activesupport
parentb4c021ec1205b33f8cf7a50f87233ef3e40200f6 (diff)
parentc69baffdf752e2255fe1efc80ce32017bb1896e7 (diff)
downloadrails-b2d070ddf6b79bf3ce0e8508c6872fc0d7e4b2e3.tar.gz
rails-b2d070ddf6b79bf3ce0e8508c6872fc0d7e4b2e3.tar.bz2
rails-b2d070ddf6b79bf3ce0e8508c6872fc0d7e4b2e3.zip
Merge pull request #15421 from gchan/time_with_zone_precision
Fixed `ActiveSupport::TimeWithZone#-` so precision is not unnecessarily lost
Diffstat (limited to 'activesupport')
-rw-r--r--activesupport/CHANGELOG.md20
-rw-r--r--activesupport/lib/active_support/time_with_zone.rb2
-rw-r--r--activesupport/test/core_ext/time_with_zone_test.rb15
3 files changed, 36 insertions, 1 deletions
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md
index 8a9d31a7bb..871e1705f7 100644
--- a/activesupport/CHANGELOG.md
+++ b/activesupport/CHANGELOG.md
@@ -1,3 +1,23 @@
+* Fixed `ActiveSupport::TimeWithZone#-` so precision is not unnecessarily lost
+ when working with objects with a nanosecond component.
+
+ `ActiveSupport::TimeWithZone#-` should return the same result as if we were
+ using `Time#-`:
+
+ Time.now.end_of_day - Time.now.beginning_of_day #=> 86399.999999999
+
+ Before:
+
+ Time.zone.now.end_of_day.nsec #=> 999999999
+ Time.zone.now.end_of_day - Time.zone.now.beginning_of_day #=> 86400.0
+
+ After:
+
+ Time.zone.now.end_of_day - Time.zone.now.beginning_of_day
+ #=> 86399.999999999
+
+ *Gordon Chan*
+
* Fixed precision error in NumberHelper when using Rationals.
before:
diff --git a/activesupport/lib/active_support/time_with_zone.rb b/activesupport/lib/active_support/time_with_zone.rb
index 3155c0ab0f..4a0ed356b1 100644
--- a/activesupport/lib/active_support/time_with_zone.rb
+++ b/activesupport/lib/active_support/time_with_zone.rb
@@ -262,7 +262,7 @@ module ActiveSupport
# If we're subtracting a Duration of variable length (i.e., years, months, days), move backwards from #time,
# otherwise move backwards #utc, for accuracy when moving across DST boundaries
if other.acts_like?(:time)
- utc.to_f - other.to_f
+ to_time - other.to_time
elsif duration_of_variable_length?(other)
method_missing(:-, other)
else
diff --git a/activesupport/test/core_ext/time_with_zone_test.rb b/activesupport/test/core_ext/time_with_zone_test.rb
index 7fe4d4a6b2..6d779bf3d5 100644
--- a/activesupport/test/core_ext/time_with_zone_test.rb
+++ b/activesupport/test/core_ext/time_with_zone_test.rb
@@ -246,16 +246,31 @@ class TimeWithZoneTest < ActiveSupport::TestCase
assert_equal 86_400.0, ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 2), ActiveSupport::TimeZone['Hawaii'] ) - Time.utc(2000, 1, 1)
end
+ def test_minus_with_time_precision
+ assert_equal 86_399.999999998, ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 2, 23, 59, 59, Rational(999999999, 1000)), ActiveSupport::TimeZone['UTC'] ) - Time.utc(2000, 1, 2, 0, 0, 0, Rational(1, 1000))
+ assert_equal 86_399.999999998, ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 2, 23, 59, 59, Rational(999999999, 1000)), ActiveSupport::TimeZone['Hawaii'] ) - Time.utc(2000, 1, 2, 0, 0, 0, Rational(1, 1000))
+ end
+
def test_minus_with_time_with_zone
twz1 = ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1), ActiveSupport::TimeZone['UTC'] )
twz2 = ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 2), ActiveSupport::TimeZone['UTC'] )
assert_equal 86_400.0, twz2 - twz1
end
+ def test_minus_with_time_with_zone_precision
+ twz1 = ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1, 0, 0, 0, Rational(1, 1000)), ActiveSupport::TimeZone['UTC'] )
+ twz2 = ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1, 23, 59, 59, Rational(999999999, 1000)), ActiveSupport::TimeZone['UTC'] )
+ assert_equal 86_399.999999998, twz2 - twz1
+ end
+
def test_minus_with_datetime
assert_equal 86_400.0, ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 2), ActiveSupport::TimeZone['UTC'] ) - DateTime.civil(2000, 1, 1)
end
+ def test_minus_with_datetime_precision
+ assert_equal 86_399.999999999, ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1, 23, 59, 59, Rational(999999999, 1000)), ActiveSupport::TimeZone['UTC'] ) - DateTime.civil(2000, 1, 1)
+ end
+
def test_minus_with_wrapped_datetime
assert_equal 86_400.0, ActiveSupport::TimeWithZone.new( DateTime.civil(2000, 1, 2), ActiveSupport::TimeZone['UTC'] ) - Time.utc(2000, 1, 1)
assert_equal 86_400.0, ActiveSupport::TimeWithZone.new( DateTime.civil(2000, 1, 2), ActiveSupport::TimeZone['UTC'] ) - DateTime.civil(2000, 1, 1)