Difference of days javascript considering dates in different months

Asked

Viewed 688 times

1

I need to pick the difference between two dates.
However, in my business rule, the difference of 17/05/2014 and 17/05/2014 is 1 day.
So I thought just adding a day in the final result would solve my problem.
However, when I ask for the interval from (for example) 30/09/2014 to 01/10/2014 it returns me the expected result. 2 days.
If I ask 30 to 30, it returns me 0.

Current script:

function parseDate(str) {
    var mdy = str.split('/')
    return new Date(mdy[2], mdy[1], mdy[0]-1);
}

function daydiff(first, second) {
    var date1 = parseDate(first);
    var date2 = parseDate(second);
    return (date2-date1)/(1000*60*60*24) + 1;
}

Why it happens and how to adjust this comparison of differences to my case?

  • 1

    I tested it in Chrome and the result was as expected. It may be rounding problem in your browser. Try putting: return Math.ceil(date2 - date1) / (1000 * 60 * 60 *24)) + 1;

  • 2

    A word: Moment.

  • @Viníciusgobboa.deOliveira, if you test 30/09/2014 for 01/10/2014, the result returned will be 3 days. :/

  • Just check one thing: the parameter month goes from 0 to 11. It would have to decrease 1 of the month in the construction of the object (2nd parameter)

  • What if the month is 0? :) Anyway, if you look at the parseDate function, it already takes care of it.

  • But the third parameter is not the day?

  • Dates enter daydiff with format br: dd/mm/yyy. And then, it triggers parseDate to delimit the string and create a new date.

  • I have tested it in many ways here. And what it seems is that there really is this inconsistency in calculating dates.

  • The same script with the same calculations in php works perfectly.

  • 2

    @rrnan.. Thanks. I solved using Moment.js

  • @Rafaelsoufraz put his solution as an answer, explaining how he used it and what the result was. This may help future questions on the same subject. :)

Show 6 more comments

2 answers

1

I set up this function based on research.
I think it’s better than using a library, because then you go straight to the point you don’t carry extra resources, however it is a restrictive tando, you would have to adapt.

function betweenDates(d1, d2, diff, returnLiteral){

    d1      = d1.split(' ');    // Divide o timestamp em data e hora
    d1[0]   = d1[0].split('-'); // Separa as variacoes da data
    d1[1]   = d1[1].split(':'); // Separa as variacoes da hora
    d1      = d1[0].concat(d1[1]); // concatena os dois conteudos formando um array unico.

    d1 = new Date(d1[0],d1[1],d1[2],d1[3],d1[4],d1[5]); // gera o objeto date
    d1 = Date.UTC(d1.getFullYear(), d1.getMonth(), d1.getDate(), d1.getHours(), d1.getMinutes(), d1.getSeconds()); // retona o time UTC corespondente da data.

    d2      = d2.split(' ');
    d2[0]   = d2[0].split('-');
    d2[1]   = d2[1].split(':');
    d2      = d2[0].concat(d2[1]);

    d2 = new Date(d2[0],d2[1],d2[2],d2[3],d2[4],d2[5]);
    d2 = Date.UTC(d2.getFullYear(), d2.getMonth(), d2.getDate(), d2.getHours(), d2.getMinutes(), d2.getSeconds());

    var dDiff = d2 - d1; // calcula a diferenca entre as datas

    var out = {
        'y' : dDiff/1000/60/60/24/30/12,    // calculo para ano
        'm' : dDiff/1000/60/60/24/30,       // calculo para mes
        'd' : dDiff/1000/60/60/24,          // calculo para dia
        'h' : dDiff/1000/60/60,             // calculo para hora
        'i' : dDiff/1000/60,                // calculo para minuto
        's' : dDiff/1000/1                  // calculo para segundo
    };

    out = Math.floor(out[diff]);    // Saida (inteiro do calculo)

    // Retorno
    if(out < 0 && !returnLiteral){
        return out*-1;
    }else{
        return out;
    }
}

betweenDates('2015-11-02 00:00:00', '2015-10-02 23:00:00', 'y') // 0
betweenDates('2015-11-02 00:00:00', '2015-10-02 23:00:00', 'm') // -1
betweenDates('2015-10-02 00:00:00', '2015-11-02 23:00:00', 'm') // 1
betweenDates('2015-10-02 00:00:00', '2015-10-02 23:00:00', 's') // 82800
betweenDates('2015-10-02 00:00:00', '2015-10-02 23:00:00', 'h') // 23

1

The problem with your code is the month, which is indexed to zero, but you’re subtracting from the day. In addition the split result can return an unexpected number, so it is necessary to round with Math.ceil().

function parseDate(str) { // aceita dia/mes/ano
    var mdy = str.split('/')
    return new Date(mdy[2], mdy[1] - 1, mdy[0]);
}

function daydiff(first, second) {
    var date1 = parseDate(first);
    var date2 = parseDate(second);
    return Math.ceil((date2 - date1) / (1000 * 60 * 60 * 24)) + 1;
}

// exibição dos resultados
var pre = document.body.appendChild(document.createElement('pre'));
pre.textContent += '30/09/2014 a 30/09/2014: ';
pre.textContent += daydiff('30/09/2014', '30/09/2014') + ' dia(s)\n';
pre.textContent += '30/09/2014 a 01/10/2014: ';
pre.textContent += daydiff('30/09/2014', '01/10/2014') + ' dia(s)\n';
pre.textContent += '30/09/2014 a 30/10/2014: ';
pre.textContent += daydiff('30/09/2014', '30/10/2014') + ' dia(s)\n';

Browser other questions tagged

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