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

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

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.47/5 (15投票s)

2007 年 9 月 24 日

CPOL

3分钟阅读

viewsIcon

61225

downloadIcon

1250

本文介绍了CJalaliCalendar类,该类可用于处理伊朗Jalali(Shamsi)日历。

Screenshot - JalaliCalendar.jpg

引言

本文献给所有程序员,特别是那些希望在应用程序中使用Jalali日历的伊朗程序员。我设计了CJalaliCalendar类,您可以通过它获取当前的Jalali日期,确定两个日期之间的时间间隔,获取星期几的名称,等等。

有了提供的类,就不需要处理公历和Jalali日历的闰年问题。这里考虑了两种日历所有当前采用的方法。

我尝试在这个类中添加与Jalali日历相关的任何必要功能,希望这对您有所帮助。

背景

让我告诉您一些关于Jalali和公历日历的事实。您可能知道,地球绕太阳运行需要365.2421898天(非整数值)。我们应该考虑到这一点。公历和Jalali日历对此问题有不同的解决方案。

根据Chris Maunder和LeRoy Baxter撰写的文章《Leap Years》,公历的规则是

  1. 大多数能被4整除的年份闰年(例如1996年是)。
  2. 但是,大多数能被100整除的年份不是!(1900年不是)。
  3. 除非它们也能被400整除(2000年将是)。

提供的类适用于1900年以上的年份。对于1900年以下的年份,我的代码会产生意外的结果。

对于Jalali日历,我们可以说以下陈述

  1. Jalali日历是周期为33年的周期性日历。每个周期从年份33k + 23(即1376)开始。
  2. 每个周期的前28年是七个4年子周期,每个子周期的第四年是闰年。
  3. 周期的最后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日:首次发布
Jalali (Shamsi) 日历类,简单实用 - CodeProject - 代码之家
© . All rights reserved.