获取日期范围中的日期列表

时间:2013-03-14 14:40:36

标签: c# asp.net

说我有一个LockedDate列表。

LockedDate有一个DateTime和一个IsYearly bool。如果IsYearly是真的,则不应考虑年份,因为它可能是任何一年。永远不要考虑时间。

Ex:X-Mas,12月25日是一年一度。

现在我有一个LockedDate列表。

没有重复。

现在我需要这个功能:

  

这个功能可以:   如果LockedDate不是每年且日,月和年都在来自源的范围内,则添加到返回列表。

     

如果LockedDate是每年,并且其月/日落在该范围内,则为该范围内的每年添加新日期。

     

假设我在12月25日与IsYearly一样真实。我的范围是2013年1月22日至2015年2月23日。需要将2013年12月25日作为新日期和2014年12月25日作为新日期添加到列表中。

List<Date> GetDateRange(List<LockedDate> source, DateTime start, DateTime end)
{


}

由于

Dec 25 Yearly -> Dec 25 2013, Dec 25 2014
Dec 2, 2011  NOT Yearly -> Nothing
March 25, 2013 => March 25 2013

4 个答案:

答案 0 :(得分:2)

这可能至少给你一个想法,它根本没有经过测试

List<DateTime> GetDateRange(List<LockedDate> source, DateTime start, DateTime end)
{
    if (start > end)
        throw new ArgumentException("Start must be before end");

    var ts = end - start;
    var dates = Enumerable.Range(0, ts.Days)
        .Select(i => start.AddDays(i))
        .Where(d => source.Any(ld => ld.Date == d
            || (ld.IsYearly && ld.Date.Month == d.Month && ld.Date.Day == d.Day)));
    return dates.ToList();
}

更新以下是包含示例数据的演示,似乎有效:http://ideone.com/3KFi97

答案 1 :(得分:0)

此代码可以在不使用Linq的情况下执行您的操作:

    List<DateTime> GetDateRange(List<LockedDate> source, DateTime start, DateTime end)
    {
        List<DateTime> result = new List<DateTime>();

        foreach (LockedDate lockedDate in source)
        {
            if (!lockedDate.IsYearly && (lockedDate.Date >= start && lockedDate.Date <= end))
            {
                result.Add(lockedDate.Date);
            }
            else if (lockedDate.IsYearly && (lockedDate.Date >= start && lockedDate.Date <= end))
            {
                DateTime date = new DateTime(start.Year, lockedDate.Date.Month, lockedDate.Date.Day);

                do
                {
                    result.Add(date);
                    date = date.AddYears(1);
                } while (date <= end);
            }
        }

        return result;
    }

请务必询问您不理解的部分,以便我详细解释,但我认为这非常简单。

此代码假定您的LockedDate类具有Date对象的属性DateTime

答案 2 :(得分:0)

如果你有这样的Class LockedDate:

public class LockedDate
{
       public DateTime Date { get; set; }
       public bool IsYearly { get; set; }
       ...
}

您可以使用此代码来获取所需的日期:

List<DateTime> GetDateRange(List<LockedDate> source, DateTime start, DateTime end)
{

       List<DateTime> dt = new List<DateTime>();
       foreach(LockedDate d in source)
       {
             if(!d.IsYearly)
             {
                  if(start<=d.Date && d.Date<=end)
                       dt.Add(d.Date);
             }
             else
             {
                  for(DateTime i = new DateTime(start.Year,d.Date.Month,d.Date.Day);i<=new DateTime(end.Year,d.Date.Month,d.Date.Day);i=i.AddYears(1))
                  {
                        dt.Add(i);
                  }
             }

      }
      return dt;
}

答案 3 :(得分:0)

var notYearly = lockDates.Where(d => !d.IsYearly && (d.Date.Date >= start && d.Date.Date <= end)).Select(d => d.Date);

var years = ((end - start).Days / 365) + 2;
var startYear = start.Year;

var yearly = lockDates.Where(d => d.IsYearly)
                        .SelectMany(d => Enumerable.Range(startYear, years)
                                                    .Select(e => new DateTime(e, d.Date.Month, d.Date.Day))
                                                    .Where(i => i.Date >= start && i.Date <= end));

var allDates = notYearly.Union(yearly)

应该比仅仅迭代开始和结束之间的所有日子和检查更有效,如果那个日期好的话。