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

一、简介

       该算法从网上找到,将公历转成农历,只能计算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)若需要沟通可以联系yang.ao@i-soft.com.cn。

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]怎么获得的,符合什么规则。有明白的可以推荐讲解。
   


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
要编写Excel公历农历的函数代码,可以遵循以下步骤: 1. 定义公历农历的数据表:首先,需要创建一个公历农历的数据表,该表包含了每个公历日和对应的农历日。可以从互联网上搜索到这样的表,或者使用已有的开源数据。 2. 导入数据表:将公历农历的数据表导入Excel,确保数据表中的每一列有一个唯一的标识符,如公历日期和农历日期。 3. 创建VLOOKUP函数:在Excel中,可以使用VLOOKUP函数来查找公历日期并返回对应的农历日期。语法为:VLOOKUP(lookup_value, table_array, col_index_num, range_lookup)。其中,lookup_value是待查找的公历日期,table_array是导入的数据表范围,col_index_num是农历日期所在的列号,range_lookup设置为FALSE表示精确匹配。 4. 结合DATE函数:如果要将公历日期拆分为年、月和日,并换为对应的农历日期,可以结合DATE函数和VLOOKUP函数。例如,DATE函数用于将年、月和日作为参数,返回对应的公历日期,然后使用VLOOKUP函数将公历日期换为农历日期。 5. 自定义函数:可以将上述步骤封装为一个自定义函数,以便在Excel中直接调用。自定义函数包含输入参数,例如公历日期,然后执行上述步骤,并返回农历日期。 通过以上步骤,可以编写一个Excel公历农历的函数代码。具体实现方式取决于具体的数据表和需求,并可能需要进行一些调整和优化。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乌托邦2号

博文不易,支持的请给予小小打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值