Thursday, September 20, 2012

C# - LINQ on dates

I recently had a need to get all the days in a month that were on a Monday (so for 9/2012 - the days are 3, 10, 17, 24).  Still being new to C#, LINQ was not my first thought... hell, it wasn't even one of my thoughts. I did a little googling to see if any of the current APIs did this already (I figured there was no reason to re-invent the wheel, right).  While I didn't find any APIs, I did find some ideas.  I found some similar examples using LINQ... so, I started playing around with them and this is what I ended up with.

The first part required an iteration of the days in the given month... for this, I used something else that I learned (and is no less cool) - the yield operator.  This is not something we have in the java world and I would really love to have it!
private static IEnumerable EnumerateDaysInRange(
                                   DateTime start, DateTime end)
{
    for (var day = start.Date; day <= end; day = day.AddDays(1))
 yield return day;
}
With this enumeration, I can now build a "from" component in a LINQ satement.
public static List DetermineDaysWeekly(
     Payee payee, 
     DayOfWeek dayOfWeek, 
     int month, 
     int year)
{
    DateTime firstDayOfMonth = new DateTime(year, month, 1);
    DateTime lastDayOfMonth = new DateTime(year, month, 
        DateTime.DaysInMonth(year, month));
    IEnumerable dates = 
     from date in 
            EnumerateDaysInRange(firstDayOfMonth, lastDayOfMonth)
   where (date.DayOfWeek == dayOfWeek)
   select date.Day;
    return dates.ToList();
}
All I am doing here is setting the date for the first day of the month and the last day of the month to pass to the previous function I built above (EnumerateDaysInRange).  The where clause simply checks if the day of the week during that iteration is the one we want and if it is (the select) captures the Day property on the date.  The days are all added to the IEnumerable object, which I convert to a list in my return statement.

Pretty simple really.  Now that I know more about LINQ, I will be sure to look for more places where this could be useful.  In this particular use case, I wasn't too worried about performance, but if I were, I would really need to take some time to research the performance of LINQ.  If anyone has thoughts regarding performance, or anything else for that matter, feel free to leave a comment.

No comments:

Post a Comment

Followers