Dan*_*ski 31 language-agnostic design-patterns data-structures
我正在寻找用于存储重复事件的数据结构模式,但我想出的所有内容都会导致大量特殊情况处理或用户输入和数据检索过于复杂.(我得到了明显的感觉,我还没有完全理解问题领域.)
如何存储Outlook风格的定期事件?
Mar*_*son 17
支持标准的iCalendar事件类型
IETF在创建互联网日历和调度核心对象规范(更好地称为iCalendar)时考虑了这一点.
规范包括事件重现.
此外,您的数据库还可以与其他iCalendar兼容数据源(如Google和Apple日历)共享数据.
Vin*_*vic 16
有各种论文描述了这个用例的数据结构和算法.此外,您还可以看到crontab和Quartz(Java)或Quartz.NET(.NET)的开源实现的代码或描述.
这是一篇这样的论文
http://portal.acm.org/citation.cfm?id=359763.359801&coll=ACM&dl=ACM&CFID=63647367&CFTOKEN=55814330
例如,cron存储这样的信息(*意味着每个,所以*月份意味着每个月)
.---------------- minute (0 - 59) | .------------- hour (0 - 23) | | .---------- day of month (1 - 31) | | | .------- month (1 - 12) OR jan,feb,mar,apr ... | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat | | | | | * * * * * There are several special entries, most of which are just shortcuts, that can be used instead of specifying the full cron entry: Entry Description Equivalent To @reboot Run once, at startup. None @yearly Run once a year 0 0 1 1 * @annually (same as @yearly) 0 0 1 1 * @monthly Run once a month 0 0 1 * * @weekly Run once a week 0 0 * * 0 @daily Run once a day 0 0 * * * @midnight (same as @daily) 0 0 * * * @hourly Run once an hour 0 * * * *
Event: StartDate EndDate (calculated on change of NumberOfOccurances) NumberOfOccurances (calculated on change of EndDate ) Frequency e.g. 1/2hrs, 1/month, 1/day, .... CorrectionFunction e.g. first Tuesday, last Sunday, ... bool OccuresOn(day) Date NextOccurance(date)
这是我的看法 - 请告诉我,如果我遗漏了什么:
根据Outlook Recurrence选项,您有一个包含常规必填字段的表:
FieldName DataType Sample Data
ID int primary key
EventID int foreign key (to EventID from Event Table)
StartTime DateTime 8:00 AM
EndTime DateTime 8:30 AM
Duration int 30 (minutes)
StartDate DateTime 01/25/2014
EndBy DateTime 01/25/2024
NoEndDate bit False
NumOccurrences int 10
RecurrenceType int ****See below for instructions on how to use these last 6 fields
Int1 int
Int2 int
Int3 int
String1 nvarchar(50)
IntYears int
Run Code Online (Sandbox Code Playgroud)
这是神奇发生的地方.这个逻辑只需要4个整数和一个字符串.
The month of year (1 = Jan, 12 = Dec),
The day of the month (1 = the 1st, 31 = 31st),
Day of the week (0 = Sunday, 1=Monday, 6= Saturday),
Week of the month (1 = first, 4 = forth, 5 = last),
Yearly reocurrence ( 1=1,2=2)
When multiple days can be selected I use a comma delimited string (1,3,5 = Monday, Wed, Friday)
Run Code Online (Sandbox Code Playgroud)
我按照它们出现在outlook Appointment Recurrence调度程序中的顺序输入3个整数,这样可以节省额外的费用,逻辑,烦恼. *如果您打开outlook appt调度程序,这将更容易遵循:
The RecurrenceType field can be any of the 7 following choices
Run Code Online (Sandbox Code Playgroud)
(每日,每月和每年有2个选项,每周有一个选项):
10 = Daily (Every `Int1` day(s) )
Every 4 day(s)
11 = Daily (Every Weekday) -- no variables needed
Every Weekday (MTWTF)
20 = Weekly (Recur every `Int1` week(s) on: `String1`
Recur every 3 week(s) on Monday, Wednesday, Friday
(`String1` will be a list of days selected (0=Sunday, 1=Monday, 2=Tuesday... 7=Saturday) so for (Mon, Wed, Fri) String1 would hold "1,3,5". You would parse this on the code side to pull the actual days.)
30 = Monthly (Day `Int1` of every `int2' month(s)
Day 28 of every 2 month(s)
31 = Monthly (The `Int1` `Int2` of every `Int3` month(s)
The forth Tuesday of every 1 month(s)
40 = Yearly (Recur every `intYears` year(s) On `Int1` `Int2`) --
Recur every 1 year(s) on Jan 28th
41 = Yearly (Recur every `intYears` year(s) on the `Int1` `Int2` of `Int3`) --
Recur every 1 year(s) on the forth Tuesday of January
Run Code Online (Sandbox Code Playgroud)
拉动或保存重复的代码变得相当简单
if (RecurrenceType = 10 )
Every `int1` days
if (RecurrenceType = 11)
Every Weekday
if (RecurrenceType = 20)
Every `int1 weeks on
parse `string1` and populate checkboxes for Mon, Tues, ...
if (RecurrenceType = 30)
`int1 day of every `int2` month
etc...
Run Code Online (Sandbox Code Playgroud)
我希望我能够彻底解释这一点.如果有什么不清楚或是否不起作用,请告诉我.我正在为当前的应用程序构建此功能.谢谢大家.