我正在构建一个需要支持重复事件的组日历应用程序,但我提出的处理这些事件的所有解决方案似乎都很简单。我可以限制一个人可以看多远的未来,然后一次性生成所有事件。或者,我可以将事件存储为重复的,并在日历上动态显示它们,但如果有人想更改事件的特定实例的细节,则必须将它们转换为正常事件。

我相信有更好的办法,但我还没找到。对重复发生的事件建模的最佳方法是什么?在这种方法中,您可以更改或删除特定事件实例的细节?

(我使用Ruby,但请不要让这限制了你的回答。如果有ruby特定的库或其他东西,那么最好知道。)


当前回答

查看下面的文章,了解三个优秀的ruby日期/时间库。 对于递归规则和事件日历需要的其他东西,Ice_cube似乎是一个可靠的选择。 http://www.rubyinside.com/3-new-date-and-time-libraries-for-rubyists-3238.html

其他回答

您可以直接将事件存储在iCalendar格式中,这允许无限重复、时区本地化等等。

您可以将这些存储在CalDAV服务器中,然后当您想要显示事件时,您可以使用CalDAV中定义的报告选项,要求服务器在所查看的时间段内扩展重复出现的事件。

或者你可以自己将它们存储在数据库中,并使用某种iCalendar解析库来进行扩展,而不需要PUT/GET/REPORT与后端CalDAV服务器进行对话。这可能是更多的工作-我相信CalDAV服务器隐藏的复杂性在某个地方。

从长远来看,以iCalendar格式保存事件可能会让事情变得更简单,因为人们总是希望将它们导出,以便放在其他软件中。

From these answers, I've sort of sifted out a solution. I really like the idea of the link concept. Recurring events could be a linked list, with the tail knowing its recurrence rule. Changing one event would then be easy, because the links stay in place, and deleting an event is easy as well - you just unlink an event, delete it, and re-link the event before and after it. You still have to query recurring events every time someone looks at a new time period never been looked at before on the calendar, but otherwise this is pretty clean.

I would use a 'link' concept for all future recurring events. They are dynamically displayed in the calendar and link back to a single reference object. When events have taken place the link is broken and the event becomes a standalone instance. If you attempt to edit a recurring event then prompt to change all future items (i.e. change single linked reference) or change just that instance (in which case convert this to a standalone instance and then make change). The latter cased is slightly problematic as you need to keep track in your recurring list of all future events that were converted to single instance. But, this is entirely do-able.

因此,在本质上,有两类事件-单个实例和重复事件。

将事件存储为重复事件并动态地显示它们,但是允许重复事件包含特定事件的列表,这些事件可以覆盖特定日期的默认信息。

当您查询重复发生的事件时,它可以检查当天的特定覆盖。

如果用户进行了更改,那么您可以询问他是希望更新所有实例(默认详细信息)还是仅更新当天(创建一个新的特定事件并将其添加到列表中)。

如果用户要求删除此事件的所有递归,您还可以获得详细信息列表,并可以轻松删除它们。

唯一有问题的情况是用户想要更新这个事件和所有未来的事件。在这种情况下,你必须把重复发生的事件分成两部分。此时,您可能需要考虑以某种方式链接重复发生的事件,以便将它们全部删除。

在javascript中:

处理重复的日程安排: http://bunkat.github.io/later/

处理这些计划之间的复杂事件和依赖关系: http://bunkat.github.io/schedule/

基本上,您创建规则,然后要求库计算接下来的N个重复事件(是否指定日期范围)。可以对规则进行解析/序列化,以便将它们保存到模型中。

如果您有一个重复发生的事件,并且只想修改其中一个重复发生的事件,您可以使用except()函数来取消特定的一天,然后为该条目添加一个新的修改过的事件。

库支持非常复杂的模式,时区,甚至croning事件。