SafeChildren Banner

Havoc Oracle Solaris Experts

lunes, 17 de mayo de 2010

Gestión y Husos Horarios en PostgreSQL

Introduccion
Hace un tiempo hablábamos de los Husos Horarios en Oracle, hoy toca el turno a PostgreSQL. Vamos a ver como podemos gestionar las fechas con los desplazamientos en nuestra base de datos PostgreSQL.

Vamos a repetir los mismos ejemplos que hicimos con Oracle, para ver las diferencias y comprobar, que -aunque parezca extraño- en PostgreSQL es mucho mas sencillo.

Definición del TimeZone
En PostgreSQL definiremos nuestro TimeZone en el archivo de configuración <$PGDATA/postgres.conf> utilizando la variable <timezone>, sin embargo, si no tenemos asignado un valor, por defecto cogerá el valor de la variable de entorno TZ

$ echo $TZ
Europe/Madrid
Por lo tanto, nuestro <dbtimezone> será <Europe/Madrid> en mi caso.

Obtener los TimeZones
postgres=# SELECT DISTINCT name FROM pg_timezone_names ORDER BY 1;
               name              
----------------------------------
 Africa/Abidjan
 Africa/Accra
 Africa/Addis_Ababa
 Africa/Algiers
 Africa/Asmara
 Africa/Asmera
 Africa/Bamako
...
... continúa ...
...
Obtener la Fecha/Hora del Sistema con TimeZone
Podemos obtener la Fecha y Hora del Sistema con desplazamiento utilizando <now()> o &CURRENT_TIMESTAMP>, en ambos caso el resultado es el mismo.
postgres=# SELECT current_timestamp;
              now             
-------------------------------
 2010-05-17 20:27:39.573957+02
(1 fila)

postgres=# SELECT now();
              now             
-------------------------------
 2010-05-17 20:27:46.809705+02
(1 fila)

Mostrar el Desplazamiento Horario de un TimeZone en concreto
Por ejemplo, si queremos saber cuál es el desplazamiento de US/Arizona
postgres=# SELECT utc_offset FROM pg_timezone_names WHERE name = 'US/Arizona';
 utc_offset
------------
 -07:00:00
(1 fila)
Mostrar una Fecha y Hora con otro TimeZone
Por ejemplo, si queremos saber que Fecha y Hora es <US/Arizona>, utilizaremos el modificador <AT TIME ZONE 'timezone'>, veamos un ejemplo.
postgres=# SELECT now() AT TIME ZONE 'US/Arizona' as Hora_Arizona;
        hora_arizona       
----------------------------
 2010-05-17 11:35:07.475627
(1 fila)

Diferencias con Oracle
La mayor diferencia con Oracle la encontramos con fechas incorrectas, por ejemplo, <2010-03-28 01:10:00 +0100>. Esta hora en España no es válida -ya que a las 02:00h son las 03:00h.
Esto en Oracle produce un error ORA-01878, sin embargo en PostgreSQL se realiza la corrección y nos muestra la hora correcta sin mostrar error alguno, veamos un ejemplo
postgres=# SELECT '2010-03-28 02:10:00'::TIMESTAMP WITH TIME ZONE;                                                                                                                                             timestamptz      
------------------------
 2010-03-28 03:10:00+02
(1 fila)
postgres=# SELECT '2010-03-28 02:10:00 +0200'::TIMESTAMP WITH TIME ZONE;
      timestamptz      
------------------------
 2010-03-28 01:10:00+01
(1 fila)

Conclusiones
Realmente el manejo de Husos horarios en PostgreSQL es muy sencillo, y con la ventaja de esa gestión automática de las horas incorrectas. Además, podemos crearnos alias o funciones que simulen las mismas de Oracle -si nos apetece-

Referencias

2 comentarios:

  1. Respuestas
    1. Hola Anónimo,

      No, es "huso horario", ya que no es de "usar" sino "franja horaria".

      Es un error común,

      Un Saludo,
      Urko

      Eliminar