2009-09-30 17 views

Antwort

72
var currentCulture = CultureInfo.CurrentCulture; 
var weekNo = currentCulture.Calendar.GetWeekOfYear(
       new DateTime(2013, 12, 31), 
       currentCulture.DateTimeFormat.CalendarWeekRule, 
       currentCulture.DateTimeFormat.FirstDayOfWeek); 

Seien Sie sich bewusst, dass diese nichtISO 8601 kompatibel ist. In Schweden nutzen wir ISO 8601 week Zahlen aber auch wenn die Kultur „sv-SE“ gesetzt ist, CalendarWeekRuleFirstFourDayWeek ist, und FirstDayOfWeek Montag die weekNo Variable wird auf statt der korrekten in eingestellt werden der obige Code.

Ich habe dies nur mit schwedischen Einstellungen versucht, aber ich bin mir ziemlich sicher, dass alle Länder (Österreich, Deutschland, Schweiz und mehr), die ISO 8601 Wochennummern verwenden, von diesem Problem betroffen sein werden.

Peter van Ooijen und Shawn Steele hat verschiedene Lösungen für dieses Problem.

Hier ist eine kompakte Lösung

private static int WeekOfYearISO8601(DateTime date) 
{ 
    var day = (int)CultureInfo.CurrentCulture.Calendar.GetDayOfWeek(date); 
    return CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(date.AddDays(4 - (day == 0 ? 7 : day)), CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday); 
} 

Es ist für die folgenden Termine

getestet worden ist
var datesAndISO8601Weeks = new Dictionary<DateTime, int> 
         { 
          {new DateTime(2000, 12, 31), 52}, 
          {new DateTime(2001, 1, 1), 1}, 
          {new DateTime(2005, 1, 1), 53}, 
          {new DateTime(2007, 12, 31), 1}, 
          {new DateTime(2008, 12, 29), 1}, 
          {new DateTime(2010, 1, 3), 53}, 
          {new DateTime(2011, 12, 31), 52}, 
          {new DateTime(2012, 1, 1), 52}, 
          {new DateTime(2013, 1, 2), 1}, 
          {new DateTime(2013, 12, 31), 1}, 
         }; 

foreach (var dateWeek in datesAndISO8601Weeks) 
{ 
    Debug.Assert(WeekOfYearISO8601(dateWeek.Key) == dateWeek.Value, dateWeek.Key.ToShortDateString() + " should be week number " + dateWeek.Value + " but was " + WeekOfYearISO8601(dateWeek.Key)); 
} 
+1

Sehr nette Antwort. Danke – roosteronacid

+0

Das gleiche Problem mit dem Rest von Skandinavien Ich denke, ich bin Dänisch und ich fragte mich, warum meine Tests zeigten 31/12 Woche # 53 zu sein, wie mein Google Kalender sagt seine Woche # 1. – BerggreenDK

+0

warum überall "var" verwenden? – AndreaCi

1
My.Computer.Info.InstalledUICulture.DateTimeFormat.Calendar.GetWeekOfYear(yourDateHere, CalendarWeekRule.FirstDay, My.Computer.Info.InstalledUICulture.DateTimeFormat.FirstDayOfWeek) 

So etwas ...

4
public static int GetWeekNumber(DateTime dtPassed) 
    { 
      CultureInfo ciCurr = CultureInfo.CurrentCulture; 
      int weekNum = ciCurr.Calendar.GetWeekOfYear(dtPassed, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday); 
      return weekNum; 
    } 
4

Check out GetWeekOfYear auf MSDN hat dieses Beispiel:

using System; 
using System.Globalization; 


public class SamplesCalendar { 

    public static void Main() { 

     // Gets the Calendar instance associated with a CultureInfo. 
     CultureInfo myCI = new CultureInfo("en-US"); 
     Calendar myCal = myCI.Calendar; 

     // Gets the DTFI properties required by GetWeekOfYear. 
     CalendarWeekRule myCWR = myCI.DateTimeFormat.CalendarWeekRule; 
     DayOfWeek myFirstDOW = myCI.DateTimeFormat.FirstDayOfWeek; 

     // Displays the number of the current week relative to the beginning of the year. 
     Console.WriteLine("The CalendarWeekRule used for the en-US culture is {0}.", myCWR); 
     Console.WriteLine("The FirstDayOfWeek used for the en-US culture is {0}.", myFirstDOW); 
     Console.WriteLine("Therefore, the current week is Week {0} of the current year.", myCal.GetWeekOfYear(DateTime.Now, myCWR, myFirstDOW)); 

     // Displays the total number of weeks in the current year. 
     DateTime LastDay = new System.DateTime(DateTime.Now.Year, 12, 31); 
     Console.WriteLine("There are {0} weeks in the current year ({1}).", myCal.GetWeekOfYear(LastDay, myCWR, myFirstDOW), LastDay.Year); 

    } 

} 
1

Ich weiß, das spät ist, aber da es in meiner Suche kam ich dachte, dass ich einen anderen werfen würde Lösung in. Dies war eine aC# -Lösung.

(int)(Math.Ceiling((decimal)startDate.Day/7)) + (((new DateTime(startDate.Year, startDate.Month, 1).DayOfWeek) > startDate.DayOfWeek) ? 1 : 0);   
+0

Dies gibt "5" für das Datum 29/12/2016 zurück - es sollte 52 zurückgeben – DNKROZ

0

var cultureInfo = CultureInfo.CurrentCulture; var Kalender = cultInfo.Calendar;

 var calendarWeekRule = cultureInfo.DateTimeFormat.CalendarWeekRule; 
     var firstDayOfWeek = cultureInfo.DateTimeFormat.FirstDayOfWeek; 
     var lastDayOfWeek = cultureInfo.LCID == 1033 //En-us 
      ? DayOfWeek.Saturday 
      : DayOfWeek.Sunday; 

     var lastDayOfYear = new DateTime(date.Year, 12, 31); 

     //Check if this is the last week in the year and it doesn`t occupy the whole week 
     var weekNumber = calendar.GetWeekOfYear(date, calendarWeekRule, firstDayOfWeek); 
     return weekNumber == 53 && lastDayOfYear.DayOfWeek != lastDayOfWeek 
       ? 1 
       : weekNumber; 

Es funktioniert gut sowohl für die amerikanischen und russischen Kulturen. ISO 8601 wird auch korrekt sein, denn die russische Woche beginnt am Montag.

1

Wenn Sie die Wochennummer nach ISO 8601 wünschen, in der die Wochen mit einem Montag beginnen, sind alle Wochen sieben Tage und Woche 1 ist die Woche, die den ersten Donnerstag des Jahres enthält. Dies könnte eine Lösung sein.

Da es keine .Net-Kultur zu geben scheint, die die korrekte ISO-8601-Wochennummer liefert, würde ich die integrierte Wochenbestimmung insgesamt umgehen und die Berechnung manuell durchführen, anstatt zu versuchen, sie zu korrigieren ein teilweise korrektes Ergebnis

, was ich mit der folgenden Erweiterungsmethode endete:

public static int GetIso8601WeekNumber(this DateTime date) 
{ var thursday = date.AddDays(3 - ((int)date.DayOfWeek + 6) % 7); 
    return 1 + (thursday.DayOfYear - 1)/7; 
} 

Zu allererst ((int) date.DayOfWeek + 6)% 7) bestimmt den Wochentag Zahl, 0 = Montag, 6 = Sonntag.

date.AddDays (- ((int) date.DayOfWeek + 6)% 7) bestimmt das Datum des Montag vor der gewünschten Wochennummer.

Drei Tage später ist das Ziel Donnerstag, die bestimmt, in welchem ​​Jahr die Woche in ist.

Wenn Sie die (Null basierend) Tag-Nummer innerhalb des Jahres um sieben (abgerundet) teilen, erhalten Sie die (Null basierte) Wochennummer im Jahr.

In C# werden die Ergebnisse der Ganzzahlberechnung implizit abgerundet.

Verwandte Themen