- Add compile-time @build_timestamp to Application module - Create ToweropsWeb.TimeHelpers module for shared time formatting - Update footer to display 'Last deployed Xm ago · YYYY-MM-DD HH:MM:SS UTC' - Refactor AgentLive.Helpers to delegate to shared TimeHelpers - Consolidate duplicate time formatting logic into single module - Timestamp updates automatically on each build/deploy
106 lines
2.5 KiB
Elixir
106 lines
2.5 KiB
Elixir
defmodule ToweropsWeb.TimeHelpers do
|
|
@moduledoc """
|
|
Helper functions for formatting time and date values.
|
|
"""
|
|
|
|
@doc """
|
|
Formats a DateTime into a human-readable "time ago" string.
|
|
|
|
Supports short time periods (seconds, minutes, hours, days) and
|
|
long time periods (months, years) for things like build timestamps.
|
|
|
|
## Examples
|
|
|
|
iex> datetime = DateTime.add(DateTime.utc_now(), -65, :second)
|
|
iex> ToweropsWeb.TimeHelpers.format_time_ago(datetime)
|
|
"1m ago"
|
|
|
|
iex> datetime = DateTime.add(DateTime.utc_now(), -7200, :second)
|
|
iex> ToweropsWeb.TimeHelpers.format_time_ago(datetime)
|
|
"2h ago"
|
|
|
|
"""
|
|
@spec format_time_ago(DateTime.t() | nil) :: String.t()
|
|
def format_time_ago(nil), do: "Never"
|
|
|
|
def format_time_ago(datetime) do
|
|
now = DateTime.utc_now()
|
|
diff = DateTime.diff(now, datetime, :second)
|
|
|
|
cond do
|
|
diff < 60 ->
|
|
"#{diff}s ago"
|
|
|
|
diff < 3600 ->
|
|
minutes = div(diff, 60)
|
|
"#{minutes}m ago"
|
|
|
|
diff < 86_400 ->
|
|
hours = div(diff, 3600)
|
|
"#{hours}h ago"
|
|
|
|
diff < 2_592_000 ->
|
|
days = div(diff, 86_400)
|
|
"#{days}d ago"
|
|
|
|
diff < 31_536_000 ->
|
|
months = div(diff, 2_592_000)
|
|
"#{months}mo ago"
|
|
|
|
true ->
|
|
years = div(diff, 31_536_000)
|
|
"#{years}y ago"
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Formats a DateTime into a full date and time string.
|
|
|
|
## Examples
|
|
|
|
iex> datetime = ~U[2026-01-15 14:34:00Z]
|
|
iex> ToweropsWeb.TimeHelpers.format_datetime(datetime)
|
|
"Jan 15, 2026 at 02:34 PM UTC"
|
|
|
|
"""
|
|
@spec format_datetime(DateTime.t() | nil) :: String.t()
|
|
def format_datetime(nil), do: "Never"
|
|
|
|
def format_datetime(datetime) do
|
|
Calendar.strftime(datetime, "%b %d, %Y at %I:%M %p %Z")
|
|
end
|
|
|
|
@doc """
|
|
Formats a DateTime into a short date string.
|
|
|
|
## Examples
|
|
|
|
iex> datetime = ~U[2026-01-15 14:34:00Z]
|
|
iex> ToweropsWeb.TimeHelpers.format_date(datetime)
|
|
"Jan 15, 2026"
|
|
|
|
"""
|
|
@spec format_date(DateTime.t() | nil) :: String.t()
|
|
def format_date(nil), do: "Never"
|
|
|
|
def format_date(datetime) do
|
|
Calendar.strftime(datetime, "%b %d, %Y")
|
|
end
|
|
|
|
@doc """
|
|
Formats a DateTime into ISO 8601 format with UTC timezone.
|
|
|
|
## Examples
|
|
|
|
iex> datetime = ~U[2026-01-15 14:34:00Z]
|
|
iex> ToweropsWeb.TimeHelpers.format_iso8601(datetime)
|
|
"2026-01-15 14:34:00 UTC"
|
|
|
|
"""
|
|
@spec format_iso8601(DateTime.t() | nil) :: String.t()
|
|
def format_iso8601(nil), do: "Never"
|
|
|
|
def format_iso8601(datetime) do
|
|
Calendar.strftime(datetime, "%Y-%m-%d %H:%M:%S UTC")
|
|
end
|
|
end
|