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

Sco*_*ach 128 javascript datetime date date-range node.js

var range = getDates(new Date(), new Date().addDays(7));
Run Code Online (Sandbox Code Playgroud)

我希望"range"是一个日期对象数组,两个日期之间每天一个.

诀窍是它应该处理月和年的边界.

谢谢.

Joh*_*ock 155

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;
}
Run Code Online (Sandbox Code Playgroud)

这是一个功能演示 http://jsfiddle.net/jfhartsock/cM3ZU/

  • 编辑答案以反映斯科特的纠正. (3认同)
  • 谢谢约翰.我主要使用你的,但是你有一个byRef错误,因为currentDate无法被推到数组上,或者你最终会得到一个包含n个元素的数组,这些都是最后一个日期.将其更改为currentDate = new Date(currentDate)有效. (2认同)

Moh*_*eer 46

试试这个,记得包括片刻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;
}
Run Code Online (Sandbox Code Playgroud)

  • 值得注意的是,不再推荐使用 moment.js。该项目的开发已经停止,虽然仍将得到维护,但维护人员建议寻找替代方案。 (4认同)
  • **重要修正**:`var currentDate = moment(startDate);` 如果你在同一个 moment.js 日期使用这个方法两次,你会很困惑为什么它只在第一次起作用。发生这种情况是因为 javascripts 通过引用传递对象,因此该函数最终使用 startDate 两次(已经发生了变化)。修补上述修复程序可确保您在函数范围内处理新的和独特的 moment js 对象。检查这个[小提琴](http://jsfiddle.net/adrian_moisa/x076j4dh/8/) (2认同)

Ahm*_*ani 26

我使用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);
Run Code Online (Sandbox Code Playgroud)

我在http://jsfiddle.net/Lkzg1bxb/上运行了这个


ene*_*esn 26

我看了上面的所有.结束写自己.你不需要为此做点什么.原生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;};
Run Code Online (Sandbox Code Playgroud)

长版

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

列出之间的日期:

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"
*/
Run Code Online (Sandbox Code Playgroud)

从过去的日期到现在的天数:

var daylist = getDaysArray(new Date("2018-05-01"),new Date());
daylist.map((v)=>v.toISOString().slice(0,10)).join("")
Run Code Online (Sandbox Code Playgroud)

  • @HamedTaheri - 是的,但这可以通过将 *start* 的副本分配给 *dt* 而不是 *start* 本身来解决,例如 `for (var arr=[], dt=new Date(start), ... )`。;-) (4认同)
  • 当日期范围发生时间变化(例如从夏令时/DST 切换到标准时间)时,这将无法按预期工作。你最终会错过最后一天。可以通过专门设置时间来防止。 (4认同)
  • 该函数操作源输入日期。:) 我测试过。 (2认同)

Phr*_*ogz 15

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)
Run Code Online (Sandbox Code Playgroud)

  • 为了安全起见,与上述不同,您通常应该在一天中间选择一个时间,以避免由于夏令时造成的轻微变化. (3认同)

Sco*_*ach 14

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;

}
Run Code Online (Sandbox Code Playgroud)

  • 如果您提供的日期顺序不正确,则会冻结 (5认同)

ste*_*khn 11

我在使用上面的答案时遇到了麻烦。由于当地夏令时 (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);
Run Code Online (Sandbox Code Playgroud)

注意:是否应用某个时区或 DST,完全取决于您的语言环境。覆盖它通常不是一个好主意。使用UTC 日期可以缓解大部分时间相关的问题。

奖励:您可以使用可选steps参数设置要为其创建时间戳的时间间隔。如果您希望将每周时间戳设置steps7.

  • 这次真是万分感谢。超级有用。我最终在推入数组之前转换为 ISO 字符串。我可以预见自己将来会经常使用它。 (2认同)

Akr*_*ion 9

如果您使用的是时刻,则可以使用其“官方插件”来确定范围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')))
Run Code Online (Sandbox Code Playgroud)

瞬间范围浏览器示例:

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')))
Run Code Online (Sandbox Code Playgroud)
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')))
Run Code Online (Sandbox Code Playgroud)

date fns示例:

如果您使用的date-fnseachDay是你的朋友,你迄今为止最短和最简洁的答案得到:

<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>
Run Code Online (Sandbox Code Playgroud)
console.log(dateFns.eachDay(
  new Date(2018, 11, 30),
  new Date(2019, 30, 09)
))
Run Code Online (Sandbox Code Playgroud)

  • date fns 从 // v2.0.0 开始发生了重大变化,现在是eachDayOfInterval( { start: new Date(2014, 0, 10), end: new Date(2014, 0, 20) } ) (8认同)

Irf*_*rfy 8

刚遇到这个问题,最简单的方法就是使用力矩:

您需要先安装瞬间和瞬间范围:

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)
Run Code Online (Sandbox Code Playgroud)


gor*_*181 7

我最近在使用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));
Run Code Online (Sandbox Code Playgroud)

结果将是:

["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"]
Run Code Online (Sandbox Code Playgroud)


Adr*_*isa 6

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

用法:

  • 提供moment.js日期为值startDate,endDate参数
  • interval参数是可选的,默认为"天".使用.add()方法支持的间隔(moment.js).更多细节在这里
  • total以分钟为单位指定间隔时,参数很有用.默认为1.

调用:

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

getDatesRangeArray(startDate, endDate, 'minutes', 30);
Run Code Online (Sandbox Code Playgroud)

功能:

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;
};
Run Code Online (Sandbox Code Playgroud)


小智 6

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"]
Run Code Online (Sandbox Code Playgroud)

  • while 循环中的 `strDate` 之前不应该有 `var`! (2认同)

KAR*_*N.A 6

我使用简单的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);
}
Run Code Online (Sandbox Code Playgroud)


dig*_*uru 6

使用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));
Run Code Online (Sandbox Code Playgroud)

  • “优雅”取决于你的观点。`new Date(2017,12,30)` 是 2018 年 1 月 30 日,对我来说,日期范围从 2018 年 1 月 29 日开始。并非所有遵守夏令时的日子都是 8.64e7 毫秒(24 小时)长。;-) (3认同)

May*_*dol 6

Array(7).fill().map((_,i) => dayjs().subtract(i, "day").format("YYYY-MM-DD"));
Run Code Online (Sandbox Code Playgroud)


FDG*_*FDG 5

这是使用 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');
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/date-fns/1.30.1/date_fns.js"></script>
Run Code Online (Sandbox Code Playgroud)