Dharil Kothari Ответов: 1

Найдите дату начала и окончания по номеру недели , дню начала недели и Году


Я хочу получить дату начала и окончания конкретной недели.
У меня есть три входа :
1-летний
2. Номер недели
3. день начала недели (настраивается : определяется конфигурацией на нашем сайте, а не стандартом или c#).

У меня есть перечисление, как показано ниже, в соответствии с моим требованием(поэтому я использую перечисление c#, Где воскресенье принимает значение 0):
публичное перечисление EN50160DayOfWeek
{
Понедельник = 1,
Вторник = 2,
Среда = 3,
Четверг = 4,
Пятница = 5,
Суббота = 6,
Воскресенье = 7
}

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

Что я уже пробовал:

Не в состоянии создать логику.Я хочу создать универсальную функцию.

Richard MacCutchan

Используйте объект DateTime.

1 Ответов

Рейтинг:
0

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);


jekin77

Прекрасно объяснено