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

问题描述 投票:0回答:10

我有两个时刻日期:

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

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

如果没有,除了创建一个将

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正确的日期,但只有最终日期被添加到数组中。这是怎么/为什么?这听起来像是某种变量引用问题 - 但我没有看到它。

javascript momentjs
10个回答
111
投票

.add()
是一个 mutator 方法,因此这一行中的赋值是不必要的:

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

你可以这样做,并获得相同的效果:

startDate.add(1, 'days');

虽然它的名称意味着创建一个新的

Date
对象,但
toDate()
方法实际上只是返回现有的内部
Date
对象。

因此,您的方法调用都不会创建新的

Date
moment
对象实例。通过使用
.clone()
获取新实例来修复此问题:

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

或者更好的是,将值包装在对

moment()
的调用中,如 Mtz 在注释中建议的那样,如果该值是一个 moment 对象,它将克隆实例,或者它将解析输入以创建一个新的 moment实例。

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

55
投票

给你了:

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/


16
投票

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

9
投票

使用

moment library
for 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>


5
投票

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

moment-range

具体来说,请查看迭代文档


3
投票

作为凯尔答案的扩展 - 我一直在尝试让它与 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']

3
投票

使用ES6表示法

const from = moment('01/01/2014', 'DD/MM/YYYY')
const to   = moment('06/01/2014', 'DD/MM/YYYY')

const nbDays = to.diff(from, 'days') + 1
const result = [...Array(nbDays).keys()]
          .map(i => from.clone().add(i, 'd'))

console.log(result)
<script src="https://momentjs.com/downloads/moment.min.js"></script>


2
投票

您可以使用

moment.js
轻松枚举,这是针对天、周、月或年的更通用解决方案:

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


0
投票

使用矩库和 for 循环,您可以枚举两个日期之间的值。

const moment = require('moment');

 let startDate = moment('2021-12-24');
 let endDate = moment('2022-1-4');
 let date = [];

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

 console.log(date)


0
投票

使用递归的简短解决方案

import type { Moment } from 'moment';

export const getDatesBetween = (start: Moment, end: Moment): Moment[] => {
  if (!start.isValid() || !end.isValid() || start.isAfter(end, 'day')) return [];

  if (start.isSame(end, 'day')) return [start];

  return [start].concat(getDatesBetween(start.clone().add(1, 'day'), end));
};
© www.soinside.com 2019 - 2024. All rights reserved.