2009-10-10 12 views
30

Ich bin auf der Suche nach einem Datenstrukturmuster für die Speicherung von wiederkehrenden Ereignissen, aber alles, was ich kam, würde zu einer hohen Anzahl von Sonderfällen führen oder Benutzereingaben und Datenabruf sind übermäßig komplex. (Ich habe das deutliche Gefühl, dass ich die Problemdomäne nicht gut genug verstanden habe, um dies zu tun.)Datenstruktur zum Speichern wiederkehrender Ereignisse?

Wie kann ich Outlook-ähnliche wiederkehrende Ereignisse speichern?

  • Jeden Tag um 08.00 Uhr
  • Jeden ersten Dienstag im Monat
  • Jeden 1. Dezember drei Jahre
  • alle zwei Stunden für eine Woche
  • ...

Antwort

16

Es Verschiedene Arbeiten beschreiben Datenstrukturen und Algorithmen für diesen Anwendungsfall. Außerdem können Sie den Code oder die Beschreibungen der Open Source-Implementierung von crontab und von Quartz (Java) oder Quartz.NET (.NET) sehen.

Dies ist ein solches Papier

http://portal.acm.org/citation.cfm?id=359763.359801&coll=ACM&dl=ACM&CFID=63647367&CFTOKEN=55814330

Zum Beispiel cron speichert die Informationen wie folgt aus (* jedes Mittel, so ein * unter Monat bedeutet jeden Monat)

 

.---------------- 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 * * * * 

6
 
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) 
17

Unterstützt den Standard iCalendar Ereignistypen

Die IETF setzen einige Gedanken in diese, wenn sie erstellt die Internet Kalender und Terminplanung Core-Object Specification, besser bekannt als iCalendar.

Die Spezifikation enthält Ereigniswiederholung.

Als zusätzlichen Bonus ist Ihre Datenbank für den Austausch von Daten mit anderen iCalendar-kompatiblen Datenquellen wie Google und Apple-Kalendern geeignet.

http://tools.ietf.org/html/rfc5545

5

Hier ist mein nehmen - bitte lassen Sie mich wissen, wenn ich etwas fehle:

Basierend auf den Outlook Recurrence Optionen, haben Sie eine Tabelle mit den regulären notwendigen Felder:

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 

Hier passiert die Magie. Diese Logik benötigt nur 4 ganze Zahlen und eine Zeichenfolge.

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) 

ich die drei Zahlen in der Reihenfolge, wie sie in dem Outlook-Termine Recurrence Scheduler erscheinen eingegeben hat, speichert diese zusätzliche feilds, Logik, Ärger. * Wenn Sie auf die Aussichten APPT Scheduler öffnen, wird dies etwas einfacher zu folgen:

The RecurrenceType field can be any of the 7 following choices 

(Es gibt 2 Möglichkeiten für Tages-, Monats- und Jahres, und eine Option für Woche):

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 

Der Code zu ziehen oder die reocurrence speichern wird ziemlich einfach

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... 

Ich hoffe, ich erkläre das gründlich genug. Lassen Sie mich wissen, wenn etwas unklar ist oder ob es nicht funktioniert. Ich baue dies für eine aktuelle App. Dank an alle.

+0

Hey! Gute Antwort! Es bleibt eine offene Frage offen: Gibt es eine schnelle Möglichkeit, alle Daten zwischen dem Startdatum und dem Ende nach Datum zu berechnen, ohne jedes Datum zu wiederholen? –

Verwandte Themen