Há uma resposta longa e bastante esclarecedora sobre as diferenças entre
TIMESTAMP WITH TIME ZONE
-vs-TIMESTAMP WITHOUT TIME ZONE
disponível nesta postagem do SO . O que eu gostaria de saber é: existe algum caso de uso válido para realmente usar TIMESTAMP WITHOUT TIME ZONE
ou deve ser considerado um antipadrão.
postgresql
Marcus Junius Brutus
fonte
fonte
Respostas:
Isso é afirmado em muitos lugares, mas acho que vale a pena mencionar sempre quando comparamos os tipos
timestamp with time zone
comtimestamp without time zone
: otimestamp WITH time zone
não armazena as informações de fuso horário junto com o registro de data e hora . O que ele faz é armazenar todos os dados no fuso horário UTC, conforme declarado nos documentos :É considerado válido para alguns usarem
timestamp WITHOUT time zone
em situações em que (1) tudo está no mesmo fuso horário ou (2) a camada de aplicativo lida com o fuso horário e apenas armazena tudo em um determinado fuso horário (geralmente UTC). Mas também é considerado um antipadrão, simples porque a solução correta para (1) é definir a configuração do Fuso Horário para o fuso horário especificado para o sistema e (2) já está resolvido, pois o PostgreSQL já armazena tudo no mesmo fuso horário. (UTC).Agora, com os dois para baixo, posso veio com apenas uma boa razão para usar
timestamp WITHOUT time zone
. É quando você deseja armazenar eventos no futuro e que algum tipo de alerta deve ser acionado quando chegamos a esse momento. Isso pode ser bom paratimestamp WITH time zone
se, e somente se, as regras definidas pelas leis da região sobre fuso horário nunca mudarem. A regra mais comum que muda é sobre a adoção ou não do horário de verão (DST).Por exemplo, imagine que você está, digamos,
2013-06-15
(ainda não no horário de verão), programa algum evento para acontecer2013-01-15 10:00
(que já estaria no horário de verão) e na2013-06-15
sua região foi designado para adotar o horário de verão; mas, algum tempo depois disso, o governo mudou a regra e disse que sua região não usará mais o horário de verão e, de repente, o horário agendado se tornará2013-01-15 11:00
(em vez de10:00
), se você usartimestamp WITH time zone
, e manter suas configurações de TZ atualizadas. É claro que você também pode perceber que é possível tratar esses casos também com fuso horário, se acompanhar as alterações das regras nas regiões / fusos horários de seu interesse e atualizar os registros afetados.Vale ressaltar que algumas regiões frequentemente alteram essas regras (como no Brasil, alguns estados - e não todo o país - frequentemente mudam), mas na maioria dos casos elas são alteradas muito antes, para que seus usuários sejam afetados apenas por eventos agendados muito longe a hora atual.
Com tudo isso dito, só tenho mais uma sugestão. Se você possui usuários, logs ou qualquer coisa em fusos horários diferentes, armazene o fuso horário de onde eles vêm e escolha e use
timestamp with time zone
. Dessa forma, você pode (1) cruzar eventos que estão mais próximos entre si para diferentes fontes (independentemente de seus fusos horários) e (2) mostrar a hora original (a hora do relógio) em que o evento ocorreu.fonte
Sim. Existem casos de uso para
TIMESTAMP WITHOUT TIME ZONE
.TIMESTAMP WITH TIME ZONE
, nãoWITHOUT
.TIMESTAMP WITHOUT TIME ZONE
valores não são um ponto na linha do tempo, nem momentos reais. Eles representam uma idéia aproximada de momentos em potencial , possíveis pontos na linha do tempo ao longo de um período de 26 a 27 horas (o intervalo de fusos horários em todo o mundo). Eles não têm significado real até você aplicar um fuso horário ou um desvio do UTC .Ex: Natal
Por exemplo, suponha que você precise registrar o início dos feriados / dias santos.
Para registrar o fato de que o Natal começa depois da meia-noite de 25 de dezembro deste ano, precisamos dizer
2016-12-25 00:00:00
sem fuso horário. No início do dia do Papai Noel, ele visita Auckland na Nova Zelândia logo após a meia-noite, pois é uma das primeiras noites do mundo. Então ele segue seu caminho para o oeste, como acontece a próxima meia-noite, logo chegando às Filipinas. Em seguida, as renas seguem em direção oeste, chegando à Índia à meia-noite, o que ocorre várias horas depois da meia-noite de Auckland. Muito mais tarde ainda é meia-noite em Paris FR, e ainda mais tarde em Montreal CA. Todas essas visitas do Papai Noel acontecem em momentos diferentes , mas ainda assim logo após a meia-noite, por meia-noite de cada localidade.Portanto, gravar
2016-12-25 00:00:00
sem fuso horário no início do Natal é informativo e legítimo, mas apenas vagamente. Até você dizer "Natal em Auckland" ou "Natal em Montreal", não temos um momento específico. Se você estiver gravando o momento real toda vez que o trenó tocar, você deve usarTIMESTAMP WITH TIME ZONE
oWITHOUT
tipo.Semelhante ao Natal é a véspera de Ano Novo. Quando o Times Square Ball cai em Nova York , as pessoas em Seattle ainda estão tomando champanhe e preparando os chifres da festa . No entanto, gravaríamos a ideia do momento do ano novo como
2017-01-01 00:00:00
em aTIMESTAMP WITHOUT TIME ZONE
. Por outro lado, se queremos gravar quando a bola caiu em Nova York ou quando as pessoas em Seattle tocaram a buzina, em vez disso, usaríamosTIMESTAMP WITH TIME ZONE
(nãoWITHOUT
) para registrar esses momentos reais, cada três horas separados um do outro.Ex: turnos de fábrica
Outro exemplo pode ser o registro de uma política que envolve o horário do relógio de parede em vários locais. Digamos que temos fábricas em Detroit, Düsseldorf e Delhi. Se dissermos que, nas três fábricas, o primeiro turno começa às 6 da manhã, com um intervalo para o almoço às 11:30, que pode ser registrado como a
TIMESTAMP WITHOUT TIME ZONE
. Novamente, essas informações são úteis de maneira vaga, mas não indicam um momento específico no tempo até aplicarmos um fuso horário. Um novo dia amanhece mais cedo no leste. Assim, a fábrica de Délhi será a primeira a abrir às seis da manhã. Horas depois, a fábrica de Düsseldorf começa a trabalhar às seis da manhã. Mas a fábrica de Detroit não abrirá até outras seis horas depois, quando as seis da manhã acontecerem.Compare essa idéia (de quando o turno da fábrica geralmente começa) ao fato histórico de quando cada operário entrou em ação para iniciar seu turno em um determinado dia. A entrada do relógio é um momento real, um ponto real na linha do tempo. Então, gravaríamos isso em uma coluna do tipo
TIMESTAMP WITH TIME ZONE
e não doWITHOUT
tipo.Portanto, sim, existem casos de uso legítimos para
TIMESTAMP WITHOUT TIME ZONE
. Mas, na minha experiência com aplicativos de negócios, eles são relativamente raros. Nos negócios, tendemos a nos preocupar com momentos reais: quando a fatura realmente chegou, quando exatamente esse contrato entra em vigor, em que momento a transação bancária foi executada. Então, em situações tão comuns, queremos oTIMESTAMP WITH TIME ZONE
tipo.Para obter mais discussões, consulte minha resposta à pergunta semelhante. Devo armazenar registros de data e hora UTC ou hora local para turnos
Postgres
Observe que o Postgres especificamente nunca salva as informações de fuso horário especificadas ao inserir um carimbo de data / hora.
TIMESTAMP WITH TIME ZONE
TIMESTAMP WITH TIME ZONE
comoTIMESTAMP WITH RESPECT FOR TIME ZONE
.TIMESTAMP WITHOUT TIME ZONE
O padrão SQL mal toca em questões de tipos e comportamento de dados de data e hora. Portanto, o banco de dados varia amplamente na manipulação da data e hora.
fonte
21:00
)Gostaria de acrescentar outra visão a isso, que contraria muito do que foi escrito nas outras respostas. Na minha opinião,
timestamp with time zone
tem muito pouco casos de uso válidos etimestamp without time zone
, em geral , deve ser preferido.Primeiro, você deve entender o padrão "UTC em todos os lugares", geralmente recomendado para todos os aplicativos que não possuem requisitos muito especiais. Simplesmente significa que seu aplicativo deve representar todos os carimbos de data e hora no UTC, em qualquer lugar e em qualquer lugar. Obviamente, você mostrará a data / hora local para os usuários, mas a ideia é convertê-los na extremidade do seu programa, ao renderizar a exibição. Este é o lugar certo para combinar o carimbo de data / hora UTC (que você pode ter carregado de um banco de dados) e o fuso horário do usuário (que pode ter vindo do navegador) em um carimbo de data / hora local.
Se você está seguindo esse padrão,
timestamp with time zone
é um anti-padrão. Tudo isso faz com que o PostgreSQL realize conversões de fuso horário ao ler e escrever carimbos de data / hora, com base na suaTimeZone
variável de sessão do PostgreSQL . Em vez de lidar com fusos horários nas extremidades do seu aplicativo, você os introduziu no coração, na própria comunicação com o banco de dados. Você deve sempre ter o PostgreSQL sempreTimeZone
configurado corretamente, adicionando outro ponto desnecessário de falha e confusão.E para quê? Se você estiver seguindo o padrão UTC em todos os lugares, seu aplicativo só terá carimbos de data e hora UTC; então por que pedir ao seu banco de dados para fazer conversões de fuso horário neles? Você pode simplesmente armazená-los em uma
timestamp without time zone
coluna e tratá-los como se fossem sempre UTC. Sem conversões, sem fusos horários, sem complicações.fonte
Instance
no NodaTime / JodaTime). Você está descrevendo basicamente uma situação onde "UTC em todos os lugares" é quase seguidos, ou meio que seguiu ...timestamptz
. O objetivo deste tipo é realizar conversões de fuso horário como valores lidos e gravados no PostgreSQL (internamente no banco de dados, o registro de data e hora é sempre salvo como UTC). Sempre definir o fuso horário da sessão como UTC desativa efetivamente essas conversões. Por que usartimestamptz
? Dito de outra forma, se os valores no banco de dados são UTC e os valores que entram e saem do banco de dados são sempre UTC, por que o reconhecimento de fuso horário está presente no banco de dados?O
date
registro de data e hora também não inclui informações de fuso horário, mas muitas pessoas as usam.Claro, isso por si só não é uma resposta.
É válido usar
timestamp
edate
para quaisquer carimbos de data e hora que estejam sempre no mesmo fuso horário ou que estejam sendo armazenados em relação a algum fuso horário conhecido.Se o fuso horário for sempre o mesmo ou implícito, é mais antipadrão armazená-lo do que não armazená-lo (informações redundantes).
Os carimbos de data / hora também podem ser usados para armazenar informações técnicas, como usadas nos logs do aplicativo ou para medições de desempenho. Nesse caso, o fuso horário também pode não ter importância.
Por outro lado, se você estiver projetando ou trabalhando em um sistema distribuído ou em qualquer sistema em que partes do sistema sejam distribuídas por fusos horários diferentes, pode ser considerado um antipadrão a não ser utilizado
timestamp with timezone
, embora alguns sistemas possam ser projetados para execução em um fuso horário, por exemplo, UTC. Nesse caso, a lógica do fuso horário pode estar sendo empurrada para a camada de aplicativo - mas eu consideraria isso um antipadrão, sim.fonte
timestamp without timezone
, mas alguma vez me compra alguma coisa? Caso contrário, por que devo me preocupar se otimestamp with timezone data
tipo é sempre igualmente ou mais apropriado?timestamp without timezone
seria mais rápido, também, mas que é provavelmente apenas importante se você estiver processando bilhões de linhas ...timestamp
etimestamptz
ambos são armazenados da mesma maneira. Não há informações de fuso horário sendo armazenadas em atimestamptz
, mas elas são convertidas em UTC para armazenamento. Eu diria, sempre usetimestamptz
quando os timestamps em questão denotarem tempo absoluto . Isso é tudo o quetimestamptz
significa. Eu escrevi sobre isso aqui .Pode parecer tentador armazenar e processar datas / horas no horário local se seu aplicativo estiver limitado a um único fuso horário, mas acredito que isso seja um erro.
Ao voltar do horário de verão para o horário padrão, uma hora no horário local é repetida (supondo que a diferença seja de uma hora). Onde eu moro, isso normalmente acontece por volta das 2h da manhã. O horário local é 01:58, 01:59, 01:00 e avança para 02:00 no final da hora repetida.
Se você tentar ordenar eventos por horário usando a hora local, isso significa que os eventos de duas horas separadas são misturados e não aparecem na ordem em que eles realmente ocorreram.
Em comparação, o UTC não tem esse problema e faz pedidos de forma limpa. Portanto, mesmo ao trabalhar com apenas um fuso horário, você deseja que o banco de dados armazene e processe horários no UTC e converta para / da hora local para entrada / exibição. Esse é o comportamento do TIMESTAMP WITH TIME ZONE.
fonte