diff --git a/lib/elixir/lib/calendar/naive_datetime.ex b/lib/elixir/lib/calendar/naive_datetime.ex index df37473ee04..0c7af910141 100644 --- a/lib/elixir/lib/calendar/naive_datetime.ex +++ b/lib/elixir/lib/calendar/naive_datetime.ex @@ -570,9 +570,11 @@ defmodule NaiveDateTime do "unsupported time unit. Expected :day, :hour, :minute, :second, :millisecond, :microsecond, :nanosecond, or a positive integer, got #{inspect(unit)}" end - units1 = naive_datetime1 |> to_iso_days() |> Calendar.ISO.iso_days_to_unit(unit) - units2 = naive_datetime2 |> to_iso_days() |> Calendar.ISO.iso_days_to_unit(unit) - units1 - units2 + diff_microsecond = + (naive_datetime1 |> to_iso_days() |> Calendar.ISO.iso_days_to_unit(:microsecond)) - + (naive_datetime2 |> to_iso_days() |> Calendar.ISO.iso_days_to_unit(:microsecond)) + + System.convert_time_unit(diff_microsecond, :microsecond, unit) end @doc """ diff --git a/lib/elixir/test/elixir/calendar/naive_datetime_test.exs b/lib/elixir/test/elixir/calendar/naive_datetime_test.exs index 14e724dad3c..7c2f02f21aa 100644 --- a/lib/elixir/test/elixir/calendar/naive_datetime_test.exs +++ b/lib/elixir/test/elixir/calendar/naive_datetime_test.exs @@ -221,6 +221,29 @@ defmodule NaiveDateTimeTest do assert NaiveDateTime.diff(%{dt | second: 57}, dt, :second) == 50 end + + test "truncates the elapsed difference, not each operand (matches DateTime.diff)" do + # The true elapsed span is 0.5s (< 1s) and 86399.5s (< 1 day). Sub-second + # fractions must not inflate the count: per the "rounds incomplete days to + # zero" guarantee, and consistent with the sibling DateTime.diff/3. + assert NaiveDateTime.diff( + ~N[2000-01-01 00:00:01.200000], + ~N[2000-01-01 00:00:00.700000], + :second + ) == 0 + + assert NaiveDateTime.diff( + ~N[2000-01-02 00:00:00.200000], + ~N[2000-01-01 00:00:00.700000], + :day + ) == 0 + + assert NaiveDateTime.diff( + ~N[2000-01-01 00:00:00.001200], + ~N[2000-01-01 00:00:00.000700], + :millisecond + ) == 0 + end end test "convert/2" do