2

I have a set of events that reoccur. I need to be able to calculate when these events occur with the next 5 weeks or so.

This system will inform the user that within this month, these events will occur..

For example:

Event1

  • Date Started = Monday 19th Dec 2011
  • Recurrence Pattern = Monday/Fortnightly

Event2

  • Date Started = Thursday 3rd Feb 2012
  • Recurrence Pattern = Thursday/Every Three Weeks

It's now 22 March - within the next 5 weeks what dates will Events 1 & 2 fall on.

It would also be useful to be able to detect if it's Xmas then the event will fall onto another day.

I'm using .NET MVC2 but I guess that's incidental.

Thanks for any assistance

beebul
  • 993
  • 1
  • 16
  • 37
  • this is a very common theme... http://stackoverflow.com/questions/4517376/recurrence-library-for-date-calculations-for-net – Lloyd Mar 22 '12 at 11:59

2 Answers2

4

Something like this should do the trick:

//enum for various patterns
public enum OccurrenceRate
{
    Weekly,
    Fortnightly,
    Monthly
}

public static List<DateTime> GetOccurrences(DateTime startDate, DateTime endDate, OccurrenceRate rate)
{
    List<DateTime> occurrences = new List<DateTime>();

    var nextDate = startDate;

    while (true)
    {
        if (nextDate <= endDate)
        {
            occurrences.Add(nextDate);
        }
        else
        {
            break;
        }

        switch (rate)
        {
            case OccurrenceRate.Weekly:
            {
                nextDate = nextDate.AddDays(7);
                break;
            }
            case OccurrenceRate.Fortnightly:
            {
                nextDate = nextDate.AddDays(14);
                break;
            }
            case OccurrenceRate.Monthly:
            {
                nextDate = nextDate.AddMonths(1);
                break;
            }
        }
    }

    return occurrences;
}

Example of calling code:

DateTime startDate = DateTime.Now;
DateTime endDate = startDate.AddDays(35); //5 weeks

var dates = GetOccurrences(startDate, startDate.AddDays(35), OccurrenceRate.Weekly);
dates.ForEach(date =>
{
    Console.WriteLine("{0:yyyy-MM-dd}", date);
});
tobias86
  • 4,979
  • 1
  • 21
  • 30
  • I've edited my original post, just to mention that the recurrence patterns are varied.. is there a way of incorporating various patterns? – beebul Mar 22 '12 at 11:55
  • @beebul: See edited answer. You would have to modify the enumeration and relevant logic if you'd like to add more patterns – tobias86 Mar 22 '12 at 12:04
  • Thanks I'll give this a go and report back :) – beebul Mar 22 '12 at 12:56
  • how do I add in the event start date which the Recurrence needs? – beebul Mar 22 '12 at 15:16
  • @beebul: See the example at the bottom of my answer. You just pass it into the method. – tobias86 Mar 23 '12 at 06:19
  • Sorry that allows me to put a date range in, it doesn't allow me to put a start date when an event originally occurred so that we can say in a years time what date it will fall on.. – beebul Mar 23 '12 at 08:48
  • @beebul: This is not in the scope of your question. Surely you can just use `endDate = startDate.AddYears(1)` then take the last occurrence of your event as the following year's occurrence? – tobias86 Mar 23 '12 at 08:53
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/9225/discussion-between-beebul-and-tobias86) – beebul Mar 23 '12 at 08:55
  • Thanks Tob got your solution to work - many thanks for your assistance! David – beebul Mar 23 '12 at 10:30
2

You should probably just use the DateTime.AddDays method:

var date = new DateTime(2011, 12, 19);
var end = new DateTime(2012, 4, 26); // five weeks from now
while (date < end)
{
    if (date > DateTime.Now)
    {
        // This is a date you want
    }
    date = date.AddDays(14);
}
David M
  • 71,481
  • 13
  • 158
  • 186