Logo depois de postar isso, executei outra consulta para verificar uma suspeita:
SELECT * FROM pg_timezone_abbrevs
WHERE abbrev IN ('CEST', 'CET');
abbrev | utc_offset | is_dst
--------+------------+--------
CEST | 02:00:00 | t
CET | 01:00:00 | f
Acontece que há também uma abreviatura de fuso horário chamado
CET
(o que faz sentido, sendo "CET" uma abreviatura). E parece que o PostgreSQL escolhe a abreviação sobre o nome completo. Então, embora eu tenha encontrado CET
no fuso horário nomes , a expressão '2012-01-18 1:0 CET'::timestamptz é interpretada de acordo com as regras sutilmente diferentes para abreviações de fuso horário . SELECT '2012-01-18 1:0 CEST'::timestamptz(0)
,'2012-01-18 1:0 CET'::timestamptz(0)
,'2012-01-18 1:0 Europe/Vienna'::timestamptz(0);
timestamptz | timestamptz | timestamptz
------------------------+------------------------+------------------------
2012-01-18 00:00:00+01 | 2012-01-18 01:00:00+01 | 2012-01-18 01:00:00+01
SELECT '2012-08-18 1:0 CEST'::timestamptz(0)
,'2012-08-18 1:0 CET'::timestamptz(0)
,'2012-08-18 1:0 Europe/Vienna'::timestamptz(0);
timestamptz | timestamptz | timestamptz
------------------------+------------------------+------------------------
2012-08-18 01:00:00+02 | 2012-08-18 02:00:00+02 | 2012-08-18 01:00:00+02
Encontrei 10 casos de abreviaturas de fuso horário no fuso horário nomes e não conseguem entender por que eles estão lá. Qual é o propósito?
Entre eles, o deslocamento de tempo (
utc_offset
) discorda em quatro casos devido à configuração do horário de verão:SELECT n.*, a.*
FROM pg_timezone_names n
JOIN pg_timezone_abbrevs a ON a.abbrev = n.name
WHERE n.utc_offset <> a.utc_offset;
name | abbrev | utc_offset | is_dst | abbrev | utc_offset | is_dst
------+--------+------------+--------+--------+------------+--------
CET | CEST | 02:00:00 | t | CET | 01:00:00 | f
EET | EEST | 03:00:00 | t | EET | 02:00:00 | f
MET | MEST | 02:00:00 | t | MET | 01:00:00 | f
WET | WEST | 01:00:00 | t | WET | 00:00:00 | f
Nesses casos, as pessoas podem ser enganadas (como eu), procurando o tz nome e encontrar um deslocamento de tempo que não é realmente aplicado. Esse é um design infeliz - se não for um bug, pelo menos um bug de documentação .
Não consigo encontrar nada no manual sobre como as ambiguidades entre os nomes de fuso horário e abreviaturas são resolvidos. Obviamente, as abreviaturas têm precedência.
Apêndice B.1. A interpretação de entrada de data/hora menciona a pesquisa de abreviações de fuso horário, mas permanece incerta como o fuso horário nomes são identificados e qual deles tem prioridade no caso de um token ambíguo.
Se o token for uma string de texto, combine com as strings possíveis:
Faça uma pesquisa de tabela de pesquisa binária para o token como uma abreviação de fuso horário.
Bem, há uma pequena dica nesta frase de que as abreviações vêm primeiro, mas nada definitivo. Além disso, há uma coluna
abbrev
em ambas as tabelas, pg_timezone_names
e pg_timezone_abbrevs
...