Skip to content

Commit 3db4da0

Browse files
committed
fix: Retain float microsecond value when formatting datetime
1 parent 83d4a32 commit 3db4da0

File tree

5 files changed

+29
-26
lines changed

5 files changed

+29
-26
lines changed

lib/ecto/adapters/sqlite3/codec.ex

+3-7
Original file line numberDiff line numberDiff line change
@@ -114,16 +114,12 @@ defmodule Ecto.Adapters.SQLite3.Codec do
114114
end
115115

116116
@text_datetime_format "%Y-%m-%d %H:%M:%S"
117-
@iso8601_format "%Y-%m-%dT%H:%M:%S"
118-
119-
def datetime_format(:text_datetime), do: @text_datetime_format
120-
def datetime_format(_), do: @iso8601_format
121117

122118
def utc_datetime_encode(nil, :iso8601), do: {:ok, nil}
123119
def utc_datetime_encode(nil, :text_datetime), do: {:ok, nil}
124120

125-
def utc_datetime_encode(%{time_zone: "Etc/UTC"} = value, :iso8601) do
126-
{:ok, Calendar.strftime(value, @iso8601_format)}
121+
def utc_datetime_encode(%DateTime{time_zone: "Etc/UTC"} = value, :iso8601) do
122+
{:ok, DateTime.to_iso8601(value)}
127123
end
128124

129125
def utc_datetime_encode(%{time_zone: "Etc/UTC"} = value, :text_datetime) do
@@ -139,7 +135,7 @@ defmodule Ecto.Adapters.SQLite3.Codec do
139135
def naive_datetime_encode(nil, :text_datetime), do: {:ok, nil}
140136

141137
def naive_datetime_encode(value, :iso8601) do
142-
{:ok, Calendar.strftime(value, @iso8601_format)}
138+
{:ok, NaiveDateTime.to_iso8601(value)}
143139
end
144140

145141
def naive_datetime_encode(value, :text_datetime) do

lib/ecto/adapters/sqlite3/connection.ex

+8-1
Original file line numberDiff line numberDiff line change
@@ -1372,7 +1372,14 @@ defmodule Ecto.Adapters.SQLite3.Connection do
13721372
@datetime_type Application.compile_env(:ecto_sqlite3, :datetime_type, :iso8601)
13731373

13741374
defp expr({:datetime_add, _, [datetime, count, interval]}, sources, query) do
1375-
format = Ecto.Adapters.SQLite3.Codec.datetime_format(@datetime_type)
1375+
format =
1376+
case @datetime_type do
1377+
:text_datetime ->
1378+
"%Y-%m-%d %H:%M:%f000Z"
1379+
1380+
_ ->
1381+
"%Y-%m-%dT%H:%M:%f000Z"
1382+
end
13761383

13771384
[
13781385
"CAST (",

test/ecto/adapters/sqlite3/codec_test.exs

+15-15
Original file line numberDiff line numberDiff line change
@@ -144,26 +144,26 @@ defmodule Ecto.Adapters.SQLite3.CodecTest do
144144
end
145145

146146
describe ".utc_datetime_encode/2" do
147-
setup do
148-
[dt: ~U[2021-08-25 10:58:59Z]]
149-
end
150-
151147
test "nil" do
152148
assert {:ok, nil} = Codec.utc_datetime_encode(nil, :iso8601)
153149
assert {:ok, nil} = Codec.utc_datetime_encode(nil, :text_datetime)
154150
end
155151

156-
test "iso8601", %{dt: dt} do
157-
dt_str = "2021-08-25T10:58:59"
152+
test "iso8601" do
153+
dt = ~U[2021-08-25 10:58:59Z]
154+
dt_str = "2021-08-25T10:58:59Z"
158155
assert {:ok, ^dt_str} = Codec.utc_datetime_encode(dt, :iso8601)
159156
end
160157

161-
test ":text_datetime", %{dt: dt} do
158+
test ":text_datetime" do
159+
dt = ~U[2021-08-25 10:58:59Z]
162160
dt_str = "2021-08-25 10:58:59"
163161
assert {:ok, ^dt_str} = Codec.utc_datetime_encode(dt, :text_datetime)
164162
end
165163

166-
test "unknown datetime type", %{dt: dt} do
164+
test "unknown datetime type" do
165+
dt = ~U[2021-08-25 10:58:59Z]
166+
167167
msg =
168168
"expected datetime type to be either `:iso8601` or `:text_datetime`, but received `:whatsthis`"
169169

@@ -174,26 +174,26 @@ defmodule Ecto.Adapters.SQLite3.CodecTest do
174174
end
175175

176176
describe ".naive_datetime_encode/2" do
177-
setup do
178-
[dt: ~U[2021-08-25 10:58:59Z], dt_str: "2021-08-25T10:58:59"]
179-
end
180-
181177
test "nil" do
182178
assert {:ok, nil} = Codec.naive_datetime_encode(nil, :iso8601)
183179
assert {:ok, nil} = Codec.naive_datetime_encode(nil, :text_datetime)
184180
end
185181

186-
test "iso8601", %{dt: dt} do
182+
test "iso8601" do
183+
dt = ~U[2021-08-25 10:58:59Z]
187184
dt_str = "2021-08-25T10:58:59"
188185
assert {:ok, ^dt_str} = Codec.naive_datetime_encode(dt, :iso8601)
189186
end
190187

191-
test ":text_datetime", %{dt: dt} do
188+
test ":text_datetime" do
189+
dt = ~U[2021-08-25 10:58:59Z]
192190
dt_str = "2021-08-25 10:58:59"
193191
assert {:ok, ^dt_str} = Codec.naive_datetime_encode(dt, :text_datetime)
194192
end
195193

196-
test "unknown datetime type", %{dt: dt} do
194+
test "unknown datetime type" do
195+
dt = ~U[2021-08-25 10:58:59Z]
196+
197197
msg =
198198
"expected datetime type to be either `:iso8601` or `:text_datetime`, but received `:whatsthis`"
199199

test/ecto/adapters/sqlite3/connection/datetime_add_test.exs

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ defmodule Ecto.Adapters.SQLite3.Connection.DatetimeAddTest do
1111
|> select([], true)
1212
|> plan()
1313

14-
assert ~s{SELECT 1 FROM "schema" AS s0 WHERE (CAST (strftime('%Y-%m-%dT%H:%M:%S',s0.\"foo\",1 || ' month') AS TEXT) > s0."bar")} ==
14+
assert ~s{SELECT 1 FROM "schema" AS s0 WHERE (CAST (strftime('%Y-%m-%dT%H:%M:%f000Z',s0.\"foo\",1 || ' month') AS TEXT) > s0."bar")} ==
1515
all(query)
1616
end
1717

@@ -22,7 +22,7 @@ defmodule Ecto.Adapters.SQLite3.Connection.DatetimeAddTest do
2222
|> select([], true)
2323
|> plan()
2424

25-
assert ~s{SELECT 1 FROM "schema" AS s0 WHERE (CAST (strftime('%Y-%m-%dT%H:%M:%S',CAST(s0.\"foo\" AS TEXT),1 || ' month') AS TEXT) > s0."bar")} ==
25+
assert ~s{SELECT 1 FROM "schema" AS s0 WHERE (CAST (strftime('%Y-%m-%dT%H:%M:%f000Z',CAST(s0.\"foo\" AS TEXT),1 || ' month') AS TEXT) > s0."bar")} ==
2626
all(query)
2727
end
2828
end

test/ecto/integration/timestamps_test.exs

+1-1
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ defmodule Ecto.Integration.TimestampsTest do
197197
})
198198

199199
assert [
200-
%{name: "Foo"},
200+
%{name: "Foo"}
201201
] =
202202
Product
203203
|> select([p], p)

0 commit comments

Comments
 (0)