文档创建的重复事件
Recurring Events for Document Creation
几天来我一直在思考这个问题。我需要能够在预定的时间段内从我的 Mongo 数据库中提取文档以创建文档的副本(没有时间表)。
示例:
时间表:每 30 周一次,周一、周三和周六
文档:
{
_id: 'abcxyz',
service: 'HVAC',
assignedTo: 'xyzabc',
details: 'Check HVAC System for problems'
}
我会有大量文件,时间安排各不相同。有些有诸如每三个月(季度)的第一个星期一之类的事情。
我尝试过使用诸如 later-js 之类的东西,但后来的 js 似乎无法理解诸如 30 weeks
之类的东西,我认为这是因为 30 weeks
不是您通常会理解的东西做一个crontab。
为了完成这个,我假设我会生成 nextRunDate
并提取每个具有今天 nextRunDate
的文档。话虽如此,我每次都需要计算 nextRunDate
如果当前 运行 日期是第一个,我觉得这很难做到 Monday
你会如何计算下一个 运行 日期是星期三而不是 30 周后?
无论如何,我将非常感谢您对此问题的任何帮助。如果我上面所说的令人困惑,我相信它与 google 日历调度程序非常相似。
在查看了许多库后,我发现 momentjs 和 later-js 都缺少使这成为可能的部分。然而在功能上,momentjs 提供了大部分所需的工具。
momentjs 无法定位一周中的特定一天,即星期一,尤其是在一个月的第一个星期一的情况下。
later-js 缺少安排 30 周后的功能,因为它没有 every(30).weeks()
选项。
我的解决方案是创建一种方法来查找时刻之外的 first Monday of a month
以及计算下一个重复日期。
这是执行此操作的代码
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'),
})
);
几天来我一直在思考这个问题。我需要能够在预定的时间段内从我的 Mongo 数据库中提取文档以创建文档的副本(没有时间表)。
示例:
时间表:每 30 周一次,周一、周三和周六
文档:
{
_id: 'abcxyz',
service: 'HVAC',
assignedTo: 'xyzabc',
details: 'Check HVAC System for problems'
}
我会有大量文件,时间安排各不相同。有些有诸如每三个月(季度)的第一个星期一之类的事情。
我尝试过使用诸如 later-js 之类的东西,但后来的 js 似乎无法理解诸如 30 weeks
之类的东西,我认为这是因为 30 weeks
不是您通常会理解的东西做一个crontab。
为了完成这个,我假设我会生成 nextRunDate
并提取每个具有今天 nextRunDate
的文档。话虽如此,我每次都需要计算 nextRunDate
如果当前 运行 日期是第一个,我觉得这很难做到 Monday
你会如何计算下一个 运行 日期是星期三而不是 30 周后?
无论如何,我将非常感谢您对此问题的任何帮助。如果我上面所说的令人困惑,我相信它与 google 日历调度程序非常相似。
在查看了许多库后,我发现 momentjs 和 later-js 都缺少使这成为可能的部分。然而在功能上,momentjs 提供了大部分所需的工具。
momentjs 无法定位一周中的特定一天,即星期一,尤其是在一个月的第一个星期一的情况下。
later-js 缺少安排 30 周后的功能,因为它没有 every(30).weeks()
选项。
我的解决方案是创建一种方法来查找时刻之外的 first Monday of a month
以及计算下一个重复日期。
这是执行此操作的代码
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'),
})
);