Javascript - get array of dates between 2 dates
Javascriptnode.jsDateDatetimeDate RangeJavascript Problem Overview
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.
Javascript Solutions
Solution 1 - Javascript
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 2 - Javascript
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 3 - Javascript
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 4 - Javascript
I use [moment.js][1] and [Twix.js][2] 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/ [1]: http://momentjs.com [2]: http://icambron.github.io/twix.js/#home
Solution 5 - Javascript
var boxingDay = new Date("12/26/2010");
var nextWeek = boxingDay*1 + 7*24*3600*1000;
function getDates( d1, d2 ){
var oneDay = 24*3600*1000;
for (var d=[],ms=d1*1,last=d2*1;ms<last;ms+=oneDay){
d.push( new Date(ms) );
}
return d;
}
getDates( boxingDay, nextWeek ).join("\n");
// Sun Dec 26 2010 00:00:00 GMT-0700 (Mountain Standard Time)
// Mon Dec 27 2010 00:00:00 GMT-0700 (Mountain Standard Time)
// Tue Dec 28 2010 00:00:00 GMT-0700 (Mountain Standard Time)
// Wed Dec 29 2010 00:00:00 GMT-0700 (Mountain Standard Time)
// Thu Dec 30 2010 00:00:00 GMT-0700 (Mountain Standard Time)
// Fri Dec 31 2010 00:00:00 GMT-0700 (Mountain Standard Time)
// Sat Jan 01 2011 00:00:00 GMT-0700 (Mountain Standard Time)
Solution 6 - Javascript
If you are using moment then you can use their "official plugin" for ranges moment-range
and then this becomes trivial.
moment-range node example:
const Moment = require('moment');
const MomentRange = require('moment-range');
const moment = MomentRange.extendMoment(Moment);
const start = new Date("11/30/2018"), end = new Date("09/30/2019")
const range = moment.range(moment(start), moment(end));
console.log(Array.from(range.by('day')))
moment-range browser example:
window['moment-range'].extendMoment(moment);
const start = new Date("11/30/2018"), end = new Date("09/30/2019")
const range = moment.range(moment(start), moment(end));
console.log(Array.from(range.by('day')))
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-range/4.0.1/moment-range.js"></script>
date fns example:
If you are using date-fns
then eachDay
is your friend and you get by far the shortest and most concise answer:
console.log(dateFns.eachDay(
new Date(2018, 11, 30),
new Date(2019, 30, 09)
))
<script src="https://cdnjs.cloudflare.com/ajax/libs/date-fns/1.29.0/date_fns.min.js"></script>
Solution 7 - Javascript
I had trouble using the answers above. The date ranges were missing single days due to timezone shift caused by the local day light saving time (DST). I implemented a version using UTC dates that fixes that problem:
function dateRange(startDate, endDate, steps = 1) {
const dateArray = [];
let currentDate = new Date(startDate);
while (currentDate <= new Date(endDate)) {
dateArray.push(new Date(currentDate));
// Use UTC date to prevent problems with time zones and DST
currentDate.setUTCDate(currentDate.getUTCDate() + steps);
}
return dateArray;
}
const dates = dateRange('2020-09-27', '2020-10-28');
console.log(dates);
Note: Whether a certain timezone or DST is applied, depends entirely on your locale. Overriding this is generally not a good idea. Using UTC dates mitigates most of the time related problems.
Bonus: You can set the time interval for which you want to create timestamps with the optional steps
parameter. If you want weekly timetamps set steps
to 7
.
Solution 8 - Javascript
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 9 - Javascript
Using ES6 you have Array.from meaning you can write a really elegant function, that allows for dynamic Intervals (hours, days, months).
function getDates(startDate, endDate, interval) { const duration = endDate - startDate; const steps = duration / interval; return Array.from({length: steps+1}, (v,i) => new Date(startDate.valueOf() + (interval * i))); } const startDate = new Date(2017,12,30); const endDate = new Date(2018,1,3); const dayInterval = 1000 * 60 * 60 * 24; // 1 day const halfDayInterval = 1000 * 60 * 60 * 12; // 1/2 day
console.log("Days", getDates(startDate, endDate, dayInterval)); console.log("Half Days", getDates(startDate, endDate, halfDayInterval));
Solution 10 - Javascript
Just came across this question, the easiest way to do this is using moment:
You need to install moment and moment-range first:
const Moment = require('moment');
const MomentRange = require('moment-range');
const moment = MomentRange.extendMoment(Moment);
const start = moment()
const end = moment().add(2, 'months')
const range = moment.range(start, end)
const arrayOfDates = Array.from(range.by('days'))
console.log(arrayOfDates)
Solution 11 - Javascript
I was recently working with moment.js, following did the trick..
function getDateRange(startDate, endDate, dateFormat) {
var dates = [],
end = moment(endDate),
diff = endDate.diff(startDate, 'days');
if(!startDate.isValid() || !endDate.isValid() || diff <= 0) {
return;
}
for(var i = 0; i < diff; i++) {
dates.push(end.subtract(1,'d').format(dateFormat));
}
return dates;
};
console.log(getDateRange(startDate, endDate, dateFormat));
Result would be:
["09/03/2015", "10/03/2015", "11/03/2015", "12/03/2015", "13/03/2015", "14/03/2015", "15/03/2015", "16/03/2015", "17/03/2015", "18/03/2015"]
Solution 12 - Javascript
I have been using @Mohammed Safeer solution for a while and I made a few improvements. Using formated dates is a bad practice while working in your controllers. moment().format()
should be used only for display purposes in views. Also remember that moment().clone()
ensures separation from input parameters, meaning that the input dates are not altered. I strongly encourage you to use moment.js when working with dates.
Usage:
- Provide moment.js dates as values for
startDate
,endDate
parameters interval
parameter is optional and defaults to 'days'. Use intervals suported by.add()
method (moment.js). More details heretotal
parameter is useful when specifying intervals in minutes. It defaults to 1.
Invoke:
var startDate = moment(),
endDate = moment().add(1, 'days');
getDatesRangeArray(startDate, endDate, 'minutes', 30);
Function:
var getDatesRangeArray = function (startDate, endDate, interval, total) {
var config = {
interval: interval || 'days',
total: total || 1
},
dateArray = [],
currentDate = startDate.clone();
while (currentDate < endDate) {
dateArray.push(currentDate);
currentDate = currentDate.clone().add(config.total, config.interval);
}
return dateArray;
};
Solution 13 - Javascript
I'm using simple while loop to calculate the between dates
var start = new Date("01/05/2017");
var end = new Date("06/30/2017");
var newend = end.setDate(end.getDate()+1);
end = new Date(newend);
while(start < end){
console.log(new Date(start).getTime() / 1000); // unix timestamp format
console.log(start); // ISO Date format
var newDate = start.setDate(start.getDate() + 1);
start = new Date(newDate);
}
Solution 14 - Javascript
var listDate = [];
var startDate ='2017-02-01';
var endDate = '2017-02-10';
var dateMove = new Date(startDate);
var strDate = startDate;
while (strDate < endDate){
var strDate = dateMove.toISOString().slice(0,10);
listDate.push(strDate);
dateMove.setDate(dateMove.getDate()+1);
};
console.log(listDate);
//["2017-02-01", "2017-02-02", "2017-02-03", "2017-02-04", "2017-02-05", "2017-02-06", "2017-02-07", "2017-02-08", "2017-02-09", "2017-02-10"]
Solution 15 - Javascript
I use this function
function getDatesRange(startDate, stopDate) {
const ONE_DAY = 24*3600*1000;
var days= [];
var currentDate = new Date(startDate);
while (currentDate <= stopDate) {
days.push(new Date (currentDate));
currentDate = currentDate - 1 + 1 + ONE_DAY;
}
return days;
}
Solution 16 - Javascript
You can do it easily using momentJS
Add moment to your dependencies
npm i moment
Then import that in your file
var moment = require("moment");
Then use the following code to get the list of all dates between two dates
let dates = [];
let currDate = moment.utc(new Date("06/30/2019")).startOf("day");
let lastDate = moment.utc(new Date("07/30/2019")).startOf("day");
do {
dates.push(currDate.clone().toDate());
} while (currDate.add(1, "days").diff(lastDate) < 0);
dates.push(currDate.clone().toDate());
console.log(dates);
Solution 17 - Javascript
d3js provides a lot of handy functions and includes d3.time for easy date manipulations
For your specific request:
Utc
var range = d3.utcDay.range(new Date(), d3.utcDay.offset(new Date(), 7));
or local time
var range = d3.timeDay.range(new Date(), d3.timeDay.offset(new Date(), 7));
range will be an array of date objects that fall on the first possible value for each day
you can change timeDay to timeHour, timeMonth etc for the same results on different intervals
Solution 18 - Javascript
Here's a one liner that doesn't require any libraries in-case you don't want to create another function. Just replace startDate (in two places) and endDate (which are js date objects) with your variables or date values. Of course you could wrap it in a function if you prefer
Array(Math.floor((endDate - startDate) / 86400000) + 1).fill().map((_, idx) => (new Date(startDate.getTime() + idx * 86400000)))
Solution 19 - Javascript
This is how i like to do it
// hours * minutes * seconds * milliseconds
const DAY_IN_MS = 24 * 60 * 60 * 1000
/**
* Get range of dates
* @param {Date} startDate
* @param {Number} numOfDays
* @returns {array}
*/
const dateRange = (startDate, numOfDays) => {
const startDateMs = startDate.getTime()
// get array of days and map it to Date object
return [...Array(numOfDays).keys()].map(i => new Date(startDateMs + i * DAY_IN_MS))
}
Solution 20 - Javascript
Note: I'm aware this is slightly different than the requested solution, but I think many will find it useful.
If you want to find each "x" intervals (days, months, years, etc...) between two dates, moment.js and the moment-range extension packages enable this functionality.
For example, to find each 30th day between two dates:
window['moment-range'].extendMoment(moment);
var dateString = "2018-05-12 17:32:34.874-08";
var start = new Date(dateString);
var end = new Date();
var range1 = moment.range(start, end);
var arrayOfIntervalDates = Array.from(range1.by('day', { step: 30 }));
arrayOfIntervalDates.map(function(intervalDate){
console.log(intervalDate.format('YY-M-DD'))
});
Solution 21 - Javascript
@softvar's solution, but then including working dates option
/**
* Returns array of working days between two dates.
*
* @param {string} startDate
* The start date in yyyy-mm-dd format.
* @param {string} endDate
* The end date in yyyy-mm-dd format.
* @param {boolean} onlyWorkingDays
* If true only working days are returned. Default: false
*
* @return {array}
* Array of dates in yyyy-mm-dd string format.
*/
function getDates(startDate, stopDate, onlyWorkingDays) {
let doWd = typeof onlyWorkingDays ==='undefined' ? false : onlyWorkingDays;
let dateArray = [];
let dayNr;
let runDateObj = moment(startDate);
let stopDateObj = moment(stopDate);
while (runDateObj <= stopDateObj) {
dayNr = runDateObj.day();
if (!doWd || (dayNr>0 && dayNr<6)) {
dateArray.push(moment(runDateObj).format('YYYY-MM-DD'));
}
runDateObj = moment(runDateObj).add(1, 'days');
}
return dateArray;
}
Solution 22 - Javascript
-
Generate an array of years:
const DAYS = () => { const days = [] const dateStart = moment() const dateEnd = moment().add(30, ‘days') while (dateEnd.diff(dateStart, ‘days') >= 0) { days.push(dateStart.format(‘D')) dateStart.add(1, ‘days') } return days } console.log(DAYS())
-
Generate an arrays for month:
const MONTHS = () => { const months = [] const dateStart = moment() const dateEnd = moment().add(12, ‘month') while (dateEnd.diff(dateStart, ‘months') >= 0) { months.push(dateStart.format(‘M')) dateStart.add(1, ‘month') } return months } console.log(MONTHS())
-
Generate an arrays for days:
const DAYS = () => { const days = [] const dateStart = moment() const dateEnd = moment().add(30, ‘days') while (dateEnd.diff(dateStart, ‘days') >= 0) { days.push(dateStart.format(‘D')) dateStart.add(1, ‘days') } return days } console.log(DAYS())
Solution 23 - Javascript
Array(7).fill().map((_,i) => dayjs().subtract(i, "day").format("YYYY-MM-DD"));
Solution 24 - Javascript
That's another few lines solution using date-fns library:
const { format, differenceInDays, addDays } = dateFns;
const getRangeDates = (startDate, endDate) => {
const days = differenceInDays(endDate, startDate);
console.log([...Array(days + 1).keys()].map((i) => format(addDays(startDate, i), 'YYYY-MM-DD')));
};
getRangeDates('2021-06-01', '2021-06-05');
<script src="https://cdnjs.cloudflare.com/ajax/libs/date-fns/1.30.1/date_fns.js"></script>
Solution 25 - Javascript
This may help someone,
> You can get the row output from this and format the row_date object as you want.
var from_date = '2016-01-01';
var to_date = '2016-02-20';
var dates = getDates(from_date, to_date);
console.log(dates);
function getDates(from_date, to_date) {
var current_date = new Date(from_date);
var end_date = new Date(to_date);
var getTimeDiff = Math.abs(current_date.getTime() - end_date.getTime());
var date_range = Math.ceil(getTimeDiff / (1000 * 3600 * 24)) + 1 ;
var weekday = ["SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"];
var months = ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"];
var dates = new Array();
for (var i = 0; i <= date_range; i++) {
var getDate, getMonth = '';
if(current_date.getDate() < 10) { getDate = ('0'+ current_date.getDate());}
else{getDate = current_date.getDate();}
if(current_date.getMonth() < 9) { getMonth = ('0'+ (current_date.getMonth()+1));}
else{getMonth = current_date.getMonth();}
var row_date = {day: getDate, month: getMonth, year: current_date.getFullYear()};
var fmt_date = {weekDay: weekday[current_date.getDay()], date: getDate, month: months[current_date.getMonth()]};
var is_weekend = false;
if (current_date.getDay() == 0 || current_date.getDay() == 6) {
is_weekend = true;
}
dates.push({row_date: row_date, fmt_date: fmt_date, is_weekend: is_weekend});
current_date.setDate(current_date.getDate() + 1);
}
return dates;
}
https://gist.github.com/pranid/3c78f36253cbbc6a41a859c5d718f362.js
Solution 26 - Javascript
Here's a canned method that will accept Moment dates or strings or a mixture as inputs and generate an array of dates as Moment dates. If you don't want Moment dates as output then change what the map()
method returns.
const moment = require('moment');
// ...
/**
* @param {string|import('moment').Moment} start
* @param {string|import('moment').Moment} end
* @returns {import('moment').Moment[]}
*/
const getDateRange = (start, end) => {
const s = moment.isMoment(start) ? start : moment(start);
const e = moment.isMoment(end) ? end : moment(end);
return [...Array(1 + e.diff(s, 'days')).keys()].map(n => moment(s).add(n, 'days'));
};
Solution 27 - Javascript
Function:
var dates = [],
currentDate = startDate,
addDays = function(days) {
var date = new Date(this.valueOf());
date.setDate(date.getDate() + days);
return date;
};
while (currentDate <= endDate) {
dates.push(currentDate);
currentDate = addDays.call(currentDate, 1);
}
return dates;
};
Usage:
var dates = getDatesRange(new Date(2019,01,01), new Date(2019,01,25));
dates.forEach(function(date) {
console.log(date);
});
Hope it helps you
Solution 28 - Javascript
Using lodash & moment:
const startDate = moment();
_.range(0, 7).map((d) => startDate.clone().add(d, 'day').toDate())
Solution 29 - Javascript
getDates = (from, to) => {
const cFrom = new Date(from);
const cTo = new Date(to);
let daysArr = [new Date(cFrom)];
let tempDate = cFrom;
while (tempDate < cTo) {
tempDate.setUTCDate(tempDate.getUTCDate() + 1);
daysArr.push(new Date(tempDate));
}
return daysArr;
}
Solution 30 - Javascript
Not a shortest possible but easy, immutable and without dependencies
function datesArray(start, end) {
let result = [], current = new Date(start);
while (current <= end)
result.push(current) && (current = new Date(current)) && current.setDate(current.getDate() + 1);
return result;
}
Usage
function datesArray(start, end) { let result = [], current = new Date(start); while (current <= end) result.push(current) && (current = new Date(current)) && current.setDate(current.getDate() + 1); return result; }
// Usage
const test = datesArray(
new Date('2020-02-26'),
new Date('2020-03-05')
);
for (let i = 0; i < test.length; i ++ ) {
console.log(
test[i].toISOString().slice(0,10)
);
}
Solution 31 - Javascript
Using JavaScript
const getDatesBetween = (startDate, endDate, includeEndDate) => {
const dates = [];
const currentDate = startDate;
while (currentDate < endDate) {
dates.push(new Date(currentDate));
currentDate.setDate(currentDate.getDate() + 1);
}
if (includeEndDate) dates.push(endDate);
return dates;
};
Using TypeScript
const getDatesBetween = (
startDate: Date,
endDate: Date,
includeEndDate?: boolean
) => {
const dates = [];
const currentDate = startDate;
while (currentDate < endDate) {
dates.push(new Date(currentDate));
currentDate.setDate(currentDate.getDate() + 1);
}
if (includeEndDate) dates.push(endDate);
return dates;
};
Example
console.log(getDatesBetween(new Date(2020, 0, 1), new Date(2020, 0, 3)));
console.log(getDatesBetween(new Date(2020, 0, 1), new Date(2020, 0, 3), true));