defmodule Timex.Time do
@moduledoc """
This module provides helper functions for working with Times
"""
@doc """
Converts an hour between 0..24 to {1..12, :am/:pm}
## Examples
iex> Timex.Time.to_12hour_clock(23)
{11, :pm}
"""
@spec to_12hour_clock(0..24) :: {1..12, :am | :pm}
def to_12hour_clock(hour) when hour in 0..24 do
case hour do
hour when hour in [0, 24] -> {12, :am}
hour when hour < 12 -> {hour, :am}
hour when hour === 12 -> {12, :pm}
hour when hour > 12 -> {hour - 12, :pm}
end
end
@doc """
Converts an hour between 1..12 in either am or pm, to value between 0..24
## Examples
iex> Timex.Time.to_24hour_clock(7, :pm)
19
"""
@spec to_24hour_clock(1..12, :am | :pm) :: 0..23
def to_24hour_clock(hour, am_or_pm) when hour in 1..12 and am_or_pm in [:am, :pm] do
case am_or_pm do
:am when hour === 12 -> 0
:am -> hour
:pm when hour === 12 -> hour
:pm -> hour + 12
end
end
if Version.compare(System.version(), "1.11.0") == :lt do
@doc false
def new!(hour, minute, second, microsecond \\ {0, 0}, calendar \\ Calendar.ISO) do
case Time.new(hour, minute, second, microsecond, calendar) do
{:ok, time} ->
time
{:error, reason} ->
raise ArgumentError, "cannot build time, reason: #{inspect(reason)}"
end
end
@doc false
def to_seconds_after_midnight(%Time{
hour: h,
minute: m,
second: s,
microsecond: us,
calendar: cal
}) do
{microsecond, _} = us
iso_days = {0, cal.time_to_day_fraction(h, m, s, us)}
{Calendar.ISO.iso_days_to_unit(iso_days, :second), microsecond}
end
else
@doc false
defdelegate new!(hour, minute, second, microsecond \\ {0, 0}, calendar \\ Calendar.ISO),
to: Time
@doc false
defdelegate to_seconds_after_midnight(time), to: Time
end
end