sqlpostgresqlintervaldates

JUSTIFY_INTERVAL no PostgreSQL: normalizando intervalos em dias e meses

JUSTIFY_HOURS, JUSTIFY_DAYS e JUSTIFY_INTERVAL transformam um intervalo bruto em dias e meses legiveis.

2 min de leituraReferencesql · postgresql · interval · dates · justify

Quando voce soma e subtrai intervalos no PostgreSQL, o resultado costuma sair "bruto": 36 horas, 90 dias, 800 minutos. A familia JUSTIFY_* reorganiza esse intervalo em algo legivel, jogando as horas que sobram para dias e os dias que sobram para meses.

Tres funcoes e o que cada uma carrega

O PostgreSQL traz tres funcoes de normalizacao, cada uma responsavel por uma "casa":

  • JUSTIFY_HOURS(i) pega cada 24 horas e as transforma em 1 dia.
  • JUSTIFY_DAYS(i) pega cada 30 dias e os transforma em 1 mes.
  • JUSTIFY_INTERVAL(i) faz os dois transportes de uma vez e ajusta os sinais.
SELECT JUSTIFY_HOURS(INTERVAL '36 hours')   AS h,   -- 1 day 12:00:00
       JUSTIFY_DAYS(INTERVAL '90 days')      AS d,   -- 3 mons
       JUSTIFY_INTERVAL(INTERVAL '1 mon 33 days 27 hours') AS full;
-- full -> 2 mons 4 days 03:00:00

Repare que nenhuma delas achata o intervalo ate segundos. O PostgreSQL guarda um intervalo em tres campos independentes — meses, dias e microssegundos — e JUSTIFY_* apenas remaneja valores entre esses campos sem mudar o significado.

Para que serve: duracao de um pedido

Digamos que medimos ha quanto tempo um pedido esta em processamento. A subtracao simples de tempos da um intervalo onde tudo se acumula em horas:

SELECT id,
       created_at,
       NOW() - created_at AS raw_age
FROM orders
WHERE status = 'processing';
-- raw_age poderia ser, por exemplo, '52:30:00'

A string 52:30:00 esta tecnicamente correta, mas e desconfortavel num relatorio. Envolva o resultado em JUSTIFY_HOURS:

SELECT id,
       JUSTIFY_HOURS(NOW() - created_at) AS readable_age
FROM orders
WHERE status = 'processing';
-- readable_age -> 2 days 04:30:00

Agora se le como "2 dias e algumas horas" — exatamente o que um gestor espera ver.

Tempo de casa e grandes contagens de dias

JUSTIFY_DAYS e bem util quando voce acumula dias e quer uma estimativa aproximada em meses. Imagine agregar dias por departamento:

SELECT dept,
       JUSTIFY_DAYS(SUM(NOW() - created_at)) AS dept_tenure
FROM employees
GROUP BY dept;

Quando um intervalo carrega horas e dias ao mesmo tempo, use JUSTIFY_INTERVAL — ele organiza em todas as frentes. Um bom habito e normalizar uma diferenca antes de compara-la, para que sinais misturados nao te peguem de surpresa:

SELECT name,
       JUSTIFY_INTERVAL(salary_review_at - hired_at) AS service
FROM employees
ORDER BY service DESC;

Pegadinha: 30 dias nao e um mes de calendario

A armadilha principal de JUSTIFY_DAYS e JUSTIFY_INTERVAL e que elas tratam um mes como exatamente 30 dias. Meses reais nunca sao assim: fevereiro tem 28 ou 29 dias, julho tem 31.

SELECT JUSTIFY_INTERVAL(INTERVAL '60 days');
-- 2 mons   (nao "1 mes mais alguns dias de calendario")

Por causa disso, um intervalo normalizado serve para relatorios e rotulos legiveis, mas e errado para aritmetica exata de datas. Tenha a distincao em mente:

  • JUSTIFY_* aplica regras fixas: 24 horas = 1 dia, 30 dias = 1 mes.
  • AGE(end, start) olha o calendario real e devolve meses e dias verdadeiros.

Se voce precisa de uma "idade" honesta, use AGE. Se so quer exibir uma duracao acumulada de forma organizada, use JUSTIFY_*.

Diferencas em outros bancos

As funcoes JUSTIFY_* sao especificas do PostgreSQL; nao ha equivalente direto em outros bancos.

  • MySQL: nao existe um tipo interval de primeira classe, entao as diferencas costumam viver como segundos ou dias. Voce normaliza na mao com DIV e MOD, por exemplo seconds DIV 86400 para dias.
  • ClickHouse: os intervalos tambem nao se normalizam sozinhos; use dateDiff('day', ...) e aritmetica numerica simples para derivar as casas que quiser.

Resumo: JUSTIFY_* e uma conveniencia de apresentacao que vive no PostgreSQL. Em codigo portavel, normalize as duracoes voce mesmo e lembre-se de que "um mes igual a 30 dias" e uma simplificacao, nao uma verdade do calendario.

Pratique com exercícios reais

Resolva exercícios no treinador de SQL com correção instantânea e dicas.

Abrir o treinador