¿Cómo puedo obtener el DateTime para el comienzo de la semana?

¿Cómo puedo saber el comienzo de la semana (tanto el domingo como el lunes) sabiendo exactamente la hora actual en C #?

Algo como:

DateTime.Now.StartWeek(Monday); 

Use un método de extensión. Ellos son la respuesta a todo, ¿sabes? 😉

 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 se puede usar de la siguiente manera:

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

Un poco más detallado y consciente de la 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; 

La manera más rápida que se me ocurre es:

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

Si desea que cualquier otro día de la semana sea su fecha de inicio, todo lo que necesita hacer es agregar el valor de DayOfWeek al 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 Fluent DateTime :

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

Feo, pero al menos da las fechas correctas de vuelta

Con el inicio de la semana establecido por el sistema:

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

Sin:

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

Combinamos la respuesta de cultivo seguro y la respuesta del método de extensión:

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

Esto puede ser algo así como un hack, pero puedes convertir la propiedad .DayOfWeek en una int (es una enumeración y dado que no tiene su tipo de datos subyacente cambiado, por defecto es int) y usar eso para determinar el inicio previo de la semana .

Parece que la semana especificada en la enumeración DayOfWeek comienza el domingo, por lo que si restamos 1 de este valor será igual a cuántos días el lunes es anterior a la fecha actual. También tenemos que asignar el domingo (0) a 7, por lo tanto, dado 1 – 7 = -6, el domingo se asignará al lunes anterior: –

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

El código del domingo anterior es más simple ya que no tenemos que hacer este ajuste:

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

Esto te daría el domingo anterior (creo):

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

Poniéndolo todo junto, con Globalización y permitiendo especificar el primer día de la semana como parte de la llamada que tenemos

 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; 

Esto le daría la medianoche del primer domingo de la semana:

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

Esto te da el primer lunes a la medianoche:

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

Intenté varios pero no resolví el problema con una semana que comenzó el lunes, lo que resultó en darme el próximo lunes un domingo. Así que lo modifiqué un poco y lo hice funcionar con este código:

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

El siguiente método debe devolver el DateTime que desee. Pase en true para que el domingo sea el primer día de la semana, falso para el lunes:

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

Gracias por los ejemplos. Necesitaba usar siempre el primer día de la semana “CurrentCulture” y para obtener una matriz, necesitaba saber el número de día exacto, así que aquí están mis primeras extensiones:

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

intente con esto en c #. Con este código, puede obtener la primera fecha y la última fecha de una semana determinada. Aquí el domingo es el primer día y el sábado es el último día, pero puede establecer los dos días según su 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; } 

Nadie parece haber respondido esto correctamente todavía. Pegaré mi solución aquí en caso de que alguien la necesite. El siguiente código funciona independientemente de si el primer día de la semana es un lunes o un domingo u otra cosa.

 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 en C # funciona mal para -1mod7 (debería ser 6, c # devuelve -1) así que … la solución “oneliner” se verá así 🙂

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

Puede usar la excelente biblioteca de Umbrella :

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

Sin embargo, parecen haber almacenado el lunes como el primer día de la semana (ver la propiedad nVentive.Umbrella.Extensions.Calendar.DefaultDateTimeCalendarExtensions.WeekBeginsOn ), por lo que la solución localizada anterior es un poco mejor. Desgraciado.

Editar : mirando más de cerca la pregunta, parece que Umbrella también podría funcionar para eso:

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

Aunque vale la pena señalar que si solicita el lunes anterior un lunes, le dará un plazo de siete días. Pero esto también es cierto si usa BeginningOfWeek , que parece un error :(.

Esto devolverá el comienzo de la semana y las fechas de fin de 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; } 

He publicado el código completo para calcular el comienzo / final de semana, mes, trimestre y año en mi 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(); } } } 

Lo mismo para el final de la semana (en el estilo de @Compile Esta es la respuesta):

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

Aquí hay una combinación de algunas de las respuestas. Utiliza un método de extensión que permite pasar la cultura, si no se pasa, se utiliza la cultura actual. Esto le dará máxima flexibilidad y reutilización.

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

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

si quieres sábado o domingo o cualquier día de la semana pero no excede la semana actual (sábados y domingos), te cubrí con esta pieza 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; }