最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Dates array using Moment.js - Stack Overflow

programmeradmin1浏览0评论

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. For instance if the start date is 7/1/2019 and the end date is 6/30/2020 and the interval is 7 days; 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]

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. For instance if the start date is 7/1/2019 and the end date is 6/30/2020 and the interval is 7 days; 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]
Share Improve this question edited Jul 1, 2019 at 19:50 Dalton Cézane 3,7922 gold badges40 silver badges62 bronze badges asked Jul 1, 2019 at 19:15 DaveDave 1,2773 gold badges29 silver badges64 bronze badges 2
  • There are functions to create dates & add to dates, so you can build what you describe out of those. – Scott Hunter Commented Jul 1, 2019 at 19:17
  • With regard to "Our team is just starting to use moment.js...". Please consider learning something else instead. The Moment team remends Luxon for new app development. There's also date-fns, and js-joda to choose from. – Matt Johnson-Pint Commented Jul 1, 2019 at 22:14
Add a ment  | 

5 Answers 5

Reset to default 3

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

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 parison', endTimer.getTime() - startTimer.getTime());
<script src="https://cdnjs.cloudflare./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 parison. That is to say:

current.isBefore(endDate)

is much slower than, (after you make a moment object from 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 parison', endTimer.getTime() - startTimer.getTime());
<script src="https://cdnjs.cloudflare./ajax/libs/moment.js/2.12.0/moment.js"></script>

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 for-of loops and make arrays with a generator function.

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)) { /* ... */ }

You can use momentJS add function for this. For an example

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

You can just loop through by adding interval to the starting date. https://momentjs./docs/#/manipulating/add/

And another project which is built on top of momentjs would be this https://github./rotaready/moment-range where you can directly get ranges with intervals. 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))
发布评论

评论列表(0)

  1. 暂无评论