Skip to content

Commit a0fb49f

Browse files
authored
Use iodata in calendar modules (#14131)
1 parent 5579253 commit a0fb49f

File tree

2 files changed

+74
-33
lines changed

2 files changed

+74
-33
lines changed

lib/elixir/lib/calendar/datetime.ex

Lines changed: 56 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,8 +1092,21 @@ defmodule DateTime do
10921092
@spec to_iso8601(Calendar.datetime(), :basic | :extended, nil | integer()) :: String.t()
10931093
def to_iso8601(datetime, format \\ :extended, offset \\ nil)
10941094

1095-
def to_iso8601(%{calendar: Calendar.ISO} = datetime, format, nil)
1095+
def to_iso8601(%{calendar: Calendar.ISO} = datetime, format, offset)
1096+
when format in [:extended, :basic] do
1097+
datetime
1098+
|> to_iso8601_iodata(format, offset)
1099+
|> IO.iodata_to_binary()
1100+
end
1101+
1102+
def to_iso8601(%{calendar: _} = datetime, format, offset)
10961103
when format in [:extended, :basic] do
1104+
datetime
1105+
|> convert!(Calendar.ISO)
1106+
|> to_iso8601(format, offset)
1107+
end
1108+
1109+
defp to_iso8601_iodata(datetime, format, nil) do
10971110
%{
10981111
year: year,
10991112
month: month,
@@ -1107,35 +1120,51 @@ defmodule DateTime do
11071120
std_offset: std_offset
11081121
} = datetime
11091122

1110-
datetime_to_string(year, month, day, hour, minute, second, microsecond, format) <>
1111-
Calendar.ISO.offset_to_string(utc_offset, std_offset, time_zone, format)
1123+
[
1124+
datetime_to_iodata(year, month, day, hour, minute, second, microsecond, format),
1125+
Calendar.ISO.offset_to_iodata(utc_offset, std_offset, time_zone, format)
1126+
]
11121127
end
11131128

1114-
def to_iso8601(
1115-
%{calendar: Calendar.ISO, microsecond: {_, precision}, time_zone: "Etc/UTC"} = datetime,
1116-
format,
1117-
0
1118-
)
1119-
when format in [:extended, :basic] do
1129+
defp to_iso8601_iodata(
1130+
%{microsecond: {_, precision}, time_zone: "Etc/UTC"} = datetime,
1131+
format,
1132+
0
1133+
) do
11201134
{year, month, day, hour, minute, second, {microsecond, _}} = shift_by_offset(datetime, 0)
11211135

1122-
datetime_to_string(year, month, day, hour, minute, second, {microsecond, precision}, format) <>
1123-
"Z"
1136+
[
1137+
datetime_to_iodata(
1138+
year,
1139+
month,
1140+
day,
1141+
hour,
1142+
minute,
1143+
second,
1144+
{microsecond, precision},
1145+
format
1146+
),
1147+
?Z
1148+
]
11241149
end
11251150

1126-
def to_iso8601(%{calendar: Calendar.ISO} = datetime, format, offset)
1127-
when format in [:extended, :basic] do
1151+
defp to_iso8601_iodata(datetime, format, offset) do
11281152
{_, precision} = datetime.microsecond
11291153
{year, month, day, hour, minute, second, {microsecond, _}} = shift_by_offset(datetime, offset)
11301154

1131-
datetime_to_string(year, month, day, hour, minute, second, {microsecond, precision}, format) <>
1132-
Calendar.ISO.offset_to_string(offset, 0, nil, format)
1133-
end
1134-
1135-
def to_iso8601(%{calendar: _} = datetime, format, offset) when format in [:extended, :basic] do
1136-
datetime
1137-
|> convert!(Calendar.ISO)
1138-
|> to_iso8601(format, offset)
1155+
[
1156+
datetime_to_iodata(
1157+
year,
1158+
month,
1159+
day,
1160+
hour,
1161+
minute,
1162+
second,
1163+
{microsecond, precision},
1164+
format
1165+
),
1166+
Calendar.ISO.offset_to_iodata(offset, 0, nil, format)
1167+
]
11391168
end
11401169

11411170
defp shift_by_offset(%{calendar: calendar} = datetime, offset) do
@@ -1148,10 +1177,12 @@ defmodule DateTime do
11481177
|> calendar.naive_datetime_from_iso_days()
11491178
end
11501179

1151-
defp datetime_to_string(year, month, day, hour, minute, second, microsecond, format) do
1152-
Calendar.ISO.date_to_string(year, month, day, format) <>
1153-
"T" <>
1154-
Calendar.ISO.time_to_string(hour, minute, second, microsecond, format)
1180+
defp datetime_to_iodata(year, month, day, hour, minute, second, microsecond, format) do
1181+
[
1182+
Calendar.ISO.date_to_iodata(year, month, day, format),
1183+
?T,
1184+
Calendar.ISO.time_to_iodata(hour, minute, second, microsecond, format)
1185+
]
11551186
end
11561187

11571188
@doc """

lib/elixir/lib/calendar/naive_datetime.ex

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -930,6 +930,19 @@ defmodule NaiveDateTime do
930930

931931
def to_iso8601(%{calendar: Calendar.ISO} = naive_datetime, format)
932932
when format in [:basic, :extended] do
933+
naive_datetime
934+
|> to_iso8601_iodata(format)
935+
|> IO.iodata_to_binary()
936+
end
937+
938+
def to_iso8601(%{calendar: _} = naive_datetime, format)
939+
when format in [:basic, :extended] do
940+
naive_datetime
941+
|> convert!(Calendar.ISO)
942+
|> to_iso8601(format)
943+
end
944+
945+
defp to_iso8601_iodata(naive_datetime, format) do
933946
%{
934947
year: year,
935948
month: month,
@@ -940,14 +953,11 @@ defmodule NaiveDateTime do
940953
microsecond: microsecond
941954
} = naive_datetime
942955

943-
Calendar.ISO.date_to_string(year, month, day, format) <>
944-
"T" <> Calendar.ISO.time_to_string(hour, minute, second, microsecond, format)
945-
end
946-
947-
def to_iso8601(%{calendar: _} = naive_datetime, format) when format in [:basic, :extended] do
948-
naive_datetime
949-
|> convert!(Calendar.ISO)
950-
|> to_iso8601(format)
956+
[
957+
Calendar.ISO.date_to_iodata(year, month, day, format),
958+
?T,
959+
Calendar.ISO.time_to_iodata(hour, minute, second, microsecond, format)
960+
]
951961
end
952962

953963
@doc """

0 commit comments

Comments
 (0)