使用google-rfc-2445(iCalendar)时,有些情况下会返回开始日期。

8
我为了测试 google-rfc-2445IETF RFC 2445 iCalendar 的 Java 实现)的性能而运行了许多 RRULEs。
我发现在某些情况下,返回的列表中包含了开始日期。
这个测试非常简单:
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);
    }
}

工厂返回的列表返回此列表。
第一个日期是开始日期,它是一个不应该存在的星期六。 RRULE 中还包含 COUNT=10,为什么要返回 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

有人使用Google-rfc-2445遇到过这个问题吗?

我在项目页面上发布了这个问题,但那里很安静。 链接到Google-rfc-2445页面上的问题

2个回答

3

RFC2445第4.3.10节“重复规则”指定:

[...] COUNT规则部分定义了要限制重复次数的次数。如果指定了“DTSTART”属性值,则计为第一次出现。[...]

因此,返回列表中存在DTSTART是正常的,但返回列表的大小比较意外。

根据RFC2445规范,让DTSTART成为重复的第一个实例更有意义,以确保其他日历正确理解ical文件。

还需注意的是,RFC2445RFC5545废止,后者还将DTSTART指定为RRULE的第一个实例(甚至强调了这一点,注意:我添加了always这个词)。

RFC5545 RRULE节:COUNT规则部分定义了要限制重复次数的次数。 "DTSTART"属性值始终计为第一次出现。


我因为和主题发起人一样的问题而来到这里,你的答案起初帮了我很大的忙,但是在我找到rrule.js库之后,它让我更加困惑了。如果我在这里使用这个RRULE字符串 FREQ=WEEKLY;COUNT=10;BYDAY=MO;DTSTART=20150301:http://jakubroztocil.github.io/rrule/ 它会给我确切的10次出现,而不计算DTSTART作为第一次出现,这是错误的吗?可能是rrule.js没有正确实现吗?谢谢。 - Anatoly

2

尝试这样做:

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();

}

这个想法是提前一天开始序列,并使用EXDATE规则排除第一个日期。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接