CHill60
Первая проблема, которая у вас есть, - это определение "номера недели". Я предполагаю, что вы имеете в виду номер недели ISO (Дата недели ISO - Википедия[^]), что приравнивается к CalendarWeekRule.FirstFourDayWeek
Чтобы понять, почему это важно, рассмотрим этот фрагмент кода, в котором перечислены недели, на которые приходится 2017-16 января по Григорианскому календарю, для 3 различных вариантов подсчета недель:
var cc = new GregorianCalendar();
dt = new DateTime(2017,1,16);
Console.WriteLine("Week {0} {1} {2}", cc.GetWeekOfYear(dt, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday), cc.GetWeekOfYear(dt, CalendarWeekRule.FirstFullWeek, DayOfWeek.Monday), cc.GetWeekOfYear(dt, CalendarWeekRule.FirstDay, DayOfWeek.Monday));
Console.WriteLine("Week {0} {1} {2}", cc.GetWeekOfYear(dt, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Tuesday), cc.GetWeekOfYear(dt, CalendarWeekRule.FirstFullWeek, DayOfWeek.Tuesday), cc.GetWeekOfYear(dt, CalendarWeekRule.FirstDay, DayOfWeek.Tuesday));
Console.WriteLine("Week {0} {1} {2}", cc.GetWeekOfYear(dt, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Wednesday), cc.GetWeekOfYear(dt, CalendarWeekRule.FirstFullWeek, DayOfWeek.Wednesday), cc.GetWeekOfYear(dt, CalendarWeekRule.FirstDay, DayOfWeek.Wednesday));
Console.WriteLine("Week {0} {1} {2}", cc.GetWeekOfYear(dt, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Thursday), cc.GetWeekOfYear(dt, CalendarWeekRule.FirstFullWeek, DayOfWeek.Thursday), cc.GetWeekOfYear(dt, CalendarWeekRule.FirstDay, DayOfWeek.Thursday));
Console.WriteLine("Week {0} {1} {2}", cc.GetWeekOfYear(dt, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Friday), cc.GetWeekOfYear(dt, CalendarWeekRule.FirstFullWeek, DayOfWeek.Friday), cc.GetWeekOfYear(dt, CalendarWeekRule.FirstDay, DayOfWeek.Friday));
Console.WriteLine("Week {0} {1} {2}", cc.GetWeekOfYear(dt, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Saturday), cc.GetWeekOfYear(dt, CalendarWeekRule.FirstFullWeek, DayOfWeek.Saturday), cc.GetWeekOfYear(dt, CalendarWeekRule.FirstDay, DayOfWeek.Saturday));
Console.WriteLine("Week {0} {1} {2}", cc.GetWeekOfYear(dt, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Sunday), cc.GetWeekOfYear(dt, CalendarWeekRule.FirstFullWeek, DayOfWeek.Sunday), cc.GetWeekOfYear(dt, CalendarWeekRule.FirstDay, DayOfWeek.Sunday));
Это дает результаты
Week 3 3 4
Week 2 2 3
Week 2 2 3
Week 3 2 3
Week 3 2 3
Week 3 2 3
Week 3 3 3
Ваша следующая проблема-это ваше перечисление. Во-первых, он не очень хорошо сформирован, MS советует, чтобы перечисления всегда имели запись со значением 0. Я действительно не понимаю, почему вы просто не используете стандартное перечисление - в конце концов, вас действительно не волнует номер, а только "имя" дня
[Serializable]
[ComVisible(true)]
public enum DayOfWeek
{
Sunday = 0,
Monday = 1,
Tuesday = 2,
Wednesday = 3,
Thursday = 4,
Friday = 5,
Saturday = 6,
}
Чтобы использовать стандарт
DateTime
функции, которые вам нужно будет преобразовать в стандартное перечисление, что вы можете сделать следующим образом:
var Week_start = EN50160DayOfWeek.Tuesday;
var realday = (int)Enum.Parse(typeof(DayOfWeek), Week_start.ToString());
Следующий шаг - это разработка даты для нужного вам номера недели, основываясь на вашем настраиваемом начале рабочего дня. В приведенном ниже коде я выбрал подход "грубой силы" - начните с первого дня года и продолжайте добавлять день, пока не доберетесь до нужной недели. Очевидно, что это будет первый день этой недели, и добавление 6 дней даст вам дату последнего дня на этой неделе:
var year = 2017;
var week_number = 3;
var Week_start = EN50160DayOfWeek.Tuesday;
var realday = Enum.Parse(typeof(DayOfWeek), Week_start.ToString());
var cc = new GregorianCalendar();
var dt = new DateTime(year, 1, 1);
for (var i = 0; i < 365; i++)
{
dt = dt.AddDays(1);
if (week_number == cc.GetWeekOfYear(dt, CalendarWeekRule.FirstFourDayWeek, (DayOfWeek)realday)) break;
}
var startOfWeek = dt;
var endOfWeek = startOfWeek.AddDays(6);
Если вы считаете, что этот метод слишком неэффективен для последующих недель года, то вы можете увеличить дату гггг-январь-01 на 1, пока не дойдете до начала недели 1. Это не так глупо, как это звучит, как это только
CalendarWeekRule.FirstDay
это гарантирует, что Неделя 1 начнется 1 января. Как только у вас будет дата начала недели 1, Просто добавьте соответствующее количество дней, чтобы найти нужную неделю. Подобный этому:
var year = 2017;
var week_number = 3;
var Week_start = EN50160DayOfWeek.Tuesday;
var realday = Enum.Parse(typeof(DayOfWeek), Week_start.ToString());
var cc = new GregorianCalendar();
var dt = new DateTime(year, 1, 1);
while (cc.GetWeekOfYear(dt, CalendarWeekRule.FirstFourDayWeek, (DayOfWeek)realday) > 1)
{
// Handle start of January being week 52 or 53 of the previous year (2017 for example)
dt = dt.AddDays(1);
}
var startOfWeek = dt.AddDays((7 * (week_number - 1)));
var endOfWeek = startOfWeek.AddDays(6);