@rschedule/rschedule
Version:
A typescript library for working with recurring dates and events.
54 lines (39 loc) • 1.4 kB
text/typescript
import { IByDayOfMonthRuleOptions, normalizeByDayOfMonth } from './05-by-day-of-month.pipe';
import { IPipeRule, IPipeRunFn, PipeError, PipeRule } from './interfaces';
export class RevByDayOfMonthPipe extends PipeRule<IByDayOfMonthRuleOptions>
implements IPipeRule<IByDayOfMonthRuleOptions> {
run(args: IPipeRunFn) {
if (args.invalidDate) {
return this.nextPipe.run(args);
}
let { date } = args;
const normalizedByDayOfMonth = normalizeByDayOfMonth(
date,
this.options.byDayOfMonth!,
this.options.byDayOfWeek,
).reverse();
const currentDay = date.get('day');
for (const day of normalizedByDayOfMonth) {
if (currentDay < day) continue;
if (currentDay === day) return this.nextPipe.run({ date });
return this.nextValidDate(args, date.endGranularity('month').set('day', day));
}
let next: number | undefined;
let nextMonth = date;
let index = 0;
while (!next && index < 30) {
nextMonth = nextMonth.endGranularity('month').subtract(1, 'month');
next = normalizeByDayOfMonth(
nextMonth,
this.options.byDayOfMonth!,
this.options.byDayOfWeek,
).pop();
index++;
}
if (index >= 13) {
throw new PipeError('byDayOfMonth Infinite while loop');
}
date = nextMonth.set('day', next!);
return this.nextValidDate(args, date);
}
}