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.
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.
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.) |
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.
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.
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.
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)
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.
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:
Embora o tipo date não possua zona horária associada, o tipo time pode possuir. As zonas horárias do mundo real possuem pouco significado a menos que estejam 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 como um deslocamento numérico constante em relação ao UTC. Não é possível, portanto, fazer ajuste devido ao horário de verão ao se realizar aritmética de data e hora entre fronteiras do horário de verão (DST). [3]
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:
Se timezone não for especificada no arquivo de configuração postgresql.conf, nem como uma chave da linha de comando do postmaster, o servidor tenta utilizar o valor da variável de ambiente TZ como a zona horária padrão. Se TZ não estiver definida, ou não contiver nenhum nome de zona horária conhecido pelo PostgreSQL, o servidor tenta determinar a zona horária padrão do sistema operacional verificando o comportamento da função localtime() da biblioteca C. A zona horária padrão é selecionada através da correspondência mais próximas entre as zonas horárias conhecidas pelo PostgreSQL.
O comando SQL SET TIME ZONE define a zona horária para a sessão. Esta é uma forma alternativa de SET TIMEZONE TO com uma sintaxe mais compatível com a especificação SQL.
Se a variável de ambiente PGTZ estiver definida no cliente, é utilizada pelos aplicativos libpq para enviar o comando SET TIME ZONE para o servidor durante a conexão.
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] |
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 |