TIMESTAMP Vs. TIMESTAMPTZ
6 Ene
La diferencia entre los dos tipos es cómo se interpreta la hora.
TIMESTAMP WITHOUT TIME ZONE (TIMESTAMP, que es un alias) asume que tú sabes perfectamente de qué TZ (time zone) es la hora que le estás pasando, y que no necesitas que sea consistente con los TZs de otros valores de ese mismo tipo; o bien, que tienes 100% seguridad que siempre estarán todos en el mismo TZ. Cosa que, es difícil de asegurar puesto que uno nunca tiene claridad de las líneas de desarrollo futuro de sus sistemas.
En cambio, un TIMESTAMP WITH TIME ZONE (TIMESTAMPTZ) asume que la hora está en el TZ local, configurado con la variable TimeZone (que puedes cambiar en el archivo postgresql.conf o usando la orden SET). Para almacenarla, le quita la diferencia de horas de GMT (es decir, la lleva a GMT) y lo guarda de esa forma; es decir, en el almacenamiento, todos los valores de una columna de tipo timestamptz van a estar en GMT. Al momento de desplegar un valor, se vuelve a rotar desde GMT hasta el TZ actual agregándole la diferencia de horas de GMT.
Si se piensa detenidamente, notaremos que esto significa que si se tiene un usuario en un TZ que ingresa una hora, y luego viene otro usuario en un TZ distinto que la examina, el valor de la hora va a ser distinto para cada uno de ellos: para cada uno, va a estar en su TZ local.
Esta es una característica muy útil y generalmente mal comprendida.
Por lo tanto, lo recomendable es utilizar el TZ que se debe aplicar en cada momento (por ej. si acceden al sistema desde una provincia que tenga diferencia horaria con otra) y se realicen los correctos seteos en el parámetro TimeZone del cliente, de manera que todas las horas del sistema sean consistentes y coherentes, sobre todo si los usuarios interactúan con otros que están en TZs distintos.
Haciéndolo de esta forma se ahorra mucho código del lado de la aplicación, dado a que se evita tener que implementar la rotaciones horarias.
Recomendación personal: nunca uses los tipos TIMESTAMP WITHOUT TIME ZONE ni TIMESTAMP (a menos que se entienda muy bien el por qué)
Ejemplo:
CREATE TABLE public.prueba_time (t1 TIMESTAMPTZ, t2 TIMESTAMP);
INSERT INTO public.prueba_time VALUES (TIMESTAMPTZ ’2010-12-27 20:38:40′, TIMESTAMP ’2010-12-27 20:38:40′);
SELECT * from public.prueba_time;
–”2010-12-27 20:38:40-03″ ; “2010-12-27 20:38:40″
SET timezone = ‘MST’; –seteo otro TZ
SELECT * from public.prueba_time;
–”2010-12-27 16:38:40-07″ ; “2010-12-27 20:38:40″
Texto basado en respuestas de listas de mails (Alvaro Herrera) y documentación oficial de PostgreSQL
