Как я могу получить DateTime для начала недели?


469

Как найти начало недели (как в воскресенье, так и в понедельник), зная только текущее время в C #?

Что-то вроде:

DateTime.Now.StartWeek(Monday);

Ответы:


746

Используйте метод расширения. Знаете, они ответ на все вопросы! ;)

public static class DateTimeExtensions
{
    public static DateTime StartOfWeek(this DateTime dt, DayOfWeek startOfWeek)
    {
        int diff = (7 + (dt.DayOfWeek - startOfWeek)) % 7;
        return dt.AddDays(-1 * diff).Date;
    }
}

Который может быть использован следующим образом:

DateTime dt = DateTime.Now.StartOfWeek(DayOfWeek.Monday);
DateTime dt = DateTime.Now.StartOfWeek(DayOfWeek.Sunday);

15
Вы можете упростить это следующим образом: int diff = dayOfWeek - dt.DayOfWeek; return dt.AddDays(diff).Date;
Трой

13
Трой, я не верю, что твой код работает, если указанная дата - воскресенье, а начало недели - понедельник. Он вернется (воскресенье + 1) вместо (воскресенье - 6)
Аарон Хоффман

1
Это не работает , если dtэто UTC и уже начало недели , например , 2012-09-02 16:00:00Zкоторый Mon, 03 Sep 2012 00:00:00по местному времени. Так что нужно конвертировать dtв местное время или сделать что-то более умное. Также необходимо будет вернуть результат в формате UTC, если вход был UTC.
row1

1
@ row1 DateTime.Parse("2012-09-02 16:00:00Z")возвращает эквивалент по местному времени, и этот метод правильно возвращает то же время, что и местное время. Если вы используете DateTime.Parse("2012-09-02 16:00:00Z").ToUniversalTime()явную передачу времени UTC, этот метод корректно возвращает 6 дней, 16 часов раньше, как время UTC. Это работает именно так, как я ожидал.
Роулинг

1
Это было бы иногда на один день для меня. Это сработало для меня, как только я убрал компонент времени dt. Я использовалint diff = dt.Date.DayOfWeek - startOfWeek;
Винсент Зельцлер

80

Самый быстрый способ, которым я могу придумать это:

var sunday = DateTime.Today.AddDays(-(int)DateTime.Today.DayOfWeek);

Если вы хотите, чтобы любой другой день недели был вашей начальной датой, все, что вам нужно сделать, это добавить значение DayOfWeek в конец

var monday = DateTime.Today.AddDays(-(int)DateTime.Today.DayOfWeek + (int)DayOfWeek.Monday);

var tuesday = DateTime.Today.AddDays(-(int)DateTime.Today.DayOfWeek + (int)DayOfWeek.Tuesday); 

2
самые простые ответы самые лучшие, этот работал нормально, но культура зависела
Cerveser

7
В Латвии неделя начинается в понедельник .. Вообще-то ... Мне всегда интересно, как может начаться неделя в воскресенье ... мне кажется неловким ..;)
0xDEAD BEEF

Это решение хорошо. Кроме того, вы можете сделать начало недели любым днем, добавив DayOfWeek, с которого хотите начать. var sunday = DateTime.Today.AddDays (- (int) DateTime.Today.DayOfWeek); var monday = DateTime.Today.AddDays (- (int) DateTime.Today.DayOfWeek + (int) DayOfWeek.Monday);
Loligans

7
Этот добавленный код не работает для ситуации, описанной Threezol. Если вы хотите, чтобы началом недели был понедельник, то в воскресенье подсчет даст вам следующий понедельник, а не предыдущий.
Джованни Б.

4
Да .. В воскресенье, это дает следующий Modnay .. не предыдущий: P
Ajay Aradhya

64

Немного более многословно и с учетом культуры:

System.Globalization.CultureInfo ci = 
    System.Threading.Thread.CurrentThread.CurrentCulture;
DayOfWeek fdow = ci.DateTimeFormat.FirstDayOfWeek;
DayOfWeek today = DateTime.Now.DayOfWeek;
DateTime sow = DateTime.Now.AddDays(-(today - fdow)).Date;

4
получил ошибку с этим: сегодня = воскресенье; fdow = понедельник; (сегодня - ФДОУ) == -1; DateTime.Now.AddDays (- (- 1)). Date == DateTime.Now.AddDays (+1) .Date; 01-02-2010! = 25-01-2010 !!
balexandre

3
Если вы попробуете это в воскресенье, то в основном это AddDays (0 - 1) для en-GB. Так что ему нужно заявление if @ Sarcastic
Chris S

3
Вы также можете использовать текущую культуру, CultureInfo.CurrentCultureвместо того, чтобы вытягивать ее из темы. Похоже, странный способ получить к нему доступ.
Хэнк

7
Еще одна проблема: опасно называть Nowимущество дважды. Если между двумя вызовами текущее время пройдет 24:00 (или 12:00 полночь), дата изменится.
Джепп Стиг Нильсен

1
На самом деле этот ответ заключается в следующем: «внутри текущей недели .NET (начиная с воскресенья и заканчивая в субботу согласно нумерации перечисления DayOfWeek) найдите день недели .NET, который является первым днем ​​недели. в современной культуре ". Это, вероятно, не то, что вы хотите.
Матье Ренда

36

Использование Fluent DateTime :

var monday = DateTime.Now.Previous(DayOfWeek.Monday);
var sunday = DateTime.Now.Previous(DayOfWeek.Sunday);

29
Я бы не хотел брать зависимость только для этого. «Знай свои зависимости и убей их», кажется, приходит на ум. :)
Эстебан Арайя

7
Кто-нибудь заметил, КАК "Свободно" работает? Просто взгляните на код. Он использует цикл do ... while. Не хочу называть это именами, но если я решу это сделать, это не будет приятным. public static DateTime Previous(this DateTime start, DayOfWeek day) { do { start = start.PreviousDay(); } while (start.DayOfWeek != day); return start; }
nsimeonov

10
@nsimeonov это с открытым исходным кодом. пожалуйста, не стесняйтесь предоставлять лучшую реализацию, а не бросать камни.
Симон

12
Да, как будто у меня было все время в мире, чтобы исправить каждую ошибку в каждом программном обеспечении с открытым исходным кодом в мире ...
nsimeonov

4
Мне пришлось комментировать, потому что я получил огромный смех от жалобы на использование цикла "делать ... пока"! Веселое! Я никогда не слышал, чтобы другой программист вздрогнул о цикле. Хотелось бы увидеть лицо этого клоуна, когда / если он когда-нибудь поймет, во что на самом деле компилируется его код.
Джош Стодола

22

Уродливо, но это, по крайней мере, дает правильные даты

С началом недели, установленным системой:

    public static DateTime FirstDateInWeek(this DateTime dt)
    {
        while (dt.DayOfWeek != System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat.FirstDayOfWeek)
            dt = dt.AddDays(-1);
        return dt;
    }

Без:

    public static DateTime FirstDateInWeek(this DateTime dt, DayOfWeek weekStartDay)
    {
        while (dt.DayOfWeek != weekStartDay)
            dt = dt.AddDays(-1);
        return dt;
    }

3
Это действительно заслуживает большего количества голосов за его простоту и удобочитаемость.
ProfK

Этот ресурс тоже помог: markb.uk/… (если вы хотите получить первый / последний день недели или месяца).
FranzHuber23

13

Давайте объединим ответ, безопасный для культуры, и ответ метода расширения:

public static class DateTimeExtensions
{
    public static DateTime StartOfWeek(this DateTime dt, DayOfWeek startOfWeek)
    {
        System.Globalization.CultureInfo ci = System.Threading.Thread.CurrentThread.CurrentCulture;
        DayOfWeek fdow = ci.DateTimeFormat.FirstDayOfWeek;
        return DateTime.Today.AddDays(-(DateTime.Today.DayOfWeek- fdow));
    }
}

12
ни dt, ни startOfWeek не используются в вашей функции, я думаю, что первое должно использоваться вместо DateTime.Today
hultqvist

2
В контексте вопроса требуется, чтобы дополнительное свойство использовалось вне Datetime таким же образом, как .Today или .Now. Я согласен, что это неловко, но это то, о чем просили.
Джоэл Коухорн

7
Я знаю, что это старый ответ, но он неверен на многих уровнях; в дополнение к полному игнорированию аргументов метода, математика заставит его выбрать будущую дату во многих случаях. Это должно было быть написано, чтобы использовать dtвместо DateTime.Today, чтобы обернуть математику в, (offset + 7) % 7чтобы гарантировать отрицательное смещение, использовать перегрузку метода с одним параметром, которая передает текущую культуру в FirstDayOfWeekкачестве startOfWeekаргумента, и, возможно (в зависимости от спецификации), чтобы привести смещение нуля до 7-дневного смещения, так что «последний вторник» не возвращается сегодня, если это уже вторник.
Aaronaught

10

Это даст вам предыдущее воскресенье (я думаю):

DateTime t = DateTime.Now;
t -= new TimeSpan ((int) t.DayOfWeek, 0, 0, 0);

9

Это может быть немного хакерским, но вы можете привести свойство .DayOfWeek к int (это enum и поскольку его базовый тип данных не изменился, по умолчанию используется int) и использовать его для определения предыдущего начала недели. ,

Похоже, что неделя, указанная в перечислении DayOfWeek, начинается в воскресенье, поэтому, если мы вычтем 1 из этого значения, оно будет равно числу дней, в которые понедельник находится перед текущей датой. Нам также нужно сопоставить воскресенье (0) равным 7, поэтому при 1 - 7 = -6 воскресенье сопоставится с предыдущим понедельником: -

DateTime now = DateTime.Now;
int dayOfWeek = (int)now.DayOfWeek;
dayOfWeek = dayOfWeek == 0 ? 7 : dayOfWeek;
DateTime startOfWeek = now.AddDays(1 - (int)now.DayOfWeek);

Код предыдущего воскресенья проще, так как нам не нужно делать эту настройку:

DateTime now = DateTime.Now;
int dayOfWeek = (int)now.DayOfWeek;
DateTime startOfWeek = now.AddDays(-(int)now.DayOfWeek);

9

На понедельник

DateTime startAtMonday = DateTime.Now.AddDays(DayOfWeek.Monday - DateTime.Now.DayOfWeek);

На воскресенье

DateTime startAtSunday = DateTime.Now.AddDays(DayOfWeek.Sunday- DateTime.Now.DayOfWeek);

1
У меня была другая потребность в приложении, однако я использовал это, чтобы заставить меня работать. Мне это нравится, потому что он самый простой, без приведения - хранение операций в тех же / соответствующих типах.
qxotk

1
Это не работает, когда день воскресенье. Это дает следующий понедельник, а не начало текущей недели.
Грант J

Также вы скопировали воскресенье или понедельник. У меня есть 2 ответа: один, если вы хотите в понедельник, и 2 часа, если вы хотите в воскресенье ..... Я только что проверил его, и он прекрасно работает для меня. DateTime.Now.DayOfWeek; Воскресенье и результат DateTime.Now.AddDays (DayOfWeek.Sunday - DateTime.Now.DayOfWeek); {10/11/2019 4:14:55 μμ} Дата: {10/11/2019 12:00:00 πμ} День: 10 DayOfWeek: воскресенье DayOfYear: 314 Час: 16 Вид: Местная Миллисекунда: 172 Минута: 14 Месяц : 11 Секунда: 55 Тиков: 637089992951723516 TimeOfDay: {16: 14: 55.1723516} Год: 2019
Джордж Ставру

@GrantJ Какую линию ты взял ??? Я только что проверил, и это отлично работает.
Джордж

Я попробовал первый, заменив ваш DateTime.Now на DateTime, представляющий воскресенье 10 ноября 2019 года. Он должен давать понедельник 4 ноября 2019 года, но это понедельник 11 ноября 2019 года. Я настроил скрипку, демонстрирующую это здесь: dotnetfiddle.net/ Jw3ZiO
Грант J

5
using System;
using System.Globalization;

namespace MySpace
{
    public static class DateTimeExtention
    {
        // ToDo: Need to provide culturaly neutral versions.

        public static DateTime GetStartOfWeek(this DateTime dt)
        {
            DateTime ndt = dt.Subtract(TimeSpan.FromDays((int)dt.DayOfWeek));
            return new DateTime(ndt.Year, ndt.Month, ndt.Day, 0, 0, 0, 0);
        }

        public static DateTime GetEndOfWeek(this DateTime dt)
        {
            DateTime ndt = dt.GetStartOfWeek().AddDays(6);
            return new DateTime(ndt.Year, ndt.Month, ndt.Day, 23, 59, 59, 999);
        }

        public static DateTime GetStartOfWeek(this DateTime dt, int year, int week)
        {
            DateTime dayInWeek = new DateTime(year, 1, 1).AddDays((week - 1) * 7);
            return dayInWeek.GetStartOfWeek();
        }

        public static DateTime GetEndOfWeek(this DateTime dt, int year, int week)
        {
            DateTime dayInWeek = new DateTime(year, 1, 1).AddDays((week - 1) * 7);
            return dayInWeek.GetEndOfWeek();
        }
    }
}

3
Прежде всего, добро пожаловать в сообщество :) Уже есть несколько высококачественных ответов на этот вопрос, большинство из которых были опубликованы семь лет назад, когда был задан вопрос. Хотя может быть полезным попытаться ответить на простые вопросы, подобные этому, чтобы расширить свои навыки программирования, публикация этого ответа в его текущем состоянии ничего не добавляет к вопросу. Если в вашем ответе есть что-то новое, пожалуйста, возьмите пару предложений, чтобы объяснить, чем он отличается и почему это делает его лучше.
MTCoster

4

Собираем все вместе, с помощью глобализации и позволяем указать первый день недели как часть нашего звонка

public static DateTime StartOfWeek ( this DateTime dt, DayOfWeek? firstDayOfWeek )
{
    DayOfWeek fdow;

    if ( firstDayOfWeek.HasValue  )
    {
        fdow = firstDayOfWeek.Value;
    }
    else
    {
        System.Globalization.CultureInfo ci = System.Threading.Thread.CurrentThread.CurrentCulture;
        fdow = ci.DateTimeFormat.FirstDayOfWeek;
    }

    int diff = dt.DayOfWeek - fdow;

    if ( diff < 0 )
    {
        diff += 7;
    }

    return dt.AddDays( -1 * diff ).Date;

}

4
var now = System.DateTime.Now;

var result = now.AddDays(-((now.DayOfWeek - System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat.FirstDayOfWeek + 7) % 7)).Date;

2

Это даст вам полночь в первое воскресенье недели:

DateTime t = DateTime.Now;
t -= new TimeSpan ((int) t.DayOfWeek, t.Hour, t.Minute, t.Second);

Это дает вам первый понедельник в полночь:

DateTime t = DateTime.Now;
t -= new TimeSpan ((int) t.DayOfWeek - 1, t.Hour, t.Minute, t.Second);

2

попробуйте это в c #. С помощью этого кода вы можете получить как первую дату, так и последнюю дату данной недели. Здесь воскресенье - первый день, а суббота - последний день, но вы можете установить оба дня в соответствии с вашей культурой.

DateTime firstDate = GetFirstDateOfWeek(DateTime.Parse("05/09/2012").Date,DayOfWeek.Sunday);
DateTime lastDate = GetLastDateOfWeek(DateTime.Parse("05/09/2012").Date, DayOfWeek.Saturday);

public static DateTime GetFirstDateOfWeek(DateTime dayInWeek, DayOfWeek firstDay)
{
    DateTime firstDayInWeek = dayInWeek.Date;
    while (firstDayInWeek.DayOfWeek != firstDay)
        firstDayInWeek = firstDayInWeek.AddDays(-1);

    return firstDayInWeek;
}
public static DateTime GetLastDateOfWeek(DateTime dayInWeek, DayOfWeek firstDay)
{
    DateTime lastDayInWeek = dayInWeek.Date;
    while (lastDayInWeek.DayOfWeek != firstDay)
        lastDayInWeek = lastDayInWeek.AddDays(1);

    return lastDayInWeek;
}

2

Пробовал несколько, но не решил проблему с неделей, начинающейся в понедельник, в результате чего дал мне грядущий понедельник в воскресенье. Поэтому я немного изменил его и заставил работать с этим кодом:

int delta = DayOfWeek.Monday - DateTime.Now.DayOfWeek;
DateTime monday = DateTime.Now.AddDays(delta == 1 ? -6 : delta);
return monday;

Кажется, что проблема «наступающего понедельника» зависит от культуры (см. Также ответ от Эрика и комментарий от Cerveser.) Однако, если вам не нужно учитывать воскресенья (как при обычных деловых встречах), ваша формула может Упрощенно:dt.AddDays(DayOfWeek.Monday - dt.DayOfWeek);
Дамиан Фогель

2

Шаг 1: Создайте статический класс

  public static class TIMEE
{
    public static DateTime StartOfWeek(this DateTime dt, DayOfWeek startOfWeek)
    {
        int diff = (7 + (dt.DayOfWeek - startOfWeek)) % 7;
        return dt.AddDays(-1 * diff).Date;
    }
    public static DateTime EndOfWeek(this DateTime dt, DayOfWeek startOfWeek)
    {
        int diff = (7 - (dt.DayOfWeek - startOfWeek)) % 7;
        return dt.AddDays(1 * diff).Date;
    }
}

Шаг 2: Используйте этот класс, чтобы получить начальный и конечный день недели

 DateTime dt =TIMEE.StartOfWeek(DateTime.Now ,DayOfWeek.Monday);
        DateTime dt1 = TIMEE.EndOfWeek(DateTime.Now, DayOfWeek.Sunday);

Конец недели требуется (6 - (dt.DayOfWeek - startOfWeek)) % 7для меня против модульных тестов, которые я написал.
mlhDev

1

Следующий метод должен вернуть DateTime, который вы хотите. Введите true для воскресенья, являющегося первым днем ​​недели, false для понедельника:

private DateTime getStartOfWeek(bool useSunday)
{
    DateTime now = DateTime.Now;
    int dayOfWeek = (int)now.DayOfWeek;

    if(!useSunday)
        dayOfWeek--;

    if(dayOfWeek < 0)
    {// day of week is Sunday and we want to use Monday as the start of the week
    // Sunday is now the seventh day of the week
        dayOfWeek = 6;
    }

    return now.AddDays(-1 * (double)dayOfWeek);
}

1

Спасибо за примеры. Мне нужно было всегда использовать «CurrentCulture» в первый день недели, и для массива мне нужно было знать точное число Daynumber .. поэтому вот мои первые расширения:

public static class DateTimeExtensions
{
    //http://stackoverflow.com/questions/38039/how-can-i-get-the-datetime-for-the-start-of-the-week
    //http://stackoverflow.com/questions/1788508/calculate-date-with-monday-as-dayofweek1
    public static DateTime StartOfWeek(this DateTime dt)
    {
        //difference in days
        int diff = (int)dt.DayOfWeek - (int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek; //sunday=always0, monday=always1, etc.

        //As a result we need to have day 0,1,2,3,4,5,6 
        if (diff < 0)
        {
            diff += 7;
        }
        return dt.AddDays(-1 * diff).Date;
    }

    public static int DayNoOfWeek(this DateTime dt)
    {
        //difference in days
        int diff = (int)dt.DayOfWeek - (int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek; //sunday=always0, monday=always1, etc.

        //As a result we need to have day 0,1,2,3,4,5,6 
        if (diff < 0)
        {
            diff += 7;
        }
        return diff + 1; //Make it 1..7
    }
}

1

Кажется, никто еще не ответил правильно. Я вставлю свое решение здесь, на случай, если оно кому-нибудь понадобится. Следующий код работает независимо от того, является ли первый день недели понедельником, воскресеньем или чем-то еще.

public static class DateTimeExtension
{
  public static DateTime GetFirstDayOfThisWeek(this DateTime d)
  {
    CultureInfo ci = System.Threading.Thread.CurrentThread.CurrentCulture;
    var first = (int)ci.DateTimeFormat.FirstDayOfWeek;
    var current = (int)d.DayOfWeek;

    var result = first <= current ?
      d.AddDays(-1 * (current - first)) :
      d.AddDays(first - current - 7);

    return result;
  }
}

class Program
{
  static void Main()
  {
    System.Threading.Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("en-US");
    Console.WriteLine("Current culture set to en-US");
    RunTests();
    Console.WriteLine();
    System.Threading.Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("da-DK");
    Console.WriteLine("Current culture set to da-DK");
    RunTests();
    Console.ReadLine();
  }

  static void RunTests()
  {
    Console.WriteLine("Today {1}: {0}", DateTime.Today.Date.GetFirstDayOfThisWeek(), DateTime.Today.Date.ToString("yyyy-MM-dd"));
    Console.WriteLine("Saturday 2013-03-02: {0}", new DateTime(2013, 3, 2).GetFirstDayOfThisWeek());
    Console.WriteLine("Sunday 2013-03-03: {0}", new DateTime(2013, 3, 3).GetFirstDayOfThisWeek());
    Console.WriteLine("Monday 2013-03-04: {0}", new DateTime(2013, 3, 4).GetFirstDayOfThisWeek());
  }
}

1

Modulo в C # работает плохо для -1mod7 (должно быть 6, c # возвращает -1), так что ... решение "oneliner" для этого будет выглядеть так :)

private static DateTime GetFirstDayOfWeek(DateTime date)
    {
        return date.AddDays(-(((int)date.DayOfWeek - 1) - (int)Math.Floor((double)((int)date.DayOfWeek - 1) / 7) * 7));
    }

1

То же самое в конце недели (в стиле @Compile Это ответ):

    public static DateTime EndOfWeek(this DateTime dt)
    {
        int diff = 7 - (int)dt.DayOfWeek;

        diff = diff == 7 ? 0 : diff;

        DateTime eow = dt.AddDays(diff).Date;

        return new DateTime(eow.Year, eow.Month, eow.Day, 23, 59, 59, 999) { };
    }

0

Вы можете использовать отличную библиотеку Umbrella :

using nVentive.Umbrella.Extensions.Calendar;
DateTime beginning = DateTime.Now.BeginningOfWeek();

Однако они , похоже, сохранили понедельник как первый день недели (см. Свойство nVentive.Umbrella.Extensions.Calendar.DefaultDateTimeCalendarExtensions.WeekBeginsOn), так что предыдущее локализованное решение немного лучше. Несчастная.

Изменить : если присмотреться к вопросу, похоже, что Umbrella на самом деле тоже может сработать:

// Or DateTime.Now.PreviousDay(DayOfWeek.Monday)
DateTime monday = DateTime.Now.PreviousMonday(); 
DateTime sunday = DateTime.Now.PreviousSunday();

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


0

Это вернет даты начала и конца недели:

    private string[] GetWeekRange(DateTime dateToCheck)
    {
        string[] result = new string[2];
        TimeSpan duration = new TimeSpan(0, 0, 0, 0); //One day 
        DateTime dateRangeBegin = dateToCheck;
        DateTime dateRangeEnd = DateTime.Today.Add(duration);

        dateRangeBegin = dateToCheck.AddDays(-(int)dateToCheck.DayOfWeek);
        dateRangeEnd = dateToCheck.AddDays(6 - (int)dateToCheck.DayOfWeek);

        result[0] = dateRangeBegin.Date.ToString();
        result[1] = dateRangeEnd.Date.ToString();
        return result;

    }

Я разместил полный код для вычисления начала / конца недели, месяца, квартала и года в моем блоге ZamirsBlog


0
    namespace DateTimeExample
    {
        using System;

        public static class DateTimeExtension
        {
            public static DateTime GetMonday(this DateTime time)
            {
                if (time.DayOfWeek != DayOfWeek.Monday)
                    return GetMonday(time.AddDays(-1)); //Recursive call

                return time;
            }
        }

        internal class Program
        {
            private static void Main()
            {
                Console.WriteLine(DateTime.Now.GetMonday());
                Console.ReadLine();
            }
        }
    } 

Можете ли вы расширить свой ответ, чтобы включить объяснение вашего кода? Это помогает читателю больше, чем вы думаете.
gunr2171

Использование рекурсии - очень плохая реализация. То, что вы можете использовать рекурсии, не означает, что вы должны это делать. Это будет медленнее и больше памяти, чем другие решения, представленные здесь.
mikecamimo

0

Вот комбинация нескольких ответов. Он использует метод расширения, который позволяет передавать культуру, если она не передана, используется текущая культура. Это даст ему максимальную гибкость и повторное использование.

/// <summary>
/// Gets the date of the first day of the week for the date.
/// </summary>
/// <param name="date">The date to be used</param>
/// <param name="cultureInfo">If none is provided, the current culture is used</param>
/// <returns>The date of the beggining of the week based on the culture specifed</returns>
public static DateTime StartOfWeek(this DateTime date, CultureInfo cultureInfo=null) =>         
             date.AddDays(-1 * (7 + (date.DayOfWeek - (cultureInfo??CultureInfo.CurrentCulture).DateTimeFormat.FirstDayOfWeek)) % 7).Date;

Пример использования:

public static void TestFirstDayOfWeekExtension() {          
        DateTime date = DateTime.Now;
        foreach(System.Globalization.CultureInfo culture in CultureInfo.GetCultures(CultureTypes.UserCustomCulture | CultureTypes.SpecificCultures)) {
            Console.WriteLine($"{culture.EnglishName}: {date.ToShortDateString()} First Day of week: {date.StartOfWeek(culture).ToShortDateString()}");
        }
    }

0

если вы хотите, чтобы суббота или воскресенье или любой другой день недели, но не превышали текущую неделю (суббота-воскресенье), я покрою вас этим фрагментом кода.

public static DateTime GetDateInCurrentWeek(this DateTime date, DayOfWeek day)
{
    var temp = date;
    var limit = (int)date.DayOfWeek;
    var returnDate = DateTime.MinValue;

    if (date.DayOfWeek == day) return date;

    for (int i = limit; i < 6; i++)
    {
        temp = temp.AddDays(1);

        if (day == temp.DayOfWeek)
        {
            returnDate = temp;
            break;
        }
    }
    if (returnDate == DateTime.MinValue)
    {
        for (int i = limit; i > -1; i++)
        {
            date = date.AddDays(-1);

            if (day == date.DayOfWeek)
            {
                returnDate = date;
                break;
            }
        }
    }
    return returnDate;
}

0

Нам нравятся строки: получите разницу между первым днем ​​недели текущей культуры и текущим днем, затем вычтите количество дней из текущего дня.

var weekStartDate = DateTime.Now.AddDays(-((int)now.DayOfWeek - (int)DateTimeFormatInfo.CurrentInfo.FirstDayOfWeek));

0

Следуя ответу «Скомпилируйте этот ответ», используйте следующий метод, чтобы получить дату для любого дня недели:

public static DateTime GetDayOfWeek(this DateTime dt, DayOfWeek day)
{            
    int diff = (7 + (dt.DayOfWeek - DayOfWeek.Monday)) % 7;
    var monday = dt.AddDays(-1 * diff).Date;

    switch (day)
    {
        case DayOfWeek.Tuesday:
            return monday.AddDays(1).Date;

        case DayOfWeek.Wednesday:
            return monday.AddDays(2).Date;

        case DayOfWeek.Thursday:
            return monday.AddDays(3).Date;

        case DayOfWeek.Friday:
            return monday.AddDays(4).Date;

        case DayOfWeek.Saturday:
            return monday.AddDays(5).Date;

        case DayOfWeek.Sunday:
            return monday.AddDays(6).Date;
    }

    return monday;
}

0

Попробуйте создать функцию, которая использует рекурсию. Ваш объект DateTime является входным параметром, и функция возвращает новый объект DateTime, который обозначает начало недели.

    DateTime WeekBeginning(DateTime input)
    {
        do
        {
            if (input.DayOfWeek.ToString() == "Monday")
                return input;
            else
                return WeekBeginning(input.AddDays(-1));
        } while (input.DayOfWeek.ToString() == "Monday");
    }

Хотя этот код может решить вопрос, в том числе объяснение того, как и почему это решает проблему, действительно поможет улучшить качество вашего сообщения и, вероятно, получит больше голосов "за". Помните, что вы отвечаете на вопрос для читателей в будущем, а не только для того, кто спрашивает сейчас. Пожалуйста, измените свой ответ, чтобы добавить объяснения и указать, какие ограничения и предположения применяются.
Дэвид Бак

0

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

Обратите внимание, что выполнение этого расчета для дня, который является понедельником, даст текущий понедельник, а не предыдущий.

//Replace with whatever input date you want
DateTime inputDate = DateTime.Now;

//For this example, weeks start on Monday
int startOfWeek = (int)DayOfWeek.Monday;

//Calculate the number of days it has been since the start of the week
int daysSinceStartOfWeek = ((int)inputDate.DayOfWeek + 7 - startOfWeek) % 7;

DateTime previousStartOfWeek = inputDate.AddDays(-daysSinceStartOfWeek);
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.