FullCalendar V4 - Как учитывать более короткие месяцы в серии повторяющихся событий?
Я использую FullCalendar v4-alpha-3 с плагином RRule для генерации повторяющихся событий. Он работает, как и ожидалось, только с одной проблемой: как изменить повторяющееся событие для учета месяцев с меньшим количеством дней, чем начальный месяц в серии?
Например, если первое ежемесячное вхождение происходит 29 января 2019 года; событие будет повторяться 29-го числа всех последующих месяцев, кроме февраля, поскольку в нем только 28 дней (без учета високосных лет).
Я пытался сбросить dtstart
в первый день следующего месяца. Это работает, за исключением того, что событие больше не является рекурсивным.
Вот урезанный фрагмент моей настройки:
let calendar = new Calendar(calendarEl, {
plugins: [ rrulePlugin ],
events: [
{
rrule: 'DTSTART:20190129 RRULE:FREQ=MONTHLY;UNTIL=20200130;COUNT=13;BYMONTHDAY=29'
}
],
eventRender: function(info) {
...
// reset start date to the first day of the following month
// if current month has fewer days than base month
let start = event.start;
let day = start.getDate();
let now = new Date();
let currentMonth = now.getMonth();
let currentYear = now.getFullYear();
let daysInCurrent = getDaysInMonth(currentMonth + 1, currentYear);
let nextStart = start;
if (day > daysInCurrent) {
nextStart = new Date(currentYear, currentMonth + 1, 1);
event.setStart(nextStart);
event.setEnd(null);
}
}
});
Буду признателен за понимание.
2 ответа
Не совсем то решение, на которое я надеялся, но RRule's bysetpos
свойство, кажется, предлагает следующую лучшую альтернативу, так как оно допускает запасную дату в случае, если указанная не существует.
Например, следующее произойдет вхождение 30-го числа каждого месяца; или последний день месяца, если 30-го числа не существует:
FREQ=MONTHLY;BYMONTHDAY=28,29,30;BYSETPOS=-1
,
Источник: https://icalevents.com/2555-paydays-last-working-days-and-why-bysetpos-is-useful/
Я знаю, что это старый вопрос, но, возможно, это будет полезно для кого-то:
Я использую библиотеку momentjs
monthly:
let endofmonth = moment('2020-02-29', "YYYY-MM-DD").endOf('month').format('DD');
let curday = moment('2020-02-29, "YYYY-MM-DD").format('DD');
single_event.title = title;
single_event.rrule = {};
single_event.rrule.freq = 'monthly';
single_event.rrule.dtstart = start_date;
single_event.rrule.interval = reminder_interval;
single_event.rrule.count = reminder_count;
if(endofmonth == curday){
// Checking if given day of the month is last
single_event.rrule.byweekday = ['mo','tu','we','th','fr','sa','su'];
single_event.rrule.bysetpos = -1;
}
else{
single_event.rrule.bymonthday = parseInt(curday);
}
calendar_events.push(single_event);
var calendar = new FullCalendar.Calendar(calendarEl, {
...
events: calendar_events
});
yearly:
single_event.title = title;
single_event.rrule = {};
single_event.rrule.dtstart = start_date;
single_event.rrule.count = parseInt(reminder_count);
if(endofmonth == curday){
// Checking if given day of the month is last
single_event.rrule.freq = 'monthly'; // Will work as yearly if interval is 12
single_event.rrule.interval = parseInt(reminder_interval)*12;
single_event.rrule.bymonthday = [28,29,30,31];
single_event.rrule.bysetpos = -1;
}
else{
single_event.rrule.freq = 'yearly';
single_event.rrule.bymonthday = parseInt(curday);
}
calendar_events.push(single_event);
var calendar = new FullCalendar.Calendar(calendarEl, {
...
events: calendar_events
});