PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Nomes de fuso horário com propriedades idênticas geram resultados diferentes quando aplicados ao carimbo de data/hora


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 ...