[转自:http://blog.csdn.net/baickl]
这以前本是一个MFC代码,我在这个基础上修改成了标准C++的..
即可以在VC里用,也可以在C++Builder里用..所以一并放到这里来,
希望有人喜欢..喜欢的就给点鼓励啊~~
示例代码:
代码: |
voID __fastcall TForm1::button1Click(TObject *Sender) { xDate *Date_x=new xDate();//取系统时间初始化-:) Memo1->lines->Add("公历"+IntToStr(Date_x->GetYear()) +"年"); Memo1->lines->Add("公历"+IntToStr(Date_x->GetMonth())+"月"); Memo1->lines->Add("公历"+IntToStr(Date_x->GetDay()) +"日"); if(Date_x->IsLeapYear(Date_x->GetYear())) Memo1->lines->Add("今年是闰年"); else Memo1->lines->Add("今年不是闰年"); Memo1->lines->Add("今天是星期"+IntToStr(Date_x->WeekDay(Date_x->GetYear(),Date_x->GetMonth(),Date_x->GetDay()))); Memo1->lines->Add("公历:本月"+IntToStr(Date_x->MonthDays(Date_x->GetYear(),Date_x->GetMonth()))+"天"); Memo1->lines->Add("阴历:本月"+IntToStr(Date_x->LunarMonthDays(Date_x->GetYear(),Date_x->GetMonth()))+"天"); Memo1->lines->Add("阴历今年:"+IntToStr(Date_x->LunarYearDays(Date_x->GetYear()))+"天"); //==================================================================// char ch0[20]="天干记年法表示:"; char Buffer0[8]; Date_x->FormatLunarYear(Date_x->GetYear(),Buffer0); strcat(ch0,Buffer0); Memo1->lines->Add(ch0); //==================================================================// char ch1[20]="月份中文表示法:"; char Buffer1[8]; Date_x->FormatMonth(Date_x->GetMonth(),Buffer1,true); strcat(ch1,Buffer1); Memo1->lines->Add(ch1); //==================================================================// char ch2[20]="Day中文表示法:"; char Buffer2[8]; Date_x->FormatLunarDay(Date_x->GetDay(),Buffer2); strcat(ch2,Buffer2); Memo1->lines->Add(ch2); //==================================================================// //计算两个日期相差的天数 Memo1->lines->Add("距1956,2,21有:"+IntToStr(Date_x->CalcdateDiff(Date_x->GetYear(),Date_x->GetDay(),1956,21))+"天"); //节气计算 WORD iLunarYear, iLunarMonth, iLunarDay; WORD n; n=Date_x->GetLunarDate(Date_x->GetYear(),iLunarYear,iLunarMonth,iLunarDay); if(n) Memo1->lines->Add(IntToStr(n)); else Memo1->lines->Add("不是节气"); Memo1->lines->Add("今天阴历是:"+IntToStr(iLunarYear)+"-"+IntToStr(iLunarMonth)+"-"+IntToStr(iLunarDay)); } //--------------------------------------------------------------------------- |
头文件:
代码: |
//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 IDay); xDate(); //=====================================================================================// WORD GetYear(){return m_iYear;} WORD GetMonth(){return m_iMonth;} WORD GetDay(){return m_IDay;} //=====================================================================================// voID GetDate(WORD &iYear,WORD &IDay); BOol SetDate(WORD iYear,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 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 IDay,WORD &iLunarYear,WORD &iLunarMonth,WORD &iLunarDay); }; #endif //XDATE_H |
类实现:
代码: |
//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 IDay) { if(!SetDate(iYear,IDay)) l_InitData(); } //===========================================================================// xDate::xDate() { l_InitData(); } //===========================================================================// LONG xDate::CalcdateDiff(WORD IEndYear,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,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 &iLunarDay) { l_CalcLunarDate(iLunarYear,iLunarDay,CalcdateDiff(iYear,IDay)); return l_GetLunarHolDay(iYear,IDay); } //===========================================================================// //根据节气数据存储格式,计算阳历iYear年iMonth月IDay日对应的节气, WORD xDate::l_GetLunarHolDay(WORD iYear,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 &IDay) { iYear = m_iYear; iMonth = m_iMonth; IDay = m_IDay; } //===========================================================================// BOol xDate::SetDate(WORD iYear,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 IDay) { //数组元素monthday[i]表示第i个月以前的总天数除以7的余数 WORD monthday[]={0,3,6,1,4,5,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,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,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 ,szText2 + ((IDay-1)%10)*2,2); pBuffer[4]='/0'; } else { memcpy(pBuffer ,szText1 + IDay/10*2,2); strcpy(pBuffer+2,szText2 +18); } } /****************************************************************************** 下面为阴历计算所需的数据,为节省存储空间,所以采用下面比较变态的存储方法. *******************************************************************************/ //数组glunarDay存入阴历1901年到2100年每年中的月天数信息, //阴历每月只能是29或30天,一年用12(或13)个二进制位表示,对应位为1表30天,否则为29天 WORD glunarMonthDay[]= { //测试数据只有1901.1.1 --2050.12.31 0X4ae0,0Xa570,0X5268,0Xd260,0Xd950,0X6aa8,0X56a0,0X9ad0,0X4ae8,0X4ae0, //1910 0Xa4d8,0Xa4d0,0Xd250,0Xd548,0Xb550,0X96d0,0X95b0,0X49b8,0X49b0, //1920 0Xa4b0,0Xb258,0X6a50,0X6d40,0Xada8,0X2b60,0X9570,0X4978,0X4970,0X64b0, //1930 0Xd4a0,0Xea50,0X6d48,0X5ad0,0X9370,0X92e0,0Xc968,0Xc950,0Xd4a0, //1940 0Xda50,0Xaad8,0X25d0,0X92d0,0Xc958,0Xa950,0Xb4a8,0X6ca0, //1950 0Xb550,0X55a8,0X4da0,0Xa5b0,0X52b8,0X52b0,0Xe950,0X6aa0,0Xad50, //1960 0Xab50,0X4b60,0X5260,0Xe930,0X5aa8, //1970 0X4ae8,0X4ad0,0Xd268,0Xd528,0Xb540,0Xb6a0, //1980 0X49b0,0Xa4b8,0Xa4b0,0Xada0,0Xab60, //1990 0X4970,0X6b28,0X5ac0,0X9368,0Xc960, //2000 0Xd4a8,0Xda50, //2010 0Xb4a0,0X4ba0,0Xa930,0X74a8, //2020 0X6aa0,0X4da8,0Xa4e0,0Xd530,0X5aa0, //2030 0X6b50,0Xd258,0Xd520,0Xdaa0,0Xb5a0, //2040 0X56d0,0X4ad8,0Xaa50,0Xb528,0X6d20,0X55b0, //2050 }; //数组gLanarMonth存放阴历1901年到2050年闰月的月份,如没有则为0,每字节存两年 BYTE glunarMonth[]= { 0X00,0X50,0X04,0X00,0X20, //1910 0X60,0X05,0X70, //1920 0X05,0X40,0X02,0X06, //1930 0X00,0X03,0X07, //1940 0X60, //1950 0X05,0X30,0X80, //1960 0X00, //1970 0X50,0X08,0X60, //1980 0X04,0X0a, //1990 0X00, //2000 0X40, //2010 0X04,0X09, //2020 0X00, //2030 0X30,0Xb0, //2040 0X02,0X03 //2050 }; //数组gLanarHolIDay存放每年的二十四节气对应的阳历日期 //每年的二十四节气对应的阳历日期几乎固定,平均分布于十二个月中 // 1月 2月 3月 4月 5月 6月 //小寒 大寒 立春 雨水 惊蛰 春分 清明 谷雨 立夏 小满 芒种 夏至 // 7月 8月 9月 10月 11月 12月 //小暑 大暑 立秋 处暑 白露 秋分 寒露 霜降 立冬 小雪 大雪 冬至 /********************************************************************************* 节气无任何确定规律,所以只好存表,要节省空间,所以.... 下面这种存法实在是太变态了,你就将就着看吧 **********************************************************************************/ //数据格式说明: //如1901年的节气为 // 1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月 // 6,21,19, 6,22,8,23,24,22 // 9, 11, 9, 10, 9,7, 7,9, 8,15 //上面第一行数据为每月节气对应日期,15减去每月第一个节气,每月第二个节气减去15得第二行 // 这样每月两个节气对应数据都小于16,每月用一个字节存放,高位存放第一个节气数据,低位存放 //第二个节气的数据,可得下表 BYTE glunarHolDay[]= { 0X96,0XB4,0X96,0XA6,0X97,0X78,0X79,0X69,0X77, //1901 0X96,0XA4,0X87, //1902 0X96,0XA5, //1903 0X86,0X88, //1904 0X96, //1905 0X96, //1906 0X96, //1907 0X86, //1908 0X96, //1909 0X96, //1910 0X96, //1911 0X86, //1912 0X95, //1913 0X96, //1914 0X96, //1915 0X96, //1916 0X95, //1917 0X96, //1918 0X96, //1919 0X96, //1920 0X95, //1921 0X96, //1922 0X96, //1923 0X96, //1924 0X95, //1925 0X96, //1926 0X96, //1927 0X96, //1928 0X95, //1929 0X96, //1930 0X96, //1931 0X96, //1932 0X95, //1933 0X96, //1934 0X96, //1935 0X96, //1936 0X95, //1937 0X96, //1938 0X96, //1939 0X96, //1940 0X95, //1941 0X96, //1942 0X96, //1943 0X96, //1944 0X95, //1945 0X95, //1946 0X96, //1947 0X96, //1948 0XA5, //1949 0X95, //1950 0X96, //1951 0X96, //1952 0XA5, //1953 0X95,0X68, //1954 0X96, //1955 0X96, //1956 0XA5, //1957 0X95, //1958 0X96, //1959 0X96, //1960 0XA5, //1961 0X96, //1962 0X96, //1963 0X96, //1964 0XA5, //1965 0X95, //1966 0X96, //1967 0X96, //1968 0XA5, //1969 0X95, //1970 0X96, //1971 0X96, //1972 0XA5,0XB5, //1973 0X95, //1974 0X96, //1975 0X96,0X89, //1976 0XA5, //1977 0X95, //1978 0X96, //1979 0X96, //1980 0XA5, //1981 0X95, //1982 0X95, //1983 0X96, //1984 0XA5, //1985 0XA5, //1986 0X95, //1987 0X96,0X86, //1988 0XA5, //1989 0XA5, //1990 0X95, //1991 0X96, //1992 0XA5,0XB3, //1993 0XA5, //1994 0X95,0X76, //1995 0X96, //1996 0XA5, //1997 0XA5, //1998 0X95, //1999 0X96, //2000 0XA5, //2001 0XA5, //2002 0X95, //2003 0X96, //2004 0XA5, //2005 0XA5, //2006 0X95, //2007 0X96, //2008 0XA5, //2009 0XA5, //2010 0X95, //2011 0X96, //2012 0XA5, //2013 0XA5, //2014 0X95, //2015 0X95, //2016 0XA5,0XC3, //2017 0XA5, //2018 0XA5, //2019 0X95, //2020 0XA5, //2021 0XA5, //2022 0XA5, //2023 0X95, //2024 0XA5, //2025 0XA5, //2026 0XA5, //2027 0X95, //2028 0XA5, //2029 0XA5, //2030 0XA5, //2031 0X95, //2032 0XA5, //2033 0XA5, //2034 0XA5, //2035 0X95, //2036 0XA5, //2037 0XA5, //2038 0XA5, //2039 0X95, //2040 0XA5, //2041 0XA5, //2042 0XA5, //2043 0X95, //2044 0XA5, //2045 0XA5, //2046 0XA5, //2047 0X95, //2048 0XA4, //2049 0XA5,0X87 //2050 }; |
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostID=557712
总结以上是内存溢出为你收集整理的一个C++农历类全部内容,希望文章能够帮你解决一个C++农历类所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)