简体   繁体   English

使用 Moment.js 的日期数组

[英]Dates array using Moment.js

Our team is just starting to use moment.js for date queries and is wondering if there's a function that can create an array of dates that recur x days apart.我们的团队刚刚开始使用 moment.js 进行日期查询,并且想知道是否有一个函数可以创建一个相隔 x 天重复出现的日期数组。 For instance if the start date is 7/1/2019 and the end date is 6/30/2020 and the interval is 7 days;例如,如果开始日期是 7/1/2019,结束日期是 6/30/2020,间隔是 7 天; is there a moment function that can create an array of dates that looks like this:是否有一个矩函数可以创建一个如下所示的日期数组:

[7/8/2019,
7/15/2019,
7/22/2019,
7/29/2019,
8/5/2019,
...
6/29/2020]

Maybe not a specific moment function, but certainly moment provides all the ingredients.也许不是特定的矩函数,但肯定矩提供了所有成分。 Look at add() (for adding 7 days) and isBefore() (for the end date).查看 add() (添加 7 天)和 isBefore() (结束日期)。

I've made a snippet that does something close to what you're asking:我制作了一个片段,它的功能与您所要求的很接近:

 var startDate = '1940-07-01'; var endDate = '2020-06-30' var current = new moment(startDate); var end = new moment(endDate); var dates = []; var startTimer = new Date(); while (current.isBefore(endDate)) { dates.push(current.format('MM-DD-YYYY')); current.add(7, 'days'); } var endTimer = new Date(); console.log('Using isBefore took', endTimer.getTime() - startTimer.getTime()); current = new moment(startDate); dates = []; startTimer = new Date(); while (current < end) { dates.push(current.format('MM-DD-YYYY')); current.add(7, 'days'); } endTimer = new Date(); console.log('Using simple comparison', endTimer.getTime() - startTimer.getTime());
 <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.12.0/moment.js"></script>

-- EDIT -- - 编辑 -

This is quite an old answer but it recently got some views so I want to point out something I've learned since getting more familiar with moment.这是一个很旧的答案,但它最近得到了一些观点,所以我想指出自从对时刻更加熟悉以来我学到的一些东西。

isBefore carries considerable overhead, and in fact it's much faster to user a simple comparison. isBefore 会带来相当大的开销,事实上,用户进行简单的比较要快得多。 That is to say:也就是说:

current.isBefore(endDate)

is much slower than, (after you make a moment object from endDate)比,慢得多(在你从 endDate 创建一个时刻对象之后)

var end = new moment(endDate);
if (current < endDate);

If you run the next snippet, where I've increased the time range to show the difference, you'll see the second approach is considerably faster:如果你运行下一个片段,我已经增加了时间范围来显示差异,你会看到第二种方法要快得多:

 var startDate = '1940-07-01'; var endDate = '2020-06-30' var current = new moment(startDate); var end = new moment(endDate); var dates = []; var startTimer = new Date(); while (current.isBefore(endDate)) { dates.push(current.format('MM-DD-YYYY')); current.add(7, 'days'); } var endTimer = new Date(); console.log('Using isBefore took', endTimer.getTime() - startTimer.getTime()); current = new moment(startDate); dates = []; startTimer = new Date(); while (current < end) { dates.push(current.format('MM-DD-YYYY')); current.add(7, 'days'); } endTimer = new Date(); console.log('Using simple comparison', endTimer.getTime() - startTimer.getTime());
 <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.12.0/moment.js"></script>

You can use for-of loops and make arrays with a generator function.您可以使用for-of循环并使用生成器函数创建数组。

function* dateRange(start, end, interval) {
  start = moment(start);
  end = moment(end);
  interval = moment.duration(interval);
  while (start.isBefore(end)) {
    yield start;
    start.add(interval);
  }
}

Usage:用法:

const dates = [...dateRange(start, end, interval)];
for (date of dateRange(start, end, interval)) { /* ... */ }

Just create a function which will accept the start and end dates and an interval and keep adding to an array the dates until the to date.只需创建一个函数,该函数将接受开始日期和结束日期以及一个间隔,并继续将日期添加到数组中,直到日期。

const datesArray = (from, to, interval) => {
  let ret = [];
  const fromDate = moment(from, 'DD-MM-YYYY');
  const toDate = moment(to, 'DD-MM-YYYY');
  let date = fromDate.add(interval, 'days');
  while(toDate > date) {
    ret.push(date.format('MM-DD-YYYY'));
    date = moment(date).add(interval, 'days');
  }
  return ret;
}

You can use momentJS add function for this.您可以为此使用 momentJS 添加函数。 For an example举个例子

moment().add(7, 'days');

You can just loop through by adding interval to the starting date.您可以通过将时间间隔添加到开始日期来循环。 https://momentjs.com/docs/#/manipulating/add/ https://momentjs.com/docs/#/manipulating/add/

And another project which is built on top of momentjs would be this https://github.com/rotaready/moment-range where you can directly get ranges with intervals.另一个建立在 momentjs 之上的项目是https://github.com/rotaready/moment-range ,您可以在其中直接获取间隔范围。 But if this is the only requirement it's better to go with a simple function.但如果这是唯一的要求,最好使用一个简单的函数。

Create a generator to have a flexible solution:创建一个生成器以获得灵活的解决方案:

/**
 * @param start: moment instance not included in result.
 * @param end: moment instance not included in result.
 * @param step: moment duration instance.
 * @return Generator for moment instances between start and end.
 */
function* generateMoments(start, end, step) {
  const variableMoment = start.clone();
  while(true) {
    variableMoment.add(step);
    if(variableMoment < end) {
      yield variableMoment.clone();
    } else {
      break;
    }
  }
}

And ask it for the date list:并询问它的日期列表:

Array.from(
  generateMoments(moment('2019-07-01'), moment('2020-06-30'), moment.duration({ days: 7}))
).map(m => m.format(localeDependentFormat))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM