⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 getlunardate.cpp

📁 一个学生考试成绩管理的半成品
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "stdafx.h"
#include "GetLunarDate.h"

/////////////////////////////////////////////////////////////////////////////
// CGetLunarDate


extern WORD gLunarMonthDay[];
extern BYTE gLunarMonth[];
extern BYTE gLunarHolDay[];

const WORD START_YEAR =1901;
const WORD END_YEAR   =2050;

void CGetLunarDate::l_InitData()
{
	SYSTEMTIME systime;
	::GetSystemTime(&systime);

	m_iYear  = systime.wYear;
	m_iMonth = systime.wMonth;
	m_iDay   = systime.wDay;

}

CGetLunarDate::CGetLunarDate(WORD iYear, WORD iMonth, WORD iDay)
{
   if(!SetDate(iYear, iMonth, iDay))
	   l_InitData();
}

CGetLunarDate::CGetLunarDate()
{
   l_InitData();	
}

CGetLunarDate::~CGetLunarDate()
{
  DestroyWindow(); 
}

/////////////////////////////////////////////////////////////////////////////
LONG CGetLunarDate::CalcDateDiff(WORD iEndYear, WORD iEndMonth, WORD iEndDay,WORD  iStartYear, WORD iStartMonth, WORD iStartDay)
{
	WORD monthday[]={0, 31, 59 ,90, 120, 151, 181, 212, 243, 273, 304, 334}; 

	//计算两个年份1月1日之间相差的天数
	LONG iDiffDays =(iEndYear - iStartYear)*365;
	iDiffDays += (iEndYear-1)/4 - (iStartYear-1)/4;
	iDiffDays -= ((iEndYear-1)/100 - (iStartYear-1)/100);
	iDiffDays += (iEndYear-1)/400 - (iStartYear-1)/400;

    //加上iEndYear年1月1日到iEndMonth月iEndDay日之间的天数
    iDiffDays += monthday[iEndMonth-1] +
		                           (IsLeapYear(iEndYear)&&iEndMonth>2? 1: 0);
    iDiffDays += iEndDay;

	//减去iStartYear年1月1日到iStartMonth月iStartDay日之间的天数
	iDiffDays -= (monthday[iStartMonth-1] + 
		                  (IsLeapYear(iStartYear)&&iStartMonth>2 ? 1: 0));
    iDiffDays -= iStartDay;	
	return iDiffDays;
}

BYTE  CGetLunarDate::l_CalcLunarDate(WORD &iYear, WORD &iMonth ,WORD &iDay, LONG iSpanDays)
{
	//阳历1901年2月19日为阴历1901年正月初一
	//阳历1901年1月1日到2月19日共有49天
	BYTE rcode =0;
   	if(iSpanDays <49)
	{
		iYear  = START_YEAR-1;
		if(iSpanDays <19)
		{ 
		  iMonth = 11;  
		  iDay   = 11+WORD(iSpanDays);
		}
		else
		{
			iMonth = 12;
			iDay   =  WORD(iSpanDays) -18;
		}
		return  rcode;
	}
	//下面从阴历1901年正月初一算起
	iSpanDays -=49;
    iYear  = START_YEAR;
	iMonth = 1;
	iDay   = 1;
	//计算年
	LONG tmp = LunarYearDays(iYear); 
	while(iSpanDays >= tmp)
	{
		iSpanDays -= tmp;
		tmp = LunarYearDays(++iYear);
	}
    //计算月
	tmp = LOWORD(LunarMonthDays(iYear, iMonth));
	while(iSpanDays >= tmp)
	{
		iSpanDays -= tmp;
	    if(iMonth == GetLeapMonth(iYear))
		{
			tmp  = HIWORD(LunarMonthDays(iYear, iMonth));
			if(iSpanDays < tmp)	
			{
			   rcode = 1;
			   break;
			}
			iSpanDays -= tmp;
		}
		tmp = LOWORD(LunarMonthDays(iYear, ++iMonth));
	}
	//计算日
	iDay += WORD(iSpanDays);
	return rcode;
}

WORD CGetLunarDate::GetLunarDate(WORD iYear, WORD iMonth, WORD iDay,
		                     WORD &iLunarYear, WORD &iLunarMonth, WORD &iLunarDay)
{
   l_CalcLunarDate(iLunarYear, iLunarMonth, iLunarDay, 
	                              CalcDateDiff(iYear, iMonth, iDay));

   return l_GetLunarHolDay(iYear, iMonth, iDay);
   
}

//根据节气数据存储格式,计算阳历iYear年iMonth月iDay日对应的节气,
WORD  CGetLunarDate::l_GetLunarHolDay(WORD iYear, WORD iMonth, WORD iDay)
{
	BYTE &flag = gLunarHolDay[(iYear - START_YEAR)*12+iMonth -1];
	WORD day;
	if(iDay <15)
		 day= 15 - ((flag>>4)&0x0f);
	else
		day = ((flag)&0x0f)+15;
	if(iDay == day)
	   return (iMonth-1) *2 + (iDay>15? 1: 0) +1; 
	else
	   return 0;
}
//返回当前的日期
void CGetLunarDate::GetDate(WORD &iYear, WORD &iMonth, WORD &iDay) 
{
	iYear  = m_iYear;
	iMonth = m_iMonth;
	iDay   = m_iDay;
}

BOOL CGetLunarDate::SetDate(WORD iYear, WORD iMonth, WORD iDay)
{
  if(iYear < START_YEAR || iYear > END_YEAR || iMonth <1 || iMonth >12)
    	return FALSE;

  if(iDay <1 || iDay > MonthDays(iYear, iMonth))
	    return FALSE;

  m_iYear   = iYear;
  m_iMonth  = iMonth;
  m_iDay    = iDay;

  return TRUE;
} 

WORD CGetLunarDate::WeekDay(WORD iYear, WORD iMonth, WORD iDay)
{
   	//数组元素monthday[i]表示第i个月以前的总天数除以7的余数
	WORD monthday[]={0,3,3,6,1,4,6,2,5,0,3,5};
	WORD iDays = (iYear-1)%7 + (iYear-1)/4 - (iYear-1)/100 +(iYear-1)/400;
	iDays += (monthday[iMonth-1] +iDay) ;
	//如果iYear是闰年
    if(IsLeapYear(iYear) && iMonth>2)
		iDays++;
	//返回:0,1,2,3,4,5,6表日、一、二、三、四、五、六
	return iDays%7;
}

WORD CGetLunarDate::MonthDays(WORD iYear, WORD iMonth)
{
	switch(iMonth)
	{
	case 1:case 3:case 5:case 7:case 8:case 10:case 12:
		return 31;
		break;
	case 4:case 6:case 9:case 11:
		return 30;
		break;
	case 2:
		//如果是闰年
		if(IsLeapYear(iYear))
			return 29;
		else
			return 28;
		break;
	}
	return 0;
}

WORD CGetLunarDate::GetLeapMonth(WORD iLunarYear)
{
	BYTE &flag = gLunarMonth[(iLunarYear - START_YEAR)/2];
 	return  (iLunarYear - START_YEAR)%2 ? flag&0x0f : flag>>4;
}

LONG CGetLunarDate::LunarMonthDays(WORD iLunarYear, WORD iLunarMonth)
{
	if(iLunarYear < START_YEAR) 
		return 30L;

	WORD height =0 ,low =29;
	int iBit = 16 - iLunarMonth;

    if(iLunarMonth > GetLeapMonth(iLunarYear) && GetLeapMonth(iLunarYear))
		   iBit --;

	if(gLunarMonthDay[iLunarYear - START_YEAR] & (1<<iBit))
	        low ++;
	    
	if(iLunarMonth == GetLeapMonth(iLunarYear))
		if(gLunarMonthDay[iLunarYear - START_YEAR] & (1<< (iBit -1)))
		     height =30;
		else 
			 height =29;

	return MAKELONG(low, height);
}

WORD CGetLunarDate::LunarYearDays(WORD iLunarYear)
{
	/*
	WORD days=348 ; //12*29
	int  month = 12 ;
	//如果iYear年有闰月,则为13个月
    if(gLanarMonth[iYear - START_YEAR]) 
		month ++;
    //如果某月是三十天则days++
	while(month >=0 && (gLanarMonthDay[iYear - START_YEAR] & (1 << (16 - month))))
	{   
		days ++; 
	    month --;
	}
	return days;
	*/
	WORD days =0;
	for(WORD  i=1; i<=12; i++)
	{ 
        LONG  tmp = LunarMonthDays(iLunarYear ,i); 
		days += HIWORD(tmp);
		days += LOWORD(tmp);
	}
    return days;
}

void CGetLunarDate::FormatLunarYear(WORD  iYear, char *pBuffer)
{	
	char szText1[]="甲乙丙丁戊己庚辛壬癸";
	char szText2[]="子丑寅卯辰巳午未申酉戌亥";
	char szText3[]="鼠牛虎免龙蛇马羊猴鸡狗猪";

	memcpy(pBuffer,  szText1+((iYear-4)%10)*2,2);
	memcpy(pBuffer+2,szText2+((iYear-4)%12)*2,2);
	pBuffer[4]=' ';
	memcpy(pBuffer+5,szText3+((iYear-4)%12)*2,2);
	strcpy(pBuffer+7,"年");
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -