Berechne das Datum von der Wochennummer

Jeder weiß einen einfachen Weg, um das Datum des ersten Tages in der Woche (Montag hier in Europa) zu bekommen. Ich kenne das Jahr und die Wochennummer? Ich werde das in C # machen.

    Ich hatte Probleme mit der Lösung von @HenkHolterman sogar mit der Korrektur von @RobinAndersson.

    Das Lesen des ISO 8601-Standards behebt das Problem gut. Verwenden Sie den ersten Donnerstag als Ziel und nicht Montag. Der folgende Code wird auch für Woche 53 von 2009 funktionieren.

    public static DateTime FirstDateOfWeekISO8601(int year, int weekOfYear) { DateTime jan1 = new DateTime(year, 1, 1); int daysOffset = DayOfWeek.Thursday - jan1.DayOfWeek; // Use first Thursday in January to get first week of the year as // it will never be in Week 52/53 DateTime firstThursday = jan1.AddDays(daysOffset); var cal = CultureInfo.CurrentCulture.Calendar; int firstWeek = cal.GetWeekOfYear(firstThursday, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday); var weekNum = weekOfYear; // As we're adding days to a date in Week 1, // we need to subtract 1 in order to get the right date for week #1 if (firstWeek == 1) { weekNum -= 1; } // Using the first Thursday as starting week ensures that we are starting in the right year // then we add number of weeks multiplied with days var result = firstThursday.AddDays(weekNum * 7); // Subtract 3 days from Thursday to get Monday, which is the first weekday in ISO8601 return result.AddDays(-3); } 

    Ich mag die Lösung von Henk Holterman. Aber um kulturell unabhängiger zu werden, muss man den ersten Tag der Woche für die aktuelle Kultur bekommen (es ist nicht immer Montag):

     using System.Globalization; static DateTime FirstDateOfWeek(int year, int weekOfYear) { DateTime jan1 = new DateTime(year, 1, 1); int daysOffset = (int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek - (int)jan1.DayOfWeek; DateTime firstMonday = jan1.AddDays(daysOffset); int firstWeek = CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(jan1, CultureInfo.CurrentCulture.DateTimeFormat.CalendarWeekRule, CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek); if (firstWeek < = 1) { weekOfYear -= 1; } return firstMonday.AddDays(weekOfYear * 7); } 

    Der einfachste Weg ist wahrscheinlich, den ersten Montag des Jahres zu finden und dann die entsprechende Anzahl von Wochen hinzuzufügen. Hier ist ein Beispielcode. Es nimmt eine Wochennummer an, die bei 1 übrigens beginnt:

     using System; class Test { static void Main() { // Show the third Tuesday in 2009. Should be January 20th Console.WriteLine(YearWeekDayToDateTime(2009, DayOfWeek.Tuesday, 3)); } static DateTime YearWeekDayToDateTime(int year, DayOfWeek day, int week) { DateTime startOfYear = new DateTime (year, 1, 1); // The +7 and %7 stuff is to avoid negative numbers etc. int daysToFirstCorrectDay = (((int)day - (int)startOfYear.DayOfWeek) + 7) % 7; return startOfYear.AddDays(7 * (week-1) + daysToFirstCorrectDay); } } 

    Persönlich würde ich die Kulturinformationen nutzen, um den Tag der Woche zu erhalten und zum ersten Tag der Woche zurückzukehren. Ich bin mir nicht sicher, ob ich es richtig erkläre, hier ein Beispiel:

      public DateTime GetFirstDayOfWeek(int year, int weekNumber) { return GetFirstDayOfWeek(year, weekNumber, Application.CurrentCulture); } public DateTime GetFirstDayOfWeek(int year, int weekNumber, System.Globalization.CultureInfo culture) { System.Globalization.Calendar calendar = culture.Calendar; DateTime firstOfYear = new DateTime(year, 1, 1, calendar); DateTime targetDay = calendar.AddWeeks(firstOfYear, weekNumber); DayOfWeek firstDayOfWeek = culture.DateTimeFormat.FirstDayOfWeek; while (targetDay.DayOfWeek != firstDayOfWeek) { targetDay = targetDay.AddDays(-1); } return targetDay; } 

    Gemäß ISO 8601: 1988 , die in Schweden verwendet wird, ist die erste Woche des Jahres die erste Woche, die innerhalb des neuen Jahres mindestens vier Tage hat.

    Also, wenn Ihre Woche an einem Montag beginnt, ist der erste Donnerstag jedes Jahr innerhalb der ersten Woche. Sie können DateAdd oder DateDiff davon ableiten.

    Verwenden von Fluent DateTime http://fluentdatetime.codeplex.com/

      var year = 2009; var firstDayOfYear = new DateTime(year, 1, 1); var firstMonday = firstDayOfYear.Next(DayOfWeek.Monday); var weeksDateTime = 12.Weeks().Since(firstMonday); 

    Die freie Zeitbibliothek für .NET enthält die ISO 8601- konforme class Week :

     // ---------------------------------------------------------------------- public static DateTime GetFirstDayOfWeek( int year, int weekOfYear ) { return new Week( year, weekOfYear ).FirstDayStart; } // GetFirstDayOfWeek 

    Dieses hat für mich funktioniert, es hat auch den Vorteil, eine Kulturinfo als Parameter zu erwarten, um die Formel mit verschiedenen Kulturen zu testen. Wenn es leer ist, erhält es die aktuelle Kulturinfo … gültige Werte sind wie: “it”, “en-us”, “fr”, … ando usw. Der Trick ist, die Wochennummer des ersten Tages des Jahres zu subtrahieren, die 1 sein kann, um anzuzeigen, dass der erste Tag innerhalb der ersten Woche liegt. Hoffe das hilft.

     Public Shared Function FirstDayOfWeek(ByVal year As Integer, ByVal weekNumber As Integer, ByVal culture As String) As Date Dim cInfo As System.Globalization.CultureInfo If culture = "" Then cInfo = System.Globalization.CultureInfo.CurrentCulture Else cInfo = System.Globalization.CultureInfo.CreateSpecificCulture(culture) End If Dim calendar As System.Globalization.Calendar = cInfo.Calendar Dim firstOfYear As DateTime = New DateTime(year, 1, 1, calendar) Dim firstDayWeek As Integer = calendar.GetWeekOfYear(firstOfYear, cInfo.DateTimeFormat.CalendarWeekRule, cInfo.DateTimeFormat.FirstDayOfWeek) weekNumber -= firstDayWeek Dim targetDay As DateTime = calendar.AddWeeks(firstOfYear, weekNumber) Dim fDayOfWeek As DayOfWeek = cInfo.DateTimeFormat.FirstDayOfWeek While (targetDay.DayOfWeek <> fDayOfWeek) targetDay = targetDay.AddDays(-1) End While Return targetDay End Function 

    Hier ist eine Methode, die mit den Wochenzahlen von Google Analytics kompatibel ist, und auch mit dem gleichen Nummerierungsschema, das wir intern bei Intel verwendet haben und von dem ich sicher bin, dass es auch in vielen anderen Kontexten verwendet wird.

     // Google Analytics does not follow ISO standards for date. // It numbers week 1 starting on Jan. 1, regardless what day of week it starts on. // It treats Sunday as the first day of the week. // The first and last weeks of a year are usually not complete weeks. public static DateTime GetStartDateTimeFromWeekNumberInYear(int year, uint weekOfYear) { if (weekOfYear == 0 || weekOfYear > 54) throw new ArgumentException("Week number must be between 1 and 54! (Yes, 54... Year 2000 had Jan. 1 on a Saturday plus 53 Sundays.)"); // January 1 -- first week. DateTime firstDayInWeek = new DateTime(year, 1, 1); if (weekOfYear == 1) return firstDayInWeek; // Get second week, starting on the following Sunday. do { firstDayInWeek = firstDayInWeek.AddDays(1); } while (firstDayInWeek.DayOfWeek != DayOfWeek.Sunday); if (weekOfYear == 2) return firstDayInWeek; // Now get the Sunday of whichever week we're looking for. return firstDayInWeek.AddDays((weekOfYear - 2)*7); } 

    Angenommen, die Wochennummer beginnt bei 1

     DateTime dt = new DateTime(YearNumber, 1, 1).AddDays((WeekNumber - 1) * 7 - (WeekNumber == 1 ? 0 : 1)); return dt.AddDays(-(int)dt.DayOfWeek); 

    Dies sollte Ihnen den ersten Tag in einer bestimmten Woche geben. Ich habe nicht viel getestet, aber es sieht so aus, als ob es funktioniert. Es ist eine kleinere Lösung als die meisten anderen, die ich im Internet gefunden habe, wollte also teilen.

    Leicht geänderter Mikael Svenson Code. Ich fand die Woche des ersten Montag und ändere die Wochennummer.

      DateTime GetFirstWeekDay(int year, int weekNum) { Calendar calendar = CultureInfo.CurrentCulture.Calendar; DateTime jan1 = new DateTime(year, 1, 1); int daysOffset = DayOfWeek.Monday - jan1.DayOfWeek; DateTime firstMonday = jan1.AddDays(daysOffset); int firstMondayWeekNum = calendar.GetWeekOfYear(firstMonday, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday); DateTime firstWeekDay = firstMonday.AddDays((weekNum-firstMondayWeekNum) * 7); return firstWeekDay; } 

    Ich habe einige Codes oben versucht und einige haben kleine Fehler, wenn Sie verschiedene Jahre mit verschiedenen beginnenden Tagen der Woche versuchen, werden Sie sie sehen, nahm ich den Code von Jon Skeet, repariere es, und es funktioniert, sehr einfacher Code.

     Public Function YearWeekDayToDateTime(ByVal year As Integer, ByVal weekDay As Integer, ByVal week As Integer) As DateTime ' weekDay, day you want Dim startOfYear As New DateTime(year, 1, 1) Dim startOfYearFixDay As Integer If startOfYear.DayOfWeek <> DayOfWeek.Sunday Then startOfYearFixDay = startOfYear.DayOfWeek Else startOfYearFixDay = 7 End If Return startOfYear.AddDays((7 * (week)) - startOfYearFixDay + weekDay) End Function 

    Gute Nachrichten! Eine Pull-Anforderung, die System.Globalization.ISOWeek zu .NET Core hinzufügt, wurde gerade zusammengeführt und ist derzeit für die Version 3.0 vorgesehen. Hoffentlich wird es in nicht allzu ferner Zukunft auf die anderen .NET-Plattformen übertragen werden.

    Sie sollten in der Lage sein, die ISOWeek.ToDateTime(int year, int week, DayOfWeek dayOfWeek) verwenden, um dies zu berechnen.

    Sie können den Quellcode hier finden .

    Woche 1 ist definiert als die Woche, die an einem Montag beginnt und den ersten Donnerstag des Jahres enthält.

    Um in beide Richtungen zu konvertieren, siehe hier: Wikipedia-Artikel über ISO-Wochendaten

    Ich verbesserte ein wenig die Lösung von Thomas mit einem Override:

      public static DateTime FirstDateOfWeek(int year, int weekOfYear) { return Timer.FirstDateOfWeekOfMonth(year, 1, weekOfYear); } public static DateTime FirstDateOfWeekOfMonth(int year, int month, int weekOfYear) { DateTime dtFirstDayOfMonth = new DateTime(year, month, 1); //I also commented out this part: /* if (firstWeek < = 1) { weekOfYear -= 1; } */ 

    Ansonsten war das Datum um eine Woche voraus.

    Danke Thomas, große Hilfe.

    Ich habe eine der Lösungen verwendet, aber es hat mir falsche Ergebnisse gebracht, einfach weil der Sonntag als erster Tag der Woche zählt.

    Ich habe mich verändert:

     var firstDay = new DateTime(DateTime.Now.Year, 1, 1).AddDays((weekNumber - 1) * 7); var lastDay = firstDay.AddDays(6); 

    zu:

     var lastDay = new DateTime(DateTime.Now.Year, 1, 1).AddDays((weekNumber) * 7); var firstDay = lastDay.AddDays(-6); 

    und jetzt funktioniert es wie ein Zauber.

    Die vorgeschlagene Lösung ist nicht vollständig – sie funktioniert nur für CalendarWeekRule.FirstFullWeek. Andere Arten von Wochenregeln funktionieren nicht. Dies kann mit diesem Testfall gesehen werden:

     foreach (CalendarWeekRule rule in Enum.GetValues(typeof(CalendarWeekRule))) { for (int year = 1900; year < 2000; year++) { DateTime date = FirstDateOfWeek(year, 1, rule); Assert(CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(date, rule, DayOfWeek.Monday) == 1); Assert(CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(date.AddDays(-1), rule, DayOfWeek.Monday) != 1); } } 

    Ich habe eine verfeinerte Version der vorgeschlagenen Lösung gemacht, die einfacher ist und parametrisiert die FirstDayOfWeek:

     public static DateTime GetFirstDayOfWeek(int year, int week, DayOfWeek firstDayOfWeek) { return GetWeek1Day1(year, firstDayOfWeek).AddDays(7 * (week - 1)); } public static DateTime GetWeek1Day1(int year, DayOfWeek firstDayOfWeek) { DateTime date = new DateTime(year, 1, 1); // Move towards firstDayOfWeek date = date.AddDays(firstDayOfWeek - date.DayOfWeek); // Either 1 or 52 or 53 int weekOfYear = CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(date, CalendarWeekRule.FirstFullWeek, firstDayOfWeek); // Move forwards 1 week if week is 52 or 53 date = date.AddDays(7 * System.Math.Sign(weekOfYear - 1)); return date; } 

    Das ist meine Lösung, wenn wir ein Datum mit Jahr, Woche und Wochentag berechnen wollen.

     int Year = 2014; int Week = 48; int DayOfWeek = 4; DateTime FecIni = new DateTime(Year, 1, 1); FecIni = FecIni.AddDays(7 * (Week - 1)); if ((int)FecIni.DayOfWeek > DayOfWeek) { while ((int)FecIni.DayOfWeek != DayOfWeek) FecIni = FecIni.AddDays(-1); } else { while ((int)FecIni.DayOfWeek != DayOfWeek) FecIni = FecIni.AddDays(1); } 

    Ich habe den von Mikael Svensson bereitgestellten Code vereinfacht, der für viele Länder in Europa korrekt ist.

     public static DateTime FirstDateOfWeekIso8601(int year, int week) { var firstThursdayOfYear = new DateTime(year, 1, 1); while (firstThursdayOfYear.DayOfWeek != DayOfWeek.Thursday) { firstThursdayOfYear = firstThursdayOfYear.AddDays(1); } var startDateOfWeekOne = firstThursdayOfYear.AddDays(-(DayOfWeek.Thursday - DayOfWeek.Monday)); return startDateOfWeekOne.AddDays(7 * (week - 1)); } 

    Ich habe den folgenden Code geschrieben und getestet und funktioniert perfekt für mich. Bitte lassen Sie mich wissen, wenn jemand Probleme damit hat, habe ich auch eine Frage gestellt, um die bestmögliche Antwort zu bekommen. Jemand könnte es nützlich finden.

     public static DateTime GetFirstDateOfWeekByWeekNumber(int year, int weekNumber) { var date = new DateTime(year, 01, 01); var firstDayOfYear = date.DayOfWeek; var result = date.AddDays(weekNumber * 7); if (firstDayOfYear == DayOfWeek.Monday) return result.Date; if (firstDayOfYear == DayOfWeek.Tuesday) return result.AddDays(-1).Date; if (firstDayOfYear == DayOfWeek.Wednesday) return result.AddDays(-2).Date; if (firstDayOfYear == DayOfWeek.Thursday) return result.AddDays(-3).Date; if (firstDayOfYear == DayOfWeek.Friday) return result.AddDays(-4).Date; if (firstDayOfYear == DayOfWeek.Saturday) return result.AddDays(-5).Date; return result.AddDays(-6).Date; } 

    Derzeit gibt es keine C # -class, die ISO 8601-Woche-Nummern korrekt verarbeitet. Auch wenn Sie eine Kultur instanziieren können, suchen Sie nach der nächsten Sache und korrigieren Sie diese, ich denke, es ist besser, die vollständige Berechnung selbst durchzuführen:

      ///  /// Converts a date to a week number. /// ISO 8601 week 1 is the week that contains the first Thursday that year. ///  public static int ToIso8601Weeknumber(this DateTime date) { var thursday = date.AddDays(3 - date.DayOfWeek.DayOffset()); return (thursday.DayOfYear - 1) / 7 + 1; } ///  /// Converts a week number to a date. /// Note: Week 1 of a year may start in the previous year. /// ISO 8601 week 1 is the week that contains the first Thursday that year, so /// if December 28 is a Monday, December 31 is a Thursday, /// and week 1 starts January 4. /// If December 28 is a later day in the week, week 1 starts earlier. /// If December 28 is a Sunday, it is in the same week as Thursday January 1. ///  public static DateTime FromIso8601Weeknumber(int weekNumber, int? year = null, DayOfWeek day = DayOfWeek.Monday) { var dec28 = new DateTime((year ?? DateTime.Today.Year) - 1, 12, 28); var monday = dec28.AddDays(7 * weekNumber - dec28.DayOfWeek.DayOffset()); return monday.AddDays(day.DayOffset()); } ///  /// Iso8601 weeks start on Monday. This returns 0 for Monday. ///  private static int DayOffset(this DayOfWeek weekDay) { return ((int)weekDay + 6) % 7; }