1

I'm having trouble using a function with JS. I got this JS code from here Difference between two dates in years, months, days in JavaScript

The months work fine but when I try to call the days it doesn't seem to work right, it will show 30 days when it should be 24. can anyone see anything wrong with the code?

    function monthDiff(d1, d2) {
        var months;
        months = (d2.getFullYear() - d1.getFullYear()) * 12;
        months -= d1.getMonth() + 1;
        months += d2.getMonth();
        return months <= 0 ? 0 : months;
    }
    function daysInMonth(date) {
        return new Date(date.getYear(), date.getMonth() + 1, 0).getDate();
    }    
function diffDate(date1, date2) {
    if (date2 && date2.getTime() && !isNaN(date2.getTime())) {
        var months = monthDiff(d1, d2);
        var days = 0;

        if (date1.getUTCDate() >= date2.getUTCDate()) {
            days = date1.getUTCDate() - date2.getUTCDate();
        }
        else {
            months--;
            days = date1.getUTCDate() - date2.getUTCDate() + daysInMonth(date2);
        }

        // Use the variables months and days how you need them.
    }
}

Here's the var that uses the functions

var     months = monthDiff(new Date(), options.timestamp ) % 12 + 1,
        days = daysInMonth(new Date()),
Community
  • 1
  • 1
Krypton
  • 118
  • 12
  • I think I should be using the diffDate instead of daysInMonth but when I do it that way it will only show 0 – Krypton Sep 03 '16 at 13:39

3 Answers3

6

Try this code which is short, easy and accurate:

var _MS_PER_DAY = 1000 * 60 * 60 * 24;

// a and b are javascript Date objects
var a = new Date("7/13/2010");
var b = new Date("12/15/2010");

function dateDiffInDays(a, b) {
  // Discard the time and time-zone information.
  var utc1 = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate());
  var utc2 = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate());

  return Math.round((utc2 - utc1) / _MS_PER_DAY);
}
Abhijeet
  • 4,069
  • 1
  • 22
  • 38
  • Good idea. You will have a small problem on days when the time switches from DST to standard. On those days `utc2 - utc1` might give 23 or 25 hours. You can take care of that case by using `Math.round` instead of `Math.floor`. – redneb Sep 03 '16 at 13:46
  • Thanks for suggestion @redneb I will update my code accordingly – Abhijeet Sep 03 '16 at 13:47
  • Great answer and works great, however it counted the total number of days not the days remaining from months and years. – Krypton Sep 03 '16 at 15:55
2

I think that you might use moment.js

Don't reinvent the wheel again.

Just plug Moment.js Date Range Plugin.


Example:

var starts = moment('2014-02-03 12:53:12');
var ends   = moment();

var duration = moment.duration(ends.diff(starts));

// with ###moment precise date range plugin###
// it will tell you the difference in human terms

var diff = moment.preciseDiff(starts, ends, true); 
// example: { "years": 2, "months": 7, "days": 0, "hours": 6, "minutes": 29, "seconds": 17, "firstDateWasLater":  false }


// or as string:
var diffHuman = moment.preciseDiff(starts, ends);
// example: 2 years 7 months 6 hours 29 minutes 17 seconds

document.getElementById('output1').innerHTML = JSON.stringify(diff)
document.getElementById('output2').innerHTML = diffHuman
<html>
<head>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.14.1/moment.min.js"></script>

  <script src="https://raw.githubusercontent.com/codebox/moment-precise-range/master/moment-precise-range.js"></script>

</head>
<body>
  
  <h2>Difference between "NOW and 2014-02-03 12:53:12"</h2>
  <span id="output1"></span>
  <br />
  <span id="output2"></span>
  
</body>
</html>
Inanc Gumus
  • 25,195
  • 9
  • 85
  • 101
  • I did consider using moment.js, but doesn't it have a limit with showing Years Months and Days at the same time? – Krypton Sep 03 '16 at 16:38
  • You mean formatting? If so, no it doesn't. I've been using it for years with joy. – Inanc Gumus Sep 03 '16 at 16:38
  • http://stackoverflow.com/questions/17732897/difference-between-two-dates-in-years-months-days-in-javascript?rq=1 This question says that you can only use it for Days or years or months not all three? Is that formatting? – Krypton Sep 03 '16 at 16:41
  • That explanation in the question is wrong. Aren't you asking the day difference? What's your goal? – Inanc Gumus Sep 03 '16 at 16:43
  • All of the solutions here are trying to find the day difference, how're they different? – Inanc Gumus Sep 03 '16 at 16:47
  • The goal is the same as in the link I provided. To show the amount of years(total years) months(months left within the years) and days(days left until the end of the month) So it would show eg: 2 years 6 months and 10 days I was having trouble specifically with getting the days to work though. – Krypton Sep 03 '16 at 16:49
  • Not 2 years 24 months and 550 days. – Krypton Sep 03 '16 at 16:50
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/122581/discussion-between-inanc-and-krypton). – Inanc Gumus Sep 03 '16 at 17:06
  • @Krypton I updated the code according to your needs with a working example, best. – Inanc Gumus Sep 03 '16 at 17:26
  • @Krypton Is it OK? – Inanc Gumus Sep 03 '16 at 20:34
  • Seems to be, but I'm having trouble including the data. could you have a look at the chat log? the code I've tried is there :) – Krypton Sep 03 '16 at 20:38
  • @Krypton I'm on there right now :) – Inanc Gumus Sep 03 '16 at 20:47
1

Here is a function that will return the difference expressed in number of years, months and days:

function dateDiff(d1, d2) {
    var years = 0, months = 0, days = 0, arr;
    if (d1 > d2) { // call inverse
        interval = dateDiff(d2, d1);
        return {
            years: -interval.years, 
            months: -interval.months, 
            days: -interval.days
        };
    }
    days = d2.getDate() - d1.getDate();
    if (days < 0) {
        months--;
        days+= new Date(new Date(d2).setDate(0)).getDate();
    }
    months += d2.getMonth() - d1.getMonth();
    if (months < 0) {
        years--;
        months+=12;
    }
    years += d2.getFullYear() - d1.getFullYear();
    return {
        years: years, 
        months: months,
        days: days
    };
}

// Sample data
var d1 = new Date('2013-10-20');
var d2 = new Date('2016-12-16')
// Call
var interval = dateDiff(d1, d2);
// Output each number separately
console.log('Years: ', interval.years);
console.log('Months: ', interval.months);
console.log('Days: ', interval.days);
trincot
  • 317,000
  • 35
  • 244
  • 286
  • I think this is going to solve my problem but how would I use the data days, months, years individually? instead of all at once? – Krypton Sep 03 '16 at 14:36
  • The function returns an object with three properties. Just use the property that you need. Like `interval.years`. – trincot Sep 03 '16 at 14:37
  • Awesome :). This is probably a simple question but how would I get the value without the 'months:' part? – Krypton Sep 03 '16 at 15:52
  • How do you mean? You want the `days` to be something like 266 without splitting into months? – trincot Sep 03 '16 at 15:54
  • Or do you mean `console.log(interval.years, interval.days)`? It would not be an accurate representation if you would just drop the months part of course. – trincot Sep 03 '16 at 15:57
  • No it calculates everything right :) but when running the snipped it shows years: xxx months: xxx days: xxx How would you just show the xxx? Thanks for your help as well, I've accepted your answer :) – Krypton Sep 03 '16 at 15:59
  • The var that I'm using it in needs just the digits, does that make sense? Couldn't figure out why it wasn't working then I run the code and I'm like OH that's why! – Krypton Sep 03 '16 at 16:10
  • Well, like I said above, this is just a matter of working with an object. Just use the properties to get the numbers. I updated the snippet to show you how you can show the individual numbers. – trincot Sep 03 '16 at 16:39
  • Ah, I see! I'm really new to JS and you've helped me a lot. THANK YOU! – Krypton Sep 03 '16 at 16:43