Skip to content

Commit 99678f2

Browse files
committed
Rounding errors w/datetime2(0) types having no fractional seconds. Fixes #465.
Thanks @alawton
1 parent 0daeae6 commit 99678f2

File tree

5 files changed

+17
-3
lines changed

5 files changed

+17
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* Undefined method `database_prefix_remote_server?' Fixes #450. Thanks @jippeholwerda
66
* Document two methods for avoiding N'' quoting on char/varchar columns.
77
* First run failure of `change_column` while dropping constraint. Fixes #420. Thanks @GrumpyRainbow @rkr090
8+
* Rounding errors w/datetime2(0) types having no fractional seconds. Fixes #465. Thanks @alawton
89

910
#### Changed
1011

Gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ group :development do
5252
gem 'mocha'
5353
gem 'minitest', '< 5.3.4' # PENDING: [Rails5.x] Remove test order constraint.
5454
gem 'minitest-spec-rails'
55+
gem 'pry'
5556
end
5657

5758
group :guard do

lib/active_record/connection_adapters/sqlserver/type/time_value_fractional.rb

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,13 @@ module TimeValueFractional
99

1010
def cast_fractional(value)
1111
return value if !value.respond_to?(fractional_property) || value.send(fractional_property).zero?
12-
seconds = value.send(fractional_property).to_f / fractional_operator.to_f
13-
seconds = ((seconds * (1 / fractional_precision)).round / (1 / fractional_precision)).round(fractional_scale)
14-
frac_seconds = (seconds * fractional_operator).to_i
12+
frac_seconds = if fractional_scale == 0
13+
0
14+
else
15+
seconds = value.send(fractional_property).to_f / fractional_operator.to_f
16+
seconds = ((seconds * (1 / fractional_precision)).round / (1 / fractional_precision)).round(fractional_scale)
17+
(seconds * fractional_operator).to_i
18+
end
1519
value.change fractional_property => frac_seconds
1620
end
1721

test/cases/column_test_sqlserver.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,13 @@ def assert_obj_set_and_save(attribute, value)
373373
obj.datetime2_1.must_equal time.change(nsec: 100000000), "Nanoseconds were <#{obj.datetime2_1.nsec}> vs <100000000>"
374374
obj.save! ; obj.reload
375375
obj.datetime2_1.must_equal time.change(nsec: 100000000), "Nanoseconds were <#{obj.datetime2_1.nsec}> vs <100000000>"
376+
col = column('datetime2_0')
377+
col.cast_type.precision.must_equal 0
378+
time = Time.utc 2016, 4, 19, 16, 45, 40, 771036
379+
obj.datetime2_0 = time
380+
obj.datetime2_0.must_equal time.change(nsec: 0), "Nanoseconds were <#{obj.datetime2_0.nsec}> vs <0>"
381+
obj.save! ; obj.reload
382+
obj.datetime2_0.must_equal time.change(nsec: 0), "Nanoseconds were <#{obj.datetime2_0.nsec}> vs <0>"
376383
end
377384

378385
it 'datetimeoffset' do

test/schema/datatypes/2012.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ CREATE TABLE [sst_datatypes] (
2828
[datetime2_7] [datetime2](7) NULL DEFAULT '9999-12-31 23:59:59.9999999',
2929
[datetime2_3] [datetime2](3) NULL,
3030
[datetime2_1] [datetime2](1) NULL,
31+
[datetime2_0] [datetime2](0) NULL,
3132
[datetimeoffset_7] [datetimeoffset](7) NULL DEFAULT '1984-01-24 04:20:00.1234567 -08:00',
3233
[datetimeoffset_3] [datetimeoffset](3) NULL,
3334
[datetimeoffset_1] [datetimeoffset](1) NULL,

0 commit comments

Comments
 (0)