Skip to content

Commit 4f66340

Browse files
committed
dk_use_iodata_when_formatting_dates
1 parent b0abc2b commit 4f66340

File tree

1 file changed

+98
-30
lines changed

1 file changed

+98
-30
lines changed

lib/elixir/lib/calendar/iso.ex

Lines changed: 98 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,6 +1220,17 @@ defmodule Calendar.ISO do
12201220
:basic | :extended
12211221
) :: String.t()
12221222
def time_to_string(
1223+
hour,
1224+
minute,
1225+
second,
1226+
microsecond,
1227+
format \\ :extended
1228+
) do
1229+
time_to_iodata(hour, minute, second, microsecond, format)
1230+
|> IO.iodata_to_binary()
1231+
end
1232+
1233+
def time_to_iodata(
12231234
hour,
12241235
minute,
12251236
second,
@@ -1228,24 +1239,27 @@ defmodule Calendar.ISO do
12281239
)
12291240
when is_hour(hour) and is_minute(minute) and is_second(second) and
12301241
is_microsecond(ms_value, ms_precision) and format in [:basic, :extended] do
1231-
time_to_string_guarded(hour, minute, second, microsecond, format)
1242+
time_to_iodata_guarded(hour, minute, second, microsecond, format)
12321243
end
12331244

1234-
defp time_to_string_guarded(hour, minute, second, {_, 0}, format) do
1235-
time_to_string_format(hour, minute, second, format)
1245+
defp time_to_iodata_guarded(hour, minute, second, {_, 0}, format) do
1246+
time_to_iodata_format(hour, minute, second, format)
12361247
end
12371248

1238-
defp time_to_string_guarded(hour, minute, second, {microsecond, precision}, format) do
1239-
time_to_string_format(hour, minute, second, format) <>
1240-
"." <> (microsecond |> zero_pad(6) |> binary_part(0, precision))
1249+
defp time_to_iodata_guarded(hour, minute, second, {microsecond, precision}, format) do
1250+
[
1251+
time_to_iodata_format(hour, minute, second, format),
1252+
".",
1253+
microsecond |> zero_pad(6) |> IO.iodata_to_binary() |> binary_part(0, precision)
1254+
]
12411255
end
12421256

1243-
defp time_to_string_format(hour, minute, second, :extended) do
1244-
zero_pad(hour, 2) <> ":" <> zero_pad(minute, 2) <> ":" <> zero_pad(second, 2)
1257+
defp time_to_iodata_format(hour, minute, second, :extended) do
1258+
[zero_pad(hour, 2), ":", zero_pad(minute, 2), ":", zero_pad(second, 2)]
12451259
end
12461260

1247-
defp time_to_string_format(hour, minute, second, :basic) do
1248-
zero_pad(hour, 2) <> zero_pad(minute, 2) <> zero_pad(second, 2)
1261+
defp time_to_iodata_format(hour, minute, second, :basic) do
1262+
[zero_pad(hour, 2), zero_pad(minute, 2), zero_pad(second, 2)]
12491263
end
12501264

12511265
@doc """
@@ -1273,18 +1287,27 @@ defmodule Calendar.ISO do
12731287
@doc since: "1.4.0"
12741288
@spec date_to_string(year, month, day, :basic | :extended) :: String.t()
12751289
@impl true
1276-
def date_to_string(year, month, day, format \\ :extended)
1290+
def date_to_string(year, month, day, format \\ :extended) do
1291+
date_to_iodata(year, month, day, format)
1292+
|> IO.iodata_to_binary()
1293+
end
1294+
1295+
def date_to_iodata(year, month, day, format \\ :extended)
12771296
when is_integer(year) and is_integer(month) and is_integer(day) and
12781297
format in [:basic, :extended] do
1279-
date_to_string_guarded(year, month, day, format)
1298+
date_to_iodata_guarded(year, month, day, format)
12801299
end
12811300

1282-
defp date_to_string_guarded(year, month, day, :extended) do
1283-
zero_pad(year, 4) <> "-" <> zero_pad(month, 2) <> "-" <> zero_pad(day, 2)
1301+
defp date_to_iodata_guarded(year, month, day, :extended) do
1302+
[zero_pad(year, 4), "-", zero_pad(month, 2), "-", zero_pad(day, 2)]
12841303
end
12851304

1286-
defp date_to_string_guarded(year, month, day, :basic) do
1287-
zero_pad(year, 4) <> zero_pad(month, 2) <> zero_pad(day, 2)
1305+
defp date_to_iodata_guarded(year, month, day, :basic) do
1306+
[
1307+
zero_pad(year, 4),
1308+
zero_pad(month, 2),
1309+
zero_pad(day, 2)
1310+
]
12881311
end
12891312

12901313
@doc """
@@ -1327,8 +1350,34 @@ defmodule Calendar.ISO do
13271350
microsecond,
13281351
format \\ :extended
13291352
) do
1330-
date_to_string(year, month, day, format) <>
1331-
" " <> time_to_string(hour, minute, second, microsecond, format)
1353+
naive_datetime_to_iodata(
1354+
year,
1355+
month,
1356+
day,
1357+
hour,
1358+
minute,
1359+
second,
1360+
microsecond,
1361+
format
1362+
)
1363+
|> IO.iodata_to_binary()
1364+
end
1365+
1366+
def naive_datetime_to_iodata(
1367+
year,
1368+
month,
1369+
day,
1370+
hour,
1371+
minute,
1372+
second,
1373+
microsecond,
1374+
format \\ :extended
1375+
) do
1376+
[
1377+
date_to_iodata(year, month, day, format),
1378+
" ",
1379+
time_to_iodata(hour, minute, second, microsecond, format)
1380+
]
13321381
end
13331382

13341383
@doc """
@@ -1397,17 +1446,27 @@ defmodule Calendar.ISO do
13971446
)
13981447
when is_time_zone(time_zone) and is_zone_abbr(zone_abbr) and is_utc_offset(utc_offset) and
13991448
is_std_offset(std_offset) do
1400-
date_to_string(year, month, day, format) <>
1401-
" " <>
1402-
time_to_string(hour, minute, second, microsecond, format) <>
1403-
offset_to_string(utc_offset, std_offset, time_zone, format) <>
1404-
zone_to_string(utc_offset, std_offset, zone_abbr, time_zone)
1449+
[
1450+
date_to_iodata(year, month, day, format),
1451+
" ",
1452+
time_to_iodata(hour, minute, second, microsecond, format),
1453+
offset_to_iodata(utc_offset, std_offset, time_zone, format),
1454+
zone_to_iodata(utc_offset, std_offset, zone_abbr, time_zone)
1455+
]
1456+
|> IO.iodata_to_binary()
14051457
end
14061458

14071459
@doc false
14081460
def offset_to_string(0, 0, "Etc/UTC", _format), do: "Z"
14091461

1410-
def offset_to_string(utc, std, _zone, format) do
1462+
def offset_to_string(utc, std, zone, format) do
1463+
offset_to_iodata(utc, std, zone, format)
1464+
|> IO.iodata_to_binary()
1465+
end
1466+
1467+
def offset_to_iodata(0, 0, "Etc/UTC", _format), do: "Z"
1468+
1469+
def offset_to_iodata(utc, std, _zone, format) do
14111470
total = utc + std
14121471
second = abs(total)
14131472
minute = second |> rem(3600) |> div(60)
@@ -1416,15 +1475,15 @@ defmodule Calendar.ISO do
14161475
end
14171476

14181477
defp format_offset(total, hour, minute, :extended) do
1419-
sign(total) <> zero_pad(hour, 2) <> ":" <> zero_pad(minute, 2)
1478+
[sign(total), zero_pad(hour, 2), ":", zero_pad(minute, 2)]
14201479
end
14211480

14221481
defp format_offset(total, hour, minute, :basic) do
1423-
sign(total) <> zero_pad(hour, 2) <> zero_pad(minute, 2)
1482+
[sign(total), zero_pad(hour, 2), zero_pad(minute, 2)]
14241483
end
14251484

1426-
defp zone_to_string(_, _, _, "Etc/UTC"), do: ""
1427-
defp zone_to_string(_, _, abbr, zone), do: " " <> abbr <> " " <> zone
1485+
defp zone_to_iodata(_, _, _, "Etc/UTC"), do: ""
1486+
defp zone_to_iodata(_, _, abbr, zone), do: [" ", abbr, " ", zone]
14281487

14291488
@doc """
14301489
Determines if the date given is valid according to the proleptic Gregorian calendar.
@@ -1490,11 +1549,20 @@ defmodule Calendar.ISO do
14901549

14911550
defp zero_pad(val, count) when val >= 0 do
14921551
num = Integer.to_string(val)
1493-
:binary.copy("0", max(count - byte_size(num), 0)) <> num
1552+
1553+
case max(count - byte_size(num), 0) do
1554+
0 -> num
1555+
1 -> ["0", num]
1556+
2 -> ["00", num]
1557+
3 -> ["000", num]
1558+
4 -> ["0000", num]
1559+
5 -> ["00000", num]
1560+
6 -> ["000000", num]
1561+
end
14941562
end
14951563

14961564
defp zero_pad(val, count) do
1497-
"-" <> zero_pad(-val, count)
1565+
["-", zero_pad(-val, count)]
14981566
end
14991567

15001568
@doc """

0 commit comments

Comments
 (0)