You are viewing alvherre

lo que cayó, cayó - WITH TIME ZONE o WITHOUT? [entries|archive|friends|userinfo]
alvherre

[ website | My Website ]
[ userinfo | livejournal userinfo ]
[ archive | journal archive ]

WITH TIME ZONE o WITHOUT? [Dec. 17th, 2010|05:14 pm]
Previous Entry Share
[Tags|]

Muchas personas creen que el tipo TIMESTAMP WITH TIME ZONE, en PostgreSQL, almacena el huso horario, pero están equivocados. En verdad, la diferencia entre los tipos TIMESTAMP WITH TIME ZONE y TIMESTAMP WITHOUT TIME ZONE no es bien comprendida; este artículo intenta aclarar un poco el tema.

Círculo en el sol, aguacero o temblor
La diferencia entre los dos tipos es cómo se interpreta la hora. TIMESTAMP WITHOUT TIME ZONE (y además TIMESTAMP, que es un alias) asume que tú sabes perfectamente de qué TZ 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 (y su alias 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, lo “rota” 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 lo piensas detenidamente, te darás cuenta que esto significa que si tienes 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 tremendamente útil y generalmente mal comprendida.

Entonces, lo recomendable es que almacenes el TZ que se debe aplicar en cada momento (por ej. si estás haciendo un sistema con usuarios, guardes el TZ de cada usuario) y hagas cambies el parámetro TimeZone cada vez, 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 te ahorras muchos dolores de cabeza en el lado de tu aplicación, puesto que te evitas tener que implementar el código para hacer las rotaciones horarias.

Mi recomendación: nunca uses los tipos TIMESTAMP WITHOUT TIME ZONE ni TIMESTAMP a menos que entiendas muy bien por qué.

Nota final: existe el operador AT TIME ZONE que permite cambiar un TIMESTAMP WITH TIME ZONE en TIMESTAMP WITHOUT TIME ZONE y viceversa.
LinkReply

Comments:
From: cadmarapy
2011-11-02 12:08 am (UTC)

(Link)

Super-Duper site! I am loving it!! Will come back again – taking your RSS feeds also, Thanks.