DEV Community

Cover image for Uma alternativa vanilla JS para o método moment.js timeFromNow()
doug-source
doug-source

Posted on

Uma alternativa vanilla JS para o método moment.js timeFromNow()

Nota: apenas traduzi o texto abaixo e postei aqui.

O que o método moment().timeFromNow() faz

O método moment().timeFromNow() retorna uma string formatada com "há quanto tempo algo aconteceu".

Você passa uma data do passado e ela retorna coisas como alguns segundos atrás ou 2 anos atrás.

// 16 anos atrás
moment([2007, 0, 29]).fromNow();
Enter fullscreen mode Exit fullscreen mode

Ele apenas fornece datas no passado. Existe outra function, moment.timeToNow(), para datas futuras.

O que nossa helper function timeFromNow() fará

Nossa helper function funcionará de maneira um pouco diferente.

Uma das coisas que gosto no Vanilla JS é o maior controle que você tem. Em vez de obter uma string pré-formatada, prefiro ter a diferença de tempo e as unidades de tempo (anos, meses, etc.) com as quais posso trabalhar como quiser.

Eu também preferiria uma function que funcionasse tanto para eventos passados quanto futuros.

Em vez de retornar uma string, nossa helper function retornará um object a diferença de tempo, as unidades de tempo e se o tempo está no passado ou no futuro.

Contruindo uma helper function timeFromNow()

Primeiro, vamos configurar uma helper function que aceita o time como argument.

var timeFromNow = function (time) {
    // O código vai aqui...
};
Enter fullscreen mode Exit fullscreen mode

O valor time pode ser uma string, um Date() object ou um unix timestamp em milissegundos.

// Esses são todos válidos
timeFromNow('December 31, 1999');
timeFromNow('1999/12/31');
timeFromNow(new Date('1999-12-31T10:30:00-04:00'));
timeFromNow(946650600000);
Enter fullscreen mode Exit fullscreen mode

Calculando a diferença de tempo

Para encontrar a diferença entre o time e now, primeiro precisamos obter um valor de timestamp para o nosso time.

Iremos passá-lo para um novo Date() object e, em seguida, chamaremos o método getTime() nele. Também criaremos outro novo Date() object para obter o time de now e obter um timestamp para isso também.

Se não houver unixTime válido (se o usuário informou uma data incorreta, por exemplo), retornaremos null.

var timeFromNow = function (time) {
    // Obtêm timestamps
    var unixTime = new Date(time).getTime();
    if (!unixTime) return null;
    var now = new Date().getTime();
};
Enter fullscreen mode Exit fullscreen mode

A seguir, subtrairemos o time de now do nosso unixTime para obter a diferença entre o time e now.

Ambos timestamps estão em milissegundos, e a menor unidade com a qual queremos trabalhar são segundos, então dividiremos os dois numbers por 1000 primeiro para convertê-los em segundos.

var timeFromNow = function (time) {
    // Obtêm timestamps
    var unixTime = new Date(time).getTime();
    if (!unixTime) return null;
    var now = new Date().getTime();

    // Calcula a diferença
    var difference = (unixTime / 1000) - (now / 1000);
};
Enter fullscreen mode Exit fullscreen mode

Criando nosso time a partir dos dados de now

A seguir, vamos configurar um object chamado tfn que armazenará nossos dados de time a partir de now (agora).

O primeiro dado que adicionaremos é quando o time acontece: no passado, agora ou no futuro. Se a diferença for maior que 0, isso aconteceu no futuro. Se for menor que -1, isso aconteceu no passado. Caso contrário, está acontecendo agora.

(Usamos -1 em vez de 0 para contabilizar pequenas frações que podem ocorrer com timestamps).

var timeFromNow = function (time) {
    // Obtêm timestamps
    var unixTime = new Date(time).getTime();
    if (!unixTime) return null;
    var now = new Date().getTime();

    // Calcula a diferença
    var difference = (unixTime / 1000) - (now / 1000);

    // Configura o object retornado
    var tfn = {};

    // Verifique se o time está no passado, presente ou futuro
    tfn.when = 'presente';
    if (difference > 0) {
        tfn.when = 'futuro';
    } else if (difference < -1) {
        tfn.when = 'passado';
    }
};
Enter fullscreen mode Exit fullscreen mode

Calculando as unidades de tempo

Em seguida, precisamos descobrir se a nossa diferença tem anos, meses, dias, horas ou segundos.

Primeiro, usaremos o método Math.abs() para converter quaisquer números negativos em positivos. Então, podemos verificar unitOfTime.

Para isso, dividiremos a diferença pelo número de segundos de um ano, mês, dia e hora. Se esse valor for maior que 1, essa é a nossa unidade. Caso contrário, continuamos. Como a duração dos meses pode variar, usaremos 45 para o número de dias.

Também definiremos tfn.time e usaremos o método Math.floor() para arredondar para o integer mais próximo.

var timeFromNow = function (time) {
    // ...

    // Converte a diferença para "absolute"
    difference = Math.abs(difference);

    // Calcula a unidade de tempo
    if (difference / (60 * 60 * 24 * 365) > 1) {
        // Anos
        tfn.unitOfTime = 'anos';
        tfn.time = Math.floor(difference / (60 * 60 * 24 * 365));
    } else if (difference / (60 * 60 * 24 * 45) > 1) {
        // Meses
        tfn.unitOfTime = 'meses';
        tfn.time = Math.floor(difference / (60 * 60 * 24 * 45));
    } else if (difference / (60 * 60 * 24) > 1) {
        // Dias
        tfn.unitOfTime = 'dias';
        tfn.time = Math.floor(difference / (60 * 60 * 24));
    } else if (difference / (60 * 60) > 1) {
        // Horas
        tfn.unitOfTime = 'horas';
        tfn.time = Math.floor(difference / (60 * 60));
    } else {
        // Segundos
        tfn.unitOfTime = 'segundos';
        tfn.time = Math.floor(difference);
    }
};
Enter fullscreen mode Exit fullscreen mode

Se esses números são confusos, vamos detalhá-los um pouco.

Um minuto tem 60 segundos, uma hora tem 60 minutos e um dia tem 24 horas. Existem 365 dias em um ano. Para calcular o número de segundos em um ano, multiplicamos todos esses números juntos.

// O número de segundos em um ano
var year = 60 * 60 * 24 * 365;
Enter fullscreen mode Exit fullscreen mode

Por dias, multiplicaríamos 60 segundos por 60 minutos para obter uma hora de segundos e depois multiplicaríamos por 24 (o número de horas em um dia).

// O número de segundos em um dia
var day = 60 * 60 * 24;
Enter fullscreen mode Exit fullscreen mode

Retornando nosso tfn object

Agora que fizemos todos os nossos cálculos, a última coisa a fazer é retornar nosso tfn object.

var timeFromNow = function (time) {
    // ...

    // Retorna o time dos dados de agora
    return tfn;
};
Enter fullscreen mode Exit fullscreen mode

Isso funcionará em todos os navegadores modernos e, pelo menos, no IE 9.

Saúde,

Fonte

Newsletter de Go Make Things

Top comments (0)