Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

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.
  • Loading branch information...
commit 53ca22f2e11cd3050d75385bc31b6bb5055a2738 1 parent ebb4a3d
@aripollak aripollak authored
View
6 activerecord/CHANGELOG.md
@@ -1,5 +1,11 @@
## Rails 4.0.0 (unreleased) ##
+* Fix Column.microseconds and Column.fast_string_to_date to avoid converting

Possibly, is this not fast_string_to_date but fast_string_to_time?

You're right, fixed in d23c761, thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ 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`.
*Roman Shatsov*
View
4 activerecord/lib/active_record/connection_adapters/column.rb
@@ -208,7 +208,7 @@ def value_to_decimal(value)
# '0.123456' -> 123456
# '1.123456' -> 123456
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
def new_date(year, mon, mday)
@@ -233,7 +233,7 @@ def fast_string_to_date(string)
# Doesn't handle time zones.
def fast_string_to_time(string)
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
end
end
View
1  activerecord/test/cases/base_test.rb
@@ -231,6 +231,7 @@ def test_preserving_time_objects
assert_equal 11, Topic.find(1).written_on.sec
assert_equal 223300, Topic.find(1).written_on.usec
assert_equal 9900, Topic.find(2).written_on.usec
+ assert_equal 129346, Topic.find(3).written_on.usec
end
end
View
2  activerecord/test/fixtures/topics.yml
@@ -25,7 +25,7 @@ third:
id: 3
title: The Third Topic of the day
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
approved: true
replies_count: 1

0 comments on commit 53ca22f

Please sign in to comment.
Something went wrong with that request. Please try again.