我需要存储某事是否发生一次,每天,工作日,每周,一周中的某些天,一个月中的某些天,这可能是数字或符号,例如每个月的第一个星期一,等等。
有什么建议吗?有什么要查看的代码、数据结构或架构吗?
我需要存储某事是否发生一次,每天,工作日,每周,一周中的某些天,一个月中的某些天,这可能是数字或符号,例如每个月的第一个星期一,等等。
有什么建议吗?有什么要查看的代码、数据结构或架构吗?
有复杂的解决方案和简单的解决方案。两个最简单的解决方案是:
将重复事件扇出到某个恒定数量的实例,或最多到将来某个固定的日期范围。为每个指向重复描述的实例存储一个 FKrecurrence_id,并允许批量编辑和取消。
预先计算的扇出方法的优点是它可以非常容易地实现重复异常,这几乎肯定是您获得的第一个功能请求。
在显示时计算。计算机速度很快,根据您希望能够回答的有关数据的问题,计算一个日期范围内的所有事件通常很容易。您可以聪明地尝试在进行重复计算之前快速将您的日期范围括起来,或者您可以从开始日期开始强制使用它。
除此之外,您只需要一个存储重复规则的解决方案,该规则适用于您用于计算重复的任何内容。(例如,如果您使用 iCalendar 启用库,则您的架构是 varchar(255),其中包含 RRULE 值)
如果您必须推出自己的重复周期计算器,并且希望保持简单,则将重复周期限制为每天、每周、每月或每年覆盖您的前 80% 用例,并且非常容易计算。
此时您的潜在重复模式看起来像:
id
recurrence_start
recurrence_end
type (daily|weekly|monthly|yearly)
day_of_week (for weekly)
month
day_of_month
坦率地说,复杂的解决方案可能不值得:)
这听起来像是 Outlook 中的“重复事件”。我将使用一个名为 RecurrenceType 的表来存储每个时间段(每天、每周等)。另一个名为 Event 的表将按键引用 RecurrenceType。然后可以使用标准日期函数计算大多数重复类型的未来日期。
问题是指定这样的间隔有无限的可能性。例如 - “如果日期是偶数,但不是 4,并且该月不是长年的二月,则每隔一个月的第一个星期一”。你愿意走多远?最终,您只需要让用户输入一个布尔表达式,该表达式在事件再次发生的日子里计算为 TRUE。从 UI 的角度来看不是很好。
您应该确定系统的一些限制。一旦你知道了这些,剩下的就应该很容易了——或者至少可以对 SO 负责。:)
此处描述的架构捕获重复日期
在一个相关的、有用的 SO 线程中提到了它,但是如果你碰巧使用 Ruby,一个很好的、积极维护的 Runt 替代品是ice_cube。您还没有提到您的存储后端要求是什么,但对于数据库模式,@kellan 和上述线程中的一些是好的开始。