9.9. Funções e operadores de data e hora #

9.9.1. EXTRACT, date_part
9.9.2. date_trunc
9.9.3. date_bin
9.9.4. AT TIME ZONE e AT LOCAL
9.9.5. Data e hora corrente
9.9.6. Atrasando a execução

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)

date + integerdate

Soma um número de dias a uma data

date '2001-09-28' + 72001-10-05

date + intervaltimestamp

Soma um intervalo a uma data

date '2001-09-28' + interval '1 hour'2001-09-28 01:00:00

date + timetimestamp

Soma uma hora do dia a uma data

date '2001-09-28' + time '03:00'2001-09-28 03:00:00

interval + intervalinterval

Soma intervalos

interval '1 day' + interval '1 hour'1 day 01:00:00

timestamp + intervaltimestamp

Soma um intervalo a um carimbo de data e hora

timestamp '2001-09-28 01:00' + interval '23 hours'2001-09-29 00:00:00

time + intervaltime

Soma um intervalo a uma hora

time '01:00' + interval '3 hours'04:00:00

- intervalinterval

Inverte o sinal do intervalo

- interval '23 hours'-23:00:00

- interval '-23 hours'23:00:00

date - dateinteger

Subtrai datas, produzindo o número de dias transcorridos

date '2001-10-01' - date '2001-09-28'3

date - integerdate

Subtrai um número de dias de uma data

date '2001-10-01' - 72001-09-24

date - intervaltimestamp

Subtrai um intervalo de uma data

date '2001-09-28' - interval '1 hour'2001-09-27 23:00:00

time - timeinterval

Subtrai horas

time '05:00' - time '03:00'02:00:00

time - intervaltime

Subtrai um intervalo de uma hora

time '05:00' - interval '2 hours'03:00:00

timestamp - intervaltimestamp

Subtrai um intervalo de um carimbo de data e hora

timestamp '2001-09-28 23:00' - interval '23 hours'2001-09-28 00:00:00

interval - intervalinterval

Subtrai intervalos

interval '1 day' - interval '1 hour'1 day -01:00:00

timestamp - timestampinterval

Subtrai carimbos de data e hora (converte intervalos de 24 horas em dias, semelhante à função justify_hours())

timestamp '2001-09-29 03:00' - timestamp '2001-07-27 12:00'63 days 15:00:00

interval * double precisioninterval

Multiplica um intervalo por um escalar

interval '1 second' * 90000:15:00

interval '1 day' * 2121 days

interval '1 hour' * 3.503:30:00

interval / double precisioninterval

Divide um intervalo por um escalar

interval '1 hour' / 1.500:40:00


Tabela 9.33. Funções de data e hora

Função

Descrição

Exemplo(s)

age ( timestamp, timestamp ) → interval

Subtrai os argumentos, produzindo um resultado simbólico que usa também anos e meses, em vez de apenas dias

age(timestamp '2001-04-10', timestamp '1957-06-13')43 years 9 mons 27 days

age ( timestamp ) → interval

Subtrai o argumento de current_date (à meia-noite)

age(timestamp '1957-06-13')62 years 6 mons 10 days

clock_timestamp ( ) → timestamp with time zone

Data e hora corrente (muda durante a execução da instrução); veja a Seção 9.9.5

clock_timestamp()2019-12-23 14:39:53.662522-05

current_datedate

Data corrente; veja a Seção 9.9.5

current_date2019-12-23

current_timetime with time zone

Hora corrente do dia; veja a Seção 9.9.5

current_time14:39:53.662522-05

current_time ( integer ) → time with time zone

Hora corrente do dia, com precisão limitada; veja a Seção 9.9.5

current_time(2)14:39:53.66-05

current_timestamptimestamp with time zone

Data e hora correntes (início da transação corrente); veja a Seção 9.9.5

current_timestamp2019-12-23 14:39:53.662522-05

current_timestamp ( integer ) → timestamp with time zone

Data e hora correntes (início da transação corrente), com precisão limitada; veja a Seção 9.9.5

current_timestamp(0)2019-12-23 14:39:53-05

date_add ( timestamp with time zone, interval [, text ] ) → timestamp with time zone

Adiciona um interval a um timestamp with time zone, calculando a hora corrente e ajustando-a às mudanças de horário de verão de acordo com a zona horária especificada pelo terceiro argumento, ou a configuração corrente de TimeZone, caso este argumento seja omitido. A sintaxe com dois argumentos é equivalente ao operador de timestamp with time zone + interval.

date_add('2021-10-31 00:00:00+02'::timestamptz, '1 day'::interval, 'Europe/Warsaw')2021-10-31 23:00:00+00

date_bin ( interval, timestamp, timestamp ) → timestamp

Coloca uma data dentro do intervalo especificado, alinhada com a origem determinada; veja a Seção 9.9.3

date_bin('15 minutes', timestamp '2001-02-16 20:38:40', timestamp '2001-02-16 20:05:00')2001-02-16 20:35:00

date_part ( text, timestamp ) → double precision

Extrai um subcampo de um carimbo de data e hora (equivalente à função extract); veja a Seção 9.9.1

date_part('hour', timestamp '2001-02-16 20:38:40')20

date_part ( text, interval ) → double precision

Extrai um subcampo de um intervalo (equivalente à função extract); veja a Seção 9.9.1

date_part('month', interval '2 years 3 months')3

date_subtract ( timestamp with time zone, interval [, text ] ) → timestamp with time zone

Subtrai um interval de um timestamp with time zone, calculando a hora corrente e ajustando-a às mudanças de horário de verão de acordo com a zona horária especificada pelo terceiro argumento, ou a configuração corrente de TimeZone, caso este argumento seja omitido. A sintaxe com dois argumentos é equivalente ao operador de timestamp with time zone - interval.

date_subtract('2021-11-01 00:00:00+01'::timestamptz, '1 day'::interval, 'Europe/Warsaw')2021-10-30 22:00:00+00

date_trunc ( text, timestamp ) → timestamp

Trunca para a precisão especificada; veja a Seção 9.9.2

date_trunc('hour', timestamp '2001-02-16 20:38:40')2001-02-16 20:00:00

date_trunc ( text, timestamp with time zone, text ) → timestamp with time zone

Trunca para a precisão especificada na zona horária especificada; veja a Seção 9.9.2

date_trunc('day', timestamptz '2001-02-16 20:38:40+00', 'Australia/Sydney')2001-02-16 13:00:00+00

date_trunc ( text, interval ) → interval

Trunca para a precisão especificada; veja a Seção 9.9.2

date_trunc('hour', interval '2 days 3 hours 40 minutes')2 days 03:00:00

extract ( field from timestamp ) → numeric

Extrai um subcampo de um carimbo de data e hora; veja a Seção 9.9.1

extract(hour from timestamp '2001-02-16 20:38:40')20

extract ( field from interval ) → numeric

Extrai um subcampo de um intervalo; veja a Seção 9.9.1

extract(month from interval '2 years 3 months')3

isfinite ( date ) → boolean

Teste para data finita (não +/-infinito)

isfinite(date '2001-02-16')true

isfinite ( timestamp ) → boolean

Teste para carimbo de data e hora finito (não +/-infinito)

isfinite(timestamp 'infinity')false

isfinite ( interval ) → boolean

Testa para um intervalo finito (no momento é sempre verdade)

isfinite(interval '4 hours')true

justify_days ( interval ) → interval

Ajusta o intervalo, convertendo períodos de 30 dias em meses

justify_days(interval '1 year 65 days')1 year 2 mons 5 days

justify_hours ( interval ) → interval

Ajusta o intervalo, convertendo períodos de 24 horas em dias

justify_hours(interval '50 hours 10 minutes')2 days 02:10:00

justify_interval ( interval ) → interval

Ajusta o intervalo usando as funções justify_days e justify_hours, com ajustes adicionais de sinal

justify_interval(interval '1 mon -1 hour')29 days 23:00:00

localtimetime

Hora corrente do dia; veja a Seção 9.9.5

localtime14:39:53.662522

localtime ( integer ) → time

Hora corrente do dia, com precisão limitada; veja a Seção 9.9.5

localtime(0)14:39:53

localtimestamptimestamp

Data e hora correntes (início da transação corrente); veja a Seção 9.9.5

localtimestamp2019-12-23 14:39:53.662522

localtimestamp ( integer ) → timestamp

Data e hora correntes (início da transação corrente), com precisão limitada; veja a Seção 9.9.5

localtimestamp(2)2019-12-23 14:39:53.66

make_date ( year int, month int, day int ) → date

Cria data a partir dos campos de ano, mês e dia (anos negativos significam BC)

make_date(2013, 7, 15)2013-07-15

make_interval ( [ years int [, months int [, weeks int [, days int [, hours int [, mins int [, secs double precision ]]]]]]] ) → interval

Cria intervalo a partir dos argumentos years, months, weeks, days, hours, mins e secs, cada um deles tendo zero como valor padrão

make_interval(days => 10)10 days

make_time ( hour int, min int, sec double precision ) → time

Cria hora a partir dos campos hour, min e sec

make_time(8, 15, 23.5)08:15:23.5

make_timestamp ( year int, month int, day int, hour int, min int, sec double precision ) → timestamp

Cria carimbo de data e hora a partir dos campos year, month, day, hour, min e sec (anos negativos significam BC)

make_timestamp(2013, 7, 15, 8, 15, 23.5)2013-07-15 08:15:23.5

make_timestamptz ( year int, month int, day int, hour int, min int, sec double precision [, timezone text ] ) → timestamp with time zone

Cria carimbo de data e hora com zona horária a partir dos campos year, month, day, hour, min, sec e timezone Se timezone não for especificada, será utilizada a zona horária corrente; os exemplos pressupõem que a zona horária da sessão seja Europe/London

make_timestamptz(2013, 7, 15, 8, 15, 23.5)2013-07-15 08:15:23.5+01

make_timestamptz(2013, 7, 15, 8, 15, 23.5, 'America/New_York')2013-07-15 13:15:23.5+01

now ( ) → timestamp with time zone

Data e hora correntes (início da transação corrente); veja a Seção 9.9.5

now()2019-12-23 14:39:53.662522-05

statement_timestamp ( ) → timestamp with time zone

Data e hora correntes (início da instrução corrente); veja a Seção 9.9.5

statement_timestamp()2019-12-23 14:39:53.662522-05

timeofday ( ) → text

Data e hora corrente (como a função clock_timestamp, mas retorna uma cadeia de caracteres do tipo de dados text); veja a Seção 9.9.5

timeofday()Mon Dec 23 14:39:53.662522 2019 EST

transaction_timestamp ( ) → timestamp with time zone

Data e hora correntes (início da transação corrente); veja a Seção 9.9.5

transaction_timestamp()2019-12-23 14:39:53.662522-05

to_timestamp ( double precision ) → timestamp with time zone

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

to_timestamp(1284352323)2010-09-13 04:32:03+00


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-06
SELECT 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

9.9.1. EXTRACT, date_part #

EXTRACT(field FROM source)

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');
→ 20
SELECT EXTRACT(CENTURY FROM TIMESTAMP '2001-02-16 20:38:40');
→ 21
SELECT EXTRACT(CENTURY FROM DATE '0001-01-01 AD');
→ 1
SELECT EXTRACT(CENTURY FROM DATE '0001-12-31 BC');
→ -1
SELECT 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');
→ 16
SELECT EXTRACT(DAY FROM INTERVAL '40 days 1 minute');
→ 40
decade

O 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').

doy

O 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.120000
SELECT EXTRACT(EPOCH FROM TIMESTAMP '2001-02-16 20:38:40.12');
→ 982355920.120000
SELECT 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.

hour

O 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.

isoyear

O ano do calendário ISO 8601 baseado na semana em que a data se encontra.

SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-01'); -- Domingo
→ 2005
SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-02'); -- Segunda-feira
→ 2006
SELECT 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].

julian

A 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');
→ 2453737
SELECT EXTRACT(JULIAN FROM TIMESTAMP '2006-01-01 12:00');
→ 2453737.50000000000000000000
microseconds

O 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');
→ 3
SELECT 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.

milliseconds

O 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
minute

O 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');
→ 2
SELECT EXTRACT(MONTH FROM INTERVAL '2 years 3 months');
→ 3
SELECT 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');
→ 1
SELECT EXTRACT(QUARTER FROM INTERVAL '1 year 6 months');
→ 3
second

O campo dos segundos, incluindo quaisquer frações de segundo.

SELECT EXTRACT(SECOND FROM TIMESTAMP '2001-02-16 20:38:40');
→ 40.000000
SELECT EXTRACT(SECOND FROM TIME '17:12:28.5');
→ 28.500000
timezone

O 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_hour

O componente hora do deslocamento de zona horária

timezone_minute

O componente minuto do deslocamento de zona horária

week

O 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');
→ 7
SELECT EXTRACT(WEEK FROM INTERVAL '13 days 24 hours');
→ 1
SELECT 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');
→ 2001
SELECT 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:00
SELECT EXTRACT(MINUTES FROM INTERVAL '80 minutes');
→ 20

Nota

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

9.9.2. 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

9.9.3. 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.

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

timestamp without time zone AT TIME ZONE zonetimestamp with time zone

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.

timestamp '2026-01-24 08:10:33' at time zone 'Brazil/Acre'2026-01-24 10:10:33-03

timestamp without time zone AT LOCALtimestamp with time zone

Converte o carimbo de data e hora fornecido sem zona horária em carimbo de data e hora com o valor de TimeZone da sessão como zona horária.

timestamp '2026-01-24 08:10:33' at local2026-01-24 08:10:33-03

timestamp with time zone AT TIME ZONE zonetimestamp without time zone

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.

timestamp with time zone '2026-01-24 10:10:33-03' at time zone 'Brazil/Acre'2026-01-24 08:10:33

timestamp with time zone AT LOCALtimestamp without time zone

Converte o carimbo de data e hora fornecido com zona horária em carimbo de tempo sem, como apareceria se o valor de TimeZone da sessão fosse zona horária.

timestamp with time zone '2026-01-24 08:10:33-03' at local2026-01-24 08:10:33

time with time zone AT TIME ZONE zonetime with time zone

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.

time with time zone '08:10:33-03' at time zone 'UTC'11:10:33+00

time with time zone AT LOCALtime with time zone

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 TimeZone da sessão.

Assumindo que o TimeZone da sessão esteja definido como UTC:

time with time zone '05:34:17-05' at local10:34:17+00


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 local, onde local é 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-08
SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE 'America/Denver';
→ 2001-02-16 18:38:40
SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'Asia/Tokyo' AT TIME ZONE 'America/Chicago';
→ 2001-02-16 05:38:40
SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT LOCAL;
→ 2001-02-16 17:38:40
SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE '+05';
→ 2001-02-16 20:38:40
SELECT 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 timezone(zone, timestamp) equivale à construção em conformidade com o padrão SQL timestamp AT TIME ZONE zone.

A função timezone(zone, time) equivale à construção em conformidade com o padrão SQL time AT TIME ZONE zone.

A função timezone(timestamp) equivale à construção em conformidade com o padrão SQL timestamp AT LOCAL.

A função timezone(time) equivale à construção em conformidade com o padrão SQL time AT LOCAL.

9.9.5. Data e hora corrente #

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-03
SELECT CURRENT_DATE;
→ 2026-01-24
SELECT CURRENT_TIMESTAMP;
→ 2026-01-24 09:52:54.973257-03
SELECT CURRENT_TIMESTAMP(2);
→ 2026-01-24 09:52:54.97-03
SELECT 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.

Nota

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

Dica

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

9.9.6. Atrasando a execução #

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');

Nota

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.

Atenção

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