Estou fazendo algumas importações de dados que incluem conversão de fuso horário. Os dados que estou importando estão no fuso horário América/Nova_Iorque e preciso importá-los como carimbo de data/hora UTC.
Tentei alguns exemplos que encontrei na internet, como:
to_timestamp(tar.read_at_date || ' ' || tar.read_at_hour, 'MM/DD/YYYY HH24:MI')::timestamp without time zone at time zone 'America/New_York' at time zone 'utc'
e isso pareceu funcionar bem para a maioria dos dados, no entanto, notei algumas conversões estranhas em horários específicos, como se o Postgres estivesse aplicando o horário de verão para o fuso horário UTC (???).
Para ilustrar rapidamente o comportamento, veja os exemplos e resultados abaixo:
select ('2023-03-25 22:00:00'::timestamp at time zone 'America/New_York' at time zone 'utc');
result: 2023-03-26 03:00:00.000
select ('2023-03-25 23:00:00'::timestamp at time zone 'America/New_York' at time zone 'utc');
result: 2023-03-26 03:00:00.000
Estou executando essas consultas em:
PostgreSQL [15.5
PostgreSQL 15.5 on aarch64-unknown-linux-gnu, compiled by gcc (GCC) 7.3.1 20180712 (Red Hat 7.3.1-6), 64-bit]
Além disso, para mencionar que em 2023, o horário de verão em Nova York começou no domingo, 12 de março, às 2h. O que é interessante aqui é que no dia 26 de março de 2023, às 2h, é quando os relógios avançam na Europa.
Alguma explicação razoável de por que isso acontece?
A função
to_timestamp()
que recebetext
retornatimestamptz
. Não éIMMUTABLE
porque depende datimezone
configuração atual.A expressão de entrada
tar.read_at_date || ' ' || tar.read_at_hour
não parece ter um deslocamento de fuso horário anexado . A maneira correta de informar ao Postgres que seus carimbos de data e hora estão noAmerica/New_York
fuso horário é definirtimezone
adequadamente (para a sessão atual):Isso é ambíguo:
Nenhum dos tipos de carimbo de data/hora do Postgres está "em" nenhum fuso horário. Ver:
O tipo de dados
timestamp
(timestamp without time zone
) não tem conceito de fuso horário. Ele precisa ser definido em um determinado fuso horário para ser significativo como horário universal.O tipo de dados
timestamptz
(timestamp with time zone
) é armazenado como UTC internamente. Sua representação textual é formatada de acordo com atimezone
configuração da sessão atual. Mas é sempre o mesmo momento. Para mim (comtimezone = 'Europe/Vienna'
), os carimbos de data e hora são exibidos atualmente com deslocamento '+02' (graças ao "horário de verão" totalmente inútil). Então:.. é exibido como '2023-04-26 01:00:00+02'. Exatamente o mesmo valor, apenas formatado para um fuso horário diferente.