ICal4j 中的递归规则

发布于 2024-12-10 08:34:12 字数 907 浏览 0 评论 0原文

我正在尝试使用 ICal4j 创建 .ics 文件。
但是,当我尝试添加重复时,它失败了,抛出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);

没有这个规则它工作正常,但我想添加这个每周一活动
直到 2011 年 12 月 12 日dateTo 返回的日期)。有什么想法吗?

I'm trying to create an .ics file using ICal4j.
But when I try to add a recurrence it fails, throwing a 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)

My code to add the recurrence is:

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

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

Without this rule it works fine, but I want to add this event every monday
until 12 December 2011 (the date returned by dateTo). Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

情丝乱 2024-12-17 08:34:12

重复发生规则 (RRULE) 属性必须添加到日历中的特定事件 (VEVENT),而不是日历本身。例如

myEvent.getProperties().add(rule);

,如果您希望事件发生在星期一,您可能应该使用这样的规则:

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

这不是我的想法,所以最好检查 RFC 以确保:

https://www.rfc-editor.org/rfc/rfc5545#section-3.3.10

A reccurrence rule (RRULE) property must be added to a specific event (VEVENT) in the calendar, not the calendar itself. e.g.

myEvent.getProperties().add(rule);

Also if you want the event to occur on a Monday you should probably use a rule like this:

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

This is off the top of my head, so best to check the RFC to be sure:

https://www.rfc-editor.org/rfc/rfc5545#section-3.3.10

别再吹冷风 2024-12-17 08:34:12

这是我的重复规则的示例
每周重复规则是

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;
            }   

        }

Here is an example for my recurrence rule for same
Weekly Recurrence Rule is

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>

So as per this your rule will be like : "RRULE:FREQ=MONTHLY;INTERVAL=1;BYDAY=MO;UNTIL=20111212T000000Z"

Given is the code to create recurrence rule and dates

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 will have methods to create Rule and generate Dates:

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;
            }   

        }
乜一 2024-12-17 08:34:12

我对这个 API 也有类似的问题。不幸的是,我现在没有代码,但我记得问题是某些属性是“可选的”。有一个 API 允许他们注册。我建议您下载源代码并查看方法 validate 的作用。您将看到它验证该属性是否在集合(或映射)中。然后只需找到向该集合添加属性的方法即可。

如果您在获取源代码时遇到困难,只需反编译类文件即可。我个人用这个包做到了这一点。我使用 Eclipse 插件来反编译没有关联源代码的每个类: http://java .decompiler.free.fr/?q=jdeclipse

很抱歉我的回答不够具体,但我希望它无论如何都有帮助。祝你好运。

I had similar problem with this API. Unfortunately I do not have the code right now but I remember that problem was that some properties are "optional". There is an API that allows their registration. I'd recommend you to download the source code and check out what does method validate do. You will see that it verifies that the property is in collection (or map). Then just find that method that adds properties to this collection.

If you have troubles with achieving the source code just decompile the class files. I personally did this with this package. I used plugin to eclipse that decompiles every class that does not have associated source code: http://java.decompiler.free.fr/?q=jdeclipse

I am sorry that my answer is not concrete enough but I hope it is helpful anyway. Good luck.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文