CREATE or replace FUNCTION mytimecast(val timestamp with time zone) RETURNS json AS $$
BEGIN
RETURN to_json(to_char(val, 'YYYY-MM-DD"T"HH24:MI:SS.MSZ'));
END; $$
LANGUAGE PLPGSQL;
--custom cast that uses the above user defined function
create cast (timestamp with time zone AS json ) with function mytimecast (timestamp with time zone) AS IMPLICIT;
Direct cast to json uses the custom cast and returns the formatted date time from the user defined function:
select now()::json;
now
----------------------------
"2017-08-31T13:01:04.782Z"
However, to_json() function didn't use the custom cast and returning the default UTC format:
select to_json(now());
to_json
------------------------------------
"2017-08-31T13:01:18.474781+00:00"