Правило повторения в ICal4j

Я пытаюсь создать файл .ics с помощью ICal4j.
Но когда я пытаюсь добавить повторение, он терпит неудачу, выдавая ValidationException:

net.fortuna.ical4j.model.ValidationException: Invalid property: RRULE at
        net.fortuna.ical4j.model.Calendar.validate(Calendar.java:297) at  
        net.fortuna.ical4j.model.Calendar.validate(Calendar.java:257) at 
        net.fortuna.ical4j.data.CalendarOutputter.output(CalendarOutputter.java:96) at 
        net.fortuna.ical4j.data.CalendarOutputter.output(CalendarOutputter.java:83)

Мой код для добавления повторения:

Recur recur = new Recur(Recur.WEEKLY,null);
recur.setUntil( new DateTime(dateTo.getTime()) );

RRule rule = new RRule(recur);
cal.getProperties().add(rule);

Без этого правила все работает нормально, но я хочу добавлять это событие каждый понедельник
до 12 December 2011 (дата, возвращаемая dateTo). Любые идеи?


person user970183    schedule 16.10.2011    source источник


Ответы (3)


Свойство правила повторения (RRULE) должно быть добавлено к определенному событию (VEVENT) в календаре, а не к самому календарю. например

myEvent.getProperties().add(rule);

Кроме того, если вы хотите, чтобы событие произошло в понедельник, вам, вероятно, следует использовать такое правило:

FREQ=WEEKLY;BYDAY=MO;UNTIL=<date>

Это не в моей голове, поэтому лучше проверить RFC, чтобы быть уверенным:

http://tools.ietf.org/html/rfc5545#section-3.3.10

person fortuna    schedule 17.10.2011

Вот пример моего правила повторения для одного и того же правила еженедельного повторения:

RRULE:FREQ=MONTHLY;INTERVAL=1;BYDAY=MO;UNTIL=20161222T000000Z
RRULE:FREQ=MONTHLY;INTERVAL=<Every month/with some interval>;BYDAY=<Day of week>;UNTIL=<Until Date>

Поэтому ваше правило будет выглядеть так: "RRULE:FREQ=MONTHLY;INTERVAL=1;BYDAY=MO;UNTIL=20111212T000000Z"

Дан код для создания правила повторения и дат

class CreateRule{

    static {
        weekMap.put(Short.valueOf("0"), "SU");
        weekMap.put(Short.valueOf("1"), "MO");
        weekMap.put(Short.valueOf("2"), "TU");
        weekMap.put(Short.valueOf("3"), "WE");
        weekMap.put(Short.valueOf("4"), "TH");
        weekMap.put(Short.valueOf("5"), "FR");
        weekMap.put(Short.valueOf("6"), "SA");
    }

    Short repeatCountMonthly = repeatCount != null ? repeatCount : 0;
    String weekDay = weekMap.get(<repeatMonthWeek>);
    //Create recurrence Rule    
    String monthlyRecurrenceRule = DateUtils.getMonthlyRecurrenceRule(repeatCountMonthly,endsNever,                             endsAfterOccurrences,endTime,repeatMonthDay,weekDay);
    //Create recurrence Dates
    Set<LocalDate> monthlyStartDates = CalendarUtils.getRecurrenceDates(monthlyRecurrenceRule,
                    LocalDate.fromDateFields(startDate));

}

Класс будет иметь методы для создания правила и генерации дат:

class DateUtils{

            public static String getMonthlyRecurrenceRule(Short interval,boolean endsNever,Integer occurrences, StringBuilder endTime,Short dayOfMonth,String dayOfWeek){
                StringBuilder monthlyRecurrenceRule = new StringBuilder("RRULE:FREQ=MONTHLY");

                if(interval!=null&&interval.intValue()>0)
                    monthlyRecurrenceRule.append(";INTERVAL=").append(interval.toString());

                if(dayOfMonth!=null && dayOfMonth>0)
                    monthlyRecurrenceRule.append(";BYMONTHDAY=").append(dayOfMonth.toString());
                else
                    monthlyRecurrenceRule.append(";BYDAY=").append(dayOfWeek);

                if(endsNever){
                    //set endtime as startdate+10 years
                    monthlyRecurrenceRule.append(";UNTIL=").append("20271231T090000Z");
                }
                else{
                    if(occurrences!=null&&occurrences.intValue()>0)
                        monthlyRecurrenceRule.append(";COUNT=").append(occurrences.toString());
                    else
                        monthlyRecurrenceRule.append(";UNTIL=").append(endTime.toString());
                }

                return monthlyRecurrenceRule.toString();
            }

            public static Set<LocalDate> getRecurrenceDates(String rRule,LocalDate startDate) throws ParseException{
                Set<LocalDate> recurrenceDates = new HashSet<LocalDate>();

                for (LocalDate date : LocalDateIteratorFactory.createLocalDateIterable(rRule, startDate, true)) {
                     recurrenceDates.add(date);
                    }

                return recurrenceDates;
            }   

        }
person Riddhi Gohil    schedule 23.09.2016
comment
аналогичный код у меня есть здесь. Но я не знаю, какая библиотека используется в примере. Откуда у вас CalendarUtils.getRecurrenceDates(..) (библиотека репозитория, ссылка git и т. д.)? - person Sergii; 14.07.2017

У меня была аналогичная проблема с этим API. К сожалению, сейчас у меня нет кода, но я помню, что проблема заключалась в том, что некоторые свойства были «необязательными». Существует API, который позволяет их регистрацию. Я рекомендую вам загрузить исходный код и проверить, что делает метод validate. Вы увидите, что он проверяет, находится ли свойство в коллекции (или на карте). Затем просто найдите тот метод, который добавляет свойства в эту коллекцию.

Если у вас возникли проблемы с получением исходного кода, просто декомпилируйте файлы классов. Я лично сделал это с этим пакетом. Я использовал плагин для eclipse, который декомпилирует каждый класс, не имеющий связанного исходного кода: http://java.decompiler.free.fr/?q=jdeclipse

Извините, что мой ответ недостаточно конкретен, но я все равно надеюсь, что он будет полезен. Удачи.

person AlexR    schedule 16.10.2011
comment
Вы также можете увидеть исходный код в отчетах по проекту здесь: ссылка - person fortuna; 18.10.2011