Bhav
Bhav

Reputation: 2207

Using moment to calculate the number of days between 2 dates

I'm trying to work out the number of days between 2 dates in Javascript with the following code.

    console.log(self.StartDate());
    var start = moment(self.StartDate(), "YYYY-MM-DD");
    console.log(start);
    console.log(self.EndDate());
    var end = moment(self.EndDate(), "YYYY-MM-DD");
    console.log(end);
    var duration = moment.duration(start.diff(end));
    console.log(duration);

    //no of days between start and end
    console.log(duration.asDays());

console output:

Thu Jun 20 2019 01:00:00 GMT+0100 (British Summer Time)
n {_isAMomentObject: true, _i: Thu Jun 20 2019 01:00:00 GMT+0100 (British Summer Time), _f: "YYYY-MM-DD", _isUTC: false, _pf: {…}, …}_d: Wed Aug 19 0020 00:00:00 GMT-0001 (British Summer Time) {}_f: "YYYY-MM-DD"_i: Thu Jun 20 2019 01:00:00 GMT+0100 (British Summer Time) {}_isAMomentObject: true_isUTC: false_locale: r {_ordinalParse: /\d{1,2}(th|st|nd|rd)/, ordinal: ƒ, _abbr: "en", _ordinalParseLenient: /\d{1,2}(th|st|nd|rd)|\d{1,2}/}_pf: {empty: false, unusedTokens: Array(0), unusedInput: Array(3), overflow: 1, charsLeftOver: 49, …}__proto__: Object
Mon Jun 24 2019 15:10:41 GMT+0100 (British Summer Time)
n {_isAMomentObject: true, _i: Mon Jun 24 2019 15:10:41 GMT+0100 (British Summer Time), _f: "YYYY-MM-DD", _isUTC: false, _pf: {…}, …}
Ea {_milliseconds: -126230400000, _days: 0, _months: 0, _data: {…}, _locale: r}
-1461

self.StartDate() is 20/06/2019 and self.EndDate() is 24/06/2019 so I'm exciting the alert to display 4 however it displays -1461.

Why is this the case?

Upvotes: 0

Views: 1323

Answers (3)

yunzen
yunzen

Reputation: 33449

Your code should work perfectly fine. You should only swap start and end at the defference calculation to get positive values.

var startDate = moment("2019-06-20", "YYYY-MM-DD");
var endDate = moment("2019-06-24", "YYYY-MM-DD");
var duration = moment.duration(startDate.diff(endDate));

//no of days between start and end
console.log(duration.asDays());


var duration = moment.duration(endDate.diff(startDate));
console.log(duration.asDays());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.js"></script>

If you are only interested in the difference calculated in days, this code will be shorter:

var startDate = moment("2019-06-20", "YYYY-MM-DD");
var endDate = moment("2019-06-24", "YYYY-MM-DD");
var diff  = startDate.diff(endDate, 'days');
console.log(diff);


var diff  = endDate.diff(startDate, 'days');
console.log(diff);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.js"></script>

There has to be some issue with the dates themselves.
And in fact, it's the way you parse the date strings

// This is parsed as the 19th day of 6th month in year 2020
var startDate = moment("20/06/2019", "YYYY-MM-DD");
// This is parsed as the 19th day of 6th month in year 2024
var endDate = moment("24/06/2019", "YYYY-MM-DD");
var diff  = endDate.diff(startDate, 'days');
console.log({"start": startDate, "end": endDate, "diff": diff});

// You either need to change the date strings or the format strings
var startDate = moment("20/06/2019", "DD/MM/YYYY");
var endDate = moment("24/06/2019", "DD/MM/YYYY");
var diff  = endDate.diff(startDate, 'days');
console.log({"start": startDate, "end": endDate, "diff": diff});


// You either need to change the date strings or the format strings
var startDate = moment("2019-06-20", "YYYY-MM-DD");
var endDate = moment("2019-06-24", "YYYY-MM-DD");
var diff  = endDate.diff(startDate, 'days');
console.log({"start": startDate, "end": endDate, "diff": diff});
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.js"></script>

Upvotes: 0

Liron Navon
Liron Navon

Reputation: 1097

Your date is invalid, you specified a start date of "20/06/2019" which is a template of "DD/MM/YYYY", but told moment to use the template of "YYYY-MM-DD".

You simply need to replace the template that you pass to moment, and here is a bit cleaner way to do it:

const DEFAULT_DATE_TEMPLATE = "DD/MM/YYYY";

const getDaysBetweenDates = (date1, date2, dateTemplate = DEFAULT_DATE_TEMPLATE) => {
    const start = moment(date1, dateTemplate);
    const end = moment(date2, dateTemplate);
    const duration = moment.duration(start.diff(end));
    const daysDiff = duration.asDays();

    // for your example you will get -4, abs will make it into 4 for you
    return Math.abs(daysDiff); 
}


const myDiff = getDaysBetweenDates('20/06/2019', '24/06/2019');
console.log(myDiff); // 4

// or if you rather keep your other template
const myDiff2 = getDaysBetweenDates('2019-06-20', '2019-06-24', 'YYYY-MM-DD');
console.log(myDiff2); // 4

Upvotes: -1

VLAZ
VLAZ

Reputation: 29116

The problem is that your dates are not formatted the way you tell moment.js they are. 20/06/2019 is DD/MM/YYYY and not YYYY-MM-DD. As per the documentation, non-numeric characters are ignored so 20/06/2019 would be parsed as 2006-20-19. Since such a date does not exist, Moment.js tries to guess what you actually meant and it comes up with 2020-06-19:

var start = moment("20/06/2019", "YYYY-MM-DD");

console.log(start);
<script src="https://cdn.jsdelivr.net/momentjs/2.14.1/moment-with-locales.min.js"></script>

Same thing happens with the end date.

You need to either change the format you tell to Moment.js or fix the start and end dates to use the format you specified, in both cases, you'd get the correct result:

var self = {
    StartDate: () => "20/06/2019",
    EndDate: () => "24/06/2019"
}

var start = moment(self.StartDate(), "DD/MM/YYYY"); //using the correct format
var end = moment(self.EndDate(), "DD/MM/YYYY");
var duration = moment.duration(start.diff(end));

console.log(duration.asDays());
<script src="https://cdn.jsdelivr.net/momentjs/2.14.1/moment-with-locales.min.js"></script>

var self = {
    StartDate: () => "2019-06-20", //using dates in the correct format
    EndDate: () => "2019-06-24"
}

var start = moment(self.StartDate(), "YYYY-MM-DD");
var end = moment(self.EndDate(), "YYYY-MM-DD");
var duration = moment.duration(start.diff(end));

console.log(duration.asDays());
<script src="https://cdn.jsdelivr.net/momentjs/2.14.1/moment-with-locales.min.js"></script>

Upvotes: 2

Related Questions