2010-01-25 13 views
33

Le librerie .NET hanno un modo semplice per restituire il numero della settimana per una data specifica? Ad esempio, l'input di Year = 2010, Month = 1, Day = 25 deve produrre 5 per il numero della settimana.Calcolare la settimana del mese in .NET

Il più vicino che ho trovato era Calendar.GetWeekOfYear, che è quasi arrivato.

Java ha un formato di stringa di data "W" che restituisce la settimana del mese ma non riesco a vedere nulla di equivalente in .NET.

risposta

49

ci nessun è costruito in modo per fare questo, ma qui è un metodo di estensione che dovrebbe fare il lavoro per voi:

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

Usage:

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

uscita:

5 

È possibile modificare GetWeekOfYear in base alle proprie esigenze.

4

Come specificato qui: http://forums.asp.net/t/1268112.aspx

è possibile utilizzare:

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 pensato che le vostre esigenze possono variare in quanto vi sono alcune scelte algoritmiche. Cioè è una settimana con lunedì-venerdì a fine febbraio anche la prima settimana di marzo, o quali criteri definisce la "prima" settimana di un mese? ISO 8601: 2004 non fornisce una definizione per "Settimana del mese".

+0

Questo non è corretto; restituisce '-48' per' dt = new DateTime (2010, 1, 25) '. – jason

+0

@Jason Buona cattura. Il problema era il primo giorno di gennaio che apparteneva all'ultima settimana di dicembre. Risolto il problema per ignorarlo. – GaussZ

18

Non esiste un modo incorporato diretto per eseguire questa operazione, ma può essere fatto abbastanza facilmente. Qui è un metodo di estensione che può essere usato per ottenere facilmente il numero della settimana a base di anno di una data:

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

Possiamo quindi utilizzare tale per calcolare il numero Mese-based, un po 'come Jason shows. Una versione cultura amichevole potrebbe somigliare a questo:

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 per cultura amichevole – eddiegroves

+0

@eddiegroves: Grazie. Almeno qualcuno lo apprezza: p – Svish

0

questo è un vecchio thread, ma avevo bisogno di qualcosa di simile, e questo è quello che mi viene in mente.

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: questo dovrebbe funzionare se si desidera utilizzare lunedì come primo giorno della settimana. Se vuoi che la settimana inizi la domenica, fallisce nella seconda settimana di marzo 2015 e probabilmente in altre date. Lunedì 9 marzo 2015 è il primo giorno della seconda settimana. Il calcolo sopra restituisce "3" per questa data. Versione

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

volta che hai la DayOfWeek del primo giorno del mese, è possibile ottenere la settimana del mese con aritmetica intera.

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

Qualcosa di semplice ...:)

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

Il titolo è fuorviante. La domanda riguarda davvero il numero della settimana di calendario (il numero della settimana se contate le righe su un calendario) del mese, non il numero della settimana reale.

Per il numero della settimana del mese, è possibile utilizzare:

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

Concordo sul fatto che il titolo sia fuorviante. Stavo cercando di calcolare, per esempio, il quarto lunedì del mese. Tuttavia, quando ho scritto i miei test unitari usando altre risposte fornite sotto questa domanda, alcuni risultati non corrispondevano a quello che mi aspettavo. Questo perché se il primo giorno del mese è martedì o più tardi nella settimana, i risultati sono scaduti di una settimana. Il codice fornito da questa risposta è quello che ho usato per risolvere il problema. – user3308241

+1

Questo non è allineato con l'esempio. Il 1 gennaio 2010 era venerdì, quindi la prima settimana di calendario aveva solo due giorni. Di conseguenza, il 25, che normalmente scenderà sotto la settimana 4 utilizzando questa formula, è in realtà la settimana 5. Poiché l'esempio dice che il 1 ° gennaio 2010 dovrebbe produrre la settimana 5, la formula in questa risposta non può essere giusta, perché produce settimana 4 (cioè (int ((25 - 1)/7) + 1) = 4. – Triynko

2

Questa è la mia soluzione:

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

Sai che è possibile di 6 settimane al mese? –

1

Ecco una semplice opzione se si desidera che i primi 7 giorni di tempo per essere considerato il prima settimana, anche se il mese non inizia di Domenica:

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) 
Problemi correlati