A Tabela 9.33 descreve as funções
disponíveis para processamento de valor de data e hora, com os
detalhes aparecendo nas subseções que se seguem.
A Tabela 9.32 descreve o comportamento
dos operadores aritméticos básicos (+,
*, etc.).
Para as funções de formatação, deve ser consultada a
Seção 9.8.
Você deve estar familiarizado com as informações básicas sobre os
tipos de dados de data e hora descritos na
Seção 8.5.
Além destas funções, estão disponíveis para os tipos de dados de data
e hora os operadores de comparação usuais descritos na
Tabela 9.1.
Datas e carimbos de data e hora (com ou sem zona horária) são todos
comparáveis, enquanto as horas (com ou sem zona horária) e intervalos,
só podem ser comparados a outros valores do mesmo tipo de dados.
Ao comparar um carimbo de data e hora sem zona horária com um carimbo
de data e hora com zona horária, assume-se que o primeiro valor está
fornecido na zona horária especificada pelo parâmetro de configuração
TimeZone, sendo convertido para UTC para
comparação com o último valor (que já está em UTC internamente).
Da mesma forma, é assumido que um valor de data representa meia-noite
na zona horária da TimeZone ao compará-lo com um
carimbo de data e hora.
Na verdade, todas as funções e operadores descritos abaixo, que aceitam
entradas do tipo de dados time ou timestamp,
possuem duas formas alternativas: uma que aceita os tipos de dados
time with time zone ou timestamp with time zone,
e outra que aceita os tipos de dados time without time zone
ou timestamp without time zone.
Por uma questão de brevidade, estas formas alternativas não são
descritas separadamente.
Além disso, os operadores + e *
estão presentes em pares comutativos (por exemplo, o par
date + integer e
integer + date);
de cada um desses pares, apenas um é mostrado aqui.
Tabela 9.32. Operadores da data e hora
Operador Descrição Exemplo(s) |
|---|
Soma um número de dias a uma data
|
Soma um intervalo a uma data
|
Soma uma hora do dia a uma data
|
Soma intervalos
|
Soma um intervalo a um carimbo de data e hora
|
Soma um intervalo a uma hora
|
Inverte o sinal do intervalo
|
Subtrai datas, produzindo o número de dias transcorridos
|
Subtrai um número de dias de uma data
|
Subtrai um intervalo de uma data
|
Subtrai horas
|
Subtrai um intervalo de uma hora
|
Subtrai um intervalo de um carimbo de data e hora
|
Subtrai intervalos
|
Subtrai carimbos de data e hora (converte intervalos de 24
horas em dias, semelhante à função
|
Multiplica um intervalo por um escalar
|
Divide um intervalo por um escalar
|
Tabela 9.33. Funções de data e hora
Função Descrição Exemplo(s) |
|---|
Subtrai os argumentos, produzindo um resultado “simbólico” que usa também anos e meses, em vez de apenas dias
|
Subtrai o argumento de
|
Data e hora corrente (muda durante a execução da instrução); veja a Seção 9.9.5
|
|
Data corrente; veja a Seção 9.9.5
|
Hora corrente do dia; veja a Seção 9.9.5
|
Hora corrente do dia, com precisão limitada; veja a Seção 9.9.5
|
Data e hora correntes (início da transação corrente); veja a Seção 9.9.5
|
Data e hora correntes (início da transação corrente), com precisão limitada; veja a Seção 9.9.5
|
Adiciona um
|
Coloca uma data dentro do intervalo especificado, alinhada com a origem determinada; veja a Seção 9.9.3
|
Extrai um subcampo de um carimbo de data e hora (equivalente
à função
|
Extrai um subcampo de um intervalo (equivalente à função
|
Subtrai um
|
Trunca para a precisão especificada; veja a Seção 9.9.2
|
Trunca para a precisão especificada na zona horária especificada; veja a Seção 9.9.2
|
Trunca para a precisão especificada; veja a Seção 9.9.2
|
Extrai um subcampo de um carimbo de data e hora; veja a Seção 9.9.1
|
Extrai um subcampo de um intervalo; veja a Seção 9.9.1
|
|
Teste para data finita (não +/-infinito)
|
Teste para carimbo de data e hora finito (não +/-infinito)
|
Testa para um intervalo finito (no momento é sempre verdade)
|
Ajusta o intervalo, convertendo períodos de 30 dias em meses
|
Ajusta o intervalo, convertendo períodos de 24 horas em dias
|
Ajusta o intervalo usando as funções
|
|
Hora corrente do dia; veja a Seção 9.9.5
|
Hora corrente do dia, com precisão limitada; veja a Seção 9.9.5
|
|
Data e hora correntes (início da transação corrente); veja a Seção 9.9.5
|
Data e hora correntes (início da transação corrente), com precisão limitada; veja a Seção 9.9.5
|
Cria data a partir dos campos de ano, mês e dia (anos negativos significam BC)
|
Cria intervalo a partir dos argumentos
|
Cria hora a partir dos campos
|
Cria carimbo de data e hora a partir dos campos
|
Cria carimbo de data e hora com zona horária a partir dos campos
|
Data e hora correntes (início da transação corrente); veja a Seção 9.9.5
|
Data e hora correntes (início da instrução corrente); veja a Seção 9.9.5
|
|
Data e hora corrente (como a função
|
Data e hora correntes (início da transação corrente); veja a Seção 9.9.5
|
Converte a época do Unix (segundos desde 1970-01-01 00:00:00+00) para um carimbo de data e hora com zona horária
|
Além destas funções, tem suporte o operador OVERLAPS
do SQL:
(start1,end1) OVERLAPS (start2,end2) (start1,length1) OVERLAPS (start2,length2)
Esta expressão retorna verdade quando dois períodos de tempo
(definidos por suas extremidades) se sobrepõem, e falso quando
não se sobrepõem.
Os pontos das extremidades podem ser especificados como um par de
datas, horas ou datas e horas; ou como uma data, hora ou
data e hora seguida por um intervalo.
Quando é fornecido um par de valores, pode ser escrito primeiro o
início ou o fim do período; OVERLAPS toma
automaticamente o valor mais antigo do par como o início do período.
Cada período de tempo é considerado representando o intervalo
semiaberto início <=
hora < fim,
a menos que início e fim
sejam iguais, caso onde representam um determinado instante de tempo.
Isto significa, por exemplo, que dois períodos de tempo, com apenas
um ponto de extremidade em comum não se sobrepõem.
SELECT (DATE '2001-02-16', DATE '2001-12-21') OVERLAPS
(DATE '2001-10-30', DATE '2002-10-30'); → true
SELECT (DATE '2001-02-16', INTERVAL '100 days') OVERLAPS
(DATE '2001-10-30', DATE '2002-10-30'); → false
SELECT (DATE '2001-10-29', DATE '2001-10-30') OVERLAPS
(DATE '2001-10-30', DATE '2001-10-31'); → false
SELECT (DATE '2001-10-30', DATE '2001-10-30') OVERLAPS
(DATE '2001-10-30', DATE '2001-10-31'); → true
Ao adicionar um valor do tipo de dados interval
(ou subtrair um valor do tipo de dados interval)
de um valor do tipo de dados timestamp ou
timestamp with time zone, os campos de meses, dias
e microssegundos do valor de interval são tratados
um de cada vez.
Primeiro, um campo de meses diferente de zero avança ou decrementa
a data do carimbo de data e hora pelo número de meses indicado,
mantendo o dia do mês o mesmo, a menos que já tenha passado do
final do novo mês, caso em que o último dia deste mês é usado.
(Por exemplo, 31 de março mais 1 mês se torna 30 de abril,
mas 31 de março mais 2 meses se torna 31 de maio.)
Em seguida, o campo de dias avança ou decrementa a data do carimbo
de data e hora pelo número de dias indicado.
Em ambas as etapas, a hora local é mantida a mesma.
Por fim, se houver um campo de microssegundos diferente de zero,
ele é adicionado ou subtraído literalmente.
Ao realizar cálculos aritméticos em um valor do tipo de dados
timestamp with time zone em uma zona horária que
reconhece o horário de verão, isto significa que adicionar ou subtrair
(digamos) interval '1 day' não necessariamente
produz o mesmo resultado que somar ou subtrair
interval '24 hours'.
Por exemplo, com a zona horária da sessão definido como
America/Denver:
SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '1 day'; →2005-04-03 12:00:00-06SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '24 hours'; →2005-04-03 13:00:00-06
Isto acontece porque foi saltada uma hora devido à mudança para o
horário de verão em 2005-04-03 02:00:00
na zona horária America/Denver.
Note que pode haver ambiguidade no campo months
retornado pela função age, porque meses
diferentes têm números de dias diferentes.
A abordagem do PostgreSQL usa o mês da
primeira das duas datas ao calcular os meses parciais.
Por exemplo, age('2004-06-01', '2004-04-30') usa
Abril para produzir 1 mon 1 day, enquanto que
usando Maio produziria 1 mon 2 days, porque Maio
tem 31 dias, enquanto Abril tem apenas 30.
A subtração de datas e carimbos de data e hora também pode ser complexa.
Uma maneira conceitualmente simples de realizar a subtração seria
converter cada valor em número de segundos usando
EXTRACT(EPOCH FROM ...) e, em seguida, subtrair os
resultados produzindo o número de segundos
entre os dois valores.
Com isso seria ajustado o número de dias de cada mês, as alterações
de zona horária e os ajustes do horário de verão.
A subtração de valores de data ou de carimbo de data e hora usando o
operador “-” retorna o número de dias
(24 horas) e horas/minutos/segundos entre os valores, fazendo os
mesmos ajustes.
A função age retorna anos, meses, dias e
horas/minutos/segundos, realizando a subtração campo a campo e,
em seguida, ajustando para os valores de campo negativos.
As consultas a seguir mostram as diferenças destas abordagens.
Os resultados da amostra foram produzidos usando timezone
= 'US/Eastern'; há uma mudança de horário de verão entre
as duas datas usadas:
SELECT EXTRACT(EPOCH FROM timestamptz '2013-07-01 12:00:00') -
EXTRACT(EPOCH FROM timestamptz '2013-03-01 12:00:00');
→ 10537200.000000
SELECT (EXTRACT(EPOCH FROM timestamptz '2013-07-01 12:00:00') -
EXTRACT(EPOCH FROM timestamptz '2013-03-01 12:00:00'))
/ 60 / 60 / 24;
→ 121.9583333333333333
SELECT timestamptz '2013-07-01 12:00:00' - timestamptz '2013-03-01 12:00:00';
→ 121 days 23:00:00
SELECT age(timestamptz '2013-07-01 12:00:00', timestamptz '2013-03-01 12:00:00');
→ 4 mons
EXTRACT, date_part #EXTRACT(fieldFROMsource)
A função extract extrai subcampos como ano
ou hora a partir de valores de data/hora.
source deve ser uma expressão de valor
do tipo de dados timestamp, date,
time ou interval.
(Os valores de data e hora e os carimbos de de data e hora podem
incluir ou não a zona horária.)
field é um identificador ou cadeia de
caracteres que seleciona qual campo extrair do valor de origem.
Nem todos os campos são válidos para todos os tipos de dados de
entrada; por exemplo, campos menores que dia não podem ser
extraídos de um tipo de dados date, enquanto campos
de um dia ou mais não podem ser extraídos de um tipo de dados
time.
A função extract retorna valores do tipo de
dados numeric.
Os seguintes nomes de campo são válidos:
century
O século; para valores do tipo de dados interval,
o campo do ano dividido por 100.
SELECT EXTRACT(CENTURY FROM TIMESTAMP '2000-12-16 12:21:13'); →20SELECT EXTRACT(CENTURY FROM TIMESTAMP '2001-02-16 20:38:40'); →21SELECT EXTRACT(CENTURY FROM DATE '0001-01-01 AD'); →1SELECT EXTRACT(CENTURY FROM DATE '0001-12-31 BC'); →-1SELECT EXTRACT(CENTURY FROM INTERVAL '2001 years'); →20
day
O dia do mês (1–31); para valores do tipo de dados
interval, o número de dias
SELECT EXTRACT(DAY FROM TIMESTAMP '2001-02-16 20:38:40'); →16SELECT EXTRACT(DAY FROM INTERVAL '40 days 1 minute'); →40
decadeO campo ano dividido por 10
SELECT EXTRACT(DECADE FROM TIMESTAMP '2001-02-16 20:38:40');
→ 200
dow
O dia da semana, de Domingo (0)
a Sábado (6)
SELECT EXTRACT(DOW FROM TIMESTAMP '2001-02-16 20:38:40');
→ 5
Note que a numeração do dia da semana da função
extract
é diferente da função to_char(..., 'D').
doyO dia do ano (1–365/366)
SELECT EXTRACT(DOY FROM TIMESTAMP '2001-02-16 20:38:40');
→ 47
epoch
Para os valores do tipo de dados timestamp with time zone,
é o número de segundos desde 1970-01-01 00:00:00 UTC
(negativo para carimbos de data e hora anteriores a esta data);
para os valores dos tipos de dados date e
timestamp, é o número de segundos nominal
(não ajustado) desde 1970-01-01 00:00:00,
independentemente da zona horária, ou das regras de horário de verão;
para os valores do tipo de dados interval,
é o número total de segundos no intervalo
SELECT EXTRACT(EPOCH FROM TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40.12-08'); →982384720.120000SELECT EXTRACT(EPOCH FROM TIMESTAMP '2001-02-16 20:38:40.12'); →982355920.120000SELECT EXTRACT(EPOCH FROM INTERVAL '5 days 3 hours'); →442800.000000
Pode ser convertido um valor de época de volta para
timestamp with time zone usando a função
to_timestamp:
SELECT to_timestamp(982384720.12);
→ 2001-02-17 04:38:40.12+00
Esteja ciente que aplicar a função
to_timestamp a uma época extraída de um
valor do tipo de dados date ou timestamp,
pode produzir um resultado enganoso: o resultado vai assumir que
o valor original foi fornecido em UTC, podendo não ser o caso.
hourO campo hora (0–23 em carimbos de data e hora, sem restrições em intervalos)
SELECT EXTRACT(HOUR FROM TIMESTAMP '2001-02-16 20:38:40');
→ 20
isodow
O dia da semana, de Segunda-feira (1) a
Domingo (7)
SELECT EXTRACT(ISODOW FROM TIMESTAMP '2001-02-18 20:38:40');
→ 7
É idêntico a dow, exceto para o Domingo.
Corresponde à numeração dos dias da semana da norma ISO 8601.
isoyearO ano do calendário ISO 8601 baseado na semana em que a data se encontra.
SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-01'); -- Domingo →2005SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-02'); -- Segunda-feira →2006SELECT EXTRACT(ISOYEAR FROM DATE '2027-01-01'); -- Sexta-feira →2026
Cada ano do calendário ISO-8601 baseado em semana
começa na segunda-feira da semana contendo o dia 4 de janeiro.
Portanto, no início de janeiro e no final de dezembro o ano
ISO pode ser diferente do ano gregoriano.
Veja o campo week para obter mais informações
[69].
julianA Data Juliana correspondente à data ou carimbo de data e hora. Os carimbos de data e hora que não estão à meia-noite local resultam em um valor fracionário. Veja a Seção B.7 para obter mais informações.
SELECT EXTRACT(JULIAN FROM DATE '2006-01-01'); →2453737SELECT EXTRACT(JULIAN FROM TIMESTAMP '2006-01-01 12:00'); →2453737.50000000000000000000
microsecondsO campo segundos, incluindo as partes fracionárias, multiplicado por 1 000 000; observe que estão incluídos os segundos completos
SELECT EXTRACT(MICROSECONDS FROM TIME '17:12:28.5');
→ 28500000
millennium
O milênio; para os valores do tipo de dados interval,
o campo do ano dividido por 1000
SELECT EXTRACT(MILLENNIUM FROM TIMESTAMP '2001-02-16 20:38:40'); →3SELECT EXTRACT(MILLENNIUM FROM INTERVAL '2001 years'); →2
Os anos de 1900 estão no segundo milênio. O terceiro milênio começou em 1º de janeiro de 2001.
millisecondsO campo segundos, incluindo as partes fracionárias, multiplicado por 1.000. Observe que estão incluídos os segundos completos
SELECT EXTRACT(MILLISECONDS FROM TIME '17:12:28.5');
→ 28500.000
minuteO campo minutos (0–59)
SELECT EXTRACT(MINUTE FROM TIMESTAMP '2001-02-16 20:38:40');
→ 38
month
O número do mês dentro do ano (1–12);
para valores do tipo de dados interval,
o número de meses módulo 12 (0–11)
SELECT EXTRACT(MONTH FROM TIMESTAMP '2001-02-16 20:38:40'); →2SELECT EXTRACT(MONTH FROM INTERVAL '2 years 3 months'); →3SELECT EXTRACT(MONTH FROM INTERVAL '2 years 13 months'); →1
quarter
O trimestre do ano no qual a data se encontra (1–4);
para valores do tipo de dados interval,
o campo do mês dividido por 3 mais 1
SELECT EXTRACT(QUARTER FROM TIMESTAMP '2001-02-16 20:38:40'); →1SELECT EXTRACT(QUARTER FROM INTERVAL '1 year 6 months'); →3
secondO campo dos segundos, incluindo quaisquer frações de segundo.
SELECT EXTRACT(SECOND FROM TIMESTAMP '2001-02-16 20:38:40'); →40.000000SELECT EXTRACT(SECOND FROM TIME '17:12:28.5'); →28.500000
timezoneO deslocamento da zona horária do UTC, medido em segundos Valores positivos correspondem a zonas horárias a leste do UTC, valores negativos a zonas a oeste do UTC. (Tecnicamente, o PostgreSQL não usa UTC, porque não são tratados os segundos bissextos.)
timezone_hourO componente hora do deslocamento de zona horária
timezone_minuteO componente minuto do deslocamento de zona horária
weekO número da semana da data pelo calendário ISO-8601 baseado em semana. Por definição, as semanas ISO começam às segundas-feiras, e a primeira semana do ano inclui 4 de janeiro deste ano. Em outras palavras, a primeira quinta-feira do ano está na semana 1 deste ano.
No sistema de numeração de semanas ISO,
é possível que as datas do início de janeiro façam parte da
52ª ou 53ª semana do ano anterior, e que as datas do final de
dezembro façam parte da primeira semana do ano seguinte.
Por exemplo, 2005-01-01 está na 53ª semana
do ano de 2004, e 2006-01-01 está na 52ª
semana do ano de 2005, enquanto 2012-12-31
está na primeira semana de 2013.
É recomendado usar o campo isoyear junto com
week para obter resultados consistentes.
[70]
Para valores do tipo de dados interval, o campo da
semana é simplesmente o número de dias inteiros dividido por 7.
SELECT EXTRACT(WEEK FROM TIMESTAMP '2001-02-16 20:38:40'); →7SELECT EXTRACT(WEEK FROM INTERVAL '13 days 24 hours'); →1SELECT EXTRACT(WEEK FROM DATE '2027-01-01'); →53
year
O campo ano. Tenha em mente que 0 AD
não existe, portanto subtrair anos BC
de anos AD deve ser feito com cuidado.
SELECT EXTRACT(YEAR FROM TIMESTAMP '2001-02-16 20:38:40'); →2001SELECT EXTRACT(YEAR FROM DATE '2027-01-01'); →2027
Ao processar um valor do tipo de dados interval,
a função extract produz valores de campo que
correspondem à interpretação usada pela função de saída do intervalo.
Poderão ser produzidos resultados surpreendentes se partirmos de uma
representação de intervalo não normalizada como, por exemplo:
SELECT INTERVAL '80 minutes'; →01:20:00SELECT EXTRACT(MINUTES FROM INTERVAL '80 minutes'); →20
Quando o valor da entrada é +/-Infinity,
a função extract retorna
+/-Infinity para campos monotonicamente
crescentes (epoch, julian,
year, isoyear,
decade, century e
millennium para entradas do tipo de dados
timestamp;
epoch, hour,
day, year,
decade, century e
millennium para entradas do tipo de dados
interval).
Para os demais campos, é retornado o valor NULL.
As versões do PostgreSQL anteriores
à 9.6 retornavam zero em todos os casos de entrada infinita.
A função extract destina-se principalmente ao
processamento computacional.
Para formatar valores de data e hora para exibição, veja a
Seção 9.8.
A função date_part é modelada no equivalente
tradicional do Ingres para a função
extract do padrão SQL:
date_part('field', source)
Note que aqui o parâmetro field (campo)
precisa ser um valor cadeia de caracteres, e não um nome.
Os nomes de campo válidos para a função date_part
são os mesmos para a função extract.
Por razões históricas, a função date_part
retorna valores do tipo de dados double precision,
o que pode resultar em uma perda de precisão em certos casos.
Por isto, recomenda-se usar a função extract
em vez da função date_part.
SELECT date_part('day', TIMESTAMP '2001-02-16 20:38:40');
→ 16
SELECT date_part('hour', INTERVAL '4 hours 3 minutes');
→ 4
date_trunc #
A função date_trunc é conceitualmente
semelhante à função trunc para números.
date_trunc(field,source[,time_zone])
source é uma expressão de valor do tipo
de dados timestamp, timestamp with time zone,
ou interval.
(Os valores dos tipos de dados date e time
são convertidos, automaticamente, para os tipos de dados
timestamp ou interval, respectivamente.)
field seleciona para qual precisão o
valor da entrada deve ser truncado.
O valor retornado também é do tipo de dados
timestamp, timestamp with time zone,
ou interval, como na entrada, com todos os campos menos
significativos que o campo selecionado definidos como zero
(ou um, para dia e mês).
Os valores válidos para field são:
microseconds |
milliseconds |
second |
minute |
hour |
day |
week |
month |
quarter |
year |
decade |
century |
millennium |
Quando o valor da entrada é do tipo de dados
timestamp with time zone,
o truncamento é realizado em relação à zona horária especificada;
por exemplo, o truncamento para day produz um
valor que é meia-noite nessa zona horária.
Por padrão, o truncamento é feito em relação à configuração corrente
de TimeZone, mas o argumento opcional
time_zone pode ser fornecido para
especificar uma zona horária diferente.
O nome da zona horária pode ser especificado em qualquer uma das
formas descritas na Seção 8.5.3.
Não pode ser especificada a zona horária ao se processar as
entradas dos tipos de dados timestamp without time zone
ou interval.
Estas entradas são sempre aceitas como se encontram, sem interpretação.
Exemplos (assumindo que a zona horária local é
America/New_York):
SELECT date_trunc('hour', TIMESTAMP '2001-02-16 20:38:40');
→ 2001-02-16 20:00:00
SELECT date_trunc('year', TIMESTAMP '2001-02-16 20:38:40');
→ 2001-01-01 00:00:00
SELECT date_trunc('day', TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40+00');
→ 2001-02-16 00:00:00-05
SELECT date_trunc('day', TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40+00', 'Australia/Sydney');
→ 2001-02-16 08:00:00-05
SELECT date_trunc('hour', INTERVAL '3 days 02:47:33');
→ 3 days 02:00:00
date_bin #
A função date_bin posiciona (“bins”)
o carimbo de data e hora de entrada no intervalo especificado
(o stride) alinhado com uma origem especificada.
date_bin(stride,source,origin)
source é uma expressão de valor do tipo
de dados timestamp ou timestamp with time zone.
(Os valores do tipo de dados date são convertidos
automaticamente para o tipo de dados timestamp.)
stride é uma expressão de valor do tipo
de dados interval.
O valor retornado também é do tipo de dados timestamp
ou timestamp with time zone, e marca o início do
intervalo no qual source está localizada.
Exemplos:
SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-01-01');
→ 2020-02-11 15:30:00
SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-01-01 00:02:30');
→ 2020-02-11 15:32:30
No caso de unidades inteiras (1 minuto, 1 hora, etc.), produz o mesmo
resultado que a chamada análoga à função date_trunc,
mas a diferença é que a função date_bin pode
truncar em um intervalo arbitrário.
O intervalo do stride (passo) deve ser maior
que zero, e não pode conter unidades de mês ou maiores.
AT TIME ZONE e AT LOCAL #
O operador AT TIME ZONE converte carimbo de data
e hora sem zona horária de/para carimbo de data
e hora com zona horária, e o valores do tipo de
dados time with time zone para uma zona horária diferente.
A Tabela 9.34 descreve as
suas formas alternativas.
Tabela 9.34. Formas alternativas de AT TIME ZONE e AT LOCAL
Operador Descrição Exemplo(s) |
|---|
Converte o carimbo de data e hora fornecido sem zona horária em carimbo de data e hora com zona horária, assumindo que o valor fornecido esteja na zona horária especificada.
|
Converte o carimbo de data e hora fornecido sem
zona horária em carimbo de data e hora com
o valor de
|
Converte o carimbo de data e hora fornecido com zona horária em carimbo de tempo sem zona horária, conforme apareceria nessa zona horária.
|
Converte o carimbo de data e hora fornecido com
zona horária em carimbo de tempo sem,
como apareceria se o valor de
|
Converte a hora fornecida com zona horária para uma nova zona horária. Como a data não é fornecida, é utilizado o deslocamento UTC atualmente ativo para a zona horária de destino.
|
Converte a hora fornecida com
zona horária para uma nova zona horária.
Como a data não é fornecida, é utilizado o deslocamento UTC
atualmente ativo para o valor de
Assumindo que o
|
Nestas expressões, a zona horária desejada (zona)
pode ser especificada como um valor de texto
(por exemplo, 'America/Los_Angeles')
ou como um intervalo (por exemplo, INTERVAL '-08:00').
No caso de texto, o nome da zona horária pode ser especificado em
qualquer uma das formas descritas em Seção 8.5.3.
O caso de intervalo é útil apenas para zonas que possuem deslocamentos
fixos do UTC, portanto não é muito comum na prática.
A sintaxe AT LOCAL pode ser usada como uma forma
abreviada para
AT TIME ZONE ,
onde locallocal é o valor de
TimeZone da sessão.
Exemplos (assumindo que a definição corrente de
TimeZone é
America/Los_Angeles):
SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'America/Denver'; →2001-02-16 19:38:40-08SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE 'America/Denver'; →2001-02-16 18:38:40SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'Asia/Tokyo' AT TIME ZONE 'America/Chicago'; →2001-02-16 05:38:40SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT LOCAL; →2001-02-16 17:38:40SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE '+05'; →2001-02-16 20:38:40SELECT TIME WITH TIME ZONE '20:38:40-05' AT LOCAL; →17:38:40
O primeiro exemplo adiciona uma zona horária a um valor que não
possui zona horária e exibe o resultado usando a configuração
corrente de TimeZone.
O segundo exemplo muda o carimbo de data e hora com valor de zona
horária para a zona horária especificada, e retorna o valor sem
zona horária.
Isto permite o armazenamento e exibição de valores diferentes da
configuração corrente de TimeZone.
O terceiro exemplo converte a hora de Tóquio para a hora de Chicago.
O quarto exemplo desloca o carimbo de data e hora com o valor da
zona horária para a zona horária atualmente especificado pela
configuração TimeZone e retorna o valor sem
zona horária.
O quinto exemplo demonstra que o sinal em uma especificação de
zona horária no estilo POSIX tem o significado
oposto ao do sinal em um literal de data e hora ISO-8601.
conforme descrito na Seção 8.5.3 e na
Apêndice B.
O sexto exemplo serve de alerta. Devido ao fato de não haver data
associada ao valor de entrada, a conversão é feita usando a
data corrente da sessão.
Portanto, este exemplo estático pode apresentar um resultado
incorreto dependendo da época do ano em que for visto, porque
'America/Los_Angeles' obedece o Horário de Verão.
A função equivale à
construção em conformidade com o padrão SQL
timezone(zone,
timestamp).
timestamp AT TIME ZONE
zone
A função equivale à
construção em conformidade com o padrão SQL
timezone(zone,
time).
time AT TIME ZONE
zone
A função
equivale à construção em conformidade com o padrão SQL
timezone(timestamp).
timestamp AT LOCAL
A função
equivale à construção em conformidade com o padrão SQL
timezone(time).
time AT LOCAL
O PostgreSQL fornece várias funções que
retornam valores relacionados à data e hora corrente.
Todas estas funções do padrão SQL retornam valores
com base na hora de início da transação corrente:
CURRENT_DATE CURRENT_TIME CURRENT_TIMESTAMP CURRENT_TIME(precisão) CURRENT_TIMESTAMP(precisão) LOCALTIME LOCALTIMESTAMP LOCALTIME(precisão) LOCALTIMESTAMP(precisão)
CURRENT_TIME e
CURRENT_TIMESTAMP
retornam valores com zona horária;
LOCALTIME e
LOCALTIMESTAMP
retornam valores sem zona horária.
CURRENT_TIME,
CURRENT_TIMESTAMP,
LOCALTIME e
LOCALTIMESTAMP
podem receber, opcionalmente, um parâmetro de precisão, que faz
com que o resultado seja arredondado para esse número de dígitos
fracionários no campo de segundos.
Sem o parâmetro de precisão, o resultado é fornecido com a
precisão total disponível.
Alguns exemplos:
SELECT CURRENT_TIME; →09:52:54.973257-03SELECT CURRENT_DATE; →2026-01-24SELECT CURRENT_TIMESTAMP; →2026-01-24 09:52:54.973257-03SELECT CURRENT_TIMESTAMP(2); →2026-01-24 09:52:54.97-03SELECT LOCALTIMESTAMP; →2026-01-24 09:52:54.973257
Como estas funções retornam a hora de início da transação corrente, seus valores não mudam durante a transação. Isto é considerado uma funcionalidade: a intenção é permitir que cada transação tenha uma noção consistente da hora “corrente”, de modo que várias modificações dentro da mesma transação tenham o mesmo carimbo de data e hora.
Outros sistemas de banco de dados podem avançar estes valores com mais frequência.
O PostgreSQL também fornece funções que
retornam a hora de início da instrução corrente, assim como a hora
corrente real no instante em que a função é chamada.
A lista completa das funções de tempo fora do padrão
SQL é:
transaction_timestamp() statement_timestamp() clock_timestamp() timeofday() now()
transaction_timestamp() é equivalente a
CURRENT_TIMESTAMP, mas recebe esse nome para
refletir claramente o que retorna.
statement_timestamp() retorna a hora de início
da instrução corrente (mais especificamente, a hora de recebimento
da última mensagem de comando do cliente).
statement_timestamp() e transaction_timestamp()
retornam o mesmo valor na primeira instrução de uma transação,
mas podem ser diferentes nas instruções subsequentes.
clock_timestamp() retorna a hora corrente real
e, portanto, seu valor muda mesmo dentro de uma única instrução
SQL.
timeofday() é uma função histórica do
PostgreSQL.
Como clock_timestamp(), retorna a hora corrente,
mas como uma cadeia de caracteres de texto formatada em vez de um
valor do tipo de dados timestamp with time zone.
now() é uma função equivalente tradicional do
PostgreSQL para
transaction_timestamp().
Todos os tipos de dados de data e hora também aceitam o valor literal
especial now para especificar a data e hora corrente
(novamente, interpretado como a hora de início da transação).
Assim, os três comandos seguintes retornam o mesmo resultado:
SELECT CURRENT_TIMESTAMP; SELECT now(); SELECT TIMESTAMP 'now'; -- mas veja a dica abaixo
Não use a terceira forma para especificar um valor a ser avaliado
mais tarde, por exemplo, em uma cláusula DEFAULT
para uma coluna da tabela.
O sistema converte now em timestamp
assim que a constante é analisada, de modo que quando o valor padrão
for necessário, será usada a hora da criação da tabela!
As duas primeiras formas não são avaliadas até que o valor padrão
seja usado, porque são chamadas de função.
Assim, estas funções darão o comportamento desejado de usar como
padrão a hora de inserção da linha.
(Veja também a Seção 8.5.1.4.)
Estão disponíveis as seguintes funções para atrasar a execução do processo servidor:
pg_sleep (double precision) pg_sleep_for (interval) pg_sleep_until (timestamp with time zone)
A função pg_sleep faz com que o processo da
sessão corrente durma até que tenha decorrido o número de segundos
especificado.
Podem ser especificados atrasos de frações de segundos.
A função pg_sleep_for é uma função de conveniência
para permitir que o tempo dormindo seja especificado como um
interval.
A função pg_sleep_until é uma função de conveniência
para quando se deseja uma hora específica para despertar.
Por exemplo:
SELECT pg_sleep(1.5);
SELECT pg_sleep_for('5 minutes');
SELECT pg_sleep_until('tomorrow 03:00');
A resolução efetiva do intervalo de tempo a ser dormido é
específica da plataforma; 0,01 segundos é um valor comum.
O atraso dormindo será pelo menos tão longo quanto o valor
especificado.
Pode ser mais longo, dependendo de fatores como a carga do servidor.
Em particular, não não há garantia de que a função
pg_sleep_until acorde exatamente na hora
especificada, porém não vai acordar antes.
Certifique-se de que a sessão não tenha mais bloqueios do que o
necessário ao chamar a função pg_sleep,
ou uma de suas formas alternativas. Caso contrário, outras sessões
podem ter que esperar pelo seu processo que está dormindo,
diminuindo a velocidade de todo o sistema.
[69] O Calendário ISO-8601 baseado em semana é um padrão internacional para dados relacionados a datas. Veja Calendário ISO-8601 baseado em semana.
[70] Python epiweeks: Um pacote Python para calcular semanas epidemiológicas usando os sistemas de numeração de semanas do CDC dos EUA (MMWR) e ISO. O CDC dos EUA define a semana (semana MMWR) como sete dias, começando no domingo e terminando no sábado. A ISO define a semana (semana ISO) como sete dias, começando na segunda-feira e terminando no domingo. Nos dois casos, o final da primeira semana do ano, por definição, deve cobrir pelo menos quatro dias no ano. Os números das semanas variam de 1 a 53 por ano, embora a maioria dos anos possua 52 semanas. (N. T.)