提交 53ca22f2 编写于 作者: A Ari Pollak

Fix occasional microsecond conversion inaccuracy

ActiveRecord::ConnectionAdapters::Column#microseconds did an unnecessary
conversion to from Rational to float when calculating the integer number
of microseconds. Some terminating decimal numbers in base10 are
repeating decimal numbers in base2 (the format of float), and
occasionally this causes a rounding error.
Patch & explanation originally from Logan Bowers.
上级 ebb4a3d5
## Rails 4.0.0 (unreleased) ## ## Rails 4.0.0 (unreleased) ##
* Fix Column.microseconds and Column.fast_string_to_date to avoid converting
timestamp seconds to a float, since it occasionally results in inaccuracies
with microsecond-precision times. Fixes #7352.
*Ari Pollak*
* Raise `ArgumentError` if list of attributes to change is empty in `update_all`. * Raise `ArgumentError` if list of attributes to change is empty in `update_all`.
*Roman Shatsov* *Roman Shatsov*
......
...@@ -208,7 +208,7 @@ def value_to_decimal(value) ...@@ -208,7 +208,7 @@ def value_to_decimal(value)
# '0.123456' -> 123456 # '0.123456' -> 123456
# '1.123456' -> 123456 # '1.123456' -> 123456
def microseconds(time) def microseconds(time)
((time[:sec_fraction].to_f % 1) * 1_000_000).to_i time[:sec_fraction] ? (time[:sec_fraction] * 1_000_000).to_i : 0
end end
def new_date(year, mon, mday) def new_date(year, mon, mday)
...@@ -233,7 +233,7 @@ def fast_string_to_date(string) ...@@ -233,7 +233,7 @@ def fast_string_to_date(string)
# Doesn't handle time zones. # Doesn't handle time zones.
def fast_string_to_time(string) def fast_string_to_time(string)
if string =~ Format::ISO_DATETIME if string =~ Format::ISO_DATETIME
microsec = ($7.to_f * 1_000_000).to_i microsec = ($7.to_r * 1_000_000).to_i
new_time $1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i, microsec new_time $1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i, microsec
end end
end end
......
...@@ -231,6 +231,7 @@ def test_preserving_time_objects ...@@ -231,6 +231,7 @@ def test_preserving_time_objects
assert_equal 11, Topic.find(1).written_on.sec assert_equal 11, Topic.find(1).written_on.sec
assert_equal 223300, Topic.find(1).written_on.usec assert_equal 223300, Topic.find(1).written_on.usec
assert_equal 9900, Topic.find(2).written_on.usec assert_equal 9900, Topic.find(2).written_on.usec
assert_equal 129346, Topic.find(3).written_on.usec
end end
end end
......
...@@ -25,7 +25,7 @@ third: ...@@ -25,7 +25,7 @@ third:
id: 3 id: 3
title: The Third Topic of the day title: The Third Topic of the day
author_name: Carl author_name: Carl
written_on: 2005-07-15t15:28:00.0099+01:00 written_on: 2012-08-12t20:24:22.129346+00:00
content: I'm a troll content: I'm a troll
approved: true approved: true
replies_count: 1 replies_count: 1
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册