leo*_*ora 29 c# icalendar recurrence calendar
我正在构建一个日历网站(ASP.NET MVC
)应用程序(想想outlook的简单版本),我想开始支持重复出现的日历事件(每月,每年等)
现在我正在存储我的实际日期,但我想弄清楚是否重复,是否有意义继续存储日期(有一些明显的截止),或者我应该存储重复选项并在运行中生成日期.
它让我思考Outlook,谷歌邮件等是如何做这个或任何其他支持重复日历项目的服务.
对此有什么建议吗?
Jon*_*eet 48
将您的数据分为两部分:"规范"数据(重复规则)和"服务"(生成日期;除了重新生成之外的只读数据).如果规范数据发生更改,请在该点重新生成"服务"数据.对于无限重复,保留一定数量的实例并在用完时生成更多实例(例如,如果用户查看其2020年的日历).
如果你有无限的处理器速度,你只需要规范数据 - 但实际上,在每个页面视图上对所有重复规则进行所有日期/时间处理可能太耗时...所以你交易关闭一些存储(和复杂性)以保存重复计算.与大量事件所需的计算相比,存储通常非常便宜.如果您只需要存储事件的日期,那真的非常便宜 - 您可以轻松地使用4字节整数来表示日期,然后从中生成完整的日期/时间,假设您的重复都是基于日期的.对于基于时间的重复(例如"每三个小时"),您可以完整的UTC时刻 - 只要您可能需要,8个字节就可以表示非常精细的分辨率.
你必须要小心,虽然保持有效性-如果定期召开的会议发生变化的今天,当它不改变已经发生过的事情...所以你可能想也有关于复发时实际发生的典型的只读数据.显然你不会希望永远保持过去,所以你可能想要"垃圾收集"超过几年的事件,这取决于你的存储限制.
您可能还需要能够在每次出现的基础上添加注释和例外(例如,"由于公共假日而未在今天开会"或"移至下午4点").当你改变复发时,这变得非常有趣 - 如果你将"每个星期一"更改为"每个星期二",你是否保留了例外情况?当你从"每一天"变为"每周"时,你如何匹配例外情况?这些不是直接关于存储的问题 - 但存储决策将影响实施您决定的任何策略的容易程度.
您需要单独处理事件和事件.
事件明智:对于事件,您需要存储复发规则(可以是rfc5545指定的规则,但也可以是rfc5545中的rdate等明确的日期集),但也有异常(参见rfc5545的exdate和rfc2445中的exrule) .您还需要跟踪这些规则的变化:rdate,exdate的变化在将来发生时没有问题,在过去的日期会被忽略.由于影响之前的出现,rrule的变化更加棘手.我个人的偏好是为旧的和新的rrule添加一个特定的属性,以指定它们各自的开始和结束日期.
如果事件的时间跨度有限(比如COUNT或UNTIL属性),则应将其开始和结束存储在表中,以便更容易查询事件(特别是在预先计算的时间窗口之外查找事件时(见下文),可以帮助减少重新计算的事件数量).
发生故障:对于出现的情况,您应该将实例存储在当前周围的预定义窗口内(例如+/- 6个月或12个月并定期计算)并保留此记录以允许重新计算,如果您的用户希望进一步查看未来(表演问题).您还应该考虑计算索引(RECURRENCE-ID)以帮助更容易地找到下一个事件.
在后端更少,但在前端更多,你还应该跟踪tzid更改,以询问用户是否在某个给定的tzid上安排的事件,如果它要保持在当前时区,则需要更新(想想萨摩亚岛上有人安排在2011年12月30日星期五举行会议,然后国家决定这一天不存在),同样地,你可以询问在夏令时期间发生的事件是否意味着"从不发生"或'发生两次’(更多关于这个话题在这里)
注意:您可能需要考虑超出rfc5545在rencence规则中定义的支持,并且还要添加对宗教经常性规则的支持(请参阅USNO日历介绍或来自E. Reingol和N的印刷"Calendrical Calculations"(第三版) .德肖威茨)
由于您询问现有的实现,您可以轻松检查sunbird(sqlite)或Apple开源日历和联系人服务器的数据库模式,这是caldav服务器的现有开源项目的更完整列表(可能是其中的一部分)你在寻找)可以在这里)
我必须构建一个与调度一起工作的系统,我们两个都做了.这就是我们所拥有的
随着日程安排,事情变得非常棘手,因为您必须记住,在任何时间点,日程安排都可能发生变化.此外,当您的应用程序未运行时,项目可能到期,并且当它再次启动时,您需要知道如何识别过期项目.
此外,我们确保跟踪实际时间表的表格是独立的.原因是这些是系统中最复杂的表集合,我们希望能够重用它们,以便它们可以用于需要调度的不同事物.例如发送管理员电子邮件,发送通知以及清理日志文件等服务器维护.