Javascript-获取两个日期之间的日期数组

var range = getDates(new Date(), new Date().addDays(7));

我希望“ range”是一个日期对象数组,两个日期之间的每一天都有一个对象。

诀窍在于,它还应该处理月份和年份的界限。

355886 次浏览
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)
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/

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.jsTwix.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/上运行这个

我最近在用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"]

试试这个,记得加上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;
}

我一直在使用@Mohammed Safeer的解决方案一段时间,我做了一些改进。在控制器中工作时,使用格式化日期是一种糟糕的做法。moment().format()只能用于视图中的显示目的。还要记住moment().clone()确保与输入参数分离,这意味着输入日期不会改变。我强烈建议您在处理日期时使用moment.js。

用法:

  • 提供moment.js日期作为startDateendDate参数的值
  • interval参数是可选参数,默认为'days'。使用.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;
};

这可能会帮助到一些人,

您可以从中获得行输出,并根据需要格式化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

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

d3js提供了许多方便的函数,并包括d3.time用于简单的日期操作

https://github.com/d3/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));

Range将是一个日期对象数组,它位于每一天的第一个可能值上

您可以将timeDay更改为timeHour, timmonth等,在不同的间隔上获得相同的结果

这里有一个不需要任何库的代码行,以防你不想创建另一个函数。只需用变量或日期值替换startDate(在两个地方)和endDate(这是js的日期对象)。当然,如果你愿意,你可以把它包装在一个函数中

Array(Math.floor((endDate - startDate) / 86400000) + 1).fill().map((_, idx) => (new Date(startDate.getTime() + idx * 86400000)))

我使用简单的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:

你需要先安装moment和moment-range:

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)

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

我看了上面所有的。最后我自己开始写作。你不需要花时间一个原生的for循环就足够了,这是最有意义的,因为for循环的存在是为了计算范围内的值。

一个衬套:

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

长版本

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

列出中间的日期:

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("")

这是一个罐装方法,它将接受Moment日期或字符串或混合作为输入,并生成一个日期数组作为Moment日期。如果你不想要时刻日期作为输出,那么改变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'));
};

如果你正在使用moment,那么你可以使用他们的“官方插件”为范围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')))

Moment-range浏览器示例:

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>

注意:我知道这是稍微不同于要求的解决方案,但我认为许多人会发现它有用。

如果你想找到两个日期之间的每个“x”间隔(天、月、年等),moment.jsmoment-range扩展包启用了此功能。

例如,找出两个日期之间的每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'))
});

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

希望对你有所帮助

我使用这个函数

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;
}
  1. 生成一个年份数组:

    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())
    
  2. 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())
    
  3. 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())
    

你可以使用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);

我喜欢这样做

// 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))
}

我在使用上面的答案时遇到了麻烦。由于当地夏令时(DST)导致时区偏移,日期范围丢失了一天。我实现了一个使用UTC日期的版本,解决了这个问题:

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

请注意:是否应用了特定的时区或DST,完全取决于你的语言环境。忽略这一点通常不是一个好主意。使用UTC日期可以缓解大多数与时间相关的问题。

奖金:你可以用可选的steps参数来设置你想要创建时间戳的时间间隔。如果你想要每周的时间表,将steps设置为7

使用lodash &时刻:

const startDate = moment();
_.range(0, 7).map((d) => startDate.clone().add(d, 'day').toDate())
Array(7).fill().map((_,i) => dayjs().subtract(i, "day").format("YYYY-MM-DD"));

这是另外几行使用date-fns库的解决方案:

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>

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

不是最短的,而是简单,不可变,没有依赖

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

使用

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

使用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;
};

使用打印稿

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

例子

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