var range = getDates(new Date(), new Date().addDays(7));
Я бы хотел, чтобы «диапазон» был массивом объектов даты, по одному на каждый день между двумя датами.
Хитрость заключается в том, что он должен обрабатывать границы месяца и года.
var range = getDates(new Date(), new Date().addDays(7));
Я бы хотел, чтобы «диапазон» был массивом объектов даты, по одному на каждый день между двумя датами.
Хитрость заключается в том, что он должен обрабатывать границы месяца и года.
Ответы:
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/
startDate
и endDate
? Потому что, если startDate
время позже, чем stopDate
время, оно не будет включено stopDate
в результат, верно?
Попробуйте это, не забудьте включить момент 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;
}
var dateArray = [];
Подробности здесь
var currentDate = moment(startDate);
если вы используете этот метод дважды в один и тот же день moment.js, вы будете удивлены, почему он работает только в первый раз. Это происходит потому, что javascripts передает объекты по ссылке, поэтому функция в конце дважды использует startDate (которая уже мутирована). Исправление вышеупомянутого исправления гарантирует, что вы работаете с новыми и уникальными моментами js объектов в области действия функции. Проверьте эту скрипку
Я посмотрел все выше. Закончил писать сам. Вам не нужны моменты для этого . Достаточно встроенного цикла for, и оно имеет больше смысла, поскольку существует цикл for для подсчета значений в диапазоне.
Один лайнер:
var getDaysArray = function(s,e) {for(var a=[],d=new Date(s);d<=e;d.setDate(d.getDate()+1)){ a.push(new Date(d));}return a;};
Длинная версия
var getDaysArray = function(start, end) {
for(var arr=[],dt=new Date(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("")
getDaysArray
? Не дни между ними.
for (var arr=[], dt=new Date(start), ...)
. ;-)
Я использую 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/
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)
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;
}
Если вы используете момент, то вы можете использовать их «официальный плагин» для диапазонов 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>
пример даты 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>
Просто наткнулся на этот вопрос, самый простой способ сделать это - использовать момент:
Сначала нужно установить момент и диапазон моментов:
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)
Некоторое время я использовал решение @Mohammed Safeer и внес несколько улучшений. Использование форматированных дат - плохая практика при работе в ваших контроллерах. moment().format()
следует использовать только для отображения в представлениях. Также помните, что это moment().clone()
обеспечивает отделение от входных параметров, а это означает, что даты ввода не изменяются. Я настоятельно рекомендую вам использовать moment.js при работе с датами.
Использование:
startDate
, endDate
параметровinterval
параметр является необязательным и по умолчанию устанавливается в «дни». Используйте интервалы, поддерживаемые .add()
методом (moment.js). Подробнее здесьtotal
Параметр полезен при указании интервалов в минутах. По умолчанию это 1.Invoke:
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;
};
Используя ES6, вы получаете Array.from, что означает, что вы можете написать действительно элегантную функцию, которая учитывает динамические интервалы (часы, дни, месяцы).
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));
new Date(2017,12,30)
30 января 2018 года, для меня диапазон дат начинается 29 января 2018 года. Не все дни имеют продолжительность 8,64e7 мс (24 часа), когда наблюдается переход на летнее время. ;-)
Я недавно работал с 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"]
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"]
var
раньше strDate
внутри цикла while!
d3js предоставляет множество удобных функций и включает d3.time для легкой манипуляции с датой
Для вашего конкретного запроса:
Универсальное глобальное время
var range = d3.utcDay.range(new Date(), d3.utcDay.offset(new Date(), 7));
или местное время
var range = d3.timeDay.range(new Date(), d3.timeDay.offset(new Date(), 7));
диапазон будет массивом объектов даты, которые попадают в первое возможное значение для каждого дня
Вы можете изменить timeDay на timeHour, timeMonth и т. д. для получения одинаковых результатов на разных интервалах
Вот один вкладыш, который не требует никаких библиотек на тот случай, если вы не хотите создавать другую функцию. Просто замените startDate (в двух местах) и endDate (которые являются объектами даты js) вашими переменными или значениями даты. Конечно, вы можете обернуть его в функцию, если вы предпочитаете
Array(Math.floor((endDate - startDate) / 86400000) + 1).fill().map((_, idx) => (new Date(startDate.getTime() + idx * 86400000)))
Я использую эту функцию
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;
}
Я использую простой цикл while для расчета между датами
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);
}
Примечание: я знаю, что это немного отличается от запрошенного решения, но я думаю, что многие найдут его полезным.
Если вы хотите найти каждый интервал "x" (дни, месяцы, годы и т. Д.) Между двумя датами, moment.js и диапазоном момента расширения включите эту функцию.
Например, чтобы найти каждый 30-й день между двумя датами :
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'))
});
Создайте массив лет:
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())
Генерация массивов за месяц:
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())
Генерация массивов за дни:
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())
Вы можете сделать это легко с помощью momentJS
Добавьте момент к вашим зависимостям
npm i moment
Затем импортируйте это в свой файл
var moment = require("moment");
Затем используйте следующий код, чтобы получить список всех дат между двумя датами
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);
Это может помочь кому-то,
Вы можете получить вывод строки и отформатировать объект row_date, как хотите.
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
Вот стандартный метод, который будет принимать даты или строки Момента в качестве входных данных и генерировать массив дат как Моментные даты. Если вы не хотите, чтобы даты Момента выводились, измените то, что map()
возвращает метод.
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'));
};
решение @ softvar, но затем с опцией рабочих дат
/**
* 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;
}
Функция:
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;
};
Использование:
var dates = getDatesRange(new Date(2019,01,01), new Date(2019,01,25));
dates.forEach(function(date) {
console.log(date);
});
Надеюсь, это поможет вам