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

如何基于给定的活动时间规则计算距离下一次活动触发的剩余时长

JavaScript 活动下一次触发剩余时间计算实现

核心逻辑

  • 先建立星期名称到JS原生日期对象星期索引的映射:JS中Date.getDay()返回值为0~6,0对应周日、1对应周一、6对应周六
  • 拆分两种时间规则的解析逻辑:
    • 标注EVERY的每日规则:优先取今日对应时间,若今日时间已过则自动顺延到次日
    • 标注具体星期的周规则:优先取本周对应星期的时间,若本周时间已过则自动顺延到下周
  • 单个活动存在多个触发规则时取时间最近的计算剩余时长
  • 自动格式化剩余时长为天/时/分/秒的可读格式

注意事项

原events对象中AirDrop的规则Thusday为拼写错误,需改为Thursday才能正常解析。

完整实现代码

// 活动规则定义(修正了AirDrop的星期拼写错误)
let events = {
  "KOTH Airship": ["EVERY 19:00"],
  "KOTH Castle": ["EVERY 20:00"],
  "Totem": ["EVERY 17:00", "EVERY 23:00"],
  "Jump": ["Monday 18:00"],
  "Laby PvP": ["Tuesday 18:00"],
  "MegaKOTH Nether": ["Wednesday 18:00"],
  "AirDrop": ["Thursday 18:00"],
  "Rain of Items": ["Friday 18:00"],
  "MegaKOTH Pyramid": ["Saturday 18:00"],
  "MegaKOTH End": ["Sunday 18:00"],
};

// 星期映射表
const WEEK_MAP = {
  Sunday: 0,
  Monday: 1,
  Tuesday: 2,
  Wednesday: 3,
  Thursday: 4,
  Friday: 5,
  Saturday: 6
};

/**
 * 解析时间规则生成下一次触发的Date对象
 * @param {string} rule 时间规则
 * @returns {Date} 下一次触发时间
 */
function parseRuleToNextDate(rule) {
  const now = new Date();
  // 处理每日规则
  if (rule.startsWith('EVERY ')) {
    const [hour, minute] = rule.replace('EVERY ', '').split(':').map(Number);
    const triggerTime = new Date(now.getFullYear(), now.getMonth(), now.getDate(), hour, minute, 0);
    // 今日时间已过,顺延到明天
    if (triggerTime < now) {
      triggerTime.setDate(triggerTime.getDate() + 1);
    }
    return triggerTime;
  }
  // 处理周规则
  const [weekName, timeStr] = rule.split(' ');
  const [hour, minute] = timeStr.split(':').map(Number);
  const targetWeekDay = WEEK_MAP[weekName];
  const currentWeekDay = now.getDay();
  // 计算距离目标星期的天数差
  let diffDays = targetWeekDay - currentWeekDay;
  const triggerTime = new Date(now.getFullYear(), now.getMonth(), now.getDate(), hour, minute, 0);
  // 本周时间已过,加7天到下周
  if (diffDays < 0 || (diffDays === 0 && triggerTime < now)) {
    diffDays += 7;
  }
  triggerTime.setDate(triggerTime.getDate() + diffDays);
  return triggerTime;
}

/**
 * 格式化剩余时间为可读格式
 * @param {number} ms 剩余毫秒数
 * @returns {string} 格式化后的剩余时间
 */
function formatRemainTime(ms) {
  const days = Math.floor(ms / (1000 * 60 * 60 * 24));
  const hours = Math.floor((ms % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
  const minutes = Math.floor((ms % (1000 * 60 * 60)) / (1000 * 60));
  const seconds = Math.floor((ms % (1000 * 60)) / 1000);
  return `${days}天${hours}小时${minutes}分${seconds}秒`;
}

/**
 * 获取所有活动下一次触发的剩余时间
 * @returns {Object} 各活动剩余时间映射
 */
function getAllEventNextRemainTime() {
  const now = new Date();
  const result = {};
  for (const [eventName, rules] of Object.entries(events)) {
    // 生成所有规则的下一次触发时间,取最近的
    const nextTimes = rules.map(rule => parseRuleToNextDate(rule));
    const nearestTime = new Date(Math.min(...nextTimes));
    const remainMs = nearestTime - now;
    result[eventName] = {
      nextTriggerTime: nearestTime.toLocaleString(),
      remainTime: formatRemainTime(remainMs)
    };
  }
  return result;
}

// 调用示例
console.log(getAllEventNextRemainTime());

输出示例

执行调用后会返回如下结构的结果:

{
  "KOTH Airship": {
    "nextTriggerTime": "2024/5/20 19:00:00",
    "remainTime": "0天3小时25分12秒"
  },
  // 其余活动数据省略
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 17:36:03