This post originated from an RSS feed registered with .NET Buzz
by Peter van Ooijen.
Original Post: ISO weeknumbers of a date, a C# implementation
Feed Title: Peter's Gekko
Feed URL: /error.htm?aspxerrorpath=/blogs/peter.van.ooijen/rss.aspx
Feed Description: My weblog cotains tips tricks and opinions on ASP.NET, tablet PC's and tech in general.
The DateTime class in the .NET framework is very rich in methods for manipulating and computing dates. In my former language Delphi working with dates was no fun. All had to be done by manipulating strings but given the fact that nobody can agree on what comes first, day or month, all code was tricky and prone to bugs.
The only thing which is missing in the class is a weeknumber property. Every workweek has its own number. In Europe this is very often used. There is an ISO 8601 standard which describes how this number is calculated: Week 01 of a year is per definition the first week that has the Thursday in this year, which is equivalent to the week that contains the fourth day of January.
There are plenty of implementations to be found on the web to calculate this number. Finding a good one in C# took some assembling. This one is based on a Delphi implementation on the SDN site. Thanks to the DateTime class it needs only a fraction of the code.
privateint weekNumber(DateTime fromDate) { // Get jan 1st of the year DateTime startOfYear = fromDate.AddDays(- fromDate.Day + 1).AddMonths(- fromDate.Month +1); // Get dec 31st of the year DateTime endOfYear = startOfYear.AddYears(1).AddDays(-1); // ISO 8601 weeks start with Monday // The first week of a year includes the first Thursday // DayOfWeek returns 0 for sunday up to 6 for saterday int[] iso8601Correction = {6,7,8,9,10,4,5}; int nds = fromDate.Subtract(startOfYear).Days + iso8601Correction[(int)startOfYear.DayOfWeek]; int wk = nds / 7; switch(wk) { case 0 : // Return weeknumber of dec 31st of the previous year return weekNumber(startOfYear.AddDays(-1)); case 53 : // If dec 31st falls before thursday it is week 01 of next year if (endOfYear.DayOfWeek < DayOfWeek.Thursday) return 1; else return wk; default : return wk; } }
The nice thing I used from the Delphi sample was the iso8601 correction array using the day of the week as index.
It would be even nicer to add the method as a property to a derived DateTime class. Alas that class is sealed.