Files
music_library/lib/music_library_web/duration.ex
T
Claudio Ortolina 7cf9b4e7f8 First pass at uniformed types, specs and docs
- spec public functions (skipping controllers, views, live views and
components)
- use types instead of explanations in docs
- remove redundant docs
- fix typos
2026-03-06 08:33:11 +00:00

63 lines
1.4 KiB
Elixir

defmodule MusicLibraryWeb.Duration do
@moduledoc """
Formats durations from milliseconds to human-readable strings.
"""
@doc """
Formats a duration in milliseconds as a human-readable string.
## Examples
iex> MusicLibraryWeb.Duration.format_duration(30_000)
"0:30"
iex> MusicLibraryWeb.Duration.format_duration(90_000)
"1:30"
iex> MusicLibraryWeb.Duration.format_duration(3_723_000)
"1:02:03"
iex> MusicLibraryWeb.Duration.format_duration(0)
"0:00"
"""
@spec format_duration(non_neg_integer()) :: String.t()
def format_duration(milliseconds) do
milliseconds
|> System.convert_time_unit(:millisecond, :second)
|> format_seconds()
end
defp format_seconds(seconds) when seconds <= 59 do
"0:#{zero_pad(seconds)}"
end
defp format_seconds(seconds) do
minutes = div(seconds, 60)
remaining_seconds = rem(seconds, 60)
format_minutes(minutes, remaining_seconds)
end
defp format_minutes(minutes, seconds) when minutes <= 59 do
"#{minutes}:#{zero_pad(seconds)}"
end
defp format_minutes(minutes, seconds) do
hours = div(minutes, 60)
remaining_minutes = rem(minutes, 60)
format_hours(hours, remaining_minutes, seconds)
end
defp format_hours(hours, minutes, seconds) do
"#{hours}:#{zero_pad(minutes)}:#{zero_pad(seconds)}"
end
defp zero_pad(integer) do
integer
|> to_string()
|> String.pad_leading(2, "0")
end
end