Search code examples
javascriptdatesplitdate-formatdynamic-arrays

create array of array of datepairs that have gap of n days between them


Consider 2 dates, format will be MM/DD/YYYY

1st date = today 2nd date = 45 days from today

Note: Here, the 1st date and 2nd date are variable. i.e. 1st date that is today can be tomorrow or any other date. 2nd date can be 15 days, 24 days, 105 days i.e. this "n" can also vary.

Assuming the above 2 dates as startDate and stopDate. I want to create array of datePairs of a given gap between them.

For e.g. if startDate = 12/01/2022 & stopDate = 12/20/2022. I want to have datePairs having gap of 2 (n = 2) days between them. So, the output array should look like

[
    ['12/01/2022', '12/03/2022'],
    ['12/04/2022', '12/06/2022'],
    ['12/07/2022', '12/09/2022'],
    ['12/10/2022', '12/12/2022'],
    ['12/13/2022', '12/15/2022'],
    ['12/16/2022', '12/18/2022'],
    ['12/19/2022', '12/20/2022']
]

NOTE: Here, the last array does not have the gap of 2 dates because it's just 1 day away from the stopDate. In such case, the last pair can have less gap between them.

The only condition is the above array length should always be even.

Date.prototype.addDays = function (days) {
    var dat = new Date(this.valueOf());
    dat.setDate(dat.getDate() + days);
    return dat;
};

function splitInto(array, size, inplace) {
    var output, i, group;
    if (inplace) {
        output = array;
        for (i = 0; i < array.length; i++) {
            group = array.splice(i, size);
            output.splice(i, 0, group);
        }
    } else {
        output = [];
        for (i = 0; i < array.length; i += size) {
            output.push(array.slice(i, size + i));
        }
    }
    return output;
}

function getDates(startDate, stopDate) {
    var dateArray = new Array();
    var currentDate = startDate;
    var i = 0;
    while (currentDate <= stopDate) {
        if (i % 2 == 1) {
            const options = {
                year: 'numeric'
            };
            options.month = options.day = '2-digit';
            var formattedCSTDate = new Intl.DateTimeFormat([], options).format(currentDate);
            dateArray.push(formattedCSTDate);
            currentDate = currentDate.addDays(1);
        } else {
            const options = {
                year: 'numeric'
            };
            options.month = options.day = '2-digit';
            var formattedCSTDate = new Intl.DateTimeFormat([], options).format(currentDate);
            dateArray.push(formattedCSTDate);
            currentDate = currentDate.addDays(3);
        }
        i = i + 1;
    }
    return dateArray;
};
var dateArray = getDates(new Date(), (new Date()).addDays(43));
var datePairLength = 2;
var rangeArray = splitInto(dateArray, datePairLength, false);
console.log(rangeArray);

Solution

  • It seems to me you're making it more complicated than it needs to be. Just build each range as an array and avoid the splitInto function. You might use a date library (there are many to chose from) for adding days and formatting:

    function makeRanges(start = new Date(), end = new Date(), interval = 1) {
      let f = new Intl.DateTimeFormat('default', {
        year:'numeric',month:'short',day:'2-digit'
      });
      let s = new Date(start);
      let ranges = [];
      while (s < end) {
        let t = new Date(s);
        t.setDate(t.getDate() + interval);
        ranges.push([f.format(s), t < end? f.format(t) : f.format(end)]);
        s.setDate(s.getDate() + interval + 1)
      }
      return ranges;
    }
    console.log(
      makeRanges(new Date(2022,0,1), new Date(2022,1,1), 2)
    );