javascriptjquerydate

Getting a list of all dates within a given date range in JavaScript


I am trying to figure out if there are any helper functions available or any techniques that might be helpful to get a list of dates within a given date range.

Lets say the user enters the following parameters which would be a 2 year contract:
Day: 15
StartDate: 1/15/2015
EndDate: 12/15/2016

I would expect the date for each month within that period including the start and end months to be returned:

1/15/2015
2/15/2015
3/15/2015
.....
1/15/2016
2/15/2016
3/15/2016
.....
12/15/2016

Solution

  • You need to use setMonth and getMonth methods:

    Note: As @RobG said in the comments, I made a mistake using a date format like this: 2015-12-01 for the example. The date format using - is not interpreted by all browsers. It is better use the / character instead.

    Note 2: October 18th 2024: The above note is not true anymore. The documentation states that dates using slashes are non-standard (even if they are accepted and work in all browsers).

    const start = new Date('2015-01-15');
    const end = new Date('2016-12-15');
    
    while (start <= end) {
        console.log( new Date(start) );
        start.setMonth( start.getMonth() + 1 );
    }

    A more dynamic solution:

    function getDatesBtween(from, to, day) {
    
      const fromDate = new Date(from);
      const toDate = new Date(to);
    
      fromDate.setDate(day);
      toDate.setDate(day);
    
      const dates = [];
    
      while (fromDate <= toDate) {
    
        dates.push(new Date(fromDate));
    
        fromDate.setMonth(fromDate.getMonth() + 1);
    
      }
    
      return dates;
    
    }
    
    const dates = getDatesBtween('2015-01-15', '2016-12-15', 15);
    
    console.log(dates);

    Note: As @HBP has mentioned in the comments, the above solution does not take in account edge cases and it does not work with the last days of a month (29th, 30th and 31st days of the month). For example 2015/02/31 = 2015/03/03 in some cases and 2015/03/02 in others (in leap years). The next solution solves this problem:

    function DateManager() {
    
      // Create a date with specific day
      function setDate(date, day) {
    
        date = new Date(date);
        date.setDate(day);
        date.setHours(23);
    
        return date;
    
      }
    
      // Generate dates method
      this.getDatesBetween = function(date1, date2, day) {
    
        const range1 = new Date(date1);
        const range2 = new Date(date2);
        const dates = [];
        let temp = null;
        
        date1 = setDate(date1, day);
        date2 = setDate(date2, day);
    
        while (date1 <= date2) {
    
          if (date1.getDate() != day) {
    
            temp = setDate(date1, 0);
    
            if (temp >= range1 && temp <= range2) dates.push(temp);
    
            date1 = setDate(date1, day);
    
          } else {
    
            temp = new Date(date1);
    
            if (temp >= range1 && temp <= range2) dates.push(temp);
    
            date1.setMonth(date1.getMonth() + 1);
    
          }
    
        }
    
        return dates;
    
      };
    
    }
    
    const manager = new DateManager();
    const dates = manager.getDatesBetween('2015-01-15', '2016-12-15', 31);
    
    console.log(dates);

    The result will be something like:

    2015/01/31
    2015/02/28
    2015/03/31
    2015/04/30
    2015/05/31
    ...
    2016/02/29
    ...
    2016/11/30