8

我跑了很多 RRULE 只是为了测试google-rfc-2445IETF RFC 2445 iCalendar的 Java 实现)的性能。

我看到在某些情况下,我在方法的返回列表中得到了开始日期。

测试非常简单:

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 页面上的问题

4

2 回答 2

3

RFC2445 第 4.3.10 节 Recurrence Rule指定

[...] COUNT 规则部分定义了对重复范围进行范围限制的出现次数。“DTSTART”属性值(如果指定)计为第一次出现。[...]

因此,虽然DTSTART返回列表中存在 是正常的,但不太期望的是返回列表的大小。

DTSTART鉴于 RFC2445 规范,让重复的第一个实例也确保其他日历正确理解 ical 文件更有意义。

还要注意RFC2445的是已经过时了RFC5545,它还指定了DTSTART作为的第一个实例RRULE(甚至强调它,注意:添加的词总是(emahsis由我添加)

RFC5545 RRULE 部分:COUNT 规则部分定义了对重复范围进行范围限制的出现次数。“DTSTART”属性值始终计为第一次出现。

于 2014-12-26T16:24:39.183 回答
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 规则排除第一个日期。

于 2014-12-23T21:57:13.107 回答