If all are aware that the timestamp value is supposed to represent UTC time it should work, basically. A convenient advantage is that default input and output is less noisy.
I would still suggest
timestamptz. Here are some reasons:
timestamptz literally is the "preferred type" among date/time types in Postgres. See:
test=> SELECT typname, typispreferred FROM pg_type WHERE typcategory = 'D';
typname | typispreferred
date | f
time | f
timestamp | f
timestamptz | t -- !
timetz | f
time_stamp | f
The manual about pg_types.
This can work in favor of
timestamptz in corner cases of type/function/operator resolution.
When you have
timestamptz literals as data input, that just works with type
Inserting the same into a
timestamp column would ignore the time offset (lose information). One would have to cast to
timestamptz explicitly, then transpose to UTC timestamp with something like:
'2020-04-22 04:46:46.790969+02'::timestamptz AT TIME ZONE 'UTC'
The opposite direction is less error prone. When inserting a
timestamp literal into a
timestamptz column, the current time zone is assumed in the absence of explicit information.
timestamptz. If you need
timestamp, you have to cast. Internally,
LOCALTIMESTAMP does just that: it casts
transaction_timestamp(). To get the current timestamp for UTC you need
now() AT TIME ZONE 'UTC' or similar.
Displaying timestamps for a given time zone is simpler based on
SELECT my_timestamptz AT TIME ZONE 'US/Hawaii';
That's more work with
timestamp. We know it's supposed to be UTC time. But Postgres does not until we say so, explicitly:
SELECT my_timestamp AT TIME ZONE 'UTC' AT TIME ZONE 'US/Hawaii'