网站搜索

javascript - 给定一个日期和一个 cron 表达式,你能验证该日期是否属于该 cron 表达式吗


我有一个 cron 表达式,我需要检查某个日期是否属于它。(意思是 cron 会在该日期触发)(使用 Node.js)

答案#1

你可以使用 cron-parser 包并这样做:

const isDateMatchesCronExpression = (expression, date, scope = 'second') => {
  scope = ['second', 'minute', 'hour', 'day', 'month', 'weekday'].indexOf(scope.toLowerCase());
  try {
    const data = cronParser.parseExpression(expression).fields;

    if (scope <= 0 && !data.second.includes(date.getSeconds())) return false;
    if (scope <= 1 && !data.minute.includes(date.getMinutes())) return false;
    if (scope <= 2 && !data.hour.includes(date.getHours())) return false;
    if (scope <= 3 && !data.dayOfMonth.includes(date.getDate())) return false;
    if (scope <= 4 && !data.month.includes(date.getMonth() + 1)) return false;
    if (scope <= 5 && !data.dayOfWeek.includes(date.getDay())) return false;

    return true;
  } catch (e) {
    throw new Error(`isDateMatchesCronExpression error: ${e}`);
  }
};

答案#2

借助像 croner 这样的包,您可以实现这个功能:

/**
 * @param {string} cronExpression The cron expression. See https://croner.56k.guru/usage/pattern/
 * @param {Date} [timestamp] The timestamp to check. Defaults to the current time.
 * @returns {Number} The number of seconds until the next cron run.
 */
export function getSecondsUntilNextCronRun(cronExpression, timestamp = new Date()) {
  // Required for seconds precision
  const adjustedTimestamp = new Date(timestamp.getTime() - 1000);
  
  // https://www.npmjs.com/package/croner
  const cronJob = new Cron(cronExpression);
  const nextRunTime = cronJob.nextRun(adjustedTimestamp);

  const secondsDelta = (nextRunTime - adjustedTimestamp) / 1000;
  return secondsDelta;
}

然后你可以这样调用它:

getSecondsUntilNextCronRun("* * 14 * * *", new Date("2023-10-20T14:30:00")) <= 1; // true
getSecondsUntilNextCronRun("* 45 * * * *", new Date("2023-10-20T14:30:00")) <= 1; // false

此外,你还可以有像这样的便利功能:

const isCronJobScheduled = (expression, time) => getSecondsUntilNextCronRun(expression, time) <= 1;