Click here to Skip to main content
Licence 
First Posted 8 Aug 2002
Views 140,459
Bookmarked 29 times

Gregorian Date To ISO Date Converter

By | 8 Aug 2002 | Article
An article on converting Gregorian calendar date to ISO 8601 calendar date

Introduction

In .NET the DateTime class is implemented using Gregorian calendar. Sometimes, we need to extend the capabilities of this DateClass class. For example, if we wanted to know the ISO 8601 week number of the year, we need to create a new class for this implementation, as we can't extend the DateTime class. The following class DateEx written in C# is used to convert a date from Gregorian Calendar to ISO formatted date.

ISO-8601 defines the week as starting with Monday and ending with Sunday, i.e., Monday is weekday 1 and Sunday is weekday 7. The first week of a year is the week, which contains the first Thursday of the Gregorian year; and the week containing January 4th. Week numbers in ISO 8601 are integers from 1 to 52 or 53; parts of week 1 may be in the previous calendar year; parts of week 52 may be in the following calendar year; and if a year has a week 53, parts of it must be in the following calendar year. The correct way to represent a week in ISO 8601 format is YYYY-WW.

For example, in the year 2002, the ISO week 1 began on Monday December 31st, 2001; and the last ISO week (week 53) ended on Sunday January 2nd, 2003. Therefore, December 31st, 2001, is in the ISO week 2002-01; and January 2nd, 2003, is in the ISO week 2002-53.

Following is the code for DateEx. It contains four static functions; ISOWeekNumber, WeekDay, IsLeapYear, DisplayISODate.

// DateEx.cs 
using System;

public class DateEx {
    
    // Static Method to check Leap Year
    public static bool IsLeapYear(int yyyy) {
        
        if ((yyyy % 4 == 0 && yyyy % 100 != 0) || (yyyy % 400 == 0))
            return true;
        else
            return false;
    }    


    // Static Method to return ISO WeekNumber (1-53) for a given year
    public static int ISOWeekNumber(DateTime dt) {
        
        // Set Year
        int yyyy=dt.Year;

        // Set Month
        int mm=dt.Month;
        
        // Set Day
        int dd=dt.Day;

        // Declare other required variables
        int DayOfYearNumber;
        int Jan1WeekDay;
        int WeekNumber=0, WeekDay;

    
        int i,j,k,l,m,n;
        int[] Mnth = new int[12] {0,31,59,90,120,151,181,212,243,273,304,334};

        int YearNumber;

        
        // Set DayofYear Number for yyyy mm dd
        DayOfYearNumber = dd + Mnth[mm-1];

        // Increase of Dayof Year Number by 1, if year is leapyear and month is february
        if ((IsLeapYear(yyyy) == true) && (mm == 2))
            DayOfYearNumber += 1;

        // Find the Jan1WeekDay for year 
        i = (yyyy - 1) % 100;
        j = (yyyy - 1) - i;
        k = i + i/4;
        Jan1WeekDay = 1 + (((((j / 100) % 4) * 5) + k) % 7);

        // Calcuate the WeekDay for the given date
        l= DayOfYearNumber + (Jan1WeekDay - 1);
        WeekDay = 1 + ((l - 1) % 7);

        // Find if the date falls in YearNumber set WeekNumber to 52 or 53
        if ((DayOfYearNumber <= (8 - Jan1WeekDay)) && (Jan1WeekDay > 4))
          {
            YearNumber = yyyy - 1;
            if ((Jan1WeekDay == 5) || ((Jan1WeekDay == 6) && (Jan1WeekDay > 4)))
                WeekNumber = 53;
            else
                WeekNumber = 52;
          }
        else
            YearNumber = yyyy;
        

        // Set WeekNumber to 1 to 53 if date falls in YearNumber
        if (YearNumber == yyyy)
          {
            if (IsLeapYear(yyyy)==true)
                m = 366;
            else
                m = 365;
            if ((m - DayOfYearNumber) < (4-WeekDay))
            {
                YearNumber = yyyy + 1;
                WeekNumber = 1;
            }
          }
        
        if (YearNumber==yyyy) {
            n=DayOfYearNumber + (7 - WeekDay) + (Jan1WeekDay -1);
            WeekNumber = n / 7;
            if (Jan1WeekDay > 4)
                WeekNumber -= 1;
        }

        return (WeekNumber);
    }


    // Static Method to Calculate WeekDay (Monday=1...Sunday=7)
    public static int WeekDay(DateTime dt) {

        // Set Year
        int yyyy=dt.Year;

        // Set Month
        int mm=dt.Month;
        
        // Set Day
        int dd=dt.Day;

        // Declare other required variables
        int DayOfYearNumber;
        int Jan1WeekDay;
        int WeekDay;


        int i,j,k,l;
        int[] Mnth = new int[12] {0,31,59,90,120,151,181,212,243,273,304,334};


        // Set DayofYear Number for yyyy mm dd
        DayOfYearNumber = dd + Mnth[mm-1];

        // Increase of Dayof Year Number by 1, if year is leapyear and month is february
        if ((IsLeapYear(yyyy) == true) && (mm == 2))
            DayOfYearNumber += 1;

        // Find the Jan1WeekDay for year 
        i = (yyyy - 1) % 100;
        j = (yyyy - 1) - i;
        k = i + i/4;
        Jan1WeekDay = 1 + (((((j / 100) % 4) * 5) + k) % 7);

        // Calcuate the WeekDay for the given date
        l= DayOfYearNumber + (Jan1WeekDay - 1);
        WeekDay = 1 + ((l - 1) % 7);

        return WeekDay;
    }


    // Static Method to Display date in ISO Format (Year - WeekNumber - WeekDay)
    public static string DisplayISODate(DateTime dt) {
        string str;
        int year,weekday,weeknumber;
        
        year=dt.Year;
        weeknumber = ISOWeek(dt);
        weekday = WeekDay(dt);

        str = year.ToString("d0") + "-" + weeknumber.ToString("d0")
                                  + "-" + weekday.ToString("d0");
        return str;
    }

}

Now converting Gregorian Date to ISO Date is very easy.

using System;
using System.Globalization; 

public class DateImpl {
    
    public static void Main() {
        try {
            DateTime dt=new DateTime(2002,12,1);

            Console.WriteLine("Gregorian Date : {0}",
                  dt.ToString("d", DateTimeFormatInfo.InvariantInfo));

            Console.WriteLine("ISO Date : {0}",DateEx.DisplayISODate(dt));
        }
        catch(Exception e) {
            Console.WriteLine("Error \n\n {0}", e.ToString());
        }
    }
}

This class can be easily extended to handle needs for other calendars such as Julian, Indian Civil Calendar etc.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Siva Ram Mateti



United States United States

Member



Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralThis feature is already implemented PinmemberFrancisko6:26 6 Mar '07  
Hi,
 
This is a very good practice, but you can do the same thing with System.Globalization.Calendar plus a great deal of features... please take a look because is really awesome.
 
Bye!
 
http://msdn2.microsoft.com/en-us/library/system.globalization.calendar.getweekofyear.aspx
 
Francisco Trigo Martínez
 
MCAD

GeneralRe: This feature is already implemented PinmemberdvptUml3:22 27 Sep '09  
QuestionWhy not use the .Net Framework? PinmemberMattias Olgerfelt5:41 27 Sep '04  
AnswerRe: Why not use the .Net Framework? PinmemberdvptUml3:20 27 Sep '09  
GeneralJan1WeekDay PinsussAnonymous10:39 25 Aug '04  
GeneralA better implementation PinmemberJulian Bucknall [MSFT]17:41 20 Aug '03  
GeneralErroneous weekdays PinsussAnonymous5:17 15 May '03  
GeneralAbove has bugs!!! Pinmemberjbkosman5:56 26 Mar '03  
Generaljust a thought PinsussAnonymous11:24 23 Jan '03  
GeneralYou can't extend DateTime but... PineditorJames T. Johnson17:21 9 Aug '02  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web01 | 2.5.120529.1 | Last Updated 9 Aug 2002
Article Copyright 2002 by Siva Ram Mateti
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid