65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.61/5 (13投票s)

2012年5月4日

CPOL

5分钟阅读

viewsIcon

46252

downloadIcon

2623

这是“使用 C# 类以字符串格式获取完整的 Shamsi 日期”的替代方案

引言

太阳历(Solar Hijri)或现代波斯历于 1925 年(公元)或 1304 年(太阳历)在伊朗采用。历年从北半球春季开始。它有 4 个季节,12 个月,365 天(除了每 4 年在最后一月增加一天,称为闰月或“کبیسه”)。

这是对“使用 C# 类获取字符串格式的完整 Shamsi 日期”的替代方案。

在此替代方案中,我将介绍一种轻松使用 System.Globalization.PersianCalendar 的方法。

在本文之后,我们将能够

  • 创建一个类似于 System.DateTimePersianDate
  • 识别其所有功能并在我们的程序中使用创建的类
  • 转换 System.DateTimePersianDate,反之亦然

背景

我想用波斯语写这个替代方案,因为大多数使用波斯历的开发者都是波斯人;但这是一个英文网站;隐式地,所有 .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

获取 PersianDate 一年中的星期几的原生名称。例如:“shambih”(意为“周六”)

公共属性 DateString string 格式获取 PersianDate 的值。例如:“1391/02/15
公共属性 FormalDateTime 获取或设置一个 System.DateTime,用于与 PersianDate 相互转换。
公共属性 IsLeapYear 获取一个值,该值指示 PersianDate 的年份是否为闰年。
公共属性 静态成员 MaxValue

获取 PersianDate 的最大值(一个 PersianDate 对象)。
它是 9378/10/10

公共属性 静态成员 MinValue 获取 PersianDate 的最小值(一个 PersianDate 对象)。
它是 01/01/01
公共属性 Month

获取或设置 PersianDate 的月份。它是一个大于 0 且小于 13int

公共属性 MonthString

获取 PersianDate 的月份的原生名称。例如:“ordibehesht

公共属性 静态成员 Now 获取一个 PersianDate 对象,该对象设置为此计算机上的当前日期和时间,表示为本地时间。
公共属性 Year 获取或设置 PersianDate 的年份。类型是大于 0 且小于 9379int

方法

名称

描述

公共方法 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() 的其余部分,继续?!

DateStringFormalDateTimeMonthStringDayOfWeek 之前已经介绍过了,只有 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,现在 yearmonthday 是局部变量。如果它们与 YearMonthDay(属性)不同,那么它将被初始化;否则,它将不需要初始化这些属性。

在更改任何 DayMonthYear 后;将调用 SetDateTime()。例如

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

      SetDateTime();
   }
}

您知道 SetDateTime() 的作用是什么吗?!

我建议并坚持您下载源代码和演示,并在您的应用程序中使用该库。

Demo

结论

请帮助。如果文章中有任何问题,如果您有任何更好的想法;您的提醒将帮助我改进文章。

谢谢!

© . All rights reserved.