defmodule Mobilizon.Service.TimezoneDetector do @moduledoc """ Detect the timezone from a point """ @type detectable :: Geo.Point.t() | Geo.PointZ.t() | {float() | float()} @doc """ Detect the most appropriate timezone from a value, a geographic set of coordinates and a fallback """ @spec detect(String.t() | nil, detectable() | nil, String.t()) :: String.t() def detect(tz, nil, fallback), do: detect(tz, fallback) def detect(nil, geo, fallback) do case TzWorld.timezone_at(geo) do {:ok, timezone} -> timezone {:error, :time_zone_not_found} -> fallback {:error, :enoent} -> fallback end end def detect(timezone, geo, fallback) do if Tzdata.zone_exists?(timezone) do timezone else detect(nil, geo, fallback) end end @spec detect(String.t() | nil, String.t()) :: String.t() def detect(nil, fallback), do: fallback def detect(timezone, fallback) do if Tzdata.zone_exists?(timezone) do timezone else fallback end end end