8.5. Tipos para data e hora

O PostgreSQL suporta o conjunto completo de tipos para data e hora do SQL, mostrados na Tabela 8-9 .

Tabela 8-9. Tipos para data e hora

Nome Tamanho de armazenamento Descrição Menor valor Maior valor Resolução
timestamp [ (p) ] [ without time zone ] 8 bytes tanto data quanto hora 4713 AC 5874897 DC 1 microssegundo / 14 dígitos
timestamp [ (p) ] with time zone 8 bytes tanto data quanto hora, com zona horária 4713 AC 5874897 DC 1 microssegundo / 14 dígitos
interval [ (p) ] 12 bytes intervalo de tempo -178000000 anos 178000000 anos 1 microssegundo
date 4 bytes somente data 4713 AC 32767 DC 1 dia
time [ (p) ] [ without time zone ] 8 bytes somente a hora do dia 00:00:00.00 23:59:59.99 1 microssegundo
time [ (p) ] with time zone 12 bytes somente a hora do dia, com zona horária 00:00:00.00+12 23:59:59.99-12 1 microssegundo

Nota: Antes do PostgreSQL 7.3, escrever apenas timestamp equivalia a escrever timestamp with time zone. Isto foi mudado para ficar em conformidade com o padrão SQL.

Os tipos time, timestamp, e interval aceitam um valor opcional de precisão p, que especifica o número de dígitos fracionários mantidos no campo de segundos. Por padrão não existe limite explícito para a precisão. O intervalo permitido para p é de 0 a 6 para os tipos timestamp e interval.

Nota: Quando os valores de timestamp são armazenados como números de ponto flutuante de precisão dupla (atualmente o padrão), o limite efetivo da precisão pode ser inferior a 6. Os valores de timestamp são armazenados como segundos antes ou após a meia-noite de 2000-01-01. A precisão de microssegundos é obtida para datas próximas a 2000-01-01 (alguns anos), mas a precisão degrada para datas mais afastadas. Quando os valores de timestamp são armazenadas como inteiros de oito bytes (uma opção de compilação), a precisão de microssegundo está disponível para toda a faixa de valores. Entretanto, os valores de timestamp em inteiros de 8 bytes possuem uma faixa de tempo mais limitada do que a mostrada acima: de 4713 AC até 294276 DC.

Para os tipos time o intervalo permitido para p é de 0 a 6 quando armazenados em inteiros de oito bytes, e de 0 a 10 quando armazenados em ponto flutuante.

O tipo time with time zone é definido pelo padrão SQL, mas a definição contém propriedades que levam a uma utilidade duvidosa. Na maioria dos casos, a combinação de date, time, timestamp without time zone e timestamp with time zone deve fornecer uma faixa completa de funcionalidades para data e hora requeridas por qualquer aplicação.

Os tipos abstime e reltime são tipos de menor precisão usados internamente. É desestimulada a utilização destes tipos em novas aplicações, além de ser incentivada a migração das aplicações antigas quando apropriado. Qualquer um destes tipos internos pode desaparecer em uma versão futura, ou mesmo todos.

8.5.1. Entrada de data e hora

A entrada da data e da hora é aceita em praticamente todos os formatos razoáveis, incluindo o ISO 8601, o SQL-compatível, o POSTGRES tradicional, além de outros. Para alguns formatos a ordem do dia, mês e ano na entrada da data é ambíguo e, por isso, existe suporte para especificar a ordem esperada destes campos. Deve ser definido o parâmetro datestyle como MDY para selecionar a interpretação mês-dia-ano, DMY para selecionar a interpretação dia-mês-ano, ou YMD para selecionar a interpretação ano-mês-dia.

O PostgreSQL é mais flexível no tratamento da entrada de data e hora do que o requerido pelo padrão SQL. Consulte o Apêndice B para conhecer as regras exatas de análise da entrada de data e hora e os campos texto reconhecidos, incluindo meses, dias da semana e zonas horárias.

Lembre-se que qualquer entrada literal de data ou hora necessita estar entre apóstrofos, como os textos das cadeias de caracteres. Consulte a Seção 4.1.2.4 para obter mais informações. O SQL requer a seguinte sintaxe

tipo [ (p) ] 'valor'

onde p, na especificação opcional da precisão, é um número inteiro correspondendo ao número de dígitos fracionários do campo de segundos. A precisão pode ser especificada para os tipos time, timestamp e interval. Os valores permitidos estão mencionados acima. Se não for especificada nenhuma precisão na especificação da constante, a precisão do valor literal torna-se o padrão.

8.5.1.1. Datas

A Tabela 8-10 mostra algumas entradas possíveis para o tipo date.

Tabela 8-10. Entrada de data

Exemplo Descrição
January 8, 1999 não-ambíguo em qualquer modo de entrada em datestyle
1999-01-08 ISO 8601; 8 de janeiro em qualquer modo (formato recomendado)
1/8/1999 8 de janeiro no modo MDY; 1 de agosto no modo DMY
1/18/1999 18 de janeiro no modo MDY; rejeitado nos demais modos
01/02/03 2 de janeiro de 2003 no modo MDY; 1 de fevereiro de 2003 no modo DMY; 3 de fevereiro de 2001 no modo YMD
1999-Jan-08 8 de janeiro e qualquer modo
Jan-08-1999 8 de janeiro em qualquer modo
08-Jan-1999 8 de janeiro em qualquer modo
99-Jan-08 8 de janeiro no modo YMD, caso contrário errado
08-Jan-99 8 de janeiro, porém errado no modo YMD
Jan-08-99 8 de janeiro, porém errado no modo YMD
19990108 ISO 8601; 8 de janeiro de 1999 em qualquer modo
990108 ISO 8601; 8 de janeiro de 1999 em qualquer modo
1999.008 ano e dia do ano
J2451187 dia juliano
January 8, 99 BC ano 99 Antes de Cristo

8.5.1.2. Horas

Os tipos hora-do-dia são time [ (p) ] without time zone e time [ (p) ] with time zone. Escrever apenas time equivale a escrever time without time zone.

Entradas válidas para estes tipos consistem na hora do dia seguida por uma zona horária opcional (Veja a Tabela 8-11 e a Tabela 8-12 ). Se for especificada a zona horária na entrada de time without time zone, esta é ignorada em silêncio.

Tabela 8-11. Entrada de hora

Exemplo Descrição
04:05:06.789 ISO 8601
04:05:06 ISO 8601
04:05 ISO 8601
040506 ISO 8601
04:05 AM o mesmo que 04:05; AM não afeta o valor
04:05 PM o mesmo que 16:05; a hora entrada deve ser <= 12
04:05:06.789-8 ISO 8601
04:05:06-08:00 ISO 8601
04:05-08:00 ISO 8601
040506-08 ISO 8601
04:05:06 PST zona horária especificada pelo nome

Tabela 8-12. Entrada de zona horária

Exemplo Descrição
PST Hora Padrão do Pacífico (Pacific Standard Time)
-8:00 deslocamento ISO-8601 para PST
-800 deslocamento ISO-8601 para PST
-8 deslocamento ISO-8601 para PST
zulu Abreviatura militar para UTC
z Forma abreviada de zulu

8.5.1.3. Carimbos do tempo

As entradas válidas para os tipos carimbo do tempo são formadas pela concatenação da data com a hora seguida, opcionalmente, por AD ou BC, seguida por uma zona horária opcional. Portanto

1999-01-08 04:05:06

e

1999-01-08 04:05:06 -8:00

são valores válidos, que seguem o padrão ISO 8601. Além desses, é suportado o formato muito utilizado

January 8 04:05:06 1999 PST

Para timestamp [without time zone], uma zona horária explicitamente especificada na entrada é ignorada em silêncio, ou seja, o valor de data e hora resultante é derivado dos campos de data e hora explicitados nos valores dos campos de entrada, não sofrendo ajuste da zona horária.

Para timestamp with time zone, o valor armazenado internamente está sempre em UTC (Tempo Universal Coordenado, tradicionalmente conhecido por Hora Média de Greenwich,GMT [1] ). Um valor de entrada possuindo a zona horária especificada explicitamente é convertido em UTC utilizando o deslocamento apropriado para esta zona horária. Se não for especificada nenhuma zona horária na cadeia de caracteres da entrada, pressupõe-se que está na mesma zona horária indicada pelo parâmetro do sistema timezone, sendo convertida em UTC utilizando o deslocamento da zona em timezone.

Quando um valor de timestamp with time zone é enviado para a saída, é sempre convertido de UTC para a zona horária corrente de timezone, e mostrado como hora local desta zona. Para ver a hora em outra zona horária, ou se muda timezone ou se usa a construção AT TIME ZONE (veja a Seção 9.8.3 ).

As conversões entre timestamp without time zone e timestamp with time zone normalmente assumem que os valores de timestamp without time zone devem ser recebidos ou fornecidos como hora local da timezone. A referência para uma zona horária diferente pode ser especificada para a conversão utilizando AT TIME ZONE.

8.5.1.4. Intervalos

Os valores do tipo interval podem ser escritos utilizando uma das seguintes sintaxes:

[@] quantidade unidade [quantidade unidade...] [direção]

onde: quantidade é um número (possivelmente com sinal); unidade é second, minute, hour, day, week, month, year, decade, century, millennium, ou abreviaturas ou plurais destas unidades; direção pode ser ago (atrás) ou vazio. O sinal de arroba (@) é opcional. As quantidades com unidades diferentes são implicitamente adicionadas na conta com o sinal adequado.

As quantidades de dias, horas, minutos e segundos podem ser especificadas sem informar explicitamente as unidades. Por exemplo, '1 12:59:10' é lido do mesmo modo que '1 day 12 hours 59 min 10 sec'.

A precisão opcional p deve estar entre 0 e 6, sendo usado como padrão a precisão do literal da entrada.

8.5.1.5. Valores especiais

Também podem ser utilizadas as seguintes funções, compatíveis com o padrão SQL, para obter o valor corrente de data e hora para o tipo de dado correspondente: CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP, LOCALTIME e LOCALTIMESTAMP. As últimas quatro aceitam, opcionalmente, a especificação da precisão (veja também a Seção 9.8.4 ). Entretanto, deve ser observado que são funções SQL, não sendo reconhecidas como cadeias de caracteres de entrada de dados.

Por ser conveniente, o PostgreSQL também suporta vários valores especiais para entrada de data e hora, conforme mostrado na Tabela 8-13 . Os valores infinity e -infinity possuem representação especial dentro do sistema, sendo mostrados da mesma maneira; porém, os demais são simplesmente notações abreviadas convertidas para valores comuns de data e hora ao serem lidos (Em particular, now e as cadeias de caracteres relacionadas são convertidas para um valor específico de data e hora tão logo são lidas). Todos estes valores devem ser escritos entre apóstrofos quando usados como constantes nos comandos SQL.

Tabela 8-13. Entradas especiais de data e hora

Cadeia de caracteres entrada Tipos válidos Descrição
epoch date, timestamp 1970-01-01 00:00:00+00 (hora zero do sistema Unix)
infinity timestamp mais tarde que todos os outros carimbos do tempo
-infinity timestamp mais cedo que todos os outros carimbos do tempo
now date, time, timestamp hora de início da transação corrente
today date, timestamp meia-noite de hoje
tomorrow date, timestamp meia-noite de amanhã
yesterday date, timestamp meia-noite de ontem
allballs time 00:00:00.00 UTC

Exemplo 8-6. Utilização das entradas especiais de data e hora

Neste exemplo são mostradas utilizações das entradas especiais de data e hora para o tipo timestamp with time zone. [2]

=> CREATE TABLE t ( c1 TEXT, c2 TIMESTAMP WITH TIME ZONE );
=> BEGIN;
=> INSERT INTO t VALUES ('epoch', 'epoch');
=> INSERT INTO t VALUES ('infinity', 'infinity');
=> INSERT INTO t VALUES ('-infinity', '-infinity');
=> INSERT INTO t VALUES ('now', 'now');
=> INSERT INTO t VALUES ('today', 'today');
=> INSERT INTO t VALUES ('tomorrow', 'tomorrow');
=> INSERT INTO t VALUES ('yesterday', 'yesterday');
=> INSERT INTO t VALUES ('CURRENT_TIMESTAMP', CURRENT_TIMESTAMP);
=> END;
=> SELECT * FROM t;

        c1         |              c2
-------------------+-------------------------------
 epoch             | 1969-12-31 21:00:00-03
 infinity          | infinity
 -infinity         | -infinity
 now               | 2005-04-19 18:20:35.164293-03
 today             | 2005-04-19 00:00:00-03
 tomorrow          | 2005-04-20 00:00:00-03
 yesterday         | 2005-04-18 00:00:00-03
 CURRENT_TIMESTAMP | 2005-04-19 18:20:35.164293-03
(8 linhas)

8.5.2. Saídas de data e hora

Utilizando o comando SET datestyle o formato de saída para os tipos de data e hora pode ser definido como um dos quatro estilos ISO 8601, SQL (Ingres), POSTGRES tradicional e German. O padrão é o formato ISO (o padrão SQL requer a utilização do formato ISO 8601; o nome do formato de saída "SQL" é um acidente histórico). A Tabela 8-14 mostra exemplo de cada um dos estilos de saída. A saída dos tipos date e time obviamente utilizam apenas a parte da data ou da hora de acordo com os exemplos fornecidos.

Tabela 8-14. Estilos de saída de data e hora

Especificação de estilo Descrição Exemplo
ISO ISO 8601/padrão SQL 2005-04-21 18:39:28.283566-03
SQL estilo tradicional 04/21/2005 18:39:28.283566 BRT
POSTGRES estilo original Thu Apr 21 18:39:28.283566 2005 BRT
German estilo regional 21.04.2005 18:39:28.283566 BRT

Nos estilos SQL e POSTGRES, o dia vem antes do mês se a ordem de campo DMY tiver sido especificada, senão o mês vem antes do dia (veja na Seção 8.5.1 como esta especificação também afeta a interpretação dos valores de entrada). A Tabela 8-15 mostra um exemplo.

Tabela 8-15. Convenções de ordem na data

Definição de datestyle Ordem de entrada Exemplo de saída
SQL, DMY dia/mês/ano 21/04/2005 18:39:28.283566 BRT
SQL, MDY mês/dia/ano 04/21/2005 18:39:28.283566 BRT
Postgres, DMY dia/mês/ano Thu 21 Apr 18:39:28.283566 2005 BRT

A saída do tipo interval se parece com o formato da entrada, exceto que as unidades como century e week são convertidas em anos e dias, e que ago é convertido no sinal apropriado. No modo ISO a saída se parece com

[ quantidade unidade [ ... ] ] [ dias ] [ horas:minutos:segundos ]

Os estilos de data e hora podem ser selecionados pelo usuário utilizando o comando SET datestyle, o parâmetro datestyle no arquivo de configuração postgresql.conf, ou a variável de ambiente PGDATESTYLE no servidor ou no cliente. A função de formatação to_char (veja a Seção 9.7 ) também pode ser utilizada como uma forma mais flexível de formatar a saída de data e hora.

8.5.3. Zonas horárias

Zonas horárias e convenções de zonas horárias são influenciadas por decisões políticas, e não apenas pela geometria da Terra. As zonas horárias em torno do mundo se tornaram um tanto padronizadas durante o século XX, mas continuam propensas a mudanças arbitrárias, particularmente com relação a horários de inverno e de verão. O PostgreSQL utiliza as funcionalidades presentes no sistema operacional para fornecer apoio à saída de zona horária, sendo que os sistemas geralmente contêm informações apenas para o período entre 1902 e 2038 (correspondendo à faixa completa de tempo de um sistema Unix convencional). timestamp with time zone e time with time zone usam informação de zona horária somente dentro desta faixa de anos, assumindo que as horas fora deste intervalo estão em UTC. Mas uma vez que o suporte a zona horária é derivado das funcionalidades do sistema operacional que está por trás, este pode tratar horário de verão e outros comportamentos especiais.

O PostgreSQL se esforça para ser compatível com as definições do padrão SQL para o uso típico. Entretanto, o padrão SQL possui uma combinação única de tipos e funcionalidades para data e hora. Os dois problemas óbvios são:

Para superar estas dificuldades, recomenda-se utilizar tipos de data e hora contendo tanto a data quanto a hora quando utilizar zonas horárias. Recomenda-se não utilizar o tipo time with time zone (embora seja suportado pelo PostgreSQL para aplicações legadas e para conformidade com o padrão SQL). O PostgreSQL assume a zona horária local para qualquer tipo contendo apenas a data ou a hora.

Todas as datas e horas com zona horária são armazenadas internamente em UTC. As horas são convertidas para a hora local no servidor de banco de dados antes de ser enviada para o cliente e, por isso, por padrão, estão na zona horária do servidor.

Existem várias maneiras de selecionar a zona horária utilizada pelo servidor:

Nota: Se uma zona horária inválida for especificada, então a zona horária passa a ser a UTC (pelo menos na maioria dos sistemas).

Consulte o Apêndice B para obter a lista de zonas horárias disponíveis.

8.5.4. Internamente

O PostgreSQL utiliza datas Julianas [4] para todos os cálculos de data e hora, porque possuem a boa propriedade de predizer/calcular corretamente qualquer data mais recente que 4713 AC até bem distante no futuro, partindo da premissa que o ano possui 365,2425 dias.

As convenções de data anteriores ao século 19 são uma leitura interessante, mas não são suficientemente consistentes para permitir a codificação em rotinas tratadoras de data e hora.

Notas

[1]

GMT — Greenwich Mean Time ( Hora média de Greenwich); UTC - Tempo Universal Coordenado ( Hora adotada por todos os países que substituiu o GMT a partir de 1972). Carimbo do Tempo, Como Funciona ?

[2]

Exemplo escrito pelo tradutor, não fazendo parte do manual original.

[3]

DST — "Daylight Saving Time", também conhecido como Horário de Verão. O DST é utilizado em muitos países como ajuste dos relógios locais, para tirar vantagem da luz natural existente durante os meses de verão. (N. do T.)

[4]

Dia Juliano — É obtido pela contagem de dias a partir de um ponto inicial ao meio dia em Janeiro 4713 B.C. (Dia Juliano Zero). Uma forma de informar que dia é, com a menor ambiguidade possível. ( Este sistema foi criado por Joseph Justus Scaliger, (1540 a 1609), que escolheu seu início ao meio dia em 01 de janeiro de 4713 BC, ano bissexto, ano de indição, sendo também domingo, com lua nova. — Asimov,Isaac ?"Counting the Eons") Dia Juliano

SourceForge.net Logo