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);
}
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.
C# to Powershell port from code above from il_guru:
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.
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.
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.
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.
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.
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.
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:
You can find the source code here.