Я хочу получить список недель в определенном году вместе с датами начала и окончания.
Я попробовал решение, приведенное в это
который:
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
});
он правильно возвращает недели для 2023 года. Но когда я выбираю 2020 год, он занимает первый день с 2019 года и последний день с 2021 года:
Ни одна неделя не должна включать даты из другого года в начале/конце. Например, если год начинается в четверг, предыдущая неделя закончится в среду, а новая неделя начнется с четверга.
Любые предложения, чтобы решить эту проблему? Я хочу недели в том же формате, просто чтобы решить эту проблему с началом и концом
Заранее спасибо!
ОБНОВЛЯТЬ:
Я пробовал следующий код, который получает правильную дату начала и окончания для первой недели, но вторая неделя начинается с даты окончания первой недели:
var jan1 = new DateTime(year, 1, 1);
var dec31 = new DateTime(year, 12, 31);
CultureInfo cultInfo = CultureInfo.CurrentCulture;
var startOfFirstWeek = jan1.AddDays(0 - (int)(jan1.DayOfWeek));
return Enumerable.Range(0, 54)
.Select(i => new Week
{
StartDate = i == 0
? jan1
: startOfFirstWeek.AddDays(i * 7),
EndDate = startOfFirstWeek.AddDays(i * 7 + 7).Year == year
? startOfFirstWeek.AddDays(i * 7 + 7)
: dec31,
Number = i + 1
})
.TakeWhile(week => week.StartDate.Year == year)
.ToList();
Согласно моему требованию, я не хочу этого. это система расчета стоимости за год. мы не можем брать дополнительные дни начала/окончания.
Если вы делаете это по неделям, то «дополнительных» дней не будет. 30 и 31 декабря 2019 года считаются первой неделей 2020 года, кстати...
Если ваше требование состоит в том, чтобы исключить все дни не из текущего года (что приведет к ошибкам в расчетах), вам нужно будет перепроверить, действительно ли это требуется. Он упадет через несколько дней.
Вы должны проверить свое требование того, какому стандарту вы хотите следовать здесь. Какая первая неделя (и, следовательно, первый день этой недели) года, зависит от культуры и стандарта, которому вы хотите следовать (например, ISO8601). Вы действительно хотите полные недели здесь? Значит, первую и последнюю неделю можно просто вырезать в последний/первый день года?
Привет, @Ralf, да, последний/первый день будет сокращен, если приближается начало конца года. например, год заканчивается в среду, тогда первая неделя следующего года должна начинаться с четверга. Я следую стандарту, где понедельник — первый день недели.
Вы сказали: «Я следую стандарту, где понедельник — первый день недели», но затем вы также сказали: «Он правильно возвращает недели для 2023 года». Но так как 2023 год начался в воскресенье, это не имеет смысла, если я что-то не упустил. Пожалуйста, обновите свой исходный вопрос дополнительными требованиями (которые, по-видимому, заключаются в том, что недели не должны быть включены, если они содержат дни из другого года?).
@RufusL Все недели должны быть включены, но их следует вырезать с начала и конца, если наступит еще один год.
@RufusL Я добавил это в свой вопрос.
Обратите внимание, что также возможно, что несколько дней с конца года X можно считать относящимися к первой неделе года X+1. Что вы хотите, чтобы случилось с ними? (Что отличается от «последняя неделя года X содержит несколько дней года X + 1»)
@Fildor Например, если в 2020 году конец года приходится на вторник, на последней неделе 2020 года будет только два дня, то есть понедельник и вторник. а затем 2021 год начнется со среды и будет иметь 5 дней со среды по воскресенье. и затем 2-я неделя 2021 года начнется с понедельника и так далее
Я могу только порекомендовать перепроверить, действительно ли это требуется. «Последняя / первая неделя года» действительно может иметь совершенно разные определения в разных стандартах / личных мнениях. Также убедитесь, что люди находятся на одной странице, что конкретно представляет собой желаемый стандарт и как он это определяет.





Вы должны изменить свой код, чтобы сделать исключения для первой и последней недель. Для первого вы устанавливаете начало на 1 января, а для последнего вы удаляете все дни следующего года.
var jan1 = new DateTime(DateTime.Today.Year , 1, 1);
var nextJan1 = new DateTime(DateTime.Today.Year + 1 , 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 = i == 0 ? jan1 : startOfFirstWeek.AddDays(i * 7)
})
.TakeWhile(x => x.weekStart.Year <= jan1.Year)
.Select(x => new {
x.weekStart,
weekFinish= x.weekStart.AddDays(4) < nextJan1 ? x.weekStart.AddDays(4) : x.weekStart.AddDays((nextJan1 , 1, 1) - x.weekStart).TotalDays)
})
.SkipWhile(x => x.weekFinish < jan1.AddDays(1) )
.Select((x,i) => new {
x.weekStart,
x.weekFinish,
weekNum=i+1
});
Спасибо за разъяснение вашего вопроса, я думаю, что понимаю, что вы хотите. Первая неделя года должна начинаться 1 января, а последняя неделя должна заканчиваться 31 декабря.
Я бы решил это, прежде всего, используя реальный класс вместо анонимного типа для представления недели (у которого есть Number, StartDate и EndDate):
public class Week
{
public int Number { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
}
Затем мы можем создать метод для заполнения списка недель для указанного года.
В методе, когда мы перечисляем каждую неделю, мы устанавливаем дату начала либо на 1 января (если это первая неделя), либо рассчитываем дату начала на основе фактического первого дня первой недели (который может быть в предыдущем году). ), как мы делали раньше.
Мы также гарантируем, что последний день последней недели установлен на 31 декабря, проверяя, имеет ли фактический последний день недели год больше, чем тот, который передан в наш метод. В противном случае мы просто используем результат добавления 6 к StartDate.
Кроме того, я не уверен, почему в вашем коде так много операторов Select — вы можете просто выбрать каждую неделю один раз, заполнив StartDate, EndDate и Number все за один раз.
ОБНОВЛЯТЬ
Вы упомянули, что хотите, чтобы недели начинались Monday и заканчивались Sunday. Чтобы добиться этого, я изменил приведенный ниже метод, чтобы использовать необязательный параметр firstDayOfWeek, который указывает, какой день следует считать первым днем недели.
Затем мы можем взять значение firstDayOfWeek и вычесть из него jan1.DayOfWeek, чтобы определить количество дней, которое нам нужно добавить к jan1, чтобы добраться до целевого дня начала недели.
Например:
static List<Week> GetWeeks(int year, DayOfWeek firstDayOfWeek = DayOfWeek.Monday)
{
var jan1 = new DateTime(year, 1, 1);
var dec31 = new DateTime(year, 12, 31);
var startOfFirstWeek = jan1.AddDays(firstDayOfWeek - jan1.DayOfWeek);
return Enumerable.Range(0, 54)
.Select(i => new Week
{
StartDate = i == 0
? jan1
: startOfFirstWeek.AddDays(i * 7),
EndDate = startOfFirstWeek.AddDays(i * 7 + 6).Year == year
? startOfFirstWeek.AddDays(i * 7 + 6)
: dec31,
Number = i + 1
})
.TakeWhile(week => week.StartDate.Year == year)
.ToList();
}
Спасибо за решение Руфус. Неделя начинается с воскресенья и заканчивается в субботу. в то время как мне нужен понедельник как начало и воскресенье как конец.
Если я добавлю 7 вместо 6, чтобы считать, что это 7-дневная неделя, та же дата окончания первой недели будет датой начала следующей недели.
Я добавил обновление, в котором есть снимок экрана с проблемами, можете ли вы что-нибудь предложить?
Я обновил ответ и добавил в метод необязательный параметр, который позволяет изменить первый день недели. Значение по умолчанию — понедельник, но теперь его можно легко изменить для других сценариев.
«Но когда я выбираю 2020 год, он берет первый день из 2019 года и последний день из 2021 года:» - Почему вы думаете, что это неправильно? Первая неделя 2020 г. началась в понедельник, 30 декабря. 2019 г. и последняя неделя 2020 г. закончилась в пятницу, 1 января 2021 г.