-4

LockedDate のリストがあるとします。

LockedDate には DateTime と IsYearly ブール値があります。IsYearly が true の場合は、任意の年になる可能性があるため、その年は考慮されません。時間は決して考慮されるべきではありません。

例: X-Mas、12 月 25 日は毎年です。

これで LockedDate のリストができました。

重複はありません。

今、私はこの機能が必要です:

この関数は次のことを行います: LockedDate が年次ではなく、日、月、および年がソースからの範囲内にある場合は、戻りリストに追加します。

LockedDate が年単位で、その月/日が範囲内にある場合は、範囲内の年ごとに新しい日付を追加します。

IsYearly が true の Dec 25 があるとします。私の範囲は 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

4 に答える 4

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

于 2013-03-14T14:54:06.017 に答える
0

次のようなクラス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;
}
于 2013-03-14T15:04:19.103 に答える
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)

開始から終了までのすべての日を繰り返し、その日付が問題ないかどうかを確認するよりも効率的です。

于 2013-03-14T15:38:16.667 に答える
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のプロパティがあることを前提としています。DateDateTime

于 2013-03-14T14:57:58.493 に答える