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 currentDate = moment(startDate);
Якщо ви користуєтесь цим методом двічі за ті самі дати moment.js, вам буде спантеличено, чому він працює лише в перший раз. Це відбувається тому, що javascripts передає об'єкти за посиланням, тому функція закінчується за допомогою startDate двічі (що вже мутується). Виправлення вищезгаданого виправлення гарантує, що ви загрожуєте новими та унікальними об'єктами js моменту у межах функції. Перевірте цю скрипку
Я переглянув усі вище. Закінчив писати сам. Для цього вам не потрібні моменти . Народного для циклу достатньо і має найбільш сенс, оскільки для циклу існує підрахунок значень у діапазоні.
Один вкладиш:
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:
Якщо ви використовуєте, 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.Викликати:
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.З значить ви можете написати дійсно елегантну функцію, яка дозволяє динамічно проходити інтервали (години, дні, місяці).
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 для легких маніпуляцій з датою
Для вашого конкретного запиту:
Utc
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);
}
Примітка. Я знаю, що це дещо інше, ніж запитуване рішення, але я думаю, що багато хто вважатиме це корисним.
Якщо ви хочете знайти кожен "х" інтервал (дні, місяці, роки тощо) між двома датами, 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'));
};
@ софтвар рішення, але потім включаючи опцію робочих дат
/**
* 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);
});
Сподіваюся, це допоможе вам