From dc45abe7fec31c6a1ebad457db15f1e6a36875ba Mon Sep 17 00:00:00 2001 From: Daniel Kukula Date: Tue, 31 Dec 2024 16:39:08 +0100 Subject: [PATCH 1/2] refcator datetime modules --- lib/elixir/lib/calendar/datetime.ex | 83 ++++++++++++++++------- lib/elixir/lib/calendar/naive_datetime.ex | 28 +++++--- 2 files changed, 77 insertions(+), 34 deletions(-) diff --git a/lib/elixir/lib/calendar/datetime.ex b/lib/elixir/lib/calendar/datetime.ex index 76c5d33ed1e..f3837eecd86 100644 --- a/lib/elixir/lib/calendar/datetime.ex +++ b/lib/elixir/lib/calendar/datetime.ex @@ -1092,8 +1092,21 @@ defmodule DateTime do @spec to_iso8601(Calendar.datetime(), :basic | :extended, nil | integer()) :: String.t() def to_iso8601(datetime, format \\ :extended, offset \\ nil) - def to_iso8601(%{calendar: Calendar.ISO} = datetime, format, nil) + def to_iso8601(%{calendar: Calendar.ISO} = datetime, format, offset) do + datetime + |> to_iso8601_iodata(format, offset) + |> IO.iodata_to_binary() + end + + def to_iso8601(%{calendar: _} = datetime, format, offset) when format in [:extended, :basic] do + datetime + |> convert!(Calendar.ISO) + |> to_iso8601(format, offset) + end + + defp to_iso8601_iodata(datetime, format, nil) + when format in [:extended, :basic] do %{ year: year, month: month, @@ -1107,35 +1120,53 @@ defmodule DateTime do std_offset: std_offset } = datetime - datetime_to_string(year, month, day, hour, minute, second, microsecond, format) <> - Calendar.ISO.offset_to_string(utc_offset, std_offset, time_zone, format) + [ + datetime_to_iodata(year, month, day, hour, minute, second, microsecond, format), + Calendar.ISO.offset_to_iodata(utc_offset, std_offset, time_zone, format) + ] end - def to_iso8601( - %{calendar: Calendar.ISO, microsecond: {_, precision}, time_zone: "Etc/UTC"} = datetime, - format, - 0 - ) - when format in [:extended, :basic] do + defp to_iso8601_iodata( + %{microsecond: {_, precision}, time_zone: "Etc/UTC"} = datetime, + format, + 0 + ) + when format in [:extended, :basic] do {year, month, day, hour, minute, second, {microsecond, _}} = shift_by_offset(datetime, 0) - datetime_to_string(year, month, day, hour, minute, second, {microsecond, precision}, format) <> - "Z" + [ + datetime_to_iodata( + year, + month, + day, + hour, + minute, + second, + {microsecond, precision}, + format + ), + ?Z + ] end - def to_iso8601(%{calendar: Calendar.ISO} = datetime, format, offset) - when format in [:extended, :basic] do + defp to_iso8601_iodata(datetime, format, offset) + when format in [:extended, :basic] do {_, precision} = datetime.microsecond {year, month, day, hour, minute, second, {microsecond, _}} = shift_by_offset(datetime, offset) - datetime_to_string(year, month, day, hour, minute, second, {microsecond, precision}, format) <> - Calendar.ISO.offset_to_string(offset, 0, nil, format) - end - - def to_iso8601(%{calendar: _} = datetime, format, offset) when format in [:extended, :basic] do - datetime - |> convert!(Calendar.ISO) - |> to_iso8601(format, offset) + [ + datetime_to_iodata( + year, + month, + day, + hour, + minute, + second, + {microsecond, precision}, + format + ), + Calendar.ISO.offset_to_iodata(offset, 0, nil, format) + ] end defp shift_by_offset(%{calendar: calendar} = datetime, offset) do @@ -1148,10 +1179,12 @@ defmodule DateTime do |> calendar.naive_datetime_from_iso_days() end - defp datetime_to_string(year, month, day, hour, minute, second, microsecond, format) do - Calendar.ISO.date_to_string(year, month, day, format) <> - "T" <> - Calendar.ISO.time_to_string(hour, minute, second, microsecond, format) + defp datetime_to_iodata(year, month, day, hour, minute, second, microsecond, format) do + [ + Calendar.ISO.date_to_iodata(year, month, day, format), + ?T, + Calendar.ISO.time_to_iodata(hour, minute, second, microsecond, format) + ] end @doc """ diff --git a/lib/elixir/lib/calendar/naive_datetime.ex b/lib/elixir/lib/calendar/naive_datetime.ex index 01dab368112..67c2a6dfde8 100644 --- a/lib/elixir/lib/calendar/naive_datetime.ex +++ b/lib/elixir/lib/calendar/naive_datetime.ex @@ -928,8 +928,21 @@ defmodule NaiveDateTime do @spec to_iso8601(Calendar.naive_datetime(), :basic | :extended) :: String.t() def to_iso8601(naive_datetime, format \\ :extended) - def to_iso8601(%{calendar: Calendar.ISO} = naive_datetime, format) + def to_iso8601(%{calendar: Calendar.ISO} = naive_datetime, format) do + naive_datetime + |> to_iso8601_iodata(format) + |> IO.iodata_to_binary() + end + + def to_iso8601(%{calendar: _} = naive_datetime, format) when format in [:basic, :extended] do + naive_datetime + |> convert!(Calendar.ISO) + |> to_iso8601(format) + end + + defp to_iso8601_iodata(naive_datetime, format) + when format in [:basic, :extended] do %{ year: year, month: month, @@ -940,14 +953,11 @@ defmodule NaiveDateTime do microsecond: microsecond } = naive_datetime - Calendar.ISO.date_to_string(year, month, day, format) <> - "T" <> Calendar.ISO.time_to_string(hour, minute, second, microsecond, format) - end - - def to_iso8601(%{calendar: _} = naive_datetime, format) when format in [:basic, :extended] do - naive_datetime - |> convert!(Calendar.ISO) - |> to_iso8601(format) + [ + Calendar.ISO.date_to_iodata(year, month, day, format), + ?T, + Calendar.ISO.time_to_iodata(hour, minute, second, microsecond, format) + ] end @doc """ From b32d7e2348bc95ad3049fcfc116f69f8809a8982 Mon Sep 17 00:00:00 2001 From: Daniel Kukula Date: Tue, 31 Dec 2024 16:43:38 +0100 Subject: [PATCH 2/2] move guards to top level' --- lib/elixir/lib/calendar/datetime.ex | 12 +++++------- lib/elixir/lib/calendar/naive_datetime.ex | 6 +++--- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/lib/elixir/lib/calendar/datetime.ex b/lib/elixir/lib/calendar/datetime.ex index f3837eecd86..10952097eed 100644 --- a/lib/elixir/lib/calendar/datetime.ex +++ b/lib/elixir/lib/calendar/datetime.ex @@ -1092,7 +1092,8 @@ defmodule DateTime do @spec to_iso8601(Calendar.datetime(), :basic | :extended, nil | integer()) :: String.t() def to_iso8601(datetime, format \\ :extended, offset \\ nil) - def to_iso8601(%{calendar: Calendar.ISO} = datetime, format, offset) do + def to_iso8601(%{calendar: Calendar.ISO} = datetime, format, offset) + when format in [:extended, :basic] do datetime |> to_iso8601_iodata(format, offset) |> IO.iodata_to_binary() @@ -1105,8 +1106,7 @@ defmodule DateTime do |> to_iso8601(format, offset) end - defp to_iso8601_iodata(datetime, format, nil) - when format in [:extended, :basic] do + defp to_iso8601_iodata(datetime, format, nil) do %{ year: year, month: month, @@ -1130,8 +1130,7 @@ defmodule DateTime do %{microsecond: {_, precision}, time_zone: "Etc/UTC"} = datetime, format, 0 - ) - when format in [:extended, :basic] do + ) do {year, month, day, hour, minute, second, {microsecond, _}} = shift_by_offset(datetime, 0) [ @@ -1149,8 +1148,7 @@ defmodule DateTime do ] end - defp to_iso8601_iodata(datetime, format, offset) - when format in [:extended, :basic] do + defp to_iso8601_iodata(datetime, format, offset) do {_, precision} = datetime.microsecond {year, month, day, hour, minute, second, {microsecond, _}} = shift_by_offset(datetime, offset) diff --git a/lib/elixir/lib/calendar/naive_datetime.ex b/lib/elixir/lib/calendar/naive_datetime.ex index 67c2a6dfde8..cfff254f923 100644 --- a/lib/elixir/lib/calendar/naive_datetime.ex +++ b/lib/elixir/lib/calendar/naive_datetime.ex @@ -928,7 +928,8 @@ defmodule NaiveDateTime do @spec to_iso8601(Calendar.naive_datetime(), :basic | :extended) :: String.t() def to_iso8601(naive_datetime, format \\ :extended) - def to_iso8601(%{calendar: Calendar.ISO} = naive_datetime, format) do + def to_iso8601(%{calendar: Calendar.ISO} = naive_datetime, format) + when format in [:basic, :extended] do naive_datetime |> to_iso8601_iodata(format) |> IO.iodata_to_binary() @@ -941,8 +942,7 @@ defmodule NaiveDateTime do |> to_iso8601(format) end - defp to_iso8601_iodata(naive_datetime, format) - when format in [:basic, :extended] do + defp to_iso8601_iodata(naive_datetime, format) do %{ year: year, month: month,