Explorar o código

公历农历转换库

Jeff %!s(int64=6) %!d(string=hai) anos
pai
achega
3702353822

+ 26 - 0
LunarCalendar/LunarCalendar.sln

@@ -0,0 +1,26 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LunarCalendar", "LunarCalendar\LunarCalendar.vcproj", "{BA863651-B0FE-44EA-97E0-11825249735B}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Test", "Test\Test.vcproj", "{5EEA4E51-051A-4A63-B780-62A5997A74D6}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{BA863651-B0FE-44EA-97E0-11825249735B}.Debug|Win32.ActiveCfg = Debug|Win32
+		{BA863651-B0FE-44EA-97E0-11825249735B}.Debug|Win32.Build.0 = Debug|Win32
+		{BA863651-B0FE-44EA-97E0-11825249735B}.Release|Win32.ActiveCfg = Release|Win32
+		{BA863651-B0FE-44EA-97E0-11825249735B}.Release|Win32.Build.0 = Release|Win32
+		{5EEA4E51-051A-4A63-B780-62A5997A74D6}.Debug|Win32.ActiveCfg = Debug|Win32
+		{5EEA4E51-051A-4A63-B780-62A5997A74D6}.Debug|Win32.Build.0 = Debug|Win32
+		{5EEA4E51-051A-4A63-B780-62A5997A74D6}.Release|Win32.ActiveCfg = Release|Win32
+		{5EEA4E51-051A-4A63-B780-62A5997A74D6}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal

+ 65 - 0
LunarCalendar/LunarCalendar/Def.h

@@ -0,0 +1,65 @@
+#ifndef __DEF__
+#define __DEF__
+
+const int BEGIN_YEAR = 1901;
+const int NUMBER_YEAR = 199;
+
+CONST INT nNormalMonth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+CONST INT nLeapMonth[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+
+//为了提高效率,记录每月一日是一年中的第几天;
+const int NORMAL_YDAY[12] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
+//闰年的情况;
+const int LEAP_YDAY[12] = { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 };
+
+// 使用比特位记录每年的情况
+// 0~4 共5bit 春节日份
+// 5~6 共2bit 春节月份
+// 7~19 共13bit 13个月的大小月情况(如果无闰月,最后位无效),大月为1,小月为0
+// 20~23 共4bit 记录闰月的月份,如果没有闰月为0
+const unsigned int LUNAR_YEARS[199] =
+{
+	0x04AE53, 0x0A5748, 0x5526BD, 0x0D2650, 0x0D9544, 0x46AAB9, 0x056A4D, 0x09AD42, 0x24AEB6, 0x04AE4A, //1901-1910
+	0x6A4DBE, 0x0A4D52, 0x0D2546, 0x5D52BA, 0x0B544E, 0x0D6A43, 0x296D37, 0x095B4B, 0x749BC1, 0x049754, //1911-1920
+	0x0A4B48, 0x5B25BC, 0x06A550, 0x06D445, 0x4ADAB8, 0x02B64D, 0x095742, 0x2497B7, 0x04974A, 0x664B3E, //1921-1930
+	0x0D4A51, 0x0EA546, 0x56D4BA, 0x05AD4E, 0x02B644, 0x393738, 0x092E4B, 0x7C96BF, 0x0C9553, 0x0D4A48, //1931-1940
+	0x6DA53B, 0x0B554F, 0x056A45, 0x4AADB9, 0x025D4D, 0x092D42, 0x2C95B6, 0x0A954A, 0x7B4ABD, 0x06CA51, //1941-1950
+	0x0B5546, 0x555ABB, 0x04DA4E, 0x0A5B43, 0x352BB8, 0x052B4C, 0x8A953F, 0x0E9552, 0x06AA48, 0x7AD53C, //1951-1960
+	0x0AB54F, 0x04B645, 0x4A5739, 0x0A574D, 0x052642, 0x3E9335, 0x0D9549, 0x75AABE, 0x056A51, 0x096D46, //1961-1970
+	0x54AEBB, 0x04AD4F, 0x0A4D43, 0x4D26B7, 0x0D254B, 0x8D52BF, 0x0B5452, 0x0B6A47, 0x696D3C, 0x095B50, //1971-1980
+	0x049B45, 0x4A4BB9, 0x0A4B4D, 0xAB25C2, 0x06A554, 0x06D449, 0x6ADA3D, 0x0AB651, 0x093746, 0x5497BB, //1981-1990
+	0x04974F, 0x064B44, 0x36A537, 0x0EA54A, 0x86B2BF, 0x05AC53, 0x0AB647, 0x5936BC, 0x092E50, 0x0C9645, //1991-2000
+	0x4D4AB8, 0x0D4A4C, 0x0DA541, 0x25AAB6, 0x056A49, 0x7AADBD, 0x025D52, 0x092D47, 0x5C95BA, 0x0A954E, //2001-2010
+	0x0B4A43, 0x4B5537, 0x0AD54A, 0x955ABF, 0x04BA53, 0x0A5B48, 0x652BBC, 0x052B50, 0x0A9345, 0x474AB9, //2011-2020
+	0x06AA4C, 0x0AD541, 0x24DAB6, 0x04B64A, 0x69573D, 0x0A4E51, 0x0D2646, 0x5E933A, 0x0D534D, 0x05AA43, //2021-2030
+	0x36B537, 0x096D4B, 0xB4AEBF, 0x04AD53, 0x0A4D48, 0x6D25BC, 0x0D254F, 0x0D5244, 0x5DAA38, 0x0B5A4C, //2031-2040
+	0x056D41, 0x24ADB6, 0x049B4A, 0x7A4BBE, 0x0A4B51, 0x0AA546, 0x5B52BA, 0x06D24E, 0x0ADA42, 0x355B37, //2041-2050
+	0x09374B, 0x8497C1, 0x049753, 0x064B48, 0x66A53C, 0x0EA54F, 0x06B244, 0x4AB638, 0x0AAE4C, 0x092E42, //2051-2060
+	0x3C9735, 0x0C9649, 0x7D4ABD, 0x0D4A51, 0x0DA545, 0x55AABA, 0x056A4E, 0x0A6D43, 0x452EB7, 0x052D4B, //2061-2070
+	0x8A95BF, 0x0A9553, 0x0B4A47, 0x6B553B, 0x0AD54F, 0x055A45, 0x4A5D38, 0x0A5B4C, 0x052B42, 0x3A93B6, //2071-2080
+	0x069349, 0x7729BD, 0x06AA51, 0x0AD546, 0x54DABA, 0x04B64E, 0x0A5743, 0x452738, 0x0D264A, 0x8E933E, //2081-2090
+	0x0D5252, 0x0DAA47, 0x66B53B, 0x056D4F, 0x04AE45, 0x4A4EB9, 0x0A4D4C, 0x0D1541, 0x2D92B5 //2091-2099
+};
+
+//	如:
+//	0x955ABF
+//	1001 0101010110101  01    11111
+//	闰月月份 7-19.13个月 春月  春日;
+
+//保存一个农历日期;
+typedef struct _STLUNARDATE_ {
+	int		nYear;
+	int		nMonth;
+	int		nDay;
+	bool	bIsLeapMonth;	//是否闰月;
+
+	_STLUNARDATE_()	{
+		nYear = 0;
+		nMonth = 0;
+		nDay = 0;
+		bIsLeapMonth = FALSE;
+	}
+} LunarDate, *pLunarDate;
+
+
+#endif

+ 602 - 0
LunarCalendar/LunarCalendar/LunarCalendar.cpp

@@ -0,0 +1,602 @@
+// LunarCalendar.cpp : 定义 DLL 的初始化例程。
+//
+
+#include "stdafx.h"
+#include "Def.h"
+#include "LunarCalendar.h"
+#include <bitset>
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+//
+//TODO: 如果此 DLL 相对于 MFC DLL 是动态链接的,
+//		则从此 DLL 导出的任何调入
+//		MFC 的函数必须将 AFX_MANAGE_STATE 宏添加到
+//		该函数的最前面。
+//
+//		例如:
+//
+//		extern "C" BOOL PASCAL EXPORT ExportedFunction()
+//		{
+//			AFX_MANAGE_STATE(AfxGetStaticModuleState());
+//			// 此处为普通函数体
+//		}
+//
+//		此宏先于任何 MFC 调用
+//		出现在每个函数中十分重要。这意味着
+//		它必须作为函数中的第一个语句
+//		出现,甚至先于所有对象变量声明,
+//		这是因为它们的构造函数可能生成 MFC
+//		DLL 调用。
+//
+//		有关其他详细信息,
+//		请参阅 MFC 技术说明 33 和 58。
+//
+
+// CLunarCalendarApp
+
+BEGIN_MESSAGE_MAP(CLunarCalendarApp, CWinApp)
+END_MESSAGE_MAP()
+
+
+// CLunarCalendarApp 构造
+
+CLunarCalendarApp::CLunarCalendarApp()
+{
+	// TODO: 在此处添加构造代码,
+	// 将所有重要的初始化放置在 InitInstance 中
+}
+
+
+// 唯一的一个 CLunarCalendarApp 对象
+
+CLunarCalendarApp theApp;
+
+
+// CLunarCalendarApp 初始化
+
+BOOL CLunarCalendarApp::InitInstance()
+{
+	CWinApp::InitInstance();
+
+	return TRUE;
+}
+
+
+extern "C" BOOL __declspec(dllexport) IsValidLunanrDate2(LPCTSTR lpDate)
+{
+	if (lpDate == NULL || _tcscmp(lpDate, _T("")) == 0)
+		return FALSE;
+
+	CString strDate = lpDate;
+	if (strDate.IsEmpty()) return FALSE;
+
+	static int lunar_year, lunar_month, lunar_day;
+	lunar_year = lunar_month = lunar_day = 0;
+
+	lunar_year = _ttoi(strDate.Left(4));
+	lunar_month = _ttoi(strDate.Mid(5, 2));
+	lunar_day = _ttoi(strDate.Mid(8, 2));
+
+	//越界检查,如果越界,返回无效日期;
+	if (lunar_year <= BEGIN_YEAR || lunar_year > BEGIN_YEAR + NUMBER_YEAR - 1)
+		return FALSE;
+
+	if (lunar_month < 1 || lunar_month > 12)
+		return FALSE;
+
+	// 1.农历年是否有闰月;
+	int nYearIndex = lunar_year - BEGIN_YEAR;
+	int leap_month = (LUNAR_YEARS[nYearIndex] >> 20) & 0xF;
+
+	// 2.月份大小月天数;
+	int month_day = 0;
+	if ((LUNAR_YEARS[nYearIndex] >> (7 + 13 - lunar_month)) & 0x1)
+		month_day = 30;
+	else
+		month_day = 29;
+
+	if (lunar_day < 0 || lunar_day > month_day)
+		return FALSE;
+
+	return TRUE;
+}
+
+extern "C" BOOL __declspec(dllexport) IsValidLunanrDate(int lunar_year, int lunar_month, int lunar_day)
+{
+	//越界检查,如果越界,返回无效日期;
+	if (lunar_year <= BEGIN_YEAR || lunar_year > BEGIN_YEAR + NUMBER_YEAR - 1)
+		return FALSE;
+
+	if (lunar_month < 1 || lunar_month > 12)
+		return FALSE;
+
+	// 1.农历年是否有闰月;
+	int nYearIndex = lunar_year - BEGIN_YEAR;
+	int leap_month = (LUNAR_YEARS[nYearIndex] >> 20) & 0xF;
+
+	// 2.月份大小月天数;
+	int month_day = 0;
+	if ((LUNAR_YEARS[nYearIndex] >> (7 + 13 - lunar_month)) & 0x1)
+		month_day = 30;
+	else
+		month_day = 29;
+
+	if (lunar_day < 0 || lunar_day > month_day)
+		return FALSE;
+
+	return TRUE;
+}
+
+// ------------------------------------------------------------------------------------------------------------------------
+// 对外接口函数
+//
+// 函数:IsValidSolarDate
+// 描述:判断日期是否有效;
+// 参数:
+//		strDate	格式如:2014-01-02 或 2014/01/02;
+// 返回:有效;
+//
+// ------------------------------------------------------------------------------------------------------------------------
+extern "C" BOOL __declspec(dllexport) IsValidSolarStrDate(LPCTSTR lpStrDate, BOOL bThisyear)
+{
+	if (lpStrDate == NULL) return FALSE;
+
+	CString strDate = lpStrDate;
+
+	// 判断日期合法性;
+	static int nYear = 0;
+	static int nMonth = 0;
+	static int nDay = 0;
+
+	nYear = nMonth = nDay = 0;
+
+	if (bThisyear)
+		nYear = CTime::GetCurrentTime().GetYear();
+	else
+		nYear = _ttoi(strDate.Left(4));
+
+	nMonth = _ttoi(strDate.Mid(5, 2));
+	nDay = _ttoi(strDate.Mid(8, 2));
+
+	if ((nDay <= 0) || (nDay > 31) || (nMonth <= 0) || (nMonth > 12)) return FALSE;
+
+	if ((nYear % 400 == 0) || (nYear % 4 == 0 && nYear % 100 != 0))
+	{
+		if (nDay > nLeapMonth[nMonth - 1])	return FALSE;
+	}
+	else
+	{
+		if (nDay > nNormalMonth[nMonth - 1]) return FALSE;
+	}
+
+	return TRUE;
+}
+
+// ------------------------------------------------------------------------------------------------------------------------
+// 对外接口函数
+//
+// 函数:IsValidSolarDate
+// 描述:判断日期是否有效;
+// 参数:
+//		nSolarYear		公历年;
+//		nSolarMonth		公历月;
+//		nSolarDay		公历日;
+// 返回:有效;
+//
+// ------------------------------------------------------------------------------------------------------------------------
+extern "C" BOOL __declspec(dllexport) IsValidSolarDate(CONST int &nSolarYear, CONST int &nSolarMonth, CONST int &nSolarDay)
+{
+	if (nSolarYear < 0 ) return FALSE;
+
+	// 判断日期合法性;
+	if ((nSolarDay <= 0) || (nSolarDay > 31) || (nSolarMonth <= 0) || (nSolarMonth > 12)) return FALSE;
+
+	if ((nSolarYear % 400 == 0) || (nSolarYear % 4 == 0 && nSolarYear % 100 != 0))
+	{
+		if (nSolarDay > nLeapMonth[nSolarMonth - 1])	return FALSE;
+	}
+	else
+	{
+		if (nSolarDay > nNormalMonth[nSolarMonth - 1]) return FALSE;
+	}
+
+	return TRUE;
+}
+
+
+// ------------------------------------------------------------------------------------------------------------------------
+// 对外接口函数
+//
+// 函数:DayOfSolarYear
+// 描述:计算这个公历日期是这一年中的第几天
+// 参数:
+//		nSolarYear		公历年;
+//		nSolarMonth		公历月;
+//		nSolarDay		公历日;
+// 返回:如果日期正确,返回公历日期在这一年中的第几天; 否则返回-1;
+//
+// ------------------------------------------------------------------------------------------------------------------------
+extern "C" int __declspec(dllexport) DayOfSolarYear(IN const int &nSolarYear,IN const int &nSolarMonth, IN const int &nSolarDay)
+{
+	if( !IsValidSolarDate(nSolarYear,nSolarMonth,nSolarDay) )
+		return -1;
+
+	const int *t_year_yday_ = NORMAL_YDAY;
+
+	//判断是否是公历闰年;
+	if (nSolarYear % 4 == 0)
+	{
+		if (nSolarYear % 100 != 0)
+			t_year_yday_ = LEAP_YDAY;
+		if (nSolarYear % 400 == 0)
+			t_year_yday_ = LEAP_YDAY;
+	}
+
+	return t_year_yday_[nSolarMonth - 1] + nSolarDay;
+}
+
+// ------------------------------------------------------------------------------------------------------------------------
+// 函数:SolarToLuanrDate
+// 描述:将公历日期转为对应的农历日期
+// 参数:
+//		nSolarYear		公历年;
+//		nSolarMonth		公历月;
+//		nSolarDay		公历日;
+// 返回:返回结构体;
+//
+// ------------------------------------------------------------------------------------------------------------------------
+INT SolarToLuanrDate(OUT LunarDate &tagLunarDate, IN const int &nSolarYear, IN const int &nSolarMonth, IN const int &nSolarDay)
+{
+	if( !IsValidSolarDate(nSolarYear,nSolarMonth,nSolarDay) )
+		return -1;
+
+	tagLunarDate.nYear = nSolarYear;
+	//越界检查,如果越界,返回无效日期;
+	if (nSolarYear <= BEGIN_YEAR || nSolarYear > BEGIN_YEAR + NUMBER_YEAR - 1)
+		return -1;
+
+	int year_index = nSolarYear - BEGIN_YEAR;
+
+	//计算春节的公历日期;
+	int spring_ny_month = (LUNAR_YEARS[year_index] & 0x60) >> 5;
+	int spring_ny_day = (LUNAR_YEARS[year_index] & 0x1F);
+
+	//计算今天是公历年的第几天;
+	int today_solar_yd = DayOfSolarYear(nSolarYear, nSolarMonth, nSolarDay);
+	if(today_solar_yd == -1)
+		return -1;
+
+	//计算春节是公历年的第几天;
+	int spring_ny_yd = DayOfSolarYear(nSolarYear, spring_ny_month, spring_ny_day);
+	if(spring_ny_yd == -1)
+		return -1;
+
+	//计算今天是农历年的第几天 = 农历今天在的公历第几天 - 今年农历春节在公历的第几天;
+	int today_luanr_yd = today_solar_yd - spring_ny_yd + 1;
+
+	//如果今天在春节的前面,重新计算today_luanr_yd;
+	if (today_luanr_yd <= 0)
+	{
+		//农历年比当前公历年小1;
+		year_index--;
+		tagLunarDate.nYear--;
+
+		//越界,返回无效日期;
+		if (year_index < 0)
+			return -1;
+
+		// 去年农历春节月;
+		spring_ny_month = (LUNAR_YEARS[year_index] & 0x60) >> 5;
+		// 去年农历春节日;
+		spring_ny_day = (LUNAR_YEARS[year_index] & 0x1F);
+		// 去年公历年共多少天;
+		int year_total_day = DayOfSolarYear(tagLunarDate.nYear, 12, 31);
+		if(year_total_day == -1)
+			return -1;
+
+		spring_ny_yd = DayOfSolarYear(nSolarYear, spring_ny_month, spring_ny_day);
+		if(spring_ny_yd == -1)
+			return -1;
+		// 计算今天是农历年的第几天;
+		today_luanr_yd = today_solar_yd + year_total_day - spring_ny_yd + 1;
+
+	}
+
+	int luanr_month = 1;
+
+	//计算月份和日期;
+	for (; luanr_month <= 13; luanr_month++)
+	{
+		int month_day = 29;
+
+		if ((LUNAR_YEARS[year_index] >> (7 + 13 - luanr_month)) & 0x1)
+			month_day = 30;
+		if (today_luanr_yd <= month_day)
+			break;
+		else
+			today_luanr_yd -= month_day;
+	}
+
+	tagLunarDate.nDay = today_luanr_yd;
+
+	//处理闰月;
+	int leap_month = (LUNAR_YEARS[year_index] >> 20) & 0xf;
+	if (leap_month > 0 && leap_month < luanr_month)
+	{
+		luanr_month--;
+
+		//如果当前月为闰月,设置闰月标志;
+		if (luanr_month == leap_month)
+			tagLunarDate.bIsLeapMonth = true;
+	}
+
+	if ( leap_month > 12 )
+		return -1;
+
+	tagLunarDate.nMonth = luanr_month;
+
+	return 0L;
+}
+
+
+// ------------------------------------------------------------------------------------------------------------------------
+// 对外接口函数
+//
+// 函数:GetLunarDate
+// 描述:将公历日期转为对应的农历日期
+// 参数:
+//		nSolarYear		公历年;
+//		nSolarMonth		公历月;
+//		nSolarDay		公历日;
+// 返回:暂时未细致处理返回值的定义,错误的值都为负数;
+// ------------------------------------------------------------------------------------------------------------------------
+extern "C" INT __declspec(dllexport) GetLunarDate(OUT LPTSTR lpLunarDate,IN const int &nSolarYear, IN const int &nSolarMonth, IN const int &nSolarDay)
+{
+	if( !IsValidSolarDate(nSolarYear,nSolarMonth,nSolarDay) )
+		return -1;
+
+	LunarDate luanr_date;
+	luanr_date.nYear = nSolarYear;
+	luanr_date.nMonth = 0;
+	luanr_date.nDay = 0;
+	luanr_date.bIsLeapMonth = false;
+
+	//越界检查,如果越界,返回无效日期;
+	if (nSolarYear <= BEGIN_YEAR || nSolarYear > BEGIN_YEAR + NUMBER_YEAR - 1)
+		return -2;
+
+	int year_index = nSolarYear - BEGIN_YEAR;
+
+	//计算春节的公历日期;
+	int spring_ny_month = (LUNAR_YEARS[year_index] & 0x60) >> 5;
+	int spring_ny_day = (LUNAR_YEARS[year_index] & 0x1F);
+
+	//计算今天是公历年的第几天;
+	int today_solar_yd = DayOfSolarYear(nSolarYear, nSolarMonth, nSolarDay);
+	if (today_solar_yd == -1)
+		return -3;
+
+	//计算春节是公历年的第几天;
+	int spring_ny_yd = DayOfSolarYear(nSolarYear, spring_ny_month, spring_ny_day);
+	if (spring_ny_yd == -1)
+		return -4;
+
+	//计算今天是农历年的第几天 = 农历今天在的公历第几天 - 今年农历春节在公历的第几天;
+	int today_luanr_yd = today_solar_yd - spring_ny_yd + 1;
+
+	//如果今天在春节的前面,重新计算today_luanr_yd;
+	if (today_luanr_yd <= 0)
+	{
+		//农历年比当前公历年小1;
+		year_index--;
+		luanr_date.nYear--;
+
+		//越界,返回无效日期;
+		if (year_index < 0)
+			return -2;
+
+		// 去年农历春节月;
+		spring_ny_month = (LUNAR_YEARS[year_index] & 0x60) >> 5;
+		// 去年农历春节日;
+		spring_ny_day = (LUNAR_YEARS[year_index] & 0x1F);
+		// 去年公历年共多少天;
+		int year_total_day = DayOfSolarYear(luanr_date.nYear, 12, 31);
+		if (year_total_day == -1)
+			return -1;
+
+		spring_ny_yd = DayOfSolarYear(nSolarYear, spring_ny_month, spring_ny_day);
+		if (spring_ny_yd == -1)
+			return -1;
+
+		// 计算今天是农历年的第几天;
+		today_luanr_yd = today_solar_yd + year_total_day - spring_ny_yd + 1;
+	}
+
+	int luanr_month = 1;
+
+	//计算月份和日期;
+	for (; luanr_month <= 13; luanr_month++)
+	{
+		int month_day = 29;
+		if ((LUNAR_YEARS[year_index] >> (7 + 13 - luanr_month)) & 0x1)
+
+			month_day = 30;
+		if (today_luanr_yd <= month_day)
+			break;
+		else
+			today_luanr_yd -= month_day;
+	}
+
+	luanr_date.nDay = today_luanr_yd;
+
+	//处理闰月;
+	int leap_month = (LUNAR_YEARS[year_index] >> 20) & 0xf;
+	if (leap_month > 0 && leap_month < luanr_month)
+	{
+		luanr_month--;
+
+		//如果当前月为闰月,设置闰月标志;
+		if (luanr_month == leap_month)
+			luanr_date.bIsLeapMonth = true;
+	}
+
+	if ( leap_month > 12)
+		return -1;
+
+	luanr_date.nMonth = luanr_month;
+	_stprintf_s(lpLunarDate, 11, _T("%04d-%02d-%02d"),luanr_date.nYear,luanr_date.nMonth,luanr_date.nDay);
+
+	return 0L;
+}
+
+// ------------------------------------------------------------------------------------------------------------------------
+// 对外接口函数
+//
+// 函数:LuanrToSolarDate
+// 描述:将农历日期转为对应的公历日期
+// 参数:
+//		nLunarYear		农历年;
+//		nLunarMonth		农历月;
+//		nLunarDay		农历日;
+//		bIsLeapMonth	TRUE,若该年有闰月且正好是输入月份,返回闰月对应的公历;
+// 返回:返回公历日期在这一年中的第几天;
+//
+// ------------------------------------------------------------------------------------------------------------------------
+extern "C" BOOL __declspec(dllexport) LuanrToSolarDate(OUT LPTSTR lpSolarDate,IN const int &nLunarYear, IN const int &nLunarMonth, IN const int &nLunarDay, BOOL bIsLeapMonth/*=FALSE*/)
+{
+	// 越界检查,如果越界,返回无效日期;
+	if (nLunarYear <= BEGIN_YEAR || nLunarYear > BEGIN_YEAR + NUMBER_YEAR - 1)
+		return FALSE;
+
+	// 1.判断该农历年是否有闰月;
+	INT nIndexYear = nLunarYear - BEGIN_YEAR;
+	INT nLeapMonth = (LUNAR_YEARS[nIndexYear] >> 20) & 0xF;
+
+	int nDays = 0;
+	long nMonths = (LUNAR_YEARS[nIndexYear] & 0x0FFF80) >> 7;
+	std::bitset<13> btMonth(nMonths);
+	for ( int i = 0; i < nLunarMonth-1; i++ )
+	{
+		nDays +=  btMonth[i] ? 30 : 29;
+	}
+
+	if ( bIsLeapMonth && nLeapMonth != 0 )
+	{
+		nDays +=  btMonth[nLunarMonth-1] ? 30 : 29;
+	}
+	nDays += nLunarDay;
+
+	// 公历年是否是闰年;
+	BOOL isLeapYear = FALSE;
+	if ((nLunarYear % 400 == 0) || (nLunarYear % 4 == 0 && nLunarYear % 100 != 0))
+	{
+		isLeapYear = TRUE;
+	}
+	else
+	{
+		isLeapYear = FALSE;
+	}
+
+	// 正月的公历月份;
+	int SolarNewYearMonth = (LUNAR_YEARS[nIndexYear] & 0x000060) >> 5;
+	// 正月初一的公历日期;
+	int SolarNewYearDay = LUNAR_YEARS[nIndexYear] & 0x00001F;
+
+	int nSolarDay = 0;
+	int nSolarDays = 0;
+	int nSolarMonth = -1;
+	if ( isLeapYear )
+	{
+		nSolarDays = LEAP_YDAY[SolarNewYearMonth-1] + SolarNewYearDay + nDays;
+		for ( int i = SolarNewYearMonth; i < 12; i++)
+		{
+			if ( nSolarDays >= LEAP_YDAY[i] && nSolarDays < LEAP_YDAY[i+1])
+			{
+				nSolarMonth = i+1;
+				nSolarDay = nSolarDays - LEAP_YDAY[i] -1;
+			}
+		}
+
+		if ( nSolarMonth == -1 )
+			nSolarDays -= LEAP_YDAY[12];
+	}
+	else
+	{
+		nSolarDays = NORMAL_YDAY[SolarNewYearMonth-1]+ SolarNewYearDay + nDays;
+		for ( int i = SolarNewYearMonth; i < 12; i++)
+		{
+			if ( nSolarDays >= NORMAL_YDAY[i] && nSolarDays < NORMAL_YDAY[i+1])
+			{
+				nSolarMonth = i+1;
+				nSolarDay = nSolarDays - NORMAL_YDAY[i] -1;
+			}
+		}
+
+		if ( nSolarMonth == -1 )
+			nSolarDays -= NORMAL_YDAY[12];
+	}
+
+	_stprintf_s(lpSolarDate, 11, _T("%4d-%02d-%02d"), nLunarYear, nSolarMonth, nSolarDay);
+	if ( nSolarMonth == -1 )
+	{// 超出本年;
+		int nYear = nLunarYear+1 ;
+		if ((nYear % 400 == 0) || (nYear % 4 == 0 && nYear % 100 != 0))
+		{
+			isLeapYear = TRUE;
+		}
+		else
+		{
+			isLeapYear = FALSE;
+		}
+
+		if ( isLeapYear )
+		{
+			for ( int i = 0; i < 12; i++)
+			{
+				if ( nSolarDays >= LEAP_YDAY[i] && nSolarDays < LEAP_YDAY[i+1])
+				{
+					nSolarMonth = i+1;
+					nSolarDay = nSolarDays - LEAP_YDAY[i] -1;
+				}
+			}
+		}
+		else
+		{
+			for ( int i = 0; i < 12; i++)
+			{
+				if ( nSolarDays >= NORMAL_YDAY[i] && nSolarDays < NORMAL_YDAY[i+1])
+				{
+					nSolarMonth = i+1;
+					nSolarDay = nSolarDays - NORMAL_YDAY[i] -1;
+				}
+			}
+		}
+		_stprintf_s(lpSolarDate, 11, _T("%4d-%02d-%02d"), nYear, nSolarMonth, nSolarDay);
+	}
+
+	return true;
+}
+
+
+// ------------------------------------------------------------------------------------------------------------------------
+// 对外接口函数
+//
+// 函数:
+// 描述:判断输入的农历日期的月份是否有闰月;
+// 参数:
+//		nLunarYear		农历年;
+// 返回:若有闰月返回闰月值,否则返回0;
+//
+// ------------------------------------------------------------------------------------------------------------------------
+extern "C" INT __declspec(dllexport) IsLeapMonth(IN const int &nLunarYear)
+{
+	// 越界检查,如果越界,返回无效日期;
+	if (nLunarYear <= BEGIN_YEAR || nLunarYear > BEGIN_YEAR + NUMBER_YEAR - 1)
+		return -1;
+
+	// 1.判断该农历年是否有闰月;
+	return (LUNAR_YEARS[nLunarYear - BEGIN_YEAR] >> 20) & 0xF;
+}

+ 12 - 0
LunarCalendar/LunarCalendar/LunarCalendar.def

@@ -0,0 +1,12 @@
+; LunarCalendar.def : 声明 DLL 的模块参数。
+
+LIBRARY      "LunarCalendar"
+
+EXPORTS
+    ; 此处可以是显式导出
+	IsValidSolarStrDate
+	IsValidSolarDate
+	DayOfSolarYear
+	GetLunarDate
+	LuanrToSolarDate
+	IsLeapMonth

+ 27 - 0
LunarCalendar/LunarCalendar/LunarCalendar.h

@@ -0,0 +1,27 @@
+// LunarCalendar.h : LunarCalendar DLL 的主头文件
+//
+
+#pragma once
+
+#ifndef __AFXWIN_H__
+	#error "在包含此文件之前包含“stdafx.h”以生成 PCH 文件"
+#endif
+
+#include "resource.h"		// 主符号
+
+
+// CLunarCalendarApp
+// 有关此类实现的信息,请参阅 LunarCalendar.cpp
+//
+
+class CLunarCalendarApp : public CWinApp
+{
+public:
+	CLunarCalendarApp();
+
+// 重写
+public:
+	virtual BOOL InitInstance();
+
+	DECLARE_MESSAGE_MAP()
+};

+ 128 - 0
LunarCalendar/LunarCalendar/LunarCalendar.rc

@@ -0,0 +1,128 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#ifndef APSTUDIO_INVOKED
+#include "targetver.h"
+#endif
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// 中文(中华人民共和国) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
+#ifdef _WIN32
+LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
+#pragma code_page(936)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE 
+BEGIN
+    "resource.h\0"
+END
+
+2 TEXTINCLUDE 
+BEGIN
+    "#ifndef APSTUDIO_INVOKED\r\n"
+    "#include ""targetver.h""\r\n"
+    "#endif\r\n"
+    "#include ""afxres.h""\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE 
+BEGIN
+    "#define _AFX_NO_SPLITTER_RESOURCES\r\n"
+    "#define _AFX_NO_OLE_RESOURCES\r\n"
+    "#define _AFX_NO_TRACKER_RESOURCES\r\n"
+    "#define _AFX_NO_PROPERTY_RESOURCES\r\n"
+    "\r\n"
+    "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)\r\n"
+    "LANGUAGE 4, 2\r\n"
+    "#pragma code_page(936)\r\n"
+    "#include ""res\\LunarCalendar.rc2""  // 非 Microsoft Visual C++ 编辑的资源\r\n"
+    "#include ""l.CHS\\afxres.rc""      // 标准组件\r\n"
+    "#endif\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,2
+ PRODUCTVERSION 1,0,0,2
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "080403a8"
+        BEGIN
+            VALUE "CompanyName", "利亚方舟科技有限公司 "
+            VALUE "FileDescription", "公历农历转换"
+            VALUE "FileVersion", "1.0.0.2"
+            VALUE "InternalName", "LunarCalendar.dll"
+            VALUE "LegalCopyright", "利亚方舟科技有限公司 版权所有 (C) 2014"
+            VALUE "OriginalFilename", "LunarCalendar.dll"
+            VALUE "ProductName", "LunarCalendar"
+            VALUE "ProductVersion", "1.0.0.2"
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x804, 936
+    END
+END
+
+#endif    // 中文(中华人民共和国) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#define _AFX_NO_SPLITTER_RESOURCES
+#define _AFX_NO_OLE_RESOURCES
+#define _AFX_NO_TRACKER_RESOURCES
+#define _AFX_NO_PROPERTY_RESOURCES
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
+LANGUAGE 4, 2
+#pragma code_page(936)
+#include "res\LunarCalendar.rc2"  // 非 Microsoft Visual C++ 编辑的资源
+#include "l.CHS\afxres.rc"      // 标准组件
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+

+ 263 - 0
LunarCalendar/LunarCalendar/LunarCalendar.vcproj

@@ -0,0 +1,263 @@
+<?xml version="1.0" encoding="gb2312"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="LunarCalendar"
+	ProjectGUID="{BA863651-B0FE-44EA-97E0-11825249735B}"
+	RootNamespace="LunarCalendar"
+	Keyword="MFCDLLProj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="..\..\..\bin\$(SolutionName)"
+			IntermediateDirectory="$(OutDir)\$(ConfigurationName)"
+			ConfigurationType="2"
+			UseOfMFC="2"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				PreprocessorDefinitions="_DEBUG"
+				MkTypLibCompatible="false"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG;_USRDLL"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="_DEBUG"
+				Culture="2052"
+				AdditionalIncludeDirectories="$(IntDir)"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="2"
+				ModuleDefinitionFile=".\LunarCalendar.def"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="..\..\..\bin\$(SolutionName)"
+			IntermediateDirectory="$(OutDir)\$(ConfigurationName)"
+			ConfigurationType="2"
+			UseOfMFC="1"
+			CharacterSet="1"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				PreprocessorDefinitions="NDEBUG"
+				MkTypLibCompatible="false"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;_USRDLL"
+				RuntimeLibrary="0"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="2052"
+				AdditionalIncludeDirectories="$(IntDir)"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="1"
+				ModuleDefinitionFile=".\LunarCalendar.def"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Ô´Îļþ"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath=".\LunarCalendar.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\LunarCalendar.def"
+				>
+			</File>
+			<File
+				RelativePath=".\stdafx.cpp"
+				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						UsePrecompiledHeader="1"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						UsePrecompiledHeader="1"
+					/>
+				</FileConfiguration>
+			</File>
+		</Filter>
+		<Filter
+			Name="Í·Îļþ"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<File
+				RelativePath=".\Def.h"
+				>
+			</File>
+			<File
+				RelativePath=".\LunarCalendar.h"
+				>
+			</File>
+			<File
+				RelativePath=".\Resource.h"
+				>
+			</File>
+			<File
+				RelativePath=".\stdafx.h"
+				>
+			</File>
+			<File
+				RelativePath=".\targetver.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="×ÊÔ´Îļþ"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+			<File
+				RelativePath=".\LunarCalendar.rc"
+				>
+			</File>
+			<File
+				RelativePath=".\res\LunarCalendar.rc2"
+				>
+			</File>
+		</Filter>
+		<File
+			RelativePath=".\ReadMe.txt"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

+ 44 - 0
LunarCalendar/LunarCalendar/ReadMe.txt

@@ -0,0 +1,44 @@
+========================================================================
+    MICROSOFT 基础类库 : LunarCalendar 项目概述
+========================================================================
+
+
+应用程序向导已为您创建了此 LunarCalendar DLL。此 DLL 不仅演示 Microsoft 基础类的基本使用方法,还可作为您编写 DLL 的起点。
+
+本文件概要介绍组成 LunarCalendar DLL 的每个文件的内容。
+
+LunarCalendar.vcproj
+    这是使用应用程序向导生成的 VC++ 项目的主项目文件,
+    其中包含生成该文件的 Visual C++ 的版本信息,以及有关使用应用程序向导选择的平台、配置和项目功能的信息。
+
+LunarCalendar.h
+    这是 DLL 的主头文件。它声明了 CLunarCalendarApp 类。
+
+LunarCalendar.cpp
+    这是主 DLL 源文件。它包含 CLunarCalendarApp 类。
+
+LunarCalendar.rc
+    这是程序使用的所有 Microsoft Windows 资源的列表。它包括 RES 子目录中存储的图标、位图和光标。此文件可以直接在 Microsoft Visual C++ 中进行编辑。
+
+res\LunarCalendar.rc2
+    此文件包含不在 Microsoft Visual C++ 中进行编辑的资源。您应该将不可由资源编辑器编辑的所有资源放在此文件中。
+
+LunarCalendar.def
+    此文件包含在 Microsoft Windows 中运行所必需的 DLL 的有关信息。它定义了 DLL 的名称和说明等参数,而且还从 DLL 导出函数。
+
+/////////////////////////////////////////////////////////////////////////////
+其他标准文件:
+
+StdAfx.h, StdAfx.cpp
+    这些文件用于生成名为 LunarCalendar.pch 的预编译头 (PCH) 文件和名为 StdAfx.obj 的预编译类型文件。
+
+Resource.h
+    这是标准头文件,可用于定义新的资源 ID。
+    Microsoft Visual C++ 将读取并更新此文件。
+
+/////////////////////////////////////////////////////////////////////////////
+其他注释:
+
+应用程序向导使用“TODO:”来指示应添加或自定义的源代码部分。
+
+/////////////////////////////////////////////////////////////////////////////

+ 16 - 0
LunarCalendar/LunarCalendar/Resource.h

@@ -0,0 +1,16 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by LunarCalendar.rc
+//
+
+// жÔÏóµÄÏÂÒ»×éĬÈÏÖµ
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+
+#define _APS_NEXT_RESOURCE_VALUE	1000
+#define _APS_NEXT_CONTROL_VALUE		1000
+#define _APS_NEXT_SYMED_VALUE		1000
+#define _APS_NEXT_COMMAND_VALUE		32771
+#endif
+#endif

+ 13 - 0
LunarCalendar/LunarCalendar/res/LunarCalendar.rc2

@@ -0,0 +1,13 @@
+//
+// LunarCalendar.RC2 - Microsoft Visual C++ 不会直接编辑的资源
+//
+
+#ifdef APSTUDIO_INVOKED
+#error 此文件不能用 Microsoft Visual C++ 编辑
+#endif //APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+// 在此处添加手动编辑的资源...
+
+/////////////////////////////////////////////////////////////////////////////

+ 7 - 0
LunarCalendar/LunarCalendar/stdafx.cpp

@@ -0,0 +1,7 @@
+// stdafx.cpp : 只包括标准包含文件的源文件
+// LunarCalendar.pch 将作为预编译头
+// stdafx.obj 将包含预编译类型信息
+
+#include "stdafx.h"
+
+

+ 39 - 0
LunarCalendar/LunarCalendar/stdafx.h

@@ -0,0 +1,39 @@
+// stdafx.h : 标准系统包含文件的包含文件,
+// 或是经常使用但不常更改的
+// 特定于项目的包含文件
+
+#pragma once
+
+#ifndef VC_EXTRALEAN
+#define VC_EXTRALEAN            // 从 Windows 头中排除极少使用的资料
+#endif
+
+#include "targetver.h"
+
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS      // 某些 CString 构造函数将是显式的
+
+#include <afxwin.h>         // MFC 核心组件和标准组件
+#include <afxext.h>         // MFC 扩展
+
+#ifndef _AFX_NO_OLE_SUPPORT
+#include <afxole.h>         // MFC OLE 类
+#include <afxodlgs.h>       // MFC OLE 对话框类
+#include <afxdisp.h>        // MFC 自动化类
+#endif // _AFX_NO_OLE_SUPPORT
+
+#ifndef _AFX_NO_DB_SUPPORT
+#include <afxdb.h>                      // MFC ODBC 数据库类
+#endif // _AFX_NO_DB_SUPPORT
+
+#ifndef _AFX_NO_DAO_SUPPORT
+#include <afxdao.h>                     // MFC DAO 数据库类
+#endif // _AFX_NO_DAO_SUPPORT
+
+#ifndef _AFX_NO_OLE_SUPPORT
+#include <afxdtctl.h>           // MFC 对 Internet Explorer 4 公共控件的支持
+#endif
+#ifndef _AFX_NO_AFXCMN_SUPPORT
+#include <afxcmn.h>                     // MFC 对 Windows 公共控件的支持
+#endif // _AFX_NO_AFXCMN_SUPPORT
+
+

+ 26 - 0
LunarCalendar/LunarCalendar/targetver.h

@@ -0,0 +1,26 @@
+
+#pragma once
+
+// 以下宏定义要求的最低平台。要求的最低平台
+// 是具有运行应用程序所需功能的 Windows、Internet Explorer 等产品的
+// 最早版本。通过在指定版本及更低版本的平台上启用所有可用的功能,宏可以
+// 正常工作。
+
+// 如果必须要针对低于以下指定版本的平台,请修改下列定义。
+// 有关不同平台对应值的最新信息,请参考 MSDN。
+#ifndef WINVER                          // 指定要求的最低平台是 Windows Vista。
+#define WINVER 0x0600           // 将此值更改为相应的值,以适用于 Windows 的其他版本。
+#endif
+
+#ifndef _WIN32_WINNT            // 指定要求的最低平台是 Windows Vista。
+#define _WIN32_WINNT 0x0600     // 将此值更改为相应的值,以适用于 Windows 的其他版本。
+#endif
+
+#ifndef _WIN32_WINDOWS          // 指定要求的最低平台是 Windows 98。
+#define _WIN32_WINDOWS 0x0410 // 将此值更改为适当的值,以适用于 Windows Me 或更高版本。
+#endif
+
+#ifndef _WIN32_IE                       // 指定要求的最低平台是 Internet Explorer 7.0。
+#define _WIN32_IE 0x0700        // 将此值更改为相应的值,以适用于 IE 的其他版本。
+#endif
+

+ 884 - 0
LunarCalendar/Test/CalendarEx..cpp

@@ -0,0 +1,884 @@
+#include "StdAfx.h"
+#include "CalendarEx.h"
+#include <time.h> //或者 #include <ctime>
+#include <bitset>
+namespace CalendarEx
+{
+	//////////////////////////////////////////////////////////////////////////
+	// 全局定义;
+	// const static int BEGIN_YEAR = 1901;
+	// const static int NUMBER_YEAR = 199;
+	#define BEGIN_YEAR 1901
+	#define NUMBER_YEAR 199
+
+	// 非闰年的月份天数;
+	const static int nNormalMonth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+	// 闰年的月份天数;
+	const static int nLeapMonth[12] =   { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+
+	// 为了提高效率,记录每月一日是一年中的第几天;
+	// 平年的情况;
+	const static int NORMAL_YDAY[13] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
+	// 闰年的情况;
+	const static int LEAP_YDAY[13] = { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 };
+
+	// 使用比特位记录每年的情况
+	// 0~4 共5bit 春节日份
+	// 5~6 共2bit 春节月份
+	// 7~19 共13bit 13个月的大小月情况(如果无闰月,最后位无效),大月为1(30天),小月为0(29天)
+	// 20~23 共4bit 记录闰月的月份,如果没有闰月为0
+
+	//////////////////////////////////////////////////////////////////////////
+	// 示例
+	//0x955ABF	2014年, 农9月有闰月, 公历1月31号为春节;
+	//   1001						0101010110101	     01					11111
+	// 20~23bit.闰月月份			7-19.13个月		 5~6bit.春月         0~4bit.春节日期;
+
+	////1001 0101010110101  01    11111
+
+	//0X252ABF
+	//1001010010101010111111
+
+	const static DWORD LUNAR_YEARS[199] =
+	{
+		0x04AE53, 0x0A5748, 0x5526BD, 0x0D2650, 0x0D9544, 0x46AAB9, 0x056A4D, 0x09AD42, 0x24AEB6, 0x04AE4A, //1901-1910
+		0x6A4DBE, 0x0A4D52, 0x0D2546, 0x5D52BA, 0x0B544E, 0x0D6A43, 0x296D37, 0x095B4B, 0x749BC1, 0x049754, //1911-1920
+		0x0A4B48, 0x5B25BC, 0x06A550, 0x06D445, 0x4ADAB8, 0x02B64D, 0x095742, 0x2497B7, 0x04974A, 0x664B3E, //1921-1930
+		0x0D4A51, 0x0EA546, 0x56D4BA, 0x05AD4E, 0x02B644, 0x393738, 0x092E4B, 0x7C96BF, 0x0C9553, 0x0D4A48, //1931-1940
+		0x6DA53B, 0x0B554F, 0x056A45, 0x4AADB9, 0x025D4D, 0x092D42, 0x2C95B6, 0x0A954A, 0x7B4ABD, 0x06CA51, //1941-1950
+		0x0B5546, 0x555ABB, 0x04DA4E, 0x0A5B43, 0x352BB8, 0x052B4C, 0x8A953F, 0x0E9552, 0x06AA48, 0x7AD53C, //1951-1960
+		0x0AB54F, 0x04B645, 0x4A5739, 0x0A574D, 0x052642, 0x3E9335, 0x0D9549, 0x75AABE, 0x056A51, 0x096D46, //1961-1970
+		0x54AEBB, 0x04AD4F, 0x0A4D43, 0x4D26B7, 0x0D254B, 0x8D52BF, 0x0B5452, 0x0B6A47, 0x696D3C, 0x095B50, //1971-1980
+		0x049B45, 0x4A4BB9, 0x0A4B4D, 0xAB25C2, 0x06A554, 0x06D449, 0x6ADA3D, 0x0AB651, 0x093746, 0x5497BB, //1981-1990
+		0x04974F, 0x064B44, 0x36A537, 0x0EA54A, 0x86B2BF, 0x05AC53, 0x0AB647, 0x5936BC, 0x092E50, 0x0C9645, //1991-2000
+		0x4D4AB8, 0x0D4A4C, 0x0DA541, 0x25AAB6, 0x056A49, 0x7AADBD, 0x025D52, 0x092D47, 0x5C95BA, 0x0A954E, //2001-2010
+		0x0B4A43, 0x4B5537, 0x0AD54A, 0x955ABF, 0x04BA53, 0x0A5B48, 0x652BBC, 0x052B50, 0x0A9345, 0x474AB9, //2011-2020
+		0x06AA4C, 0x0AD541, 0x24DAB6, 0x04B64A, 0x69573D, 0x0A4E51, 0x0D2646, 0x5E933A, 0x0D534D, 0x05AA43, //2021-2030
+		0x36B537, 0x096D4B, 0xB4AEBF, 0x04AD53, 0x0A4D48, 0x6D25BC, 0x0D254F, 0x0D5244, 0x5DAA38, 0x0B5A4C, //2031-2040
+		0x056D41, 0x24ADB6, 0x049B4A, 0x7A4BBE, 0x0A4B51, 0x0AA546, 0x5B52BA, 0x06D24E, 0x0ADA42, 0x355B37, //2041-2050
+		0x09374B, 0x8497C1, 0x049753, 0x064B48, 0x66A53C, 0x0EA54F, 0x06B244, 0x4AB638, 0x0AAE4C, 0x092E42, //2051-2060
+		0x3C9735, 0x0C9649, 0x7D4ABD, 0x0D4A51, 0x0DA545, 0x55AABA, 0x056A4E, 0x0A6D43, 0x452EB7, 0x052D4B, //2061-2070
+		0x8A95BF, 0x0A9553, 0x0B4A47, 0x6B553B, 0x0AD54F, 0x055A45, 0x4A5D38, 0x0A5B4C, 0x052B42, 0x3A93B6, //2071-2080
+		0x069349, 0x7729BD, 0x06AA51, 0x0AD546, 0x54DABA, 0x04B64E, 0x0A5743, 0x452738, 0x0D264A, 0x8E933E, //2081-2090
+		0x0D5252, 0x0DAA47, 0x66B53B, 0x056D4F, 0x04AE45, 0x4A4EB9, 0x0A4D4C, 0x0D1541, 0x2D92B5 //2091-2099
+	};
+
+	/************************************************************************/
+	/*  函数:IsValidLunanrDate[2/23/2017 Jeff];
+	/*  描述:农历日期有效性;
+	/*  参数:;
+	/*  	[IN] lpLunarDate:输入的农历日期;
+	/*  返回:有效的农历日期返回true,否则返回false;
+	/*  注意:lpLunarDate的日期格式必须是:yyyy/mm/dd 或 yyyy-mm-dd;
+	/*  示例:;
+	/*
+	/*  修改:;
+	/*  日期:;
+	/*  内容:;
+	/************************************************************************/
+	bool IsValidLunanrDate(IN const TCHAR* lpLunarDate)
+	{
+		if (lpLunarDate == NULL || _tcslen(lpLunarDate) != 10 )
+			return false;
+
+		CString strLunarDate = lpLunarDate;
+		if (strLunarDate.IsEmpty()) return false;
+
+		static int nLunarYear, nLunarMonth, nLunarDay;
+		nLunarYear = nLunarMonth = nLunarDay = 0;
+
+		nLunarYear = _ttoi(strLunarDate.Left(4));
+		nLunarMonth = _ttoi(strLunarDate.Mid(5, 2));
+		nLunarDay = _ttoi(strLunarDate.Mid(8, 2));
+
+		//越界检查,如果越界,返回无效日期;
+		if (nLunarYear <= BEGIN_YEAR || nLunarYear > BEGIN_YEAR + NUMBER_YEAR - 1)
+			return false;
+
+		if (nLunarMonth < 1 || nLunarMonth > 12)
+			return false;
+
+		// 1.农历年是否有闰月;
+		int nYearIndex = nLunarYear - BEGIN_YEAR;
+		int nLeapMonth = (LUNAR_YEARS[nYearIndex] >> 20) & 0xF;
+
+		// 2.月份大小月天数;
+		int nMonthDays = 0;
+		if ((LUNAR_YEARS[nYearIndex] >> (7 + 13 - nLunarMonth)) & 0x1)
+			nMonthDays = 30;
+		else
+			nMonthDays = 29;
+
+		if (nLunarDay < 0 || nLunarDay > nMonthDays)
+			return false;
+
+		return true;
+	}
+
+	/************************************************************************/
+	/*  函数:IsValidLunanrDate[2/23/2017 Jeff];
+	/*  描述:农历日期有效性;
+	/*  参数:;
+	/*  	[IN] nLunarYear:输入的农历年;
+	/*  	[IN] nLunarMonth:输入的农历月;
+	/*  	[IN] nLunarDay:输入的农历日;
+	/*  返回:有效的农历日期返回true,否则返回false;
+	/*  注意:;
+	/*  示例:;
+	/*
+	/*  修改:;
+	/*  日期:;
+	/*  内容:;
+	/************************************************************************/
+	bool IsValidLunanrDate(IN const int &nLunarYear, IN const int &nLunarMonth, IN const int &nLunarDay)
+	{
+		//越界检查,如果越界,返回无效日期;
+		if (nLunarYear <= BEGIN_YEAR || nLunarYear > BEGIN_YEAR + NUMBER_YEAR - 1)
+			return false;
+
+		if (nLunarMonth < 1 || nLunarMonth > 12)
+			return false;
+
+		// 1.农历年是否有闰月;
+		int nYearIndex = nLunarYear - BEGIN_YEAR;
+		int nLeapMonth = (LUNAR_YEARS[nYearIndex] >> 20) & 0xF;
+
+		// 2.月份大小月天数;
+		int nMonthDays = 0;
+		if ((LUNAR_YEARS[nYearIndex] >> (7 + 13 - nLunarMonth)) & 0x1)
+			nMonthDays = 30;
+		else
+			nMonthDays = 29;
+
+		if (nLunarDay < 0 || nLunarDay > nMonthDays)
+			return false;
+
+		return true;
+	}
+
+	/************************************************************************/
+	/*  函数:IsValidSolarDate[2/23/2017 Jeff];
+	/*  描述:判断公历日期是否有效;
+	/*  参数:;
+	/*  	[IN] lpSolarDate:输入的公历日期;
+	/*  返回:有效的公历日期返回true,否则返回false;
+	/*  注意:lpSolarDate的日期格式必须是:yyyy/mm/dd 或 yyyy-mm-dd;
+	/*  示例:;
+	/*
+	/*  修改:;
+	/*  日期:;
+	/*  内容:;
+	/************************************************************************/
+	bool IsValidSolarDate(IN const TCHAR* lpSolarDate)
+	{
+		if (lpSolarDate == NULL || _tcslen(lpSolarDate) != 10) return false;
+
+		CString strSolarDate = lpSolarDate;
+
+		// 判断日期合法性;
+		static int nSolarYear = 0;
+		static int nSolarMonth = 0;
+		static int nSolarDay = 0;
+
+		nSolarYear = nSolarMonth = nSolarDay = 0;
+
+		nSolarYear = _ttoi(strSolarDate.Left(4));
+		nSolarMonth = _ttoi(strSolarDate.Mid(5, 2));
+		nSolarDay = _ttoi(strSolarDate.Mid(8, 2));
+
+		if ((nSolarDay <= 0) || (nSolarDay > 31) || (nSolarMonth <= 0) || (nSolarMonth > 12)) return false;
+
+		if ((nSolarYear % 400 == 0) || (nSolarYear % 4 == 0 && nSolarYear % 100 != 0))
+		{
+			if (nSolarDay > nLeapMonth[nSolarMonth - 1]) return false;
+		}
+		else
+		{
+			if (nSolarDay > nNormalMonth[nSolarMonth - 1]) return false;
+		}
+
+		return true;
+	}
+
+	/************************************************************************/
+	/*  函数:IsValidSolarDate[2/23/2017 Jeff];
+	/*  描述:判断公历日期是否有效;
+	/*  参数:;
+	/*  	[IN] nSolarYear:输入的公历年;
+	/*  	[IN] nSolarMonth:输入的公历月;
+	/*  	[IN] nSolarDay:输入的公历日;
+	/*  返回:若公历日期有效返回true,否则返回false;
+	/*  注意:;
+	/*  示例:;
+	/*
+	/*  修改:;
+	/*  日期:;
+	/*  内容:;
+	/************************************************************************/
+	bool IsValidSolarDate(IN const int &nSolarYear, IN const int &nSolarMonth, IN const int &nSolarDay)
+	{
+		if (nSolarYear < 0 ) return false;
+
+		// 判断日期合法性;
+		if ((nSolarDay <= 0) || (nSolarDay > 31) || (nSolarMonth <= 0) || (nSolarMonth > 12)) return false;
+
+		if ((nSolarYear % 400 == 0) || (nSolarYear % 4 == 0 && nSolarYear % 100 != 0))
+		{
+			if (nSolarDay > nLeapMonth[nSolarMonth - 1]) return false;
+		}
+		else
+		{
+			if (nSolarDay > nNormalMonth[nSolarMonth - 1]) return false;
+		}
+
+		return true;
+	}
+
+	/************************************************************************/
+	/*  函数:DayOfSolarYear[2/23/2017 Jeff];
+	/*  描述:计算这个公历日期是这一年中的第几天;
+	/*  参数:;
+	/*  	[IN] nSolarYear:输入的公历年;
+	/*  	[IN] nSolarMonth:输入的公历月;
+	/*  	[IN] nSolarDay:输入的公历日;
+	/*  返回:如果日期正确,返回公历日期在这一年中的第几天; 否则返回-1;
+	/*  注意:;
+	/*  示例:;
+	/*
+	/*  修改:;
+	/*  日期:;
+	/*  内容:;
+	/************************************************************************/
+	int DayOfSolarYear(IN const int &nSolarYear,IN const int &nSolarMonth, IN const int &nSolarDay)
+	{
+		if( !IsValidSolarDate(nSolarYear,nSolarMonth,nSolarDay) )
+			return -1;
+
+		const int *nDaysYear = NORMAL_YDAY;
+
+		//判断是否是公历闰年;
+		if (nSolarYear % 4 == 0)
+		{
+			if (nSolarYear % 100 != 0)
+				nDaysYear = LEAP_YDAY;
+			if (nSolarYear % 400 == 0)
+				nDaysYear = LEAP_YDAY;
+		}
+
+		return nDaysYear[nSolarMonth - 1] + nSolarDay;
+	}
+
+	/************************************************************************/
+	/*  函数:SolarToLuanrDate[2/23/2017 Jeff];
+	/*  描述:将公历日期转为对应的农历日期;
+	/*  参数:;
+	/*  	[IN] nSolarYear:输入的公历年;
+	/*  	[IN] nSolarMonth:输入的公历月;
+	/*  	[IN] nSolarDay:输入的公历日;
+	/*		[OUT] lnaDate:公历日期有效转换的农历日期;
+	/*  返回:日期有效且转换成功返回true;
+	/*  注意:;
+	/*  示例:;
+	/*
+	/*  修改:;
+	/*  日期:;
+	/*  内容:;
+	/************************************************************************/
+	bool SolarToLuanrDate(IN const int &nSolarYear,IN const int &nSolarMonth, IN const int &nSolarDay, OUT LunarDate &lnaDate )
+	{
+		if( !IsValidSolarDate(nSolarYear,nSolarMonth,nSolarDay) )
+			return false;
+
+		lnaDate.nYear = nSolarYear;
+		// 越界检查,如果越界,返回无效日期;
+		if (nSolarYear <= BEGIN_YEAR || nSolarYear > BEGIN_YEAR + NUMBER_YEAR - 1)
+			return false;
+
+		int nIndexYear = nSolarYear - BEGIN_YEAR;
+
+		//////////////////////////////////////////////////////////////////////////
+		// 计算春节的公历日期;
+		// 春节:Spring Festival 或者 Chinese new Year;
+		// 春节的公历月份;
+		int nSpringMonth = (LUNAR_YEARS[nIndexYear] & 0x60) >> 5;
+		// 春节的公历日号;
+		int nSpringDay = (LUNAR_YEARS[nIndexYear] & 0x1F);
+
+		// 计算今天是公历年的第几天;
+		int nTodayInSolarYear = DayOfSolarYear(nSolarYear, nSolarMonth, nSolarDay);
+		if( nTodayInSolarYear == -1 )
+			return false;
+
+		// 计算春节是公历年的第几天;
+		int nSpringDayInSolarYear = DayOfSolarYear(nSolarYear, nSpringMonth, nSpringDay);
+		if( nSpringDayInSolarYear == -1 )
+			return false;
+
+		// 计算今天是农历年的第几天 = 农历今天在的公历第几天 - 今年农历春节在公历的第几天;
+		int nTodayInLunarYear = nTodayInSolarYear - nSpringDayInSolarYear + 1;
+
+		// 如果今天在春节的前面,重新计算today_luanr_yd;
+		if ( nTodayInLunarYear <= 0 )
+		{
+			// 农历年比当前公历年小1;
+			nIndexYear--;
+			lnaDate.nYear--;
+
+			// 越界,返回无效日期;
+			if (nIndexYear < 0)
+				return false;
+
+			// 去年农历春节月;
+			nSpringMonth = (LUNAR_YEARS[nIndexYear] & 0x60) >> 5;
+			// 去年农历春节日;
+			nSpringDay = (LUNAR_YEARS[nIndexYear] & 0x1F);
+			// 去年公历年共多少天;
+			int nDaysSolarYear = DayOfSolarYear(lnaDate.nYear, 12, 31);
+			if( nDaysSolarYear == -1)
+				return false;
+
+			nSpringDayInSolarYear = DayOfSolarYear(nSolarYear, nSpringMonth, nSpringDay);
+			if(nSpringDayInSolarYear == -1)
+				return false;
+			// 计算今天是农历年的第几天;
+			nTodayInLunarYear = nTodayInSolarYear + nDaysSolarYear - nSpringDayInSolarYear + 1;
+
+		}
+
+		int nLunarMonth = 1;
+		// 计算月份和日期;
+		for (; nLunarMonth <= 13; nLunarMonth++)
+		{
+			int nMonthDays = 29;
+			if ((LUNAR_YEARS[nIndexYear] >> (7 + 13 - nLunarMonth)) & 0x1)
+				nMonthDays = 30;
+
+			if (nTodayInLunarYear <= nMonthDays)
+				break;
+			else
+				nTodayInLunarYear -= nMonthDays;
+		}
+
+		lnaDate.nDay = nTodayInLunarYear;
+
+		// 处理闰月;
+		int nLeapMonth = (LUNAR_YEARS[nIndexYear] >> 20) & 0xf;
+		if (nLeapMonth > 0 && nLeapMonth < nLunarMonth)
+		{
+			nLunarMonth--;
+			// 如果当前月为闰月,设置闰月标志;
+			if (nLunarMonth == nLeapMonth)
+				lnaDate.bIsLeapMonth = true;
+		}
+
+		if ( nLeapMonth > 12 )
+			return false;
+
+		lnaDate.nMonth = nLunarMonth;
+
+		return true;
+	}
+
+	/************************************************************************/
+	/*  函数:SolarToLuanrDate[2/23/2017 Jeff];
+	/*  描述:将公历日期转为对应的农历日期;
+	/*  参数:;
+	/*  	[IN] nSolarYear:输入的公历年;
+	/*  	[IN] nSolarMonth:输入的公历月;
+	/*  	[IN] nSolarDay:输入的公历日;
+	/*		[OUT] lpLunarDate:公历日期有效转换的农历日期;
+	/*  返回:日期有效且转换成功返回true;
+	/*  注意:;
+	/*  示例:;
+	/*
+	/*  修改:;
+	/*  日期:;
+	/*  内容:;
+	/************************************************************************/
+	bool SolarToLuanrDate(IN const int &nSolarYear, IN const int &nSolarMonth, IN const int &nSolarDay,OUT TCHAR* lpLunarDate)
+	{
+		if( !IsValidSolarDate(nSolarYear,nSolarMonth,nSolarDay) )
+			return false;
+
+		LunarDate lnaDate;
+		lnaDate.nYear = nSolarYear;
+		lnaDate.nMonth = 0;
+		lnaDate.nDay = 0;
+		lnaDate.bIsLeapMonth = false;
+
+		// 越界检查,如果越界,返回无效日期;
+		if ( nSolarYear <= BEGIN_YEAR || nSolarYear > BEGIN_YEAR + NUMBER_YEAR - 1 )
+			return false;
+
+		int nIndexYear = nSolarYear - BEGIN_YEAR;
+
+		//////////////////////////////////////////////////////////////////////////
+		// 计算春节的公历日期;
+		// 春节:Spring Festival 或者 Chinese new Year;
+		// 春节的公历月份;
+		int nSpringMonth = (LUNAR_YEARS[nIndexYear] & 0x60) >> 5;
+		// 春节的公历日号;
+		int nSpringDay = (LUNAR_YEARS[nIndexYear] & 0x1F);
+
+		// 计算今天是公历年的第几天;
+		int nTodayInSolarYear = DayOfSolarYear(nSolarYear, nSolarMonth, nSolarDay);
+		if ( nTodayInSolarYear == -1 )
+			return false;
+
+		// 计算春节是公历年的第几天;
+		int nSpringDayInSolarYear = DayOfSolarYear(nSolarYear, nSpringMonth, nSpringDay);
+		if ( nSpringDayInSolarYear == -1 )
+			return false;
+
+		// 计算今天是农历年的第几天 = 农历今天在的公历第几天 - 今年农历春节在公历的第几天;
+		int nTodayInLunarYear = nTodayInSolarYear - nSpringDayInSolarYear + 1;
+
+		// 如果今天在春节的前面,重新计算today_luanr_yd;
+		if (nTodayInLunarYear <= 0)
+		{
+			// 农历年比当前公历年小1;
+			nIndexYear--;
+			lnaDate.nYear--;
+
+			// 越界,返回无效日期;
+			if (nIndexYear < 0)
+				return false;
+
+			// 去年农历春节月;
+			nSpringMonth = (LUNAR_YEARS[nIndexYear] & 0x60) >> 5;
+			// 去年农历春节日;
+			nSpringDay = (LUNAR_YEARS[nIndexYear] & 0x1F);
+			// 去年公历年共多少天;
+			int nDaysSolarYear = DayOfSolarYear(lnaDate.nYear, 12, 31);
+			if (nDaysSolarYear == -1)
+				return false;
+
+			nSpringDayInSolarYear = DayOfSolarYear(nSolarYear, nSpringMonth, nSpringDay);
+			if (nSpringDayInSolarYear == -1)
+				return false;
+
+			// 计算今天是农历年的第几天;
+			nTodayInLunarYear = nTodayInSolarYear + nDaysSolarYear - nSpringDayInSolarYear + 1;
+		}
+
+		int nLunarMonth = 1;
+		//计算月份和日期;
+		for (; nLunarMonth <= 13; nLunarMonth++)
+		{
+			int nMonthDays = 29;
+			if ((LUNAR_YEARS[nIndexYear] >> (7 + 13 - nLunarMonth)) & 0x1)
+				nMonthDays = 30;
+
+			if (nTodayInLunarYear <= nMonthDays)
+				break;
+			else
+				nTodayInLunarYear -= nMonthDays;
+		}
+
+		lnaDate.nDay = nTodayInLunarYear;
+
+		//处理闰月;
+		int nLeapMonth = (LUNAR_YEARS[nIndexYear] >> 20) & 0xf;
+		if (nLeapMonth > 0 && nLeapMonth < nLunarMonth)
+		{
+			nLunarMonth--;
+			//如果当前月为闰月,设置闰月标志;
+			if (nLunarMonth == nLeapMonth)
+				lnaDate.bIsLeapMonth = true;
+		}
+
+		if ( nLeapMonth > 12)
+			return false;
+
+		lnaDate.nMonth = nLunarMonth;
+		_stprintf_s(lpLunarDate, 11, _T("%04d-%02d-%02d"),lnaDate.nYear,lnaDate.nMonth,lnaDate.nDay);
+
+		return true;
+	}
+	
+	/************************************************************************/
+	/*  函数:LuanrToSolarDate[2/23/2017 Jeff];
+	/*  描述:将农历日期转为对应的公历日期;
+	/*  参数:;
+	/*  	[IN] nLunarYear:输入的农历年;
+	/*  	[IN] nLunarMonth:输入的农历月;
+	/*  	[IN] nLunarDay:输入的农历日;
+	/*		[OUT] lpSolarDate:农历日期有效转换的公历日期;
+	/*		[IN] bIsLeapMonth:若true,若该年公历有闰月且正好是输入月份,返回闰月对应的公历;
+	/*  返回:转换公历成功返回true;
+	/*  注意:2016-12-20转公历时出错,未纠正;2018-02-29转公历同样出错;
+	/*  示例:;
+	/*
+	/*  修改:;
+	/*  日期:;
+	/*  内容:;
+	/************************************************************************/
+	bool LuanrToSolarDate(IN const int &nLunarYear, IN const int &nLunarMonth, IN const int &nLunarDay, OUT TCHAR* lpSolarDate, IN bool bIsLeapMonth/*=false*/)
+	{
+		// 越界检查,如果越界,返回无效日期;
+		if (nLunarYear <= BEGIN_YEAR || nLunarYear > BEGIN_YEAR + NUMBER_YEAR - 1)
+			return false;
+
+		// 1.判断该农历年是否有闰月;
+		int nIndexYear = nLunarYear - BEGIN_YEAR;
+		int nLeapMonth = (LUNAR_YEARS[nIndexYear] >> 20) & 0xF;
+
+		int nDays = 0;
+		long nMonths = (LUNAR_YEARS[nIndexYear] & 0x0FFF80) >> 7;
+		std::bitset<13> btMonth(nMonths);
+		for ( int i = 0; i < nLunarMonth-1; i++ )
+		{
+			nDays +=  btMonth[i] ? 30 : 29;
+		}
+
+		if ( bIsLeapMonth && nLeapMonth != 0 )
+		{
+			nDays +=  btMonth[nLunarMonth-1] ? 30 : 29;
+		}
+		nDays += nLunarDay;
+
+		// 公历年是否是闰年;
+		bool isLeapYear = false;
+		if ((nLunarYear % 400 == 0) || (nLunarYear % 4 == 0 && nLunarYear % 100 != 0))
+		{
+			isLeapYear = true;
+		}
+		else
+		{
+			isLeapYear = false;
+		}
+
+		// 正月的公历月份;
+		int SolarNewYearMonth = (LUNAR_YEARS[nIndexYear] & 0x000060) >> 5;
+		// 正月初一的公历日期;
+		int SolarNewYearDay = LUNAR_YEARS[nIndexYear] & 0x00001F;
+
+		int nSolarDay = 0;
+		int nSolarDays = 0;
+		int nSolarMonth = -1;
+		int nSolarYear = nLunarYear;
+		if ( isLeapYear )
+		{
+			nSolarDays = LEAP_YDAY[SolarNewYearMonth-1] + SolarNewYearDay + nDays;
+			for ( int i = SolarNewYearMonth; i < 12; i++)
+			{
+				if ( nSolarDays >= LEAP_YDAY[i] && nSolarDays < LEAP_YDAY[i+1])
+				{
+					nSolarMonth = i+1;
+					nSolarDay = nSolarDays - LEAP_YDAY[i] -1;
+				}
+			}
+
+			if ( nSolarMonth == -1 )
+				nSolarDays -= LEAP_YDAY[12];
+		}
+		else
+		{
+			nSolarDays = NORMAL_YDAY[SolarNewYearMonth-1]+ SolarNewYearDay + nDays;
+			for ( int i = SolarNewYearMonth; i < 12; i++)
+			{
+				if ( nSolarDays >= NORMAL_YDAY[i] && nSolarDays < NORMAL_YDAY[i+1])
+				{
+					nSolarMonth = i+1;
+					nSolarDay = nSolarDays - NORMAL_YDAY[i] -1;
+				}
+			}
+
+			if ( nSolarMonth == -1 )
+				nSolarDays -= NORMAL_YDAY[12];
+		}
+
+		if ( nSolarMonth == -1 )
+		{// 超出本年;
+			nSolarYear = nLunarYear+1 ;
+			if ((nSolarYear % 400 == 0) || (nSolarYear % 4 == 0 && nSolarYear % 100 != 0))
+			{
+				isLeapYear = true;
+			}
+			else
+			{
+				isLeapYear = false;
+			}
+
+			if ( isLeapYear )
+			{
+				for ( int i = 0; i < 12; i++)
+				{
+					if ( nSolarDays >= LEAP_YDAY[i] && nSolarDays < LEAP_YDAY[i+1])
+					{
+						nSolarMonth = i+1;
+						nSolarDay = nSolarDays - LEAP_YDAY[i] -1;
+					}
+				}
+			}
+			else
+			{
+				for ( int i = 0; i < 12; i++)
+				{
+					if ( nSolarDays >= NORMAL_YDAY[i] && nSolarDays < NORMAL_YDAY[i+1])
+					{
+						nSolarMonth = i+1;
+						nSolarDay = nSolarDays - NORMAL_YDAY[i] -1;
+					}
+				}
+			}
+		}
+		_stprintf_s(lpSolarDate, 11, _T("%4d-%02d-%02d"), nSolarYear, nSolarMonth, nSolarDay);
+
+		return true;
+	}
+
+	bool LuanrToSolarDate(IN const int &nLunarYear, IN const int &nLunarMonth, IN const int &nLunarDay, OUT LunarDate &lnaDate, IN bool bIsLeapMonth/*=false*/)
+	{
+		// 越界检查,如果越界,返回无效日期;
+		if (nLunarYear <= BEGIN_YEAR || nLunarYear > BEGIN_YEAR + NUMBER_YEAR - 1)
+			return false;
+
+		// 1.判断该农历年是否有闰月;
+		int nIndexYear = nLunarYear - BEGIN_YEAR;
+		int nLeapMonth = (LUNAR_YEARS[nIndexYear] >> 20) & 0xF;
+
+		int nDays = 0;
+		long nMonths = (LUNAR_YEARS[nIndexYear] & 0x0FFF80) >> 7;
+		std::bitset<13> btMonth(nMonths);
+		for ( int i = 0; i < nLunarMonth-1; i++ )
+		{
+			nDays +=  btMonth[i] ? 30 : 29;
+		}
+
+		if ( bIsLeapMonth && nLeapMonth != 0 )
+		{
+			nDays +=  btMonth[nLunarMonth-1] ? 30 : 29;
+		}
+		nDays += nLunarDay;
+
+		// 公历年是否是闰年;
+		bool isLeapYear = false;
+		if ((nLunarYear % 400 == 0) || (nLunarYear % 4 == 0 && nLunarYear % 100 != 0))
+		{
+			isLeapYear = true;
+		}
+		else
+		{
+			isLeapYear = false;
+		}
+
+		// 正月的公历月份;
+		int SolarNewYearMonth = (LUNAR_YEARS[nIndexYear] & 0x000060) >> 5;
+		// 正月初一的公历日期;
+		int SolarNewYearDay = LUNAR_YEARS[nIndexYear] & 0x00001F;
+
+		int nSolarDay = 0;
+		int nSolarDays = 0;
+		int nSolarYear = nLunarYear;
+		int nSolarMonth = -1;
+		if ( isLeapYear )
+		{
+			nSolarDays = LEAP_YDAY[SolarNewYearMonth-1] + SolarNewYearDay + nDays;
+			for ( int i = SolarNewYearMonth; i < 12; i++)
+			{
+				if ( nSolarDays >= LEAP_YDAY[i] && nSolarDays < LEAP_YDAY[i+1])
+				{
+					nSolarMonth = i+1;
+					nSolarDay = nSolarDays - LEAP_YDAY[i] -1;
+				}
+			}
+
+			if ( nSolarMonth == -1 )
+				nSolarDays -= LEAP_YDAY[12];
+		}
+		else
+		{
+			nSolarDays = NORMAL_YDAY[SolarNewYearMonth-1]+ SolarNewYearDay + nDays;
+			for ( int i = SolarNewYearMonth; i < 12; i++)
+			{
+				if ( nSolarDays >= NORMAL_YDAY[i] && nSolarDays < NORMAL_YDAY[i+1])
+				{
+					nSolarMonth = i+1;
+					nSolarDay = nSolarDays - NORMAL_YDAY[i] -1;
+				}
+			}
+
+			if ( nSolarMonth == -1 )
+				nSolarDays -= NORMAL_YDAY[12];
+		}
+
+		if ( nSolarMonth == -1 )
+		{// 超出本年;
+			nSolarYear = nLunarYear+1 ;
+			if ((nSolarYear % 400 == 0) || (nSolarYear % 4 == 0 && nSolarYear % 100 != 0))
+			{
+				isLeapYear = true;
+			}
+			else
+			{
+				isLeapYear = false;
+			}
+
+			if ( isLeapYear )
+			{
+				for ( int i = 0; i < 12; i++)
+				{
+					if ( nSolarDays >= LEAP_YDAY[i] && nSolarDays < LEAP_YDAY[i+1])
+					{
+						nSolarMonth = i+1;
+						nSolarDay = nSolarDays - LEAP_YDAY[i] -1;
+					}
+				}
+			}
+			else
+			{
+				for ( int i = 0; i < 12; i++)
+				{
+					if ( nSolarDays >= NORMAL_YDAY[i] && nSolarDays < NORMAL_YDAY[i+1])
+					{
+						nSolarMonth = i+1;
+						nSolarDay = nSolarDays - NORMAL_YDAY[i] -1;
+					}
+				}
+			}
+		}
+
+		lnaDate.nYear = nSolarYear;
+		lnaDate.nMonth = nSolarMonth;
+		lnaDate.nDay = nSolarDay;
+
+		return true;
+	}
+
+	/************************************************************************/
+	/*  函数:[1/17/2018 Jeff];
+	/*  描述:给农历增加天数;
+	/*  参数:;
+	/*  	[IN] :;
+	/*  	[OUT] :;
+	/*  	[IN/OUT] :;
+	/*  返回:void;
+	/*  注意:;
+	/*  示例:;
+	/*
+	/*  修改:;
+	/*  日期:;
+	/*  内容:;
+	/************************************************************************/
+	void SolarDateAddDay(struct tm &tmSolar, int nDays = 1)
+	{
+		// 参数校验;
+		if ((tmSolar.tm_mday <= 0) || (tmSolar.tm_mday > 31) || (tmSolar.tm_mon < 0) || (tmSolar.tm_mon > 11)) 
+			return ;
+
+		if ((tmSolar.tm_year % 400 == 0) || (tmSolar.tm_year % 4 == 0 && tmSolar.tm_year % 100 != 0))
+		{// 如果是闰年;
+			int nDValue = nLeapMonth[tmSolar.tm_mon - 1] - tmSolar.tm_mday - nDays;
+			if (nDValue < 0) 
+			{
+				// 月份加1;
+				if ( tmSolar.tm_mon != 11 )
+				{
+					++tmSolar.tm_mon;
+					tmSolar.tm_mday -= nDValue;
+				}
+				else
+				{// 年月加1,月份和天数变成1;
+					++tmSolar.tm_year;
+					tmSolar.tm_mon = 1;
+					tmSolar.tm_mday = 1;
+				}
+			}
+		}
+		else
+		{
+			if (tmSolar.tm_mday > nNormalMonth[tmSolar.tm_mon - 1]) 
+				return;
+		}
+	}
+
+	/************************************************************************/
+	/*  函数:[2/23/2017 Jeff];
+	/*  描述:判断输入的农历日期的月份是否有闰月;
+	/*  参数:;
+	/*  	[IN] nLunarYear:农历年;
+	/*  	[OUT] :;
+	/*  	[IN/OUT] :;
+	/*  返回:若有闰月返回闰月值,否则返回0;
+	/*  注意:;
+	/*  示例:;
+	/*
+	/*  修改:;
+	/*  日期:;
+	/*  内容:;
+	/************************************************************************/
+	int IsLeapMonth(IN const int &nLunarYear)
+	{
+		// 越界检查,如果越界,返回无效日期;
+		if (nLunarYear <= BEGIN_YEAR || nLunarYear > BEGIN_YEAR + NUMBER_YEAR - 1)
+			return -1;
+
+		// 1.判断该农历年是否有闰月;
+		return (LUNAR_YEARS[nLunarYear - BEGIN_YEAR] >> 20) & 0xF;
+	}
+
+	/************************************************************************/
+	/*  函数:获取年龄[2/23/2017 Jeff];
+	/*  描述:;
+	/*  参数:;
+	/*  	[IN] lpLunarBirthDay:公历生日;
+	/*  	[OUT] :;
+	/*  	[IN/OUT] :;
+	/*  返回:void;
+	/*  注意:2014-11-22农历生日, 在2018-;
+	/*  示例:;
+	/*
+	/*  修改:;
+	/*  日期:;
+	/*  内容:;
+	/************************************************************************/
+	int GetAge(IN const TCHAR* lpLunarBirthDay, IN bool bIsLeapMonth /*= false*/)
+	{
+		if ( !IsValidLunanrDate(lpLunarBirthDay) )
+			return -1;
+
+		// 1.将农历转成公历;
+#ifdef USE_MFC
+		CString strLunarDate = lpLunarBirthDay;
+		int nLunarYear = _ttoi(strLunarDate.Left(4));
+		int nLunarMonth = _ttoi(strLunarDate.Mid(5, 2));
+		int nLunarDay = _ttoi(strLunarDate.Mid(8, 2));
+#else
+#ifdef UNICODE
+		std::wstring strLunarDate = lpLunarBirthDay;
+#else
+		std::string strLunarDate = lpLunarBirthDay;		
+#endif
+		int nLunarYear = _ttoi(strLunarDate.substr(0,4).c_str());
+		int nLunarMonth = _ttoi(strLunarDate.substr(5, 2).c_str());
+		int nLunarDay = _ttoi(strLunarDate.substr(8, 2).c_str());
+#endif
+		// 获取今年年份;
+		__time64_t gmt = time(NULL);// 获取当前日历时间(1900-01-01开始的Unix时间戳);
+		struct tm gmtm = {0};
+		//gmtime_s(&gmtm, &gmt); // 时间戳转成UTC时间(也叫GMT时间);
+		localtime_s(&gmtm, &gmt); // 时间戳转成本地时间;
+		// 获取今天的农历日期;
+		LunarDate lunarToday;
+		if ( SolarToLuanrDate(gmtm.tm_year + 1900, gmtm.tm_mon+1, gmtm.tm_mday, lunarToday) )
+		{
+			LunarDate solarBirthday;
+			if ( LuanrToSolarDate(lunarToday.nYear, nLunarMonth, nLunarDay, solarBirthday, bIsLeapMonth) )
+			{
+				struct tm bdtm = {0};
+				bdtm.tm_year = solarBirthday.nYear - 1900;
+				bdtm.tm_mon = solarBirthday.nMonth - 1;
+				bdtm.tm_mday = solarBirthday.nDay;
+
+				__time64_t bdgmt = _mkgmtime64(&bdtm);
+				if (bdgmt >= gmt )// 不满周年;
+					return lunarToday.nYear - nLunarYear - 1;
+				else// 满周年;
+					return lunarToday.nYear - nLunarYear;
+			}
+		}
+
+		return -1;
+	}
+};

+ 88 - 0
LunarCalendar/Test/CalendarEx.h

@@ -0,0 +1,88 @@
+#ifndef __CALENDAREX_20160127__
+#define __CALENDAREX_20160127__
+
+#pragma once
+
+#ifndef IN
+#define IN
+#endif
+
+#ifndef OUT
+#define OUT
+#endif
+
+namespace CalendarEx
+{
+	//保存一个农历日期;
+	typedef struct _STLUNARDATE_ 
+	{
+		int		nYear;
+		int		nMonth;
+		int		nDay;
+		bool	bIsLeapMonth;	//是否闰月;
+
+		_STLUNARDATE_()	{
+			nYear = 0;
+			nMonth = 0;
+			nDay = 0;
+			bIsLeapMonth = false;
+		}
+	} LunarDate, *pLunarDate;
+
+	// 农历日期有效性;
+	bool IsValidLunanrDate(IN const TCHAR* lpLunarDate );
+	// 农历日期有效性;
+	bool IsValidLunanrDate(IN const int &nLunarYear, IN const int &nLunarMonth, IN const int &nLunarDay);
+	// 公历日期有效性;
+	bool IsValidSolarDate(IN const TCHAR* lpSolarDate);
+	// 公历日期有效性;	
+	bool IsValidSolarDate(
+		IN const int &nSolarYear, 
+		IN const int &nSolarMonth, 
+		IN const int &nSolarDay);
+	// 返回指定日期在当年的第几天;
+	int DayOfSolarYear(
+		IN const int &nSolarYear,
+		IN const int &nSolarMonth, 
+		IN const int &nSolarDay);
+	// 返回指定日期在当年的第几周;
+	int DayOfSolarWeek(
+		IN const int &nSolarYear,
+		IN const int &nSolarMonth, 
+		IN const int &nSolarDay);
+	// 公历转农历;
+	bool SolarToLuanrDate(
+		IN const int &nSolarYear,
+		IN const int &nSolarMonth, 
+		IN const int &nSolarDay, 
+		OUT LunarDate &lnaDate);
+	// 公历转农历;
+	bool SolarToLuanrDate(
+		IN const int &nSolarYear, 
+		IN const int &nSolarMonth, 
+		IN const int &nSolarDay,
+		OUT TCHAR* lpLunarDate);
+	// 农历转公历;
+	bool LuanrToSolarDate(
+		IN const int &nLunarYear, 
+		IN const int &nLunarMonth, 
+		IN const int &nLunarDay, 
+		OUT LunarDate &lnaDate,
+		IN bool bIsLeapMonth = false );
+
+	bool LuanrToSolarDate(
+		IN const int &nLunarYear, 
+		IN const int &nLunarMonth, 
+		IN const int &nLunarDay, 
+		OUT TCHAR* lpSolarDate,
+		IN bool bIsLeapMonth = false );
+
+	bool LuanrToSolarDate( IN const TCHAR* lpLunarDate, OUT TCHAR* lpSolarDate, IN bool bIsLeapMonth = false);
+
+	// 返回某一年的闰月月份;
+	int IsLeapMonth(IN const int &nLunarYear);
+	// 计算年龄,返回周岁;
+	int GetAge(IN const TCHAR* lpLunarBirthDay, IN bool bIsLeapMonth = false);
+};
+
+#endif

+ 520 - 0
LunarCalendar/Test/LunarCalendar.cpp

@@ -0,0 +1,520 @@
+#include "StdAfx.h"
+#include "LunarCalendar.h"
+
+namespace CalendarEx
+{
+	//////////////////////////////////////////////////////////////////////////
+	// 全局定义;
+	// const static INT BEGIN_YEAR = 1901;
+	// const static INT NUMBER_YEAR = 199;
+	#define BEGIN_YEAR 1901
+	#define NUMBER_YEAR 199
+
+	const static INT nNormalMonth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+	const static INT nLeapMonth[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+
+	//为了提高效率,记录每月一日是一年中的第几天;
+	// 平年的情况;
+	const static INT NORMAL_YDAY[12] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
+	// 闰年的情况;
+	const static INT LEAP_YDAY[12] = { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 };
+
+	// 使用比特位记录每年的情况
+	// 0~4 共5bit 春节日份
+	// 5~6 共2bit 春节月份
+	// 7~19 共13bit 13个月的大小月情况(如果无闰月,最后位无效),大月为1,小月为0
+	// 20~23 共4bit 记录闰月的月份,如果没有闰月为0
+	const static DWORD LUNAR_YEARS[199] =
+	{
+		0x04AE53, 0x0A5748, 0x5526BD, 0x0D2650, 0x0D9544, 0x46AAB9, 0x056A4D, 0x09AD42, 0x24AEB6, 0x04AE4A, //1901-1910
+		0x6A4DBE, 0x0A4D52, 0x0D2546, 0x5D52BA, 0x0B544E, 0x0D6A43, 0x296D37, 0x095B4B, 0x749BC1, 0x049754, //1911-1920
+		0x0A4B48, 0x5B25BC, 0x06A550, 0x06D445, 0x4ADAB8, 0x02B64D, 0x095742, 0x2497B7, 0x04974A, 0x664B3E, //1921-1930
+		0x0D4A51, 0x0EA546, 0x56D4BA, 0x05AD4E, 0x02B644, 0x393738, 0x092E4B, 0x7C96BF, 0x0C9553, 0x0D4A48, //1931-1940
+		0x6DA53B, 0x0B554F, 0x056A45, 0x4AADB9, 0x025D4D, 0x092D42, 0x2C95B6, 0x0A954A, 0x7B4ABD, 0x06CA51, //1941-1950
+		0x0B5546, 0x555ABB, 0x04DA4E, 0x0A5B43, 0x352BB8, 0x052B4C, 0x8A953F, 0x0E9552, 0x06AA48, 0x7AD53C, //1951-1960
+		0x0AB54F, 0x04B645, 0x4A5739, 0x0A574D, 0x052642, 0x3E9335, 0x0D9549, 0x75AABE, 0x056A51, 0x096D46, //1961-1970
+		0x54AEBB, 0x04AD4F, 0x0A4D43, 0x4D26B7, 0x0D254B, 0x8D52BF, 0x0B5452, 0x0B6A47, 0x696D3C, 0x095B50, //1971-1980
+		0x049B45, 0x4A4BB9, 0x0A4B4D, 0xAB25C2, 0x06A554, 0x06D449, 0x6ADA3D, 0x0AB651, 0x093746, 0x5497BB, //1981-1990
+		0x04974F, 0x064B44, 0x36A537, 0x0EA54A, 0x86B2BF, 0x05AC53, 0x0AB647, 0x5936BC, 0x092E50, 0x0C9645, //1991-2000
+		0x4D4AB8, 0x0D4A4C, 0x0DA541, 0x25AAB6, 0x056A49, 0x7AADBD, 0x025D52, 0x092D47, 0x5C95BA, 0x0A954E, //2001-2010
+		0x0B4A43, 0x4B5537, 0x0AD54A, 0x955ABF, 0x04BA53, 0x0A5B48, 0x652BBC, 0x052B50, 0x0A9345, 0x474AB9, //2011-2020
+		0x06AA4C, 0x0AD541, 0x24DAB6, 0x04B64A, 0x69573D, 0x0A4E51, 0x0D2646, 0x5E933A, 0x0D534D, 0x05AA43, //2021-2030
+		0x36B537, 0x096D4B, 0xB4AEBF, 0x04AD53, 0x0A4D48, 0x6D25BC, 0x0D254F, 0x0D5244, 0x5DAA38, 0x0B5A4C, //2031-2040
+		0x056D41, 0x24ADB6, 0x049B4A, 0x7A4BBE, 0x0A4B51, 0x0AA546, 0x5B52BA, 0x06D24E, 0x0ADA42, 0x355B37, //2041-2050
+		0x09374B, 0x8497C1, 0x049753, 0x064B48, 0x66A53C, 0x0EA54F, 0x06B244, 0x4AB638, 0x0AAE4C, 0x092E42, //2051-2060
+		0x3C9735, 0x0C9649, 0x7D4ABD, 0x0D4A51, 0x0DA545, 0x55AABA, 0x056A4E, 0x0A6D43, 0x452EB7, 0x052D4B, //2061-2070
+		0x8A95BF, 0x0A9553, 0x0B4A47, 0x6B553B, 0x0AD54F, 0x055A45, 0x4A5D38, 0x0A5B4C, 0x052B42, 0x3A93B6, //2071-2080
+		0x069349, 0x7729BD, 0x06AA51, 0x0AD546, 0x54DABA, 0x04B64E, 0x0A5743, 0x452738, 0x0D264A, 0x8E933E, //2081-2090
+		0x0D5252, 0x0DAA47, 0x66B53B, 0x056D4F, 0x04AE45, 0x4A4EB9, 0x0A4D4C, 0x0D1541, 0x2D92B5 //2091-2099
+	};
+
+	//	如:
+	//	0x955ABF
+	//	1001 0101010110101  01    11111
+	//	闰月月份 7-19.13个月 春月  春日;
+
+	//////////////////////////////////////////////////////////////////////////
+	// 函数实现;
+	BOOL IsValidLunanrDate(IN LPCTSTR lpLunarDate)
+	{
+		if (lpLunarDate == NULL || _tcslen(lpLunarDate) != 10 )
+			return FALSE;
+
+		CString strLunarDate = lpLunarDate;
+		if (strLunarDate.IsEmpty()) return FALSE;
+
+		static INT nLunarYear, nLunarMonth, nLunarDay;
+		nLunarYear = nLunarMonth = nLunarDay = 0;
+
+		nLunarYear = _ttoi(strLunarDate.Left(4));
+		nLunarMonth = _ttoi(strLunarDate.Mid(5, 2));
+		nLunarDay = _ttoi(strLunarDate.Mid(8, 2));
+
+		//越界检查,如果越界,返回无效日期;
+		if (nLunarYear <= BEGIN_YEAR || nLunarYear > BEGIN_YEAR + NUMBER_YEAR - 1)
+			return FALSE;
+
+		if (nLunarMonth < 1 || nLunarMonth > 12)
+			return FALSE;
+
+		// 1.农历年是否有闰月;
+		INT nYearIndex = nLunarYear - BEGIN_YEAR;
+		INT nLeapMonth = (LUNAR_YEARS[nYearIndex] >> 20) & 0xF;
+
+		// 2.月份大小月天数;
+		INT nMonthDays = 0;
+		if ((LUNAR_YEARS[nYearIndex] >> (7 + 13 - nLunarMonth)) & 0x1)
+			nMonthDays = 30;
+		else
+			nMonthDays = 29;
+
+		if (nLunarDay < 0 || nLunarDay > nMonthDays)
+			return FALSE;
+
+		return TRUE;
+	}
+
+	BOOL IsValidLunanrDate(IN INT nLunarYear, IN INT nLunarMonth, IN INT nLunarDay)
+	{
+		//越界检查,如果越界,返回无效日期;
+		if (nLunarYear <= BEGIN_YEAR || nLunarYear > BEGIN_YEAR + NUMBER_YEAR - 1)
+			return FALSE;
+
+		if (nLunarMonth < 1 || nLunarMonth > 12)
+			return FALSE;
+
+		// 1.农历年是否有闰月;
+		INT nYearIndex = nLunarYear - BEGIN_YEAR;
+		INT nLeapMonth = (LUNAR_YEARS[nYearIndex] >> 20) & 0xF;
+
+		// 2.月份大小月天数;
+		INT nMonthDays = 0;
+		if ((LUNAR_YEARS[nYearIndex] >> (7 + 13 - nLunarMonth)) & 0x1)
+			nMonthDays = 30;
+		else
+			nMonthDays = 29;
+
+		if (nLunarDay < 0 || nLunarDay > nMonthDays)
+			return FALSE;
+
+		return TRUE;
+	}
+
+	// ------------------------------------------------------------------------------------------------------------------------
+	// 对外接口函数
+	//
+	// 函数:IsValidSolarDate
+	// 描述:判断日期是否有效;
+	// 参数:
+	//		strDate	格式如:2014-01-02 或 2014/01/02;
+	// 返回:有效;
+	//
+	// ------------------------------------------------------------------------------------------------------------------------
+	BOOL IsValidSolarStrDate(IN LPCTSTR lpSolarDate, IN BOOL bThisyear)
+	{
+		if (lpSolarDate == NULL || _tcslen(lpSolarDate) != 10) return FALSE;
+
+		CString strSolarDate = lpSolarDate;
+
+		// 判断日期合法性;
+		static int nSolarYear = 0;
+		static int nSolarMonth = 0;
+		static int nSolarDay = 0;
+
+		nSolarYear = nSolarMonth = nSolarDay = 0;
+
+		if (bThisyear)
+			nSolarYear = CTime::GetCurrentTime().GetYear();
+		else
+			nSolarYear = _ttoi(strSolarDate.Left(4));
+
+		nSolarMonth = _ttoi(strSolarDate.Mid(5, 2));
+		nSolarDay = _ttoi(strSolarDate.Mid(8, 2));
+
+		if ((nSolarDay <= 0) || (nSolarDay > 31) || (nSolarMonth <= 0) || (nSolarMonth > 12)) return FALSE;
+
+		if ((nSolarYear % 400 == 0) || (nSolarYear % 4 == 0 && nSolarYear % 100 != 0))
+		{
+			if (nSolarDay > nLeapMonth[nSolarMonth - 1])	return FALSE;
+		}
+		else
+		{
+			if (nSolarDay > nNormalMonth[nSolarMonth - 1]) return FALSE;
+		}
+
+		return TRUE;
+	}
+
+	// ------------------------------------------------------------------------------------------------------------------------
+	// 对外接口函数
+	//
+	// 函数:IsValidSolarDate
+	// 描述:判断日期是否有效;
+	// 参数:
+	//		nSolarYear		公历年;
+	//		nSolarMonth		公历月;
+	//		nSolarDay		公历日;
+	// 返回:有效;
+	//
+	// ------------------------------------------------------------------------------------------------------------------------
+	BOOL IsValidSolarDate(IN CONST INT &nSolarYear, IN CONST INT &nSolarMonth, IN CONST INT &nSolarDay)
+	{
+		if (nSolarYear < 0 ) return FALSE;
+
+		// 判断日期合法性;
+		if ((nSolarDay <= 0) || (nSolarDay > 31) || (nSolarMonth <= 0) || (nSolarMonth > 12)) return FALSE;
+
+		if ((nSolarYear % 400 == 0) || (nSolarYear % 4 == 0 && nSolarYear % 100 != 0))
+		{
+			if (nSolarDay > nLeapMonth[nSolarMonth - 1])	return FALSE;
+		}
+		else
+		{
+			if (nSolarDay > nNormalMonth[nSolarMonth - 1]) return FALSE;
+		}
+
+		return TRUE;
+	}
+
+
+	// ------------------------------------------------------------------------------------------------------------------------
+	// 对外接口函数
+	//
+	// 函数:DayOfSolarYear
+	// 描述:计算这个公历日期是这一年中的第几天
+	// 参数:
+	//		nSolarYear		公历年;
+	//		nSolarMonth		公历月;
+	//		nSolarDay		公历日;
+	// 返回:如果日期正确,返回公历日期在这一年中的第几天; 否则返回-1;
+	//
+	// ------------------------------------------------------------------------------------------------------------------------
+	INT DayOfSolarYear(IN CONST INT &nSolarYear,IN CONST INT &nSolarMonth, IN CONST INT &nSolarDay)
+	{
+		if( !IsValidSolarDate(nSolarYear,nSolarMonth,nSolarDay) )
+			return -1;
+
+		const INT *nDaysYear = NORMAL_YDAY;
+
+		//判断是否是公历闰年;
+		if (nSolarYear % 4 == 0)
+		{
+			if (nSolarYear % 100 != 0)
+				nDaysYear = LEAP_YDAY;
+			if (nSolarYear % 400 == 0)
+				nDaysYear = LEAP_YDAY;
+		}
+
+		return nDaysYear[nSolarMonth - 1] + nSolarDay;
+	}
+
+	// ------------------------------------------------------------------------------------------------------------------------
+	// 函数:SolarToLuanrDate
+	// 描述:将公历日期转为对应的农历日期
+	// 参数:
+	//		nSolarYear		公历年;
+	//		nSolarMonth		公历月;
+	//		nSolarDay		公历日;
+	// 返回:返回结构体;
+	//
+	// ------------------------------------------------------------------------------------------------------------------------
+	INT SolarToLuanrDate(IN CONST INT &nSolarYear,IN CONST INT &nSolarMonth, IN CONST INT &nSolarDay, OUT LunarDate &lnaDate )
+	{
+		if( !IsValidSolarDate(nSolarYear,nSolarMonth,nSolarDay) )
+			return -1;
+
+		lnaDate.nYear = nSolarYear;
+		// 越界检查,如果越界,返回无效日期;
+		if (nSolarYear <= BEGIN_YEAR || nSolarYear > BEGIN_YEAR + NUMBER_YEAR - 1)
+			return -1;
+
+		INT nIndexYear = nSolarYear - BEGIN_YEAR;
+
+		//////////////////////////////////////////////////////////////////////////
+		// 计算春节的公历日期;
+		// 春节:Spring Festival 或者 Chinese new Year;
+		// 春节的公历月份;
+		INT nSpringMonth = (LUNAR_YEARS[nIndexYear] & 0x60) >> 5;
+		// 春节的公历日号;
+		INT nSpringDay = (LUNAR_YEARS[nIndexYear] & 0x1F);
+
+		// 计算今天是公历年的第几天;
+		INT nTodayInSolarYear = DayOfSolarYear(nSolarYear, nSolarMonth, nSolarDay);
+		if( nTodayInSolarYear == -1 )
+			return -1;
+
+		// 计算春节是公历年的第几天;
+		INT nSpringDayInSolarYear = DayOfSolarYear(nSolarYear, nSpringMonth, nSpringDay);
+		if( nSpringDayInSolarYear == -1 )
+			return -1;
+
+		// 计算今天是农历年的第几天 = 农历今天在的公历第几天 - 今年农历春节在公历的第几天;
+		INT nTodayInLunarYear = nTodayInSolarYear - nSpringDayInSolarYear + 1;
+
+		// 如果今天在春节的前面,重新计算today_luanr_yd;
+		if ( nTodayInLunarYear <= 0 )
+		{
+			// 农历年比当前公历年小1;
+			nIndexYear--;
+			lnaDate.nYear--;
+
+			// 越界,返回无效日期;
+			if (nIndexYear < 0)
+				return -1;
+
+			// 去年农历春节月;
+			nSpringMonth = (LUNAR_YEARS[nIndexYear] & 0x60) >> 5;
+			// 去年农历春节日;
+			nSpringDay = (LUNAR_YEARS[nIndexYear] & 0x1F);
+			// 去年公历年共多少天;
+			int nDaysSolarYear = DayOfSolarYear(lnaDate.nYear, 12, 31);
+			if( nDaysSolarYear == -1)
+				return -1;
+
+			nSpringDayInSolarYear = DayOfSolarYear(nSolarYear, nSpringMonth, nSpringDay);
+			if(nSpringDayInSolarYear == -1)
+				return -1;
+			// 计算今天是农历年的第几天;
+			nTodayInLunarYear = nTodayInSolarYear + nDaysSolarYear - nSpringDayInSolarYear + 1;
+
+		}
+
+		INT nLunarMonth = 1;
+
+		// 计算月份和日期;
+		for (; nLunarMonth <= 13; nLunarMonth++)
+		{
+			INT nMonthDays = 29;
+			if ((LUNAR_YEARS[nIndexYear] >> (7 + 13 - nLunarMonth)) & 0x1)
+				nMonthDays = 30;
+
+			if (nTodayInLunarYear <= nMonthDays)
+				break;
+			else
+				nTodayInLunarYear -= nMonthDays;
+		}
+
+		lnaDate.nDay = nTodayInLunarYear;
+
+		// 处理闰月;
+		INT nLeapMonth = (LUNAR_YEARS[nIndexYear] >> 20) & 0xf;
+		if (nLeapMonth > 0 && nLeapMonth < nLunarMonth)
+		{
+			nLunarMonth--;
+			// 如果当前月为闰月,设置闰月标志;
+			if (nLunarMonth == nLeapMonth)
+				lnaDate.bIsLeapMonth = true;
+		}
+
+		if ( nLeapMonth > 12 )
+			return -1;
+
+		lnaDate.nMonth = nLunarMonth;
+
+		return 0L;
+	}
+
+
+	// ------------------------------------------------------------------------------------------------------------------------
+	// 对外接口函数
+	//
+	// 函数:GetLunarDate
+	// 描述:将公历日期转为对应的农历日期
+	// 参数:
+	//		nSolarYear		公历年;
+	//		nSolarMonth		公历月;
+	//		nSolarDay		公历日;
+	// 返回:暂时未细致处理返回值的定义,错误的值都为负数;
+	// ------------------------------------------------------------------------------------------------------------------------
+	INT GetLunarDate(IN CONST int &nSolarYear, IN CONST int &nSolarMonth, IN CONST int &nSolarDay,OUT LPTSTR lpLunarDate)
+	{
+		if( !IsValidSolarDate(nSolarYear,nSolarMonth,nSolarDay) )
+			return -1;
+
+		LunarDate lnaDate;
+		lnaDate.nYear = nSolarYear;
+		lnaDate.nMonth = 0;
+		lnaDate.nDay = 0;
+		lnaDate.bIsLeapMonth = false;
+
+		// 越界检查,如果越界,返回无效日期;
+		if ( nSolarYear <= BEGIN_YEAR || nSolarYear > BEGIN_YEAR + NUMBER_YEAR - 1 )
+			return -2;
+
+		INT nIndexYear = nSolarYear - BEGIN_YEAR;
+
+		// 计算春节的公历日期;
+		INT nSpringMonth = (LUNAR_YEARS[nIndexYear] & 0x60) >> 5;
+		INT nSpringDay = (LUNAR_YEARS[nIndexYear] & 0x1F);
+
+		// 计算今天是公历年的第几天;
+		INT nTodayInSolarYear = DayOfSolarYear(nSolarYear, nSolarMonth, nSolarDay);
+		if ( nTodayInSolarYear == -1 )
+			return -3;
+
+		// 计算春节是公历年的第几天;
+		INT nSpringDayInSolarYear = DayOfSolarYear(nSolarYear, nSpringMonth, nSpringDay);
+		if ( nSpringDayInSolarYear == -1 )
+			return -4;
+
+		// 计算今天是农历年的第几天 = 农历今天在的公历第几天 - 今年农历春节在公历的第几天;
+		INT nTodayInLunarYear = nTodayInSolarYear - nSpringDayInSolarYear + 1;
+
+		// 如果今天在春节的前面,重新计算today_luanr_yd;
+		if (nTodayInLunarYear <= 0)
+		{
+			// 农历年比当前公历年小1;
+			nIndexYear--;
+			lnaDate.nYear--;
+
+			// 越界,返回无效日期;
+			if (nIndexYear < 0)
+				return -2;
+
+			// 去年农历春节月;
+			nSpringMonth = (LUNAR_YEARS[nIndexYear] & 0x60) >> 5;
+			// 去年农历春节日;
+			nSpringDay = (LUNAR_YEARS[nIndexYear] & 0x1F);
+			// 去年公历年共多少天;
+			INT nDaysSolarYear = DayOfSolarYear(lnaDate.nYear, 12, 31);
+			if (nDaysSolarYear == -1)
+				return -1;
+
+			nSpringDayInSolarYear = DayOfSolarYear(nSolarYear, nSpringMonth, nSpringDay);
+			if (nSpringDayInSolarYear == -1)
+				return -1;
+
+			// 计算今天是农历年的第几天;
+			nTodayInLunarYear = nTodayInSolarYear + nDaysSolarYear - nSpringDayInSolarYear + 1;
+		}
+
+		INT nLunarMonth = 1;
+		//计算月份和日期;
+		for (; nLunarMonth <= 13; nLunarMonth++)
+		{
+			INT nMonthDays = 29;
+			if ((LUNAR_YEARS[nIndexYear] >> (7 + 13 - nLunarMonth)) & 0x1)
+				nMonthDays = 30;
+
+			if (nTodayInLunarYear <= nMonthDays)
+				break;
+			else
+				nTodayInLunarYear -= nMonthDays;
+		}
+
+		lnaDate.nDay = nTodayInLunarYear;
+
+		//处理闰月;
+		INT nLeapMonth = (LUNAR_YEARS[nIndexYear] >> 20) & 0xf;
+		if (nLeapMonth > 0 && nLeapMonth < nLunarMonth)
+		{
+			nLunarMonth--;
+			//如果当前月为闰月,设置闰月标志;
+			if (nLunarMonth == nLeapMonth)
+				lnaDate.bIsLeapMonth = true;
+		}
+
+		if ( nLeapMonth > 12)
+			return -1;
+
+		lnaDate.nMonth = nLunarMonth;
+		_stprintf_s(lpLunarDate, 11, _T("%04d-%02d-%02d"),lnaDate.nYear,lnaDate.nMonth,lnaDate.nDay);
+
+		return 0L;
+	}
+
+	// ------------------------------------------------------------------------------------------------------------------------
+	// 对外接口函数
+	//
+	// 函数:LuanrToSolarDate
+	// 描述:将农历日期转为对应的公历日期
+	// 参数:
+	//		nLunarYear		农历年;
+	//		nLunarMonth		农历月;
+	//		nLunarDay		农历日;
+	//		bIsLeapMonth	TRUE,若该年有闰月且正好是输入月份,返回闰月对应的公历;
+	// 返回:返回公历日期在这一年中的第几天;
+	//
+	// ------------------------------------------------------------------------------------------------------------------------
+	BOOL LuanrToSolarDate(IN CONST int &nLunarYear, IN CONST int &nLunarMonth, IN CONST int &nLunarDay, OUT LPTSTR lpSolarDate, IN BOOL bIsLeapMonth/*=FALSE*/)
+	{
+		// 越界检查,如果越界,返回无效日期;
+		if (nLunarYear <= BEGIN_YEAR || nLunarYear > BEGIN_YEAR + NUMBER_YEAR - 1)
+			return FALSE;
+
+		// 1.判断该农历年是否有闰月;
+		INT nIndexYear = nLunarYear - BEGIN_YEAR;
+		INT nLeapMonth = (LUNAR_YEARS[nIndexYear] >> 20) & 0xF;
+
+		COleDateTime Solar;
+		Solar.SetDateTime(nLunarYear, nLunarMonth, nLunarDay, 0, 0, 0);
+		COleDateTimeSpan Span(1, 0, 0, 0);
+
+		BOOL bExist = FALSE;
+		LunarDate Luanr_date;
+		for (INT i = 0; i < 120; i++)
+		{
+			if(SolarToLuanrDate( Solar.GetYear(), Solar.GetMonth(), Solar.GetDay(),Luanr_date) == -1)
+				return FALSE;
+			if (Luanr_date.nYear == nLunarYear && Luanr_date.nMonth == nLunarMonth && Luanr_date.nDay == nLunarDay)
+			{
+				if (bIsLeapMonth && nLeapMonth == nLunarMonth)
+				{
+					bIsLeapMonth = FALSE;
+					Solar += Span;
+					continue;
+				}
+				else
+				{
+					_stprintf_s(lpSolarDate,11,_T("%4d-%02d-%02d"),Solar.GetYear(), Solar.GetMonth(), Solar.GetDay());
+					bExist = TRUE;
+					break;
+				}
+			}
+			Solar += Span;
+		}
+
+		return bExist;
+	}
+
+
+	// ------------------------------------------------------------------------------------------------------------------------
+	// 对外接口函数
+	//
+	// 函数:
+	// 描述:判断输入的农历日期的月份是否有闰月;
+	// 参数:
+	//		nLunarYear		农历年;
+	// 返回:若有闰月返回闰月值,否则返回0;
+	//
+	// ------------------------------------------------------------------------------------------------------------------------
+	INT IsLeapMonth(IN const int &nLunarYear)
+	{
+		// 越界检查,如果越界,返回无效日期;
+		if (nLunarYear <= BEGIN_YEAR || nLunarYear > BEGIN_YEAR + NUMBER_YEAR - 1)
+			return -1;
+
+		// 1.判断该农历年是否有闰月;
+		return (LUNAR_YEARS[nLunarYear - BEGIN_YEAR] >> 20) & 0xF;
+	}
+};

+ 63 - 0
LunarCalendar/Test/LunarCalendar.h

@@ -0,0 +1,63 @@
+#ifndef __CALENDAREX_20160127__
+#define __CALENDAREX_20160127__
+
+#pragma once
+
+namespace CalendarEx
+{
+	//保存一个农历日期;
+	typedef struct _STLUNARDATE_ 
+	{
+		INT		nYear;
+		INT		nMonth;
+		INT		nDay;
+		bool	bIsLeapMonth;	//是否闰月;
+
+		_STLUNARDATE_()	{
+			nYear = 0;
+			nMonth = 0;
+			nDay = 0;
+			bIsLeapMonth = FALSE;
+		}
+	} LunarDate, *pLunarDate;
+
+	// 农历日期有效性;
+	BOOL IsValidLunanrDate(IN LPCTSTR lpLunarDate);
+	// 农历日期有效性;
+	BOOL IsValidLunanrDate(IN INT nLunarYear, IN INT nLunarMonth, IN INT nLunarDay);
+
+	BOOL IsValidSolarStrDate(IN LPCTSTR lpSolarDate, IN BOOL bThisyear);
+	
+	BOOL IsValidSolarDate(
+		IN CONST INT &nSolarYear, 
+		IN CONST INT &nSolarMonth, 
+		IN CONST INT &nSolarDay);
+	
+	INT DayOfSolarYear(
+		IN CONST INT &nSolarYear,
+		IN CONST INT &nSolarMonth, 
+		IN CONST INT &nSolarDay);
+
+	INT SolarToLuanrDate(
+		IN CONST INT &nSolarYear,
+		IN CONST INT &nSolarMonth, 
+		IN CONST INT &nSolarDay, 
+		OUT LunarDate &lnaDate);
+
+	INT GetLunarDate(
+		IN CONST INT &nSolarYear, 
+		IN CONST INT &nSolarMonth, 
+		IN CONST INT &nSolarDay,
+		OUT LPTSTR lpLunarDate);
+
+	BOOL LuanrToSolarDate(
+		IN CONST INT &nLunarYear, 
+		IN CONST INT &nLunarMonth, 
+		IN CONST INT &nLunarDay, 
+		OUT LPTSTR lpSolarDate,
+		IN BOOL bIsLeapMonth = FALSE );
+
+	INT IsLeapMonth(IN const INT &nLunarYear);
+};
+
+#endif

+ 69 - 0
LunarCalendar/Test/ReadMe.txt

@@ -0,0 +1,69 @@
+================================================================================
+    MICROSOFT 基础类库: Test 项目概述
+===============================================================================
+
+应用程序向导已为您创建此 Test 应用程序。此应用程序不仅演示使用 Microsoft 基础类的基本知识,而且可作为编写应用程序的起点。
+
+此文件包含组成 Test 应用程序的各个文件的内容摘要。
+
+Test.vcproj
+    这是使用应用程序向导生成的 VC++ 项目的主项目文件。
+    它包含有关生成文件的 Visual C++ 版本的信息,以及有关使用应用程序向导选择的平台、配置和项目功能的信息。
+
+Test.h
+    这是应用程序的主要头文件。它包括其他项目特定的头文件(包括 Resource.h),并声明 CTestApp 应用程序类。
+
+Test.cpp
+    这是包含应用程序类 CTestApp 的主要应用程序源文件。
+
+Test.rc
+    这是程序使用的所有 Microsoft Windows 资源的列表。它包括 RES 子目录中存储的图标、位图和光标。此文件可以直接在 Microsoft Visual C++ 中进行编辑。项目资源位于 2052 中。
+
+res\Test.ico
+    这是用作应用程序图标的图标文件。此图标包括在主要资源文件 Test.rc 中。
+
+res\Test.rc2
+    此文件包含不是由 Microsoft Visual C++ 编辑的资源。您应该将不可由资源编辑器编辑的所有资源放在此文件中。
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+应用程序向导创建一个对话框类:
+
+TestDlg.h,TestDlg.cpp - 对话框
+    这些文件包含 CTestDlg 类。该类定义应用程序主对话框的行为。该对话框的模板位于 Test.rc 中,该文件可以在 Microsoft Visual C++ 中进行编辑。
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+其他功能:
+
+ActiveX 控件
+    应用程序包括对使用 ActiveX 控件的支持。
+
+打印及打印预览支持
+    应用程序向导已通过从 MFC 库调用 CView 类中的成员函数,生成了用于处理打印、打印设置和打印预览命令的代码。
+
+/////////////////////////////////////////////////////////////////////////////
+
+其他标准文件:
+
+StdAfx.h, StdAfx.cpp
+    这些文件用于生成名为 Test.pch 的预编译头(PCH)文件和名为 StdAfx.obj 的预编译类型文件。
+
+Resource.h
+    这是标准头文件,它定义新资源 ID。
+    Microsoft Visual C++ 将读取并更新此文件。
+
+Test.manifest
+	Windows XP 使用应用程序清单文件描述应用程序	对特定版本并行程序集的依赖性。加载程序使用此	信息从程序集缓存加载相应程序集或	从应用程序加载私有信息。应用程序清单可能作为	与应用程序可执行文件安装在同一文件夹中的外部 .manifest 文件包括在内以便重新发布,	也可能以资源的形式包括在该可执行文件中。
+/////////////////////////////////////////////////////////////////////////////
+
+其他注释:
+
+应用程序向导使用“TODO:”指示应添加或自定义的源代码部分。
+
+如果应用程序在共享 DLL 中使用 MFC,则将需要重新发布 MFC DLL。如果应用程序所用与操作系统的区域设置不同,则也将必须重新发布对应的本地化资源 MFC90XXX.DLL。
+有关这两个主题的详细信息,请参阅 MSDN 文档中有关重新发布 Visual C++ 应用程序的部分。
+
+/////////////////////////////////////////////////////////////////////////////

+ 84 - 0
LunarCalendar/Test/Test.cpp

@@ -0,0 +1,84 @@
+
+// Test.cpp : 定义应用程序的类行为。
+//
+
+#include "stdafx.h"
+#include "Test.h"
+#include "TestDlg.h"
+#include "CalendarEx.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// CTestApp
+
+BEGIN_MESSAGE_MAP(CTestApp, CWinAppEx)
+	ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
+END_MESSAGE_MAP()
+
+
+// CTestApp 构造
+
+CTestApp::CTestApp()
+{
+	// TODO: 在此处添加构造代码,
+	// 将所有重要的初始化放置在 InitInstance 中
+}
+
+
+// 唯一的一个 CTestApp 对象
+
+CTestApp theApp;
+
+
+// CTestApp 初始化
+
+BOOL CTestApp::InitInstance()
+{
+	// 如果一个运行在 Windows XP 上的应用程序清单指定要
+	// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
+	//则需要 InitCommonControlsEx()。否则,将无法创建窗口。
+	INITCOMMONCONTROLSEX InitCtrls;
+	InitCtrls.dwSize = sizeof(InitCtrls);
+	// 将它设置为包括所有要在应用程序中使用的
+	// 公共控件类。
+	InitCtrls.dwICC = ICC_WIN95_CLASSES;
+	InitCommonControlsEx(&InitCtrls);
+
+	CWinAppEx::InitInstance();
+
+	AfxEnableControlContainer();
+
+	TCHAR szSolar[MAX_PATH] = {0};
+	CalendarEx::LuanrToSolarDate(2015, 2, 26, szSolar);
+	CalendarEx::LuanrToSolarDate(2016, 12, 20, szSolar);
+
+	// 标准初始化
+	// 如果未使用这些功能并希望减小
+	// 最终可执行文件的大小,则应移除下列
+	// 不需要的特定初始化例程
+	// 更改用于存储设置的注册表项
+	// TODO: 应适当修改该字符串,
+	// 例如修改为公司或组织名
+	SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
+
+	CTestDlg dlg;
+	m_pMainWnd = &dlg;
+	INT_PTR nResponse = dlg.DoModal();
+	if (nResponse == IDOK)
+	{
+		// TODO: 在此放置处理何时用
+		//  “确定”来关闭对话框的代码
+	}
+	else if (nResponse == IDCANCEL)
+	{
+		// TODO: 在此放置处理何时用
+		//  “取消”来关闭对话框的代码
+	}
+
+	// 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
+	//  而不是启动应用程序的消息泵。
+	return FALSE;
+}

+ 32 - 0
LunarCalendar/Test/Test.h

@@ -0,0 +1,32 @@
+
+// Test.h : PROJECT_NAME 应用程序的主头文件
+//
+
+#pragma once
+
+#ifndef __AFXWIN_H__
+	#error "在包含此文件之前包含“stdafx.h”以生成 PCH 文件"
+#endif
+
+#include "resource.h"		// 主符号
+
+
+// CTestApp:
+// 有关此类的实现,请参阅 Test.cpp
+//
+
+class CTestApp : public CWinAppEx
+{
+public:
+	CTestApp();
+
+// 重写
+	public:
+	virtual BOOL InitInstance();
+
+// 实现
+
+	DECLARE_MESSAGE_MAP()
+};
+
+extern CTestApp theApp;

+ 212 - 0
LunarCalendar/Test/Test.rc

@@ -0,0 +1,212 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#ifndef APSTUDIO_INVOKED
+#include "targetver.h"
+#endif
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// 中文(中华人民共和国) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
+#ifdef _WIN32
+LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
+#pragma code_page(936)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE 
+BEGIN
+    "resource.h\0"
+END
+
+2 TEXTINCLUDE 
+BEGIN
+    "#ifndef APSTUDIO_INVOKED\r\n"
+    "#include ""targetver.h""\r\n"
+    "#endif\r\n"
+    "#include ""afxres.h""\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE 
+BEGIN
+    "#define _AFX_NO_SPLITTER_RESOURCES\r\n"
+    "#define _AFX_NO_OLE_RESOURCES\r\n"
+    "#define _AFX_NO_TRACKER_RESOURCES\r\n"
+    "#define _AFX_NO_PROPERTY_RESOURCES\r\n"
+    "\r\n"
+    "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)\r\n"
+    "LANGUAGE 4, 2\r\n"
+    "#pragma code_page(936)\r\n"
+    "#include ""res\\Test.rc2""  // 非 Microsoft Visual C++ 编辑的资源\r\n"
+    "#include ""l.CHS\\afxres.rc""      // 标准组件\r\n"
+    "#endif\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDR_MAINFRAME           ICON                    "res\\Test.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_ABOUTBOX DIALOGEX 0, 0, 170, 62
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "关于 Test"
+FONT 9, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+    ICON            IDR_MAINFRAME,IDC_STATIC,14,14,21,20
+    LTEXT           "Test,1.0 版",IDC_STATIC,42,14,114,8,SS_NOPREFIX
+    LTEXT           "Copyright (C) 2014",IDC_STATIC,42,26,114,8
+    DEFPUSHBUTTON   "确定",IDOK,113,41,50,14,WS_GROUP
+END
+
+IDD_TEST_DIALOG DIALOGEX 0, 0, 291, 138
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_APPWINDOW
+CAPTION "测试工具"
+FONT 9, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+    DEFPUSHBUTTON   "确定",IDOK,176,117,50,14
+    PUSHBUTTON      "取消",IDCANCEL,234,117,50,14
+    CONTROL         "",IDC_DATETIMEPICKER1,"SysDateTimePick32",DTS_RIGHTALIGN | DTS_LONGDATEFORMAT | WS_TABSTOP,8,14,75,15
+    PUSHBUTTON      "转换成农历",IDC_BUTTON1,88,15,81,14
+    EDITTEXT        Edit_Lunar,173,14,104,14,ES_AUTOHSCROLL
+    EDITTEXT        Edit_Solar,173,37,104,14,ES_AUTOHSCROLL
+    PUSHBUTTON      "转换成公历",IDC_BUTTON2,88,37,81,14
+    EDITTEXT        Edit_LunarDate,8,37,75,14,ES_AUTOHSCROLL
+    CONTROL         "闰月",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,54,30,10
+    EDITTEXT        ET_LUNAR_BRITHDAY,8,76,75,14,ES_AUTOHSCROLL
+    PUSHBUTTON      "农历生日计算年龄",BT_GETAGE,88,76,81,14
+    EDITTEXT        ET_AGE,173,77,104,14,ES_AUTOHSCROLL
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,1
+ PRODUCTVERSION 1,0,0,1
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "080403a8"
+        BEGIN
+            VALUE "CompanyName", "TODO: <公司名>"
+            VALUE "FileDescription", "TODO: <文件说明>"
+            VALUE "FileVersion", "1.0.0.1"
+            VALUE "InternalName", "Test.exe"
+            VALUE "LegalCopyright", "TODO: (C) <公司名>。保留所有权利。"
+            VALUE "OriginalFilename", "Test.exe"
+            VALUE "ProductName", "TODO: <产品名>"
+            VALUE "ProductVersion", "1.0.0.1"
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x804, 936
+    END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO 
+BEGIN
+    IDD_ABOUTBOX, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 163
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 55
+    END
+
+    IDD_TEST_DIALOG, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 284
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 131
+    END
+END
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE 
+BEGIN
+    IDS_ABOUTBOX            "关于 Test(&A)..."
+END
+
+#endif    // 中文(中华人民共和国) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#define _AFX_NO_SPLITTER_RESOURCES
+#define _AFX_NO_OLE_RESOURCES
+#define _AFX_NO_TRACKER_RESOURCES
+#define _AFX_NO_PROPERTY_RESOURCES
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
+LANGUAGE 4, 2
+#pragma code_page(936)
+#include "res\Test.rc2"  // 非 Microsoft Visual C++ 编辑的资源
+#include "l.CHS\afxres.rc"      // 标准组件
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+

+ 280 - 0
LunarCalendar/Test/Test.vcproj

@@ -0,0 +1,280 @@
+<?xml version="1.0" encoding="gb2312"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="Test"
+	ProjectGUID="{5EEA4E51-051A-4A63-B780-62A5997A74D6}"
+	RootNamespace="Test"
+	Keyword="MFCProj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="..\..\..\bin\$(SolutionName)"
+			IntermediateDirectory="$(OutDir)\$(ConfigurationName)"
+			ConfigurationType="1"
+			UseOfMFC="2"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				PreprocessorDefinitions="_DEBUG"
+				MkTypLibCompatible="false"
+				ValidateParameters="true"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="_DEBUG"
+				Culture="2052"
+				AdditionalIncludeDirectories="$(IntDir)"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="2"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="..\..\..\bin\$(SolutionName)"
+			IntermediateDirectory="$(OutDir)\$(ConfigurationName)"
+			ConfigurationType="1"
+			UseOfMFC="2"
+			CharacterSet="1"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				PreprocessorDefinitions="NDEBUG"
+				MkTypLibCompatible="false"
+				ValidateParameters="true"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
+				MinimalRebuild="false"
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="2"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="2052"
+				AdditionalIncludeDirectories="$(IntDir)"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="1"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Ô´Îļþ"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath=".\CalendarEx..cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\stdafx.cpp"
+				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						UsePrecompiledHeader="1"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						UsePrecompiledHeader="1"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\Test.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\TestDlg.cpp"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Í·Îļþ"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<File
+				RelativePath=".\CalendarEx.h"
+				>
+			</File>
+			<File
+				RelativePath=".\Resource.h"
+				>
+			</File>
+			<File
+				RelativePath=".\stdafx.h"
+				>
+			</File>
+			<File
+				RelativePath=".\targetver.h"
+				>
+			</File>
+			<File
+				RelativePath=".\Test.h"
+				>
+			</File>
+			<File
+				RelativePath=".\TestDlg.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="×ÊÔ´Îļþ"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+			<File
+				RelativePath=".\res\Test.ico"
+				>
+			</File>
+			<File
+				RelativePath=".\Test.rc"
+				>
+			</File>
+			<File
+				RelativePath=".\res\Test.rc2"
+				>
+			</File>
+		</Filter>
+		<File
+			RelativePath=".\ReadMe.txt"
+			>
+		</File>
+	</Files>
+	<Globals>
+		<Global
+			Name="RESOURCE_FILE"
+			Value="Test.rc"
+		/>
+	</Globals>
+</VisualStudioProject>

+ 263 - 0
LunarCalendar/Test/TestDlg.cpp

@@ -0,0 +1,263 @@
+
+// TestDlg.cpp : 实现文件
+//
+
+#include "stdafx.h"
+#include "Test.h"
+#include "TestDlg.h"
+#include "CalendarEx.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+#if 1
+typedef INT (*GetLunarDate)(OUT LPTSTR ,IN const int &, IN const int &, IN const int &);
+typedef BOOL (*LuanrToSolarDate)(OUT LPTSTR ,IN const int &, IN const int &, IN const int &, BOOL);
+#else
+typedef INT (__stdcall *GetLunarDate)(OUT LPTSTR ,IN const int &, IN const int &, IN const int &);
+typedef BOOL (__stdcall *LuanrToSolarDate)(OUT LPTSTR ,IN const int &, IN const int &, IN const int &, BOOL);
+#endif
+
+GetLunarDate		g_GetLunarDate;
+LuanrToSolarDate	g_LuanrToSolarDate;
+// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
+
+class CAboutDlg : public CDialog
+{
+public:
+	CAboutDlg();
+
+// 对话框数据
+	enum { IDD = IDD_ABOUTBOX };
+
+	protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
+
+// 实现
+protected:
+	DECLARE_MESSAGE_MAP()
+};
+
+CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
+{
+}
+
+void CAboutDlg::DoDataExchange(CDataExchange* pDX)
+{
+	CDialog::DoDataExchange(pDX);
+}
+
+BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
+END_MESSAGE_MAP()
+
+
+// CTestDlg 对话框
+
+
+
+
+CTestDlg::CTestDlg(CWnd* pParent /*=NULL*/)
+	: CDialog(CTestDlg::IDD, pParent)
+{
+	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
+}
+
+void CTestDlg::DoDataExchange(CDataExchange* pDX)
+{
+	CDialog::DoDataExchange(pDX);
+	DDX_Control(pDX, IDC_DATETIMEPICKER1, m_ctlDT);
+}
+
+BEGIN_MESSAGE_MAP(CTestDlg, CDialog)
+	ON_WM_SYSCOMMAND()
+	ON_WM_PAINT()
+	ON_WM_QUERYDRAGICON()
+	//}}AFX_MSG_MAP
+	ON_BN_CLICKED(IDC_BUTTON1, &CTestDlg::OnBnClickedButton1)
+	ON_BN_CLICKED(IDC_BUTTON2, &CTestDlg::OnBnClickedButton2)
+	ON_BN_CLICKED(IDC_CHECK1, &CTestDlg::OnBnClickedCheck1)
+	ON_BN_CLICKED(BT_GETAGE, &CTestDlg::OnBnClickedGetage)
+END_MESSAGE_MAP()
+
+
+// CTestDlg 消息处理程序
+
+BOOL CTestDlg::OnInitDialog()
+{
+	CDialog::OnInitDialog();
+
+	// 将“关于...”菜单项添加到系统菜单中。
+
+	// IDM_ABOUTBOX 必须在系统命令范围内。
+	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
+	ASSERT(IDM_ABOUTBOX < 0xF000);
+
+	CMenu* pSysMenu = GetSystemMenu(FALSE);
+	if (pSysMenu != NULL)
+	{
+		BOOL bNameValid;
+		CString strAboutMenu;
+		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
+		ASSERT(bNameValid);
+		if (!strAboutMenu.IsEmpty())
+		{
+			pSysMenu->AppendMenu(MF_SEPARATOR);
+			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
+		}
+	}
+
+	// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
+	//  执行此操作
+	SetIcon(m_hIcon, TRUE);			// 设置大图标
+	SetIcon(m_hIcon, FALSE);		// 设置小图标
+
+	SetDlgItemText(ET_LUNAR_BRITHDAY,_T("2014-11-22"));
+	// TODO: 在此添加额外的初始化代码
+	LoadMyDllLibrary();
+
+	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
+}
+
+void CTestDlg::OnSysCommand(UINT nID, LPARAM lParam)
+{
+	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
+	{
+		CAboutDlg dlgAbout;
+		dlgAbout.DoModal();
+	}
+	else
+	{
+		CDialog::OnSysCommand(nID, lParam);
+	}
+}
+
+// 如果向对话框添加最小化按钮,则需要下面的代码
+//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
+//  这将由框架自动完成。
+
+void CTestDlg::OnPaint()
+{
+	if (IsIconic())
+	{
+		CPaintDC dc(this); // 用于绘制的设备上下文
+
+		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
+
+		// 使图标在工作区矩形中居中
+		int cxIcon = GetSystemMetrics(SM_CXICON);
+		int cyIcon = GetSystemMetrics(SM_CYICON);
+		CRect rect;
+		GetClientRect(&rect);
+		int x = (rect.Width() - cxIcon + 1) / 2;
+		int y = (rect.Height() - cyIcon + 1) / 2;
+
+		// 绘制图标
+		dc.DrawIcon(x, y, m_hIcon);
+	}
+	else
+	{
+		CDialog::OnPaint();
+	}
+}
+
+//当用户拖动最小化窗口时系统调用此函数取得光标
+//显示。
+HCURSOR CTestDlg::OnQueryDragIcon()
+{
+	return static_cast<HCURSOR>(m_hIcon);
+}
+
+
+void CTestDlg::OnBnClickedButton1()	// 公历转农历;
+{
+	// TODO: 在此添加控件通知处理程序代码
+	COleDateTime oleDT;
+	m_ctlDT.GetTime(oleDT);
+
+	int nYear = oleDT.GetYear();
+	int nMonth = oleDT.GetMonth();
+	int nDay = oleDT.GetDay();
+
+	CString strLunarDate;
+	TCHAR szLunarDate[11] = {0};
+	//if(g_GetLunarDate(szLunarDate, nYear,nMonth,nDay) != 0)
+	if ( !CalendarEx::SolarToLuanrDate(nYear, nMonth, nDay, szLunarDate))
+	{
+		AfxMessageBox(_T("出错"));
+		return;
+	}
+	SetDlgItemText(Edit_Lunar,szLunarDate);
+}
+
+void CTestDlg::OnBnClickedButton2()	// 农历转公历;
+{
+	// TODO: 在此添加控件通知处理程序代码
+	CString strLunarDate;
+	GetDlgItemText(Edit_LunarDate,strLunarDate);
+
+	int nYear = _ttoi(strLunarDate.Left(4));
+	int nMonth = _ttoi(strLunarDate.Mid(5, 2));
+	int nDay = _ttoi(strLunarDate.Mid(8, 2));
+
+	TCHAR szSolarDate[11] = {0};
+	//if(g_LuanrToSolarDate(szSolarDate,nYear,nMonth,nDay,m_IsLeapMonth) == FALSE)
+	if ( !CalendarEx::LuanrToSolarDate(nYear, nMonth, nDay, szSolarDate, m_IsLeapMonth))
+	{
+		AfxMessageBox(_T("出错"));
+		return;
+	}
+	SetDlgItemText(Edit_Solar,szSolarDate);
+
+}
+
+void CTestDlg::LoadMyDllLibrary()
+{
+	m_MyDllModule = LoadLibrary(_T("LunarCalendar.dll"));
+
+	DWORD dwEr = 0;
+	if (m_MyDllModule == NULL)
+	{
+		dwEr = GetLastError();
+		CString strShow;
+		strShow.Format(_T(".初始化动态加失败(%d),请检查文件是否存在或损坏..."), dwEr);
+		return;
+	}
+
+	// 2.加载全部需要的方法;
+	g_GetLunarDate = (GetLunarDate)::GetProcAddress(m_MyDllModule, "GetLunarDate");
+	g_LuanrToSolarDate = (LuanrToSolarDate)::GetProcAddress(m_MyDllModule, "LuanrToSolarDate");
+}
+
+void CTestDlg::FreeMyDllLibrary()
+{
+	if (m_MyDllModule != NULL)
+	{
+		FreeLibrary(m_MyDllModule);
+	}
+}
+
+void CTestDlg::OnBnClickedCheck1()
+{
+	// TODO: 在此添加控件通知处理程序代码
+	if ( ((CButton*)GetDlgItem(IDC_CHECK1))->GetCheck())
+	{
+		m_IsLeapMonth = TRUE;
+	}
+	else
+		m_IsLeapMonth = FALSE;
+	
+}
+
+void CTestDlg::OnBnClickedGetage()
+{
+	// TODO: 在此添加控件通知处理程序代码
+	CString strLunarBrithday;
+	GetDlgItemText(ET_LUNAR_BRITHDAY, strLunarBrithday);
+
+	INT nAge = CalendarEx::GetAge(strLunarBrithday.GetString(), m_IsLeapMonth);
+	if ( nAge != -1 )
+	{
+		SetDlgItemInt(ET_AGE, nAge);
+	}
+}

+ 48 - 0
LunarCalendar/Test/TestDlg.h

@@ -0,0 +1,48 @@
+
+// TestDlg.h : 头文件
+//
+
+#pragma once
+#include "afxdtctl.h"
+
+
+
+// CTestDlg 对话框
+class CTestDlg : public CDialog
+{
+// 构造
+public:
+	CTestDlg(CWnd* pParent = NULL);	// 标准构造函数
+
+// 对话框数据
+	enum { IDD = IDD_TEST_DIALOG };
+
+	protected:
+	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持
+
+
+// 实现
+protected:
+	HICON m_hIcon;
+
+	// 生成的消息映射函数
+	virtual BOOL OnInitDialog();
+	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
+	afx_msg void OnPaint();
+	afx_msg HCURSOR OnQueryDragIcon();
+	DECLARE_MESSAGE_MAP()
+public:
+	afx_msg void OnBnClickedButton1();
+	afx_msg void OnBnClickedButton2();
+
+	HINSTANCE m_MyDll;
+	HMODULE   m_MyDllModule;
+
+	void LoadMyDllLibrary();
+	void FreeMyDllLibrary();
+	CDateTimeCtrl m_ctlDT;
+	afx_msg void OnBnClickedCheck1();
+
+	BOOL m_IsLeapMonth;
+	afx_msg void OnBnClickedGetage();
+};

BIN=BIN
LunarCalendar/Test/res/Test.ico


+ 13 - 0
LunarCalendar/Test/res/Test.rc2

@@ -0,0 +1,13 @@
+//
+// Test.RC2 - Microsoft Visual C++ 不会直接编辑的资源
+//
+
+#ifdef APSTUDIO_INVOKED
+#error 此文件不能用 Microsoft Visual C++ 编辑
+#endif //APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+// 在此处添加手动编辑的资源...
+
+/////////////////////////////////////////////////////////////////////////////

+ 31 - 0
LunarCalendar/Test/resource.h

@@ -0,0 +1,31 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by Test.rc
+//
+#define IDM_ABOUTBOX                    0x0010
+#define IDD_ABOUTBOX                    100
+#define IDS_ABOUTBOX                    101
+#define IDD_TEST_DIALOG                 102
+#define IDR_MAINFRAME                   128
+#define IDC_DATETIMEPICKER1             1000
+#define IDC_BUTTON1                     1001
+#define Edit_Lunar                      1002
+#define Edit_Solar                      1003
+#define IDC_BUTTON2                     1004
+#define Edit_LunarDate                  1005
+#define IDC_CHECK1                      1006
+#define ET_LUNAR_BRITHDAY               1007
+#define IDC_BUTTON3                     1008
+#define BT_GETAGE                       1008
+#define ET_AGE                          1009
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        129
+#define _APS_NEXT_COMMAND_VALUE         32771
+#define _APS_NEXT_CONTROL_VALUE         1010
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif

+ 8 - 0
LunarCalendar/Test/stdafx.cpp

@@ -0,0 +1,8 @@
+
+// stdafx.cpp : 只包括标准包含文件的源文件
+// Test.pch 将作为预编译头
+// stdafx.obj 将包含预编译类型信息
+
+#include "stdafx.h"
+
+

+ 60 - 0
LunarCalendar/Test/stdafx.h

@@ -0,0 +1,60 @@
+
+// stdafx.h : 标准系统包含文件的包含文件,
+// 或是经常使用但不常更改的
+// 特定于项目的包含文件
+
+#pragma once
+
+#ifndef _SECURE_ATL
+#define _SECURE_ATL 1
+#endif
+
+#ifndef VC_EXTRALEAN
+#define VC_EXTRALEAN            // 从 Windows 头中排除极少使用的资料
+#endif
+
+#include "targetver.h"
+
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS      // 某些 CString 构造函数将是显式的
+
+// 关闭 MFC 对某些常见但经常可放心忽略的警告消息的隐藏
+#define _AFX_ALL_WARNINGS
+
+#include <afxwin.h>         // MFC 核心组件和标准组件
+#include <afxext.h>         // MFC 扩展
+
+
+#include <afxdisp.h>        // MFC 自动化类
+
+
+
+#ifndef _AFX_NO_OLE_SUPPORT
+#include <afxdtctl.h>           // MFC 对 Internet Explorer 4 公共控件的支持
+#endif
+#ifndef _AFX_NO_AFXCMN_SUPPORT
+#include <afxcmn.h>             // MFC 对 Windows 公共控件的支持
+#endif // _AFX_NO_AFXCMN_SUPPORT
+
+#include <afxcontrolbars.h>     // 功能区和控件条的 MFC 支持
+
+
+
+
+
+
+
+
+
+#ifdef _UNICODE
+#if defined _M_IX86
+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
+#elif defined _M_IA64
+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"")
+#elif defined _M_X64
+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
+#else
+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
+#endif
+#endif
+
+

+ 26 - 0
LunarCalendar/Test/targetver.h

@@ -0,0 +1,26 @@
+
+#pragma once
+
+// 以下宏定义要求的最低平台。要求的最低平台
+// 是具有运行应用程序所需功能的 Windows、Internet Explorer 等产品的
+// 最早版本。通过在指定版本及更低版本的平台上启用所有可用的功能,宏可以
+// 正常工作。
+
+// 如果必须要针对低于以下指定版本的平台,请修改下列定义。
+// 有关不同平台对应值的最新信息,请参考 MSDN。
+#ifndef WINVER                          // 指定要求的最低平台是 Windows Vista。
+#define WINVER 0x0600           // 将此值更改为相应的值,以适用于 Windows 的其他版本。
+#endif
+
+#ifndef _WIN32_WINNT            // 指定要求的最低平台是 Windows Vista。
+#define _WIN32_WINNT 0x0600     // 将此值更改为相应的值,以适用于 Windows 的其他版本。
+#endif
+
+#ifndef _WIN32_WINDOWS          // 指定要求的最低平台是 Windows 98。
+#define _WIN32_WINDOWS 0x0410 // 将此值更改为适当的值,以适用于 Windows Me 或更高版本。
+#endif
+
+#ifndef _WIN32_IE                       // 指定要求的最低平台是 Internet Explorer 7.0。
+#define _WIN32_IE 0x0700        // 将此值更改为相应的值,以适用于 IE 的其他版本。
+#endif
+