機電之家資源網(wǎng)
單片機首頁|單片機基礎(chǔ)|單片機應(yīng)用|單片機開發(fā)|單片機文案|軟件資料下載|音響制作|電路圖下載 |嵌入式開發(fā)
培訓(xùn)信息
贊助商
農(nóng)歷計算
農(nóng)歷計算
 更新時間:2008-7-27 16:07:53  點擊數(shù):2
【字體: 字體顏色

        近日對農(nóng)歷計算感興趣 , 在網(wǎng)上找了一些源碼看了看,發(fā)現(xiàn)一個廣為流傳的源碼,好像是漢王的人所寫。但是這個源碼不但參數(shù)表太大,并且運算速度很慢,不適合于用到嵌入式產(chǎn)品中。后來看到一個不錯的版本(可能為臺灣人所寫),于是對它的參數(shù)表進行了優(yōu)化,得到了一個不錯的程序,非常適合于嵌入式系統(tǒng)。
        參數(shù)表所占存儲空間為:30 + 4×支持年數(shù)
        經(jīng)在MSP430仿真測試,參數(shù)表占有154字節(jié),代碼占有622字節(jié),執(zhí)行一次的典型時間是1382個時鐘周期。

// -----------------------------------------------------------------
//      農(nóng)歷計算:
//      Copy From "西歷農(nóng)歷轉(zhuǎn)換程式    黃曉鳴  1995,7,25"
//      Modify  : Blove
//      Date            : 16:02 2005-12-1
// -----------------------------------------------------------------
typedef         unsigned char   INT8U;
typedef         unsigned short  INT16U;
typedef         unsigned long   INT32U;

typedef struct _SolarDate_Tag_
{
        INT16U  wYear;
        INT8U   chMonth;
        INT8U   chDate;
}sSolarDateTag;


typedef struct _LunarDate_Tag_
{
        INT16U  wYear;
        INT8U   chMonth;
        INT8U   chDate;
        INT8U   chKan;
        INT8U   chChi;
}sLunarDateTag;


// -------------------------------------------------------------------
//      農(nóng)歷計算參數(shù)位定義:
//              31-25   7       : ( BaseDays    )到公歷1月1日到農(nóng)歷正月初一的累積日數(shù)
//              24-20   5       : ( Intercalation)閏月月份. 0==此年沒有閏月
//              19-13   7       : ( BaseKanChih  )此年公歷1月1日之干支序號減 1
//              12- 0   13      : ( MonthDays    )此農(nóng)歷年每月之大小, 0==小月(29日), 1==大月(30日)
// -------------------------------------------------------------------
#define         LPARA_MASK_BASE_DAYS            0xFE000000
#define         LPARA_MASK_INTERCALATION        0x01F00000
#define         LPARA_MASK_BASE_KANCHI          0x000FE000
#define         LPARA_MASK_MONTH_DAYS           0x00001FFF

#define         LPARA_SHIFT_BASE_DAYS           25
#define         LPARA_SHIFT_INTERCALATION       20
#define         LPARA_SHIFT_BASE_KANCHI         13
#define         LPARA_SHIFT_MONTH_DAYS          0

#define         LPara_GetBaseDays(i)            ( (m_dwLunarParas[i]&LPARA_MASK_BASE_DAYS)>>LPARA_SHIFT_BASE_DAYS )
#define         LPara_GetIntercalation(i)       ( (m_dwLunarParas[i]&LPARA_MASK_INTERCALATION)>>LPARA_SHIFT_INTERCALATION )
#define         LPara_GetBaseKanChi(i)          ( (m_dwLunarParas[i]&LPARA_MASK_BASE_KANCHI)>>LPARA_SHIFT_BASE_KANCHI )
#define         LPara_GetMonthDays(wYear,chMonth)       \
                                ( (((m_dwLunarParas[wYear]&LPARA_MASK_MONTH_DAYS)>>LPARA_SHIFT_MONTH_DAYS)>>chMonth)&0x01 )

// -----------------------------------------------------------
//      農(nóng)歷計算參數(shù)表
// -----------------------------------------------------------
static  const   INT32U  m_dwLunarParas[] =
{
        0x2E47752B, 0x5400952B, 0x3E012A5B, 0x2A21D55A, 0x4E02956A,     // 2005
        0x38733B55, 0x6003DBA4, 0x4A047B49, 0x32553A93, 0x5805DA95,
        0x4206752D, 0x2C470AAD, 0x50004AAD, 0x3C90F5AA, 0x620195D2,     // 2015
        0x4C022DA5, 0x3662FD4A, 0x5C038D4A, 0x46042C95, 0x3044D52E,
        0x54059556, 0x3E062AB5, 0x2A26D5B2, 0x500776D2, 0x3860AEA5,     // 2025
        0x5E015725, 0x4801F64B, 0x32528C97, 0x56035CAB, 0x4203E55A,
        0x2C348AD6                                                                              // 2031
};

#define FIRSTYEAR       2001                                                    // 參數(shù)表中的第一年
#define YEAR_NUMS       ( sizeof(m_dwLunarParas) / sizeof(INT32U) )
#define LASTYEAR        ( FIRSTYEAR + YEAR_NUMS - 1 )           // 參數(shù)表中的最后一年


// -----------------------------------------------------------
//      公歷年每月天數(shù)標記表
//              由高位到低位為12-1月:1表示31天,0表示30天,二月除外
//      月份: 12  11  10   9    8   7    6   5    4   3    2    1
//                31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 28, 31
//                1    0    1    0   1    1    0    1   0   1    0   1
// -----------------------------------------------------------
static  const   INT16U  m_wSolarMonthDaysFlag = 0x0AD5;

// -----------------------------------------------------------
// 公歷年每月累積天數(shù), 平年與閏年
// -----------------------------------------------------------
static  const   INT16U m_wSolarDays[14] =
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365, 396 };


// -----------------------------------------------------------
// 求此公歷年是否為閏年, 返回 0 為平年, 1 為閏年
// -----------------------------------------------------------
BOOL    Lunar_IsIntercalation( INT16U   wYear )
{
        if ( wYear % 400 == 0 )
                return 1;
        else if ( wYear % 100 == 0 )
                return 0;
        else if ( wYear % 4 == 0 )
                return 1;
        else
                return 0;
}


// -----------------------------------------------------------
//      農(nóng)歷計算
// -----------------------------------------------------------
int Lunar_Cal( sSolarDateTag *psSolarDate, sLunarDateTag *psLunarDate )
{
        INT16U  wSolarMonth, wDaySum, wSolarDaysSum, im, wTmp1, wTmp2, i, wKanChiSum;
        BOOL    bLeapFlag;
        INT8U   chMonthDays, chYearIndex;

        // 輸入?yún)?shù)的有效性檢查
        if ( psSolarDate->wYear<=FIRSTYEAR || psSolarDate->wYear>LASTYEAR )
                return 1;

        wSolarMonth = psSolarDate->chMonth - 1;
        if ( wSolarMonth > 11 )
                return 2;

        bLeapFlag = Lunar_IsIntercalation( psSolarDate->wYear );
        if ( wSolarMonth == 1)
        // 二月
        {
                chMonthDays = bLeapFlag + 28;
        }
        else
        // 其他月份
        {
                chMonthDays = 30 + ((m_wSolarMonthDaysFlag>>wSolarMonth)&0x01);
        }

        if ( psSolarDate->chDate<1 || psSolarDate->chDate>chMonthDays )
                return 3;

        chYearIndex = psSolarDate->wYear - FIRSTYEAR;

        wSolarDaysSum = m_wSolarDays[wSolarMonth];
        if ( wSolarMonth > 1 )
                wSolarDaysSum += bLeapFlag;
        wDaySum = wSolarDaysSum + psSolarDate->chDate;

        wKanChiSum = wDaySum + LPara_GetBaseKanChi(chYearIndex);
        psLunarDate->chKan      = wKanChiSum % 10;
        psLunarDate->chChi      = wKanChiSum % 12;

        if ( wDaySum <= LPara_GetBaseDays(chYearIndex) )
        {
                chYearIndex--;
                psLunarDate->wYear      = psSolarDate->wYear - 1;
                bLeapFlag                       = Lunar_IsIntercalation( psLunarDate->wYear );
                wSolarMonth               += 12;

                wSolarDaysSum = m_wSolarDays[wSolarMonth];
                if ( wSolarMonth > 1 )
                        wSolarDaysSum += bLeapFlag;
                wDaySum = wSolarDaysSum + psSolarDate->chDate;
        }
        else
        {
                psLunarDate->wYear      = psSolarDate->wYear;
        }

        wTmp1 = LPara_GetBaseDays(chYearIndex);
        for ( i=0; i<13; i++ )
        {
                wTmp2 = wTmp1 + LPara_GetMonthDays( chYearIndex, i) + 29;
                if ( wDaySum <= wTmp2 )
                        break;
                wTmp1 = wTmp2;
        }

        psLunarDate->chMonth = i + 1;
        psLunarDate->chDate = wDaySum - wTmp1;

        im = LPara_GetIntercalation(chYearIndex);
        if ( im != 0 && psLunarDate->chMonth > im)
                psLunarDate->chMonth--;

        if ( psLunarDate->chMonth > 12)
                psLunarDate->chMonth -= 12;

        return 0;
}

 

  • 上一篇: 18B20驅(qū)動程序
  • 下一篇: 初學(xué)C51
  • 發(fā)表評論   告訴好友   打印此文  收藏此頁  關(guān)閉窗口  返回頂部
    熱點文章
     
    推薦文章
     
    相關(guān)文章
    網(wǎng)友評論:(只顯示最新5條。)
    關(guān)于我們 | 聯(lián)系我們 | 廣告合作 | 付款方式 | 使用幫助 | 機電之家 | 會員助手 | 免費鏈接

    點擊這里給我發(fā)消息66821730(技術(shù)支持)點擊這里給我發(fā)消息66821730(廣告投放) 點擊這里給我發(fā)消息41031197(編輯) 點擊這里給我發(fā)消息58733127(審核)
    本站提供的機電設(shè)備,機電供求等信息由機電企業(yè)自行提供,該企業(yè)負責(zé)信息內(nèi)容的真實性、準確性和合法性。
    機電之家對此不承擔(dān)任何保證責(zé)任,有侵犯您利益的地方請聯(lián)系機電之家,機電之家將及時作出處理。
    Copyright 2007 機電之家 Inc All Rights Reserved.機電之家-由機電一體化網(wǎng)更名-聲明
    電話:0571-87774297 傳真:0571-87774298
    杭州濱興科技有限公司提供技術(shù)支持

    主辦:杭州市高新區(qū)(濱江)機電一體化學(xué)會
    中國行業(yè)電子商務(wù)100強網(wǎng)站

    網(wǎng)站經(jīng)營許可證:浙B2-20080178-1