Javascript - get array of dates between 2 dates

313,098

Solution 1

function (startDate, endDate, addFn, interval) {

 addFn = addFn || Date.prototype.addDays;
 interval = interval || 1;

 var retVal = [];
 var current = new Date(startDate);

 while (current <= endDate) {
  retVal.push(new Date(current));
  current = addFn.call(current, interval);
 }

 return retVal;

}

Solution 2

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

function getDates(startDate, stopDate) {
    var dateArray = new Array();
    var currentDate = startDate;
    while (currentDate <= stopDate) {
        dateArray.push(new Date (currentDate));
        currentDate = currentDate.addDays(1);
    }
    return dateArray;
}

Here is a functional demo http://jsfiddle.net/jfhartsock/cM3ZU/

Solution 3

I looked all the ones above. Ended up writing myself. You do not need momentjs for this. A native for loop is enough and makes most sense because a for loop exists to count values in a range.

One Liner:

var getDaysArray = function(s,e) {for(var a=[],d=new Date(s);d<=new Date(e);d.setDate(d.getDate()+1)){ a.push(new Date(d));}return a;};

Long Version

var getDaysArray = function(start, end) {
    for(var arr=[],dt=new Date(start); dt<=new Date(end); dt.setDate(dt.getDate()+1)){
        arr.push(new Date(dt));
    }
    return arr;
};

List dates in between:

var daylist = getDaysArray(new Date("2018-05-01"),new Date("2018-07-01"));
daylist.map((v)=>v.toISOString().slice(0,10)).join("")
/*
Output: 
    "2018-05-01
    2018-05-02
    2018-05-03
    ...
    2018-06-30
    2018-07-01"
*/

Days from a past date until now:

var daylist = getDaysArray(new Date("2018-05-01"),new Date());
daylist.map((v)=>v.toISOString().slice(0,10)).join("")

Solution 4

Try this, remember to include moment js,

function getDates(startDate, stopDate) {
    var dateArray = [];
    var currentDate = moment(startDate);
    var stopDate = moment(stopDate);
    while (currentDate <= stopDate) {
        dateArray.push( moment(currentDate).format('YYYY-MM-DD') )
        currentDate = moment(currentDate).add(1, 'days');
    }
    return dateArray;
}

Solution 5

I use moment.js and Twix.js they provide a very great support for date and time manpulation

var itr = moment.twix(new Date('2012-01-15'),new Date('2012-01-20')).iterate("days");
var range=[];
while(itr.hasNext()){
    range.push(itr.next().toDate())
}
console.log(range);

I have this running on http://jsfiddle.net/Lkzg1bxb/

Share:
313,098

Related videos on Youtube

Scott Klarenbach
Author by

Scott Klarenbach

Updated on April 10, 2022

Comments

  • Scott Klarenbach
    Scott Klarenbach about 2 years
    var range = getDates(new Date(), new Date().addDays(7));
    

    I'd like "range" to be an array of date objects, one for each day between the two dates.

    The trick is that it should handle month and year boundaries as well.

  • Phrogz
    Phrogz over 13 years
    To be safe, unlike the above, you should usually choose a time in the middle of the day to avoid slight variations due to daylight-savings.
  • Scott Klarenbach
    Scott Klarenbach over 13 years
    Thanks John. I mostly used yours, but you have a byRef bug, in that currentDate can't get pushed onto the array or you'll end up with an array of n elements, all as the last date. Changing it to currentDate = new Date(currentDate) works.
  • vaibhav kulkarni
    vaibhav kulkarni almost 9 years
    I have download all the files related with it but still it shows the error TypeError: moment.twix is not a function
  • vaibhav kulkarni
    vaibhav kulkarni almost 9 years
    this is fine for the future date,But when I am working on past date like 30 days before where should i change the above code to get only date not time.
  • John Hartsock
    John Hartsock over 8 years
    @vaibhavkulkarni You can simply reverse the addays() prototype and modify the while loop. In addition, comments are not the place to start up a new question.
  • Adrian Moisa
    Adrian Moisa over 8 years
    Just a minor improvement: shorthand notation for creating arrays is recommended var dateArray = []; Details here
  • Mohammed Safeer
    Mohammed Safeer over 8 years
    It is the new way of defining arrays, and I suppose it is shorter/cleaner.
  • Adrian Moisa
    Adrian Moisa over 8 years
    Important fix: var currentDate = moment(startDate); In case you are using this method twice on the same moment.js dates you will be puzzled why it works just the first time. This happens because javascripts passes objects by reference so the function ends up using the startDate twice (which is allready mutated). Patching the above fix ensures that you are wroking with new and unique moment js objects in function scope. Check this fiddle
  • Hp93
    Hp93 almost 8 years
    Should we better remove time from startDate and endDate? Because if startDate's time is later than stopDate's time, it won't include stopDate in the result, right?
  • John Hartsock
    John Hartsock almost 8 years
    @Hp93 Not sure exactly what your talking about. If you run the fiddle I provided you will see that it covers that situation.
  • Hp93
    Hp93 almost 8 years
    I mean, if d2 = d1 +2 days and setHour(1,0,0,0). If so getDates(d1,d2) will only return 2 days and not include the third day. Of course it might be intent to work like this, but in my case, I want to get all days involved in. Here a fiddle based on your: fiddle
  • John Hartsock
    John Hartsock almost 8 years
    @Hp93 Your issue is fairly easy to account for if you simply remove the time element. I had the parameters for input described by OP and I followed them to assist a specific question. As for what your asking, simply remove the time element from the date.
  • Dr Bala Soundararaj
    Dr Bala Soundararaj over 7 years
    You might have to include the libraries. In nodejs it goes like, var moment = require('moment'); require('twix');
  • koceeng
    koceeng about 7 years
    Please add more description and/or information about your answer and how it solves the asked problem so others can easily understand it without asking for clarification
  • woodhead92
    woodhead92 almost 7 years
    I find this is skipping 2016-03-31 for some reason!
  • Erik Kubica
    Erik Kubica almost 7 years
    Does not work correctly for me. Skips few days. Like 1.1.2017, 1.2, 1.4, 1.5, 1.7. (m.d.y). any idea?
  • John Hartsock
    John Hartsock over 6 years
    Worked fine for me jsfiddle.net/cM3ZU/1326 have a look at the modified example. I believe you may be running into a formating issue with the dates. I am using m/d/yyyy as my format.
  • Janak Bhatta
    Janak Bhatta over 6 years
    nice but it will change startDate and stopDate alwo
  • Janak Bhatta
    Janak Bhatta over 6 years
    clone and send date Date.prototype.clone = function (): Date { return new Date(+this); }; otherwise start and stop date will also changed
  • chickens
    chickens almost 6 years
    I wish you'd also add middle of the day change to the code as well.
  • Saitama
    Saitama over 5 years
    What if you want to fetch all the days you specified in getDaysArray? Not the days between it.
  • mpsyp
    mpsyp over 5 years
    thanks! exactly what I needed with no dependencies. :)
  • Mike
    Mike about 5 years
    this doesn't take into consideration Daylight/Standard Savings Time changes.. some days are longer and some are shorter
  • Boris Yakubchik
    Boris Yakubchik over 4 years
    You should not have var before strDate inside the while loop!
  • Hamed Taheri
    Hamed Taheri over 4 years
    this function manipulates the source input date. :) I tested it.
  • RobG
    RobG over 4 years
    @HamedTaheri—yes, but that can be fixed by assigning a copy of start to dt rather than start itself, e.g. for (var arr=[], dt=new Date(start), ...). ;-)
  • RobG
    RobG over 4 years
    "Elegant" depends on your point of view. new Date(2017,12,30) is 30 Jan 2018, for me the date range starts on 29 Jan 2018. Not all days are 8.64e7 ms (24 hr) long where daylight saving is observed. ;-)
  • Victor
    Victor over 4 years
    working good, but too bad a for(;;) loop is not so readable to the software maintenance when you are working with a lot of other people.
  • Adam Pietrasiak
    Adam Pietrasiak over 4 years
    This would freeze if you provide dates in incorrect order
  • Albert MN.
    Albert MN. over 3 years
    It's worth noting that using moment.js is not longer recommended. Development on the project has stopped, and while it will still be maintained, the maintainers recommend finding an alternative.
  • Fire Druid
    Fire Druid over 3 years
    This function does not work when changing the clocks (summer to winter). For example, in Europe, with October 26 included, it will not return the correct array. This can be corrected by changing the while line to this : while (currentDate.setHours(0,0,0) <= stopDate.setHours(0,0,0))
  • Felix Wienberg
    Felix Wienberg over 3 years
    This won't work as expected when there is a time change in the date span (e.g. switch from summer time/DST to standard time). You'll end up with the last day missing. Can be prevented though by specifically setting the time.
  • Srinath Kamath
    Srinath Kamath over 3 years
    Works like a charm! However, I would make one more addition. dt<=end to dt<=new Date(end)
  • MarketerInCoderClothes
    MarketerInCoderClothes over 3 years
    Thank you for this. It's super useful. I eventually converted to ISO Strings before pushing into the array. I can see myself using this a lot in the future.
  • Arun A S
    Arun A S over 3 years
    Just adding a note that this won't work properly when time is specified along with the date. For example, getDates('2021-01-01 23:00:00','2021-01-04 22:00:00') returned ["2021-01-01", "2021-01-02", "2021-01-03"], this doesn't include 2021-01-04
  • Kimeiga
    Kimeiga about 3 years
    I think you can simplify this using toArray() instead of iterate(): moment.twix(new Date('2012-01-15'),new Date('2012-01-20')).toArray("days"); isaaccambron.com/twix.js/docs.html#toarray
  • Kanish
    Kanish almost 3 years
    new Date(currentDate).toString(); might help.
  • Paul Iverson Cortez
    Paul Iverson Cortez almost 3 years
    Works perfectly
  • ThisIsMyName
    ThisIsMyName almost 3 years
    Awesome mate! FYI, you have to use/install DayJs dependency. I added a .reverse() at the end to get the dates in an ascendent order!
  • Mads Hjorth
    Mads Hjorth over 2 years
    date fns has a breaking change from // v2.0.0 onward It is now eachDayOfInterval( { start: new Date(2014, 0, 10), end: new Date(2014, 0, 20) } )
  • luzmcosta
    luzmcosta over 2 years
    Thanks, May and ThisIsMyName. I was wondering how others were doing this. The only real edit I made was for ES6: [...Array(7)].map((_, i) => startOfWeek.add(i, 'day')), where startOfWeek is a dayjs object, e.g. dates.get(date).startOf('week').subtract(-1, 'week')
  • jave.web
    jave.web over 2 years
    does it return [] for you? ... you have to input date object e.g. like new Date("2021-03-01") not just "2021-03-01" for example :-) I missed this at first
  • puchu
    puchu over 2 years
    Works like charm for me :)
  • DanteDX
    DanteDX almost 2 years
    dayList.map(v => v.toISOString().split("T")[0]) this returns a nice array of all the dateStrings in between, pretty handy