【问题标题】:Dates array using Moment.js使用 Moment.js 的日期数组
【发布时间】:2019-07-01 19:15:07
【问题描述】:

我们的团队刚刚开始使用 moment.js 进行日期查询,并且想知道是否有一个函数可以创建间隔 x 天重复出现的日期数组。例如,如果开始日期是 2019 年 7 月 1 日,结束日期是 2020 年 6 月 30 日,间隔是 7 天;是否有一个矩函数可以创建一个如下所示的日期数组:

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

【问题讨论】:

  • 有创建日期和添加日期的功能,因此您可以根据这些功能构建您所描述的内容。
  • 关于“我们的团队刚刚开始使用 moment.js...”。请考虑学习其他东西。 Moment 团队推荐Luxon 用于新的应用程序开发。还有date-fnsjs-joda可供选择。

标签: javascript arrays momentjs


【解决方案1】:

也许不是特定的矩函数,但矩确实提供了所有成分。查看 add()(用于添加 7 天)和 isBefore()(用于结束日期)。

我制作了一个与您要求的功能接近的 sn-p:

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());
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.12.0/moment.js"&gt;&lt;/script&gt;

-- 编辑--

这是一个相当古老的答案,但它最近得到了一些观点,所以我想指出一些我在熟悉时刻后学到的东西。

isBefore 会带来相当大的开销,实际上用户进行简单比较会快得多。也就是说:

current.isBefore(endDate)

比,(在你从 endDate 创建一个时刻对象之后)慢得多

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

如果您运行下一个 sn-p,我增加了时间范围以显示差异,您会发现第二种方法要快得多:

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());
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.12.0/moment.js"&gt;&lt;/script&gt;

【讨论】:

    【解决方案2】:

    您可以使用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);
      }
    }
    

    用法:

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

    【讨论】:

      【解决方案3】:

      只需创建一个函数,该函数将接受开始日期和结束日期以及时间间隔,并继续将日期添加到数组中,直到截止日期。

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

      【讨论】:

        【解决方案4】:

        您可以为此使用 momentJS 添加功能。举个例子

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

        您可以通过将间隔添加到开始日期来循环。 https://momentjs.com/docs/#/manipulating/add/

        另一个建立在momentjs之上的项目是https://github.com/rotaready/moment-range 您可以在其中直接获取带间隔的范围。但如果这是唯一的要求,最好使用简单的功能。

        【讨论】:

          【解决方案5】:

          创建一个生成器以获得灵活的解决方案:

          /**
           * @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;
              }
            }
          }
          

          并要求它提供日期列表:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2013-01-31
            • 2013-04-06
            • 1970-01-01
            • 1970-01-01
            • 2015-03-16
            • 2020-02-05
            相关资源
            最近更新 更多