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
});
Другие вопросы по тегам