Packages
moar
1.4.0
5.0.0
4.3.0
4.2.0
4.1.0
4.0.0
3.2.0
3.1.0
3.0.0
2.7.0
2.6.0
2.5.0
2.4.2
2.4.1
2.4.0
2.3.0
2.2.0
2.1.0
2.0.1
2.0.0
1.64.0
1.63.1
1.63.0
1.62.0
1.61.2
1.61.1
1.61.0
1.60.0
1.59.2
1.59.1
1.59.0
1.58.0
1.57.0
1.56.2
1.56.1
1.56.0
1.55.0
1.54.0
1.53.0
1.52.1
1.52.0
1.51.0
1.50.0
1.49.0
1.48.0
1.47.0
1.46.0
1.45.1
1.45.0
1.44.0
1.43.0
1.42.0
1.41.0
1.40.0
1.39.0
1.38.0
1.37.0
1.36.0
1.35.0
1.34.0
1.33.0
1.32.0
1.31.0
1.30.0
1.29.0
1.28.0
1.27.0
1.26.0
1.25.0
1.24.1
1.24.0
1.23.0
1.22.0
1.21.0
1.20.0
1.19.3
1.19.2
1.19.1
1.19.0
1.18.1
1.18.0
1.17.0
1.16.0
1.15.0
1.14.0
1.13.1
1.13.0
1.12.0
1.11.0
1.10.0
1.9.0
1.8.0
1.7.0
1.6.0
1.5.0
1.4.0
1.3.0
1.2.0
1.1.0
1.0.0
0.1.0
A dependency-free utility library containing 100+ useful functions.
Current section
Files
Jump to
Current section
Files
lib/duration.ex
defmodule Moar.Duration do
# @related [test](/test/duration_test.exs)
@moduledoc """
A duration is a `{time, unit}` tuple.
The time is a number and the unit is one of:
`:nanosecond`, `:microsecond`, `:millisecond`, `:second`, `:minute`, `:hour`, `:day`.
"""
@seconds_per_minute 60
@seconds_per_hour 60 * 60
@seconds_per_day 60 * 60 * 24
@type t() :: {time :: number(), unit :: time_unit()}
@type time_unit() :: :nanosecond | :microsecond | :millisecond | :second | :minute | :hour | :day
@doc """
Converts a `{duration, time_unit}` tuple into a numeric duration, rounding down to the nearest whole number.
Uses `System.convert_time_unit/3` under the hood; see its documentation for more details.
```elixir
iex> Moar.Duration.convert({121, :second}, :minute)
2
```
"""
@spec convert(from :: t(), to :: time_unit()) :: number()
def convert({time, :minute}, to_unit), do: convert({time * @seconds_per_minute, :second}, to_unit)
def convert({time, :hour}, to_unit), do: convert({time * @seconds_per_hour, :second}, to_unit)
def convert({time, :day}, to_unit), do: convert({time * @seconds_per_day, :second}, to_unit)
def convert(duration, :minute), do: convert(duration, :second) |> Integer.floor_div(@seconds_per_minute)
def convert(duration, :hour), do: convert(duration, :second) |> Integer.floor_div(@seconds_per_hour)
def convert(duration, :day), do: convert(duration, :second) |> Integer.floor_div(@seconds_per_day)
def convert({time, from_unit}, to_unit), do: System.convert_time_unit(time, from_unit, to_unit)
@doc """
Converts a `{duration, time_unit}` tuple into a string.
```elixir
iex> Moar.Duration.to_string({1, :second})
"1 second"
iex> Moar.Duration.to_string({25, :millisecond})
"25 milliseconds"
```
"""
@spec to_string({duration :: t(), unit :: time_unit()}) :: String.t()
def to_string({1, unit}), do: "1 #{unit}"
def to_string({-1, unit}), do: "-1 #{unit}"
def to_string({time, unit}), do: "#{time} #{unit}s"
end