2009-10-10 14 views
30

Sto cercando un modello di struttura dati per la memorizzazione di eventi ricorrenti, ma tutto ciò che ho trovato comporterebbe un numero elevato di gestione di casi speciali o l'input dell'utente e il recupero di dati sono eccessivamente complessi. (Ho la netta sensazione, che non ho capito abbastanza bene il dominio del problema per farlo.)Struttura dati per la memorizzazione di eventi ricorrenti?

Come posso archiviare eventi ricorrenti in stile Outlook?

  • Ogni giorno alle 8 del mattino
  • Ogni primo martedì in un mese
  • ogni 1 ° dicembre per tre anni
  • Ogni due ore per una settimana
  • ...

risposta

16

Ci sono vari documenti che descrivono strutture dati e algoritmi per questo caso d'uso. Inoltre è possibile visualizzare il codice o le descrizioni dell'implementazione open source di crontab e di Quartz (Java) o Quartz.NET (.NET).

Questo è uno di questi carta

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

Memorizza ad esempio cron le informazioni come questo (* significa che ogni, quindi un * sotto mese significa che ogni mese)

 

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

Supporta lo standard iCalendar tipi di evento

L'IETF messo qualche pensiero in questo quando hanno creato il Internet Calendaring e Scheduling Nucleo Object Specification, meglio conosciuto come iCalendar.

La specifica include la ricorrenza dell'evento.

Come bonus aggiuntivo, il database sarà disponibile per condividere i dati con altre fonti di dati compatibili con iCalendar come Google e calendari Apple.

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

5

Ecco il mio prendere - per favore fatemi sapere se mi manca nulla:

In base alle opzioni di Outlook ricorrenza, si dispone di una tabella con i campi necessari regolari:

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 

Qui è dove la magia accade. questa logica richiede solo 4 numeri interi e una stringa.

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) 

entro in 3 interi nell'ordine in cui appaiono nella prospettiva Ricorrenza appuntamento scheduler, questo consente di risparmiare feilds extra, logica, fastidio. * Se si apre allo scheduler prospettive appt, questo sarà un po 'più facile da seguire:

The RecurrenceType field can be any of the 7 following choices 

(Ci sono 2 opzioni per tutti i giorni, mensili e annuali, e un'opzione per ogni settimana):

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 

il codice per tirare o salvare il reocurrence diventa abbastanza semplice

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

Spero di spiegarlo abbastanza bene. Fammi sapere se qualcosa non è chiaro o se non funzionerà. Sto costruendo questo per un'app attuale. Grazie a tutti.

+0

Ehi! Bella risposta! Mi lascia una domanda aperta: esiste un metodo rapido per calcolare tutte le date tra la data di inizio e la fine per data, senza iterare ogni data? –

Problemi correlati