0

I've tried to get this code to calculate years, months and days but the code below always calculates one month too much.

$(document).on("pagecreate","#pagethree", function(){ 
    $("#btnCalc").on("click", function(e){
        var born = $("#born").datebox('getTheDate');
        var death = $("#death").datebox('getTheDate');
        var age = death.getFullYear() - born.getFullYear();
        var m = death.getMonth() - born.getMonth();
        var da = death.getDate() - born.getDate();

        if (m < 0 || (m === 0 && death.getDate() < born.getDate())) {
            age--;
        }
        if(m<0){
            m +=12;
        }
        if(da<0){
            da +=30;
        }
        $("#p").popup("open");
        $('#altertext').html((age) + " Years "+ (Math.abs(m))+ " Months " + (Math.abs(da)) + " Days" );
    });
})

How can I fix this?

Yass
  • 2,658
  • 3
  • 13
  • 21
kubus1234
  • 11
  • 4
  • 3
    [Dates are complicated](http://stackoverflow.com/questions/6841333/why-is-subtracting-these-two-times-in-1927-giving-a-strange-result). Consider using a library like [moment.js](http://momentjs.com/). – ssube May 23 '16 at 20:26
  • 1
    What's that empty `if ()` doing? – IMTheNachoMan May 23 '16 at 20:59

2 Answers2

0

Why not just do calculations on the number of days?

$(document).on("pagecreate","#pagethree", function()
{ 
    $("#btnCalc").on("click", function(e)
    {
        var born = $("#born").datebox('getTheDate');
        var death = $("#death").datebox('getTheDate');

        // you can subtract two date objects to get the milliseconds in between
        // then figure out how many days that is
        // 1 day = 24 hours
        // 1 hour = 60 minutes
        // 1 minute = 60 seconds
        // 1 second = 1000 milliseconds
        var ageInDays = (death - born) / 1000 / 60 / 60 / 24;

        // days / 365 tells you years
        var years = Math.floor(ageInDays / 365);

        // the remainder tells you months
        var months = Math.floor(ageInDays % 365 / 31);

        // the remainder tells you days
        var days =  Math.floor(ageInDays % 365 % 31);

        $("#p").popup("open");
        $('#altertext').html(years + " Years " + months + " Months " + days + " Days" );
  });
})

Of course this doesn't take into account the fact that months and years have a different number of days.

If you want something more exact then do like @ssube says and use a library.

** EDIT **

This should work and also be accurate

// calculate difference between two dates in years, months, days
function dateDiff(start, end)
{
    // set a new temp variable we're gonna modify
    var s = new Date(start.getTime());

    // how many years
    var years = end.getFullYear() - start.getFullYear();

    // add this many years to the temp var
    s.setFullYear(s.getFullYear() + years);

    // if we've passed the end then we need to go back one year
    if(s > end)
    {
        years--;
        s.setFullYear(s.getFullYear() - 1);
    }

    // how many months between the two
    var months = 12 - s.getMonth() + end.getMonth();

    // add this many months to the temp var
    s.setMonth(s.getMonth() + months);

    // if we've passed the end then we need to back one month
    if(s > end)
    {
        months--;
        s.setMonth(s.getMonth() - 1);
    }

    // now just calculate the days between the end and temp start
    var days = Math.floor((end - s) / 1000 / 60 / 60 / 24)

    return [years, months, days];
}

It basically works by adding years and then months to the start till we meet the end.

IMTheNachoMan
  • 5,343
  • 5
  • 40
  • 89
0

Thanks for the answers! I've just added m-- to this if statement:

if(da<0){
        da +=30;
        m--;
    }
kubus1234
  • 11
  • 4