Formatando intervalos de tempo com Intl.RelativeTimeFormat em um projeto Angular
Quer transformar datas em frases como "há 5 minutos" ou "em 2 horas"? Veja neste post um exemplo prático mostrando como integrar essa funcionalidade em seus projetos Angular.
Expressar o tempo de forma mais natural, como "há 5 minutos" ou "em 2 dias", torna a informação mais compreensível e é comum em diversas aplicações, desde redes sociais até extratos bancários. Antigamente, era necessário escrever várias linhas de código para implementar essa funcionalidade, mas atualmente, com o Intl.RelativeTimeFormat
, disponível nativamente no JavaScript, podemos facilmente formatar intervalos de tempo de forma clara, relativa e sem se preocupar com as traduções, simplificando o processo.
Neste pequeno texto, vamos falar sobre como utilizar essa funcionalidade em um projeto frontend utilizando o framework Angular.
Introdução
Para quem está começando, vale lembrar que o JavaScript está em constante evolução. Em projetos frontend, quem interpreta o código JavaScript é um "motor" dentro do navegador (Chrome, Safari, Edge, entre outros). Já no backend, o código JavaScript é interpretado pelo Node.js (que usa o mesmo "motor" do Chrome, o V8) ou Deno, por exemplo.
Esses "motores" têm diferentes implementações. Por isso, novas funções JavaScript podem levar um tempo para serem suportadas em todos os lugares, portanto, algumas funcionalidades podem funcionar em um ambiente, mas não em outro.
Por exemplo, a função fetch
, que já foi comentada por aqui e é usada para buscar dados de um servidor, funciona a partir da versão 18 do Node.js. Por isso, é importante sempre verificar se os recursos JavaScript que você está usando no seu código são suportados pelo seu ambiente de execução, garantindo que tudo funcione como esperado. No caso do Intl.RelativeTimeFormat
, que é o nosso alvo de estudo, ele é suportado a partir das seguintes versões:
Navegador | Plataforma | Versão |
---|---|---|
Chrome | (Desktop) | 71 |
Edge | (Desktop) | 79 |
Firefox | (Desktop) | 65 |
Opera | (Desktop) | 58 |
Safari | (Desktop) | 14 |
Chrome | (Android) | 71 |
Firefox | (Android) | 65 |
Opera | (Android) | 50 |
Safari | (iOS) | 14 |
Node.js | (-) | 12.0.0 |
Os dados acima foram extraídos deste link em setembro de 2024.
O básico sobre o Intl.RelativeTimeFormat
O Intl.RelativeTimeFormat
permite formatar textos que descrevem intervalos de tempo de maneira simples em relação ao momento atual, por exemplo: "ontem", "há uma hora", "amanhã", "em 2 dias", entre outros.
Exemplo - Formatando intervalo de tempo
Abaixo há um exemplo bem simples de como utilizar o Intl.RelativeTimeFormat
:
const rtf = new Intl.RelativeTimeFormat(
'pt-BR',
{ numeric: 'auto' }
);
console.log(rtf.format(-1, 'day'));
// "ontem"
console.log(rtf.format(1, 'day'));
// "amanhã"
console.log(rtf.format(-3, 'day'));
// "há 3 dias"
console.log(rtf.format(2, 'week'));
// "em 2 semanas"
ctrl + shift + i
) e na aba "console" cole o código e pressione enter para ver o resultado da execução.Explicação do código acima
Antes de tudo é necessário criar uma instância do Intl.RelativeTimeFormat
. Para isso, passamos o idioma desejado e um objeto com opções de configuração. Esse objeto de configuração pode receber os seguintes parâmetros:
- locale (idioma): Por exemplo
'en-US'
para inglês (Estados Unidos) ou'pt-BR'
para português (Brasil). - options (opções): Um objeto opcional que pode conter propriedades como:
numeric
: Pode ser'always'
(sempre usar números) ou'auto'
(usar palavras como "ontem" ou "amanhã" quando aplicável).style
: Pode ser'long'
,'short'
ou'narrow'
, determinando o comprimento da string de saída.
Depois de criar a instância, podemos utilizar o método format
, que recebe dois parâmetros, para formatar o intervalo de tempo:
- primeiro parâmetro: diferença de tempo em relação a data corrente, podendo ser positivo ou negativo para indicar tempos futuros ou passados.
- segundo parâmetro: unidade de tempo (ver lista abaixo)
Exemplo:
(() => {
const opcoes = [
{ numeric: "always", style: "long" },
{ numeric: "auto", style: "long" },
{ numeric: "always", style: "short" },
{ numeric: "auto", style: "short" },
{ numeric: "always", style: "narrow" },
{ numeric: "auto", style: "narrow" },
];
for (const { numeric, style } of opcoes) {
const rtf = new Intl.RelativeTimeFormat(
"pt-BR",
{ numeric, style }
);
console.group(`${numeric}-${style}`);
console.log(
rtf.format(-1, "minute"),
rtf.format(1, "day"),
rtf.format(-2, "week"),
rtf.format(2, "month")
);
console.groupEnd();
}
})();
Resultado:
Construindo um Angular Pipe para formatar o intervalo de tempo com Intl.RelativeTimeFormat
Partindo para uma aplicação mais próxima da realidade, criei um projeto em Angular 18 utilizando o StackBlitz. Em seguida, desenvolvi um Pipe que recebe uma data de referência e retorna o intervalo de tempo formatado usando o Intl.RelativeTimeFormat
.
A implementação do Pipe ficou as seguinte forma:
O arquivo main.ts
, que define o componente principal da aplicação, ficou assim:
Resultado da execução do projeto:
Para acessar o projeto acima, utilize este link do StackBlitz.
Considerações
Neste texto, exploramos o uso do Intl.RelativeTimeFormat
para formatação de intervalos de tempo, aplicando-o em um projeto Angular, mas destacando que o mesmo conceito pode ser facilmente reutilizado em outras plataformas como Node.js, NestJS, Deno, React, Vue e entre outros.
Links interessantes: