C # Получить следующую N-ую дату пятницы с сегодняшнего дня - PullRequest
3 голосов
/ 02 ноября 2011

У меня есть следующее, но это не совсем то, что мне сейчас нужно - он возвращает даты всех пятниц за прошедший месяц.

    public static IEnumerable<DateTime> ReturnNextNthWeekdaysOfMonth(DateTime dt, DayOfWeek weekday, int amounttoshow = 4)
    {
        var days =
            Enumerable.Range(1, DateTime.DaysInMonth(dt.Year, dt.Month)).Select(
                day => new DateTime(dt.Year, dt.Month, day));

        var weekdays = from day in days
                       where day.DayOfWeek == weekday
                       orderby day.Day ascending
                       select day;

        return weekdays.Take(amounttoshow);
    }

ОДНАКО я хочу вернуть даты следующей N-й пятницы с текущей даты, независимо от месяца, в котором они находятся.

И я немного застрял ... Любая помощь очень ценится.

Ответы [ 7 ]

2 голосов
/ 02 ноября 2011
public static IEnumerable<DateTime> ReturnNextNthWeekdaysOfMonth(DateTime dt, DayOfWeek weekday, int amounttoshow = 4)
{
    // Find the first future occurance of the day.
    while(dt.DayOfWeek != weekday)
        dt = dt.AddDays(1);

    // Create the entire range of dates required. 
    return Enumerable.Range(0, amounttoshow).Select(i => dt.AddDays(i * 7));
}

Сначала выполняется поиск соответствия на следующий день weekday, затем продолжается создание amounttoshow экземпляров DateTime, каждый из которых на 7 дней дальше предыдущего, начиная с найденной даты.

2 голосов
/ 02 ноября 2011

Как насчет этого ...

    public static List<DateTime> ReturnNextNthWeekdaysOfMonth(DateTime dt, DayOfWeek weekday, int amounttoshow = 4)
    {
        List<DateTime> list = new List<DateTime>();

        dt = dt.AddDays(weekday - dt.DayOfWeek);//set to the first day in the list

        if (weekday <= dt.DayOfWeek)
            dt = dt.AddDays(7);

        for (int i = 0; i < amounttoshow; i++)
        {
            list.Add(dt);
            dt = dt.AddDays(7);
        }

        return list;
    }

Обратите внимание, что если вы переходите в текущий день, то первая дата в списке будет на следующей неделе, а не сегодня. Если вы хотите, чтобы сегодняшний день был включен в качестве первой даты в этом случае, вы можете использовать следующий код вместо этого ...

    public static IEnumerable<DateTime> ReturnNextNthWeekdaysOfMonth(DateTime dt, DayOfWeek weekday, int amounttoshow = 4)
    {
        List<DateTime> list = new List<DateTime>();

        if (weekday < dt.DayOfWeek)
            dt = dt.AddDays(7);

        dt = dt.AddDays(weekday - dt.DayOfWeek);

        for (int i = 0; i < amounttoshow; i++)
        {
            list.Add(dt);
            dt = dt.AddDays(7);
        }

        return list;
    }
1 голос
/ 02 ноября 2011

Не нужно беспокоиться о LINQ:

public static IEnumerable<DateTime> ReturnNextNthWeekdaysOfMonth(DateTime dt, DayOfWeek weekday, int amounttoshow = 4)
{
    while(dt.DayOfWeek != weekday)
        dt = dt.AddDays(1);

    for (int i = 0; i < amounttoshow; i++)
    {
        yield return dt;
        dt = dt.AddDays(7);
    }
}
0 голосов
/ 02 ноября 2011

Альтернатива с более высокой скоростью (арифметика вместо цикла поиска для первой даты и перемещение дорогостоящего умножения за пределы цикла):

public static IEnumerable<DateTime> ReturnNextNthWeekdaysOfMonth(DateTime dt, 
    DayOfWeek weekday, int amounttoshow = 4)
{
    var day = dt.AddDays(weekday > dt.DayOfWeek 
        ? weekday - dt.DayOfWeek
        : 7 - weekday - dt.DayOfWeek);
    var days = new List<DateTime>();
    for(var until = day.AddDays(7 * amounttoshow); 
        day < until; 
        day = day.AddDays(7))
        days.Add(day);
    return days.ToArray();
}
0 голосов
/ 02 ноября 2011

Попробуйте это

public static IEnumerable<DateTime> ReturnNextNthWeekdaysOfMonth(DateTime dt, DayOfWeek weekday, int amounttoshow = 4)
  {
     // get the difference from the weekday
     int diff = dt.DayOfWeek - weekday;

     // amounttoshow * 7 is the number of days in a week (28 to get 4 weeks)
     var days =
         Enumerable.Range(1, amounttoshow * 7 + diff).Select(            
             day => DayOfYear(dt, day));

     var weekdays = from day in days
                    where day.DayOfWeek == weekday
                    orderby day.Day ascending
                    select day;

     return weekdays.Take(amounttoshow);
  }

  // returns the day in datetime
  public static DateTime DayOfYear(DateTime dt, int day)
  {
     DateTime firstDayOfYear = new DateTime(dt.Year, 1, 1);
     DateTime dateTime = firstDayOfYear.AddDays(dt.DayOfYear - 1 + day);

     return dateTime;
  }

Чтобы получить значение

DateTime d = new DateTime(2011, 11, 5);
IEnumerable<DateTime> ie = ReturnNextNthWeekdaysOfMonth(d, DayOfWeek.Friday, 4);

System.Diagnostics.Debug.WriteLine(ie.First().ToString());
0 голосов
/ 02 ноября 2011

заменить полное тело метода на

return (from z in Enumerable.Range (0, amounttoshow) 
let b = (from x in Enumerable.Range (0, 6) where DateTime.Now.AddDays (x).DayOfWeek == weekday select DateTime.Now.AddDays (x)).First() 
select b.AddDays (z * 7));
0 голосов
/ 02 ноября 2011

Изменить последнюю строку на

return weekdays.Where((x, i) => i % N == 0);
...