对于公元纪年、干支纪年、王公纪年、正月、蔀首等,凡年皆以岁首为分界,与建正无关。
公元纪年:公元前以负号表示,而不使用“公元前”或“BC”,以方便利用搜索功能。岁首为阳历1月(大寒所在月)。
干支纪年:以岁首判断纪年,而非正月。古六历中,颛顼历岁首为亥月,其余岁首皆为子月。表格以干支纪年分行。
王公纪年与干支纪年一致。
正月:除颛顼历建正与岁首不同外,其余皆相同。
蔀首月即历元岁首。
相关数据参考本表:https://blog.csdn.net/weixin_42763614/article/details/81319979
cxly = -722 #程序计算起点
tiangan = ["甲","乙","丙","丁","戊","己","庚","辛","壬","癸"]
dizhi = ["子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"]
yuefen =["正月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"]
jieqi = ["冬至","小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪"]
nlrq=["初一","初二","初三","初四","初五","初六","初七","初八","初九","初十","十一","十二","十三","十四","十五","十六","十七","十八","十九","二十","二一","二二","二三","二四","二五","二六","二七","二八","二九","三十"]
gz =['']*60 #干支表
for i in range(60):
gz[i] = tiangan[i%10]+dizhi[(i)%12]
#周BC841-BC256
zhou_name = ["共和","宣王","幽王","平王","桓王","庄王","釐(僖)王","惠王","襄王","顷王","匡王","定王","简王","灵王","景王","敬王","元王","贞定王","考王","威烈王","安王","烈王","显王","慎靓王","郝王"]
zhou_year = [14,46,11,51,23,15,5,25,33,6,6,21,14,27,25,43,8,28,15,24,26,7,48,6,59]
#鲁BC855-BC477
lu_name = ["真公","武公","懿公","孝公","惠公","隐公","桓公","庄公","湣(闵)公","釐(僖)公","文公","宣公","成公","襄公","昭公","定公","哀公"]
lu_year = [30,10,9,38,46,11,18,32,2,33,18,18,18,31,32,15,18]
#秦BC255-BC206
qin_name = ["昭王","惠文王","庄襄王","始皇帝","二世"]
qin_year = [56,1,3,37,3]
#汉BC206-BC104
han_name = ["高祖","惠帝","高后","文帝","景帝","武帝"]
han_nh = [[''],[''],[''],['','后元'],['','中元','后元'],['建元','元光','元朔','元狩','元鼎','元封','太初']]
han_year = [[12],[7],[8],[16,7],[7,6,3],[6,6,6,6,6,6,4]]
bsgz=[0]*20 #蔀首干支
for i in range(20):
bsgz[i] = (i*39)%60
yue = 29+499/940 #朔策
zai = 12 * yue #太阴年
sui = 365+1/4 #岁实
sddy = int(zai) % 60 #朔旦大余
sdxy= (499 * 12 ) % 940 #朔旦小余
sdrf = 940 #朔旦日法
zqi = sui/12 #中气30又14/32
zqrf = 32
zqdy = 30
zqxy = 14
ydy = int(yue)
yxy = 499 #每月小余499
yueri = 0
gllb = []
yf = 4560
bf = 76
br = 27759
by = 940
lm = ["黄帝历","颛顼历","夏历","殷历","周历","鲁历"]
ly= [-1350,-1506,-1076,-1567,-1624,-2001] #辛卯元,乙卯元,乙丑元,甲寅元,丁巳元庚子元
def sz2hz(x): #数字转为汉字
hzjs = ["一","二","三","四","五","六","七","八","九","十"]
if x == 0: # 1
return '元'
elif x < 10: # 2-9
return hzjs[x]
elif 9<x<19: # 10-19
return hzjs[9]+hzjs[int(str(x)[1])]
elif (x+1)%10 == 0: # 20以上的整十
return hzjs[int(str(x)[0])]+hzjs[int(str(x)[1])]
else:
return hzjs[int(str(x)[0])-1]+hzjs[9]+hzjs[int(str(x)[1])]
def wnh(guohao,name,year,x): #无年号
global ce
ce = ce - x
for i in range(len(name)):
for j in range(year[i]):
if (i == 0 and j >= x) or i > 0: #非首年
wgjn[ce+841] = guohao + name[i] + sz2hz(j) + '年'
ce += 1
return wgjn
def ynh(guohao,name,nianhao,year): #有年号
global ce
for i in range(len(name)):
for j in range(len(nianhao[i])):
for k in range(year[i][j]):
wgjn[ce + 841] = guohao + name[i] + nianhao[i][j] + sz2hz(k) + '年'
ce += 1
return wgjn
ce = -841
wgjn = ['']*(1000)
lgwn = ['']*365
wnh('鲁', lu_name, lu_year, 14)
for i in range(365):
lgwn[i] = wgjn[i]
ce = -841
wnh('周', zhou_name, zhou_year, 0)
wnh('秦', qin_name, qin_year, 51)
ynh('汉', han_name, han_nh, han_year)
for i in range(365):
wgjn[i] = wgjn[i] + '、' + lgwn[i]
def tzs(ly,cxly):#求任意一年的天正朔
if ly == -2001: #鲁历
cxly -= 8
if cxly > 0:
syjn = -ly + yf * 605 + cxly - 1
else:
syjn = -ly + yf * 605 - abs(cxly)
ryn = syjn % yf # 入元年
rbn = ryn % bf # 入蔀年
rbs = ryn // bf # 入蔀数
jy = int(rbn * 235 / 19) # 积月
sjr = jy * (br / by) # 朔积日
ydy_0 = int((sjr) % 60) # 天正朔大小余
yxy_0 = round((sjr % 60 - int(sjr % 60)) * by)
qjr = rbn * 365.25
zqdy_0 = int((qjr) % 60)
zqxy_0 = round(((qjr) % 60 - zqdy_0) * zqrf) % 32
return (ydy_0-ydy+bsgz[rbs])%60,yxy_0-yxy,(zqdy_0-zqdy+bsgz[rbs])%60,zqxy_0-zqxy
def qy(dy_0,xy_0,rf,dy,xy): #求大小余分(余分前值,日法,余分)
xy_0 += xy
if xy_0 <= 0: # 逆推
dy_0 -= 1
xy_0 += rf
if xy_0 >= rf: # 顺推
dy_0 += 1
xy_0 -= rf
dy_0 = (dy_0 + dy) % 60
return dy_0, xy_0
def dxy(xy_0): #判断大小月
if xy_0 < 441:
return "小"
else:
return "大"
def wzqy(dy_0,xy_0,sdy_0,sxy_0): #无中气月(气大小余、朔大余、朔小余)
global yueri
if dxy(sxy_0) == "大": yueri = 30
else:yueri = 29
if (int(dy_0+xy_0/32+zqi)-sdy_0)%60>=yueri: #上一个中气值加中气日数即预推下一个中气的值,下一中气不在该月中则该月无中气
x = True
return x,dy_0,xy_0
else:
dy_0, xy_0 = qy(dy_0, xy_0, zqrf, zqdy, zqxy)
x = False
return x,dy_0,xy_0
def gllsrb(lm,ly,lyngz,ydy_0,yxy_0,zqdy_0,zqxy_0,cxly): #历名,历元,历元年干支
yln = cxly
gllsrb = open(lm+"朔闰表.csv", 'w')
glllb = open(lm+"历表.csv", 'w')
jqdy_0, jqxy_0 = qy(zqdy_0, zqxy_0, zqrf, zqdy // 2, zqxy // 2)
header = ["公元纪年","王公纪年", "干支纪年", "蔀名", "入蔀年", "月份", "朔日干支", "朔日大余", "朔日小余", "中气", "中气干支", "中气大余", "中气小余", "中气日期"]
gllsrb.write(','.join(header) + '\n')
header2 = ["公元纪年","王公纪年", "干支纪年", "月份", "中气", "中气干支", "节气", "节气干支", '']
glllb.write(','.join(header2 + nlrq) + '\n')
j = 0 #月数
jqcx = 1 #节气序号
lygz = 0
bs = 0
jzss = 0 #建正与岁首相差的月数
dzss = 0 #冬至与岁首相差的月数
jzly = 0 #建正与历元相差的月数
if lm == "颛顼历": #历元立春己巳朔旦,其余皆历元冬至甲子
jqcx = -1
lygz = 5
dzss = 1
jzss = 3 #岁首亥月
ydy_0, yxy_0 = qy(ydy_0, yxy_0, sdrf, 2 * -ydy, 2 * -yxy)
zqdy_0, zqxy_0 = qy(zqdy_0, zqxy_0, zqrf, -zqdy * 5 // 2, -zqxy * 5 // 2)
jqdy_0, jqxy_0 = qy(zqdy_0, zqxy_0, zqrf, zqdy // 2, zqxy // 2)
if lm == "夏历":
jzss = 2
jzly = 2
if lm == "鲁历":
bs = 18
while yln < -103:
ydy_0, yxy_0 = qy(ydy_0, yxy_0, sdrf, ydy, yxy)
zr, zqdy_0, zqxy_0 = wzqy(zqdy_0, zqxy_0, ydy_0, yxy_0)
wjq, jqdy_0, jqxy_0 = wzqy(jqdy_0, jqxy_0, ydy_0, yxy_0)
#节气
if wjq == True:
jq = "无节气"
jqgz = "\t"
else:
jq = jieqi[jqcx % 24]
jqgz = gz[(lygz+jqdy_0-bs)%60]
jqcx += 2
#历表
if zr == True:
j -= 1
ce = cxly + (j - 1 - dzss) // 12
yln = cxly + (j-jzly) // 12
rbs = (-ly + yln) // 76
srb = [ce,wgjn[841+yln], gz[(-ly+yln+lyngz)%60],gz[bsgz[rbs%20]],(-ly+yln)%76+1,"闰" + yuefen[(j-jzss) % 12] + dxy(yxy_0),gz[(lygz+ydy_0-bs)%60], (ydy_0-bsgz[rbs%20]-bs) % 60,yxy_0, "无中气",'','','','']
hlb = [ce,wgjn[841+yln], gz[(-ly+yln+lyngz)%60],"闰" + yuefen[(j-jzss) % 12] + dxy(yxy_0),"无中气",'',jq,jqgz,'']
else:
ce = cxly + (j - 1 - dzss) // 12
yln = cxly + (j-jzly) // 12
rbs = (-ly + yln) // 76
srb = [ce,wgjn[841+yln], gz[(-ly+yln+lyngz)%60],gz[bsgz[rbs%20]],(-ly+yln)%76+1,yuefen[(j-jzss) % 12] + dxy(yxy_0), gz[(lygz+ydy_0-bs)%60],(ydy_0-bsgz[rbs%20]-bs) % 60,yxy_0,jieqi[(j-dzss)%12*2], gz[(lygz+zqdy_0-bs)%60],(zqdy_0-bsgz[rbs%20]-bs)%60,zqxy_0,nlrq[(zqdy_0-ydy_0)%30]]
hlb = [ce,wgjn[841+yln], gz[(-ly+yln+lyngz)%60],yuefen[(j-jzss) % 12] + dxy(yxy_0),jieqi[(j-dzss)%12*2], gz[(lygz+zqdy_0-bs)%60],jq,jqgz,'']
for k in range(yueri):
gllb.append(gz[(lygz+ydy_0+k) % 60])
if (j-jzly) % 12 == 0 and j != 0 and zr == False:
gllsrb.write('\n')
glllb.write('\n')
j += 1
gllsrb.write(','.join('%s' % id for id in srb) + '\n')
glllb.write(','.join('%s' % id for id in hlb+gllb) + '\n')
gllb.clear()
for i in range(6): #黄帝历0,颛顼历1,夏历2,殷历3,周历4,鲁历5
ydy_0,yxy_0,zqdy_0,zqxy_0 = tzs(ly[i],cxly)
gllsrb(lm[i],ly[i],ly[i]%60-3,ydy_0,yxy_0,zqdy_0,zqxy_0,cxly)
参考资料:张培瑜《中国先秦史历表》