1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Normalize date component when writing to time columns

For legacy reasons Rails stores time columns on sqlite as full
timestamp strings. However because the date component wasn't being
normalized this meant that when they were read back they were being
prefixed with 2001-01-01 by ActiveModel::Type::Time. This had a
twofold result - first it meant that the fast code path wasn't being
used because the string was invalid and second it was corrupting the
second fractional component being read by the Date._parse code path.

Fix this by a combination of normalizing the timestamps on writing
and also changing Active Model to be more lenient when detecting
whether a string starts with a date component before creating the
dummy time value for parsing.
This commit is contained in:
Andrew White 2018-03-11 18:23:50 +00:00
parent 4d9126cfcc
commit 3f95054f1c
3 changed files with 9 additions and 6 deletions

View file

@ -31,11 +31,7 @@ module ActiveModel
return apply_seconds_precision(value) unless value.is_a?(::String)
return if value.empty?
if value.start_with?("2000-01-01")
dummy_time_value = value
else
dummy_time_value = "2000-01-01 #{value}"
end
dummy_time_value = value.sub(/\A(\d\d\d\d-\d\d-\d\d |)/, "2000-01-01 ")
fast_string_to_time(dummy_time_value) || begin
time_hash = ::Date._parse(dummy_time_value)

View file

@ -17,7 +17,7 @@ module ActiveRecord
end
def quoted_time(value)
quoted_date(value)
quoted_date(value).sub(/\A\d\d\d\d-\d\d-\d\d /, "2000-01-01 ")
end
def quoted_binary(value)

View file

@ -55,4 +55,11 @@ class SQLite3QuotingTest < ActiveRecord::SQLite3TestCase
assert_equal "'2000-01-01 12:30:00.999999'", @conn.quote(type.serialize(value))
end
def test_quoted_time_normalizes_date_qualified_time
value = ::Time.utc(2018, 3, 11, 12, 30, 0, 999999)
type = ActiveRecord::Type::Time.new
assert_equal "'2000-01-01 12:30:00.999999'", @conn.quote(type.serialize(value))
end
end