Determining expiration date based on list of months in which to refresh I have a list of months in which users are required to update some data. I want to determine at what date they should have updated their data. They must update in March, May and August. If today is March, I want to get back the 1st of March. If today is February, I want to get back last year's August. In reality the list wouldn't be hardcoded.

I do have some working code, but I wonder if there is a simpler / more elegant of writing this (the GetCheckDate method).

using System;
using System.Collections.Generic;
using System.Linq;

internal class Program
{
    private static void Main()
    {
        var listOfMonths = new List&lt;int?&gt; {3, 5, 8};
        Console.WriteLine(GetCheckDate(listOfMonths,
            new DateTime(2014, 2, 1))); // expect 2013-08-01
        Console.WriteLine(GetCheckDate(listOfMonths,
            new DateTime(2014, 3, 1))); // expect 2014-03-01
        Console.WriteLine(GetCheckDate(listOfMonths,
            new DateTime(2014, 7, 1))); // expect 2014-05-01
        Console.WriteLine(GetCheckDate(null,
            new DateTime(2014, 7, 1))); // expect 2013-07-1
        Console.WriteLine(GetCheckDate(new List&lt;int?&gt;(),
            new DateTime(2014, 7, 1))); // expect 2013-07-1
    }

    private static DateTime GetCheckDate(IEnumerable&lt;int?&gt; listOfMonths,
        DateTime curDate)
    {
        DateTime result = curDate.AddYears(-1);
        if (listOfMonths == null) return result;
        listOfMonths = listOfMonths.ToList();
        if (!listOfMonths.Any()) return result;

        listOfMonths = listOfMonths.OrderByDescending(m =&gt; m).ToList();
        var greatestSmallerThan =
            listOfMonths.FirstOrDefault(m =&gt; m &lt;= curDate.Month)
            ?? listOfMonths.FirstOrDefault(m =&gt; m &gt; curDate.Month);
        result = new DateTime(
            greatestSmallerThan.Value &lt;= curDate.Month
                ? curDate.Year : curDate.Year - 1, greatestSmallerThan.Value, 1);

        return result;
    }
}
I suggest you to improve naming:    


months instead of listOfMonths because its not list, and its better not to include variable type description into name 
date instead of curDate - its better to avoid abbreviations, also current method should not care whether moth is current or not - it just search previous month from given months
Possibly I would rename method to something like GetPreviousMonth


Also I don't see any need to have nullable type for months sequence. It should have integers. If month exist in list, then you can avoid sorting - so do this check first. Thus you are not going to add/remove month, then saving ordered sequence to array is little better:

public static DateTime GetCheckDate(IEnumerable&lt;int&gt; months, DateTime date)
{
    if (month == null || !months.Any() || months.Contains(date.Month))
        return date.AddDays(1 - date.Day);

    var orderedMonths = months.OrderByDescending(m =&gt; m).ToArray();
    if (date.Month &gt; orderedMonths.First())
        return new DateTime(date.Year, orderedMonths.First(), 1);

    if (date.Month &lt; orderedMonths.Last())            
        return new DateTime(date.Year - 1, orderedMonths.First(), 1);

    return new DateTime(date.Year, orderedMonths.First(m =&gt; m &lt; date.Month), 1);
}


But I also prefer readability on first place (performance should be improved only if its a problem) so I would go with Max and Min month instead of sorting them and keeping in mind what is Last and what is First:

public static DateTime GetCheckDate(IEnumerable&lt;int&gt; months, DateTime date)
{
    if (month == null || !months.Any() || months.Contains(date.Month))          
        return date.AddDays(1 - date.Day);            

    if (months.Max() &lt; date.Month)
        return new DateTime(date.Year, months.Max(), 1);

    if (date.Month &lt; months.Min())            
        return new DateTime(date.Year - 1, months.Max(), 1);

    return new DateTime(date.Year, months.Where(m =&gt; m &lt; date.Month).Max(), 1);
}


If I would continue making it more readable, then following extension methods would be useful:

public static DateTime FirstDayOfMonth(this DateTime date, int month = 0)
{
    return new DateTime(date.Year, month == 0 ? date.Month : month, 1);
}

public static DateTime PreviousYear(this DateTime date)
{
    return date.AddYears(-1);
}


Now whole method is very easy to understand:

public static DateTime GetCheckDate(IEnumerable&lt;int&gt; months, DateTime date)
{
    if (month == null || !months.Any() || months.Contains(date.Month))
        return date.FirstDayOfMonth();

    if (months.Max() &lt; date.Month)
        return date.FirstDayOfMonth(months.Max());

    if (date.Month &lt; months.Min())
        return date.PreviousYear().FirstDayOfMonth(months.Max());

    return date.FirstDayOfMonth(months.Where(m =&gt; m &lt; date.Month).Max());
}