51

我想遍历一系列日历日期,每次迭代都是 +1 天。我会在 Java 中使用围绕 JodaTime 构建的东西——NodeJS 中有类似的东西吗?

4

7 回答 7

149

您可以在 node.js 应用程序中使用moment.js 。

npm install moment

然后你可以很容易地做到这一点:

var moment = require('moment');

var a = moment('2013-01-01');
var b = moment('2013-06-01');

// If you want an exclusive end date (half-open interval)
for (var m = moment(a); m.isBefore(b); m.add(1, 'days')) {
  console.log(m.format('YYYY-MM-DD'));
}

// If you want an inclusive end date (fully-closed interval)
for (var m = moment(a); m.diff(b, 'days') <= 0; m.add(1, 'days')) {
  console.log(m.format('YYYY-MM-DD'));
}

嗯...这看起来很像您已经在自己的答案中编写的代码。Moment.js 是一个更受欢迎的库,具有大量功能,但我想知道哪个性能更好?也许你可以测试并让我们知道。:)

但这些都没有 JodaTime 做的那么多。为此,您需要一个在 JavaScript 中实现 TZDB 的库。我在这里列出了一些

此外,请注意JavaScript 日期的一般问题。这也会影响 NodeJS。

于 2013-06-18T16:27:54.217 回答
33

我建议对马特先前的回应进行更改。他的代码会导致a对象发生突变。尝试这个...

var moment = require('moment');
var a = moment('2013-01-01');
var b = moment('2013-06-01');

for (var m = moment(a); m.isBefore(b); m.add(1, 'days')) {
    console.log(m.format('YYYY-MM-DD'));
}
于 2014-05-01T18:04:31.377 回答
3

这是一种没有外部库的解决方案:

  var start = new Date('October 1, 2020 03:00:00Z');
  var now = new Date();

  for (var d = start; d < now; d.setDate(d.getDate() + 1)) {
    console.log(d);
  }

结果:

2020-10-01T03:00:00.000Z
2020-10-02T03:00:00.000Z
2020-10-03T03:00:00.000Z
2020-10-04T03:00:00.000Z
2020-10-05T03:00:00.000Z
2020-10-06T03:00:00.000Z

Z一个日期结束时的 UTC 时间。如果您想要您的时区,只需删除Z.

于 2020-10-06T13:27:28.893 回答
1

使用https://github.com/JerrySievert/node-date-utils框架,然后您可以像这样轻松迭代:

require('date-utils');

var d = new Date('2013-01-01');
var e = new Date('2013-06-01');

for(var i = d; i.isBefore(e); i.addDays(1)) {
  console.log(i.toFormat("YYYY-MM-DD"));  
}
于 2013-06-18T08:16:53.963 回答
0

使用带有 lodash 范围的 momentjs 的另一种方法:

let start = moment('2021-01-01');
let end = moment('2021-01-10');
_.range(b.diff(a, "d")).forEach((d) =>
  console.log(moment(a).add(d, "d").format("YYYY/MM/DD"))
);

如果你不想使用 lodash,你可以得到一个范围,如下所示

[...Array(b.diff(a, "d")).keys()].forEach((d) =>
  console.log(moment(a).add(d, "d").format("YYYY/MM/DD"))
);
于 2021-01-23T00:26:43.707 回答
0

使用 moment 和 while 循环的替代方法。
如果您想要一个专属的结束日期

let startDate = moment()
let endDate = moment().add(5, 'days')
while (endDate.isAfter(startDate)) {
    console.log(startDate.format('YYYY-MM-DD'))
    //increment by one day
   startDate = startDate.add(1, 'day')
}

如果您想要一个包容性的结束日期

let startDate = moment()
let endDate = moment().add(5, 'days')
while (endDate.isSameOrAfter(startDate)) {
    console.log(startDate.format('YYYY-MM-DD'))
    //increment by one day
    startDate = startDate.add(1, 'day')
}
于 2022-01-15T12:12:02.597 回答
-1

尽管为此有许多实用程序,但将它们集成到有用的循环中以检查数据可能很麻烦。

这应该可以解决问题。这可能是矫枉过正,但你可以很容易地让这个更基于论证。

var moment = require('moment');
var _ = require('lodash');

function(collectionsWithDateValues){
  var slots = [];
  var hours = {
    start: 7,   // 7am
    end: 21,    // 9pm
    window: 2   // How long each item should be slotted for.
  };
  var rightNow  = moment().add(0, 'days').hours(hours.start).minute(0).second(0);
  var cutoff    = moment(rightNow).add(14,'days'); // Check the next 2 weeks.
  for( rightNow ; rightNow.isBefore(cutoff) ; rightNow.add(hours.window, 'hours') ){
    // Check if we're going beyond the daily cutoff, go to the next day
    if(rightNow.isAfter(moment(rightNow).hour(hours.end))){
      rightNow.add(1, 'days').hour(hours.start);
    }
    var foundClash = false;
    _.forEach(collectionsWithDateValues,  function(item){
      // Check if the item is within now and the slotted time 
      foundClash = moment(item.date).isBetween(rightNow, moment(rightNow).add(hours.window, 'hours').subtract(1, 'minutes').seconds(59));
    });

    if(!foundClash){
      slots.push(rightNow.toString());
    }
  }
  return slots;
}
于 2015-03-26T20:10:25.383 回答