Click here to Skip to main content
15,889,810 members
Articles / Programming Languages / C#
Tip/Trick

ISO Week Number by Date, Date by ISO Week Number

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
17 Jan 2012CPOL 27.1K   3  
ISO Week
ISO Week Number by Date and Date of first day of week by ISO Week Number.

I v seen a code I took as a base in several locations: source 1, source 2. I have no idea who is primary - I post them both.

Class implements interesting functionality:
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;

namespace ValidationLog
{
    class DateUtils
    {

        public static DateTime FirstDateOfWeek(string week_format_1)
        {
            Int32 week_key = 0;
            if (week_format_1.Trim().Length != 6 || !Int32.TryParse(week_format_1, out week_key))
            {
                throw new ArgumentException(String.Format("'{0}' is invalid week format",week_format_1));
            }

            int year = week_key / 100;
            int weekOfYear = week_key % 100;

            return FirstDateOfWeek(year,weekOfYear);
        }

        public static string WeekId(DateTime date)
        {
            int wk = 0;
            int year = 0;

            DateUtils.GetWeekNumber(date, out year, out wk);

            return String.Format("{0}_{1:00}", year, wk);
        }

        /// <summary>
        /// Returns date of first day of week
        /// </summary>
        /// <param name="year">week year</param>
        /// <param name="weekOfYear">week number</param>
        /// <seealso cref="http://stackoverflow.com/questions/662379/calculate-date-from-week-number"/>
        /// <returns>date</returns>
        public static DateTime FirstDateOfWeek(int year, int weekOfYear)
        {
            DateTime jan1 = new DateTime(year, 1, 1);

            int daysOffset = (int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek - (int)jan1.DayOfWeek;

            DateTime firstMonday = jan1.AddDays(daysOffset);

            //get first week by ISO
            int firstWeek = CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(jan1, CultureInfo.InvariantCulture.DateTimeFormat.CalendarWeekRule, CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek);

            if (firstWeek <= 1)
            {
                weekOfYear -= 1;
            }

            return firstMonday.AddDays(weekOfYear * 7);
        }

        /// <summary>
        /// Calculates ISO week and year number (ISO year can differ from calendar year)
        /// </summary>
        /// <param name="date">date</param>
        /// <param name="year">ISO year</param>
        /// <param name="wk">ISO week</param>
        /// <seealso cref="http://codebetter.com/petervanooijen/2005/09/26/iso-weeknumbers-of-a-date-a-c-implementation/"/>
        public static void GetWeekNumber(DateTime date, out int year, out int wk)
        {
            year = date.Year;
            // Get jan 1st of the year
            DateTime startOfYear = new DateTime(year, 1, 1);
            // Get dec 31st of the year
            DateTime endOfYear = new DateTime(year, 12, 31);
            // 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 = date.Subtract(startOfYear).Days + iso8601Correction[(int)startOfYear.DayOfWeek];
            wk = nds / 7;
            switch (wk)
            {
                case 0:
                    // Return weeknumber of dec 31st of the previous year
                    GetWeekNumber(startOfYear.AddDays(-1), out year, out wk);
                    break;
                case 53:
                    // If dec 31st falls before thursday it is week 01 of next year
                    if (endOfYear.DayOfWeek < DayOfWeek.Thursday)
                    {
                        wk = 1; year += 1;
                    }
                    break;
                default:
                    break;
            }
        }



        /*
        public static DateTime FirstDateOfWeekCustom(int year, int weekOfYear)
        {
            return new DateTime(1999, 12, 31);
        }
        */
    }
}


Code usage:
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using ValidationLog;


namespace ConsoleApplication2010Lab
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime endDate = new DateTime(2013,1,8);
            DateTime startDate = new DateTime(2010,12,27);

            for (DateTime date = startDate; date < endDate; date = date.AddDays(7))
            {
                Console.WriteLine("{0} - {1}", DateUtils.WeekId(date), date);
            }

            Console.ReadLine();
        }
    }
}


Thanks for reading

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Database Developer Freelancer
Ukraine Ukraine
MS SQL Server Database Developer with 7+ years experience

Technologies/languages: Business Intelligence, SQL, MDX, VBA, SQL Server, Analysis Services (SSAS), Reporting services (SSRS), Integration Services (SSIS), DataWarehouse.
Also: economic background.

Feel free to contact me for rates and details.

Comments and Discussions

 
-- There are no messages in this forum --