Difference of Month in Javascript

Asked

Viewed 69 times

1

I’m developing a simple application that calculates the difference between two dates, on the console I can already make the difference between years but I can’t calculate the difference of month.

var botaoCalcular = document.querySelector("#calcular");
botaoCalcular.addEventListener("click", function (event){
    event.preventDefault();

    var form = document.querySelector("#calculaPeriodo");

    let data1 = form.dataInicio.value;
    let data2 = form.dataFim.value;

    let dataI = data1;
    let dataII = data2;

    const dataSplit = dataI.split('/');
    const dataSplit2 = dataII.split('/')

    const day = dataSplit[0]; // 30
    const month = dataSplit[1]; // 03
    const year = dataSplit[2]; // 2019

    const day2 = dataSplit2[0]; // 30
    const month2 = dataSplit2[1]; // 03
    const year2 = dataSplit2[2]; // 2019

    dataI = new Date(year, month - 1, day);
    dataII = new Date(year2, month2 - 1, day2);

    const diff = Math.abs(dataI.getTime() - dataII.getTime());

    const anos = Math.ceil(diff / (1000 * 60 * 60 * 24 * 365));

    const mes = Math.ceil(diff / (1000 * 60 * 60 * 24 * 365));
    
    console.log(dataI);
    console.log(dataII);
    console.log(diff);
    console.log(anos);
    console.log(mes);

})

2 answers

1

If you want the difference in months or years, do not need to calculate this way.

The problem of months and years is that they do not have fixed sizes. A month may be 28, 29, 30 or 31 days, and a year may be 365 or 366 days. So taking the difference in milliseconds and dividing by some arbitrary mean value will always be inaccurate (in most cases it may not be a problem, but there is corner cases too, as already explained in this question).

Even in the question quoted above there is an alternative - in my opinion, better - to calculate this difference:

function ajustaMesAno(d) {
    return d.getFullYear() * 12 + d.getMonth() + 1;
}

let inicio = new Date(2018, 0, 20); // 20 de janeiro de 2018
let fim = new Date(2020, 9, 10); // 10 de outubro de 2020

let diffMeses = ajustaMesAno(fim) - ajustaMesAno(inicio);

console.log(diffMeses); // 33

// ou, se quiser separar em anos e meses
let anos = Math.floor(diffMeses / 12);
let meses = diffMeses % 12;
console.log(`${anos} anos e ${meses} meses`); // 2 anos e 9 meses

The detail is that the code above does not take into account the day. That is, the initial date is January 20 and the final date is October 10, but even so was considered the month of October in the calculation. But if you just want it to be counted only from October 20, just adjust:

function ajustaMesAno(d) {
    return d.getFullYear() * 12 + d.getMonth() + 1;
}

let inicio = new Date(2018, 0, 20); // 20 de janeiro de 2018
let fim = new Date(2020, 9, 10); // 10 de outubro de 2020

let diffMeses = ajustaMesAno(fim) - ajustaMesAno(inicio);
if (inicio.getDate() > fim.getDate()) diffMeses--; // <- ajuste para considerar o dia

console.log(diffMeses); // 32

// ou, se quiser separar em anos e meses
let anos = Math.floor(diffMeses / 12);
let meses = diffMeses % 12;
console.log(`${anos} anos e ${meses} meses`); // 2 anos e 8 meses


Another option is to use the Moment js.:

let inicio = new Date(2018, 0, 20); // 20 de janeiro de 2018
let fim = new Date(2020, 9, 10); // 10 de outubro de 2020

// obter o total de meses
let diffMeses = moment(fim).diff(moment(inicio), 'months');
console.log(diffMeses); // 32

// ou usando duration
let diff = moment.duration(moment(fim).diff(moment(inicio)));
console.log(`${diff.years()} anos e ${diff.months()} meses`); // 2 anos e 8 meses
<script src="https://momentjs.com/downloads/moment.min.js"></script>

In the case, diff already takes into account the day (if the beginning is January 20, only from October 20 the difference would be 33 months).

-2

Your year and month calculation is being done in the same way

const anos = Math.ceil(diff / (1000 * 60 * 60 * 24 * 365));
const mes = Math.ceil(diff / (1000 * 60 * 60 * 24 * 365));

The month calculation should not be multiplying by 365 (days).

Browser other questions tagged

You are not signed in. Login or sign up in order to post.