Javascript - получить массив дат между 2 датами - PullRequest
110 голосов
/ 11 декабря 2010
var range = getDates(new Date(), new Date().addDays(7));

Я бы хотел, чтобы «диапазон» был массивом объектов даты, по одному на каждый день между двумя датами.

Хитрость в том, что он должен обрабатывать границы месяца и года.

Ответы [ 20 ]

149 голосов
/ 11 декабря 2010
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;
}

Вот функционал демо http://jsfiddle.net/jfhartsock/cM3ZU/

39 голосов
/ 06 июля 2015

Попробуйте, не забудьте включить момент 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;
}
25 голосов
/ 08 апреля 2013

Я использую moment.js и Twix.js , они очень хорошо поддерживают манипуляции с датой и временем

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);

У меня это работает http://jsfiddle.net/Lkzg1bxb/

15 голосов
/ 17 мая 2018

Я посмотрел все выше. Закончил писать сам. Вам не нужны моменты для этого . Достаточно нативного цикла for , и это имеет смысл, поскольку цикл for существует для подсчета значений в диапазоне.

Один вкладыш:

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

Длинная версия

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

Список дат между:

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"
*/

Дней с прошедшей даты до настоящего момента:

var daylist = getDaysArray(new Date("2018-05-01"),new Date());
daylist.map((v)=>v.toISOString().slice(0,10)).join("")
15 голосов
/ 11 декабря 2010
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)
12 голосов
/ 11 декабря 2010
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;

}
8 голосов
/ 21 января 2018

Только что натолкнулся на этот вопрос, самый простой способ сделать это - использовать момент:

Сначала нужно установить диапазон момента и момента:

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)
6 голосов
/ 06 декабря 2018

Если вы используете момент, то вы можете использовать их «официальный плагин» для диапазонов moment-range, и тогда это становится тривиальным.

пример узла моментного диапазона:

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')))

Пример браузера с диапазоном моментов:

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 пример:

Если вы используете date-fns, то eachDay ваш друг, и вы получите самый короткий и краткий ответ:

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>
6 голосов
/ 03 сентября 2015

Я уже некоторое время пользуюсь решением @Mohammed Safeer и сделал несколько улучшений. Использование форматированных дат - плохая практика при работе в ваших контроллерах. moment().format() следует использовать только для отображения в представлениях. Также помните, что moment().clone() обеспечивает отделение от входных параметров, что означает, что входные даты не изменяются. Я настоятельно рекомендую вам использовать moment.js при работе с датами.

Использование:

  • Укажите даты moment.js в качестве значений для startDate, endDate параметров
  • interval параметр является необязательным и по умолчанию имеет значение «дни». Используйте интервалы, поддерживаемые методом .add() (moment.js). Подробнее здесь
  • total полезен при указании интервалов в минутах. По умолчанию 1. 1. 1019 *

Вызывать:

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

getDatesRangeArray(startDate, endDate, 'minutes', 30);

Функция:

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;
};
4 голосов
/ 19 марта 2015

Я недавно работал с moment.js, после чего добился цели.

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));

Результат будет:

["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"]
...