如何在momentJS中循环显示日期,使其每月发生两次



我想从2022年1月1日到2022年6月14日(或任何给定日期(使用momentJS或LuxonJS进行循环,以便在给定月份发生两次。这是我的代码:

const frequency = [];
for (var m = moment('2022-01-01'); m.isSameOrBefore('2022-06-14'); m.add(15, 'days')) {
frequency.push({
dueDate:  moment(m).format('YYYY-MM-DD'),
});
}

这就是结果:

frequency : [
{ dueDate: '2022-01-01' },
{ dueDate: '2022-01-16' },
{ dueDate: '2022-01-31' },
{ dueDate: '2022-02-15' },
{ dueDate: '2022-03-02' },
{ dueDate: '2022-03-17' },
{ dueDate: '2022-04-01' },
{ dueDate: '2022-04-16' },
{ dueDate: '2022-05-01' },
{ dueDate: '2022-05-16' },
{ dueDate: '2022-05-31' }
]

这不是我想要的结果,因为它在一月发生三次,二月发生一次,五月发生三次

我希望循环考虑一个月的天数,这样它每个月循环两次。

我想要的结果与此类似,但不是特别的,只要它在一个月内循环两次。

desired : [
{ dueDate: '2022-01-01' },
{ dueDate: '2022-01-16' },
{ dueDate: '2022-02-01' },
{ dueDate: '2022-02-16' },
{ dueDate: '2022-03-01' },
{ dueDate: '2022-03-16' },
{ dueDate: '2022-04-01' },
{ dueDate: '2022-04-16' },
{ dueDate: '2022-05-01' },
{ dueDate: '2022-05-16' },
{ dueDate: '2022-06-01' },
]

您可以使用.daysInMonth方法来获得当前迭代月份的当前天数,并加上天数的一半。

let frequency = [];
for (var m = moment('2022-01-01'); m.isSameOrBefore('2022-06-14'); m.add(1, 'month')) {
frequency.push({
dueDate:  moment(m).format('YYYY-MM-DD'),
});
frequency.push({
dueDate:  moment(m).add(Math.floor(m.daysInMonth() / 2), 'days').format('YYYY-MM-DD'),
});
}

注意,我也按月递增,但每月推两次。它使意图更加明确。

结果:

[
{ "dueDate": "2022-01-01" },
{ "dueDate": "2022-01-16" },
{ "dueDate": "2022-02-01" },
{ "dueDate": "2022-02-15" },
{ "dueDate": "2022-03-01" },
{ "dueDate": "2022-03-16" },
{ "dueDate": "2022-04-01" },
{ "dueDate": "2022-04-16" },
{ "dueDate": "2022-05-01" },
{ "dueDate": "2022-05-16" },
{ "dueDate": "2022-06-01" },
{ "dueDate": "2022-06-16" }
]

您不需要日期库,因为它可以通过字符串操作来完成。

您可以定义日期和数字之间的1对1映射,使两个连续的数字映射到一个月(第01天或第16天(,并相应地映射回一个月的天数。

然后,它变成了一个迭代一系列数字并将这些数字映射到最新字符串的问题:

function twicePerMonth(start, end) {
const toNumber = s => (([y, m, d]) => 24*y+2*m+(d>1)+(d>16)-2)(s.split("-"));
const toString = n => [~~(n / 24), ((n % 24) >> 1) + 1, (n % 2) * 15 + 1]
.join("-").replace(/bdb/g, "0$&");
start = toNumber(start);
return Array.from({length: toNumber(end) - start}, (_, i) => ({
dueDate: toString(start + i)
}));
}
const result = twicePerMonth('2022-01-01',  '2022-06-13');
console.log(result);

最新更新