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.
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.
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 |
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 |
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.
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.
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)
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.
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.
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.
[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 |