diff --git a/lib/elixir/lib/calendar/datetime.ex b/lib/elixir/lib/calendar/datetime.ex index 19776dbff33..b945c0ab99b 100644 --- a/lib/elixir/lib/calendar/datetime.ex +++ b/lib/elixir/lib/calendar/datetime.ex @@ -1599,11 +1599,13 @@ defmodule DateTime do end naive_diff = - (datetime1 |> to_iso_days() |> Calendar.ISO.iso_days_to_unit(unit)) - - (datetime2 |> to_iso_days() |> Calendar.ISO.iso_days_to_unit(unit)) + (datetime1 |> to_iso_days() |> Calendar.ISO.iso_days_to_unit(:microsecond)) - + (datetime2 |> to_iso_days() |> Calendar.ISO.iso_days_to_unit(:microsecond)) offset_diff = utc_offset2 + std_offset2 - (utc_offset1 + std_offset1) - naive_diff + System.convert_time_unit(offset_diff, :second, unit) + + System.convert_time_unit(naive_diff, :microsecond, unit) + + System.convert_time_unit(offset_diff, :second, unit) end @doc """ diff --git a/lib/elixir/test/elixir/calendar/datetime_test.exs b/lib/elixir/test/elixir/calendar/datetime_test.exs index 8699825e0ff..712e34633ee 100644 --- a/lib/elixir/test/elixir/calendar/datetime_test.exs +++ b/lib/elixir/test/elixir/calendar/datetime_test.exs @@ -807,6 +807,24 @@ defmodule DateTimeTest do # Test with a non-struct map conforming to Calendar.datetime assert DateTime.diff(Map.from_struct(dt1), Map.from_struct(dt2)) == 3_281_904_000 end + + test "diff with microseconds" do + datetime = ~U[2023-02-01 10:30:10.123456Z] + + in_almost_7_days = + datetime + |> DateTime.add(7, :day) + |> DateTime.add(-1, :microsecond) + + assert DateTime.diff(in_almost_7_days, datetime, :day) == 6 + end + + test "diff in microseconds" do + datetime1 = ~U[2023-02-01 10:30:10.000000Z] + datetime2 = DateTime.add(datetime1, 1234, :microsecond) + + assert DateTime.diff(datetime1, datetime2, :microsecond) == -1234 + end end describe "from_naive" do