There certainly is a direct method in .NET to obtain the ISO week number. However, it is buggy, as ISO week numbering has been from VB 3.0 and Access Basic (of Access 1.0) through VBA of Office 2016, and not resolved in .NET. Fortunately, a tiny test for week 53 will get it right.
Improvement of the Original Tip
This method is as close to the default method of the framework as possible. While other perfectly valid methods exist, the method in the original tip builds on the native methods, but it fails when it comes to the ISO 8601 week numbering where week numbers cannot overlap.
For some reason, that is not clear, Microsoft has never – and that is since Visual Basic and Access Basic (of Access 1.x and 2.0) – followed the ISO 8601 method completely even though the method with the label “FirstFourDays
” indicates this.
My alternative respects the original tip as well as the framework while correcting the incompleteness of it.
Check for Week Number 1
To get the correct ISO 8601 week number of any date, check if a week 53 is followed by a week 1. If the result is 2, the week number is not 53, but 1. Very simple and clear:
using System;
using System.Globalization;
namespace DateTimeExtension
{
public static class DateTimeExtensionMethods
{
private static int _daysInWeek = 7;
private static int _minIso8601WeekNumber = 1;
private static int _maxIso8601WeekNumber = 53;
#region WeekIso8601
public static int WeekIso8601(this DateTime currentDate)
{
CultureInfo cultureInfo = CultureInfo.InvariantCulture;
Calendar calendar = cultureInfo.Calendar;
CalendarWeekRule calenderWeekRule = CalendarWeekRule.FirstFourDayWeek;
DayOfWeek firstDayOfWeek = DayOfWeek.Monday;
int weekNumber = calendar.GetWeekOfYear
(currentDate, calenderWeekRule, firstDayOfWeek);
if (weekNumber.Equals(_maxIso8601WeekNumber))
{
int weekNumberNext = calendar.GetWeekOfYear
(currentDate.AddWeeks(1), calenderWeekRule, firstDayOfWeek);
if (!weekNumberNext.Equals(_minIso8601WeekNumber))
{
weekNumber = _minIso8601WeekNumber;
}
}
return weekNumber;
}
#endregion
}
}
Why Do It This Way?
That is partly to demonstrate that the native method is incomplete if you expect it to return true ISO 8601 week numbers, partly to demonstrate that you don’t have to reinvent the wheel by creating other methods that are more difficult to comprehend.
Also, this method builds on the Globalization objects which you already may be familiar with and – very likely – will use or reuse in other parts of your code when you deal with international week numbers.
Considerations
It is still difficult to collect information on many international matters including week numbering. The ISO organization, for example, doesn’t provide its standards for free, thus you either have to pay or to consult third party sources to find out. And - in this specific case - Microsoft delivers a method with a trap that you don’t see except if you read about it - or get caught.
History
- 19th July, 2011: Initial version