2010-01-25 32 views
33

¿Las bibliotecas .NET tienen una manera 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 salida a 5 para el número de semana.Calcula la semana del mes en .NET

Lo más parecido 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.

Respuesta

49

No hay está construido en forma de hacerlo, pero aquí es un método de extensión que debe hacer el trabajo para 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.

4

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

puede utilizar:

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

Nota pensó 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".

+0

Esto es incorrecto; devuelve '-48' para' dt = new DateTime (2010, 1, 25) '. – jason

+0

@ Jason Buena captura. El problema fue con el primer día de enero perteneciente a la última semana de diciembre. Se corrigió el código para ignorar eso. – GaussZ

18

No hay una forma integrada directa de hacerlo, pero se puede hacer con bastante facilidad. Aquí es un método de extensión que se puede utilizar para obtener fácilmente el número de semana a base de 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 utilizar eso para calcular el número de la semana basada en el mes, algo así como Jason shows. Una versión para la cultura podría ser algo como esto:

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. 
} 
+0

+ 1 para cultura amigable – eddiegroves

+0

@eddiegroves: Gracias. Al menos alguien lo aprecia: p – Svish

0

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

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 utilizar 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. Versión

0
public int WeekCalc(DateTime dt) 
{ 
    CultureInfo ciCurr = CultureInfo.CurrentCulture; 
    int weekNum = ciCurr.Calendar.GetWeekOfYear(dt, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday); 
    return weekNum; 
} 
2

@Svish

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 
0

vez que tenga el DayOfWeek del primer día del mes, usted puede conseguir la semana del mes, utilizando 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; 
    } 
} 
0

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

El título es engañoso. La pregunta es realmente acerca del número de la semana del 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 utilizar:

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

Estoy de acuerdo en que el título es engañoso. Estaba intentando calcular, por ejemplo, el cuarto lunes del mes. Sin embargo, cuando escribí mis pruebas unitarias usando otras respuestas provistas en esta pregunta, algunos de los resultados no coincidían con lo que esperaba. Esto se debe a que si el primer día del mes es el martes o más tarde en la semana, los resultados están desactivados por una semana. El código proporcionado por esta respuesta es lo que terminé usando para resolver el problema. – user3308241

+1

Esto no se alinea con el ejemplo. El 1 de enero de 2010 fue el viernes, por lo que la primera semana del calendario tuvo solo dos días. Como resultado, el día 25, que normalmente caería en la semana 4 usando esta fórmula, en realidad está en la semana 5. Dado que el ejemplo dice que el 1 de enero de 2010 debe producir la semana 5, la fórmula en esta respuesta no puede ser correcta, porque produce semana 4 (es decir, (int ((25 - 1)/7) + 1) = 4. – Triynko

2

Ésta 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"; 
     } 
    } 
+0

¿Sabes que es posible de 6 semanas al mes? –

1

Aquí es una opción sencilla si desea que los primeros 7 días para tener en cuenta la primera semana, aunque el mes no se inicia en un 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; 
    } 
} 
0
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) 
Cuestiones relacionadas