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

Como faço para encontrar o início da semana (domingo e segunda-feira), sabendo apenas a hora atual em C #?

Algo como:

DateTime.Now.StartWeek(Monday); 

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

Qual pode ser usado como segue:

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

Um pouco mais detalhado e sensível à 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; 

A maneira mais rápida que eu posso chegar é:

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

Se você quiser 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); 

Usando o DateTime Fluente :

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

Feio, mas pelo menos dá as datas certas de volta

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

Vamos combinar a resposta segura para 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)); } } 

Isso pode ser um pouco de um hack, mas você pode converter a propriedade .DayOfWeek para um int (é um enum e como seu tipo de dados subjacente não foi alterado, o padrão é int) e usá-lo para determinar o início da semana anterior .

Parece que a semana especificada no enum da DayOfWeek começa no domingo, por isso, se subtrairmos 1 deste valor, será igual a quantos dias a segunda-feira é anterior à data atual. Também precisamos mapear o domingo (0) para igual a 7, de forma que 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, já que não precisamos fazer esse ajuste:

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

Isso lhe daria o domingo anterior (eu acho):

 DateTime t = DateTime.Now; t -= new TimeSpan ((int) t.DayOfWeek, 0, 0, 0); 
 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(); } } } 

Juntando tudo, com a Globalização e permitindo a especificação do primeiro dia da semana como parte da chamada que temos

 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 now = System.DateTime.Now; var result = now.AddDays(-((now.DayOfWeek - System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat.FirstDayOfWeek + 7) % 7)).Date; 

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

Isto dá-lhe a primeira segunda-feira à meia-noite:

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

Tentei vários, mas não resolvi o problema com uma semana a partir de uma segunda-feira, resultando em me dando a próxima segunda-feira em um domingo. Então modifiquei um pouco e consegui trabalhar com esse código:

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

O método a seguir deve retornar o DateTime que você deseja. Passe em true para o domingo sendo o primeiro dia da semana, false 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); } 

Obrigado pelos exemplos. Eu precisava sempre usar o primeiro dia da semana “CurrentCulture” e para uma matriz eu precisava saber o número exato do dia .. 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 } } 

tente com isso em c # .Com este código você pode obter a primeira data e última data de uma determinada semana.Aqui domingo é o primeiro dia e sábado é o último dia, mas você pode definir ambos os 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; } 

Ninguém parece ter respondido isso corretamente ainda. Vou colar minha solução aqui, caso alguém precise dela. O código a seguir funciona independentemente de o primeiro dia da semana ser uma segunda-feira ou um domingo ou qualquer 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()); } } 

Módulo em C # funciona mal para -1mod7 (deve ser 6, c # retorna -1) assim … “oneliner” solução para isso vai 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)); } 

Você poderia usar a excelente biblioteca da Umbrella :

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

No entanto, eles 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 seja um pouco melhor. Infeliz.

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

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

Embora seja importante notar que, se você pedir a segunda-feira anterior em uma segunda-feira, haverá sete dias de volta. Mas isso também é verdade se você usar BeginningOfWeek , que parece um erro :(.

Isso retornará o início da semana e o final das datas 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; } 

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

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

O mesmo para o fim de semana (em estilo de @Compile Esta é a resposta):

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

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

 ///  /// Gets the date of the first day of the week for the date. ///  /// The date to be used /// If none is provided, the current culture is used /// The date of the beggining of the week based on the culture specifed 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()}"); } } 

Se você quiser sábado ou domingo ou qualquer dia da semana, mas não exceder a semana atual (sábado e domingo), eu cobri este trecho de 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; } 
  d = DateTime.Now; int dayofweek =(int) d.DayOfWeek; if (dayofweek != 0) { d = d.AddDays(1 - dayofweek); } else { d = d.AddDays(-6); } 
 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; }