2010-10-04 25 views
9

Voglio creare una funzione in C# che per un numero di settimana mi restituirà i giorni, in quella settimana.In .net, conoscendo il numero della settimana come posso ottenere la data dei giorni feriali?

Ad esempio per il numero della settimana 40, come posso ottenere i giorni: 4/10, 5/10, 6/10, 7/10, 8/10, 9/10, 10/10.

Grazie in anticipo!

+0

possibile duplicato del [Calcola data dal numero della settimana] (http://stackoverflow.com/questions/662379/calculate-date-from-week-number) – andreiursan

risposta

8

penso che questo dovrebbe fare quello che vuoi:

public static DateTime[] WeekDays(int Year, int WeekNumber) 
    { 
     DateTime start = new DateTime(Year, 1, 1).AddDays(7 * WeekNumber); 
     start = start.AddDays(-((int)start.DayOfWeek)); 
     return Enumerable.Range(0, 7).Select(num => start.AddDays(num)).ToArray(); 
    } 

Anche se mi trattano Domenica come primo giorno della settimana, se si vuole Lunedi come primo campo di cambiamento giorno da (0,7) a (1,7).

Se si vuole essere conforme allo standard ISO, credo che questo dovrebbe funzionare:

public static DateTime[] WeekDays(int Year, int WeekNumber) 
    { 
     DateTime start = new DateTime(Year, 1, 4); 
     start = start.AddDays(-((int)start.DayOfWeek)); 
     start = start.AddDays(7 * (WeekNumber - 1)); 
     return Enumerable.Range(0, 7).Select(num => start.AddDays(num)).ToArray(); 
    } 
+1

Questo dipende fondamentalmente da dove ti trovi nel mondo, perché in Europa la settimana 1 è la prima settimana con 4 giorni, mentre negli Stati Uniti è la settimana con 1/1 (http: //en.wikipedia.org/wiki/Seven-day_week#Week_numbering) - quindi il codice è corretto tranne che la "base" potrebbe dover essere modificata. – veggerby

+2

Per quanto mi ricordo da un progetto precedente, il codice sopra non funzionerà quando si calcola con ISO-Weeks (8601 quello che viene usato spesso in Europa) anche se la base verrà regolata (vedi la mia risposta). Ma forse questo è cambiato con .net4. – HCL

+0

Sì, sei corretto non segue lo standard ISO. Potrebbe essere regolato abbastanza facilmente per adattarsi allo standard. Inserirò e correggerò. – JDunkerley

1

Nota

mi sembra di aver perso bug. Il codice attuale è stato aggiornato dal 2012-01-30 per tenere conto di questo fatto e ora deriviamo il daysOffset basato su Martedì che, secondo lo Mikael Svenson, sembra risolvere il problema. Vedi questo answer per i dettagli.

La maggior parte delle persone tende a sbagliare e, per errore, non è conforme allo standard ISO8601 (lo usiamo molto in Svezia). Questo calcolo è un po 'strano, ma tutto si riduce a questo codice in .NET:

DateTime jan1 = new DateTime(yyyy, 1, 1); 

int daysOffset = DayOfWeek.Tuesday - jan1.DayOfWeek; 

DateTime firstMonday = jan1.AddDays(daysOffset); 

var cal = CultureInfo.CurrentCulture.Calendar; 

int firstWeek = cal.GetWeekOfYear(jan1, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday); 

var weekNum = ww; 

if (firstWeek <= 1) 
{ 
    weekNum -= 1; 
} 

var result = firstMonday.AddDays(weekNum * 7 + d - 1); 

return result; 

Sarà calcolare la data di un anno (aaaa), numero della settimana (WW) e giorno della settimana (d). Lo fa prima stabilendo il primo di gennaio usando il calendario integrato (quindi questo codice può essere personalizzato). Il motivo per cui questo è un po 'strano è perché la settimana 53 a volte si verifica a gennaio e talvolta la settimana 1 si verifica a dicembre.

Se hai bisogno di andare oltre, non è del tutto banale ma il modo corretto di farlo in .NET è mostrato qui.

var c = CultureInfo.CurrentCulture.Calendar; 

// `FromDayOfWeek` fixes problem with the enumeration 
// not based on Monday being the first day of the week 
d = (byte)FromDayOfWeek(c.GetDayOfWeek(t)); 
switch (d) 
{ 
    case 1: 
    case 2: 
    case 3: 
     // see this for details 
     // http://blogs.msdn.com/shawnste/archive/2006/01/24/iso-8601-week-of-year-format-in-microsoft-net.aspx 
     t = t.AddDays(3); 
     break; 
} 

ww = (byte)c.GetWeekOfYear(t, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday); 

// Adjust year when week 53 occurs in January or week 1 occurs in December 
if (ww == 53 && t.Month == 1) 
{ 
    yyyy = (short)(t.Year - 1); 
} 
else if (ww == 1 && t.Month == 12) 
{ 
    yyyy = (short)(t.Year + 1); 
} 
else 
{ 
    yyyy = (short)t.Year; 
} 
1

La seguente funzione vi aiuterà a ottenere data dal numero della settimana e anno di inizio

public DateTime GetFirstDayFromWeekNumber(int weekNumber, int weekYear) 
     { 
      DateTime beginingYear = new DateTime(weekYear, 1, 1); 
      DateTime finalDate = new DateTime(); 
      int maxDayOfWeek = (int)DayOfWeek.Saturday; 
      int yearStartDay = (int)beginingYear.DayOfWeek; 
      int dayDeference = maxDayOfWeek - yearStartDay; 

      if (weekNumber == 1) 
      { 
       finalDate = beginingYear.AddDays(-yearStartDay); 
      } 
      else if (weekNumber == 2) 
      { 
       finalDate = beginingYear.AddDays((dayDeference + 1)); 
      } 
      else if (weekNumber > 2 && weekNumber <= 53) 
      { 
       finalDate = beginingYear.AddDays((dayDeference + 1) + ((weekNumber - 2)* 7)); 
      } 
      return finalDate; 
     }