Jalali (Shamsi) 日历类,简单实用






3.47/5 (15投票s)
本文介绍了CJalaliCalendar类,该类可用于处理伊朗Jalali(Shamsi)日历。

引言
本文献给所有程序员,特别是那些希望在应用程序中使用Jalali日历的伊朗程序员。我设计了CJalaliCalendar类,您可以通过它获取当前的Jalali日期,确定两个日期之间的时间间隔,获取星期几的名称,等等。
有了提供的类,就不需要处理公历和Jalali日历的闰年问题。这里考虑了两种日历所有当前采用的方法。
我尝试在这个类中添加与Jalali日历相关的任何必要功能,希望这对您有所帮助。
背景
让我告诉您一些关于Jalali和公历日历的事实。您可能知道,地球绕太阳运行需要365.2421898天(非整数值)。我们应该考虑到这一点。公历和Jalali日历对此问题有不同的解决方案。
根据Chris Maunder和LeRoy Baxter撰写的文章《Leap Years》,公历的规则是
- 大多数能被4整除的年份是闰年(例如1996年是)。
- 但是,大多数能被100整除的年份不是!(1900年不是)。
- 除非它们也能被400整除(2000年将是)。
提供的类适用于1900年以上的年份。对于1900年以下的年份,我的代码会产生意外的结果。
对于Jalali日历,我们可以说以下陈述
- Jalali日历是周期为33年的周期性日历。每个周期从年份33k + 23(即1376)开始。
- 每个周期的前28年是七个4年子周期,每个子周期的第四年是闰年。
- 周期的最后5年由4个普通年份和一个第五个闰年组成。
上述Jalali日历的规则自1304年起采用。实际上,我编写的代码仅适用于Shamsi 1337年以上的年份。对于1337年以下的年份,将出现意外结果。
Using the Code
所有功能都包含在CJalaliCalendar类中。要使用该类,您需要将JalaliCalendar.cpp和JalaliCalendar.h添加到您的项目中。
这是类的声明
class CJalaliCalendar
{
public:
void GetJalaliDate(int *Year, int *Month, int *Day, int *DayOfWeek = NULL,
TCHAR *DayName = NULL, TCHAR *MonthName = NULL);
void GregorianToJalali(int GYear, int GMonth, int GDay, int *JYear, int *JMonth,
int *JDay, int *JDayOfWeek = NULL, TCHAR *JDayName =
NULL, TCHAR *JMonthName = NULL);
void JalaliToGregorian(int JYear, int JMonth, int JDay, int *GYear, int *GMonth,
int *GDay, int *GDayOfWeek = NULL, TCHAR *GDayName =
NULL, TCHAR *GMonthName = NULL);
void GetJalaliDayOfWeek(int JYear, int JMonth, int JDay,
int *DayOfWeek, TCHAR *szDayName = NULL);
void GetGregorianDayOfWeek(int GYear, int GMonth, int GDay,
int *DayOfWeek, TCHAR *szDayName = NULL);
int GetGregorianDayDifference(int GYear1, int GMonth1, int GDay1,
int GYear2, int GMonth2, int GDay2);
int GetJalaliDayDifference(int JYear1, int JMonth1, int JDay1,
int JYear2, int JMonth2, int JDay2);
void GetJalaliDateWithOffset(int JYear, int JMonth, int JDay, int Offset, int *Year,
int *Month, int *Day, int *DayOfWeek =
NULL, TCHAR *DayName = NULL, TCHAR *MonthName = NULL);
void GetGregorianDateWithOffset(int GYear, int GMonth,
int GDay, int Offset, int *Year,
int *Month, int *Day, int *DayOfWeek =
NULL, TCHAR *DayName = NULL, TCHAR *MonthName = NULL);
const TCHAR *szJalaliDays[7], *szJalaliMonths[12];
const TCHAR *szGregorianDays[7], *szGregorianMonths[12];
private:
int GetGregorianOffset(int GYear, int GMonth, int GDay);
int GetJalaliOffset(int JYear, int JMonth, int JDay);
};
在每个方法中,参数的J和G前缀表示参数是Jalali日期变量还是Gregorian日期变量。请确保系统时间和日期正确。
GetJalaliDate计算当前的Jalali日期,并提供年份、月份、日期、星期几、星期几的名称和月份的名称(均以波斯语显示)。
JalaliToGregorian和GregorianToJalali在两种日历类型之间转换日期格式。
GetJalaliDayOfWeek和GetGregorianDayOfWeek给出指定日期的英文/波斯语星期几名称。
GetGregorianDayDifference和GetJalaliDayDifference返回两个日期之间的时间差(以天为单位)。
GetJalaliDateWithOffset和GetGregorianDateWithOffset计算指定日期之前/之后的日期。偏移量在Offset参数中,可以是正数或负数。
变量szJalaliDays、szJalaliMonths、szGregorianDays和szGregorianMonths包含两种日历类型的日期和月份名称,这可能对您很有用。
关注点
我的目标是设计一个CJalaliMonthCalCtrl类,类似于MFC提供的CMonthCalCtrl类。本文是实现该目标的第一步!
历史
- 2007年9月24日:首次发布