Current section
Files
Jump to
Current section
Files
lib/datetime.ex
defmodule Rivet.Utils.DateTime do
@minute_zero %{minute: 0, second: 0, microsecond: {0, 0}}
@hour_zero Map.put(@minute_zero, :hour, 0)
@day_one Map.put(@hour_zero, :day, 1)
@doc """
iex> beginning_of_hour(~U[2026-05-12 19:43:50.393307Z])
~U[2026-05-12 19:00:00Z]
iex> beginning_of_hour(~U[2027-11-21 11:23:20.333917Z])
~U[2027-11-21 11:00:00Z]
iex> beginning_of_hour(~U[2020-01-01 00:00:00Z])
~U[2020-01-01 00:00:00Z]
"""
@spec beginning_of_hour(DateTime.t()) :: DateTime.t()
def beginning_of_hour(datetime), do: Map.merge(datetime, @minute_zero)
@doc """
iex> beginning_of_day(~U[2026-05-12 19:43:50.393307Z])
~U[2026-05-12 00:00:00Z]
iex> beginning_of_day(~U[2027-11-21 11:23:20.333917Z])
~U[2027-11-21 00:00:00Z]
iex> beginning_of_day(~U[2020-01-01 00:00:00Z])
~U[2020-01-01 00:00:00Z]
"""
@spec beginning_of_day(DateTime.t()) :: DateTime.t()
def beginning_of_day(datetime), do: Map.merge(datetime, @hour_zero)
@doc """
iex> beginning_of_month(~U[2026-05-12 19:43:50.393307Z])
~U[2026-05-01 00:00:00Z]
iex> beginning_of_month(~U[2027-11-21 11:23:20.333917Z])
~U[2027-11-01 00:00:00Z]
iex> beginning_of_month(~U[2020-01-01 00:00:00Z])
~U[2020-01-01 00:00:00Z]
"""
@spec beginning_of_month(DateTime.t()) :: DateTime.t()
def beginning_of_month(datetime), do: Map.merge(datetime, @day_one)
@doc """
iex> m4 = ~U[2026-04-12 00:00:00.00Z]
iex> m5 = ~U[2026-05-12 00:00:00.00Z]
iex> m6 = ~U[2026-06-12 00:00:00.00Z]
iex> m7 = ~U[2026-07-12 00:00:00.00Z]
iex> between?(m4, %{start_at: m4, end_at: m5})
true
iex> between?(m5, %{start_at: m4, end_at: m6})
true
iex> between?(m6, %{start_at: m6, end_at: m7})
true
iex> between?(m5, %{start_at: m6, end_at: m7})
false
"""
@spec between?(DateTime.t(), %{start_at: DateTime.t(), end_at: DateTime.t()}) :: boolean()
def between?(date, %{start_at: start_at, end_at: end_at}) do
start_at_t = DateTime.to_unix(start_at)
end_at_t = DateTime.to_unix(end_at)
date_t = DateTime.to_unix(date)
start_at_t <= date_t and date_t <= end_at_t
end
end