如何在数据库表中查询存储为iCal RRULE的定期约会?

时间:2016-09-28 17:30:47

标签: jquery sql sql-server icalendar rrule

如果我有一个包含以下列的约会表,我如何查询该套期以提取在特定日期或两个日期之间发生的约会?

Appointments
------
id
name
dt_start
dt_end
rrule

例如,假设我有一个约会,从2016-09-28开始,到2017年2月28日结束,它发生在2017年周一,周五至2017年4月28日。 以下是RRule:

RRULE:FREQ=WEEKLY;INTERVAL=2;UNTIL=20170428T230000Z;BYDAY=MO,FR EXDATE:20170414T023000Z

因此,使用上面的示例,上述约会的某些日期将包括以下内容:

2016-09-30 FRI
2016-10-10 MO
2016-10-14 FRI
2016-10-24 MO

现在如何使用SQL或任何其他方法查询此表以提取2016-10-10发生的所有约会?

对于记录,这将在C#asp.net和SQL server中完成。是否有可用于解析和查询rrule的C#或SQL Server库?

我已经看了ICAL.net,但似乎没有太多关于它的文档,或者我如何将其用于上述目的。

有没有人有ICAL.net的经验?

2 个答案:

答案 0 :(得分:1)

  

有没有人有ICAL.net的经验?

非,但我是php-rrule的作者,我认为我的答案也适用于您的情况。

让我们先说一下,除非你有一套非常有限的规则并且你知道,例如,没有任何事件将是无限的,或重复超过X次或其他什么,在存储不进行之前扩展规则工作。

据我所知,你不能只在SQL中做到这一点,你必须分两步完成。

  1. 查询2016-10-10之前dt_start所在的所有事件,dt_end是否在2016-10-10之后。
  2. 放弃因2016-11-10规则而未发生的所有事件(例如BYDAY)。为此,您需要一个可以快速计算rrule字段中出现次数的库(例如我猜的ICAL.net)。
  3. 我建议您在完成后缓存结果,因此对于任何后续查询,您将能够读取2016-10-10的缓存,而不是再次进行计算。只要添加,更新或删除dt_startdt_end之间包括2016-10-10的事件,您就必须处理无效缓存。

答案 1 :(得分:0)

如果您有很多重复事件,那么数据库和应用程序需要做很多工作。在我写的日历应用程序中,我在创建事件时扩展了规则,并将每个重复事件放在一个单独的行中。我添加了一个唯一的id字段(icalendar规范中的UID,与id字段分开),因此如果需要,我可以在查询中将重复事件组合在一起(重复序列中的每个事件都具有相同的唯一ID)。使用标准查询搜索日期是一件容易的事。如果它们在规则中,它也可以更容易避免包含异常,这些异常在数据库中没有行。