defmodule MvWeb.Helpers.DateFormatter do @moduledoc """ Centralized date formatting helper for the application. Formats dates in European format (dd.mm.yyyy). DateTime can be shown in UTC or in a given IANA timezone (e.g. from browser). """ use Gettext, backend: MvWeb.Gettext @doc """ Formats a Date struct to European format (dd.mm.yyyy). ## Examples iex> MvWeb.Helpers.DateFormatter.format_date(~D[2024-03-15]) "15.03.2024" iex> MvWeb.Helpers.DateFormatter.format_date(nil) "" """ def format_date(%Date{} = date) do Calendar.strftime(date, "%d.%m.%Y") end def format_date(nil), do: "" def format_date(_), do: "Invalid date" @doc """ Formats a DateTime struct to European format (dd.mm.yyyy HH:MM). When `timezone` is a valid IANA timezone string (e.g. from the browser), the datetime is converted to that zone before formatting. When `timezone` is nil or invalid, the datetime is formatted in UTC. ## Examples iex> MvWeb.Helpers.DateFormatter.format_datetime(~U[2024-03-15 10:30:00Z]) "15.03.2024 10:30" iex> MvWeb.Helpers.DateFormatter.format_datetime(~U[2024-03-15 10:30:00Z], "Europe/Berlin") "15.03.2024 11:30" iex> MvWeb.Helpers.DateFormatter.format_datetime(nil) "" """ def format_datetime(%DateTime{} = dt), do: format_datetime(dt, nil) def format_datetime(nil), do: "" def format_datetime(_), do: "Invalid datetime" def format_datetime(%DateTime{} = dt, nil), do: format_datetime_utc(dt) def format_datetime(%DateTime{} = dt, ""), do: format_datetime_utc(dt) def format_datetime(%DateTime{} = dt, tz) when is_binary(tz) do case DateTime.shift_zone(dt, tz, Tz.TimeZoneDatabase) do {:ok, shifted} -> Calendar.strftime(shifted, "%d.%m.%Y %H:%M") {:error, _} -> format_datetime_utc(dt) end end def format_datetime(nil, _timezone), do: "" def format_datetime(_, _timezone), do: "Invalid datetime" defp format_datetime_utc(%DateTime{} = dt) do Calendar.strftime(dt, "%d.%m.%Y %H:%M") end end