mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Fixed ActiveSupport::TimeWithZone#-
so precision is not unnecessarily lost
When working with objects with a nanosecond component, the `-` method may unnecessarily cause loss of precision. `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
This commit is contained in:
parent
6963e33829
commit
c69baffdf7
3 changed files with 36 additions and 1 deletions
|
@ -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*
|
||||
|
||||
* DateTime `advance` now supports partial days.
|
||||
|
||||
Before:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue