捕获两个日期之间的每个星期五、星期日和星期三
Capture every Friday, Sunday and Wednesday between two dates
晚安。我正在尝试使用 Moment.js 捕获两个日期之间的每个星期五、星期日和星期三。我不明白为什么它没有捕捉到日子:
- 2021-12-08
- 2021-12-10
我做到了这一点:
const allDays = [0, 3, 5];
function formatToPush(dt_inicio, dt_final, dia, horas) {
let start = moment(dt_inicio);
let end = moment(dt_final);
let result = [];
let datas = [];
let current = start.clone();
if ((current.day(dia).isSameOrAfter(start)) || (current.day(dia).isSameOrAfter(end)) || (current.day(7 + dia).isSameOrBefore(end))) {
result.push(current.clone());
}
result.map(m => {
horas.map(h => {
m.set({ hour: h.split(':')[0], minute: h.split(':')[1], second: 0, millisecond: 0 });
datas.push(m.format('YYYY-MM-DD HH:mm:ss'))
})
});
return datas;
}
let final = [];
for (let i in allDays) {
final.push(...formatToPush('2021-12-01', '2021-12-10', allDays[i], ["10:00", "16:00", "22:30"]))
}
console.log(final)
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
谁能帮我找出错误?
谢谢!
对于前两个子句中的一个或两个,日期是否在范围内的条件始终为真。这意味着整个表达式为真,无需评估第三个子句,该子句可以将日期设置为您丢失的较晚日期之一。由于您不是 运行 循环中的 if 语句,它只会将一个日期推送到结果数组。
更通用的算法将使用循环。
let current = start.clone();
if (current.day(dia).isSameOrAfter(start) && current.isSameOrBefore(end)) {
result.push(current.clone());
}
while (current.day(7 + dia).isSameOrAfter(start) && current.isSameOrBefore(end)) {
result.push(current.clone());
}
注意:我还将连词更改为 && 因为在循环中,isAfter 将始终为真。另外,我在第二个子句中省略了 current.day(dia),因为第一个子句已经为当前设置了星期几。
您一天 (result.push(current.clone())
) 恰好推送一次,因此您不能期望每天有超过一个约会。您可以使用此条件创建第二个 if
语句:(current.day(7 + dia).isSameOrBefore(end))
并第二次推送它。
此外,在js中,当满足if
中的第一个条件时,其他条件未解决。
const allDays = [0, 3, 5];
function formatToPush(dt_inicio, dt_final, dia, horas) {
let start = moment(dt_inicio);
let end = moment(dt_final);
let result = [];
let datas = [];
let current = start.clone();
if ((current.day(dia).isSameOrAfter(start)) || (current.day(dia).isSameOrAfter(end)) || (current.day(7 + dia).isSameOrBefore(end))) {
result.push(current.clone());
}
if (current.day(7 + dia).isSameOrBefore(end)) {
result.push(current.clone());
}
result.map(m => {
horas.map(h => {
m.set({ hour: h.split(':')[0], minute: h.split(':')[1], second: 0, millisecond: 0 });
datas.push(m.format('YYYY-MM-DD HH:mm:ss'))
})
});
return datas;
}
let final = [];
for (let i in allDays) {
final.push(...formatToPush('2021-12-01', '2021-12-10', allDays[i], ["10:00", "16:00", "22:30"]))
}
console.log(final)
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
如果想使用日期 API 在三行简单的代码中执行此操作,这里有一个替代方法。
考虑到 momentjs 在 42k 中有 17,000 多行代码,我提供了这个替代方案。
供您考虑。
处理从开始到结束(含)的范围时
- 将日期转换为 dateString 并查找 Fri 或 Sun 或 Wed
- 如果找到 -> 将日期添加到结果数组
- 检查下一个日期
const startDate = new Date('2021', '11', '1');
const endDate = new Date('2021', '11', '31');
var tempDate = new Date('2021', '11', '1');
var result = [];
while (tempDate.valueOf() !== endDate.valueOf()) {
if (/Fri|Sun|Wed/.test(tempDate.toDateString())) result.push(new Date(tempDate));
tempDate.setDate(tempDate.getDate() + 1);
}
result.forEach(day => console.log(day.toDateString(), day.toISOString().replace("T",' ')));
晚安。我正在尝试使用 Moment.js 捕获两个日期之间的每个星期五、星期日和星期三。我不明白为什么它没有捕捉到日子:
- 2021-12-08
- 2021-12-10
我做到了这一点:
const allDays = [0, 3, 5];
function formatToPush(dt_inicio, dt_final, dia, horas) {
let start = moment(dt_inicio);
let end = moment(dt_final);
let result = [];
let datas = [];
let current = start.clone();
if ((current.day(dia).isSameOrAfter(start)) || (current.day(dia).isSameOrAfter(end)) || (current.day(7 + dia).isSameOrBefore(end))) {
result.push(current.clone());
}
result.map(m => {
horas.map(h => {
m.set({ hour: h.split(':')[0], minute: h.split(':')[1], second: 0, millisecond: 0 });
datas.push(m.format('YYYY-MM-DD HH:mm:ss'))
})
});
return datas;
}
let final = [];
for (let i in allDays) {
final.push(...formatToPush('2021-12-01', '2021-12-10', allDays[i], ["10:00", "16:00", "22:30"]))
}
console.log(final)
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
谁能帮我找出错误?
谢谢!
对于前两个子句中的一个或两个,日期是否在范围内的条件始终为真。这意味着整个表达式为真,无需评估第三个子句,该子句可以将日期设置为您丢失的较晚日期之一。由于您不是 运行 循环中的 if 语句,它只会将一个日期推送到结果数组。
更通用的算法将使用循环。
let current = start.clone();
if (current.day(dia).isSameOrAfter(start) && current.isSameOrBefore(end)) {
result.push(current.clone());
}
while (current.day(7 + dia).isSameOrAfter(start) && current.isSameOrBefore(end)) {
result.push(current.clone());
}
注意:我还将连词更改为 && 因为在循环中,isAfter 将始终为真。另外,我在第二个子句中省略了 current.day(dia),因为第一个子句已经为当前设置了星期几。
您一天 (result.push(current.clone())
) 恰好推送一次,因此您不能期望每天有超过一个约会。您可以使用此条件创建第二个 if
语句:(current.day(7 + dia).isSameOrBefore(end))
并第二次推送它。
此外,在js中,当满足if
中的第一个条件时,其他条件未解决。
const allDays = [0, 3, 5];
function formatToPush(dt_inicio, dt_final, dia, horas) {
let start = moment(dt_inicio);
let end = moment(dt_final);
let result = [];
let datas = [];
let current = start.clone();
if ((current.day(dia).isSameOrAfter(start)) || (current.day(dia).isSameOrAfter(end)) || (current.day(7 + dia).isSameOrBefore(end))) {
result.push(current.clone());
}
if (current.day(7 + dia).isSameOrBefore(end)) {
result.push(current.clone());
}
result.map(m => {
horas.map(h => {
m.set({ hour: h.split(':')[0], minute: h.split(':')[1], second: 0, millisecond: 0 });
datas.push(m.format('YYYY-MM-DD HH:mm:ss'))
})
});
return datas;
}
let final = [];
for (let i in allDays) {
final.push(...formatToPush('2021-12-01', '2021-12-10', allDays[i], ["10:00", "16:00", "22:30"]))
}
console.log(final)
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
如果想使用日期 API 在三行简单的代码中执行此操作,这里有一个替代方法。
考虑到 momentjs 在 42k 中有 17,000 多行代码,我提供了这个替代方案。
供您考虑。
处理从开始到结束(含)的范围时
- 将日期转换为 dateString 并查找 Fri 或 Sun 或 Wed
- 如果找到 -> 将日期添加到结果数组
- 检查下一个日期
const startDate = new Date('2021', '11', '1');
const endDate = new Date('2021', '11', '31');
var tempDate = new Date('2021', '11', '1');
var result = [];
while (tempDate.valueOf() !== endDate.valueOf()) {
if (/Fri|Sun|Wed/.test(tempDate.toDateString())) result.push(new Date(tempDate));
tempDate.setDate(tempDate.getDate() + 1);
}
result.forEach(day => console.log(day.toDateString(), day.toISOString().replace("T",' ')));