Articles

Tipos de dados PostgreSQL: data, hora e fusos horários

Posted by admin

continuando a nossa série de tipos de dados PostgreSQL today vamos introduzir tipos de dados de data, hora e intervalo.

PostgreSQL implementação do calendário é muito boa, e vamos mostrar alguns exemplos de ratos sobre o quão confuso este assunto é. O zonenotion do Tempo, em particular, é principalmente uma ferramenta política nos dias de hoje, e faz sentido em um princípio de engenharia: não há maneira de resolver zoneproblemas do tempo a partir de princípios de primeira mão!,

data/hora e fusos horários

as datas de manuseamento e os fusos horários são uma matéria muito complexa, e no tistópico, pode ler a peça de Erik Naggum a longa e dolorosa história do tempo.

os capítulos de documentação pós-Gresql com os títulos datas/horários, tipos de dados formativos e funções de data / hora e operadorescobrem tudo o que necessita de saber sobre a data, hora, datas e fusos horários com o PostgreSQL.

a primeira pergunta que precisamos responder aqui é sobre o uso de horários com ou sem fusos horários de nossas aplicações., A resposta é simples: utilize sempre os intervalos de tempo com fusos horários.

um mito comum é que armazenar fusos horários certamente irá adicionar à sua história e pegada de memória. É, na verdade, não é o caso:

select pg_column_size(timestamp without time zone 'now'), pg_column_size(timestamp with time zone 'now');
 pg_column_size │ pg_column_size ════════════════╪════════════════ 8 │ 8(1 row)

o PostgreSQL assume a utilizar bigint internamente para armazenar carimbos de data / hora, e no disco e na memória de formato são os mesmos, com ou sem tempo zonesupport., Aqui está toda a sua definição de tipo do PostgreSQL código-fonte(na src/include/datatype/timestamp.h):

typedef int64 Timestamp;typedef int64 TimestampTz;

o PostgreSQL documentação para carimbos de data / hora, veja como funciona:

Para o carimbo de data / hora com o fuso horário, o valor internamente armazenado é sempre em UTC(Tempo Universal Coordenado, tradicionalmente conhecido como Hora do meridiano de Greenwich,GMT). Um valor de entrada que tenha um fuso horário explícito especificado é convertido para UTC usando o deslocamento apropriado para esse fuso horário., Se nenhum Fuso-horário é estacionado na cadeia de entrada, então assume-se que está no tempo zoneindicado pelo parâmetro do fuso-horário do sistema, e é convertido para Utcusando o offset para a zona do fuso-horário.

PostgreSQL não armazena o fuso-horário de onde vêm com o seu timestamp.Em vez disso, converte de e para o fuso-horário de entrada e saída muito parecido com o que já vimos para o texto com a codificação de clientes.

neste script, nós brincamos com o tempo de ajuste do cliente e mudar de um valor francês para outro valor francês, como Tahiti é uma ilha no Pacífico que faz parte da França., Veja aqui o resultado completo como visto quando runningthis script, quando lançado com psql -a -f tz.sql:

Primeiro, vemos que a função agora() sempre retorna a mesma timestampwithin uma única transação. Se quiser ver o relógio a correr durante a tradução, use a função clock_ timestamp() em alternativa.

então, vemos que quando mudamos a configuração do cliente do fuso-horário, PostgreSQLoutputs timestamps como esperado, no fuso-horário selecionado., Se você gerenciar uma aplicação com os usuários em diferentes fusos horários e você quiser mostrar o tempo em seu próprio fuso horário local preferido, então você pode definir o fuso horário no código de aplicação do Usuário antes de fazer qualquer processamento relacionado com o timestamp, e havePostgreSQL fazer todo o trabalho duro para você.,

Finalmente, quando a seleção volta a partir do tstz tabela, vemos que o columntstz percebe que ambos os valores inseridos na verdade são o mesmo ponto intime, mas visto a partir de diferentes lugares do mundo, considerando que o ts columnmakes é impossível comparar as entradas e perceber que eles actuallyhappened exatamente ao mesmo tempo.

tal como referido anteriormente, mesmo quando se utiliza datas temporais com Fuso-horário, o PostgreSQL não armazenará o fuso-horário em uso no momento da entrada, pelo que não há forma de a nossa tabela para ourtstz saber que as entradas são ao mesmo tempo, mas apenas de lugares diferentes.,

a abertura desta seção está ligada à longa e dolorosa história do tempo, e se você não leu ainda, maybenow é um bom momento. Permitam-me citar uma parte relevante do artigo aqui:

O problema básico com o tempo, é que precisamos expressar-se tanto tempo andplace sempre que queremos para lugar algum evento no tempo e no espaço, ainda que tendto assumir as coordenadas espaciais, até mais do que nós assumimos temporalcoordinates, e, no caso de tempo em comum de comunicação, ele issimply deixadas de lado., Apesar da existência de fusos horários e do estrangulamento dos regimes de tempo em todo o mundo, a maioria das pessoas não conhece o seu próprio fuso horário e, certamente, a forma como se relaciona com as recomendações. A maioria das pessoas também não sabe que ao escolher uma notação que esteja próxima da expressão falada ou escrita das datas, torna-a irrelevante para as pessoas que podem não partilhar a cultura, mas que ainda podem ler a língua., É pouco provável que as pessoas mudem o suficiente para pôr estas questões em repouso, pelo que as pessoas responsáveis dos computadores têm de abordar as questões e resistir à vontade de abreviar e abandonar o texto.

várias opções estão disponíveis para introduzir os valores da hora de entrada no PostgreSQL. O mais fácil é usar o formato ISO, então se o código da sua aplicação permite que você esteja pronto. No exemplo a seguir deixamos o fuso horário de fora, como habitualmente, ele é tratado pelo parâmetro de sessão timezone, como visto acima., Se necessário, é claro, você pode inserir o fuso horário em que o carimbo de data / hora valuesdirectly:

select timestamptz '2017-01-08 04:05:06', timestamptz '2017-01-08 04:05:06+02';

inserir ou actualizar a hora, a usar as mesmas seqüências de caracteres literais sem o typedecoration: PostgreSQL já sabe o tipo de coluna de destino, e ituses que para analisar os valores literais na instrução DML.

algumas aplicações uso-os casos só precisam da data. Em seguida, use o tipo de dados de data em PostgreSQL., É claro que então é possível comparar uma data e atimestamp com o fuso horário em suas consultas SQL, e até mesmo adicionar um timeoffset no topo de sua data para construir um timestamp.

intervalos de tempo

PostgreSQL implementa um tipo de dados de intervalo, juntamente com os tipos de dados de tempo, data e timestamptz.,ração, como amonth ou duas semanas, ou até mesmo um milésimo de segundo:

set intervalstyle to postgres;select interval '1 month', interval '2 weeks', 2 * interval '1 week', 78389 * interval '1 ms';

O padrão do PostgreSQL saída se parece com isso:

 interval │ interval │ ?column? │ ?column? ══════════╪══════════╪══════════╪══════════════ 1 mon │ 14 days │ 14 days │ 00:01:18.389(1 row)

Vários intervalstyle valores são possíveis, e o settingpostgres_verbose é bastante agradável para interactivo psql sessões:

set intervalstyle to postgres_verbose;select interval '1 month', interval '2 weeks', 2 * interval '1 week', 78389 * interval '1 ms';

Desta vez temos um user-friendly de saída:

 interval │ interval │ ?column? │ ?column? ══════════╪═══════════╪═══════════╪═════════════════════ @ 1 mon │ @ 14 days │ @ 14 days │ @ 1 min 18.389 secs(1 row)

Quanto tempo é um mês?, Bem, depende de que mês, e o PostgreSQL sabe que:

Quando você anexar um intervalo a uma data ou data-limite no PostgreSQL então o número de dias desse intervalo ajusta-se ao calendário específico que você escolheu. Caso contrário, um intervalo de um mês é considerado 30days. Aqui vemos que computar o último dia de fevereiro é muito fácil:

conclusão

PostgreSQL implementação do calendário é muito boa, então use-o!,

Este artigo é um trecho de meu livro Mastering PostgreSQL no ApplicationDevelopment, que ensina SQL todevelopers de modo que eles podem substituir milhares de linhas de código com verysimple consultas. O livro tem um capítulo completo sobre tipos de dados no PostgreSQL,confira!

Leave A Comment