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
Tipo | Descrição | Armazenamento | Mais cedo | Mais tarde | Resolução |
---|---|---|---|---|---|
timestamp [ (p) ] [ without time zone ] | tanto data quanto hora | 8 bytes | 4713 AC | 1465001 DC | 1 microssegundo / 14 dígitos |
timestamp [ (p) ] with time zone | tanto data quanto hora | 8 bytes | 4713 BC | AD 1465001 | 1 microssegundo / 14 dígitos |
interval [ (p) ] | intervalos de tempo | 12 bytes | -178000000 anos | 178000000 anos | 1 microssegundo |
date | somente datas | 4 bytes | 4713 AC | 32767 DC | 1 dia |
time [ (p) ] [ without time zone ] | somente a hora do dia | 8 bytes | 00:00:00.00 | 23:59:59.99 | 1 microssegundo |
time [ (p) ] with time zone | somente a hora do dia | 12 bytes | 00:00:00.00+12 | 23:59:59.99-12 | 1 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.
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.
A Tabela 5-10 mostra algumas entradas possíveis para o tipo date.
Tabela 5-10. Entrada de data
Exemplo | Descrição |
---|---|
January 8, 1999 | não-ambíguo |
1999-01-08 | formato ISO-8601, o preferido |
1/8/1999 | Americano; lê primeiro de agosto no modo Europeu |
8/1/1999 | Europeu; lê primeiro de agosto no modo Americano |
1/18/1999 | Americano; lê 18 de janeiro em qualquer modo |
19990108 | ISO-8601 ano, mês e dia |
990108 | ISO-8601 ano, mês e dia |
1999.008 | ano e dia do ano |
99008 | ano e dia do ano |
J2451187 | data juliana |
January 8, 99 BC | ano de 99 Antes de Cristo |
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
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 |
allballs | o 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
Exemplo | Descrição |
---|---|
04:05:06.789-8 | ISO 8601 |
04:05:06-08:00 | ISO 8601 |
04:05-08:00 | ISO 8601 |
040506-08 | ISO 8601 |
Consulte a Tabela 5-13 para ver mais exemplos de zonas horárias.
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.
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.
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 entrada | Descrição |
---|---|
epoch | 1970-01-01 00:00:00+00 (zero horas do sistema Unix) |
infinity | depois de todos os outros registros de data e hora (não disponível para o tipo date) |
-infinity | antes de todos os outros registros de data e hora (não disponível para o tipo date) |
now | hora da transação corrente |
today | meia-noite de hoje |
tomorrow | meia-noite de amanhã |
yesterday | meia-noite de ontem |
zulu, allballs, z | 00:00:00.00 GMT |
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 estilo | Descrição | Exemplo |
---|---|---|
ISO | ISO 8601/padrão SQL | 1997-12-17 07:37:16-08 |
SQL | estilo tradicional | 12/17/1997 07:37:16.00 PST |
PostgreSQL | estilo original | Wed Dec 17 07:37:16 1997 PST |
German | estilo regional | 17.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 estilo | Descrição | Exemplo |
---|---|---|
European | dia/mês/ano | 17/12/1997 15:37:16.00 MET |
US | mês/dia/ano | 12/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.
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:
Embora o tipo date não possua zona horária associada, o tipo time pode possuir. As zonas horárias do mundo real não possuem nenhum significado, a não ser quando associadas a uma data e hora, porque o deslocamento pode variar durante o ano devido ao horário de verão.
A zona horária padrão é especificada por uma constante inteira contendo o deslocamento em relação à GMT/UTC. Não é possível fazer ajuste devido ao horário de verão (DST) ao se realizar aritmética de data e hora entre fronteiras do horário de verão (DST). [1]
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:
A variável de ambiente TZ no hospedeiro do servidor é utilizada pelo servidor como a zona horária padrão, se nenhuma outra for especificada.
O parâmetro de configuração timezone pode ser definido no arquivo postgresql.conf.
A variável de ambiente PGTZ, quando definida no cliente, é utilizada pelas aplicações que utilizam a libpq para enviar o comando SET TIME ZONE para o servidor durante a conexão.
O comando SQL SET TIME ZONE define a zona horária para a sessão.
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.
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.
[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.) |