Estaba respondiendo a esta pregunta de stackoverflow y encontré un resultado extraño:
select * from pg_timezone_names where name = 'Europe/Berlin' ;
name | abbrev | utc_offset | is_dst
---------------+--------+------------+--------
Europe/Berlin | CET | 01:00:00 | f
y siguiente consulta
select id,
timestampwithtimezone,
timestampwithtimezone at time zone 'Europe/Berlin' as berlin,
timestampwithtimezone at time zone 'CET' as cet
from data ;
id | timestampwithtimezone | berlin | cet
-----+------------------------+---------------------+---------------------
205 | 2012-10-28 01:30:00+02 | 2012-10-28 01:30:00 | 2012-10-28 00:30:00
204 | 2012-10-28 02:00:00+02 | 2012-10-28 02:00:00 | 2012-10-28 01:00:00
203 | 2012-10-28 02:30:00+02 | 2012-10-28 02:30:00 | 2012-10-28 01:30:00
202 | 2012-10-28 02:59:59+02 | 2012-10-28 02:59:59 | 2012-10-28 01:59:59
106 | 2012-10-28 02:00:00+01 | 2012-10-28 02:00:00 | 2012-10-28 02:00:00
Estoy usando PostgreSQL 9.1.2 y ubuntu 12.04.
Acabo de comprobar que en 8.2.11 el resultado es el mismo.
Según la documentación , no importa si uso el nombre o la abreviatura.
¿Es esto un error?
¿Estoy haciendo algo mal?
¿Alguien puede explicar este resultado?
EDITAR Para el comentario de que CET no es Europa / Berlín.
Solo estoy seleccionando valores de pg_timezone_names.
select * from pg_timezone_names where abbrev ='CEST';
name | abbrev | utc_offset | is_dst
------+--------+------------+--------
y
select * from pg_timezone_names where abbrev ='CET';
name | abbrev | utc_offset | is_dst
---------------------+--------+------------+--------
Africa/Tunis | CET | 01:00:00 | f
Africa/Algiers | CET | 01:00:00 | f
Africa/Ceuta | CET | 01:00:00 | f
CET | CET | 01:00:00 | f
Atlantic/Jan_Mayen | CET | 01:00:00 | f
Arctic/Longyearbyen | CET | 01:00:00 | f
Poland | CET | 01:00:00 | f
.....
Durante el invierno Europa / Berlín es +01. Durante el verano es +02.
EDITAR2
En el 28/10/2012, la zona horaria ha cambiado del horario de verano al horario de invierno a las 2:00.
Estos dos registros tienen el mismo valor en Europa / Berlín:
204 | 2012-10-28 02:00:00+02 | 2012-10-28 02:00:00 | 2012-10-28 01:00:00
106 | 2012-10-28 02:00:00+01 | 2012-10-28 02:00:00 | 2012-10-28 02:00:00
Esto sugiere que si uso una de las abreviaturas (CET o CEST) para el rango de datos grandes (horario de verano e invierno), el resultado será incorrecto para algunos de los registros. Será bueno si uso 'Europa / Berlín'.
Cambié la hora del sistema a '2012-01-17' y pg_timezone_names también ha cambiado.
select * from pg_timezone_names where name ='Europe/Berlin';
name | abbrev | utc_offset | is_dst
---------------+--------+------------+--------
Europe/Berlin | CEST | 02:00:00 | t
fuente
2012-10-28 01:30:00
es CEST, no CET.CET
es , al menos no durante el horario de verano.Europe/Berlin
Respuestas:
En realidad, la documentación dice claramente que el nombre de la zona horaria y la abreviatura se comportarán de manera diferente.
FWIW, esa misma referencia también dice
fuente
¡Y eso todavía no es lo esencial! Me encontré con un problema muy similar hace algún tiempo.
Los principales inconvenientes de las abreviaturas de zona horaria ya se han presentado aquí: no tienen en cuenta el horario de verano (DST). El principal profesional: simplicidad que resulta en un rendimiento superior . Tener en cuenta las reglas de DST hace que los nombres de zona horaria sean lentos en comparación. Las abreviaturas de zona horaria son compensaciones de tiempo simples y simbólicas, los nombres de zonas horarias están sujetos a un conjunto de reglas en constante cambio. Ejecuté puntos de referencia en esta respuesta relacionada en SO , la diferencia es notable. Pero cuando se aplica a un conjunto, generalmente es necesario usar nombres de zona horaria para cubrir el posible estado de horario de verano diferente por fila (y también diferencias históricas).
Estamos hablando de CET . La parte realmente difícil es que "CET" no sólo es (obviamente) una abreviación del huso horario , es también un nombre de zona horaria , por lo menos según mi instalación (PostgreSQL 9.1.6 en Debian Squeeze con locale "de_AT.UTF-8 ") y todos los demás que he visto hasta ahora. Menciono estos detalles, porque Postgres usa la información local del sistema operativo subyacente si está disponible.
Ver por ti mismo:
SQL Fiddle.
Postgres elige la abreviatura sobre el nombre completo. Entonces, aunque encontré CET en los nombres de zona horaria , la expresión
'2012-01-18 01:00 CET'::timestamptz
se interpreta de acuerdo con las reglas sutilmente diferentes para las abreviaturas de zona horaria .Si esa no es una pistola cargada, no sé qué es.
Para evitar ambigüedades, vaya con el nombre de zona horaria 'Europa / Berlín' (o 'Europa / Viena' en mi caso, que es efectivamente el mismo, excepto por las diferencias históricas). Encuentre más detalles sobre el tema en la pregunta estrechamente relacionada que mencioné anteriormente .
Para terminar, me gustaría expresar mi profundo desprecio por el concepto tonto de DST. Debería eliminarse de la existencia y nunca más volver a hablarse de él.
fuente
Mira esto:
+02
es CEST en Berlín, no CET.fuente