Получить список недель на год - с датами

Я ломал голову над этим, но в пятницу уже поздно, и я хожу кругами.

Мне нужно создать список рабочих недель для выпадающего списка с номером недели в качестве значения. Таким образом, код будет выводить:

Понедельник 22 августа - пятница 26 сентября
Понедельник 29 августа - пятница 2 сентября
Понедельник 5 сентября - пятница 9 сентября

так далее..

На весь год. Есть идеи, как мне этого добиться?

Благодарю.

5 ответов

Решение

Я думаю, что код ниже соответствует ISO 8601:

var jan1 = new DateTime(DateTime.Today.Year , 1, 1);
//beware different cultures, see other answers
var startOfFirstWeek = jan1.AddDays(1 - (int)(jan1.DayOfWeek));
var weeks=
    Enumerable
        .Range(0,54)
        .Select(i => new {
            weekStart = startOfFirstWeek.AddDays(i * 7)
        })
        .TakeWhile(x => x.weekStart.Year <= jan1.Year)
        .Select(x => new {
            x.weekStart,
            weekFinish=x.weekStart.AddDays(4)
        })
        .SkipWhile(x => x.weekFinish < jan1.AddDays(1) )
        .Select((x,i) => new {
            x.weekStart,
            x.weekFinish,
            weekNum=i+1
        });

Просто обновляю то, что поместил Спендер, потому что я хотел сделать вывод ваших Datetimes больше к тому, что вы хотели.

DateTime jan1 = new DateTime(DateTime.Today.Year, 1, 1);
//beware different cultures, see other answers
DateTime startOfFirstWeek = jan1.AddDays(1 - (int)(jan1.DayOfWeek));
var weeks=
    Enumerable
        .Range(0,54)
        .Select(i => new {
            weekStart = startOfFirstWeek.AddDays(i * 7)
        })
        .TakeWhile(x => x.weekStart.Year <= jan1.Year)
        .Select(x => new {
            x.weekStart,
            weekFinish=x.weekStart.AddDays(4)
        })
        .SkipWhile(x => x.weekFinish.Year < jan1.Year)
        .Select((x,i) => new {
            WeekStart = x.weekStart.ToString("dddd, d, MMMM"),
            WeekFinish = x.weekFinish.ToString("dddd, d, MMMM"),
            weekNum=i+1
        });

Изменение, чтобы исправить форматирование к тому, что вы хотели, в последнем выборе анонимного объекта.

Имейте в виду, что расчеты за неделю выполняются по-разному в разных культурах, и нет ошибки, если вы видите номер 53!

using System.Globalization;

CultureInfo cultInfo = CultureInfo.CurrentCulture;
int weekNumNow = cultInfo.Calendar.GetWeekOfYear(DateTime.Now,
                     cultInfo.DateTimeFormat.CalendarWeekRule,
                         cultInfo.DateTimeFormat.FirstDayOfWeek); 

Вы можете использовать класс Week библиотеки периодов времени для.NET:

DateTime start = DateTime.Now.Date;
DatTime end = start.AddYears( 1 );
Week week = new Week( start );
while ( week.Start < end )
{
  Console.WriteLine( "week " + week );
  week = week.GetNextWeek();
}

Возможно, вам придется немного подправить это, но оно должно дать вам то, что вам нужно:

static void Main(string[] args)
    {
        List<DateTime[]> weeks = new List<DateTime[]>();

        DateTime beginDate = new DateTime(2011, 01, 01);
        DateTime endDate = new DateTime(2012, 01, 01);

        DateTime monday = DateTime.Today;
        DateTime friday = DateTime.Today;

        while (beginDate < endDate)
        {
            beginDate = beginDate.AddDays(1);

            if (beginDate.DayOfWeek == DayOfWeek.Monday)
            {
                monday = beginDate;
            }
            else if (beginDate.DayOfWeek == DayOfWeek.Friday)
            {
                friday = beginDate;
            }
            else if (beginDate.DayOfWeek == DayOfWeek.Saturday)
            {
                weeks.Add(new DateTime[] { monday, friday });
            }
        }

        for (int x = 0; x < weeks.Count; x++)
        {
            Console.WriteLine(weeks[x][0].Date.ToShortDateString() + " - " + weeks[x][1].Date.ToShortDateString());
        }

        Console.ReadLine();

    }
Другие вопросы по тегам