java - RFC5545。同时计算 RRULE 和 EXDATE (EXRULE) 的事件发生次数

标签 java calendar find-occurrences rfc5545 ical4j

我必须计算事件的发生次数。计算应基于重复事件模式。重复事件模式为 rfc5545基于。

我找到了lib-recur库来计算出现次数。在下面的描述中,我看到它们使用特定实例集的实例(例如 rrule、exrule、rdates 或 exdates 列表)提供计算。我用RRULE计算,看起来有效。我需要在我的逻辑中正确找到所有出现的情况,包括计算EXDATEEXRULE。但似乎最后的排除在这里不支持。 小代码示例:

import org.dmfs.rfc5545.DateTime;
import org.dmfs.rfc5545.recurrenceset.RecurrenceRuleAdapter;
import org.dmfs.rfc5545.recurrenceset.RecurrenceSet;
import org.dmfs.rfc5545.recurrenceset.RecurrenceSetIterator;
@Test
public void testSpecial() throws InvalidRecurrenceRuleException {
    RecurrenceRule recurrenceRule = new RecurrenceRule("FREQ=YEARLY;BYMONTHDAY=23;BYMONTH=5;COUNT=3");
    RecurrenceRuleIterator it = recurrenceRule.iterator(DateTime.nowAndHere());
    int maxInstances = 10; // limit instances for rules that recur forever
    while (it.hasNext() && (!recurrenceRule.isInfinite() || maxInstances-- > 0)) {
        DateTime nextInstance = it.nextDateTime();
        // do something with nextInstance
        System.out.println(nextInstance);
    }
}

结果:

20170714T163325

20180523T163325

20190523T163325

我还知道google based library可以为基于rfc5545标准的RRULES、EXRULE...提供核心处理程序。但我还没有找到如何计算这里的出现次数(包括RRULES、EXDATE、EXRULE)。

更多关于 google-rfc-2445 库的示例:

import com.google.ical.compat.jodatime.LocalDateIterable;
import com.google.ical.compat.jodatime.LocalDateIterator;
import com.google.ical.compat.jodatime.LocalDateIteratorFactory;
import com.google.ical.values.RRule;
@Test
public void test() throws ParseException {
    String sRule = "RRULE:FREQ=YEARLY;COUNT=3;INTERVAL=2;BYMONTH=5;BYMONTHDAY=22,23,24,25,26,27,28;BYDAY=MO";
    LocalDateIterable localDateIterable = LocalDateIteratorFactory
            .createLocalDateIterable(sRule, org.joda.time.LocalDate.now(), true);
    LocalDateIterator iterator = localDateIterable.iterator();
    while (iterator.hasNext()) {
        System.out.println(iterator.next());
    }
}

结果:

2017-07-14

2019-05-27

2021-05-24

2023-05-22

请分享已经具有复杂出现计算功能的开源库的链接(计算应同时包括RRULE、EXDATE)。

最佳答案

lib-recur 支持计算递归集。不过,该组件的接口(interface)还不够完善(而且不太方便)。

以下是一个简短示例,说明它如何与一个 RRULE 和一个 EXRULE 配合使用:

// note: recurrence expansion takes place in a specific time zone
TimeZone tz = TimeZone.getDefault();
// the start of the recurring event
DateTime start = new DateTime(tz, 2017, 5 - 1 /* zero based */, 23, 12, 0, 0);

// parse the RRULE
RecurrenceRule recurrenceRule = new RecurrenceRule("FREQ=YEARLY;BYMONTHDAY=23;BYMONTH=5;COUNT=30");
// parse the EXRULE (in this case every 3rd instance of the RRULE)
RecurrenceRule exceptionRule = new RecurrenceRule("FREQ=YEARLY;INTERVAL=3;BYMONTHDAY=23;BYMONTH=5;COUNT=10");

// create an empty RecurrenceSet
// a recurrence set is the set of all actual instance of a recurring event and may consist of multiple instance and excludes sources 
RecurrenceSet recurrenceSet = new RecurrenceSet();
// add the instances of the RRULE
recurrenceSet.addInstances(new RecurrenceRuleAdapter(recurrenceRule));
// exclude the instances of the EXRULE
recurrenceSet.addExceptions(new RecurrenceRuleAdapter(exceptionRule));

RecurrenceSetIterator recurrenceSetIterator = recurrenceSet.iterator(start.getTimeZone(), start.getTimestamp());

int maxInstances = 10; // limit instances for rules that recur forever
// iterate as long as the recurrence set still has instances
while (recurrenceSetIterator.hasNext() && (!recurrenceRule.isInfinite() || maxInstances-- > 0))
{
    // get the next instance of the recurrence set
    DateTime nextInstance = new DateTime(start.getTimeZone(), recurrenceSetIterator.next());
    // do something with nextInstance
    System.out.println(nextInstance);
}

您可以看到 RecurrenceSet时间戳上运行,这远非理想。

要支持 RDATESEXDATES,您可以使用 RecurrenceList 适配器。 RecurrenceList 要么采用时间戳数组或时区以及逗号分隔的日期时间或日期值字符串(就像为 RDATES 和 EXDATES 定义的那样):

// add more RDATES instances 
recurrenceSet.addInstances(new RecurrenceList("20171212T121212,20181212T121212", tz));

// add EXDATES
recurrenceSet.addExceptions(new RecurrenceList("20180523T120000,20190523T120000", tz));

请注意,与 RecurrenceRuleIterator 内容相比,该组件还没有任何测试覆盖率。

关于java - RFC5545。同时计算 RRULE 和 EXDATE (EXRULE) 的事件发生次数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45101330/

相关文章:

javascript - UI Bootstrap datepicker 日历不在文本框中显示日期

powerbi - PowerBI 日期累计发生次数?

Java保存字符串

Java函数重载

python 日期时间、时间和日历重叠功能

android - vcalendar 与 icalendar

regex - Ansible:如何查找变量中出现的单词?

nlp - Spacy:计算每个句子中特定标记的出现次数

java - Android Studio Gson 到内部存储

java - PDFBox - 删除不可见文本(通过剪辑/填充路径问题)