Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to enumerate dates between two dates in Moment

I have two moment dates:

var fromDate = moment(new Date('1/1/2014'));
var toDate   = moment(new Date('6/1/2014'));

Does moment provide a way to enumerate all of the dates between these two dates?

If not, is there any better solution other than to make a loop which increments the fromDate by 1 until it reaches the toDate?

Edit: Adding date enumeration method and problem

I've mocked up a method for enumerating the days between two dates, but I'm running into an issue.

  var enumerateDaysBetweenDates = function(startDate, endDate) {
    var dates = [];

    startDate = startDate.add(1, 'days');

    while(startDate.format('M/D/YYYY') !== endDate.format('M/D/YYYY')) {
      console.log(startDate.toDate());
      dates.push(startDate.toDate());
      startDate = startDate.add(1, 'days');
    }

    return dates;
  };

Take a look at the output when I run enumerateDaysBetweenDates( moment(new Date('1/1/2014')), moment(new Date('1/5/2014'));

Thu Jan 02 2014 00:00:00 GMT-0800 (PST)
Fri Jan 03 2014 00:00:00 GMT-0800 (PST)
Sat Jan 04 2014 00:00:00 GMT-0800 (PST)
[ Sun Jan 05 2014 00:00:00 GMT-0800 (PST),
  Sun Jan 05 2014 00:00:00 GMT-0800 (PST),
  Sun Jan 05 2014 00:00:00 GMT-0800 (PST) ]

It's console.logging the right dates, but only the final date is being added to the array. How/why is this? This smells like some sort of variable reference issue - but I'm not seeing it.

like image 393
doremi Avatar asked May 21 '14 23:05

doremi


People also ask

How do you find the date between two dates in a moment?

To enumerate dates between two dates in Moment and JavaScript, we use a while loop. const enumerateDaysBetweenDates = (startDate, endDate) => { const now = startDate. clone(); const dates = []; while (now. isSameOrBefore(endDate)) { dates.

How do you find the number of days in a month with moments?

The moment(). daysInMonth() function is used to get the number of days in month of a particular month in Node.

Is between Momentjs?

Is Between - momentjs.com. Check if a moment is between two other moments, optionally looking at unit scale (minutes, hours, days, etc). The match is exclusive. The first two arguments will be parsed as moments, if not already so.


2 Answers

.add() is a mutator method, so the assignment in this line is unnecessary:

startDate = startDate.add(1, 'days');

You can just do this, and have the same effect:

startDate.add(1, 'days');

While it's name would imply the creation of a new Date object, the toDate() method really just returns the existing internal Date object.

So, none of your method calls are creating new Date or moment object instances. Fix that by using .clone() to get a new instance:

startDate = startDate.clone().add(1, 'days');

Or better yet, wrap the values in a call to moment() as Mtz suggests in a comment, and it will clone the instance, if the value is a moment object, or it will parse the input to create a new moment instance.

startDate = moment(startDate).add(1, 'days');

I think a date enumerator method should not change either of the arguments passed in. I'd create a separate variable for enumerating. I'd also compare the dates directly, rather than comparing strings:

var enumerateDaysBetweenDates = function(startDate, endDate) {
    var dates = [];

    var currDate = moment(startDate).startOf('day');
    var lastDate = moment(endDate).startOf('day');

    while(currDate.add(1, 'days').diff(lastDate) < 0) {
        console.log(currDate.toDate());
        dates.push(currDate.clone().toDate());
    }

    return dates;
};
like image 61
gilly3 Avatar answered Oct 12 '22 21:10

gilly3


Got it for you:

var enumerateDaysBetweenDates = function(startDate, endDate) {
    var now = startDate.clone(), dates = [];

    while (now.isSameOrBefore(endDate)) {
        dates.push(now.format('M/D/YYYY'));
        now.add(1, 'days');
    }
    return dates;
};

Referencing now rather than startDate made all the difference.

If you're not after an inclusive search then change .isSameOrBefore to .isBefore

Fiddle: http://jsfiddle.net/KyleMuir/sRE76/118/

like image 48
Kyle Muir Avatar answered Oct 12 '22 21:10

Kyle Muir