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 its all 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
|
PersianDate(string) |
Initializes a new instance of the PersianDate to a specified a Persian date string. for example: "1391/2/15" |
PersianDate(DateTime) |
Initializes a new instance of the PersianDate to a specified a System.DateTime date. |
PersianDate(int,int,int) |
Initializes a new instance of the PersianDate to a specified year, month and day. |
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
Methods
(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():
private void SetDateTime()
{
if (this.Day == 0 || this.Month == 0 || this.Year == 0) 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'));
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:
PersianDate date = new PersianDate();
date.Year = 1392;
date.day = 1;
Then (s)he leaves it and wants to compelete the PersianDate defining in anohter 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)

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:
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:
public PersianDate(DateTime dateTime)
{
this.FormalDateTime = dateTime;}
While initializing FormalDateTime property:
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");
int year = persianCalendar.GetYear(_formalDateTime); int month = persianCalendar.GetMonth(_formalDateTime); int day = persianCalendar.GetDayOfMonth(_formalDateTime);
if (this.Year != year || this.Month != month || this.Day != day) {
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 any need to initialize the properties.
After changing whichever Day, Month and Year; then SetDateTime() will be called. For example:
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.

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.