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

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

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

DateTime.Now.StartWeek(Monday);
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
503
0
297 477
33
Перейти к ответу Данный вопрос помечен как решенный

Ответы 33

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

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

Следующий метод должен вернуть нужный 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);
}

Это может быть чем-то вроде взлома, но вы можете преобразовать свойство .DayOfWeek в int (это перечисление, и, поскольку его базовый тип данных не изменен, по умолчанию он имеет значение 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);
Ответ принят как подходящий

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

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

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

Troy 29.03.2011 03:28

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

Aaron Hoffman 23.04.2012 18:55

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

row1 06.09.2012 08:12

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

Rawling 22.01.2013 14:51

@Rawling результат работы с типом UTC через .ToUniversalTime () для меня не ожидается - я ожидаю, что он вернет 2012-09-02 16: 00: 00Z. Я также не думаю, что использование .Date для даты в формате UTC имеет смысл, поскольку вы можете легко потерять день, если вы передаете даты в формате UTC, но ожидаете локальных результатов ... ну, в любом случае, это не имеет смысла для моего использования.

row1 23.01.2013 04:51

@Troy, ваш код на самом деле очень похож на код для EndOfWeek ;-). int diff = endOfWeek - dt.DayOfWeek; return dt.AddDays(diff).Date;

Sometowngeek 21.07.2016 15:59

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

Vincent Saelzler 26.05.2017 20:43

Немного более подробный и культурный:

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;

получил ошибку с этим: сегодня = ВОСКРЕСЕНЬЕ; fdow = ПОНЕДЕЛЬНИК; (сегодня - fdow) == -1; DateTime.Now.AddDays (- (- 1)). Date == DateTime.Now.AddDays (+1) .Date; 01-02-2010! = 25-01-2010 !!

balexandre 01.02.2010 01:44

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

Chris S 15.05.2011 18:30

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

Hank 10.12.2012 22:09

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

Jeppe Stig Nielsen 02.09.2013 19:21

На самом деле этот ответ таков: «внутри текущей недели .NET (начиная с воскресенья и заканчивая субботой, согласно нумерации перечисления DayOfWeek) найдите день недели .NET, который является первым днем ​​недели. в современной культуре ». Вероятно, это не то, что вам нужно.

Mathieu Renda 12.07.2016 20:36

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

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

Вы можете использовать отличный Зонтичная библиотека:

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, что кажется ошибкой :(.

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

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

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

hultqvist 04.05.2010 12:17

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

Joel Coehoorn 15.09.2011 00:47

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

Aaronaught 23.01.2012 19:34

Используя Беглый DateTime:

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

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

Esteban Araya 28.05.2010 07:36

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

nsimeonov 23.04.2013 01:10

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

Simon 23.04.2013 02:57

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

nsimeonov 04.06.2014 22:40

@EstebanAraya: haneycodes.net/npm-left-pad-have-we-forgotten-how-to-program

Jim G. 30.03.2016 20:16

public static System.DateTime getstartweek()
{
    System.DateTime dt = System.DateTime.Now;
    System.DayOfWeek dmon = System.DayOfWeek.Monday;
    int span = dt.DayOfWeek - dmon;
    dt = dt.AddDays(-span);
    return dt;
}

Спасибо за примеры. Мне нужно было всегда использовать "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
    }
}

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

    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;

    }

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

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

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

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

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

ProfK 07.12.2016 08:05

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

FranzHuber23 06.05.2019 12:57

Я должен согласиться, что это самый надежный метод. Просто посмотрите на все крайние случаи, с которыми встречаются другие ответы. Я слышу аргумент об эффективности, но в худшем случае вы начинаете в последний день недели и должны шесть раз вызывать AddDays, чтобы вернуться к началу. Это в пять раз больше, чем в других решениях в худшем случае, но эти решения также должны иметь дело с другими числовыми вычислениями для получения смещения. Разница, вероятно, незначительна во всех приложениях, кроме наиболее чувствительных к производительности.

Blake 23.07.2020 19:04

попробуйте с этим в 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;
}

Объединяя все это вместе с Глобализацией и позволяя указать первый день недели как часть звонка, мы имеем

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;

}

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

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

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

Cerveser 08.10.2014 23:06

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

0xDEAD BEEF 01.02.2016 19:39

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

Loligans 14.06.2016 18:52

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

Giovanni B 14.08.2017 22:49

Да .. Воскресенье дает следующий понедельник .. не предыдущий: P

Ajay Aradhya 14.02.2018 09:27

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

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

var now = System.DateTime.Now;

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

    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 02.10.2014 23:22

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

mikecamimo 31.08.2017 01:45

   d = DateTime.Now;
            int dayofweek =(int) d.DayOfWeek;
            if (dayofweek != 0)
            {
                d = d.AddDays(1 - dayofweek);
            }
            else { d = d.AddDays(-6); }

Вам нужно объяснить свой ответ

Machavity 17.03.2015 21:19

Этот ответ что-то добавляет, остальные ответы пропущены?

nvoigt 17.03.2015 21:31

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

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

MTCoster 05.12.2015 21:02

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

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

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

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

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

Damian Vogel 11.07.2018 12:03

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

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

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

/// <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()}");
        }
    }

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

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

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

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

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

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

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

qxotk 29.01.2019 18:04

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

Grant J 06.11.2019 16:31

Также вы скопировали воскресенье или понедельник. У меня есть 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

George Stavrou 06.11.2019 17:15

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

George Stavrou 06.11.2019 17:21

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

Grant J 07.11.2019 18:33

@GrantJ Если вы понизите мой ответ, вы ошибаетесь. Прежде всего отвечаю на вопрос. 2 изо всех начала недели Согласно Visual Studio, это воскресенье ... Не понедельник ....... Итак, если это 10/11/2019 (дд / ММ / гггг воскресенье, тогда начало недели 10/11/2019) Также, если вы хотите понедельник и день 10/11/2019, тогда, если неделя начинается в воскресенье, как указано ниже, то если это 10/11/2019, и вы хотите начать недели это будет 11.11.2019. Вы можете проверить это здесь. docs.microsoft.com/en-us/dotnet/api/…

George Stavrou 07.11.2019 18:59

@GrantJ Если у вас другая информация о культуре, вам следует проверить ответ Джоэла Кохорна.

George Stavrou 07.11.2019 19:28

Я думаю, вы неправильно поняли вопрос. Сравните результаты вашего ответа с принятым ответом. Либо так, либо вы неправильно сформулировали свой ответ. Я продемонстрировал, что код, который вы разместили под заголовком «На понедельник», явно указывает на понедельник следующей недели (независимо от культуры, ваш ответ сформулирован так, как будто он предназначен для людей, желающих начать неделю, когда неделя начинается понедельник).

Grant J 08.11.2019 11:38

Думаю, теперь я понимаю ваш ответ - он дает вам понедельник или воскресенье, если вы начинаете неделю в воскресенье, что (будет подходящим только для определенных культур). Однако вопрос заключался в решении, которое дает вам Начните недели, а не для решения, которое дает вам понедельник или воскресенье, если неделя начинается в воскресенье.

Grant J 08.11.2019 11:49

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

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

Шаг 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 23.12.2019 20:27

Следуя указаниям Compile This 'Answer, используйте следующий метод, чтобы получить дату для любого дня недели:

public static DateTime GetDayOfWeek(DateTime dateTime, DayOfWeek dayOfWeek)
{
   var monday = dateTime.Date.AddDays((7 + (dateTime.DayOfWeek - DayOfWeek.Monday) % 7) * -1);

   var diff = dayOfWeek - DayOfWeek.Monday;

   if (diff == -1)
   {
      diff = 6;
   }

   return monday.AddDays(diff);
} 

Попробуйте создать функцию, использующую рекурсию. Ваш объект 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");
    }

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

David Buck 27.03.2020 22:56

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

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

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

Сделал это для понедельника, но аналогичная логика для воскресенья.

public static DateTime GetStartOfWeekDate()
{
    // Get today's date
    DateTime today = DateTime.Today;
    // Get the value for today. DayOfWeek is an enum with 0 being Sunday, 1 Monday, etc
    var todayDayOfWeek = (int)today.DayOfWeek;

    var dateStartOfWeek = today;
    // If today is not Monday, then get the date for Monday
    if (todayDayOfWeek != 1)
    {
        // How many days to get back to Monday from today
        var daysToStartOfWeek = (todayDayOfWeek - 1);
        // Subtract from today's date the number of days to get to Monday
        dateStartOfWeek = today.AddDays(-daysToStartOfWeek);
    }

    return dateStartOfWeek;

}

Другие вопросы по теме