C 實現的農曆演算法

2021-04-18 00:30:32 字數 4559 閱讀 9833

農曆演算法簡介以及公式

一、節氣的計算

先給節氣進行編號,從近日點開始的第乙個節氣編為0,編號如下及其相應的月份如下:

0 小寒 臘月

6  清明 三月

12 小暑 六月

18 寒露 九月

1 大寒 臘月

7  穀雨 三月

13 大暑 六月

19 霜降 九月

2 立春 正月

8  立夏 四月

14 立秋 七月

20 立冬 十月

3 雨水 正月

9  小滿 四月

15 處暑 七月

21 小雪 十月

4 驚蟄 二月

10 芒種 五月

16 白露 八月

22 大雪 冬月

5 春分 二月

11 夏至 五月

17 秋分 八月

23 冬至 冬月

把當天和2023年1月0日(星期日)的差稱為積日,那麼第y年(2023年算第0年)第x 個節氣的積日是

f = 365.242 * y + 6.2 + 15.22 * x - 1.9 * sin(0.262 * x)

這個公式的誤差在0.05天左右。

二、朔日的計算

從2023年開始的第m個朔日的公式是

m = 1.6 + 29.5306 * m + 0.4 * sin(1 - 0.45058 * m)

這個公式的誤差在0.2天左右。

三、年份的確定

2023年1月0日是農曆癸亥年,所以用當年減去1864,用10除得的餘數作為年份天乾的,用12除得的餘數作為年份的地支,數字對應的天乾和地支如下。

數字 0

1 23 4

5 67 8

9 10

11 天乾

甲 乙丙 丁

戊 己庚 辛

壬 癸地支

子 丑寅 卯

辰 巳午 未

申 酉戌 亥

當年的1月0日換算為積日,可以用年份減去1900得到的年數被4整除,所得商數作為 y(d4),餘數作為y(m4),y(m4)為零的年份是公曆閏年,積日是

d(1) = 1461 * y(d4) - 1

y(m4)不為零的年份是公曆平年,積日是

d(1) = 1461 * y(d4) + 365 * y(m4)

四、月份的確定

計算前一年冬至的積日f(0),並用f(0)計算冬至所在的朔月m及其朔日m(0),就可以推算冬至的農曆日期,冬至所在的農曆月份總是十一月。計算下乙個中氣f(1)和下乙個朔日m(1),如果f(1)

太陽公轉週期,一年時間約365.2425天。

公曆為了對齊公轉週期,4年一閏,100年一停閏,400年加一閏。 400年共97閏, (365×400+97)/400 = 365.2425

農曆,乙個月相週期為一月,月相週期大約為29.53,   有大小月之分,大月30天,小月29天。月相變化受到地球公轉和月亮圍繞地球轉的共同影響,兩個都是橢圓軌道,且不在乙個平面上,非常複雜。所以,大小月變化規律不是乙個簡單的規律。

農曆為了對齊公轉週期,每19年加7個閏月,

因為,農曆的推算比較複雜, 大多使用查表法進行計算,包括我這裡提供的演算法。

我一直想實現乙個計算軌道的推算方法,因為人懶,現在還沒有什麼進展。我會繼續關注。

現在看到網上沒有找到滿意的c++查表農曆演算法法實現,所以自己實現了乙個。

以下檔案在linux   g++ (gcc) 4.1.2 環境編譯通過

//file: lunarday.h

//author: [email protected]

//2007-02-13 11:22:04

#ifndef luanr_calendar_h

#define luanr_calendar_h

namespace lunar

date;

//公曆轉農曆

date luanrdate(

int solar_year,

int solar_month,

int solar_day);}

//file: lunarday.cpp

//author: [email protected]

//2007-02-13 11:22:48

#include

"lunarday.h"

#include

<

ctime

>

#include

#include

#include

<

iostream

>

using

namespace

std;

using lunar:

:date;

//使用位元位記錄每年的情況

//0~4 共5bit 春節日份

//5~6 共2bit 春節月份

//7~19 共13bit 13個月的大小月情況(如果無閏月,最後位無效),大月為1,小月為0

//20~23 共4bit 記錄閏月的月份,如果沒有閏月為0

static

const

int begin_year = 1901;

static

const

int number_year = 199;

static

const

unsigned

int lunar_years[199]=;

//計算這個公曆日期是一年中的第幾天

static

int dayofsolaryear(

int year,

int month,

int day )

;//閏年的情況

static

const

int leap_yday[12]=;

const

int*t_year_yday_ = normal_yday;

//判斷是否是公曆閏年

if( year % 4 =

=0 )

return t_year_yday_[month -1]

+(day -1);}

date lunar:

:luanrdate(

int solar_year,

int solar_month,

int solar_day)

int luanr_month = 1;

//計算月份和日期

for(

;luanr_month<

=13;luanr_month++)

luanr_date.day = today_luanr_yd;

//處理閏月

int leap_month =

(lunar_years[year_index]

>

>20)

& 0xf;

if(leap_month > 0 &

& leap_month < luanr_month )

assert

(leap_month <

= 12)

;luanr_date.month = luanr_month;

return luanr_date;

}

測試主函式,列印當前農曆日期

//file: chdate.cpp

//author: [email protected]

//2007-02-13 11:21:45

#include

<

iostream

>

#include

<

ctime

>

#include

"lunarday.h"

int main(

int argc,

char

*argv)

makefile檔案,如下

#makefile for chdate

cpp = g++

ld = g++

cc_flag =   

ld_flag =

file_list = lunarday.cpp chdate.cpp

obj_list =  $(file_list:%.cpp=%.o)

bin = chdate

default: $(bin)

$(bin): $(obj_list)

$(ld) $(ld_flag) -o $(bin) $(obj_list)

%.o : %.cpp

@$(cpp) $(cc_flag) -c $< -o $@

clean:

rm $(obj_list) $(bin)

執行效果如下

sideleft@doom:~/workspace/luanrday$ ./chdate

2023年12月26日

php實現的農曆演算法例項

再加當年的幾個月 total gmdate z gmmktime 0,0,0,month,1,year 用農曆的天數累加來判斷是否超過陽曆的天數 flag1 0 判斷跳出迴圈的條件 lcj 0 while lcj 120 lci if flag1 1 break lcj 由上,得到的 lci 為當前...

C 實現農曆日曆的方法

具體實現方法如下 複製 如下 天乾 private static string tiangan 地支 private static string dizhi 十二生肖 private static string shengxiao 農曆日期 private static string dayname...

C 公曆轉農曆演算法

using system using system.collections.generic using system.text 地支 private static string dizhi 十二生肖 private static string shengxiao 農曆日期 private stati...