求农历公历互转算法
已在本论坛找到公历转农历的函数。求农历转公历的函数或算法。
尝试利用公历转农历函数原理反推。
可惜能力有限,无法看懂。
求高手们帮助,十分感激! 请问下如何拓展查询的年限呢
目前在论坛找到的代码只能查询范围 1901-2099 之间的日期。
请问如何能增加到2100或更高呢
看了下应该和这些数据有关,但是不知道这是二进制还是其他:Local $gLunarMonthDay = _
[0X4ae0, 0Xa570, 0X5268, 0Xd260, 0Xd950, 0X6aa8, 0X56a0, 0X9ad0, 0X4ae8, 0X4ae0, _
0Xa4d8, 0Xa4d0, 0Xd250, 0Xd548, 0Xb550, 0X56a0, 0X96d0, 0X95b0, 0X49b8, 0X49b0, _
0Xa4b0, 0Xb258, 0X6a50, 0X6d40, 0Xada8, 0X2b60, 0X9570, 0X4978, 0X4970, 0X64b0, _
0Xd4a0, 0Xea50, 0X6d48, 0X5ad0, 0X2b60, 0X9370, 0X92e0, 0Xc968, 0Xc950, 0Xd4a0, _
0Xda50, 0Xb550, 0X56a0, 0Xaad8, 0X25d0, 0X92d0, 0Xc958, 0Xa950, 0Xb4a8, 0X6ca0, _
0Xb550, 0X55a8, 0X4da0, 0Xa5b0, 0X52b8, 0X52b0, 0Xa950, 0Xe950, 0X6aa0, 0Xad50, _
0Xab50, 0X4b60, 0Xa570, 0Xa570, 0X5260, 0Xe930, 0Xd950, 0X5aa8, 0X56a0, 0X96d0, _
0X4ae8, 0X4ad0, 0Xa4d0, 0Xd268, 0Xd250, 0Xd528, 0Xb540, 0Xb6a0, 0X96d0, 0X95b0, _
0X49b0, 0Xa4b8, 0Xa4b0, 0Xb258, 0X6a50, 0X6d40, 0Xada0, 0Xab60, 0X9370, 0X4978, _
0X4970, 0X64b0, 0X6a50, 0Xea50, 0X6b28, 0X5ac0, 0Xab60, 0X9368, 0X92e0, 0Xc960, _
0Xd4a8, 0Xd4a0, 0Xda50, 0X5aa8, 0X56a0, 0Xaad8, 0X25d0, 0X92d0, 0Xc958, 0Xa950, _
0Xb4a0, 0Xb550, 0Xb550, 0X55a8, 0X4ba0, 0Xa5b0, 0X52b8, 0X52b0, 0Xa930, 0X74a8, _
0X6aa0, 0Xad50, 0X4da8, 0X4b60, 0X9570, 0Xa4e0, 0Xd260, 0Xe930, 0Xd530, 0X5aa0, _
0X6b50, 0X96d0, 0X4ae8, 0X4ad0, 0Xa4d0, 0Xd258, 0Xd250, 0Xd520, 0Xdaa0, 0Xb5a0, _
0X56d0, 0X4ad8, 0X49b0, 0Xa4b8, 0Xa4b0, 0Xaa50, 0Xb528, 0X6d20, 0Xada0, 0X55b0]小弟愚笨,还请高人指点! 有高人能回答下吗?这个0xxxx是什么规律呢? 这里有段c语言的农历转公历代码
http://wenku.baidu.com/view/09425b687e21af45b307a803.html
它支持 1901 到 2099 帮顶,顺便学习 求高人指点,顶起来。 很久以前写过一个。
现在都已经记不起来了。
代码献上
#include <array.au3>
#include <date.au3>
Global $bLeapMon
#cs
0x04bd8展开为二进制
0000 0100 1011 1101 1000按位整理得到
19 15 40<- 位置
^^^^
| | | |
0000 010010111101 1000
P0 P1 P2
P0表示当年闰月是闰大月还是闰小月
P1按位表示当年每月的大小情况(从高到低)
P2表示当年闰的是哪个月份
#ce
Local $tinfo= _
[0x04bd8,0x04ae0,0x0a570,0x054d5,0x0d260,0x0d950,0x16554,0x056a0,0x09ad0,0x055d2, _
0x04ae0,0x0a5b6,0x0a4d0,0x0d250,0x1d255,0x0b540,0x0d6a0,0x0ada2,0x095b0,0x14977, _
0x04970,0x0a4b0,0x0b4b5,0x06a50,0x06d40,0x1ab54,0x02b60,0x09570,0x052f2,0x04970, _
0x06566,0x0d4a0,0x0ea50,0x06e95,0x05ad0,0x02b60,0x186e3,0x092e0,0x1c8d7,0x0c950, _
0x0d4a0,0x1d8a6,0x0b550,0x056a0,0x1a5b4,0x025d0,0x092d0,0x0d2b2,0x0a950,0x0b557, _
0x06ca0,0x0b550,0x15355,0x04da0,0x0a5b0,0x14573,0x052b0,0x0a9a8,0x0e950,0x06aa0, _
0x0aea6,0x0ab50,0x04b60,0x0aae4,0x0a570,0x05260,0x0f263,0x0d950,0x05b57,0x056a0, _
0x096d0,0x04dd5,0x04ad0,0x0a4d0,0x0d4d4,0x0d250,0x0d558,0x0b540,0x0b6a0,0x195a6, _
0x095b0,0x049b0,0x0a974,0x0a4b0,0x0b27a,0x06a50,0x06d40,0x0af46,0x0ab60,0x09570, _
0x04af5,0x04970,0x064b0,0x074a3,0x0ea50,0x06b58,0x055c0,0x0ab60,0x096d5,0x092e0, _
0x0c960,0x0d954,0x0d4a0,0x0da50,0x07552,0x056a0,0x0abb7,0x025d0,0x092d0,0x0cab5, _
0x0a950,0x0b4a0,0x0baa4,0x0ad50,0x055d9,0x04ba0,0x0a5b0,0x15176,0x052b0,0x0a930, _
0x07954,0x06aa0,0x0ad50,0x05b52,0x04b60,0x0a6e6,0x0a4e0,0x0d260,0x0ea65,0x0d530, _
0x05aa0,0x076a3,0x096d0,0x04bd7,0x04ad0,0x0a4d0,0x1d0b6,0x0d250,0x0d520,0x0dd45, _
0x0b5a0,0x056d0,0x055b2,0x049b0,0x0a577,0x0a4b0,0x0aa50,0x1b255,0x06d20,0x0ada0, _
0x14b63]
Local $solarMonth=
Local $Gan=["甲","乙","丙","丁","戊","己","庚","辛","壬","癸"]
Local $Zhi=["子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"]
Local $Animals=["鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"]
Local $solarTerm = ["小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪","冬至"]
Local $sTermInfo =
Local $nStr1 = ['一','二','三','四','五','六','七','八','九','十']
Local $nStr2 = ['初','十','廿','卅','□']
;~ 国历节日 *表示放假日
Local $sFtv = ["0101*元旦&元旦 新年", _
"0106 &中国第13亿人口日", _
"0108 &周恩来逝世纪念日", _
"0115 &释迦如来成道日", _
"0121 &列宁逝世纪念日 国际声援南非日 弥勒佛诞辰", _
"0202 &世界湿地日", _
"0207 &二七大罢工纪念日", _
"0210 &国际气象节", _
"0214 情人节&情人节", _
"0215 &中国12亿人口日", _
"0219 &邓小平逝世纪念日", _
"0221 &国际母语日 反对殖民制度斗争日", _
"0222 &苗族芦笙节", _
"0224 &第三世界青年日", _
"0228 &世界居住条件调查日", _
"0301 &国际海豹日", _
"0303 &全国爱耳日", _
"0305 &学雷锋纪念日 中国青年志愿者服务日", _
"0308 妇女节&国际劳动妇女节", _
"0309 &保护母亲河日", _
"0311 &国际尊严尊敬日", _
"0312 植树节&孙中山逝世纪念日", _
"0314 &国际警察日 白色情人节", _
"0315 &消费者权益日", _
"0316 &手拉手情系贫困小伙伴全国统一行动日", _
"0317 &中国国医节 国际航海日爱尔兰圣帕特里克节", _
"0318 &全国科技人才活动日", _
"0321 &世界森林日 消除种族歧视国际日 世界儿歌日 世界睡眠日", _
"0322 &世界水日", _
"0323 &世界气象日", _
"0324 &世界防治结核病日", _
"0325 &全国中小学生安全教育日", _
"0329 &中国黄花岗七十二烈士殉难纪念", _
"0330 &巴勒斯坦国土日", _
"0401 愚人节&全国爱国卫生运动月(四月) 税收宣传月(四月)", _
"0402 &国际儿童图书日", _
"0407 &世界卫生日", _
"0411 &世界帕金森病日", _
"0421 &全国企业家活动日", _
"0422 &世界地球日 世界法律日", _
"0423 &世界图书和版权日", _
"0424 &亚非新闻工作者日 世界青年反对殖民主义日", _
"0425 &全国预防接种宣传日", _
"0426 &世界知识产权日", _
"0430 &世界交通安全反思日", _
"0501*劳动节&国际劳动节", _
"0503 &世界哮喘日 世界新闻自由日", _
"0504 青年节&中国五四青年节 科技传播日", _
"0505 &碘缺乏病防治日 日本男孩节", _
"0508 &世界红十字日", _
"0512 &国际护士节", _
"0515 &国际家庭日", _
"0517 &国际电信日", _
"0518 &国际博物馆日", _
"0520 &全国学生营养日 全国母乳喂养宣传日", _
"0523 &国际牛奶日", _
"0526 &世界向人体条件挑战日", _
"0530 &中国“五卅”运动纪念日", _
"0531 &世界无烟日 英国银行休假日",_
"0601 儿童节&国际儿童节", _
"0605 &世界环境保护日", _
"0614 &世界献血者日", _
"0617 &防治荒漠化和干旱日", _
"0620 &世界难民日", _
"0622 &中国儿童慈善活动日", _
"0623 &国际奥林匹克日", _
"0625 &全国土地日", _
"0626 &国际禁毒日 国际宪章日 禁止药物滥用和非法贩运国际日 支援酷刑受害者国际日", _
"0630 &世界青年联欢节", _
"0701 建党节&香港回归纪念日 中共诞辰 世界建筑日", _
"0702 &国际体育记者日", _
"0706 &朱德逝世纪念日", _
"0707 &抗日战争纪念日", _
"0711 &世界人口日 中国航海日", _
"0726 &世界语创立日", _
"0728 &第一次世界大战爆发", _
"0730 &非洲妇女日", _
"0801 建军节&中国人民解放军建军节", _
"0805 &恩格斯逝世纪念日", _
"0806 &国际电影节", _
"0808 &中国男子节(爸爸节)", _
"0812 &国际青年节", _
"0813 &国际左撇子日", _
"0815 &抗日战争胜利纪念", _
"0826 &全国律师咨询日", _
"0902 &日本签署无条件投降书日", _
"0903 &中国抗日战争胜利纪念日", _
"0905 &瑞士萨永中世纪节", _
"0906 &帕瓦罗蒂去世", _
"0908 &国际扫盲日 国际新闻工作者日", _
"0909 &毛泽东逝世纪念日", _
"0910 教师节&中国教师节 世界预防自杀日",_
"0914 &世界清洁地球日", _
"0916 &国际臭氧层保护日 中国脑健康日", _
"0918 &九·一八事变纪念日", _
"0920 &国际爱牙日", _
"0921 &世界停火日 预防世界老年性痴呆宣传日", _
"0927 &世界旅游日", _
"0928 &孔子诞辰", _
"0930 &国际翻译日", _
"1001*国庆节&世界音乐日 国际老人节", _
"1002*&国庆节假日 国际和平与民主自由斗争日", _
"1003*&国庆节假日", _
"1004 &世界动物日", _
"1005 &国际教师节", _
"1006 &中国老年节", _
"1008 &全国高血压日 世界视觉日", _
"1009 &世界邮政日 万国邮联日", _
"1010 &辛亥革命纪念日 世界精神卫生日 世界居室卫生日", _
"1013 &世界保健日 国际教师节 中国少年先锋队诞辰日 世界保健日", _
"1014 &世界标准日", _
"1015 &国际盲人节(白手杖节)", _
"1016 &世界粮食日", _
"1017 &世界消除贫困日", _
"1020 &世界骨质疏松日", _
"1022 &世界传统医药日", _
"1024 &联合国日 世界发展新闻日", _
"1028 &中国男性健康日", _
"1031 万圣节&万圣节 世界勤俭日", _
"1102 &达摩祖师圣诞", _
"1106 &柴科夫斯基逝世悼念日", _
"1107 &十月社会主义革命纪念日", _
"1108 &中国记者日", _
"1109 &全国消防安全宣传教育日", _
"1110 &世界青年节", _
"1111 光棍节&光棍节 国际科学与和平周", _
"1112 &孙中山诞辰纪念日", _
"1114 &世界糖尿病日", _
"1115 &泰国大象节", _
"1117 &国际大学生节 世界学生节 世界戒烟日", _
"1120 &世界儿童日", _
"1121 &世界问候日 世界电视日", _
"1129 &国际声援巴勒斯坦人民国际日", _
"1201 &世界艾滋病日", _
"1202 &废除一切形式奴役世界日", _
"1203 &世界残疾人日", _
"1204 &全国法制宣传日", _
"1205 &国际经济和社会发展志愿人员日 世界弱能人士日", _
"1207 &国际民航日", _
"1208 &国际儿童电视日", _
"1209 &世界足球日 一二·九运动纪念日", _
"1210 &世界人权日", _
"1211 &世界防止哮喘日", _
"1212 &西安事变纪念日", _
"1213 &南京大屠杀纪念日", _
"1214 &国际儿童广播电视节", _
"1215 &世界强化免疫日", _
"1220 &澳门回归纪念", _
"1221 &国际篮球日", _
"1224 平安夜&平安夜", _
"1225 圣诞节&圣诞节", _
"1226 &毛泽东诞辰纪念日&节礼日", _
"1229 &国际生物多样性日"]
;~ 农历节日 *表示放假日
Local $lFtv = ["0101*春节&春节 大年初一", _
"0102*初二&大年初二", _
"0115 元宵节&元宵节", _
"0505*端午节&端午节", _
"0707 七夕节&七夕情人节", _
"0715 中元节&中元节", _
"0815*中秋节&中秋节", _
"0909 重阳节&重阳节", _
"1208 腊八节&腊八节", _
"1223 小年&小年", _
"0100*除夕&除夕"]
;~ 某月的第几个星期几
Local $wFtv = ["0150 &世界麻风日", _
"0351 &全国中小学生安全教育日", _
"0453 &秘书节", _
"0512 &国世界哮喘日", _
"0520 母亲节&国际母亲节 救助贫困母亲日", _
"0530 &全国助残日", _
"0532 &国际牛奶日", _
"0626 &中国文化遗产日", _
"0630 父亲节&国际父亲节", _
"0716 &国际合作节", _
"0730 &被奴役国家周", _
"0932 &国际和平日", _
"0936 &全民国防教育日", _
"0940 &国际聋人节 世界儿童日", _
"0950 &世界海事日 世界心脏病日", _
"1011 &国际住房日 世界建筑日 世界人居日", _
"1023 &国际减轻自然灾害日(减灾日)", _
"1024 &世界视觉日", _
"1144 感恩节&感恩节", _
"1220 &国际儿童电视广播日"]
; ====================================== 返回农历 y年的总天数
Func lYearDays($y)
Dim $i=0x8000,$sum=348
Do
If BitAND($tinfo[$y-1900],$i)<>0 Then $sum+=1
$i=BitShift($i,1)
Until $i<=0x8
return ($sum + leapDays($y))
EndFunc
;====================================== 返回农历 y年闰月的天数
Func leapDays($y)
If leapMonth($y)<>0 Then
If BitAND($tinfo[$y-1900],0x10000)<>0 Then
Return 30
Else
Return 29
EndIf
Else
Return 0
EndIf
EndFunc
;====================================== 返回农历 y年闰哪个月 1-12 , 没闰返回 0
func leapMonth($y)
Return BitAND($tInfo[$y-1900] , 0xf);
EndFunc
;MsgBox(0,0,monthDays(2011,5))
;====================================== 返回农历 y年m月的总天数,是农历月的天数
Func monthDays($y,$m)
If BitAND($tinfo[$y-1900],BitShift(0x10000,$m)) Then
Return 30
Else
Return 29
EndIf
EndFunc
;====== 传回农历 y年的生肖
Func animalsYear($y)
return $Animals
EndFunc
;====== 传回农历 y年的干支
;MsgBox(0,2011,Ganzhi(2011))
Func Ganzhi($y)
Return $Gan & $Zhi
EndFunc
Func FormatLunarMon($mon) ;get lunar month information获得农历月
Local $LunaMonth = ["正", "二", "三", "四", "五", "六", "七", "八", "九", "十"]
Local $strLeapPre = ""
If $bLeapMon = 1 Then $strLeapPre = "闰"
If $mon <= 10 Then Return $strLeapPre & $LunaMonth[$mon - 1] & "月"
If $mon = 11 Then
Return $strLeapPre & "十一月"
Else
Return $strLeapPre & "腊月"
EndIf
EndFunc ;==>FormatLunarMon
Func FormatLunarDay($day) ;get lunar day information获得农历日
If $day <> 20 And $day <> 30 Then
$day -= 1
Return $nStr2 & $nStr1
Else
Return $nStr2[$day / 10] & $nStr1
EndIf
EndFunc ;==>FormatLunarDay
;==================计算春节是公历几月几日====================
Func chujie($y)
Dim $chunjie
For $n=1900 To $y-1
$chunjie+=lYearDays($n)
Next
Return _DateAdd('d',$chunjie,'1900/01/31')
EndFunc
;MsgBox(0,0,_DateAdd('s',Floor(31556925.9747 * (2010 - 1900) + $sTermInfo * 60),'1900/01/06 02:05:00'));计算立春
Func FormatHD($year, $mon, $day) ;get 节气
;Local $HD = ["小寒", "大寒", "立春", "雨水", "惊蛰", "春分", "清明", "谷雨", "立夏", "小满", "芒种", "夏至", "小暑", "大暑", "立秋", "处暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", "冬至"]
;每年的正小寒点到各节气正节气点(即十五度倍数点)的分钟数
;Local $sInfo =
$sMon = ($mon - 1) * 2
$offsec = Floor(31556925.9747 * ($year - 1900) + $sTermInfo[$sMon] * 60) ; offset seconds, 31556925974.7 地球公转周期,是毫秒
$offDate = _DateAdd('s', $offsec, '1900/01/06 02:05:00')
$sDay = Int(StringMid($offDate, 9, 2))
ConsoleWrite($offDate & @CRLF)
If $day = $sDay Then
Return "〖" & $solarTerm[$sMon] & "〗"
Else
$sMon = ($mon - 1) * 2 + 1;
$offsec = Floor(31556925.9747 * ($year - 1900) + $sTermInfo[$sMon] * 60)
$offDate = _DateAdd('s', $offsec, '1900/01/06 02:05:00')
$sDay = Int(StringMid($offDate, 9, 2))
ConsoleWrite($offDate & @CRLF)
If $day = $sDay Then
Return "〖" & $solarTerm[$sMon] & "〗"
Else
Return ""
EndIf
EndIf
EndFunc ;==>FormatHD
;//====================================== 算出农历, 传入日期, 传回农历日期
Func Lunar($y,$m,$d)
Local $i,$leap=0, $temp=0
Local $baseDate='1900/01/31'
Local $date=StringFormat('%04d/%02d/%02d',$y,$m,$d)
Local $offset=_DateDiff('d',$baseDate,$date)
$daycal=$offset+40
$moncyl=14
For $i=1900 To 2049
If $offset<=0 Then ExitLoop
$temp=lYearDays($i)
$offset-=$temp
$moncyl+=12
Next
If $offset<0 Then
$offset+=$temp
$i-=1
$moncyl-=12
EndIf
$year=$i
$yearCyl = $i-1864
$leap=leapMonth($i);闰哪个月
$isLeap=False
For $i=1 To 12
If $offset<=0 Then ExitLoop
If $leap>0 And $i=$leap+1 And $isleap=False Then
$i-=1
$isleap=True
$temp=leapDays($year)
Else
$temp = monthDays($year, $i)
EndIf
If $isleap=True And $i=$leap+1 Then $isleap=False;解除闰月
$offset-=$temp
If $isleap=False Then $moncyl+=1
Next
If $offset=0 And $leap>0 And $i=$leap+1 Then
If $isleap Then
$isleap=False
Else
$isleap=True
$i-=1
$moncyl-=1
EndIf
EndIf
If $offset<0 Then
$offset+=$temp
$i-=1
$moncyl-=1
EndIf
$month=$i
$day=$offset+1
;$iWeekday = _DateToDayOfWeekISO ($y,$m,$d)
;Return Ganzhi($year)&"年 "&FormatLunarMon($month)&FormatLunarDay($day)
If FormatLunarDay($day)='初一' Then
Return FormatLunarMon($month)&FormatLunarDay($day)
Else
Return FormatLunarDay($day)
EndIf
EndFunc
;MsgBox(0,0,Lunar(2011,1,16));输入公历日期,输出农历日期
;//==============================传回公历 y年某m月的天数
func solarDays($y,$m)
If $m==2 Then
If (Mod($y,4)=0 And Mod($y,100)<>0) Or Mod($y,400)=0 Then
Return 29
Else
Return 28
EndIf
Else
Return $solarMonth[$m-1]
EndIf
EndFunc
;MsgBox(0,0,solarDays(1965,8));计算1965年8月有多少天
Func FormatSF($mon, $day);返回公历节日
Local $bMatch = 0
For $i = 0 To UBound($sFtv) - 1
If StringLeft($sFtv[$i], 4) = StringFormat("%02d", $mon) & StringFormat("%02d", $day) Then
Return stringMid($sFtv[$i], 6)
EndIf
Next
EndFunc ;==>FormatSF 感谢高人指点。
不过这段注视还是看不太懂,希望能举个例子。
#cs
0x04bd8展开为二进制
0000 0100 1011 1101 1000按位整理得到
19 15 40<- 位置
^^^^
| | | |
0000 010010111101 1000
P0 P1 P2
P0表示当年闰月是闰大月还是闰小月
P1按位表示当年每月的大小情况(从高到低)
P2表示当年闰的是哪个月份
#ce
实在抱歉,小弟很笨,望谅解。。。。 最主要是不太会二进制按位算法什么的
如果要支持到 2100年,往后该怎么推算呢 回复 9# kxing
实际上,根本没有什么精确的所谓阴/阳历(也就是紫金/格里历)转换的公式。
精确的转换,都是依据天文观察,查大表出来的,就象我们历史书上现在都写着“公元XXX年XX月XX日”,这个数字怎么来的呢?其实完全是体力活,就是硬推。因为所谓阴历,其实是‘阴月阳年球日’,而所谓阳历(或公历),是‘阳月阳年球日’。中国农历基本上只有个定年月和置闰规则,实际确定是历朝政府机构按天文观测和计算得到的,误差程度不一。目前最近的就是清代的时宪历,之后就用公历了。
而我们现在用的俗称农历的,正式叫法是:紫金历,也就是根据紫金山天文台的观测数据,来确定跟阳历的转换,若在一定时间段范围内,还可以做点近似转换公式,时间远点,就会出现错误。对这有很深了解的人就知道,现在流行的转换公式,对以前(或将来)久远点时间查到的结果,根本都是错的,特别是农历里的时气这块,错误太多了,只是一般人无法对比出结果是错误的而已。
相对来说,格里历用近似公式,积累误差很小,而我们的紫金历,用现在所谓的近似公式,很容易积累误差至错误了,所以农历都是以观测为准来做表定农历。
现行闰月规则需要判断节气落在哪个月,而这个判断结果是跟时区相关的,这就可能造成不同时区的历法会有截然不同的闰月。
建议看:http://www.quirksmode.org/blog/archives/2009/04/making_time_saf.html 感谢楼上的耐心解答。
另外再请教下,3mile,上述函数中没有传入农历输出公历的吧? 3很的代码收了,3q 这个很早以前就有了. 原来有一个台湾人编的DOS下的程序,可以算公元前9999年到公元后10000年的农历,节气,天干地支,当时觉得牛,想不到现在还是牛。 学习一下,看看算法
页:
[1]
2