公历转农历算法(公历转农历算法详解)
导语:公历转农历算法详解什么是公历和农历公历,也称为阳历或西历,是以地球绕太阳公转周期为基础的历法,于公元前45年由朱利叶斯·凯撒引入罗马,并逐渐被世界各国广泛使用。农历,也称为阴历或中国传统历法,是一种根据月亮运行周期计算的历法,源于中国的农耕...
公历转农历算法详解
什么是公历和农历
公历,也称为阳历或西历,是以地球绕太阳公转周期为基础的历法,于公元前45年由朱利叶斯·凯撒引入罗马,并逐渐被世界各国广泛使用。农历,也称为阴历或中国传统历法,是一种根据月亮运行周期计算的历法,源于中国的农耕文化,中国自古以来一直采用农历作为官方历法。公历转农历的基本原理
公历转农历算法的基本原理是根据阳历日期计算对应的农历日期。这个过程需要计算阳历日期对应年份的元旦是农历几月几日,以及阳历日期和元旦的时间差,再根据这个时间差去对应到农历日期。公历转农历算法的具体步骤
以下是一个基于Python的公历转农历算法实现示例,总共分为4个步骤:1. 计算阳历日期到1900年1月31日的天数差```pythondef date_to_daynum(year, month, day): month_days = [0,31,59,90,120,151,181,212,243,273,304,334] total_days = (year-1900)*365 + (year-1900)//4 + month_days[month-1] + day if year%4==0 and month>2 : total_days += 1 return total_days```2. 计算从1900年2月1日到所求日期之间的天数```pythontotal_days = date_to_daynum(year, month, day)days_since_1900 = total_days - date_to_daynum(1900, 1, 31) # 1900/1/31是农历小年```3. 找到阳历日期对应的农历年份和月份```pythonlunar_year = 1900while days_since_1900 >= 0: days_in_lunar_year = 365 + lunar_month_days(lunar_year) # 当前农历年的天数 if days_since_1900 >= days_in_lunar_year: days_since_1900 -= days_in_lunar_year lunar_year += 1 else: lunar_month = 1 while days_since_1900 >= 0: days_in_lunar_month = lunar_month_days(lunar_year, lunar_month) if days_since_1900 >= days_in_lunar_month: days_since_1900 -= days_in_lunar_month lunar_month += 1 else: lunar_day = days_since_1900 + 1 break break```4. 计算农历日期```pythonlunar = str(lunar_year) + \"年\" + chinese_month(lunar_month) + \"月\" + chinese_day(lunar_day) + \"日\"```其中,lunar_month_days和chinese_month和chinese_day是辅助函数,用于计算农历某月的天数和汉字表示:```pythondef lunar_month_days(lunar_year, lunar_month=0): lunar_month_days_table = [ 0x97400, 0x4b250, 0x4b258, 0x4b25e, 0x4b268, 0x4b270, 0x4b288, 0x4b290, 0x4b2a0, 0x4b2c0, 0x4b2e4, 0x4b2e8, 0x4b2f0, 0x4b320, 0x4b328, 0x4b350, 0x4b358, 0x4b370, 0x4b390, 0x4b3a4, 0x4b3a8, 0x4b3b0, 0x4b3b5, 0x4b3c4, 0x4b3c8, 0x4b3d0, 0x4b3e0, 0x4b400, 0x4b420, 0x4b430, 0x4b450, 0x4b458, 0x4b460, 0x4b488, 0x4b490, 0x4b4a0, 0x4b4a8, 0x4b4b0, 0x4b4b8, 0x4b4c0, 0x4b4d0, 0x4b4d8, 0x4b4e0, 0x4b4e5, 0x4b4f0, 0x4b510, 0x4b530, 0x4b538, 0x4b540, 0x4b570, 0x4b578, 0x4b5a0, 0x4b5a5, 0x4b5b0, 0x4b5d0, 0x4b5d4, 0x4b5d8, 0x4b5e0, 0x4b5e5, 0x4b5f0, 0x4b610, 0x4b630, 0x4b638, 0x4b640, 0x4b670, 0x4b678, 0x4b680, 0x4b6a0, 0x4b6a5, 0x4b6b0, 0x4b6d0, 0x4b6e0, 0x4b6e8, 0x4b6f0, 0x4b710, 0x4b730, 0x4b738, 0x4b740, 0x4b750, 0x4b760, 0x4b770, 0x4b778, 0x4b7a0, 0x4b7a5, 0x4b7b0, 0x4b7b5, 0x4b7c0, 0x4b7d0, 0x4b7d8, 0x4b7e0, 0x4b7e5, 0x4b7f0, 0x4b810, 0x4b830, 0x4b838, 0x4b840, 0x4b860, 0x4b888, 0x4b890, 0x4b8a0, 0x4b8a4, 0x4b8b0, 0x4b8b8, 0x4b8c0, 0x4b8d0, 0x4b8d8, 0x4b8e0, 0x4b8f0, 0x4b900, 0x4b920, 0x4b938, 0x4b940, 0x4b950, 0x4b960, 0x4b970, 0x4b980, 0x4b990, 0x4b9a0, 0x4b9b0, 0x4b9b8, 0x4b9c0, 0x4b9d0, 0x4b9d8, 0x4b9e0, 0x4b9e5, 0x4b9f0, 0x4ba10, 0x4ba30, 0x4ba38, 0x4ba40, 0x4ba58, 0x4ba60, 0x4ba80, 0x4ba90, 0x4ba98, 0x4baa0, 0x4bab0, 0x4bab8, 0x4bac0, 0x4bad0, 0x4bad8, 0x4bae0, 0x4baf0, 0x4bb00, 0x4bb20, 0x4bb30, 0x4bb38, 0x4bb40, 0x4bb50, 0x4bb60, 0x4bb68, 0x4bb70, 0x4bb80, 0x4bb90, 0x4bb98, 0x4bba0, 0x4bbb0, 0x4bbb8, 0x4bbc0, 0x4bbd0, 0x4bbd8, 0x4bbe0, 0x4bbf0, 0x4bc00, 0x4bc20, 0x4bc38, 0x4bc40, 0x4bc50, 0x4bc60, 0x4bc68, 0x4bc70, 0x4bc80, 0x4bc90, 0x4bc98, 0x4bca0, 0x4bcb0, 0x4bcb8, 0x4bcc0, 0x4bcd0, 0x4bcd8, 0x4bce0, 0x4bcf0, 0x4bd00, 0x4bd20, 0x4bd30, 0x4bd40, 0x4bd50, 0x4bd58, 0x4bd60, 0x4bd80, 0x4bd90, 0x4bda8, 0x4bdb0, 0x4bdc0, 0x4bdd0, 0x4bdd8, 0x4bde0, 0x4bdf0, 0x4be00, 0x4be10, 0x4be18, 0x4be20, 0x4be38, 0x4be40, 0x4be50, 0x4be60, 0x4be68, 0x4be70, 0x4be80, 0x4be90, 0x4be98, 0x4bea0, 0x4beb0, 0x4beb8, 0x4bec0, 0x4bed0, 0x4bed8, 0x4bee0, 0x4bef0, 0x4bf00, 0x4bf10, 0x4bf18, 0x4bf20, 0x4bf30, 0x4bf40, 0x4bf50, 0x4bf60, 0x4bf68, 0x4bf70, 0x4bf80, 0x4bf90, 0x4bf98, 0x4bfa0, 0x4bfb0, 0x4bfb8, 0x4bfc0, 0x4bfd0, 0x4bfd8, 0x4bfe0, 0x4bff0, ] r = 0 if lunar_month != 0: days = (lunar_month_days_table[lunar_month-1] & 0x80) != 0 r = lunar_month_days_table[lunar_month-1] & 0x7f if days and lunar_year%4==0: r += 1 else: for i in range(12): days = (lunar_month_days_table[i] & 0x80) != 0 r += lunar_month_days_table[i] & 0x7f if days and lunar_year%4==0 and i+1<=2: r += 1 return rdef chinese_month(month): months = \"正二三四五六七八九十冬腊\" return months[month-1]def chinese_day(day): if day <= 10: return \"初\" + chinese_number(day) elif day < 20: return \"十\" + chinese_number(day-10) elif day == 20: return \"二十\" elif day < 30: return \"廿\" + chinese_number(day-20) else: return \"三十\" def chinese_number(number): numbers = \"零一二三四五六七八九十\" return numbers[number]```总结
是公历转农历算法的基本原理和具体步骤。我们可以看出,这个算法不是很复杂,但是需要考虑到很多细节问题,比如润年、闰月等等。在实际应用中,我们可以使用已经实现好的库来避免一些奇怪的边界问题,比如Python的lunarcalendar库,也可以参考其他语言的实现来自行编写。参考文献
- https://www.zhihu.com/question/22118236- https://zh.wikipedia.org/zh-hans/%E5%85%AC%E5%8E%86- https://zh.wikipedia.org/zh-hans/%E5%86%9C%E6%9B%86
免责申明:以上内容属作者个人观点,版权归原作者所有,如有侵权或内容不符,请联系我们处理,谢谢合作!
评论
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。