Amberlamps - 6 months ago 56

ASP.NET (C#) Question

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;

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

}

Answer

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