--
-- last_day/1
--
create or replace function last_day(
timestamp with time zone
) returns timestamptz as $$
declare
last_day__somedate alias for $1;
v_month integer;
v_targetmonth integer;
v_date timestamptz;
v_targetdate timestamptz;
begin
-- Initial values
v_targetdate := last_day__somedate;
v_targetmonth := extract(month from last_day__somedate);
-- Add up to 31 days to the given date, stop if month changes.
FOR i IN 1..31 LOOP
v_date := last_day__somedate + to_interval(i,'days');
v_month := extract(month from v_date);
if v_month != v_targetmonth
then
exit;
else
v_targetdate := v_date;
end if;
END LOOP;
return v_targetdate;
end;$$ language plpgsql;