Использовать совпадение скороговорки:
defmodule IsoToMine do
# "1999-01-01"
def convert(<<y::binary-size(4), "-",
m::binary-size(2), "-",
d::binary-size(2)>> = iso_date),
# add {:ok, date} = Date.from_iso8601(iso_date)
# here to blow up on wrong input
do: Enum.join([y, d, m], "/")
# "18:00:00"
def convert(<<h::binary-size(2), ":",
m::binary-size(2), ":",
_::binary-size(2)>>) do
{h, apm} =
case String.to_integer(h) do
0 -> {12, "am"}
12 -> {12, "pm"}
am when am < 12 -> {am, "am"}
pm when pm > 12 -> {rem(pm, 12), "pm"}
end
to_string(h) <> ":" <> m <> apm
end
end
Теперь IsoToMine.convert/1
всеяден:
iex|1 ▶ IsoToMine.convert "1999-01-01"
#⇒ "1999/01/01"
iex|2 ▶ IsoToMine.convert "12:03:01"
#⇒ "12:03pm"
iex|3 ▶ IsoToMine.convert "11:03:01"
#⇒ "11:03am"
iex|4 ▶ IsoToMine.convert "18:03:01"
#⇒ "6:03pm"
Обратите внимание, что вышеприведенные функции не проверяют ввод и могут взорвать исключение MatchError
/ NoFunctionClause
при неправильном вводе, но я просто повторил начальное поведение как в вашем коде (сохранить потому что вы взрываетесь в хорошо отформатированных, но невозможных датах, и моя радостно бежит.)
Добавление проверок и / или изящного отката на неправильный ввод - очень легкая задача, которую я оставляю вам в качестве упражнения.