如何在Moment中枚举两个日期之间的日期

时间:2014-05-21 23:30:55

标签: javascript momentjs

我有两个moment日期:

var fromDate = moment(new Date('1/1/2014'));
var toDate   = moment(new Date('6/1/2014'));

片刻是否提供了枚举这两个日期之间所有日期的方法?

如果没有,除了制作一个将fromDate增加1的循环直到达到toDate时,还有更好的解决方案吗?

编辑:添加日期枚举方法和问题

我已经嘲笑了一个枚举两个日期之间日期的方法,但我遇到了一个问题。

  var enumerateDaysBetweenDates = function(startDate, endDate) {
    var dates = [];

    startDate = startDate.add(1, 'days');

    while(startDate.format('M/D/YYYY') !== endDate.format('M/D/YYYY')) {
      console.log(startDate.toDate());
      dates.push(startDate.toDate());
      startDate = startDate.add(1, 'days');
    }

    return dates;
  };

运行enumerateDaysBetweenDates( moment(new Date('1/1/2014')), moment(new Date('1/5/2014'));

时查看输出
Thu Jan 02 2014 00:00:00 GMT-0800 (PST)
Fri Jan 03 2014 00:00:00 GMT-0800 (PST)
Sat Jan 04 2014 00:00:00 GMT-0800 (PST)
[ Sun Jan 05 2014 00:00:00 GMT-0800 (PST),
  Sun Jan 05 2014 00:00:00 GMT-0800 (PST),
  Sun Jan 05 2014 00:00:00 GMT-0800 (PST) ]

它是console.logging正确的日期,但只有最终日期被添加到数组中。这是怎么回事?这闻起来像某种变量引用问题 - 但我没有看到它。

7 个答案:

答案 0 :(得分:66)

.add()是一种mutator方法,因此不必在此行中进行分配:

startDate = startDate.add(1, 'days');

你可以这样做,并产生同样的效果:

startDate.add(1, 'days');

虽然它的名称意味着创建了一个新的Date对象,但toDate()方法实际上只返回现有的内部Date对象。

因此,您的方法调用都没有创建新的Datemoment对象实例。通过使用.clone()获取新实例来解决此问题:

startDate = startDate.clone().add(1, 'days');

或者更好的是,将moment()调用中的值包装为Mtz在注释中建议,并且它将克隆实例,如果值是时刻对象,或者它将解析用于创建新时刻实例的输入。

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

我认为日期枚举器方法不应该更改传入的任何参数。我将为枚举创建一个单独的变量。我还会直接比较日期,而不是比较字符串:

var enumerateDaysBetweenDates = function(startDate, endDate) {
    var dates = [];

    var currDate = moment(startDate).startOf('day');
    var lastDate = moment(endDate).startOf('day');

    while(currDate.add(1, 'days').diff(lastDate) < 0) {
        console.log(currDate.toDate());
        dates.push(currDate.clone().toDate());
    }

    return dates;
};

答案 1 :(得分:30)

得到它:

var enumerateDaysBetweenDates = function(startDate, endDate) {
    var now = startDate.clone(), dates = [];

    while (now.isSameOrBefore(endDate)) {
        dates.push(now.format('M/D/YYYY'));
        now.add(1, 'days');
    }
    return dates;
};

引用now而非startDate完全不同。

如果您未进行全面搜索,请将.isSameOrBefore更改为.isBefore

小提琴: http://jsfiddle.net/KyleMuir/sRE76/118/

答案 2 :(得分:5)

使用时间并使用while循环,代码将循环运行,直到startDate等于endDate并按下startDate,然后将其递增1天,以便获得下一个日期

function enumerateDaysBetweenDates (startDate, endDate){
  let date = []
  while(moment(startDate) <= moment(endDate)){
    date.push(startDate);
    startDate = moment(startDate).add(1, 'days').format("YYYY-MM-DD");
  }
  return date;
}

您可以通过调用这样的函数进行测试

let dateArr = enumerateDaysBetweenDates('2019-01-01', '2019-01-10');

答案 3 :(得分:4)

Momentjs本身不提供此功能,但有一个插件提供它:moment-range

具体来说,请查看Iteration docs

答案 4 :(得分:1)

作为Kyle答案的延伸 - 我一直试图让它与Unix时间戳一起工作,经过大量的试验和错误后我开始工作并认为我会在这里发布以防万一有人在寻求相同的事情,需要它。请参阅下面的代码:

fromDate = moment.unix(req.params.dateFrom).format('YYYY-MM-DD')
toDate = moment.unix(req.params.dateTo).format('YYYY-MM-DD')

// Returns an array of dates between the two dates
function enumerateDaysBetweenDates(startDate, endDate) {
    startDate = moment(startDate);
    endDate = moment(endDate);

    var now = startDate, dates = [];

    while (now.isBefore(endDate) || now.isSame(endDate)) {
        dates.push(now.format('YYYY-MM-DD'));
        now.add(1, 'days');
    }
    return dates;
};

请注意,我将其转换为Unix,然后再将该值转换为时刻。这是我遇到的问题,你需要再次使它成为片刻值才能使其发挥作用。

使用示例:

fromDate = '2017/03/11' // AFTER conversion from Unix
toDate = '2017/03/13' // AFTER conversion from Unix

console.log(enumerateDaysBetweenDates(fromDate, toDate));

将返回:

['2017/03/11', '2017/03/12', '2017/03/13']

答案 5 :(得分:1)

您可以使用moment.js轻松枚举这是一个针对数天,数周,数月或数年的更通用的解决方案:

https://gist.github.com/galioy/76f0d7b4b61b18fabfe9c0cc24fc3d2a

答案 6 :(得分:0)

使用moment libraryfor loop可以枚举两个日期。

let startDate = moment('2020-06-21');
let endDate = moment('2020-07-15');
let date = [];

for (var m = moment(startDate); m.isBefore(endDate); m.add(1, 'days')) {
    date.push(m.format('YYYY-MM-DD'));
}

console.log(date)
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>