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

如何计算日程下次激活的剩余秒数?求更优实现方案

日程激活剩余秒数计算优化问题

我们正试图解决一个看似简单的技术问题,但难以找到优质的代码实现方案:

给定星期数组、分钟数组、开始日期、结束日期、当前时间及时区,计算距离日程下次满足所有激活条件的剩余秒数。

参数说明

  • weekdays:数组形式,如[0,1,2,3,4,5,6](0通常代表周日,6代表周六,具体依定义为准)
  • minutes:数组形式,如[0,1,2,...1439](一天共1440分钟,若数组包含7,则00:07-00:08时段日程处于激活状态)
  • start date:格式为"YYYY-MM-DD"
  • end date:格式为"YYYY-MM-DD"
  • current time:例如Unix时间戳
  • timezone:例如"America/Vancouver",需考虑时区变更(如夏令时切换)

日程激活条件

  • 该时间在指定时区对应的星期属于weekdays数组
  • 该时间在指定时区对应的当日分钟数属于minutes数组
  • 该时间在指定时区对应的日期处于起止日期之间(包含边界)

我们现有一个基于Luxon的函数,虽能部分运行,但对其正确性存疑,且实现过于复杂,请问是否有更简便的解决方案?

现有代码

// Returns 0 if schedule currently active, otherwise seconds until next active or null if no future active
export const checkActive = ({
  startDate,
  endDate,
  minutes,
  weekDays,
  timezone,
  now = null
}) => {
  const nowAtTimezone = now === null
    ? DateTime.local().setZone(timezone)
    : DateTime.fromMillis(new Date(now) / 1).setZone(timezone);

  // Important: new Date('YYYY-MM-DD') creates the date in UTC, not in local timezone
  const nowDateObj = new Date(nowAtTimezone.toISODate());
  const startDateObj = new Date(startDate);
  const endDateObj = new Date(endDate === null ? '9999-01-01' : endDate);

  const nowDateActive = startDateObj <= nowDateObj;
  const nowMinute = nowAtTimezone.hour * 60 + nowAtTimezone.minute;
  let startMinuteIdx = nowDateActive ? minutes.findIndex((m) => m >= nowMinute) : 0;

  for (
    // IMPORTANT: date here is always in UTC
    let date = nowDateActive ? nowDateObj : startDateObj;
    date <= endDateObj;
    date.setUTCDate(date.getUTCDate() + 1)
  ) {
    if (startMinuteIdx !== -1 && weekDays.includes(date.getUTCDay())) {
      const datetime = DateTime.fromObject({
        year: date.getUTCFullYear(),
        month: date.getUTCMonth() + 1,
        day: date.getUTCDate()
      }, { zone: timezone });
      while (startMinuteIdx < minutes.length) {
        const startMinute = minutes[startMinuteIdx];
        const hour = Math.floor(startMinute / 60);
        const minute = startMinute % 60;
        const startTime = datetime.set({ hour, minute });
        if (startTime.hour === hour && startTime.minute === minute) {
          return Math.max(startTime.toSeconds() - Math.floor(nowAtTimezone.toSeconds()), 0);
        }
        startMinuteIdx += 1;
      }
    }
    startMinuteIdx = 0;
  }
  return null;
};

测试示例

{
  startDate: '2022-10-31',
  endDate: '2022-10-31',
  minutes: [
    405, 406, 407, 408, 409, 410, 411, 412,
    413, 414, 415, 416, 417, 418, 419, 420,
    421, 422, 423, 424, 425, 426, 427, 428,
    429, 430, 431, 432, 433, 434, 435, 436,
    437, 438, 439, 440, 441, 442, 443, 444,
    445, 446, 447, 448, 449
  ],
  weekDays: [0, 1, 2, 3, 4, 5, 6],
  timezone: 'Etc/GMT+12'
}

当当前时间为'2022-10-31T04:56:57.000Z'时,预期结果为7 * 60 * 60 + 3 * 60 + 3 + 6 * 60 * 60 + 45 * 60 = 49683。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 04:10:28