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. As operações disponíveis para estes tipos de dado estão descritas na Seção 9.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 / 14 dígitos
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 / 14 dígitos
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 / 14 dígitos

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. A mesma opção de compilação também determina se os valores de time e interval são armazenados como ponto flutuante ou inteiros de oito bytes. No caso de ponto flutuante, a precisão dos valores de interval degrada conforme o tamanho do intervalo aumenta.

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 aplicativo.

Os tipos abstime e reltime são tipos de menor precisão usados internamente. É desestimulada a utilização destes tipos em novos aplicativos, além de ser incentivada a migração dos aplicativos antigos 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.5 para obter informações adicionais. 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 January 8 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 da era comum [a]
Notas:
a. A Era Comum (EC), ou "Common Era (CE)" em inglês, é um termo relativamente novo que tem experimentado um aumento de utilização e se espera que, eventualmente, substitua AD. Este último é uma abreviação de "Anno Domini" em Latim, ou "Ano do Senhor". Este último se refere ao ano de nascimento aproximado de Yeshua de Nazaré (Jesus Cristo). EC, CE, AD e DC possuem o mesmo valor. The use of "CE" and "BCE" to identify dates (N. do T.)

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 (Consulte 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

Consulte o Apêndice B para ver a lista de nomes de zona horária reconhecidos na entrada.

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, pela zona horária, e seguida opcionalmente por AD ou BC (Como alternativa, AD ou BC pode aparecer antes da zona horária, mas esta não é a ordem preferida). 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

O padrão SQL diferencia os literais timestamp without time zone de timestamp with time zone pela existência de "+"; ou "-". Portanto, de acordo com o padrão,

TIMESTAMP '2004-10-19 10:23:54'

é um timestamp without time zone, enquanto

TIMESTAMP '2004-10-19 10:23:54+02'

é um timestamp with time zone. O PostgreSQL difere do padrão requerendo que os literais timestamp with time zone sejam digitados explicitamente:

TIMESTAMP WITH TIME ZONE '2004-10-19 10:23:54+02'

Se o literal não for informado explicitamente como sendo timestamp with time zone, o PostgreSQL ignora em silêncio qualquer indicação de zona horária no literal. Ou seja, o valor resultante de data e hora é derivado dos campos data e hora do valor da entrada, não sendo ajustado conforme a 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 (consulte a Seção 9.9.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

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

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 (consulte também a Seção 9.9.4). Entretanto, deve ser observado que são funções SQL, não sendo reconhecidas como cadeias de caracteres de entrada de dados.

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]

BEGIN;
CREATE TEMPORARY TABLE t ( c1 TEXT, c2 TIMESTAMP WITH TIME ZONE ) ON COMMIT DROP;
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);
SELECT * FROM t;
COMMIT;

        c1         |             c2
-------------------+----------------------------
 epoch             | 1969-12-31 21:00:00-03
 infinity          | infinity
 -infinity         | -infinity
 now               | 2007-03-04 09:10:20.234-03
 today             | 2007-03-04 00:00:00-03
 tomorrow          | 2007-03-05 00:00:00-03
 yesterday         | 2007-03-03 00:00:00-03
 CURRENT_TIMESTAMP | 2007-03-04 09:10:20.234-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 (consulte a Seção 9.8) 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. Atualmente o PostgreSQL suporta as regras de horário de inverno e verão (daylight-savings rules) no período de tempo que vai de 1902 até 2038 (correspondendo à faixa completa de tempo do sistema Unix convencional). Datas fora desta faixa são consideradas como estando na "hora padrão" da zona horária selecionada, sem importar em que parte do ano se encontram.

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 os aplicativos legados 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. São convertidas para a hora local na zona especificada pelo parâmetro de configuração timezone antes de serem mostradas ao cliente.

O parâmetro de configuração timezone pode ser definido no arquivo postgresql.conf, ou por qualquer outro meio padrão descrito na Seção 16.4. Existem, também, várias outras formas especiais de defini-lo:

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]

Daylight Saving Time (ou Horário de Verão, como é conhecido em muitos países) é uma maneira de aproveitar melhor os dias de verão avançando os relógios em uma hora nos dias de verão. Assim, fica parecendo que o sol nasce uma hora mais tarde de manhã, quando as pessoas geralmente estão dormindo, beneficiando as tardes que ficam com uma hora a mais, quando geralmente as pessoas estão acordadas: O nascente e o poente ficam com uma hora a mais em relação ao horário normal. About Daylight Saving Time (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 ambigüidade 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 (ano no qual, pela lei Romana, se fazia o censo das propriedades e dos indivíduos), sendo também domingo, com lua nova. — Asimov,Isaac ?"Counting the Eons") Dia Juliano

SourceForge.net Logo CSS válido!