Как получить список даты начала недели (понедельник) и даты окончания (воскресенье) для года в C# - PullRequest
0 голосов
/ 04 августа 2020

Я хочу получить только недели в течение всего года, когда я хочу получить дату начала (понедельник) и дату окончания (пятница) в C#. Например: 1/52 = 02 Jan (Monday) - 09 Jan (Sunday) 2/52 = 10 Jan (Monday) - 17 Jan (Sunday) и так далее. Я могу получить даты текущей недели, но не знаю, как получить год.

// We Set the Monday as the first day of the week.
DayOfWeek day = datetime.DayOfWeek;
int days = day - DayOfWeek.Monday;
if (days == -1)
{
    days = 6;  // this is when we have sunday as a DayOfWeek day
}

DateTime start = datetime.AddDays(-days);
DateTime end = start.AddDays(6);

Ответы [ 4 ]

0 голосов
/ 04 августа 2020

Я думаю, что это должно работать для григорианских календарей и учитывать различные культуры:

public static IList<DateTime> GetFirstDayOfWeekDates(CultureInfo cultureInfo, int year)
{
    var lastDateOfYear = new DateTime(year, 12, 31);
    var firstDate = new DateTime(year, 1, 1);
    var dayOfWeek = cultureInfo.DateTimeFormat.FirstDayOfWeek;

    while (firstDate.DayOfWeek != dayOfWeek)
    {
        firstDate = firstDate.AddDays(1);
    }
        
    var numberOfWeeksInYear = cultureInfo.Calendar.GetWeekOfYear(lastDateOfYear, cultureInfo.DateTimeFormat.CalendarWeekRule, dayOfWeek);

    var firstDayOfWeekDates = new List<DateTime>();
    firstDayOfWeekDates.Add(firstDate);

    var currentDate = firstDate;

    for (int i = 0; i < numberOfWeeksInYear; i++)
    {
        var weekLater = currentDate.AddDays(7);

        if (weekLater.Year == year)
        {
            currentDate = weekLater;
            firstDayOfWeekDates.Add(currentDate);
        }
    }

    return firstDayOfWeekDates;
}

Вы можете проверить это с помощью консольного приложения, подобного этому (сделайте метод stati c):

static void Main(string[] args)
{
    var ci = new CultureInfo("en-GB");

    var dates = GetFirstDayOfWeekDates(ci, DateTime.Now.Year);

    foreach (var dt in dates)
    {
        Console.WriteLine("Date: " + dt.ToShortDateString());
    }

    Console.ReadLine();
}

Возвращает следующее:

enter image description here

If you want to include the end date of the week as well then you can tweak this slightly by adding a new class called WeekDate:

public class WeekDate
{
    public DateTime StartOfWeek { get; set; }
    public DateTime EndOfWeek { get; set; }
}

GetFirstDayOfWeekDates then becomes:

    public static IList GetFirstDayOfWeekDates(CultureInfo cultureInfo, int year)
    {
        var lastDateOfYear = new DateTime(year, 12, 31);
        var firstDate = new DateTime(year, 1, 1);
        var dayOfWeek = cultureInfo.DateTimeFormat.FirstDayOfWeek;

        while (firstDate.DayOfWeek != dayOfWeek)
        {
            firstDate = firstDate.AddDays(1);
        }
        
        var numberOfWeeksInYear = cultureInfo.Calendar.GetWeekOfYear(lastDateOfYear, cultureInfo.DateTimeFormat.CalendarWeekRule, dayOfWeek);

        var firstDayOfWeekDates = new List();
        firstDayOfWeekDates.Add(new WeekDate { StartOfWeek = firstDate, EndOfWeek = firstDate.AddDays(6) });

        var currentDate = firstDate;

        for (int i = 0; i < numberOfWeeksInYear; i++)
        {
            var weekLater = currentDate.AddDays(7);

            if (weekLater.Year == year)
            {
                currentDate = currentDate.AddDays(7);
                firstDayOfWeekDates.Add(new WeekDate { StartOfWeek = currentDate, EndOfWeek = currentDate.AddDays(6) });
            }
        }

        return firstDayOfWeekDates;
    }

Which returns:

введите описание изображения здесь

0 голосов
/ 04 августа 2020

Вы можете использовать приведенные ниже методы для расчета дня начала любой недели любого года

public static DateTime StartOfNthWeekOfYear(int year, int weekNumber, DayOfWeek firstDayOfWeek)
{
    if(weekNumber < 1)
    {
        throw new ArgumentOutOfRangeException(nameof(weekNumber));
    }
    DateTime startOfWeek = StartOfFirstWeekOfYear(year, firstDayOfWeek).AddDays((weekNumber - 1) * 7);
    DateTime endOfWeek = startOfWeek.AddDays(6);
    if(endOfWeek.Year != year || startOfWeek.Year != year)
    {
        throw new ArgumentOutOfRangeException(nameof(weekNumber));
    }
    return startOfWeek;
}

public static DateTime StartOfFirstWeekOfYear(int year, DayOfWeek firstDayOfWeek)
{
    DateTime startOfYear = new DateTime(year, 1, 1);
    if (startOfYear.DayOfWeek != firstDayOfWeek)
    {
        return StartOfWeek(startOfYear, firstDayOfWeek).AddDays(7);
    }
    return startOfYear;
}

public static DateTime StartOfWeek(DateTime value, DayOfWeek firstDayOfWeek)
{
    if (value.DayOfWeek != firstDayOfWeek)
    {
        return value.AddDays(-((7 + (int)value.DayOfWeek - (int)firstDayOfWeek) % 7));
    }
    return value;
}
0 голосов
/ 04 августа 2020

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

            DateTime starting = new DateTime(2020, 1, 1);
            DateTime ending = new DateTime(2020, 12, 1);
            DateTime currentDay = starting;
            DateTime start = currentDay;
            DateTime end = currentDay;
            while (ending.Year >= currentDay.Year)
            {
                if (currentDay.DayOfWeek == DayOfWeek.Monday)
                {
                    start = currentDay;
                    end = start.AddDays(6);
                    currentDay = end;
                    Console.WriteLine(start + "(" + start.DayOfWeek + ")");
                    Console.WriteLine(end + "(" + end.DayOfWeek + ")");
                }
                else
                {
                    currentDay = currentDay.AddDays(1);
                }
            }
0 голосов
/ 04 августа 2020

Не усложняя задачу, вы можете просто использовать while, как показано ниже.

while (datetime.DayOfWeek != DayOfWeek.Monday)
{
    datetime= datetime.AddDays(1);
}

DateTime start = datetime;
DateTime end = start.AddDays(6);

Или вы хотите найти неделю из индекса недели 1/52 для любого year, а затем напишите функцию, как показано ниже. Используйте его как GetWeek(1, 2020), чтобы получить 06.01.2020 - 12.01.2020. Отформатируйте его в соответствии с вашими требованиями.

public DateTime GetNextMonday(DateTime datetime)
{        
    return datetime.AddDays((7 - (int)datetime.DayOfWeek + (int)DayOfWeek.Monday) % 7);
}

public string GetWeek(int week, int year) 
{
    var start = GetNextMonday(new DateTime(year, 1, 1).AddDays((week-1)*7));
    var end = start.AddDays(6);
    return start.ToShortDateString() + " - " + end.ToShortDateString();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...