RFC5545。同时计算 RRULE 和 EXDATE (EXRULE) 的事件发生
RFC5545. Calculate event occurrences for RRULE and EXDATE (EXRULE) at same time
我必须计算事件发生的次数。计算应基于重复事件模式。重复事件模式基于 rfc5545。
我找到了 lib-recur 库来计算出现次数。根据描述,我看到他们使用 特定实例集的实例(例如 rrule、exrule、rdates 或 exdates 列表) 提供计算。我对 RRULE 使用了计算,它似乎有效。我需要在我的逻辑中正确找到所有出现的地方,包括计算 EXDATE、EXRULE。但是这里似乎不支持last exclusions。
小代码示例:
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 可以为 RRULES、EXRULE...提供核心处理程序,基于 rfc5545 标准。但是我在这里也没有找到如何计算出现次数(包括 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
请分享link到已经具备复杂出现计算功能的开源库(计算应该同时包括RRULE,EXDATEs)。
lib-recur
支持计算循环集。不过,这个组件的接口还不完善(也不是很方便)。
这是一个简单的例子,说明它如何使用一个 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
对 long
时间戳进行操作,这远非理想。
要支持 RDATES
和 EXDATES
,您可以使用 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
相比,此组件还没有任何测试覆盖率。
我必须计算事件发生的次数。计算应基于重复事件模式。重复事件模式基于 rfc5545。
我找到了 lib-recur 库来计算出现次数。根据描述,我看到他们使用 特定实例集的实例(例如 rrule、exrule、rdates 或 exdates 列表) 提供计算。我对 RRULE 使用了计算,它似乎有效。我需要在我的逻辑中正确找到所有出现的地方,包括计算 EXDATE、EXRULE。但是这里似乎不支持last exclusions。 小代码示例:
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 可以为 RRULES、EXRULE...提供核心处理程序,基于 rfc5545 标准。但是我在这里也没有找到如何计算出现次数(包括 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
请分享link到已经具备复杂出现计算功能的开源库(计算应该同时包括RRULE,EXDATEs)。
lib-recur
支持计算循环集。不过,这个组件的接口还不完善(也不是很方便)。
这是一个简单的例子,说明它如何使用一个 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
对 long
时间戳进行操作,这远非理想。
要支持 RDATES
和 EXDATES
,您可以使用 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
相比,此组件还没有任何测试覆盖率。