304

I have Googled a lot and found a lot of solutions, but none of them give me the correct week number for the 2012-12-31. Even the example on MSDN (link) fails.

2012-12-31 is Monday, therefore it should be Week 1, but every method I tried gives me 53. Here are some of the methods, that I have tried:

From the MDSN Library:

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

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

Solution 2:

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

Solution 3:

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

Update

The following method actually returns 1 when date is 2012-12-31. In other words, my problem was that my methods were not following the ISO-8601 standard.

// This presumes that weeks start with Monday.
// Week 1 is the 1st week of the year with a Thursday in it.
public static int GetIso8601WeekOfYear(DateTime time)
{
    // Seriously cheat.  If its Monday, Tuesday or Wednesday, then it'll 
    // be the same week# as whatever Thursday, Friday or Saturday are,
    // and we always get those right
    DayOfWeek day = CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(time);
    if (day >= DayOfWeek.Monday && day <= DayOfWeek.Wednesday)
    {
        time = time.AddDays(3);
    }

    // Return the week of our adjusted day
    return CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(time, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
}
Stefano Altieri
  • 4,550
  • 1
  • 24
  • 41
Amberlamps
  • 39,180
  • 5
  • 43
  • 53
  • 9
    How is week 1 at the end of the year? I mean, I see where you get it. But 53 makes sense to me. – benjer3 Jun 22 '12 at 10:47
  • 1
    In my code snippets I get the CultureInfo and stuff. I thought my program knows by then what calender I am using. (Here in Germany the 31st of December 2012 is in week 1 of 2013) – Amberlamps Jun 22 '12 at 11:19
  • This code doesn't work quite as it should try dates 31-dec-2016 for example or 1-jan-2016 – Jaybeecave Mar 24 '16 at 01:30
  • @cavej03 31-dec-2016 is week 52 and the GetIso8601WeekOfYear returns 52 so i guess it works correctly. – Muflix Dec 17 '16 at 19:25

20 Answers20

392

As noted in this MSDN page there is a slight difference between ISO8601 week and .Net week numbering.

You can refer to this article in MSDN Blog for a better explanation: "ISO 8601 Week of Year format in Microsoft .Net"

Simply put, .Net allow weeks to be split across years while the ISO standard does not. In the article there is also a simple function to get the correct ISO 8601 week number for the last week of the year.

Update The following method actually returns 1 for 2012-12-31 which is correct in ISO 8601 (e.g. Germany).

// This presumes that weeks start with Monday.
// Week 1 is the 1st week of the year with a Thursday in it.
public static int GetIso8601WeekOfYear(DateTime time)
{
    // Seriously cheat.  If its Monday, Tuesday or Wednesday, then it'll 
    // be the same week# as whatever Thursday, Friday or Saturday are,
    // and we always get those right
    DayOfWeek day = CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(time);
    if (day >= DayOfWeek.Monday && day <= DayOfWeek.Wednesday)
    {
        time = time.AddDays(3);
    }

    // Return the week of our adjusted day
    return CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(time, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
} 
Callum Watkins
  • 2,844
  • 4
  • 29
  • 49
il_guru
  • 8,383
  • 2
  • 42
  • 51
  • Thank you! The code in the blog entry finally solved my problem. I included the relevant code in my question just in case anybody has the same issue. Or you might just want to copy it in your answer. – Amberlamps Jun 22 '12 at 11:34
  • 3
    @il_guru What if I wish the week starts with sunday?? Do i replace all "Monday" with "Sunday"?? – User2012384 Mar 17 '16 at 08:12
  • I think you should replace Monday with Sunday and Wednesday with Tuesday in the cheat part – il_guru Mar 24 '16 at 10:09
  • 6
    @User2012384 fyi, if you want to follow the ISO8601 standard the firstDayOfWeek should always be Monday. – Starceaker Apr 05 '16 at 09:07
  • 2
    @il_guru You don't even need this "cheat" if, do you? As far as I can tell "GetWeekOfYear(time, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);" works just fine. – Starceaker Apr 05 '16 at 09:07
  • 1
    @Starceaker you are wrong, ISO8601 states that the first week of the year is "the week with the year's first Thursday in it (the formal ISO definition)" – il_guru Apr 05 '16 at 10:23
  • @il_guru I know what the ISO states. My question is in what scenario does the combination FirstFourDayWeek and Monday not return the result you want? As far as I can tell you will always get the week with the first Thursday. – Starceaker Apr 07 '16 at 06:11
  • 2
    If you look the second link (ISO 8601 Week of Year format in Microsoft .Net), you could find the answer to your question directly from Microsoft. An example is Monday 31/12/2007: with the .Net function it will return week number 53 of 2007 while for the ISO standard it is week number 1 of 2008 – il_guru Apr 11 '16 at 13:22
  • 3
    I've manually verified this to be correct for years 2012 to 2018 (assuming that epochconverter.com is correct). We should all rejoice this year that week 1 of 2018 actually started on the first of January for once! – Aidan Oct 21 '18 at 10:39
  • I have created an extension and nullable version of this answer here: https://stackoverflow.com/a/55115601/7108481 – Jogge Mar 12 '19 at 06:49
  • 2
    This implementation actually isn't correct. 30th of December 2024 returns week 52. It actually should return week 1.. – Mittchel Mar 30 '19 at 11:40
  • 1
    It IS 1, just checked – Vadym Kyrylkov Jan 20 '20 at 16:24
  • @АлександрПекшев 01.01.2021 was part of week 53 of 2020 [google result](https://www.google.com/search?q=2020+iso+week+53&rlz=1C1GCEJ_enUS847US847&oq=2020+iso+week+53&aqs=chrome..69i57j0i390.6481j0j7&sourceid=chrome&ie=UTF-8) – Nifim Aug 04 '21 at 20:29
86

Good news! A pull request adding System.Globalization.ISOWeek to .NET Core was just merged and is currently slated for the 3.0 release. Hopefully it will propagate to the other .NET platforms in a not-too-distant future.

The type has the following signature, which should cover most ISO week needs:

namespace System.Globalization
{
    public static class ISOWeek
    {
        public static int GetWeekOfYear(DateTime date);
        public static int GetWeeksInYear(int year);
        public static int GetYear(DateTime date);
        public static DateTime GetYearEnd(int year);
        public static DateTime GetYearStart(int year);
        public static DateTime ToDateTime(int year, int week, DayOfWeek dayOfWeek);
    }
}

You can find the source code here.

UPDATE: These APIs have also been included in the 2.1 version of .NET Standard.

khellang
  • 17,550
  • 6
  • 64
  • 84
  • Any idea when v 3.0 will be released? – Jacques Aug 01 '18 at 08:25
  • "We are planning on releasing a first preview of .NET Core 3 later this year and the final version in 2019." (from [the roadmap blog post](https://blogs.msdn.microsoft.com/dotnet/2018/05/07/net-core-3-and-support-for-windows-desktop-applications/)) – khellang Aug 01 '18 at 08:41
  • @khellang how could I get ordinal week in a month based on datetime? Instead of getting week 33 I would like to see Week 2 (because week 33 is week 2 in august). https://stackoverflow.com/questions/58039103/how-could-i-get-months-week-number-based-on-year-week-number-i-e-week-33?noredirect=1#comment102479142_58039103 – Roxy'Pro Sep 21 '19 at 10:05
  • 3
    Be aware, compared to `Calendar`, `ISOWeek` is the ISO 8601 special case answer as it works only for [CalendarWeekRule.FirstFourDayWeek](https://learn.microsoft.com/en-us/dotnet/api/system.globalization.calendarweekrule) and [FirstDayOfWeek](https://learn.microsoft.com/en-us/dotnet/api/system.globalization.datetimeformatinfo.firstdayofweek) = `DayOfWeek.Monday` – McX Aug 31 '20 at 16:27
  • 8
    @McX Yes, the fact that the type is called ISOWeek should probably make it apparent that it's working with [ISO Weeks](https://en.m.wikipedia.org/wiki/ISO_week_date) – khellang Aug 31 '20 at 17:40
  • 5
    This should be the new answer. – M1sterPl0w Jan 18 '22 at 09:28
  • This is it for .net core – lnaie Feb 16 '23 at 11:16
  • Wish: a method that return both in one call: public static (int, int) GetWeekAndYear(DateTime date). public static int GetYear(DateTime date) already get the week number, so it could be renamed to GetWeekAndYear and GetYear could call GetWeekAndYear :-) – osexpert Jul 06 '23 at 23:06
  • @osexpert You mean this? https://github.com/dotnet/runtime/issues/29060 – khellang Jul 07 '23 at 06:32
  • @khellang Sort of. Here is my take at the struct part: https://github.com/osexpert/CosmosTime/blob/main/src/CosmosTime/IsoWeek.cs and I made a PR for the week and year at once part here: https://github.com/dotnet/runtime/pull/88514 In retrospect I wish, class ISOWeek could have been called class IsoWeekCalendar or IsoWeekCalculator and another struct IsoWeek to store the week and number. – osexpert Jul 07 '23 at 08:05
37

There can be more than 52 weeks in a year. Each year has 52 full weeks + 1 or +2 (leap year) days extra. They make up for a 53th week.

  • 52 weeks * 7days = 364 days.

So for each year you have at least one an extra day. Two for leap years. Are these extra days counted as separate weeks of their own?

How many weeks there are really depends on the starting day of your week. Let's consider this for 2012.

  • US (Sunday -> Saturday): 52 weeks + one short 2 day week for 2012-12-30 & 2012-12-31. This results in a total of 53 weeks. Last two days of this year (Sunday + Monday) make up their own short week.

Check your current Culture's settings to see what it uses as the first day of the week.

As you see it's normal to get 53 as a result.

  • Europe (Monday -> Sunday): January 2dn (2012-1-2) is the first monday, so this is the first day of the first week. Ask the week number for the 1st of January and you'll get back 52 as it is considered part of 2011 last's week.

It's even possible to have a 54th week. Happens every 28 years when the 1st of January and the 31st of December are treated as separate weeks. It must be a leap year too.

For example, the year 2000 had 54 weeks. January 1st (sat) was the first one week day, and 31st December (sun) was the second one week day.

var d = new DateTime(2012, 12, 31);
CultureInfo cul = CultureInfo.CurrentCulture;

var firstDayWeek = cul.Calendar.GetWeekOfYear(
    d,
    CalendarWeekRule.FirstDay,
    DayOfWeek.Monday);

int weekNum = cul.Calendar.GetWeekOfYear(
    d,
    CalendarWeekRule.FirstDay,
    DayOfWeek.Monday);

int year = weekNum == 52 && d.Month == 1 ? d.Year - 1 : d.Year;
Console.WriteLine("Year: {0} Week: {1}", year, weekNum);

Prints out: Year: 2012 Week: 54

Change CalendarWeekRule in the above example to FirstFullWeek or FirstFourDayWeek and you'll get back 53. Let's keep the start day on Monday since we are dealing with Germany.

So week 53 starts on monday 2012-12-31, lasts one day and then stops.

53 is the correct answer. Change the Culture to germany if want to to try it.

CultureInfo cul = CultureInfo.GetCultureInfo("de-DE");
Prashant Yadav
  • 531
  • 2
  • 9
  • 25
Christophe Geers
  • 8,564
  • 3
  • 37
  • 53
27

This is the way:

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

Most important for is the CalendarWeekRule parameter.

See here: https://msdn.microsoft.com/query/dev14.query?appId=Dev14IDEF1&l=IT-IT&k=k(System.Globalization.CalendarWeekRule);k(TargetFrameworkMoniker-.NETFramework

daniele3004
  • 13,072
  • 12
  • 67
  • 75
  • 4
    "Several people have noticed that Calendar.GetWeekOfYear() is almost like the ISO 8601 week when passed CalendarWeekRule.FirstFourDayWeek and DayOfWeek.Monday, however it is a little bit different. Specifically ISO 8601 always has 7 day weeks. " https://blogs.msdn.microsoft.com/shawnste/2006/01/24/iso-8601-week-of-year-format-in-microsoft-net/ – Juha Palomäki Jan 31 '17 at 22:45
  • 1
    Your link is in italian – radbyx Jun 26 '19 at 05:48
  • for new DateTime(2000,12,31) it returns just 52? – Leszek P Jan 17 '20 at 15:00
13

Since there doesn't seem to be a .Net-culture that yields the correct ISO-8601 week number, I'd rather bypass the built-in week determination altogether, and do the calculation manually, instead of attempting to correct a partially correct result.

What I ended up with is the following extension method:

/// <summary>
/// Converts a date to a week number.
/// ISO 8601 week 1 is the week that contains the first Thursday that year.
/// </summary>
public static int ToIso8601Weeknumber(this DateTime date)
{
    var thursday = date.AddDays(3 - date.DayOfWeek.DayOffset());
    return (thursday.DayOfYear - 1) / 7 + 1;
}

/// <summary>
/// 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.
/// </summary>
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());
}

/// <summary>
/// Iso8601 weeks start on Monday. This returns 0 for Monday.
/// </summary>
private static int DayOffset(this DayOfWeek weekDay)
{
    return ((int)weekDay + 6) % 7;
}

First of all, ((int)date.DayOfWeek + 6) % 7) determines the weekday number, 0=monday, 6=sunday.

date.AddDays(-((int)date.DayOfWeek + 6) % 7) determines the date of the monday preceiding the requested week number.

Three days later is the target thursday, which determines what year the week is in.

If you divide the (zero based) day-number within the year by seven (round down), you get the (zero based) week number in the year.

In c#, integer calculation results are round down implicitly.

Jogge
  • 1,654
  • 12
  • 36
realbart
  • 3,497
  • 1
  • 25
  • 37
  • 1
    This is the best solution by far but I will point out a slightly different way of doing it: DateTime is based on the proleptic Gregorian Calendar - i.e. it extends the Gregorian calendar back to the year 1. The 1st of January 0001 happens to be a Monday. `Ticks` is the number of 100-nanosecond increments since 1st January 0001. Given that there are 86,400 seconds in a day we can write: `var thursday = date.AddDays(3 - date.Ticks / 86400 / 10_000_000 % 7); return (thursday.DayOfYear - 1) / 7 + 1;` – Adrian S Jan 16 '20 at 17:04
8

In .NET 3.0 and later you can use the ISOWeek.GetWeekOfDate-Method.

Note that the year in the year + week number format might differ from the year of the DateTime because of weeks that cross the year boundary.

johh
  • 141
  • 1
  • 5
4

C# to Powershell port from code above from il_guru:

function GetWeekOfYear([datetime] $inputDate)
{
   $day = [System.Globalization.CultureInfo]::InvariantCulture.Calendar.GetDayOfWeek($inputDate)
   if (($day -ge [System.DayOfWeek]::Monday) -and ($day -le [System.DayOfWeek]::Wednesday))
   {
      $inputDate = $inputDate.AddDays(3)
   }

   # Return the week of our adjusted day
   $weekofYear = [System.Globalization.CultureInfo]::InvariantCulture.Calendar.GetWeekOfYear($inputDate, [System.Globalization.CalendarWeekRule]::FirstFourDayWeek, [System.DayOfWeek]::Monday)
   return $weekofYear
}
Rainer
  • 803
  • 10
  • 8
  • 1
    Could you explain your code? Code-only answers are generally not acceptable on StackOverflow, and as such are liable to be deleted. – Wai Ha Lee Oct 01 '15 at 00:20
  • @Wai Ha Lee the code is already explained. See post above from il_guru. I ported his code to powershell, so other people can use it in powershell because there are no good solution in powershell so far. – Rainer Oct 07 '15 at 11:29
  • If that's what you did, you should credit the original author in the answer itself. The answer you ported has better comments which you have presumably removed. Also, this isn't an answer to the question since the question did not mention PowerShell. – Wai Ha Lee Oct 07 '15 at 11:32
  • 1
    I did now @Wai Ha Lee. The question is already marked as answered, so this would be the same solution written in an other language. I made a favour for people, which are looking for an solution in Powershell language (I was looking hard for an solution in Powershell, but what I found was a solution in C#). The idea remains the same and the author gets the credit for it. – Rainer Oct 07 '15 at 11:39
4

Here is an extension version and nullable version of il_guru's answer.

Extension:

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);
}

Nullable:

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

Usages:

new DateTime(2019, 03, 15).GetIso8601WeekOfYear(); //returns 11
((DateTime?) new DateTime(2019, 03, 15)).GetIso8601WeekOfYear(); //returns 11
((DateTime?) null).GetIso8601WeekOfYear(); //returns null
Jogge
  • 1,654
  • 12
  • 36
2
var cultureInfo = CultureInfo.CurrentCulture;
var calendar = cultureInfo.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);

var weekNumber = calendar.GetWeekOfYear(date, calendarWeekRule, firstDayOfWeek);

 //Check if this is the last week in the year and it doesn`t occupy the whole week
return weekNumber == 53 && lastDayOfYear.DayOfWeek != lastDayOfWeek 
       ? 1  
       : weekNumber;

It works well both for US and Russian cultures. ISO 8601 also will be correct, `cause Russian week starts at Monday.

Arif Dewi
  • 2,222
  • 26
  • 14
2

The easiest way to determine the week number ISO 8601 style using c# and the DateTime class.

Ask this: the how-many-eth thursday of the year is the thursday of this week. The answer equals the wanted week number.

var dayOfWeek = (int)moment.DayOfWeek;
// Make monday the first day of the week
if (--dayOfWeek < 0)
    dayOfWeek = 6;
// The whole nr of weeks before this thursday plus one is the week number
var weekNumber = (moment.AddDays(3 - dayOfWeek).DayOfYear - 1) / 7 + 1;
2

In PowerShell 7.x.y: You will need both of the following codelines, if you have the need for the matching WeekYear.

[System.Globalization.ISOWeek]::GetWeekOfYear((get-date))
[System.Globalization.ISOWeek]::GetYear((get-date))
B-Art
  • 53
  • 4
2

Alternative answer if you want globalized week numbers: I also posted the answer here

From the original answer:

Built on top of this answer: by @bunny4

But not everyone is located in the US or might have to support several cultures. Use this solution to support a cultural defined week rule and first-Day rule.. e.g. Denmark has "FirstFourDayWeek" rule for weeks and "Monday" as first day of the week.

//for now, take the the current executing thread's Culture
var cultureInfo = Thread.CurrentThread.CurrentCulture;

//let's pick a date
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);
Marcus Pierce
  • 267
  • 2
  • 8
1

If you don't have .NET 5.0, extend the DateTime class to include week number.

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);
    }
}
Ronen
  • 1,225
  • 13
  • 10
0

The question is: How do you define if a week is in 2012 or in 2013? Your supposition, I guess, is that since 6 days of the week are in 2013, this week should be marked as the first week of 2013.

Not sure if this is the right way to go. That week started on 2012 (On monday 31th Dec), so it should be marked as the last week of 2012, therefore it should be the 53rd of 2012. The first week of 2013 should start on monday the 7th.

Now, you can handle the particular case of edge weeks (first and last week of the year) using the day of week information. It all depends on your logic.

James
  • 80,725
  • 18
  • 167
  • 237
Samy Arous
  • 6,794
  • 13
  • 20
  • Okay, I can see your point. The thing is when I use 2013/01/07 in any of my methods, it say week 2. So, 2012/12/31 is week 53 and 2013/01/07 is week 2. You might think there is no week 1 of 2013. But when I try 2013/01/01 it says week 1. – Amberlamps Jun 22 '12 at 11:11
0
  DateTimeFormatInfo dfi = DateTimeFormatInfo.CurrentInfo;
  DateTime date1 = new DateTime(2011, 1, 1);
  Calendar cal = dfi.Calendar;

  Console.WriteLine("{0:d}: Week {1} ({2})", date1, 
                    cal.GetWeekOfYear(date1, dfi.CalendarWeekRule, 
                                      dfi.FirstDayOfWeek),
                    cal.ToString().Substring(cal.ToString().LastIndexOf(".") + 1));      
Imran
  • 1,951
  • 1
  • 10
  • 7
0

Based on il_guru's answer, I created this version for my own needs that also returns the year component.

    /// <summary>
    /// This presumes that weeks start with Monday.
    /// Week 1 is the 1st week of the year with a Thursday in it.
    /// </summary>
    /// <param name="time">The date to calculate the weeknumber for.</param>
    /// <returns>The year and weeknumber</returns>
    /// <remarks>
    /// Based on Stack Overflow Answer: https://stackoverflow.com/a/11155102
    /// </remarks>
    public static (short year, byte week) GetIso8601WeekOfYear(DateTime time)
    {
        // Seriously cheat.  If its Monday, Tuesday or Wednesday, then it'll
        // be the same week# as whatever Thursday, Friday or Saturday are,
        // and we always get those right
        DayOfWeek day = CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(time);
        if (day >= DayOfWeek.Monday && day <= DayOfWeek.Wednesday)
        {
            time = time.AddDays(3);
        }
        // Return the week of our adjusted day
        var week = (byte)CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(time, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
        return ((short)(week >= 52 & time.Month == 1 ? time.Year - 1 : time.Year), week);
    }
NKCSS
  • 2,716
  • 1
  • 22
  • 38
0

These two methods will help, assumming our week starts on Monday

/// <summary>
    /// Returns the weekId
    /// </summary>
    /// <param name="DateTimeReference"></param>
    /// <returns>Returns the current week id</returns>
    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("Please check week");
        }

        return SelectedDateTime.AddDays(DaysOffset);
    }
/// <summary>
    /// Returns the weekId
    /// </summary>
    /// <param name="DateTimeReference"></param>
    /// <returns>Returns the current week id</returns>
    public static int GetWeekId(DateTime DateTimeReference)
    {
        CultureInfo ciCurr = CultureInfo.InvariantCulture;
        int weekNum = ciCurr.Calendar.GetWeekOfYear(DateTimeReference,
        CalendarWeekRule.FirstFullWeek, DayOfWeek.Monday);
        return weekNum;
    }
Mnyikka
  • 1,223
  • 17
  • 12
0

If you need the combination of calendar week and year (e.g. "1/22" for calender week 1 in 2022) be aware that the year component is not always equal to the year of the input date. This is because the first days of a year belong to the last calendar week of the previous year if at least 4 days of the week belong to last year. Accordingly the last days of a year belong to the first calendar week of the next year if at least 4 days of the week belong to next year.

Here is an extension for that based on the extension provided in the answer by @Jogge

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();
    }
}
René
  • 3,413
  • 2
  • 20
  • 34
-1

A year has 52 weeks and 1 day or 2 in case of a lap year (52 x 7 = 364). 2012-12-31 would be week 53, a week that would only have 2 days because 2012 is a lap year.

CarlosJ
  • 244
  • 3
  • 13
  • 1
    This is incorrect. The first day of the week of the year may fall on any day of the week, depending on how you count the weeks, the year may have a 54th week. – krowe2 Jul 17 '18 at 20:22
-1
public int GetWeekNumber()
{
   CultureInfo ciCurr = CultureInfo.CurrentCulture;
   int weekNum = ciCurr.Calendar.GetWeekOfYear(DateTime.Now, 
   CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
   return weekNum;
}
Meghnath Das
  • 145
  • 1
  • 6