How to Calculate Week Number from DateTime in C#

By FoxLearn 1/9/2025 2:37:15 AM   59
Calculating the week number is more complex than it initially seems.

Different countries have their own methods for determining week numbers, so it's important to understand the rules in play.

First, you need to figure out when a week begins does it start on Sunday or Monday? Then, what defines the first week of the year? Is it the week containing January 1st? Or is it the first week that includes at least four days? Some countries even use the first full week of the year to determine the starting point.

In my country, the week begins on Monday, and the first week of the year is the one that includes at least four days of January.

The Calendar class has a handy GetWeekOfYear method for this:

using System;
using System.Globalization;

Calendar calendar = CultureInfo.InvariantCulture.Calendar;
int weekNumber = calendar.GetWeekOfYear(DateTime.Now, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
Console.WriteLine(weekNumber);

// For example, May 31st, 2025, falls in week 22.

With this in hand, I can create a class to provide more detailed information about the week, such as its start date, end date, and which year it belongs to. This class also allows comparisons between weeks and supports sorting them. While the class may look a little more complex, it's worth the effort:

public class Week : IComparable<Week>, IEquatable<Week>
{
    private const DayOfWeek FirstDayOfWeek = DayOfWeek.Monday;
    private const DayOfWeek LastDayOfWeek = DayOfWeek.Sunday;
    private const DayOfWeek FirstDayOfYear = DayOfWeek.Thursday;
    private static readonly Calendar Calendar = CultureInfo.InvariantCulture.Calendar;

    public Week(DateTime date)
    {
        FirstDateOfWeek = GetFirstDateOfWeek(date);
        LastDateOfWeek = GetLastDateOfWeek(date);
        DateTime offsetDate = GetYearOffsetDayOfWeek(FirstDateOfWeek);
        WeekNumber = Calendar.GetWeekOfYear(offsetDate, CalendarWeekRule.FirstFourDayWeek, FirstDayOfWeek);
        WeekYear = offsetDate.Year;
    }

    public DateTime FirstDateOfWeek { get; private set; }

    public DateTime LastDateOfWeek { get; private set; }

    public int WeekNumber { get; private set; }

    public int WeekYear { get; private set; }

    public int CompareTo(Week week)
    {
        return week == null ? -1 : string.Compare(ToString(), week.ToString(), StringComparison.Ordinal);
    }

    public bool Equals(Week week)
    {
        return week != null && string.Equals(ToString(), week.ToString(), StringComparison.Ordinal);
    }

    public override string ToString()
    {
        return string.Format("{0}-W{1:00}", WeekYear, WeekNumber);
    }

    public override bool Equals(object obj)
    {
        return Equals(obj as Week);
    }

    public override int GetHashCode()
    {
        return ToString().GetHashCode();
    }

    private DateTime GetFirstDateOfWeek(DateTime date)
    {
        while (date.DayOfWeek != FirstDayOfWeek)
            date = date.AddDays(-1);
        return date;
    }

    private DateTime GetLastDateOfWeek(DateTime date)
    {
        while (date.DayOfWeek != LastDayOfWeek)
            date = date.AddDays(1);
        return date;
    }

    private DateTime GetYearOffsetDayOfWeek(DateTime firstDateOfWeek)
    {
        while (firstDateOfWeek.DayOfWeek != FirstDayOfYear)
            firstDateOfWeek = firstDateOfWeek.AddDays(1);
        return firstDateOfWeek;
    }
}

To use the Week class:

Week week = new Week(DateTime.Now);
Console.WriteLine("Date: " + DateTime.Now.ToString("yyyy-MM-dd"));
Console.WriteLine("Week: " + week.WeekNumber);
Console.WriteLine("Starts on: " + week.FirstDateOfWeek.ToString("yyyy-MM-dd"));
Console.WriteLine("Ends on: " + week.LastDateOfWeek.ToString("yyyy-MM-dd"));
Console.WriteLine("In year: " + week.WeekYear);

// Output
// Date: 2025-05-31
// Week: 22
// Starts on: 2025-05-29
// Ends on: 2025-06-04
// In year: 2025

The method GetYearOffsetDayOfWeek is a bit tricky it handles the year overlap that can occur with week numbers. For example, December 31st might belong to the last week of the previous year or the first week of the new year. This function ensures the correct year is calculated by adjusting the date until it reaches the first day of the year.

Finally, don't forget to update the FirstDayOfWeek, LastDayOfWeek, and CalendarWeekRule.FirstFourDayWeek values in the code to reflect the specific week numbering rules of your country.