Como posso obter o DateTime para o início da semana?

469

Como localizo o início da semana (domingo e segunda-feira) sabendo exatamente o horário atual em c #?

Algo como:

DateTime.Now.StartWeek(Monday);
GateKiller
fonte

Respostas:

746

Use um método de extensão. Eles são a resposta para tudo, você sabe! ;)

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

Que pode ser usado da seguinte maneira:

DateTime dt = DateTime.Now.StartOfWeek(DayOfWeek.Monday);
DateTime dt = DateTime.Now.StartOfWeek(DayOfWeek.Sunday);
Compilar isto
fonte
15
Você pode simplificar isso da seguinte maneira: int diff = dayOfWeek - dt.DayOfWeek; return dt.AddDays(diff).Date;
Troy
13
Troy, não acredito que seu código funcione se a data especificada for domingo e o início da semana for segunda-feira. Ele irá retornar (domingo + 1) em vez de (domingo - 6)
Aaron Hoffman
1
Isso não funciona se dtfor UTC e já é o início da semana, por exemplo, 2012-09-02 16:00:00Zque está Mon, 03 Sep 2012 00:00:00no horário local. Portanto, ele precisa converter dtpara a hora local ou fazer algo um pouco mais inteligente. Também seria necessário retornar o resultado como UTC se a entrada fosse UTC.
Row1
1
@ row1 DateTime.Parse("2012-09-02 16:00:00Z")retorna o equivalente à hora local e esse método retorna corretamente a mesma hora, como uma hora local. Se você usar DateTime.Parse("2012-09-02 16:00:00Z").ToUniversalTime()para passar explicitamente o horário UTC, esse método retornará corretamente 6 dias, 16 horas antes, como horário UTC. Está funcionando exatamente como eu esperava.
Rawling
1
Às vezes, isso me custaria um dia. Funcionou para mim uma vez que retirei o componente de tempo dt. Eu useiint diff = dt.Date.DayOfWeek - startOfWeek;
Vincent Saelzler
80

A maneira mais rápida de criar é:

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

Se você deseja que qualquer outro dia da semana seja sua data de início, tudo o que você precisa fazer é adicionar o valor DayOfWeek ao final

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

var tuesday = DateTime.Today.AddDays(-(int)DateTime.Today.DayOfWeek + (int)DayOfWeek.Tuesday); 
Eric
fonte
2
as respostas mais simples são o melhor, este funcionou bem, mas a cultura dependia
Cerveser
7
Na Letónia semana começa na segunda-feira .. Na verdade .. Eu sempre me pergunto como pode uma semana início no domingo .. parece estranho para mim ..;)
0xDEAD BEEF
Esta solução é boa. Além disso, você pode fazer o início da semana em qualquer dia adicionando o DayOfWeek em que deseja iniciar. var domingo: DateTime.Today.AddDays (- (int) DateTime.Today.DayOfWeek); var segunda-feira = DateTime.Today.AddDays (- (int) DateTime.Today.DayOfWeek + (int) DayOfWeek.Monday);
Loligans
7
Este código adicionado não funciona para a situação descrita pelo Threezol. Se você deseja que o início da semana seja segunda-feira, no domingo o cálculo fornece a próxima segunda-feira, não a anterior.
Giovanni B
4
Sim .. para domingo, dá o próximo Modnay .. não o anterior: P
Ajay Aradhya
64

Um pouco mais detalhado e consciente da cultura:

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;
Jason Navarrete
fonte
4
Ocorreu um erro com este: hoje = DOMINGO; fdow = segunda-feira; (hoje - fdow) == -1; DateTime.Now.AddDays (- (- 1)). Data == DateTime.Now.AddDays (+1) .Date; 01-02-2010! = 25-01-2010 !!
precisa saber é o seguinte
3
Se você tentar isso em um domingo, basicamente estará fazendo AddDays (0 - 1) para en-GB. Por isso, precisa de declaração @ do sarcastic #
Chris S
3
Você também pode obter a cultura atual usando, em CultureInfo.CurrentCulturevez de retirá-la da discussão dessa maneira. Parece uma maneira estranha de acessá-lo.
Hank
7
Outra questão: é perigoso ligar para a Nowpropriedade duas vezes. Se a hora atual passar das 24:00 (ou 12:00 da meia-noite) entre as duas chamadas, a data será alterada.
Jeppe Stig Nielsen
1
O que essa resposta realmente faz é: "na semana atual do .NET (iniciando no domingo e terminando no sábado, conforme a numeração da enumeração DayOfWeek), localize o dia da semana do .NET que é a primeira da semana na cultura atual ". Provavelmente não é isso que você deseja.
Mathieu Renda
36

Usando Fluente DateTime :

var monday = DateTime.Now.Previous(DayOfWeek.Monday);
var sunday = DateTime.Now.Previous(DayOfWeek.Sunday);
Simon
fonte
29
Eu odiaria assumir uma dependência apenas por isso. "Conheça suas dependências e mate-as" parece vir à mente. :)
Esteban Araya
7
Alguém notou COMO o "Fluente" está funcionando? Basta dar uma olhada no código. Está usando um loop do ... while. Não quero chamá-lo de nomes, mas se eu decidir fazer isso não será agradável. public static DateTime Previous(this DateTime start, DayOfWeek day) { do { start = start.PreviousDay(); } while (start.DayOfWeek != day); return start; }
Nsimeonov
10
@nsimeonov é de código aberto. sinta-se à vontade para fornecer uma melhor implementação em vez de atirar pedras.
22413 Simon
12
Sim, como se eu tivesse todo o tempo do mundo para corrigir todos os erros único em cada software de código aberto no mundo ...
nsimeonov
4
Eu tive que comentar porque ri bastante da reclamação sobre o uso de um loop "faça ... enquanto"! Hilário! Eu nunca ouvi outro programador tremer sobre um loop antes. Adoraria ver o rosto desse palhaço quando / se ele perceber o que seu código realmente compila.
Josh Stodola
22

Feio, mas pelo menos dá as datas certas

Com o início da semana definido pelo sistema:

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

Sem:

    public static DateTime FirstDateInWeek(this DateTime dt, DayOfWeek weekStartDay)
    {
        while (dt.DayOfWeek != weekStartDay)
            dt = dt.AddDays(-1);
        return dt;
    }
Janspeed
fonte
3
Isso realmente merece mais votos por sua simplicidade e legibilidade.
ProfK
Esse recurso também ajudou: markb.uk/… (Se você deseja obter o primeiro / último dia de uma semana ou mês).
FranzHuber23
13

Vamos combinar a resposta de segurança da cultura e a resposta do método de extensão:

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));
    }
}
Joel Coehoorn
fonte
12
nem dt nem startOfWeek são usados ​​em sua função, acho que o primeiro deve ser usado em vez de DateTime
Hoje
2
O contexto da pergunta está querendo que uma propriedade adicional seja usada fora do Datetime da mesma maneira que. Hoje ou. Agora. Concordo que isso é estranho, mas foi o que foi solicitado.
Joel Coehoorn
7
Eu sei que essa é uma resposta antiga, mas está errada em muitos níveis; além de ignorar totalmente os argumentos do método, a matemática fará com que escolha uma data futura em muitos casos. Isso deveria ter sido escrito para usar em dtvez de DateTime.Today, para envolver a matemática em (offset + 7) % 7para garantir um deslocamento negativo, para usar uma sobrecarga de método de parâmetro único que passa a cultura atual FirstDayOfWeekcomo startOfWeekargumento e, possivelmente (dependendo da especificação), para coagir um deslocamento de zero para deslocamento de 7 dias, para que a "última terça-feira" não retorne hoje se já for terça-feira.
Aaronaught
10

Isso daria a você no domingo anterior (eu acho):

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

Isso pode ser um pouco complicado, mas você pode converter a propriedade .DayOfWeek em um int (é uma enumeração e, como o tipo de dados subjacente não foi alterado, o padrão é int) e pode ser usado para determinar o início da semana anterior .

Parece que a semana especificada na enumeração DayOfWeek começa no domingo; portanto, se subtrairmos 1 desse valor, será igual a quantos dias a segunda-feira é anterior à data atual. Também precisamos mapear o domingo (0) para ser igual a 7, portanto, dado 1 - 7 = -6, o domingo será mapeado para a segunda-feira anterior: -

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

O código do domingo anterior é mais simples, pois não precisamos fazer esse ajuste: -

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

Para segunda-feira

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

Para domingo

DateTime startAtSunday = DateTime.Now.AddDays(DayOfWeek.Sunday- DateTime.Now.DayOfWeek);
George Stavrou
fonte
1
Eu tinha uma necessidade de aplicação diferente, no entanto, usei isso para continuar. Gosto porque é o mais simples, sem nenhum vazamento - mantendo as operações nos mesmos / tipos apropriados.
Qxotk
1
Isso não funciona quando o dia é domingo. Dá a segunda-feira seguinte, não o começo da semana atual.
Grant J
Você também copiou o domingo ou a segunda-feira. Eu tenho 2 respostas Uma, se você quiser na segunda-feira e 2 na, se você quiser no domingo ..... Acabei de testar e funciona bem para mim. DateTime.Now.DayOfWeek; Domingo e resultado DateTime.Now.AddDays (DayOfWeek.Sunday - DateTime.Now.DayOfWeek); {10/11/2019 4:14:55 μμ} Data: {10/11/2019 12:00:00 πμ} Dia: 10 Dia da semana: Domingo Dia do ano: 314 Hora: 16 Tipo: Milissegundo local: 172 Minuto: 14 meses : 11 Second: 55 Ticks: 637089992951723516 TimeOfDay: {16: 14: 55.1723516} Ano: 2019
George Stavrou
@GrantJ Que linha você pegou ??? Acabei de testar e funciona bem.
George Stavrou
Tentei o primeiro, substituindo seu DateTime. Agora, por um DateTime que representa domingo, 10 de novembro de 2019. Ele deve ser entregue na segunda-feira 4 de novembro de 2019, mas será entregue na segunda-feira 11 de novembro de 2019. Configurei um violino para demonstrá-lo aqui: dotnetfiddle.net/ Jw3ZiO
Grant 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();
        }
    }
}
Urso marrom
fonte
3
Primeiro, seja bem-vindo à comunidade :) Já existem várias respostas de alta qualidade para esta pergunta, a maioria das quais foram publicadas há sete anos quando a pergunta foi feita. Embora possa ser um exercício útil tentar responder a perguntas simples como esta para aprimorar suas habilidades de programação, postar essa resposta em seu estado atual não adiciona nada à pergunta. Se houver algo novo em sua resposta, faça algumas frases para explicar como é diferente e por que isso a torna melhor.
MTCoster
4

Juntando tudo, com a Globalização e permitindo especificar o primeiro dia da semana como parte da chamada que realizamos

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;

}
Matthew Hintzen
fonte
4
var now = System.DateTime.Now;

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

Isso lhe daria meia-noite no primeiro domingo da semana:

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

Isso fornece a primeira segunda-feira à meia-noite:

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

tente com isso em c #. Com esse código, você pode obter a primeira data e a última data de uma determinada semana. Aqui o domingo é o primeiro dia e o sábado é o último dia, mas você pode definir os dois dias de acordo com sua cultura

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;
}
yeasir007
fonte
2

Tentei várias, mas não resolvi o problema com uma semana a partir de segunda-feira, resultando em uma segunda-feira que chegaria no domingo. Então eu modifiquei um pouco e consegui trabalhar com este código:

int delta = DayOfWeek.Monday - DateTime.Now.DayOfWeek;
DateTime monday = DateTime.Now.AddDays(delta == 1 ? -6 : delta);
return monday;
Threezool
fonte
Parece que o problema da 'próxima segunda-feira' depende da cultura (consulte também a resposta de Eric e o comentário do Cerveser.) No entanto, se você não precisar levar em consideração os domingos (como em reuniões comerciais normais), sua fórmula pode simplificado:dt.AddDays(DayOfWeek.Monday - dt.DayOfWeek);
Damian Vogel
2

Etapa 1: criar uma classe estática

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

Etapa 2: use esta classe para obter o dia da semana de início e de término

 DateTime dt =TIMEE.StartOfWeek(DateTime.Now ,DayOfWeek.Monday);
        DateTime dt1 = TIMEE.EndOfWeek(DateTime.Now, DayOfWeek.Sunday);
Muhammad Abbas
fonte
Fim de semana necessário (6 - (dt.DayOfWeek - startOfWeek)) % 7para mim contra os testes de unidade que escrevi.
mlhDev
1

O método a seguir deve retornar o DateTime que você deseja. Passe verdadeiro para domingo, sendo o primeiro dia da semana, falso para segunda-feira:

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);
}
firedfly
fonte
1

Obrigado pelos exemplos. Eu precisava sempre usar o "CurrentCulture" no primeiro dia da semana e, para uma matriz, eu precisava saber o número do dia exato. Então, aqui estão minhas primeiras extensões:

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
    }
}
user324365
fonte
1

Parece que ninguém respondeu isso corretamente ainda. Vou colar minha solução aqui, caso alguém precise. O código a seguir funciona independentemente se o primeiro dia da semana for uma segunda-feira ou domingo ou outra coisa.

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());
  }
}
Andreas Kromann
fonte
1

O módulo em C # funciona mal para -1mod7 (deve ser 6, c # retorna -1), então ... a solução "oneliner" para isso ficará assim :)

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

O mesmo para o final de semana (no estilo da resposta do @Compile Isto):

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

Você pode usar a excelente biblioteca Umbrella :

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

No entanto, eles não parecem ter armazenado segunda-feira como o primeiro dia da semana (veja a propriedade nVentive.Umbrella.Extensions.Calendar.DefaultDateTimeCalendarExtensions.WeekBeginsOn), para que a solução localizada anterior é um pouco melhor. Infeliz.

Edit : olhando mais de perto a questão, parece que a Umbrella também pode funcionar para isso:

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

Embora valha a pena notar que, se você pedir a segunda-feira anterior em uma segunda-feira, isso lhe dará sete dias de volta. Mas isso também é verdade se você usar BeginningOfWeek, o que parece um bug :(.

Domenic
fonte
0

Isso retornará as datas do início da semana e do final da semana:

    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;

    }

Publiquei o código completo para calcular o início / fim de semana, mês, trimestre e ano no meu blog ZamirsBlog

Zamir
fonte
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();
            }
        }
    } 
Denis
fonte
Você pode expandir sua resposta para incluir uma explicação do seu código? Ajuda o leitor mais do que você imagina.
gunr2171
Usar recursão é uma implementação muito ruim. Só porque você poderia usar recursões não significa que deveria. Seria mais lento e consumiria mais memória do que outras soluções fornecidas aqui.
Mikecamimo
0

Aqui está uma combinação de algumas das respostas. Ele usa um método de extensão que permite que a cultura seja transmitida, se não for transmitida, a cultura atual é usada. Isso lhe dará flexibilidade e reutilização máximas.

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

Exemplo de uso:

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()}");
        }
    }
Mike
fonte
0

se você quiser sábado ou domingo ou qualquer dia da semana, mas não exceder a semana atual (sábado a domingo), cobri-o com este código.

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;
}
Ali Umair
fonte
0

Gostamos de uma linha: obtenha a diferença entre o primeiro dia da semana da cultura atual e o dia atual e subtraia o número de dias do dia atual

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

Na sequência de Compilar esta 'resposta, use o seguinte método para obter a data para qualquer dia da semana:

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;
}
Rowan Richards
fonte
0

Tente criar uma função que use recursão. Seu objeto DateTime é uma entrada e a função retorna um novo objeto DateTime, que representa o início da semana.

    DateTime WeekBeginning(DateTime input)
    {
        do
        {
            if (input.DayOfWeek.ToString() == "Monday")
                return input;
            else
                return WeekBeginning(input.AddDays(-1));
        } while (input.DayOfWeek.ToString() == "Monday");
    }
mihauuuu
fonte
Embora esse código possa resolver a questão, incluir uma explicação de como e por que isso resolve o problema realmente ajudaria a melhorar a qualidade da sua postagem e provavelmente resultaria em mais votos positivos. Lembre-se de que você está respondendo à pergunta dos leitores no futuro, não apenas à pessoa que está perguntando agora. Por favor edite sua resposta para adicionar explicações e dar uma indicação do que limitações e premissas se aplicam.
David Buck
0

O cálculo dessa maneira permite escolher qual dia da semana indica o início de uma nova semana (no exemplo que escolhi segunda-feira).

Observe que fazer esse cálculo para um dia que seja segunda-feira fornecerá a segunda-feira atual e não a anterior.

//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);
C. Keats
fonte