我正在寻找模拟重复事件的最佳方法.我正在使用fullcalendar来显示事件.但我想重复发生的事件最好在rails后端处理.
我已经查看了其他问题和现有的示例代码,但我找不到任何合适的东西.
它应该像谷歌日历一样.因此应该可以删除/修改周期性事件系列的单个事件.但是在数据库中保存事件系列的所有事件似乎效率低下.此外,应该可以创建单个事件而不会再次出现.
什么是好的模型架构?
我的事件模型现在看起来像那样(没有其他属性):
# Table name: events
#
# id :integer not null, primary key
# employee_id :integer
# created_at :datetime
# updated_at :datetime
# starts_at :datetime
# ends_at :datetime
#
class Event < ActiveRecord::Base
attr_accessible :starts_at, :ends_at
end
Run Code Online (Sandbox Code Playgroud) calendar ruby-on-rails fullcalendar ruby-on-rails-3 recurring-events
我想为我的项目找到一个ruby gem来处理符合以下要求的reccuring事件:
我找到了两个相关候选人:
你能否提出一个宝石并用它描述积极和消极的经历?
也许你可以添加一些我没有提到的相关标准/要求.
PS Pease某人用1,5K +添加recurring_events标记.谢谢
我正在构建一个需要存储/管理不同类型事件的系统.为简单起见,我将专注于设计一个日历(我正在构建一些稍微不同的东西,但日历是一个很好的比喻,很容易推理).我想听听可能的数据库/架构设计思路.
问题描述
我有一个包含不同类型事件的日历(为简单起见,假设只有一种类型的事件:任务).用户可以为特定日期添加新事件,编辑(更改某些详细信息,如标题或移至其他日期)或删除.可能存在一次性事件和重复事件(具有不同类型的重复:每X天,每月的第15天,周一的每周;有点像简单的cron).当用户移动重复发生的事件时,此事件的所有其他实例都以相同的方式移动(例如:+3天).重要部分:重复发生的事件可能有例外.因此,举例来说,假设我有一个每7天重复一次的重复事件A. 但是我想改变下周的日期,所以不是星期二,而是分配到星期五,之后它仍然会在星期二发生.移动"父"事件时,不应影响此"异常"事件.
此外,每个周期性事件都可以有其他信息,这只与1个特定实例相关,例如:我有相同的重复事件A每7天重复一次,我想为本周实例添加一条说明"X"的注释,以及我想为下个月的事件添加另一个注释"Y" - 这些字段仅对该单个实例可见.
思路
具有常规一次性事件的系统非常简单,因此我不会讨论这个问题,只关注重复发生的事件.
1.一个可能的解决方案是类似于OOP的一个:我可以有一个Event"类"包含字段,例如start_date,end_date(可null), recurrence_type(有点像用枚举的可能值EVERY_X_DAYS,DAY_OF_WEEK,DAY_OF_MONTH)和recurrence_value(说7).当用户添加新的周期性事件时,我只是Event在数据库中创建这样的事件.当用户想改变1次出现此事件,我的新条目添加到该类型的DB /类MovedEvent,从"继承" Event与不同的日期,并且具有附加字段related_to指向ID(或者UUID,如果你愿意)的Event,它的相关.但在同一时间,我需要跟踪所有的MovedEventS(否则我不得不在同一个星期2个显示事件),所以我需要有一个数组moved_events的IDs表示指向所有MovedEvent秒.
缺点:每次我想显示我需要获取的日历Event并从中选择所有事件moved_events,如果我有很多移动的事件,这不是最佳的.
2.另一个想法是每一个事件存储为一个单独的记录.IMO这是一个可怕的想法,但我只是提到它,因为它是一种可能性.缺点:每次我想编辑主要事件(例如:我想将事件从"每7天"更改为"每9天")我需要更改事件的每一次出现.但是,"异常"(更改单个实例)更容易.
SQL/NoSQL的?缩放细节
我在我的项目中使用PostgreSQL,但我对NoSQL数据库有基本的了解,如果它们更适合这类问题,我可以使用它.
比例:假设我有5k用户,每个人每周平均有150个事件,其中40%可以是"例外".因此,我想设计这个系统是有效的.
类似的问题和其他资源
我刚刚开始阅读Martin Fowler的"日历重复事件"(http://martinfowler.com/apsupp/recurring.pdf),但我不确定它是否适用于我的问题,如果适用,我将如何设计数据库根据本文档的架构(欢迎提出建议).
有类似的问题,但我没有看到任何提及"例外"(更改1个事件实例而不影响其他事件),但也许有人会发现这些链接有用:
我已经查看过至少二十几个关于此的主题,还没有真正找到一个好的答案,所以我再次请你再次询问有关重复事件的可怕主题的答案.
我现在每天,每周,每月和每年重复都很好(我仍然需要使用异常事件和诸如此类的东西来修改系统,但它暂时有效).但是,我们希望能够在每个月,每隔一个月的[第一,第二,第三,第四,第五] [太阳|周一|周二|周三|周四|周五|周六]添加重复活动的能力,每三个月一次.
现在,如果我能够理解每个月的逻辑,我可以弄清楚每隔一个月和每三个月.
这里有一点我至今(注:我不是说我做什么的最好方式,但该系统是一个我们非常缓慢更新随着时间的推移,当我们不忙于其他项目,所以因为我有时间,所以我使代码更有效率.
首先,我得到格式化日期计算的开始和结束日期:
$ending = $_POST['end_month'] . "/" . $_POST['end_day'] . "/" . substr($_POST['end_year'], 2, 2);
$starting = $_POST['month'] . "/" . $_POST['day'] . "/" . substr($_POST['year'], 2, 2);
Run Code Online (Sandbox Code Playgroud)
然后我得到这两个之间的区别知道有多少次,使用功能我相当肯定,我发现这里对前一段时间将这个金额28天重复进行,以获得只是它需要多少次重复,使每月有一个:
$repeat_number = date_diff($starting, $ending) / 28;
//find the difference in DAYS between the two dates
function date_diff($old_date, $new_date) {
$offset = strtotime($new_date) - strtotime($old_date);
return $offset/60/60/24;
}
Run Code Online (Sandbox Code Playgroud)
然后我将(第一个,第二个,等等......)部分添加到[Sun | Mon | etc ...]部分,以弄清楚他们想要给我的东西如"第一个星期天":
$find = $_POST['custom_number']. ' ' . $_POST['custom_day'];
Run Code Online (Sandbox Code Playgroud)
然后我使用一个循环,运行需要重复的次数(上面的$ repeat_number):
for($m = 0; $m <= …Run Code Online (Sandbox Code Playgroud) 我知道有关重复发生的事件的问题很常见,但我无法找到一个能够回答这个特定问题的问题,而不是那些与日历应用程序有关的重复事件.主要区别在于我们的应用程序中的事件.只会在报告中或通过他们自己而不是以日历格式出现,尽管在许多方面它们非常相似,可能只是与日历相关的行李较少.
与日历应用程序类似.事件可以一次性发生,也可以重复发生,例如每个星期四或每个月的第一个星期一,直到将来某个预先设定的时间.
事件存储在事件表中,该事件表包含开始和结束日期以及"重新加密类型ID".如果'reurrency type'为'None',则开始日期和结束日期将相同.事件表将id保存到一个单独的表中,该表保存事件类型名称,例如'Meeting'或'Weekly report'
还有一个表格,其中包含"重复种类型"列表,例如"不再发生","每个星期一","每月的第一个星期一"和"月的最后一个星期六".
为了使查找更容易,另一个表包含1960年至2060年的日期列表以及有关每个日期的相关信息,例如是否是星期一,以及星期一的星期几.
这允许查找如下:
SELECT DISTINCT(e.eventid),n.nameid,n.firstname,n.lastname,d.dt,r.recurring
FROM dates d
LEFT JOIN recurringtypes r
/* if event recurring every week E.g. 'Every Monday' */
ON (r.rectypeid BETWEEN 2 AND 8 AND r.day = d.dow)
/* if event recurring every month E.g. 'First Monday, every month' */
OR ((r.rectypeid BETWEEN 9 AND 36) AND r.day = d.dow AND r.occurrence = d.occurrence)
/* if event recurring every last week of month E.g. 'Last Monday, every month' */
OR (r.rectypeid …
我找不到一种方法来将异常日期插入到重复发生的事件中.
我正在使用成功的事件解析.ics文件(ical格式).这是.ics
BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:PUBLISH
X-WR-CALNAME:TESTING
X-WR-TIMEZONE:Europe/Amsterdam
X-WR-CALDESC:
BEGIN:VTIMEZONE
TZID:Europe/Amsterdam
X-LIC-LOCATION:Europe/Amsterdam
BEGIN:DAYLIGHT
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
TZNAME:CEST
DTSTART:19700329T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
TZNAME:CET
DTSTART:19701025T030000
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
DTSTART;TZID=Europe/Amsterdam:20140425T103000
DTEND;TZID=Europe/Amsterdam:20140425T113000
RRULE:FREQ=WEEKLY;BYDAY=FR
EXDATE;TZID=Europe/Amsterdam:20140516T103000
EXDATE;TZID=Europe/Amsterdam:20140502T103000
DTSTAMP:20140425T090449Z
UID:3bb37doi3qcuaih3t03ns0q9jo@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;CN=TESTIN
G;X-NUM-GUESTS=0:mailto:domain.com_o300s@group.calendar.google.com
CREATED:20140425T090310Z
DESCRIPTION:
LAST-MODIFIED:20140425T090427Z
LOCATION:
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:my-recurring-event-with-ex
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR
Run Code Online (Sandbox Code Playgroud)
然后,该事件将通过CalendarContract API插入到Android日历中.
dtstart:20140425T103000 dtend:20140425T113000 rrule:FREQ = WEEKLY; BYDAY = FR
如果我现在查询我的日历,我将在2014年4月25日的每个星期五看到一个活动.
问题是我还需要排除一些日期(见ical:2014年5月2日和2014年5月16日)
我尝试插入16的exdate可能只使用这样的EXDATE字段: 添加日历事件时的android:EXDATE格式 但是这不起作用,并且基于Android日历源代码甚至没有使用它.
我尝试使用CONTENT_EXCEPTION_URI插入异常通过这样的帖子:从原始重复事件中创建异常事件? Google日历代码:https://github.com/android/platform_packages_apps_calendar/blob/master/src/com/android/calendar/EventInfoFragment.java#L1401
ContentValues values2 …Run Code Online (Sandbox Code Playgroud) 我有一个网络调度应用程序,我目前正在重写,并有一些关于如何使用定期约会的问题(我知道,当涉及到重复的appts时,不缺少"什么是最好的方法").
所以我想提供定期约会,其中用户可以安排约会,如6月2日星期六,并且它应该在星期六每隔一周重复一段预定的时间段(例如1年).
什么PHP功能可以帮助我确定"每隔一个星期六"哪个日期落在哪?我附上了我的UI图片以便澄清.

我正在为客户端的 PHP/mySQL 日历应用程序创建规范。必须解决的问题之一是重复发生的事件,其发生率由“每年在 5 月的第一个周末的第一个周末”等规则确定。客户希望能够设置诸如“每三个星期四三月至六月发生”等规则。
客户要求他们有能力定义这些,而不是在接下来的 X 年中用它们预先填充事件发生率表。
是否有任何现有的日历解决方案允许这种基于模式的重复?
是否有任何日历系统基于这样的规则进行查询,而不是在创建或更新重复事件时使用参数在事件表中生成重复事件的发生率?
到目前为止我正在阅读的内容:
一种。 http://martinfowler.com/apsupp/recurring.pdf
湾 http://www.kanzaki.com/docs/ical/recur.html
C。 http://tools.ietf.org/html/rfc5545#page-37
d. http://tools.ietf.org/html/rfc5545#section-3.8.5.3
e. iCal“字段”列表(用于基于 iCal 标准的数据库架构)
G。 http://en.wikipedia.org/wiki/ICalendar#Technical%5Fspecifications
H。 http://muddybranch.thejkgroup.com/2005/01/why-remove-icalendar-recurring-rules/
一世。 构建日历应用程序时,我应该在我的数据库中存储日期或重复规则吗?
注意:这个建议存储重复规则并在 x 个月之前存储基于这些的硬实例。
克。 构建日历应用程序时,我应该在我的数据库中存储日期或重复规则吗?
一世。将您的数据分为两部分:“规范”数据(重复规则)和“服务”(生成的日期;除了重新生成外只读)。如果规范数据发生变化,则在该点重新生成“服务”数据。对于无限重复,保留一定数量的实例并在用完时生成更多实例(例如,如果用户查看他们的 2020 年日历)。
湖 日历重复/重复事件 - 最佳存储方法 独特的答案 w 模式和 SQL
米。 https://github.com/tusharmath/sheql 重复日期的语言
n. https://github.com/tplaner/When 这看起来非常适合基于规则生成日期——包括 RRULE 的
我正在使用一个允许用户在日历上创建事件(一次性或重复性)的Web应用程序,并且在事件启动前不久,系统将通知其参与者.我在为这种通知设计流程时遇到了麻烦,特别是对于重复发生的事件.
定期事件可能已排除日期(类似于RRULE和EXDATE组合).
用户可以更新事件的时间/重复规则.
该应用程序是用Python编写的,并且已经使用带有Redis代理的Celery 3.1.解决方案使用此设置会很好,但任何事情都可以.根据我的发现,目前很难用Celery动态添加周期性任务.
定期任务每天运行一次,扫描每个数据库并添加任务以在适当的时间为每天发生重复的事件发出通知.
如上生成的每个任务都将其ID临时保存在Redis中.如果用户在安排通知任务后更改当天的事件时间,则该任务将被撤销并替换为新任务.
上述解决方案的示例代码:
在tasks.py,所有要运行的任务:
from celery.task import task as celery_task
from celery.result import AsyncResult
from datetime import datetime
# ...
@celery_task
def create_notify_task():
for account in system.query(Account):
db_session = account.get_session() # get sql alchemy session
for event in db_session.query(Event):
schedule_notify_event(account, partial_event)
@celery_task(name='notify_event_users')
def notify_event_users(account_id, event_id):
# do notification for every event participant
pass
def schedule_notify_event(account, event):
partial_event = event.get_partial_on(datetime.today())
if partial_event:
result = notify_event_users.apply_async(
args = (account.id, event.id),
eta = …Run Code Online (Sandbox Code Playgroud)我一直在寻找重复事件的解决方案,到目前为止,我发现了两种方法:
为每个事件创建一个实例,因此,如果用户有一年的每日事件,则表中将需要365行。在固定的时间范围内听起来似乎合理,但是如何处理没有结束日期的事件呢?
创建一个“记录模式”表,该表使用某种“时间”表达式(Martin Fowler)在运行时创建将来的事件。
是否有理由不选择第一种方法而不是第二种方法?第一种方法是填充数据库过多,并可能影响性能,对吗?
关于方法1的引用说:
“将重复发生的事件存储为单独的行是灾难的根源。” (https://github.com/bmoeskau/Extensible/blob/master/recurrence-overview.md)
你们怎么看?我想对为什么会造成灾难有一些见解。
我感谢您的帮助