公历转农历的程序(代码转载于网络)

一、简介

       该算法从网上找到,将公历转成农历,只能计算1921年-2021年间的农历。只能显示 甲午年,生肖和农历,无法得到 庚午月、癸丑日。

二、函数

/*------------农历转换函数-----------*/

void Window::get_chinese_calendar(QDate english_calendar, QString &outLunarDay, QString &outLunarYear)
{
    int currentYear = 0, currentMonth = 0, currentDay = 0;
    int nTheDate = 0;
    int nisEnd = 0, flag = 0, n = 0, k = 0, nBit = 0, i = 0;
    char m_Lunar[100] = {0}, m_LunarDay[50] = {0}, m_zodiak[50] = {0};
    /*天干名称*/
    const char *m_TianGan[] = {"甲","乙","丙","丁","戊","己","庚","辛","壬","癸"};
    /*地支名称*/
    const char *m_DiZhi[] = {"子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"};
    /*属相名称*/
    const char *m_ShuXiang[] = {"鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"};
    /*农历日期名*/
    const char *m_DayName[] = {"*","初一","初二","初三","初四","初五",
          "初六","初七","初八","初九","初十",
          "十一","十二","十三","十四","十五",
          "十六","十七","十八","十九","二十",
          "廿一","廿二","廿三","廿四","廿五",
          "廿六","廿七","廿八","廿九","三十"};
     /*农历月份名*/
    const char *m_MonthName[] = {"*","正","二","三","四","五","六","七","八","九","十","十一","腊"};
    /*公历每月前面的天数*/
    const int m_DayAdd[12] = {0,31,59,90,120,151,181,212,243,273,304,334};
    /*农历数据*/
    const int m_LunarData[100]= {2635,333387,1701,1748,267701,694,2391,133423,1175,396438
                                 ,3402,3749,331177,1453,694,201326,2350,465197,3221,3402
                                 ,400202,2901,1386,267611,605,2349,137515,2709,464533,1738
                                 ,2901,330421,1242,2651,199255,1323,529706,3733,1706,398762
                                 ,2741,1206,267438,2647,1318,204070,3477,461653,1386,2413
                                 ,330077,1197,2637,268877,3365,531109,2900,2922,398042,2395
                                 ,1179,267415,2635,661067,1701,1748,398772,2742,2391,330031
                                 ,1175,1611,200010,3749,527717,1452,2742,332397,2350,3222
                                 ,268949,3402,3493,133973,1386,464219,605,2349,334123,2709
                                 ,2890,267946,2773,592565,1210,2651,395863,1323,2707,265877};

    currentYear = english_calendar.year();
    currentMonth = english_calendar.month();
    currentDay = english_calendar.day();
    /*---计算到初始时间1921年2月8日的天数:1921-2-8(正月初一)---*/
    nTheDate = (currentYear - 1921) *365 + (currentYear - 1921)/4  + m_DayAdd[currentMonth - 1] + currentDay - 31 - 7;
    if((!(currentYear % 4)) && (currentMonth > 2))
        nTheDate = nTheDate + 1;
    /*--计算农历天干、地支、月、日---*/
    nisEnd = 0;
    flag = 0;
    while (nisEnd != 1) {
        if (m_LunarData[flag] < 4095)  k = 11;
        else  k = 12;
        n = k;
        while (n >= 0) {
             //m_LunarData(flag)的第n个二进制位的值
            nBit = m_LunarData[flag];
            for (i = 1; i < n + 1; i++)  nBit = nBit / 2;
            nBit = nBit % 2;
            if (nTheDate <= (29 + nBit)) {
                nisEnd = 1;
                break;
            }
            nTheDate = nTheDate - 29 - nBit;
            n = n - 1;
        }
        if (nisEnd)  break;
        flag = flag + 1;
    }
    currentYear = 1921 + flag;
    currentMonth = k - n + 1;
    currentDay = nTheDate;
    if (k == 12) {
        if (currentMonth == m_LunarData[flag] / 65536 + 1)  currentMonth = 1 - currentMonth;
        else if (currentMonth > m_LunarData[flag] / 65536 + 1)  currentMonth = currentMonth - 1;
    }
    /*--生成农历天干、地支、属相*/
    sprintf(m_zodiak, "%s", m_ShuXiang[((currentYear - 4) % 60) % 12]);
    sprintf(m_Lunar, "%s%s年 【%s年】", m_TianGan[((currentYear - 4) % 60) % 10], m_DiZhi[((currentYear - 4) % 60) % 12], m_zodiak);
    /*--生成农历月、日*/
    if (currentMonth < 1)
        sprintf(m_LunarDay ,"闰%s", m_MonthName[-1 * currentMonth]);
    else
        strcpy(m_LunarDay, m_MonthName[currentMonth]);
    strcat(m_LunarDay,"月");
    strcat(m_LunarDay, m_DayName[currentDay]);

    outLunarYear = tr(m_Lunar);
    outLunarDay = tr(m_LunarDay);
}

三、调用

QString m_LunarYear = "", m_LunarDay = "";

QDate date = QDate::currentDate();     //

get_chinese_calendar(date, m_LunarYear, m_LunarDay);

qDebug() << outLunarDay;
qDebug() << outLunarYear;

运行结果:



四、总结

        (1)有研究该技术的好友可以提出更好的建议,sprintf(m_Lunar, "%s%s年 【%s年】", m_TianGan[((currentYear - 4) % 60) % 10], m_DiZhi[((currentYear - 4) % 60) % 12], m_zodiak);只能 得到甲午年,月日应该怎么计算了。

       (2)该代码是程序的一部分。需要c++使用的可改QString为String,C的更简单将m_Lunar和m_LunarDay数组作为参数传递。

       (3)若需要沟通可以联系[email protected]

patch1:

(1)计算农历的月日:

char p_LunarMonth[50] = {0}, p_LunarDay[50] = {0};
int nTheMonth = (currentYear- 1921) * 12 - 2 + currentMonth;

sprintf(p_LunarMonth, "%s%s月", m_TianGan[(nTheMonth + 6) % 10], m_DiZhi[(nTheMonth + 2) % 12]);
sprintf(p_LunarDay, "%s%s日", m_TianGan[(nTheDate + 7) % 10], m_DiZhi[(nTheDate + 1) % 12]);
输入结果为:

(2)还是不清楚农历数据const int m_LunarData[100]怎么获得的,符合什么规则。有明白的可以推荐讲解。
   


你可能感兴趣的:(linux,公历转农历)