反复出现的事件逻辑

Dón*_*nal 12 java groovy calendar

我正在开发一个Groovy/Java日历类型的应用程序,允许用户输入具有开始日期和可选重复的事件.如果它是一个反复出现的事件,它可能会重现:

  • 每月与对应于开始日期的月份日期
  • 每周一周,对应于开始日期
  • 对应于开始日期的每周的每两周一次
  • 等等

我最初计划使用Google日历API来执行所有重复逻辑,但事实证明它是一个巨大的PITA,因为如果有人关心我会进一步讨论.

所以现在,我决定推出自己的解决方案.给定一个日期,我想弄清楚在这个日期是否发生了定期事件.我的逻辑(伪代码)如下:

public boolean occursOnDate(def date, def event) {

  def firstDate = event.startDate

  if (firstDate > date) {
    return false;

  } else if (event.isWeekly()) {
    return event.dayOfWeek() == date.dayOfWeek()

  } else if (event.isMonthly()) {
    return event.dayOfMonth() == date.dayOfMonth()

  } else {
    // At this point we know the event occurs every X weeks where X > 1
    // Increment firstDate by adding X weeks to it as many times as possible, without
    // going past date
    return firstDate == date
  }  
}
Run Code Online (Sandbox Code Playgroud)

这个逻辑似乎是合理的,但是当您考虑所有奇怪的边缘情况时(例如,如何处理2月份首次发生的1月31日的月度重复事件),实际上将会付出相当大的努力.

有没有可以帮助我实现这个的库?一些细节将非常受欢迎(例如,"使用Joda时间"不会获得任何奖励).

谢谢,唐

Gar*_*ryF 8

您想要的那种重复规则在RFC-2445(基本上是iCal规范)中得到了相当明确的规定.获得这种正确的细节可能非常复杂.我建议使用google-rfc-2445库,或者像iCal4J那样使用该规范的其他实现.


mdr*_*drg 2

我对 Groovy 一无所知,我的第一个建议是 Joda,但你知道的。

我知道这对您来说似乎有些过分,甚至可能不适用,但Quartz Scheduler可以很好地处理所有这些重复和事件相关的规则。您无法使用其调度功能,而只能使用 Trigger 类(如CronTrigger)来计算事件日期。

上面的 CronTrigger 链接显示了一些可用于处理事件的表达式示例,例如这种特别令人讨厌的情况:

“0 0 12 L*?” - 在每月最后一天的中午触发一个事件(闰年等不会令人头痛)

夏令时问题也得到处理。

至于代码,创建具有所需重复次数的触发器,然后您可以提取您想要的所有触发时间:

Date firstFireTime = myTrigger.getNextFireTime();
...
while (...) {
    Date nextFireTime = myTrigger.getFireTimeAfter(previousFireTime);
    ...
}
Run Code Online (Sandbox Code Playgroud)

希望这会有用。