I would like to calculate the difference between the starting time (variable of type timestamptz
) and the NOW()
moment when my function finishes.
select * from _get_date_diff_ms(NOW(), NOW())
Using supabase.io with PG 13.3, I get this error message:
operator does not exist: timestamp with time zone - double precision"
CREATE OR REPLACE FUNCTION _get_date_diff_ms(p_begin_time timestamptz, p_end_time timestamptz)
RETURNS int AS
$$
BEGIN
RETURN ROUND ((
EXTRACT (EPOCH FROM p_begin_time -
EXTRACT (EPOCH FROM p_end_time)
) * 1000));
END;
$$ LANGUAGE plpgsql;
CodePudding user response:
I think what you are looking for is :
CREATE OR REPLACE FUNCTION public._get_date_diff_ms(p_begin_time timestamp with time zone)
RETURNS integer
LANGUAGE plpgsql
AS $function$
BEGIN
RETURN round((EXTRACT(EPOCH FROM clock_timestamp() - p_begin_time ) * 1000));
END;
$function$
;
select _get_date_diff_ms(now() - interval '.5 sec');
_get_date_diff_ms
-------------------
500
I threw a negative interval in the function call to actually get a diff. For what the the various time functions do see Current time.
CodePudding user response:
operator does not exist: timestamp with time zone - double precision
That's just because of wrong parentheses. You meant to write:
RETURN ROUND ((
EXTRACT (EPOCH FROM p_begin_time) - -- !
EXTRACT (EPOCH FROM p_end_time)
) * 1000);
But the whole approach is broken. It's been pointed out by now that now()
is a stable value within a Postgres transaction. See:
Moreover, for your expressed purpose, it makes no sense to pass a "starting time" to begin with.
- Either you mean the starting time of the transaction: then use
now()
anywhere in the function. - Or you mean the starting time of the function: then use
clock_timestamp()
at the start of the function.
Assuming the latter, I suggest:
CREATE OR REPLACE FUNCTION public._get_date_diff_ms() -- no parameter
RETURNS numeric -- !
LANGUAGE plpgsql AS
$func$
DECLARE
_start_ts timestamptz := clock_timestamp(); -- !
BEGIN
PERFORM pg_sleep(1); -- do something here (1 sec example)
RETURN round(1000 * EXTRACT(epoch FROM clock_timestamp() - _start_ts), 3);
END
$func$;
Call:
test=> SELECT public._get_date_diff_ms();
_get_date_diff_ms
-------------------
1003.440
I return numeric
with 3 fractional digits instead of integer
to capture microseconds. Else, it would just report 0 for many fast operations.
See: