Подтвердить что ты не робот

С# - Каков наилучший способ получить список недель в месяц, учитывая начальный рабочий день?

Мне нужно получить список недель для данного месяца, с понедельника в качестве стартового дня.

Так, например, за февраль 2009 года этот метод вернется:

2/2/2009
2/9/2009
2/16/2009
2/23/2009
4b9b3361

Ответ 1

 // Get the weeks in a month

 DateTime date = DateTime.Today;
 // first generate all dates in the month of 'date'
 var dates = Enumerable.Range(1, DateTime.DaysInMonth(date.Year, date.Month)).Select(n => new DateTime(date.Year, date.Month, n));
 // then filter the only the start of weeks
 var weekends = from d in dates
                where d.DayOfWeek == DayOfWeek.Monday
                select d;

Ответ 2

public static List<DateTime> GetWeeks(
    this DateTime month, DayOfWeek startOfWeek)
{
    var firstOfMonth = new DateTime(month.Year, month.Month, 1);
    var daysToAdd = ((Int32)startOfWeek - (Int32)month.DayOfWeek) % 7;
    var firstStartOfWeek = firstOfMonth.AddDays(daysToAdd);

    var current = firstStartOfWeek;
    var weeks = new List<DateTime>();
    while (current.Month == month.Month)
    {
        weeks.Add(current);
        current = current.AddDays(7);
    }

    return weeks;
}

Ответ 3

Здесь решение (фактически одна строка) с использованием С# 3.0/LINQ, если вам интересно:

var month = new DateTime(2009, 2, 1);
var weeks = Enumerable.Range(0, 4).Select(n => month.AddDays(n * 7 - (int)month.DayOfWeek + 1)).TakeWhile(monday => monday.Month == month.Month);

Ответ 4

int year = 2009;
int month = 2;
DateTime startDate = new DateTime(year, month, 1);
DateTime endDate = startDate.AddMonths(1);
while (startDate.DayOfWeek != DayOfWeek.Monday)
    startDate = startDate.AddDays(1);
for (DateTime result = startDate; result < endDate; result = result.AddDays(7))
    DoWhatYouWant(result);

Ответ 5

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

  public IEnumerable<DateTime> GetWeeks(DateTime date, DayOfWeek startDay)
  {
     var list = new List<DateTime>();
     DateTime first = new DateTime(date.Year, date.Month, 1);

     for (var i = first; i < first.AddMonths(1); i = i.AddDays(1))
     {
        if (i.DayOfWeek == startDay)
           list.Add(i);
     }

     return list;
  }

Ответ 6

Просто измените строку ответа на то, что вам нужно сделать с ней

protected void PrintDay(int year, int month, DayOfWeek dayName)
{
  CultureInfo ci = new CultureInfo("en-US");
  for (int i = 1 ; i <= ci.Calendar.GetDaysInMonth (year, month); i++)
  {
    if (new DateTime (year, month, i).DayOfWeek == dayName)
      Response.Write (i.ToString() + "<br/>");
  }
}

Быстрое решение: я не думаю, что для него есть встроенная функция....

Ответ 7

Что-то вроде следующего псевдокода должно работать:

  • Определите дату начала месяца (используйте месяц и год с даты и установите день на 1
  • Определите дату окончания месяца (дата начала + 1 месяц)
  • Определите первую дату, которая является понедельником (это ваш первый элемент в списке)
  • Добавить 7 дней, чтобы найти следующую дату и повторить, пока вы не прочитаете или не пройдете конец месяца.

Ответ 8

Я вижу, что вы получили свой ответ, но я хотел поделиться с вами вспомогательным классом, который я создал для одного из моих проектов. Это далеко не полный класс, но может помочь...

public static class WeekHelper {

#region Public Methods
public static DateTime GetWeekStart(DateTime date) {
    DateTime weekStart;
    int monday = 1;
    int crtDay = (int)date.DayOfWeek;
    if (date.DayOfWeek == DayOfWeek.Sunday)
        crtDay = 7;
    int difference = crtDay - monday;
    weekStart = date.AddDays(-difference);
    return weekStart;
}
public static DateTime GetWeekStop(DateTime date) {
    DateTime weekStart;
    int sunday = 7;
    int crtDay = (int)date.DayOfWeek;
    if (date.DayOfWeek == DayOfWeek.Sunday)
        crtDay = 7;
    int difference = sunday - crtDay;
    weekStart = date.AddDays(difference);
    return weekStart;
}
public static void GetWeekInterval(int year, int weekNo,
    out DateTime weekStart, out DateTime weekStop) {
    GetFirstWeekOfYear(year, out weekStart, out weekStop);
    if (weekNo == 1)
        return;
    weekNo--;
    int daysToAdd = weekNo * 7;
    DateTime dt = weekStart.AddDays(daysToAdd);
    GetWeekInterval(dt, out weekStart, out weekStop);
}
public static List<KeyValuePair<DateTime, DateTime>> GetWeekSeries(DateTime toDate) {
    //gets week series from beginning of the year
    DateTime dtStartYear = new DateTime(toDate.Year, 1, 1);
    List<KeyValuePair<DateTime, DateTime>> list = GetWeekSeries(dtStartYear, toDate);
    if (list.Count > 0) {
        KeyValuePair<DateTime, DateTime> week = list[0];
        list[0] = new KeyValuePair<DateTime, DateTime>(dtStartYear, week.Value);
    }
    return list;
}
public static List<KeyValuePair<DateTime, DateTime>> GetWeekSeries(DateTime fromDate, DateTime toDate) {
    if (fromDate > toDate)
        return null;
    List<KeyValuePair<DateTime, DateTime>> list = new List<KeyValuePair<DateTime, DateTime>>(100);
    DateTime weekStart, weekStop;
    toDate = GetWeekStop(toDate);
    while (fromDate <= toDate) {
        GetWeekInterval(fromDate, out weekStart, out weekStop);
        list.Add(new KeyValuePair<DateTime, DateTime>(weekStart, weekStop));
        fromDate = fromDate.AddDays(7);
    }
    return list;
}
public static void GetFirstWeekOfYear(int year, out DateTime weekStart, out DateTime weekStop) {
    DateTime date = new DateTime(year, 1, 1);
    GetWeekInterval(date, out weekStart, out weekStop);
}
public static void GetWeekInterval(DateTime date,
    out DateTime dtWeekStart, out DateTime dtWeekStop) {
    dtWeekStart = GetWeekStart(date);
    dtWeekStop = GetWeekStop(date);
}
#endregion Public Methods

}

Ответ 9

Это прекрасно работает! Все, что вам нужно сделать, это получить первый день месяца, в который вы хотите получить недели, а затем это даст вам первый день каждой недели. Вам нужно получить 5 недель (не 4), поэтому Enumerable.Range подсчитывает 5 вместо 4.

var date = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1);
var weeks = from n in Enumerable.Range(0, 5)
   select date.AddDays(7 * n + (-1 * (int)date.DayOfWeek));

Ответ 10

Вот что я сделал, используя код Chaowlert в качестве исходной базы. В основном я изменил, что вам нужно проверить, добавляются ли дни для переполнения к следующему месяцу, поэтому я не добавляю 4 дня (с понедельника по пятницу), но на самом деле минимум 4 и количество оставшихся дней в месяце, Кроме того, я проверяю, является ли текущий день выходным, иначе добавьте дни, пока он не станет будним днем. Моя цель - печатать недели через месяц, с понедельника по пятницу

DateTime fechaInicio = new DateTime(año, mes, 1);
DateTime fechaFin = fechaInicio.AddMonths(1);
int diasHastaFinMes = 0;
while (esFinDeSemana(fechaInicio))
    fechaInicio = fechaInicio.AddDays(1);
for (DateTime fecha = fechaInicio; fecha < fechaFin; fecha = fecha.AddDays(7))
{
    diasHastaFinMes = DateTime.DaysInMonth(fecha.Year, fecha.Month) - fecha.Day;
    printWeeks(fecha, fecha.AddDays(Math.Min(4, diasHastaFinMes)));
}