5.5. Tipos para data e hora

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

Tabela 5-9. Tipos para data e hora

TipoDescriçãoArmazenamentoMais cedoMais tardeResolução
timestamp [ (p) ] [ without time zone ]tanto data quanto hora8 bytes4713 AC1465001 DC1 microssegundo / 14 dígitos
timestamp [ (p) ] with time zonetanto data quanto hora8 bytes4713 BCAD 14650011 microssegundo / 14 dígitos
interval [ (p) ]intervalos de tempo12 bytes-178000000 anos178000000 anos1 microssegundo
datesomente datas4 bytes4713 AC32767 DC1 dia
time [ (p) ] [ without time zone ]somente a hora do dia8 bytes00:00:00.0023:59:59.991 microssegundo
time [ (p) ] with time zonesomente a hora do dia12 bytes00:00:00.00+1223:59:59.99-121 microssegundo

time, timestamp, e interval aceitam um valor opcional de precisão p, que especifica o número de dígitos fracionários presentes 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, porque os valores de timestamp são armazenados como segundos decorridos desde 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 timestamps são armazenadas como inteiros de oito bytes (uma opção em tempo de compilação), a precisão de microssegundo está disponível para todo o intervalo de valores.

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

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 ficaram bastante padronizadas durante o século XX, mas continuam suscetíveis a mudanças arbitrárias. 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 intervalo de tempo entre 1902 e 2038 (correspondendo ao período completo de um sistema Unix convencional). timestamp with time zone e time with time zone usam a informação de zona horária somente dentro deste intervalo de tempo, pressupondo que as horas fora deste intervalo estão em UTC.

O tipo time with time zone é definido pelo padrão SQL, mas a definição apresenta propriedades que levam a utilizações duvidosas. Na maioria dos casos, a combinação de date, time, timestamp without time zone e timestamp with time zone deve fornecer uma faixa completa das funcionalidades de data e hora necessária para qualquer aplicação.

Os tipos abstime e reltime são tipos de menor precisão usados internamente apenas. É desencorajada a utilização destes tipos em novas aplicações, além de ser encorajada a migração das aplicações antigas quando for conveniente. Qualquer um, ou mesmo todos estes tipos internos, podem desaparecer nas próximas versões.

5.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 PostgreSQL tradicional, além de outros. Para alguns formatos, a ordem do dia e do mês da entrada da data pode ser ambíguo e, por isso, existe apoio para especificar a ordem esperada destes campos. O comando SET DateStyle TO 'US' ou SET DateStyle TO 'NonEuropean' especifica a variante "mês antes do dia", o comando SET DateStyle TO 'European' especifica a variante "dia antes do mês".

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

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

type [ (p) ] 'valor'

onde p na especificação opcional da precisão é um número inteiro correspondente ao número de dígitos fracionários do campo de segundos. A precisão pode ser especificada para os tipos para time, timestamp e interval.

5.5.1.1. Datas

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

Tabela 5-10. Entrada de data

ExemploDescrição
January 8, 1999não-ambíguo
1999-01-08formato ISO-8601, o preferido
1/8/1999Americano; lê primeiro de agosto no modo Europeu
8/1/1999Europeu; lê primeiro de agosto no modo Americano
1/18/1999Americano; lê 18 de janeiro em qualquer modo
19990108ISO-8601 ano, mês e dia
990108ISO-8601 ano, mês e dia
1999.008ano e dia do ano
99008ano e dia do ano
J2451187data juliana
January 8, 99 BCano de 99 Antes de Cristo

5.5.1.2. Horas

O tipo time pode ser especificado como time ou como time without time zone. A precisão opcional p deve estar entre 0 e 6, tomando como padrão a precisão do literal de entrada da hora.

A Tabela 5-11 mostra as entradas válidas para o tipo time.

Tabela 5-11. Entrada de hora

ExemploDescrição
04:05:06.789ISO 8601
04:05:06ISO 8601
04:05ISO 8601
040506ISO 8601
04:05 AMo mesmo que 04:05; AM não afeta o valor
04:05 PMo mesmo que 16:05; a hora entrada deve ser <= 12
allballso mesmo que 00:00:00

O tipo time with time zone aceita todas as entradas incluindo a legal para o tipo time, acrescida da zona horária legal, conforme mostrado na Tabela 5-12.

Tabela 5-12. Entrada de hora com zona horária

ExemploDescrição
04:05:06.789-8ISO 8601
04:05:06-08:00ISO 8601
04:05-08:00ISO 8601
040506-08ISO 8601

Consulte a Tabela 5-13 para ver mais exemplos de zonas horárias.

5.5.1.3. Registro de data

Os tipos registro de data são timestamp [ (p) ] without time zone e timestamp [ (p) ] with time zone. Escrever apenas timestamp é equivalente a escrever timestamp without time zone.

Nota: Antes do PostgreSQL 7.3 escrever apenas timestamp era equivalente a escrever timestamp with time zone. Foi mudado para ficar conforme o padrão SQL.

As entradas válidas para registro de data consistem na concatenação da data com a hora, seguida opcionalmente por AD ou BC, seguida por uma zona horária opcional (consulte a Tabela 5-13). 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, o formato muito utilizado

January 8 04:05:06 1999 PST

é suportado.

A precisão opcional p deve estar entre 0 e 6, tomando como padrão a precisão do literal de entrada do tipo timestamp.

Para timestamp without time zone, uma zona horária explícita especificada na entrada é ignorada silenciosamente, ou seja, o valor resultante do valor da data/hora é derivada dos campos de data/hora explicitados no valor da entrada, sem ser ajustado para a zona horária.

Para timestamp with time zone, o valor armazenado internamente está sempre em UTC (GMT). O valor de entrada possuindo zona horária especificada explicitamente é convertido em UTC, utilizando o deslocamento adequado para a zona horária. Se nenhuma zona horária for especificada na cadeia de caracteres da entrada, pressupõe-se que está na mesma zona horária indicada pelo parâmetro TimeZone do sistema, sendo convertida em UTC utilizando o deslocamento da zona TimeZone.

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

As conversões entre timestamp without time zone e timestamp with time zone normalmente pressupõem que o valor de timestamp without time zone devem ser tomados 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.

Tabela 5-13. Entrada de zona horária

Zona horáriaDescrição
PSTPacific Standard Time
-8:00deslocamento ISO-8601 para PST
-800deslocamento ISO-8601 para PST
-8deslocamento ISO-8601 para PST

5.5.1.4. Intervalos

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

  Quantidade Unidade [Quantidade Unidade...] [Direção]
@ Quantidade Unidade [Quantidade Unidade...] [Direção]

onde: Quantidade é o número (possivelmente com sinal), Unidade é second, minute, hour, day, week, month, year, decade, century, millennium, ou abreviaturas ou plurais destas unidades; A Direção pode ser ago (atrás) ou vazio. O sinal de arroba (@) é uma notação 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 se 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, tomando como padrão a precisão do literal da entrada.

5.5.1.5. Valores especiais

As seguintes funções, compatíveis com o padrão SQL podem ser utilizadas como valores de data e hora para o tipo de dado correspondente: CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP. A última aceita uma especificação opcional de precisão (veja também a Seção 6.8.4).

O PostgreSQL também suporta diversos valores especiais para entrada de data e hora por conveniência, conforme mostrado na Tabela 5-14. Os valores infinity e -infinity são representados de forma especial dentro do sistema, sendo mostrados da mesma forma; porém, os demais são apenas notações abreviadas convertidas para valores comuns de data e hora quando lidos.

Tabela 5-14. Entradas especiais de data e hora

Cadeia de caracteres entradaDescrição
epoch1970-01-01 00:00:00+00 (zero horas do sistema Unix)
infinitydepois de todos os outros registros de data e hora (não disponível para o tipo date)
-infinityantes de todos os outros registros de data e hora (não disponível para o tipo date)
nowhora da transação corrente
todaymeia-noite de hoje
tomorrowmeia-noite de amanhã
yesterdaymeia-noite de ontem
zulu, allballs, z00:00:00.00 GMT

5.5.2. Saídas de data e hora

O formato da saída pode ser definido como um dos quatro estilos entre ISO 8601, SQL (Ingres), PostgreSQL tradicional e German, utilizando SET DateStyle. 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 5-15 mostra um 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 em conformidade com os exemplos fornecidos.

Tabela 5-15. Estilos de data e hora

Especificação de estiloDescriçãoExemplo
ISOISO 8601/padrão SQL1997-12-17 07:37:16-08
SQLestilo tradicional12/17/1997 07:37:16.00 PST
PostgreSQLestilo originalWed Dec 17 07:37:16 1997 PST
Germanestilo regional17.12.1997 07:37:16.00 PST

O estilo SQL possui as variantes Européia e não Européia (U.S.), as quais determinam se o mês vem antes ou depois do dia (consulte a Seção 5.5.1 para ver como esta definição também afeta a interpretação dos valores entrados). A Tabela 5-16 mostra um exemplo.

Tabela 5-16. Convenções de ordem na data

Especificação de estiloDescriçãoExemplo
Europeandia/mês/ano17/12/1997 15:37:16.00 MET
USmês/dia/ano12/17/1997 07:37:16.00 PST

A saída do tipo interval se parece com o formato da entrada, exceto que as unidades como week ou century são convertidas em dias. No modo ISO a saída se parece com

[ Quantidade Unidade [ ... ] ] [ Dias ] Horas:Minutos [ ago ]

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, e a variável do ambiente PGDATESTYLE no servidor ou no cliente. A função de formatação to_char (veja a Seção 6.7) também pode ser utilizada como forma mais flexível de formatar a saída de data e hora.

5.5.3. Zonas horárias

O PostgreSQL se esforça em ser compatível com as definições do padrão SQL para a utilização típica. Entretanto, o padrão SQL possui uma mistura de funcionalidades peculiar para tipos de data e hora. Dois problemas 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 a não utilização do tipo time with time zone (embora seja suportado pelo PostgreSQL para aplicações legadas e para compatibilidade com outras implementações do SQL). O PostgreSQL pressupõe a zona horária local para qualquer tipo contendo apenas a data ou a hora. Além disso, o suporte da zona horária é derivado da capacidade do sistema operacional subjacente e, portanto, pode tratar horário de verão (DST) e outros comportamentos esperados.

O PostgreSQL obtém o suporte de zona horária do sistema operacional subjacente para datas entre 1902 e 2038 (próximo dos limites típicos de data dos sistemas da família Unix). Fora deste intervalo, todas as datas são pressupostas como sendo especificadas e utilizadas no Universal Coordinated Time (UTC/Tempo Coordenado Universal).

Todas as datas e horas são armazenadas internamente em UTC, tradicionalmente conhecido como Greenwich Mean Time (GMT/Hora do meridiano de Greenwich). As horas são convertidas para a hora local no servidor de banco de dados antes do envio para a aplicação cliente estando, portanto, na zona horária do servidor por padrão.

Existem vários modos 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 A para obter a lista das zonas horárias disponíveis.

5.5.4. Internals

O PostgreSQL utiliza datas Julianas 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]

DST significa "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 obter mais vantagens com a luz natural existente durante os meses de verão. (N.T.)