Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / XML

PersianDate Library that Returns Value and Converts System.DateTime

4.61/5 (13 votes)
5 May 2012CPOL5 min read 45.6K   2.6K  
This is an alternative for Get Full Shamsi Date in String Format with C# Class

Introduction

Solar Hijri or Modern Persian Calendar has been adopted on 1925 (A.D) or 1304 (S.H) in Iran. The calendar year begins at the start of spring in the northern hemisphere. It has 4 seasons, 12 months and 365 days (except an extra day every 4 years at the last month of the year, that It called leap or "کبیسه")

This is an alternative for "Get Full Shamsi Date in String Format with C# Class".

In this alternative, I'm going to introduce an approach to use System.Globalization.PersianCalendar easily.

After this article, we will be able to:

  • Create or have a PersianDate class like System.DateTime
  • Identify all its features and use the created class in our program
  • Convert System.DateTime to PersianDate and vice versa

Background

I liked to write this alternative in Persian, because most developers who use Persian calendar are Persian; but it's an English site; implicitly, all .NET developers have to understand English because they are using high-technologies.

Class Introduction

I know it's extendable in future, although I tried to contrive most necessary common features.

Here you are:

Constructors

Name

Description

Public method PersianDate(string) Initializes a new instance of the PersianDate to a specified a Persian date string. for example: "1391/2/15"
Public method PersianDate(DateTime) Initializes a new instance of the PersianDate to a specified a System.DateTime date.
Public method PersianDate(int,int,int) Initializes a new instance of the PersianDate to a specified year, month and day.
Public method PersianDate(int,int,int,int,int,int,int) Initializes a new instance of the PersianDate to a specified year, month, day, hour, minute, second and millisecond.

Properties

Name

Description

Public property DayOfWeek

Gets the native name of the day of the year of the PersianDate. For example: "shambih" (means "Saturday")

Public property DateString Gets the value of PersianDate as string. For example: "1391/02/15"
Public property FormalDateTime Gets or sets a System.DateTime from or to PersianDate
Public property IsLeapYear Gets a value indicating whether the year of the PersianDate is leap.
Public property Static member MaxValue

Gets the maximum value (a PersianDate object) of a PersianDate.
It's 9378/10/10

Public property Static member MinValue Gets the minimum value (a PersianDate object) of a PersianDate.
It's 01/01/01
Public property Month

Gets or sets the month of the year of the PersianDate. It is int that is greater than 0 and less than 13.

Public property MonthString

Gets the native name of the month of the PersianDate. For example: "ordibehesht"

Public property Static member Now Gets a PersianDate object that is set to the current date and time on this computer, expressed as the local time.
Public property Year Gets or sets the year of the PersianDate. The type is int that is greater than 0 and less than 9379

Methods

Name

Description

Public method AddDays Returns a new PersianDate that adds the specified number of days to the value of this instance.
Public method AddHours Returns a new PersianDate that adds the specified number of hours to the value of this instance.
Public method AddMilliseconds Returns a new PersianDate that adds the specified number of milliseconds to the value of this instance.
Public method AddMinutes Returns a new PersianDate that adds the specified number of minutes to the value of this instance.
Public method AddMonths Returns a new PersianDate that adds the specified number of months to the value of this instance.
Public method AddSeconds Returns a new PersianDate that adds the specified number of seconds to the value of this instance.
Public method AddYears Returns a new PersianDate that adds the specified number of years to the value of this instance.
Public method AddWeeks Returns a new PersianDate that adds the specified number of weeks to the value of this instance.
Public method Clone Copy a PersianDate object and returns completely a new instance with new reference types.
Public method Static member Compare Compares two instances of PersianDate and returns an integer that indicates whether the first instance is earlier than, the same as, or later than the second instance.
Public method CompareTo Compares the value of this instance to a specified PersianDate value and returns an integer that indicates whether this instance is earlier than, the same as, or later than the specified PersianDate value.
Public method Static member Convert Converts a System.DateTime to a PersianDate. It returns a new PersianDate.
Public method Static member ToDate Coverts a PersianDate to a System.DateTime. It returns a new System.DateTime.

(Thanks to MSDN, I uesd it as a model.)

Using the Code

If you like to completely find the program logic out, you can download the source code and trace it. But I'm going to issue a brief description here about some important parts of the class.

The main and most critical part of the class is a private method named SetDateTime():

C#
private void SetDateTime()
{
   if (this.Day == 0 || this.Month == 0 || this.Year == 0)//Explained in the content
      return;

   this.DateString = string.Format("{0}/{1}/{2}", this.Year.ToString().PadLeft(3, '0'), 
                     this.Month.ToString().PadLeft(2, '0'), this.Day.ToString().PadLeft(2, '0'));

   //persianCalendar is a field and an instance of System.Globalization.PersianCalendar
   this.FormalDateTime = persianCalendar.ToDateTime(this.Year, this.Month, this.Day, this.Hour, 
                                                     this.Minute, this.Second, this.Millisecond);
   this.MonthString = months[this.Month - 1];
   this.DayOfWeek = weeks[(int)(this.FormalDateTime.DayOfWeek)];
}

Why If Day = 0 Or Month = 0 Or Year = 0 Then Exit the Method?

Because if you want to define a new PersianDate, for example:

Imagine a developer types this code:

C#
//Developer types
PersianDate date = new PersianDate();
date.Year = 1392;
date.day = 1;

Then (s)he leaves it and wants to complete the PersianDate defining in another part of the program. The condition prevents the compiler from a runtime exception.

Ok, the rest of SetDateTime(), go ahead?!

DateString, FormalDateTime, MonthString and DayOfWeek are introduced before, just weeks[] and months[] are two private fields.weeks[] contains seven native week names. and months[] contains twelve native month names. (Sorry about the picture. I still have problem with unicode.)

Image 34

I commented in the code, about System.Globalization.PersianCalendar. It represents the Persian calendar (refer to MSDN) and has many good features to convert System.DateTime to Persian calendar and vice versa; and I've been using it very much while creating PersianDate; but it doesn't return a PersianCalendar object; and it's not like System.DateTime. For example, if you want to convert date to Persian, then you need:

C#
PersianCalendar persian = new PersianCalendar();
int year = persian.GetYear(date);
int month = persian.GetMonth(date);
int day = persian.GetDayOfMonth(date);

Constructor and Initializing Properties

I describe PersianDate(DateTime dateTime) as a sample:

C#
public PersianDate(DateTime dateTime)
{
   this.FormalDateTime = dateTime;// clear
}

While initializing FormalDateTime property:

C#
private DateTime _formalDateTime;
public DateTime FormalDateTime
{
   get
   {
      return _formalDateTime;
   }
   set
   {
      _formalDateTime = value;

      if(_formalDateTime < persianCalendar.MinSupportedDateTime 
                       || _formalDateTime>persianCalendar.MaxSupportedDateTime)
          throw new Exception("Date can not be less that 01-01-622");//validates the date

      int year = persianCalendar.GetYear(_formalDateTime);//Local var
      int month = persianCalendar.GetMonth(_formalDateTime);//Local
      int day = persianCalendar.GetDayOfMonth(_formalDateTime);//Local

      if (this.Year != year || this.Month != month || this.Day != day)//Checks for any difference
      {
         this.Year = year;
         this.Month = month;
         this.Day = day;
      }
   }
}

I've given an account of PersianCalander, and now, year, month and day are local variables, If they are different from Year, Month and Day (the properties), then it will be initialized; otherwise it won't have any need to initialize the properties.

After changing whichever Day, Month and Year; then SetDateTime() will be called. For example:

C#
private int _year;
public int Year
{
   get { return _year; }
   set
   {
      _year = value;

      SetDateTime();
   }
}

And you know what SetDateTime() is for?!

I suggest and insist that you download the source code and the demo and use the library in your application. 

Demo

Conclusion

Please help. If there is any problem in the article and if you have any better idea; your reminding will help me to improve the article.

Thank you!

License

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