Calcula la semana del mes en .NET

¿Las bibliotecas .NET tienen una forma fácil de devolver el número de semana para una fecha determinada? Por ejemplo, la entrada de Year = 2010, Month = 1, Day = 25 , debe dar como resultado 5 para el número de semana.

Lo más cerca que encontré fue Calendar.GetWeekOfYear , que está casi allí.

Java tiene un formato de cadena de fecha “W” que devuelve semana tras mes, pero no puedo ver nada equivalente en .NET.

No hay una forma integrada de hacerlo, pero aquí hay un método de extensión que debería hacer el trabajo por usted:

 static class DateTimeExtensions { static GregorianCalendar _gc = new GregorianCalendar(); public static int GetWeekOfMonth(this DateTime time) { DateTime first = new DateTime(time.Year, time.Month, 1); return time.GetWeekOfYear() - first.GetWeekOfYear() + 1; } static int GetWeekOfYear(this DateTime time) { return _gc.GetWeekOfYear(time, CalendarWeekRule.FirstDay, DayOfWeek.Sunday); } } 

Uso:

 DateTime time = new DateTime(2010, 1, 25); Console.WriteLine(time.GetWeekOfMonth()); 

Salida:

 5 

Puede modificar GetWeekOfYear según sus necesidades.

No hay una forma directa incorporada de hacer esto, pero se puede hacer con bastante facilidad. Aquí hay un método de extensión que se puede usar para obtener fácilmente el número de la semana basada en el año de una fecha:

 public static int GetWeekNumber(this DateTime date) { return GetWeekNumber(date, CultureInfo.CurrentCulture); } public static int GetWeekNumber(this DateTime date, CultureInfo culture) { return culture.Calendar.GetWeekOfYear(date, culture.DateTimeFormat.CalendarWeekRule, culture.DateTimeFormat.FirstDayOfWeek); } 

Entonces podemos usar eso para calcular el número de semana basado en el mes, como muestra Jason . Una versión amigable para la cultura podría verse más o menos así:

 public static int GetWeekNumberOfMonth(this DateTime date) { return GetWeekNumberOfMonth(date, CultureInfo.CurrentCulture); } public static int GetWeekNumberOfMonth(this DateTime date, CultureInfo culture) { return date.GetWeekNumber(culture) - new DateTime(date.Year, date.Month, 1).GetWeekNumber(culture) + 1; // Or skip +1 if you want the first week to be 0. } 

El título es engañoso. La pregunta es realmente sobre el número de la semana calendario (el número de la semana si contó las filas en un calendario) del mes, no el número de la semana real.

Para el número de semana del mes, puede usar:

 VB: Function WeekNumber(TargetDate As Date) As Integer Return (TargetDate.Day - 1) \ 7 + 1 End Function C#: public int WeekNumber(DateTime TargetDate) { return (TargetDate.Day - 1) / 7 + 1; } 

Como se especifica aquí: http://forums.asp.net/t/1268112.aspx

puedes usar:

 public static int Iso8601WeekNumber(DateTime dt) { return CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(dt, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday); } public static int GetWeekOfMonth(DateTime dt) { int weekOfYear = Iso8601WeekNumber(dt); if (dt.Month == 1) { //week of year == week of month in January //this also fixes the overflowing last December week return weekOfYear; } int weekOfYearAtFirst = Iso8601WeekNumber(dt.AddDays(1 - dt.Day)); return weekOfYear - weekOfYearAtFirst + 1; } 

Tenga en cuenta que sus necesidades pueden variar ya que hay ciertas opciones algorítmicas. Es decir, es una semana de lunes a viernes a fines de febrero, también la primera semana de marzo, o ¿qué criterios definen la “primera” semana de un mes? ISO 8601: 2004 no da una definición para “Semana del mes”.

@Svish

Versión VB:

 Public Shared Function GetWeekNumber(ByVal [date] As DateTime) As Integer Return GetWeekNumber([date], CultureInfo.CurrentCulture) End Function Public Shared Function GetWeekNumber(ByVal [date] As DateTime, ByVal culture As CultureInfo) As Integer Return culture.Calendar.GetWeekOfYear([date], culture.DateTimeFormat.CalendarWeekRule, culture.DateTimeFormat.FirstDayOfWeek) End Function Public Shared Function GetWeekNumberOfMonth(ByVal [date] As DateTime) As Integer Return GetWeekNumberOfMonth([date], CultureInfo.CurrentCulture) End Function Public Shared Function GetWeekNumberOfMonth(ByVal [date] As DateTime, ByVal culture As CultureInfo) As Integer Return GetWeekNumber([date], culture) - GetWeekNumber(New DateTime([date].Year, [date].Month, 1), culture) + 1 ' Or skip +1 if you want the first week to be 0. End Function 

Esta es mi solución:

  static string GetWeekNumber() { var weekNumber = CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(DateTime.Now, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Sunday) - CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(DateTime.Now.AddDays(1 - DateTime.Now.Day), CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Sunday) + 1; switch (weekNumber) { case 1 : return "First"; case 2: return "Second"; case 3: return "Third"; default: return "Fourth"; } } 

Esta es una opción simple si desea que los primeros 7 días se consideren la primera semana, incluso si el mes no comienza el domingo:

 class Program { static void Main(string[] args) { var dates = Enumerable.Range(0, 10) .Select(r => new DateTime(2015, 10, 1).AddDays(r)) .Select(q => new { Date = q, WeekOfMonth = q.WeekOfMonth() }); foreach(var item in dates) { Console.WriteLine("Date: {0:ddd MM-dd-yyyy}, WOM: {1}", item.Date, item.WeekOfMonth); } var final = Console.ReadLine(); } } public static class DateTimeExtensions { public static int WeekOfMonth(this DateTime d) { var isExact = (d.Day % 7 == 0); var offset = isExact ? 0 : 1; return (int)Math.Floor(d.Day / 7.0) + offset; } } 
 public int WeekCalc(DateTime dt) { CultureInfo ciCurr = CultureInfo.CurrentCulture; int weekNum = ciCurr.Calendar.GetWeekOfYear(dt, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday); return weekNum; } 

Este es un hilo viejo, pero necesitaba algo como esto y esto es lo que se me ocurre.

 public static int WeekOfMonth(this DateTime date) { DateTime firstDayOfMonth = new DateTime(date.Year, date.Month, 1); int firstDay = (int)firstDayOfMonth.DayOfWeek; if (firstDay == 0) { firstDay = 7; } double d = (firstDay + date.Day - 1) / 7.0; return (int)Math.Ceiling(d); } 

Nota: Esto debería funcionar si desea usar el lunes como el primer día de la semana. Si desea que la semana comience el domingo, esto falla en la segunda semana de marzo de 2015 y probablemente en otras fechas. El lunes 9 de marzo de 2015 es el primer día de la segunda semana. El cálculo anterior arroja “3” para esta fecha.

Una vez que tenga el DayOfWeek del primer día del mes, puede obtener la semana del mes usando la aritmética de enteros.

 static class DateTimeExtensions { // Assumes that in current culture week starts on Sunday public static int GetWeekOfMonth(this DateTimeOffset time) { DateTimeOffset first = new DateTimeOffset(time.Year, time.Month, 1, 0, 0, 0, time.Offset); int firstSunday = (7 - (int)first.DayOfWeek) % 7 + 1; int weekOfMonth = 1 + (time.Day + 7 - firstSunday) / 7; return weekOfMonth; } } 

Algo simple … 🙂

 private int WeeksNumber() { int daysInMonth = DateTime.DaysInMonth(YourYear, YourMonth); DateTime date = new DateTime(Year, Month, 1); switch (daysInMonth) { case 28: { if (date.DayOfWeek == DayOfWeek.Monday) { return 4; } else { return 5; } } case 29: { return 5; } case 30: { if (date.DayOfWeek == DayOfWeek.Sunday) { return 6; } else { return 5; } } case 31: { if (date.DayOfWeek == DayOfWeek.Sunday || date.DayOfWeek == DayOfWeek.Saturday) { return 6; } else { return 5; } } default: return 5; } } 
  Dim mdt As Date = txtDT.Text Dim weekNum As Integer = CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(mdt, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Sunday) - CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(GetFirstDayOfMonth(mdt), CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Sunday) + 1 Response.Write(weekNum)