0

We have using below code.

var oneDay = 24*60*60*1000; // hours*minutes*seconds*milliseconds
var firstDate = new Date(2008,01,12);
var secondDate = new Date(2008,01,22);

var diffDays = Math.abs((firstDate.getTime() - secondDate.getTime())/(oneDay));

But we can't find both month and days between them. I want like suppose start date is 27-sep-2014 and end date is 1-nov-2014. Result will be 1 month and 5 days.

MrTux
  • 32,350
  • 30
  • 109
  • 146
krutssss
  • 934
  • 1
  • 10
  • 23

2 Answers2

3

There multiple ways to count months and days. Without further restrictions all correct of them are correct even though the results might differ.

For example from September 27 to November 1 could be either

  • 1 month and 5 days or
  • 4 days and 1 month.

This is one possible solution.

// swap dates if difference would be negative
if (firstDate.getTime() > secondDate.getTime()) {
    var tmp = firstDate;
    firstDate = secondDate;
    secondDate = tmp;
}

var years = secondDate.getFullYear() - firstDate.getFullYear();
var months = secondDate.getMonth() - firstDate.getMonth();
var days = secondDate.getDate() - firstDate.getDate();

// prevent negative amount of days by breaking up months
for (var i = 0; days < 0; ++i) {
    // while the day difference is negative
    // we break up months into days, starting with the first
    months -= 1;
    days += new Date(
        firstDate.getFullYear(),
        firstDate.getMonth() + 1 + i,
        0, 0, 0, 0, 0
    ).getDate();
}

// prevent negative amount of months by breaking up years
if (months < 0) {
    years += Math.floor(months / 12);
    months = (months % 12 + 12) % 12;
}

// print the result
console.log([
    {amount: days, unit: 'day'},
    {amount: months, unit: 'month'},
    {amount: years, unit: 'year'},
].filter(value => value.amount).map(value =>
    value.amount === 1 ?
        `${value.amount} ${value.unit}` :
        `${value.amount} ${value.unit}s`
).reduce((result, part, index, parts) =>
    index > 0 ? index === parts.length - 1 ?
        `${result} and ${part}` :
        `${result}, ${part}` :
        `${part}`,
        `0 days`
));

Examples:

  • 02/12 to 02/22: 10 days
  • 09/27 to 11/01: 4 days and 1 month // instead of 1 month and 5 days
  • 12/31 to 03/01: 1 day and 2 months // instead of 1 month and 29 days
  • 05/31 to 06/30: 30 days
  • 01/31 to 03/30: 30 days and 1 month // instead of 1 month and 27 days
  • 10/27/2010 to 08/26/2014: 30 days, 9 months and 3 years
Robert
  • 2,603
  • 26
  • 25
  • 1
    Using 2013-12-31 and 2014-03-01 gives 2 months and -2 days. – RobG Sep 27 '14 at 11:59
  • @RobG Thank you for the hint. Breaking down the distance of two dates into days and months is a bit ambiguous. Obviously my first approach (first count months, then days) had a few awkward special cases, even though I assume most people would do it this way manually. I've changed the code so now it first counts days, then months. This should solve all problems while still being not incorrect. – Robert Sep 27 '14 at 12:29
  • There are lots of "special cases", it's not easy. Now 2014-05-31 to 2014-06-30 gives 30 days, should it be 1 month? There are usually administrative rules too, such as in some jurisdictions people born on 29 February have their birthday on 28 February in non–leap years, but in other jurisdictions it's 1 March. Is 30 June +1 month 30 July or 31 July? Adding and subtracting years and months isn't necessarily symmetric either. All good fun. ;-) – RobG Sep 27 '14 at 12:36
  • Thanks for your answer. If any possibility 09/27 to 11/01: 1 month, 5 days to 09/27 to 11/01: 1 month, 4 days – krutssss Sep 29 '14 at 08:07
  • @kruti It's certainly possible. September has 30 days and October has 31 days. So both results are valid. It's just a question of what to count first. 09/27 + 1 month = 10/27, leaving 5 days. 09/27 + 4 days = 10/01, leaving 1 month. I've changed the answer accordingly. – Robert Sep 30 '14 at 15:11
1

Try this

var oneDay = 24*60*60*1000;
    var firstDate = new Date(2007,01,12);
    var secondDate = new Date(2008,01,22);

    var diffDays = Math.abs((firstDate.getTime() - secondDate.getTime()));

    var result = '',
        years, months, days;
    if((years = diffDays / (365 * oneDay)) > 1){
        result += Math.floor(years) + ' Year(s)';
        diffDays %= (365 * oneDay);
    }
    if((months = diffDays / (30 * oneDay)) > 1){
        result += Math.floor(months) + ' Month(s)';
        diffDays %= (30 * oneDay);
    }
    result += (diffDays / oneDay) + ' Days(s)';
    alert(result);
MH2K9
  • 11,951
  • 7
  • 32
  • 49