Start date returns in some cases when using google-rfc-2445 (iCalendar)

家住魔仙堡 提交于 2020-01-12 07:31:07

问题


I ran through a lot of RRULEs just for testing out the performance of google-rfc-2445 (a Java implementation of IETF RFC 2445 iCalendar).

I saw that I got the start date back in some cases in the returning list from the method.

The test is very simple:

private static void runGoogleTests() throws ParseException
{
    DateTimeZone dtz = DateTimeZone.UTC;
    DateTime dtStart = new DateTime("2014-11-22T00:00:00Z", dtz);//SATURDAY
    DateTimeIterable dti = DateTimeIteratorFactory.createDateTimeIterable("RRULE:FREQ=WEEKLY;COUNT=10;BYDAY=MO", dtStart, dtz, true);

    System.out.println("Size of iterable = " + Iterators.size(dti.iterator()));
    for(DateTime dateTime : dti)
    {
        System.out.println(dateTime);
    }
}

The list returned by the factory returns this list.

The first date is the start date and it's a saturday that should not be there. The RRULE also contained a COUNT=10 so why return 11?

Size of iterable = 11
2014-11-22T00:00:00.000Z
2014-11-24T00:00:00.000Z
2014-12-01T00:00:00.000Z
2014-12-08T00:00:00.000Z
2014-12-15T00:00:00.000Z
2014-12-22T00:00:00.000Z
2014-12-29T00:00:00.000Z
2015-01-05T00:00:00.000Z
2015-01-12T00:00:00.000Z
2015-01-19T00:00:00.000Z
2015-01-26T00:00:00.000Z

Someone using the Google-rfc-2445 must have encountered this problem before?

I posted the issue on the projects page but it's very quiet there. Link to the issue on google-rfc-2445 page


回答1:


RFC2445 section 4.3.10 Recurrence Rule specifies that

[...] The COUNT rule part defines the number of occurrences at which to range-bound the recurrence. The "DTSTART" property value, if specified, counts as the first occurrence. [...]

so while the presence of the DTSTART in the returned list is normal, what is less expected is the size of the returned list.

Given the RFC2445 specification, it makes more sense to have the DTSTART being the first instance of the recurrence to also insure that other calendars understand the ical file properly.

Also to be noted RFC2445 is obsoleted by RFC5545 which also specifies the DTSTART as the first instance of the RRULE (and even emphasizes it, note: the added word always (empahsis added by me)

RFC5545 RRULE section: The COUNT rule part defines the number of occurrences at which to range-bound the recurrence. The "DTSTART" property value always counts as the first occurrence.




回答2:


Try something like this:

public static DateTimeIterator createDateTimeIterator(
        final String repeatRules,
        final DateTime scheduleStart,
        final DateTimeZone timeZone) throws ParseException {

    DateTime start = scheduleStart;
    String exdate = "";
    final RRule rrule = new RRule(repeatRules);
    if (rrule.getFreq().ordinal() > Frequency.DAILY.ordinal()) {
        start = start.minusDays(1);
        exdate = "\nEXDATE:"
                + ISODateTimeFormat.basicDateTimeNoMillis().print(start.withZone(timeZone).toLocalDateTime());
    }

    final DateTimeIterable dateIterable = DateTimeIteratorFactory.createDateTimeIterable(
            repeatRules + exdate,
            start,
            timeZone,
            true);

    return dateIterable.iterator();

}

The idea is to start the sequence one day earlier and to exclude the first date by using EXDATE rule.



来源:https://stackoverflow.com/questions/27486705/start-date-returns-in-some-cases-when-using-google-rfc-2445-icalendar

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!