293 Stimmen

Erhalte die korrekte Kalenderwoche eines bestimmten Datums

Ich habe viel gegoogelt und viele Lösungen gefunden, aber keine davon gibt mir die richtige Wochennummer für den 31.12.2012. Selbst das Beispiel auf MSDN (link) funktioniert nicht.

Der 31.12.2012 ist ein Montag, daher sollte es Woche 1 sein, aber jede Methode, die ich ausprobiert habe, gibt mir 53. Hier sind einige der Methoden, die ich ausprobiert habe:

Aus der MSDN-Bibliothek:

DateTimeFormatInfo dfi = DateTimeFormatInfo.CurrentInfo;
Calendar cal = dfi.Calendar;

return cal.GetWeekOfYear(date, dfi.CalendarWeekRule, dfi.FirstDayOfWeek);

Lösung 2:

return new GregorianCalendar(GregorianCalendarTypes.Localized).GetWeekOfYear(date, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);

Lösung 3:

CultureInfo ciCurr = CultureInfo.CurrentCulture;
int weekNum = ciCurr.Calendar.GetWeekOfYear(dtPassed, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
return weekNum;

Aktualisierung

Die folgende Methode gibt tatsächlich 1 zurück, wenn das Datum der 31.12.2012 ist. Mit anderen Worten, mein Problem war, dass meine Methoden den ISO-8601-Standard nicht eingehalten haben.

// Das setzt voraus, dass die Wochen mit Montag beginnen.
// Woche 1 ist die 1. Woche des Jahres mit einem Donnerstag darin.
public static int GetIso8601WeekOfYear(DateTime time)
{
    // Ernsthaftes Schummeln. Wenn es Montag, Dienstag oder Mittwoch ist, wird es
    // die gleiche Wochennummer wie der Donnerstag, Freitag oder Samstag sein,
    // und wir bekommen diese immer richtig
    DayOfWeek day = CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(time);
    if (day >= DayOfWeek.Monday && day <= DayOfWeek.Wednesday)
    {
        time = time.AddDays(3);
    }

    // Gib die Woche unseres angepassten Tages zurück
    return CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(time, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
}

2voto

user6887101 Punkte 21

Der einfachste Weg, um die Wochennummer im ISO 8601-Stil mit c# und der DateTime-Klasse zu bestimmen.

Frage dies: der wievielte Donnerstag des Jahres ist der Donnerstag dieser Woche. Die Antwort entspricht der gewünschten Wochennummer.

var dayOfWeek = (int)moment.DayOfWeek;
// Mache Montag zum ersten Tag der Woche
if (--dayOfWeek < 0)
    dayOfWeek = 6;
// Die gesamte Anzahl der Wochen vor diesem Donnerstag plus eins ist die Wochennummer
var weekNumber = (moment.AddDays(3 - dayOfWeek).DayOfYear - 1) / 7 + 1;

1voto

Marcus Pierce Punkte 247

Alternative Antwort, wenn Sie globalisierte Wochennummern möchten: Ich habe die Antwort auch hier gepostet

Aus der Originalantwort:

Aufgebaut auf dieser Antwort von @bunny4

Aber nicht jeder befindet sich in den USA oder muss möglicherweise mehrere Kulturen unterstützen. Verwenden Sie diese Lösung, um eine kulturell definierte Wochenregel und eine First-Day-Regel zu unterstützen, z.B. Dänemark hat die Regel "ErsteVierTageWoche" für Wochen und den ersten Tag der Woche als "Montag".

//zunächst nehmen wir die aktuelle Ausführungskultur des Threads
var cultureInfo = Thread.CurrentThread.CurrentCulture;

//wählen wir ein Datum aus
DateTime dt = new DateTime(2020, 12, 21);

DayOfWeek firstDay = cultureInfo.DateTimeFormat.FirstDayOfWeek;
CalendarWeekRule weekRule = cultureInfo.DateTimeFormat.CalendarWeekRule;
Calendar cal = cultureInfo.Calendar;
int week = cal.GetWeekOfYear(dt, weekRule, firstDay);

1voto

Ronen Punkte 1165

Wenn Sie nicht über .NET 5.0 verfügen, erweitern Sie die DateTime-Klasse, um die Kalenderwoche einzuschließen.

public static class Extension {
    public static int Week(this 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);
    }
}

0voto

René Punkte 3088

Wenn Sie die Kombination aus Kalenderwoche und Jahr benötigen (z. B. "1/22" für Kalenderwoche 1 im Jahr 2022), sollten Sie beachten, dass die Jahreskomponente nicht immer mit dem Jahr des Eingabedatums übereinstimmt. Dies liegt daran, dass die ersten Tage eines Jahres zur letzten Kalenderwoche des Vorjahres gehören, wenn mindestens 4 Tage der Woche zum letzten Jahr gehören. Entsprechend gehören die letzten Tage eines Jahres zur ersten Kalenderwoche des nächsten Jahres, wenn mindestens 4 Tage der Woche zum nächsten Jahr gehören.

Hier ist eine Erweiterung dazu, basierend auf der Erweiterung, die in der Antwort von @Jogge bereitgestellt wurde

public static class DateTimeExtensions
{
    public static int GetIso8601WeekOfYear(this DateTime time)
    {
        var day = CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(time);
        if (day >= DayOfWeek.Monday && day <= DayOfWeek.Wednesday)
        {
            time = time.AddDays(3);
        }

        return CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(time, CalendarWeekRule.FirstFourDayWeek,
            DayOfWeek.Monday);
    }

    public static int? GetIso8601WeekOfYear(this DateTime? time)
    {
        return time?.GetIso8601WeekOfYear();
    }

    public static string GetIso8601WeekAndYearString(this DateTime time)
    {
        var week = time.GetIso8601WeekOfYear();

        var year = time.Month == 1 && week >= 52
            ? time.Year - 1
            : time.Month == 12 && week == 1
                ? time.Year + 1
                : time.Year;

        return $"{week}/{new DateTime(year, 1, 1):yy}";
    }

    public static string GetIso8601WeekAndYearString(this DateTime? time)
    {
        return time?.GetIso8601WeekAndYearString();
    }
}

0voto

Mnyikka Punkte 1203

Diese beiden Methoden helfen, vorausgesetzt, dass unsere Woche am Montag beginnt

/// 
    /// Gibt die WocheId zurück
    /// 
    /// 
    /// Gibt die aktuelle Wochen-ID zurück
    public static DateTime GetDateFromWeek(int WeekReference)
    {
        //365 leap
        int DaysOffset = 0;
        if (WeekReference > 1)
        {
            DaysOffset = 7;
            WeekReference = WeekReference - 1;
        }
        DateTime DT = new DateTime(DateTime.Now.Year, 1, 1);
        int CurrentYear = DT.Year;
        DateTime SelectedDateTime = DateTime.MinValue;

        while (CurrentYear == DT.Year)
        {
            int TheWeek = WeekReportData.GetWeekId(DT);
            if (TheWeek == WeekReference)
            {
                SelectedDateTime = DT;
                break;
            }
            DT = DT.AddDays(1.0D);
        }

        if (SelectedDateTime == DateTime.MinValue)
        {
            throw new Exception("Bitte Woche überprüfen");
        }

        return SelectedDateTime.AddDays(DaysOffset);
    }
/// 
    /// Gibt die WocheId zurück
    /// 
    /// 
    /// Gibt die aktuelle Wochen-ID zurück
    public static int GetWeekId(DateTime DateTimeReference)
    {
        CultureInfo ciCurr = CultureInfo.InvariantCulture;
        int weekNum = ciCurr.Calendar.GetWeekOfYear(DateTimeReference,
        CalendarWeekRule.FirstFullWeek, DayOfWeek.Monday);
        return weekNum;
    }

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X