La solución es utilizar campos TIMESTAMPTZ para estos instantes de tiempo. Algo como "cuándo se creó el usuario" nunca debe almacenarse con un campo TIMESTAMP ya que, de manera predeterminada, no contiene información de TZ. El controlador JDBC los maneja de manera bastante arbitraria. Por ejemplo, considere lo siguiente:
Suponga que su JVM está en la zona America/Los_Angeles mientras que su servidor de base de datos está en UTC.
Luego crea la siguiente tabla:
CREATE TABLE test (
id INTEGER,
ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
tswz TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
Si emite desde PSQL:
INSERT INTO test(id) values(1);
Obtendrá valores idénticos para "ts" y "tswz". Ambos serán la hora UTC actual. Sin embargo, si realiza la MISMA consulta EXACTA desde Java usando el controlador JDBC, entonces "ts" será la hora actual en Los Ángeles y "tswz" será la hora UTC.
No sé CÓMO el controlador transmite al servidor la zona horaria de JVM en este caso porque estamos configurando el campo por defecto en el servidor. Dicen que no establecen la zona horaria para la sesión, pero deben hacerlo. De cualquier manera, si usa un campo TIMESTAMPTZ, obtendrá los mismos instantes de cualquier JVM, independientemente de la zona horaria en la que se encuentre.