You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Node.js中实现每月固定周次同星期几的周期性会议支持

支持每月固定周次星期几的周期性会议检查

需求说明

需在现有会议室可用性检查API中新增支持每月第N个固定星期几的周期性会议规则:初始会议为某月第K个星期X(例如6月第二周周一),后续所有月份的第K个星期X均需判定为该会议的占用时段。

解决方案

1. 新增日期工具函数

添加两个工具函数,用于提取日期对应的「星期几」和「当月第几个该星期几」:

// 获取日期是当月的第几个星期几(例如当月第二个周一返回2)
function getNthDayOfMonth(date) {
  const targetDay = date.getDay(); // 0=周日,1=周一...6=周六
  const firstDayOfMonth = new Date(date.getFullYear(), date.getMonth(), 1);
  // 计算当月第一个目标星期几的日期
  const daysToFirstTarget = ((targetDay - firstDayOfMonth.getDay() + 7) % 7);
  const firstTargetDate = new Date(firstDayOfMonth);
  firstTargetDate.setDate(firstDayOfMonth.getDate() + daysToFirstTarget);

  // 计算当前日期是第几个目标星期几
  if (date < firstTargetDate) return 1; // 极端情况:日期早于第一个目标日(仅当月1日为目标日时触发)
  const daysDiff = Math.floor((date - firstTargetDate) / (1000 * 60 * 60 * 24));
  return Math.floor(daysDiff / 7) + 1;
}

// 获取星期几的数字标识(0=周日,1=周一...6=周六)
function getDayOfWeek(date) {
  return date.getDay();
}

2. 修改API核心逻辑

在原有周期判断分支中,新增对M(每月固定周次)类型的处理:

// API endpoint to retrieve the CSV data (Fetching recurring meetings)
app.get('/api/checkAvailability', (req, res) => {
  const { room, date } = req.query;

  const results = [];

  // 日期工具函数
  function getNthDayOfMonth(date) {
    const targetDay = date.getDay();
    const firstDayOfMonth = new Date(date.getFullYear(), date.getMonth(), 1);
    const daysToFirstTarget = ((targetDay - firstDayOfMonth.getDay() + 7) % 7);
    const firstTargetDate = new Date(firstDayOfMonth);
    firstTargetDate.setDate(firstDayOfMonth.getDate() + daysToFirstTarget);

    if (date < firstTargetDate) return 1;
    const daysDiff = Math.floor((date - firstTargetDate) / (1000 * 60 * 60 * 24));
    return Math.floor(daysDiff / 7) + 1;
  }

  function getDayOfWeek(date) {
    return date.getDay();
  }

  fs.createReadStream('3meetings.csv')
    .pipe(csv())
    .on('data', (data) => results.push(data))
    .on('end', () => {
      const occupiedSlots = results.filter((meeting) => {
        if (meeting.room === room && meeting.date <= date) {
          const interval = meeting.interval.toUpperCase();
          const meetingDate = new Date(meeting.date);
          const targetDate = new Date(date);

          if (interval === 'D') {
            const daysDiff = Math.floor((targetDate - meetingDate) / (1000 * 60 * 60 * 24));
            return daysDiff % 1 === 0;
          } else if (interval === 'W') {
            const daysDiff = Math.floor((targetDate - meetingDate) / (1000 * 60 * 60 * 24));
            return daysDiff % 7 === 0;
          } else if (interval === 'W2') {
            const daysDiff = Math.floor((targetDate - meetingDate) / (1000 * 60 * 60 * 24));
            return daysDiff % 14 === 0;
          } else if (interval === 'M') {
            // 匹配规则:星期几一致 + 当月第几个该星期几一致 + 目标日期在初始会议之后
            const meetingDay = getDayOfWeek(meetingDate);
            const meetingNth = getNthDayOfMonth(meetingDate);
            const targetDay = getDayOfWeek(targetDate);
            const targetNth = getNthDayOfMonth(targetDate);

            const monthDiff = (targetDate.getFullYear() - meetingDate.getFullYear()) * 12 + (targetDate.getMonth() - meetingDate.getMonth());
            return monthDiff >= 0 && meetingDay === targetDay && meetingNth === targetNth;
          }
        }
        return false;
      });

      res.json({
        isAvailable: occupiedSlots.length === 0,
        ...(occupiedSlots.length > 0 && { occupiedSlots })
      });
    });
});

3. CSV数据配置

在3meetings.csv中,将每月固定周次的会议interval字段设为M即可,例如:

room,date,interval,title
会议室A,2024-06-04,M,月度团队同步会

关键逻辑说明

  • getNthDayOfMonth:精准计算目标日期是当月的第几个指定星期几,完全匹配「每月第N个星期X」的需求
  • M类型判断:同时校验星期几、当月周次一致性,以及目标日期的时间先后,避免跨月误判
  • 兼容原有逻辑:保留对D(每日)、W(每周)、W2(每两周)类型的支持,不影响现有功能

内容的提问来源于stack exchange,提问作者user19592947

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 22:09:56