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

Obter hora com fuso horário a partir de hora sem fuso horário e o nome do fuso horário


AVISO:novato no PostgreSQL (veja comentários sobre a pergunta!). Eu sei um pouco sobre fusos horários, então sei o que faz sentido perguntar.

Parece-me que esta é basicamente uma situação sem suporte (infelizmente) quando se trata de AT TIME ZONE . Examinando o NO FUSO HORÁRIO documentação dá uma tabela onde os tipos de valor "input" são apenas:
  • carimbo de data e hora sem fuso horário
  • carimbo de data e hora com fuso horário
  • hora com fuso horário

Estamos perdendo o que você quer:tempo sem fuso horário. O que você está perguntando é um pouco lógico, embora dependa da data... pois diferentes fusos horários podem ter diferentes deslocamentos dependendo da data. Por exemplo, 12:00:00 Europa/Londres pode significa 12:00:00 UTC, ou pode significar 11:00:00 UTC, dependendo se é inverno ou verão.

No meu sistema, tendo definido o fuso horário do sistema para America/Regina, a consulta
SELECT ('2011-11-22T12:00:00'::TIMESTAMP WITHOUT TIME ZONE) 
                               AT TIME ZONE 'America/Vancouver'

me dá 2011-11-22 14:00:00-06 como resultado. Isso não é ideal , mas pelo menos dá o ponto instantâneo no tempo (eu acho). Acredito que se você buscou isso com uma biblioteca cliente - ou comparou com outro TIMESTAMP WITH TIME ZONE - você obteria o resultado certo. É apenas a conversão de texto que usa o sistema fuso horário para saída.

Isso seria bom o suficiente para você? Você pode alterar seu SCHEDULES.time campo seja um TIMESTAMP WITHOUT TIME ZONE campo ou (no momento da consulta) combinar a hora do campo com uma data para criar um carimbo de data/hora sem fuso horário?

EDIT:Se você estiver satisfeito com a "data atual", parece como se você pudesse alterar sua consulta para:
SELECT (current_date + SCHEDULES.time) AT TIME ZONE USERS.tz
from SCHEDULES JOIN USERS on USERS.ID=SCHEDULES.USERID

Claro, o atual sistema a data pode não ser a mesma que a data atual no fuso horário local . Eu acho isso vai corrigir essa parte...
SELECT ((current_timestamp AT TIME ZONE USERS.tz)::DATE + schedules.time)
       AT TIME ZONE USERS.tz
from SCHEDULES JOIN USERS on USERS.ID=SCHEDULES.USERID

Em outras palavras:
  • Pegue o instante atual
  • Calcule a data/hora local no fuso horário do usuário
  • Pegue a data disso
  • Adicione o horário da programação a essa data para obter um TIMESTAMP WITHOUT TIME ZONE
  • Usar AT TIME ZONE para aplicar o fuso horário a essa data/hora local

Tenho certeza de que há uma maneira melhor, mas acho faz sentido.

Você deve estar ciente de que, em alguns casos, isso pode falhar:
  • Qual ​​será o resultado para um horário de 01h30 em um dia em que o relógio pular de 01h para 02h, de modo que 01h30 não ocorra?
  • Qual ​​você quer que seja o resultado para um horário de 01h30 em um dia em que o relógio retroceda de 02h para 01h, de modo que 01h30 ocorra duas vezes?