Skip to content

Commit

Permalink
fix: Retain float microsecond value when formatting datetime
Browse files Browse the repository at this point in the history
  • Loading branch information
warmwaffles committed Sep 5, 2024
1 parent 83d4a32 commit 3db4da0
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 26 deletions.
10 changes: 3 additions & 7 deletions lib/ecto/adapters/sqlite3/codec.ex
Original file line number Diff line number Diff line change
Expand Up @@ -114,16 +114,12 @@ defmodule Ecto.Adapters.SQLite3.Codec do
end

@text_datetime_format "%Y-%m-%d %H:%M:%S"
@iso8601_format "%Y-%m-%dT%H:%M:%S"

def datetime_format(:text_datetime), do: @text_datetime_format
def datetime_format(_), do: @iso8601_format

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

def utc_datetime_encode(%{time_zone: "Etc/UTC"} = value, :iso8601) do
{:ok, Calendar.strftime(value, @iso8601_format)}
def utc_datetime_encode(%DateTime{time_zone: "Etc/UTC"} = value, :iso8601) do
{:ok, DateTime.to_iso8601(value)}
end

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

def naive_datetime_encode(value, :iso8601) do
{:ok, Calendar.strftime(value, @iso8601_format)}
{:ok, NaiveDateTime.to_iso8601(value)}
end

def naive_datetime_encode(value, :text_datetime) do
Expand Down
9 changes: 8 additions & 1 deletion lib/ecto/adapters/sqlite3/connection.ex
Original file line number Diff line number Diff line change
Expand Up @@ -1372,7 +1372,14 @@ defmodule Ecto.Adapters.SQLite3.Connection do
@datetime_type Application.compile_env(:ecto_sqlite3, :datetime_type, :iso8601)

defp expr({:datetime_add, _, [datetime, count, interval]}, sources, query) do
format = Ecto.Adapters.SQLite3.Codec.datetime_format(@datetime_type)
format =
case @datetime_type do
:text_datetime ->
"%Y-%m-%d %H:%M:%f000Z"

_ ->
"%Y-%m-%dT%H:%M:%f000Z"
end

[
"CAST (",
Expand Down
30 changes: 15 additions & 15 deletions test/ecto/adapters/sqlite3/codec_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -144,26 +144,26 @@ defmodule Ecto.Adapters.SQLite3.CodecTest do
end

describe ".utc_datetime_encode/2" do
setup do
[dt: ~U[2021-08-25 10:58:59Z]]
end

test "nil" do
assert {:ok, nil} = Codec.utc_datetime_encode(nil, :iso8601)
assert {:ok, nil} = Codec.utc_datetime_encode(nil, :text_datetime)
end

test "iso8601", %{dt: dt} do
dt_str = "2021-08-25T10:58:59"
test "iso8601" do
dt = ~U[2021-08-25 10:58:59Z]
dt_str = "2021-08-25T10:58:59Z"
assert {:ok, ^dt_str} = Codec.utc_datetime_encode(dt, :iso8601)
end

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

test "unknown datetime type", %{dt: dt} do
test "unknown datetime type" do
dt = ~U[2021-08-25 10:58:59Z]

msg =
"expected datetime type to be either `:iso8601` or `:text_datetime`, but received `:whatsthis`"

Expand All @@ -174,26 +174,26 @@ defmodule Ecto.Adapters.SQLite3.CodecTest do
end

describe ".naive_datetime_encode/2" do
setup do
[dt: ~U[2021-08-25 10:58:59Z], dt_str: "2021-08-25T10:58:59"]
end

test "nil" do
assert {:ok, nil} = Codec.naive_datetime_encode(nil, :iso8601)
assert {:ok, nil} = Codec.naive_datetime_encode(nil, :text_datetime)
end

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

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

test "unknown datetime type", %{dt: dt} do
test "unknown datetime type" do
dt = ~U[2021-08-25 10:58:59Z]

msg =
"expected datetime type to be either `:iso8601` or `:text_datetime`, but received `:whatsthis`"

Expand Down
4 changes: 2 additions & 2 deletions test/ecto/adapters/sqlite3/connection/datetime_add_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ defmodule Ecto.Adapters.SQLite3.Connection.DatetimeAddTest do
|> select([], true)
|> plan()

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")} ==
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")} ==
all(query)
end

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

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")} ==
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")} ==
all(query)
end
end
2 changes: 1 addition & 1 deletion test/ecto/integration/timestamps_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ defmodule Ecto.Integration.TimestampsTest do
})

assert [
%{name: "Foo"},
%{name: "Foo"}
] =
Product
|> select([p], p)
Expand Down

0 comments on commit 3db4da0

Please sign in to comment.