O PostgreSQL aceita o conjunto completo de tipos de dados de data e hora do padrão SQL, mostrados na Tabela 8.9. As operações disponíveis nesses tipos de dados são descritas na Seção 9.9. As datas são contadas segundo o calendário gregoriano, mesmo em anos anteriores à introdução desse calendário (veja a Seção B.6 para obter mais informações).
Tabela 8.9. Tipos de dados de data e hora
| Nome | Tamanho de armazenamento | Descrição | Menor valor | Maior valor | Resolução |
|---|---|---|---|---|---|
timestamp [ ( | 8 bytes | tanto data quanto hora (sem zona horária) | 4713 A.C. | 294276 D.C. | 1 microssegundo |
timestamp [ ( | 8 bytes | tanto data quanto hora, com zona horária | 4713 A.C. | 294276 D.C. | 1 microssegundo |
date | 4 bytes | data (sem hora do dia) | 4713 A.C. | 5874897 D.C. | 1 dia |
time [ ( | 8 bytes | hora do dia (sem data) | 00:00:00 | 24:00:00 | 1 microssegundo |
time [ ( | 12 bytes | hora do dia (sem data), com zona horária | 00:00:00+1559 | 24:00:00-1559 | 1 microssegundo |
interval [ | 16 bytes | intervalo de tempo | -178000000 anos | 178000000 anos | 1 microssegundo |
O padrão SQL requer que quando estiver escrito
apenas timestamp isto seja equivalente a
timestamp without time zone, e o
PostgreSQL respeita este comportamento.
O tipo de dados timestamptz é aceito como abreviatura
para o tipo de dados timestamp with time zone; esta
é uma extensão do PostgreSQL.
Os tipos de dados
time, timestamp e interval
aceitam um valor de precisão opcional p,
que especifica o número de dígitos fracionários presentes no campo
de segundos.
Por padrão, não há um limite explícito para a precisão.
O intervalo permitido para p é de 0 a 6.
O tipo de dados interval possui uma opção adicional,
que é a de restringir o conjunto de campos armazenados escrevendo
uma dessas frases:
YEAR MONTH DAY HOUR MINUTE SECOND YEAR TO MONTH DAY TO HOUR DAY TO MINUTE DAY TO SECOND HOUR TO MINUTE HOUR TO SECOND MINUTE TO SECOND
Note que, se tanto campos
quanto p forem especificados,
então campos deve incluir
SECOND, uma vez que a precisão se aplica apenas
aos segundos.
O tipo de dados time with time zone é definido pelo
padrão SQL, mas a definição exibe propriedades
que levam a uma utilidade questionável.
Geralmente, uma combinação de date,
time, timestamp without time zone e
timestamp with time zone
deve fornecer uma gama completa de funcionalidades de data/hora
requeridas por qualquer aplicação.
A entrada de data e hora é aceita em praticamente qualquer formato
razoável, incluindo ISO 8601, o formato compatível com o padrão
SQL, o formato tradicional do
POSTGRES, e outros.
Para alguns formatos, a ordem de dia, mês e ano na entrada da data
é ambíguo, e há suporte para especificar a ordem esperada destes
campos.
O parâmetro DateStyle deve ser configurado
como MDY para selecionar a interpretação mês-dia-ano,
como DMY para selecionar a interpretação dia-mês-ano, ou
como YMD para selecionar a interpretação ano-mês-dia.
Exemplo 8.6. Exemplo do tradutor
Esta consulta mostra o valor do parâmetro
DateStyle em uso, que neste caso é ISO 8601
(ano-mês-dia), seguido por DMY (dia/mês/ano).
SELECT name, setting, short_desc
FROM pg_settings
WHERE name='DateStyle';
name | setting | short_desc -----------+----------+----------------------------------------------------------- DateStyle | ISO, DMY | Define o formato de exibição para valores de data e hora. (1 linha)
O PostgreSQL é mais flexível no modo de tratar a entrada de data/hora do que o padrão SQL requer. Veja o Apêndice B para obter as regras exatas de análise de entrada de data/hora e os campos de texto reconhecidos, incluindo meses, dias da semana e zonas horárias. [43]
Lembre-se de que qualquer entrada literal de data ou hora precisa ser colocada entre apóstrofos, como as cadeias de caracteres de texto. Veja a Seção 4.1.2.7 para obter mais informações. O padrão SQL requer a seguinte sintaxe
tipo_de_dados[ (p) ] 'valor'
onde p é uma especificação de precisão
opcional, que fornece o número de dígitos fracionários no campo de
segundos. A precisão pode ser especificada para os tipos de dados
time, timestamp e interval,
podendo estar no intervalo de 0 a 6. Se nenhuma precisão for
especificada na especificação da constante, o padrão será a
precisão do valor literal (mas não mais de 6 dígitos).
A Tabela 8.10 mostra as entrada
possíveis para o tipo de dados date.
Tabela 8.10. Entradas de data
| Exemplo | Descrição |
|---|---|
| 1999-01-08 | ISO 8601; 8 de janeiro de 1999 em qualquer modo (formato recomendado) |
| January 8, 1999 | 8 de janeiro de 1999, não ambíguo em qualquer modo de
entrada em datestyle |
| 1/8/1999 | 8 de janeiro de 1999 no modo MDY;
1º de agosto de 1999 no modo DMY |
| 1/18/1999 | 18 de janeiro de 1999 no modo MDY;
rejeitado nos outros 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 de 1999 em qualquer modo |
| Jan-08-1999 | 8 de janeiro de 1999 em qualquer modo |
| 08-Jan-1999 | 8 de janeiro de 1999 em qualquer modo |
| 99-Jan-08 | 8 de janeiro de 1999 no modo YMD,
rejeitado nos outros modos |
| 08-Jan-99 | 8 de janeiro de 1999, exceto no modo
YMD, onde é rejeitado |
| Jan-08-99 | 8 de janeiro de 1999, exceto no modo
YMD, onde é rejeitado |
| 19990108 | ISO 8601; 8 de janeiro de 1999 em qualquer modo |
| 990108 | ISO 8601; 8 de janeiro de 1999 em qualquer modo |
| 1999.008 | 8 de janeiro de 1999; ano e dia do ano |
| J2451187 | 8 de janeiro de 1999; data juliana |
| January 8, 99 BC | 0099-01-08 BC, ano 99 antes de Cristo |
Os tipos de dados para hora do dia são
time [ ( e
p) ] without time zonetime [ (.
p) ] with time zonetime sozinho equivale a
time without time zone.
A entrada válida para estes tipos de dados consiste em uma
hora do dia seguida por uma zona horária opcional.
(Veja a Tabela 8.11
e a Tabela 8.12.)
Se for especificada uma zona horária na entrada para o tipo de dados
time without time zone, ela será ignorada em silêncio.
Também pode ser especificada uma data, mas ela será ignorada,
exceto quando for usado um nome de zona horária que envolva uma
regra de horário de verão como, por exemplo,
America/New_York.
Nesse caso é necessário especificar a data, para determinar se
vai ser aplicado o horário padrão ou o horário de verão.
O deslocamento de zona horária apropriado é registrado no valor de
time with time zone e é mostrado da mesma forma como
está armazenado; não é ajustado para a zona horária ativa.
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 | idêntico a 04:05; AM não afeta o valor |
04:05 PM | idêntico a 16:05; a hora entrada deve ser <= 12 |
04:05:06.789-8 | ISO 8601, com zona horária como deslocamento UTC |
04:05:06-08:00 | ISO 8601, com zona horária como deslocamento UTC |
04:05-08:00 | ISO 8601, com zona horária como deslocamento UTC |
040506-08 | ISO 8601, com zona horária como deslocamento UTC |
040506+0730 | ISO 8601, com hora fracionária de zona horária como deslocamento UTC |
040506+07:30:00 | deslocamento UTC especificado em segundos (não permitido na ISO 8601) |
04:05:06 PST | zona horária especificada por abreviatura |
2003-04-12 04:05:06 America/New_York | zona horária especificada pelo nome completo |
Tabela 8.12. Entada de zona horária
| Exemplo | Descrição |
|---|---|
PST | Abreviatura (Pacific Standard Time) |
America/New_York | Nome completo da zona horária |
PST8PDT | especificação de zona horária no estilo POSIX |
-8:00:00 | deslocamento UTC para PST |
-8:00 | deslocamento UTC para PST (formato estendido ISO 8601) |
-800 | deslocamento UTC para PST (formato básico ISO 8601) |
-8 | deslocamento UTC para PST (formato básico ISO 8601) |
zulu | Abreviatura militar para UTC |
z | Forma curta para zulu (também na ISO 8601) |
Veja a Seção 8.5.3 pata obter mais informações sobre como especificar as zonas horárias.
A entrada válida para os tipos de dados de carimbo de tempo consiste
na concatenação de uma data e uma hora, seguida por uma zona horária
opcional, seguida por AD ou BC
opcional.
(Como alternativa, AD/BC
pode aparecer antes da zona horária, mas esta não é a ordem
preferida.) Assim
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 disso, o formato comum
January 8 04:05:06 1999 PST
também é aceito.
O padrão SQL diferencia os literais
timestamp without time zone e
timestamp with time zone pela presença do símbolo
“+” ou “-” e a zona horária após
a hora. Então, segundo o padrão,
TIMESTAMP '2004-10-19 10:23:54'
é timestamp without time zone, enquanto
TIMESTAMP '2004-10-19 10:23:54+02'
é timestamp with time zone.
O PostgreSQL nunca examina o conteúdo
de literal cadeia de caracteres antes de determinar
o seu tipo de dados, portanto trata as duas formas acima como
timestamp without time zone.
Para garantir que o literal vai ser tratado como
timestamp with time zone, o tipo de dados correto
deve ser indicado explicitamente:
TIMESTAMP WITH TIME ZONE '2004-10-19 10:23:54+02'
Em um valor que tenha sido determinado como sendo
timestamp without time zone, o
PostgreSQL irá ignorar em silêncio
qualquer indicação de zona horária.
Ou seja, o valor resultante é derivado dos campos de data/hora no
valor de entrada sem ser ajustado para a zona horária.
Para valores de `timestamp with time zone`, uma
cadeia de caracteres de entrada que inclua uma zona horária
explícita será convertida para UTC
(Universal Coordinated
Time) utilizando o deslocamento apropriado para esta
zona horária.
Se não for especificada uma zona horária na cadeia de caracteres
de entrada, assume-se que a zona horária seja a indicada pelo
parâmetro do sistema TimeZone ,
sendo convertido para UTC usando o deslocamento para a zona
horária timezone.
Em ambos os casos, o valor é armazenado internamente em UTC, e a
zona horária originalmente declarada ou assumida não é mantida.
Quando um valor timestamp with time zone é mostrado,
é sempre convertido de UTC para para a zona horária corrente de
timezone, e mostrado como hora local nessa zona.
Para ver a hora em outra zona horária, deve ser mudado o valor de
timezone, ou usada a construção
AT TIME ZONE.
(veja a Seção 9.9.4).
As conversões entre timestamp without time zone e
timestamp with time zone normalmente assumem que o
valor de timestamp without time zone deve ser aceito
ou mostrado como hora local de timezone.
Uma zona horária diferente pode ser especificada para a conversão
usando AT TIME ZONE.
O PostgreSQL aceita vários valores
especiais de data/hora por conveniência, conforme mostrado na
Tabela 8.13. Os valores
infinity e -infinity
têm uma representação especial dentro do sistema, e são mostrados
sem alterações; mas os demais valores são apenas uma forma
de notação abreviada, sendo convertidos para valores comuns de
data/hora assim que são lidos.
(Em particular, now e cadeias relacionadas são
convertidas para valores específicos assim que são lidas.)
Todos estes valores precisam ser colocados entre apóstrofos quando
usados como constantes em comandos SQL.
Tabela 8.13. Entradas especiais de data e hora
| Cadeia de entrada | Tipos de dados válidos | Descrição |
|---|---|---|
epoch | date, timestamp | 1970-01-01 00:00:00+00 (hora zero do sistema Unix) |
infinity | date, timestamp, interval | mais tarde que todos os outros carimbos de tempo |
-infinity | date, timestamp, interval | mais cedo que todos os outros carimbos de tempo |
now | date, time, timestamp | hora de início da transação corrente |
today | date, timestamp | meia-noite (00:00) de hoje |
tomorrow | date, timestamp | meia-noite (00:00) de amanhã |
yesterday | date, timestamp | meia noite (00:00) de ontem |
allballs | time | 00:00:00.00 UTC |
Também podem ser usadas as seguintes funções compatíveis com o
padrão SQL no tipo de dados correspondente:
CURRENT_DATE, CURRENT_TIME,
CURRENT_TIMESTAMP, LOCALTIME,
LOCALTIMESTAMP.
(Veja a Seção 9.9.5.)
Note que estas são funções SQL e
não são reconhecidas como cadeia de caracteres
de entrada de dados (ou seja, não devem ser escritas
entre apóstrofos).
Exemplo 8.7. Exemplo do tradutor
Neste exemplo são inseridos valores em um campo do tipo de dados
timestamp with time zone usando entradas especiais e
funções de data e hora e, em seguida, é realizada uma consulta
para ver como são mostrados os que foram valores inseridos.
BEGIN;
CREATE TEMPORARY TABLE t (
c1 TEXT,
c2 TIMESTAMP WITH TIME ZONE
) ON COMMIT DROP;
INSERT INTO t VALUES
('epoch', 'epoch'),
('infinity', 'infinity'),
('-infinity', '-infinity'),
('now', 'now'),
('today', 'today'),
('tomorrow', 'tomorrow'),
('yesterday', 'yesterday'),
('LOCALTIMESTAMP', LOCALTIMESTAMP);
SELECT pg_sleep(2); -- dormir por 2 segundos
INSERT INTO t VALUES
('CURRENT_TIMESTAMP', CURRENT_TIMESTAMP);
SELECT * FROM t;
c1 | c2
-------------------+-------------------------------
epoch | 1969-12-31 21:00:00-03
infinity | infinity
-infinity | -infinity
now | 2026-01-16 10:13:56.262454-03
today | 2026-01-16 00:00:00-03
tomorrow | 2026-01-17 00:00:00-03
yesterday | 2026-01-15 00:00:00-03
LOCALTIMESTAMP | 2026-01-16 10:13:56.262454-03
CURRENT_TIMESTAMP | 2026-01-16 10:13:56.262454-03
(9 linhas)
COMMIT;
Note que a data e a hora não mudam dentro da transação, é a
data e hora da transação, e não a do comando
INSERT.
Enquanto as cadeias de caracteres de entrada now,
today, tomorrow e
yesterday são boas para uso nos comandos
SQL interativos, elas podem ter um
comportamento surpreendente quando são salvas e executadas
posteriormente como, por exemplo, em instruções preparadas,
visões e definições de função.
A cadeia de caracteres pode ser convertida em um valor de tempo
específico, que continua sendo usado por muito tempo após estar
desatualizado.
Nesses contextos é melhor usar uma função SQL.
Por exemplo, CURRENT_DATE + 1 é mais seguro
que 'tomorrow'::date.
O formato de saída dos tipos de dados de data/hora pode ser definido
como um destes quatro estilos: ISO 8601, SQL (Ingres),
POSTGRES tradicional
(formato date do Unix), ou
German.
O padrão é o formato ISO.
(O padrão SQL requer o uso do formato ISO 8601.
O nome do formato de saída “SQL” é um acidente histórico.)
A Tabela 8.14 mostra um
exemplo para cada estilo de saída.
A saída dos tipos de dados date e time
são geralmente apenas a parte da data ou da hora segundo os exemplos
fornecidos.
Entretanto, o estilo POSTGRES produz a
saída de valores para apenas data no formato ISO.
[44]
Tabela 8.14. Estilos de saída de data e hora
| Especificação do 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 |
Postgres | estilo original | Wed Dec 17 07:37:16 1997 PST |
German | estilo regional | 17.12.1997 07:37:16.00 PST |
O padrão ISO 8601 especifica o uso da letra maiúscula
T para separar a data da hora.
O PostgreSQL aceita este formato na
entrada, mas na saída usa espaço no lugar do
T, conforme mostrado acima.
Isso se dá para melhor legibilidade e consistência com o
RFC 3339,
assim como outros sistemas de banco de dados.
Nos estilos SQL e POSTGRES o dia aparece antes do mês, se tiver sido especificada a ordenação de campo DMY, caso contrário o mês aparece antes do dia. (Veja Seção 8.5.1 para saber como esta configuração também afeta a interpretação dos valores de entrada.) A Tabela 8.15 mostra exemplos.
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 | 17/12/1997 15:37:16.00 CET |
SQL, MDY | mês/dia/ano | 12/17/1997 07:37:16.00 PST |
Postgres, DMY | dia/mês/ano | Wed 17 Dec 07:37:16 1997 PST |
No estilo ISO, a zona horária é sempre mostrada
como um deslocamento numérico com sinal em relação a UTC,
com sinal positivo usado para zonas a leste de Greenwich.
O deslocamento é mostrado como hh
(somente horas) se for um número inteiro de horas, senão como
hh:mm
se for um número inteiro de minutos, senão como
hh:mm:ss.
(O terceiro caso não é possível com nenhum padrão de zona horária
moderno, mas pode aparecer ao se trabalhar com carimbos de data/hora
anteriores à adoção de zonas horárias padronizadas.)
Nos outros estilos de data, a zona horária é mostrada como
abreviatura alfabética, se isto for de uso comum na zona corrente.
Caso contrário, aparece como um deslocamento numérico com
sinal no formato ISO 8601 básico
(hh ou hhmm).
As abreviações alfabéticas exibidas nestes estilos são extraídas da
entrada do banco de dados de zona horária da IANA
atualmente selecionada pelo parâmetro de tempo de execução
TimeZone; elas não são afetadas pela definição
de timezone_abbreviations.
O estilo de data/hora pode ser selecionado pelo usuário usando o
comando SET datestyle, mudando o parâmetro
DateStyle no arquivo de configuração
postgresql.conf, ou usando a variável de
ambiente PGDATESTYLE no servidor, ou no cliente.
A função de formatação to_char
(veja a Seção 9.8) também está
disponível como uma forma mais flexível para formatar a saída de
data/hora.
Exemplo 8.8. Exemplo do tradutor
Neste exemplo é entrada uma data com a zona horária UTC-8 (PST, Hora Padrão do Pacífico, Costa Oeste, EUA), que depois é mostrada em uma máquina configurada com a zona horária America/Sao_Paulo (UTC-3)
BEGIN;
CREATE TEMPORARY TABLE t (
c TIMESTAMP WITH TIME ZONE
) ON COMMIT DROP;
INSERT INTO t VALUES ('1997-12-17 07:37:16-08');
SET datestyle = 'ISO';
SELECT * FROM t;
c
------------------------
1997-12-17 13:37:16-02
COMMIT;
Note que a data/hora foi convertida para UTC-2 devido ao Horário de Verão no Brasil em dezembro de 1997.
As zonas horárias e as convenções de zona horária são influenciadas por decisões políticas, não apenas pela geometria da Terra. As zonas horárias em todo o mundo tornaram-se um pouco padronizadas durante os anos 1900, mas continuam propensas a mudanças arbitrárias, principalmente no que diz respeito às regras de horário de verão. O PostgreSQL usa o banco de dados de zona horária IANA (Olson) amplamente utilizado para obter informações sobre as regras históricas de zona horária. [45] Para horas no futuro, supõe-se que as últimas regras conhecidas para uma determinada zona horária continuarão a ser observadas indefinidamente no futuro.
O PostgreSQL se esforça para ser compatível com as definições do padrão SQL para uso típico. Entretanto, o padrão SQL tem uma mistura estranha de tipos de dados e recursos de data e hora. Dois problemas óbvios são:
Embora o tipo de dados date
não possa ser associado a uma zona horária, o tipo de dados
time pode.
As zonas horárias no mundo real têm pouco significado, a menos
que estejam associadas a uma data e a uma hora, porque o
deslocamento pode variar ao longo do ano com os limites do
horário de verão.
A zona horária padrão é especificada como um deslocamento numérico constante de UTC. Portanto, é impossível adaptar ao horário de verão ao fazer aritmética de data/hora através dos limites do DST (Daylight Saving Time [Horário de Verão]).
Para solucionar estas dificuldades, recomenda-se usar tipos de dados
data/hora que contenham a data e a hora quando são usadas zonas
horárias.
Não é recomendado usar o tipo de dados
time with time zone (embora seja aceito 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 de dados contendo apenas a data e a hora.
Todas as datas e horas com informação de zona horária são armazenadas internamente em UTC. Elas são convertidas para a hora local na zona especificada pelo parâmetro de configuração TimeZone antes de serem mostradas no cliente.
O PostgreSQL permite especificar as zonas horárias de três maneiras diferentes:
Um nome completo de zona horária como, por exemplo,
Brazil/East.
[46]
Os nomes reconhecidos de zonas horárias estão listados na
Seção 53.34.
O PostgreSQL usa os dados de zona
horária da IANA amplamente usados para esta finalidade,
portanto os mesmos nomes de zona horária também são reconhecidos
por outros softwares.
Uma abreviatura de zona horária como, por exemplo,
PST.
Tal especificação define apenas um deslocamento específico do
UTC, em contraste com os nomes de zona horária completos, que
também podem implicar em um conjunto de regras de transição de
horário de verão.
As abreviaturas reconhecidas estão listadas na
Seção 53.33.
Não é possível definir os parâmetros de configuração
TimeZone ou
log_timezone com uma abreviatura de zona
horária, mas pode ser usada uma abreviatura nos valores de entrada
de data/hora com o operador AT TIME ZONE.
Além dos nomes e abreviaturas de zonas horárias, o PostgreSQL aceita especificações de zona horária no estilo POSIX, conforme descrito na Seção B.5. Normalmente esta opção não é a preferida para ser usada como nome de zona horária, mas pode ser necessária se nenhuma entrada de zona horária da IANA adequada estiver disponível.
Em resumo, esta é a diferença entre abreviaturas e nomes completos:
as abreviaturas representam um deslocamento UTC específico,
enquanto muitos nomes completos implicam em uma regra de horário
de verão local, portanto têm dois deslocamentos de UTC possíveis.
Por exemplo,
2014-06-04 12:00 America/New_York representa
meio-dia na hora local de Nova York, que para esta data em particular
estava no horário de verão (Eastern Daylight Time = UTC-4).
Portanto, 2014-06-04 12:00 EDT especifica este
mesmo instante de hora. Mas 2014-06-04 12:00 EST
especifica meio-dia no Horário Padrão da Costa Leste
(Eastern Standard Time = UTC-5), independentemente do horário de
verão estar em vigor nesta data ou não.
O sinal nas especificações de zona horária no estilo POSIX tem o
significado oposto ao do sinal nos valores de data e hora ISO-8601.
Por exemplo, a zona horária POSIX para
2014-06-04 12:00+04 seria UTC-4.
Para complicar as coisas, algumas jurisdições usaram a mesma
abreviatura de zona horária para significar diferentes deslocamentos
de UTC em horários diferentes; por exemplo, em Moscou
MSK significa UTC+3 em alguns anos, e UTC+4 em outros.
O PostgreSQL interpreta estas abreviaturas
conforme o que elas significam (ou significaram mais recentemente)
na data específica; mas como no exemplo de EST
acima, esta não é necessariamente idêntica à hora civil nessa data.
Em todos os casos, os nomes e abreviaturas de zona horária são reconhecidos sem distinção entre letras maiúsculas e minúsculas. (Essa é uma mudança em relação às versões do PostgreSQL anteriores a 8.2, que faziam distinção entre letras maiúsculas e minúsculas em alguns contextos, enquanto em outros não.)
Nem os nomes das zonas horárias, nem as abreviaturas, estão codificados
no servidor; estes são obtidos nos arquivos de configuração
armazenados sob .../share/timezone/ e
.../share/timezonesets/ do diretório de
instalação (veja a Seção B.4).
O parâmetro de configuração TimeZone pode ser
definido no arquivo postgresql.conf, ou de
qualquer outra forma padrão descrita no
Capítulo 19.
Também existem algumas maneiras especiais para defini-lo:
O comando SQL SET TIME ZONE
define a zona horária para a seção. Essa é uma ortografia
alternativa para SET TIMEZONE TO com uma
sintaxe mais compatível com a especificação do padrão
SQL.
A variável de ambiente PGTZ é usada pela
biblioteca libpq para enviar o
comando SET TIME ZONE para o servidor na
hora da conexão. (veja a Seção 32.15)
Exemplo 8.9. Zonas horárias para o Brasil
Embora existam algumas zonas horárias para o Brasil com o prefixo 'America/', como 'America/Sao_Paulo', também existem quatro com o prefixo 'Brazil/'. O seguinte exemplo lista estas quatro zonas horárias usando comandos do Linux e uma consulta à tabela do PostgreSQL.
$# Linux Debian 12$timedatectl list-timezones | grep Brazil
Brazil/Acre Brazil/DeNoronha Brazil/East Brazil/West
$ ls -l /usr/share/zoneinfo/Brazil/ | cut -c40-
Acre -> ../America/Rio_Branco DeNoronha -> ../America/Noronha East -> ../America/Sao_Paulo West -> ../America/Manaus
-- PostgreSQL
SELECT * FROM pg_timezone_names
WHERE name LIKE 'Brazil%'
ORDER BY abbrev;
name | abbrev | utc_offset | is_dst
------------------+--------+------------+--------
Brazil/DeNoronha | -02 | -02:00:00 | f
Brazil/East | -03 | -03:00:00 | f
Brazil/West | -04 | -04:00:00 | f
Brazil/Acre | -05 | -05:00:00 | f
(4 linhas)
Os valores de interval podem ser escritos usando a
seguinte sintaxe detalhada:
[@]quantidadeunidade[quantidadeunidade...] [direção]
onde quantidade é um número
(possivelmente com sinal); unidade é
microsecond, millisecond,
second, minute,
hour, day,
week, month,
year, decade,
century, millennium,
ou abreviaturas, ou plurais dessas unidades;
direção pode ser ago
ou estar vazia. O sinal (@) é um ruído opcional.
As quantidades das diferentes unidades são adicionadas
implicitamente com a contabilização de sinais apropriada.
ago nega todos os campos.
Essa sintaxe também será usada na saída de intervalo, se
IntervalStyle estiver definido como
postgres_verbose.
Quantidades de dias, horas, minutos e segundos podem ser
especificadas sem marcações de unidades explícitas.
Por exemplo, '1 12:59:10' é lido da mesma forma
que '1 day 12 hours 59 min 10 sec'.
Além disso, uma combinação de anos e meses pode ser especificada
com um traço; por exemplo, '200-10' é lido da
mesma forma que '200 years 10 months'.
(Estas formas mais curtas são de fato as únicas permitidas pelo
padrão SQL, sendo usadas na saída quando
IntervalStyle é definido como
sql_standard.)
Os valores de intervalo também podem ser escritos como intervalos de tempo ISO 8601, usando o “formato com designadores” da seção 4.4.3.2 do padrão, ou o “formato alternativo” da seção 4.4.3.3. O formato com designadores se parece com:
Pquantidadeunidade[quantidadeunidade...] [ T [quantidadeunidade...]]
A cadeia de caracteres deve começar com a letra P,
podendo incluir a letra T que introduz as
unidades da hora do dia.
As abreviaturas disponíveis estão listadas na
Tabela 8.16. As unidades
podem ser omitidas, podendo ser especificadas em qualquer ordem,
mas as unidades menores que um dia devem aparecer depois do
T. Em particular, o significado de
M depende se está antes ou depois do
T.
Tabela 8.16. Abreviaturas das unidades de intervalo ISO 8601
| Abreviatura | Significado |
|---|---|
| Y | Anos |
| M | Meses (na parte da data) |
| W | Semanas |
| D | Dias |
| H | Horas |
| M | Minutos (na parte da hora) |
| S | Segundos |
No formato alternativo
P [anos-meses-dias] [ Thoras:minutos:segundos]
a cadeia de caracteres deve começar com a letra P,
e o T separa a parte da data e da hora do intervalo.
Os valores são fornecidos como números semelhantes às datas
ISO 8601.
Ao escrever uma constante de intervalo com uma especificação de
campos, ou quando atribuir uma cadeia de
caracteres a uma coluna de intervalo definida com a especificação de
campos, a interpretação das quantidades
não marcadas depende de campos.
Por exemplo, INTERVAL '1' YEAR é lido como 1 ano,
enquanto INTERVAL '1' significa 1 segundo.
Também, os valores de campo
“à direita” do campo menos significativo permitido
pela especificação de campos são
descartados em silêncio. Por exemplo, escrever
INTERVAL '1 day 2:03:04' HOUR TO MINUTE
resulta na eliminação do campo de segundos, mas não no campo de dia.
Segundo o padrão SQL, todos os campos de
um valor de intervalo devem ter o mesmo sinal, então o sinal
menos à esquerda se aplica a todos os campos; por exemplo, o sinal
menos no literal de intervalo '-1 2:03:04' se
aplica tanto aos dias quanto às horas/minutos/segundos.
O PostgreSQL permite que os campos tenham
sinais diferentes e, tradicionalmente, trata cada campo na
representação textual como tendo sinais independentes, portanto a
parte de hora/minuto/segundo é considerada positiva nesse exemplo.
Se IntervalStyle estiver definido como
sql_standard, então o sinal à esquerda
é considerado como sendo aplicado a todos os campos (mas apenas
se não aparecer nenhum sinal adicional). De outra forma, a
interpretação tradicional do PostgreSQL
é usada. Para evitar ambiguidade, é recomendável anexar um sinal
explícito a cada campo se algum campo for negativo.
Internamente, os valores de interval são armazenados
como três campos de números inteiros: meses, dias e microssegundos.
Estes campos são mantidos em separado porque o número de dias
em um mês varia, e um dia pode ter 23 ou 25 horas se houver
mudança para o horário de verão.
Uma cadeia de caracteres de entrada para intervalo que utiliza
outras unidades é normalizada para este formato e, em seguida,
reconstruída de forma padronizada para a saída, por exemplo:
SELECT '2 years 15 months 100 weeks 99 hours 123456789 milliseconds'::interval;
interval
---------------------------------------
3 years 3 mons 700 days 133:17:36.789
Aqui, as semanas, entendidas como tendo “7 dias”, foram mantidas em separado, enquanto as unidades de tempo menores e maiores foram combinadas e normalizadas.
Os valores dos campos de entrada podem conter partes fracionárias
como, por exemplo, '1.5 weeks' ou
'01:02:03.45'.
Entretanto, como interval armazena internamente apenas
campos de números inteiros, os valores fracionários devem ser
convertidos em unidades menores.
As partes fracionárias de unidades maiores que meses são
arredondadas para um número inteiro de meses como, por exemplo,
'1.5 years' se torna
'1 year 6 mons'.
As partes fracionárias de semanas e dias são calculadas como um
número inteiro de dias e microssegundos, considerando 30 dias
por mês e 24 horas por dia como, por exemplo,
'1.75 months' se torna
1 mon 22 days 12:00:00.
Apenas os segundos serão mostrados como frações na saída.
A Tabela 8.17 mostra alguns
exemplos de entradas válidas para interval.
Tabela 8.17. Entrada de intervalo
| Exemplo | Descrição |
|---|---|
1-2 | formato padrão SQL: 1 ano 2 meses |
3 4:05:06 | formato padrão SQL: 3 dias 4 horas 5 minutos 6 segundos |
1 year 2 months 3 dias 4 hours 5 minutes 6 segundos | formato tradicional do Postgres: 1 ano 2 meses 3 dias 4 horas 5 minutos 6 segundos |
P1Y2M3DT4H5M6S | “formato com designadores” ISO 8601: mesmo significado acima |
P0001-02-03T04:05:06 | “formato alternativo” ISO 8601: mesmo significado acima |
Exemplo:
SELECT '1-2' ::interval,
'3 4:05:06' ::interval,
'1 year 2 months 3 days 4 hours 5 minutes 6 seconds'::interval;
interval | interval | interval ---------------+-----------------+------------------------------- 1 year 2 mons | 3 days 04:05:06 | 1 year 2 mons 3 days 04:05:06 (1 linha)
Conforme mencionado anteriormente, o PostgreSQL
armazena os valores do tipo de dados interval como
meses, dias e microssegundos.
Para a saída, o campo de meses é convertido em anos e meses
dividindo por 12. O campo de dias é mostrado tal como está.
O campo de microssegundos é convertido em horas, minutos, segundos
e frações de segundo.
Portanto, meses, minutos e segundos nunca serão mostrados excedendo
os limites 0–11, 0–59 e 0–59, respectivamente,
mas os campos mostrados com anos, dias e horas podem ser
muito grandes.
(As funções justify_days
e justify_hours
podem ser usadas se for desejado transpor valores grandes de dias
ou horas para o campo imediatamente superior.)
O formato de saída do tipo de dados interval pode ser
definido como sendo um destes quatro estilos:
sql_standard, postgres,
postgres_verbose, ou iso_8601,
usando o comando SET intervalstyle.
O padrão é o formato postgres.
A Tabela 8.18 mostra exemplos de
cada um destes quatro estilos de saída.
O estilo sql_standard produz uma saída em
conformidade com a especificação do padrão SQL
para literais de intervalo, se o valor do intervalo
estiver de acordo com as restrições do padrão (somente ano e mês,
ou somente hora do dia, sem mistura de componentes positivos e
negativos).
Caso contrário, a saída se parece com um literal de ano-mês padrão
seguido por um literal de dia-hora, com sinais explícitos
adicionados para desambiguar intervalos com sinais mistos.
A saída do estilo postgres corresponde à saída
do PostgreSQL nas versões anteriores a
8.4 quando o parâmetro DateStyle estava
definido como ISO.
A saída do estilo postgres_verbose corresponde à
saída do PostgreSQL nas versões
anteriores a 8.4 quando o parâmetro DateStyle
estava definido como não-ISO.
A saída do estilo iso_8601 corresponde ao
“formato com designadores” descrito na seção 4.4.3.2
do padrão ISO 8601.
Tabela 8.18. Exemplos de estilo de saída de intervalo
| Especificação do estilo | Intervalo ano e mês | Intervalo hora do dia | Intervalo misto |
|---|---|---|---|
sql_standard | 1-2 | 3 4:05:06 | -1-2 +3 -4:05:06 |
postgres | 1 year 2 mons | 3 days 04:05:06 | -1 year -2 mons +3 days -04:05:06 |
postgres_verbose | @ 1 year 2 mons | @ 3 days 4 hours 5 mins 6 secs | @ 1 year 2 mons -3 days 4 hours 5 mins 6 secs ago |
iso_8601 | P1Y2M | P3DT4H5M6S | P-1Y-2M3DT-4H-5M-6S |
[43]
zona horária:
Os fusos horários estão centrados nos meridianos das longitudes
múltiplas de 15°; as zonas horárias seguem os fusos
horários de forma aproximada.
Os fusos horários são definidos geograficamente, enquanto que
as zonas horárias são definidas politicamente.
Wikipédia - Fuso horário (N. T.)
[44] Formatos de data e hora: Este documento define um perfil da ISO 8601, o Padrão Internacional para a representação de datas e horas. A ISO 8601 descreve um grande número de formatos de data/hora. Para reduzir a margem de erro e a complexidade do software, é útil restringir os formatos aceitos a um pequeno número. Este perfil define alguns formatos de data/hora, provavelmente satisfazendo a maioria dos requisitos. W3C Date and Time Formats (N. T.)
[45] As regras para zona horária e horário de verão são controladas por governos individualmente. Elas às vezes são alterados com pouca antecedência, e suas histórias e futuros planejados são frequentemente registrados apenas de forma intermitente. Aqui está um resumo das tentativas de organizar e registrar dados relevantes nessa área. IANA - Sources for time zone and daylight saving time data (N. T.)
[46]
O comando do Linux
timedatectl list-timezones lista todas as zonas
horárias disponíveis, uma por linha. Os valores dessa lista
podem ser usados para definir a zona horária do sistema
usando set-timezone. (N. T.)