返回数值和转换 System.DateTime 的波斯日期库






4.61/5 (13投票s)
这是“使用 C# 类以字符串格式获取完整的 Shamsi 日期”
引言
太阳历(Solar Hijri)或现代波斯历于 1925 年(公元)或 1304 年(太阳历)在伊朗采用。历年从北半球春季开始。它有 4 个季节,12 个月,365 天(除了每 4 年在最后一月增加一天,称为闰月或“کبیسه”)。
这是对“使用 C# 类获取字符串格式的完整 Shamsi 日期”的替代方案。
在此替代方案中,我将介绍一种轻松使用 System.Globalization.PersianCalendar
的方法。
在本文之后,我们将能够
- 创建一个类似于
System.DateTime
的PersianDate
类 - 识别其所有功能并在我们的程序中使用创建的类
- 转换
System.DateTime
到PersianDate
,反之亦然
背景
我想用波斯语写这个替代方案,因为大多数使用波斯历的开发者都是波斯人;但这是一个英文网站;隐式地,所有 .NET 开发者都必须理解英语,因为他们正在使用高科技。
类介绍
我知道它将来可以扩展,尽管我尝试了构思大多数必要和常见的特性。
这是
构造函数
名称 | 描述 |
![]() PersianDate(string) | 初始化一个新的 PersianDate 实例,该实例设置为指定的波斯日期字符串。例如:“1391/2/15” |
![]() PersianDate(DateTime) | 初始化一个新的 PersianDate 实例,该实例设置为指定的 System.DateTime 日期。 |
![]() PersianDate(int,int,int) | 初始化一个新的 PersianDate 实例,该实例设置为指定的年、月和日。 |
![]() PersianDate(int,int,int,int,int,int,int) | 初始化一个新的 PersianDate 实例,该实例设置为指定的年、月、日、时、分、秒和毫秒。 |
属性
名称 | 描述 |
![]() DayOfWeek | 获取 |
![]() DateString | 以 string 格式获取 PersianDate 的值。例如:“1391/02/15 ” |
![]() FormalDateTime | 获取或设置一个 System.DateTime ,用于与 PersianDate 相互转换。 |
![]() IsLeapYear | 获取一个值,该值指示 PersianDate 的年份是否为闰年。 |
![]() ![]() MaxValue | 获取 |
![]() ![]() MinValue | 获取 PersianDate 的最小值(一个 PersianDate 对象)。它是 01/01/01 |
![]() Month | 获取或设置 |
![]() MonthString | 获取 |
![]() ![]() Now | 获取一个 PersianDate 对象,该对象设置为此计算机上的当前日期和时间,表示为本地时间。 |
![]() Year | 获取或设置 PersianDate 的年份。类型是大于 0 且小于 9379 的 int 。 |
方法
名称 | 描述 |
![]() AddDays | 返回一个新的 PersianDate ,该日期将指定的日数添加到此实例的值中。 |
![]() AddHours | 返回一个新的 PersianDate ,该日期将指定的小时数添加到此实例的值中。 |
![]() AddMilliseconds | 返回一个新的 PersianDate ,该日期将指定的毫秒数添加到此实例的值中。 |
![]() AddMinutes | 返回一个新的 PersianDate ,该日期将指定的分钟数添加到此实例的值中。 |
![]() AddMonths | 返回一个新的 PersianDate ,该日期将指定的月数添加到此实例的值中。 |
![]() AddSeconds | 返回一个新的 PersianDate ,该日期将指定的秒数添加到此实例的值中。 |
![]() AddYears | 返回一个新的 PersianDate ,该日期将指定的年数添加到此实例的值中。 |
![]() AddWeeks | 返回一个新的 PersianDate ,该日期将指定的周数添加到此实例的值中。 |
![]() Clone | 复制一个 PersianDate 对象,并返回一个完全新的实例,其中包含新的引用类型。 |
![]() ![]() Compare | 比较两个 PersianDate 实例,并返回一个整数,指示第一个实例是否早于、等于或晚于第二个实例。 |
![]() CompareTo | 比较此实例的值与指定的 PersianDate 值,并返回一个整数,指示此实例是早于、等于还是晚于指定的 PersianDate 值。 |
![]() ![]() Convert | 将 System.DateTime 转换为 PersianDate 。它返回一个新的 PersianDate 。 |
![]() ![]() ToDate | 将 PersianDate 转换为 System.DateTime 。它返回一个新的 System.DateTime 。 |
(感谢MSDN,我以它为模型。)
Using the Code
如果您想完全了解程序逻辑,可以下载源代码并进行跟踪。但我将在这里简要介绍该类的某些重要部分。
该类主要且最重要的部分是一个名为 SetDateTime()
的 private
方法。
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)];
}
为什么如果 Day = 0 或 Month = 0 或 Year = 0 则退出方法?
因为如果您想定义一个新的 PersianDate
,例如
设想一名开发人员输入了以下代码
//Developer types
PersianDate date = new PersianDate();
date.Year = 1392;
date.day = 1;
然后(他/她)离开并想在程序的另一部分完成 PersianDate
的定义。该条件可以防止编译器出现运行时异常。
好的,SetDateTime()
的其余部分,继续?!
DateString
、FormalDateTime
、MonthString
和 DayOfWeek
之前已经介绍过了,只有 weeks[]
和 months[]
是两个私有字段。weeks[]
包含七个星期的原生名称,months[]
包含十二个月的原生名称。(抱歉图片。我仍然在处理 Unicode 问题。)
我在代码中注释了关于 System.Globalization.PersianCalendar
的信息。它代表波斯历(参考 MSDN),并具有许多将 System.DateTime
转换为波斯历以及反之亦然的优秀功能;我在创建 PersianDate
时大量使用了它;但它不返回 PersianCalendar
对象;并且不像 System.DateTime
。例如,如果您想将 date
转换为波斯历,那么您需要
PersianCalendar persian = new PersianCalendar();
int year = persian.GetYear(date);
int month = persian.GetMonth(date);
int day = persian.GetDayOfMonth(date);
构造函数和初始化属性
我将 PersianDate(DateTime dateTime)
作为一个示例进行描述。
public PersianDate(DateTime dateTime)
{
this.FormalDateTime = dateTime;// clear
}
在初始化 FormalDateTime
属性时,
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;
}
}
}
我已经考虑了 PersianCalander
,现在 year
、month
和 day
是局部变量。如果它们与 Year
、Month
和 Day
(属性)不同,那么它将被初始化;否则,它将不需要初始化这些属性。
在更改任何 Day
、Month
和 Year
后;将调用 SetDateTime()
。例如
private int _year;
public int Year
{
get { return _year; }
set
{
_year = value;
SetDateTime();
}
}
您知道 SetDateTime()
的作用是什么吗?!
我建议并坚持您下载源代码和演示,并在您的应用程序中使用该库。
结论
请帮助。如果文章中有任何问题,如果您有任何更好的想法;您的提醒将帮助我改进文章。
谢谢!