文件创build的周期性事件

现在我已经把这个头转了好几天了。 我需要能够按预定时间从我的Mongo数据库中提取文档以创build文档副本(没有时间表)。

例:

时间表:周一,周三和周六每30周

文件:

{ _id: 'abcxyz', service: 'HVAC', assignedTo: 'xyzabc', details: 'Check HVAC System for problems' } 

我将有大量的文件与所有不同的时间表。 有些东西比如每三个月的第一个星期一(季度)。

我尝试过使用诸如later-js之类的东西,但后来js似乎并不了解30 weeks ,我认为这是因为30 weeks通常不会使用crontab。

为了完成这一点,我假设我会生成nextRunDate并拉动每个具有今天的下一个nextRunDate的文档。 有了这个说法,我就需要计算nextRunDate每次我觉得如果当前运行date是第一个Monday如果你计算下一个运行date为星期三而不是30周现在?

无论如何,我会疯狂感谢有关这个问题的任何援助。 如果我上面说的是混淆,我相信这将是非常类似于谷歌日历调度。

Google日历调度程序

在浏览了许多图书馆之后,我发现这两个时刻和后来的js都是缺less的东西,使得这一切成为可能。 然而在function上,时刻提供了大部分所需的工具。

目前缺乏针对某一周的某一天,即星期一的能力,特别是在一个月的第一个星期一的情况下。

后来js缺less安排30周的能力,因为它没有every(30).weeks()选项。

我的解决scheme是创build一种方法来查找first Monday of a month之外的first Monday of a month并计算下一个重复date。

这是这样做的代码

 import moment from 'moment'; /** * Gets the first week day of type in a month * @param {Date} date the original date * @param {Number} day the day of the week we are looking for * @return {Date} the new date object */ const getFirstWeekDay = (date = new Date(), day = 0) => { // set the date to the first of the month date.setDate(1); // Get the first weekday of the month while (date.getDay() !== day) { date.setDate(date.getDate() + 1); } // return the new date return date; }; /** * Returns a starting point * @param {Date} startDate the date to start from * @return {moment} a moment object */ const start = (startDate) => moment(startDate).startOf('day'); /** * Calculates a Schedule on a weekly basis * @param {Date} startDate the date to start from * @param {Array} days days of the week to create * @param {Number} weeks number of weeks for recurrance * @return {Date} the next run date */ const weekly = ({ startDate, days, weeks }) => { const today = start(startDate); const index = _.indexOf(days, today.day()); if (index === (days.length - 1)) { return today.add(weeks, 'weeks').day(days[0]).toDate(); } return today.day(days[index + 1]).toDate(); }; /** * Calculates a Schedule on a monthly basis * @param {Date} startDate the date to start from * @param {Number} day day of the week or month * @param {Number} months number of months for recurrance * @param {Boolean} weekDay starting at weekday or date * @return {Date} the next run date */ const monthly = ({ startDate, day, months, weekDay }) => { const next = start(startDate).startOf('month').add(months, 'months'); if (weekDay) { return getFirstWeekDay(next.toDate(), day); } return next.date(day).toDate(); }; // register the function in a object so we can find them const schedules = { weekly, monthly, }; /** * Returns the next run date based on a config * @param {Object} config the config for recurrence * @return {Date} the next run date */ export default (config) => schedules[config.type](config); 

你可以使用这个如下

  // this will get the next date 2 months out on the 30th of the month console.log( getSchedule({ type: 'monthly', months: 2, day: 30, }) ); // this will get the next date 2 months out on the first Wednesday // of the month console.log( getSchedule({ type: 'monthly', months: 2, day: 3, weekDay: true, }) ); // this will get the next date 30 weeks out and if it is Monday it will // instead of creating another date 30 weeks out it will create a new date // for Wednesday. Once Wednesday comes it will then find the next Monday // that is 30 weeks out console.log( getSchedule({ type: 'weekly', weeks: 30, days: [1, 3], startDate: moment().add(1, 'weeks'), }) );