defmodule Fast.Ecto.TimeZoneQuery do # -- Imports import Ecto.Query, warn: false @doc """ Converts a timestamp to the specified timezone. Ensures proper timezone conversion by: 1. Converting the timestamp to UTC 2. Converting to the target timezone 3. Converting back to timestamptz """ defmacro at_time_zone(timestamp_expr, tz_field) do quote do fragment( "((?)::timestamp AT TIME ZONE 'UTC' AT TIME ZONE (?))::timestamptz", unquote(timestamp_expr), iana_tz(unquote(tz_field)) ) end end @doc """ Converts US timezone names to IANA timezone names for PostgreSQL compatibility. """ defmacro iana_tz(tz_field) do quote do fragment( """ CASE ? WHEN 'America/Puerto_Rico' THEN 'America/Puerto_Rico' WHEN 'US/Alaska' THEN 'America/Anchorage' WHEN 'US/Aleutian' THEN 'America/Adak' WHEN 'US/Arizona' THEN 'America/Phoenix' WHEN 'US/Central' THEN 'America/Chicago' WHEN 'US/East-Indiana' THEN 'America/Indiana/Indianapolis' WHEN 'US/Eastern' THEN 'America/New_York' WHEN 'US/Hawaii' THEN 'Pacific/Honolulu' WHEN 'US/Indiana-Starke' THEN 'America/Indiana/Knox' WHEN 'US/Michigan' THEN 'America/Detroit' WHEN 'US/Mountain' THEN 'America/Denver' WHEN 'US/Pacific' THEN 'America/Los_Angeles' WHEN 'US/Samoa' THEN 'Pacific/Pago_Pago' ELSE ? END """, unquote(tz_field), unquote(tz_field) ) end end end