1、NongLi.cpp
// NongLi.cpp : Defines the entry point for the console application. // #include <stdio.h> #include "xDate.h" // http://www.chinapyg.com/forum.php?mod=viewthread&tid=2928 int main(int argc, char* argv[]) { xDate *dateX = new xDate();//取系统时间初始化-:) printf("公历(年份) : %d ", dateX->GetYear()); printf("公历(月份) : %d ", dateX->GetMonth()); printf("公历(日期) : %d ", dateX->GetDay()); if(dateX->IsLeapYear(dateX->GetYear())) printf("今年是闰年 "); else printf("今年不是闰年 "); printf("今天是星期%d ", dateX->WeekDay(dateX->GetYear(), dateX->GetMonth(), dateX->GetDay())); printf("公历:本月%d天 ", dateX->MonthDays(dateX->GetYear(), dateX->GetMonth())); printf("阴历:本月%d天 ", dateX->LunarMonthDays(dateX->GetYear(), dateX->GetMonth())); printf("阴历今年%d天 ", dateX->LunarYearDays(dateX->GetYear())); //==================================================================// char ch0[60]="天干记年法表示:"; char Buffer0[18] = {0}; dateX->FormatLunarYear(dateX->GetYear(), Buffer0); strcat(ch0, Buffer0); printf("%s ", ch0); //==================================================================// char ch1[20]="月份中文表示法:"; char Buffer1[8]; dateX->FormatMonth(dateX->GetMonth(), Buffer1, true); strcat(ch1, Buffer1); printf("%s ", ch1); //==================================================================// char ch2[20]="Day中文表示法:"; char Buffer2[8]; dateX->FormatLunarDay(dateX->GetDay(), Buffer2); strcat(ch2,Buffer2); printf("%s ", ch2); //==================================================================// //计算两个日期相差的天数 printf("距1956,2,21有%d天 :", dateX->CalcDateDiff(dateX->GetYear(), dateX->GetMonth(), dateX->GetDay(), 1956,2,21)); //节气计算 WORD iLunarYear, iLunarMonth, iLunarDay; WORD n = dateX->GetLunarDate(dateX->GetYear(), dateX->GetMonth(), dateX->GetDay(), iLunarYear, iLunarMonth, iLunarDay); if(n) printf("%d ", n); else printf("不是节气 "); printf("今天阴历是:%d-%d-%d ", iLunarYear, iLunarMonth, iLunarDay); return 0; }
2、xDate.h
//xDate.h /************************************************************************************************************ Author :xShandow Dest :A Date Class For C++ Email :chenzg@hftd.com HomePage:http://www.hftd.com Dev Env :Visual C++6.0 OS. :Windows 2000 Professinal Date :2003-NOV-15 ************************************************************************************************************/ #ifndef XDATE_H #define XDATE_H #include <windows.h> extern const WORD START_YEAR; extern const WORD END_YEAR ; class xDate { private: WORD m_iYear, m_iMonth, m_iDay; void l_InitData(); //计算从1901年1月1日过iSpanDays天后的阴历日期 static void l_CalcLunarDate(WORD &iYear, WORD &iMonth ,WORD &iDay,LONG iSpanDays); //计算公历iYear年iMonth月iDay日对应的节气 0-24,0表不是节气 static WORD l_GetLunarHolDay(WORD iYear, WORD iMonth, WORD iDay); public: //=====================================================================================// xDate(WORD iYear, WORD iMonth, WORD iDay); xDate(); //=====================================================================================// WORD GetYear(){return m_iYear;} WORD GetMonth(){return m_iMonth;} WORD GetDay(){return m_iDay;} //=====================================================================================// void GetDate(WORD &iYear, WORD &iMonth, WORD &iDay); BOOL SetDate(WORD iYear , WORD iMonth , WORD iDay); //=====================================================================================// //判断iYear是不是闰年 static BOOL IsLeapYear(WORD iYear) {return !(iYear%4)&&(iYear%100) || !(iYear%400);} //计算iYear,iMonth,iDay对应是星期几 1年1月1日 --- 65535年12月31日 static WORD WeekDay(WORD iYear, WORD iMonth, WORD iDay); //返回iYear年iMonth月的天数 1年1月 --- 65535年12月 static WORD MonthDays(WORD iYear, WORD iMonth); //返回阴历iLunarYer年阴历iLunarMonth月的天数,如果iLunarMonth为闰月, //高字为第二个iLunarMonth月的天数,否则高字为0 // 1901年1月---2050年12月 static LONG LunarMonthDays(WORD iLunarYear, WORD iLunarMonth); //返回阴历iLunarYear年的总天数 // 1901年1月---2050年12月 static WORD LunarYearDays(WORD iLunarYear); //返回阴历iLunarYear年的闰月月份,如没有返回0 // 1901年1月---2050年12月 static WORD GetLeapMonth(WORD iLunarYear); //把iYear年格式化成天干记年法表示的字符串 static void FormatLunarYear(WORD iYear, char *pBuffer); //把iMonth格式化成中文字符串 static void FormatMonth(WORD iMonth, char *pBuffer, BOOL bLunar = TRUE); //把iDay格式化成中文字符串 static void FormatLunarDay(WORD iDay, char *pBuffer); //计算公历两个日期间相差的天数 1年1月1日 --- 65535年12月31日 static LONG CalcDateDiff(WORD iEndYear, WORD iEndMonth, WORD iEndDay,WORD iStartYear = START_YEAR,WORD iStartMonth =1, WORD iStartDay =1); //计算公历iYear年iMonth月iDay日对应的阴历日期,返回对应的阴历节气 0-24 //1901年1月1日---2050年12月31日 static WORD GetLunarDate(WORD iYear, WORD iMonth, WORD iDay,WORD &iLunarYear, WORD &iLunarMonth, WORD &iLunarDay); }; #endif //XDATE_H
3、xDate.cpp
//xDate.cpp #include "xDate.h" #include <windows.h> extern WORD gLunarMonthDay[]; extern BYTE gLunarMonth[]; extern BYTE gLunarHolDay[]; const WORD START_YEAR =1901; const WORD END_YEAR =2050; //===========================================================================// void xDate::l_InitData() { SYSTEMTIME systime; ::GetSystemTime(&systime); m_iYear = systime.wYear; m_iMonth = systime.wMonth; m_iDay = systime.wDay; } //===========================================================================// xDate::xDate(WORD iYear, WORD iMonth, WORD iDay) { if(!SetDate(iYear, iMonth, iDay)) l_InitData(); } //===========================================================================// xDate::xDate() { l_InitData(); } //===========================================================================// LONG xDate::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; } //===========================================================================// void xDate::l_CalcLunarDate(WORD &iYear, WORD &iMonth ,WORD &iDay, LONG iSpanDays) { //阳历1901年2月19日为阴历1901年正月初一 //阳历1901年1月1日到2月19日共有49天 if(iSpanDays <49) { iYear = START_YEAR-1; if(iSpanDays <19) { iMonth = 11; iDay = 11+WORD(iSpanDays); } else { iMonth = 12; iDay = WORD(iSpanDays) -18; } return; } //下面从阴历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) break; iSpanDays -= tmp; } tmp = LOWORD(LunarMonthDays(iYear, ++iMonth)); } //计算日 iDay += WORD(iSpanDays); } //===========================================================================// WORD xDate::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 xDate::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 xDate::GetDate(WORD &iYear, WORD &iMonth, WORD &iDay) { iYear = m_iYear; iMonth = m_iMonth; iDay = m_iDay; } //===========================================================================// BOOL xDate::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 xDate::WeekDay(WORD iYear, WORD iMonth, WORD iDay) { //数组元素monthday表示第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 xDate::MonthDays(WORD iYear, WORD iMonth) { switch(iMonth) { case 1: //一 (月) case 3: //三 (月) case 5: //五 (月) case 7: //七 (月) case 8: //八 (月) case 10://十 (月) case 12://十二(月) return 31; case 4: //四 (月) case 6: //六 (月) case 9: //九 (月) case 11://十一(月) return 30; case 2: //二 (月) //如果是闰年 if(IsLeapYear(iYear)) return 29; else return 28; } return 0; } //===========================================================================// WORD xDate::GetLeapMonth(WORD iLunarYear) { BYTE &flag = gLunarMonth[(iLunarYear - START_YEAR)/2]; return (iLunarYear - START_YEAR)%2 ? flag&0x0f : flag>>4; } //===========================================================================// LONG xDate::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 xDate::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 xDate::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,"年"); } //===========================================================================// void xDate::FormatMonth(WORD iMonth, char *pBuffer, BOOL bLunar) { if(!bLunar && iMonth==1) { strcpy(pBuffer, " 一月"); return; } char szText[]="正二三四五六七八九十"; if(iMonth<=10) { memcpy(pBuffer ," ", 2); memcpy(pBuffer+2, szText + (iMonth -1)*2, 2); strcpy(pBuffer+4, "月"); return; } if (iMonth == 11) strcpy(pBuffer, "十一"); else strcpy(pBuffer, "十二"); strcpy(pBuffer+4 , "月"); } //===========================================================================// void xDate::FormatLunarDay(WORD iDay, char *pBuffer) { char szText1[]="初十廿三"; char szText2[]="一二三四五六七八九十"; if(iDay != 20 && iDay !=30) { memcpy(pBuffer , szText1 + (iDay-1)/10*2 ,2); memcpy(pBuffer+2, szText2 + ((iDay-1)%10)*2 ,2); pBuffer[4]='