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

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

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


当前回答

您可以将事件存储为重复的,如果编辑了特定实例,则创建具有相同事件ID的新事件。然后,在查找事件时,搜索具有相同事件ID的所有事件以获得所有信息。我不确定您是否滚动了自己的事件库,或者您是否正在使用现有的事件库,因此可能无法实现。

其他回答

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.

我建议使用ruby的date库的功能和range模块的语义。循环事件实际上是一个时间,一个日期范围(开始和结束),通常是一周中的某一天。使用日期和范围可以回答任何问题:

#!/usr/bin/ruby
require 'date'

start_date = Date.parse('2008-01-01')
end_date   = Date.parse('2008-04-01')
wday = 5 # friday

(start_date..end_date).select{|d| d.wday == wday}.map{|d| d.to_s}.inspect

产生事件的所有日子,包括闰年!

# =>"[\"2008-01-04\", \"2008-01-11\", \"2008-01-18\", \"2008-01-25\", \"2008-02-01\", \"2008-02-08\", \"2008-02-15\", \"2008-02-22\", \"2008-02-29\", \"2008-03-07\", \"2008-03-14\", \"2008-03-21\", \"2008-03-28\"]"

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

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

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

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

我开发了多个基于日历的应用程序,还编写了一组支持递归的可重用JavaScript日历组件。我写了一篇关于如何设计递归式的概述这可能对一些人有帮助。虽然有一些建议是针对我所编写的库的,但所提供的绝大多数建议都适用于任何日历实现。

以下是一些要点:

Store recurrence using the iCal RRULE format -- that's one wheel you really don't want to reinvent Do NOT store individual recurring event instances as rows in your database! Always store a recurrence pattern. There are many ways to design your event/exception schema, but a basic starting point example is provided All date/time values should be stored in UTC and converted to local for display The end date stored for a recurring event should always be the end date of the recurrence range (or your platform's "max date" if recurring "forever") and the event duration should be stored separately. This is to ensure a sane way of querying for events later. Read the linked article for more details about this. Some discussion around generating event instances and recurrence editing strategies is included

这是一个非常复杂的话题,有很多很多有效的方法来实现它。我要说的是,我实际上已经成功地实现了几次递归,并且我会谨慎地从那些没有实际使用过递归的人那里获得建议。

如果你有一个没有结束日期的重复约会怎么办?虽然空间很便宜,但你没有无限的空间,所以解决方案2在那里是行不通的……

我建议,“没有结束日期”可以解决到本世纪末的结束日期。即使是日常活动,场地数量也很便宜。