Board logo

标题: [日期时间] 批处理阳历转农历函数 [打印本页]

作者: caruko    时间: 2011-5-24 23:14     标题: 批处理阳历转农历函数

我也来发一个农历转换函数,查表法做的,支持1921-2021年。
应该无误差,除非日期如 2月31这种。
  1. @ECHO OFF&SETLOCAL ENABLEDELAYEDEXPANSION
  2. ::info 包含了1921-2021年的农历数据,每个数字的前11-12位包含大小月情况,某位为0表示某月29天,为1表示30天。11位,即<4095,表示无闰月,12位以上表示有闰月。
  3. ::然后根据 阳历日期到1921-2-8的天数差,一个一个减去阴历天数,直到 剩余天数不足一个月时,退出循环。
  4. ::再根据 把info ">>" 16位,从16位开始记录的是闰几月。
  5. ::忘记了一个小错误,“十一”月是2个字符,改程序麻烦,改成为“⑾”,最后再替换。
  6. call :getNongLi 2009 5 24 日期
  7. set "er=!ERRORLEVEL!"
  8. echo,日历: !日期!
  9. echo,农历数字,方便查节日: !er!
  10. goto :eof
  11. :getNongLi [year] [month] [day] [var_Name]   (函数返回ERRORLEVEL=农历日期数字,值为负表示当月为闰月,0为超标或者错误日期)
  12. SETLOCAL ENABLEDELAYEDEXPANSION
  13. ::检测传入
  14. set "dt=%date:~0,10%"&set "temp=%1-%2-%3"
  15. set /a $1=%1-0,$2=%2-0,$3=%3-0
  16. 2>nul set /a 1/(%1%2%3) && (
  17.     if !$1! gtr 2021 if !$1! lss 1921 if !$2! gtr 12 if !$2! lss 1 if !$3! gtr 31 if !$3! lss 1 exit /b 0
  18.     if "%4"=="" (set var_name=nonglidays) else set "var_name=%4"
  19.     ) || (
  20.     if "%1"=="" (set var_name=nonglidays) else set "var_name=%1"
  21.     set temp=!dt!
  22. )
  23. ::初始变量
  24. set "info=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"
  25. set "weeks=日一二三四五六"
  26. set "天干表=甲乙丙丁戊己庚辛壬癸"
  27. set "地支表=子丑寅卯辰巳午未申酉戌亥"
  28. set "生肖表=鼠牛虎兔龙蛇马羊猴鸡狗猪"
  29. set "农历日期表=初一初二初三初四初五初六初七初八初九初十十一十二十三十四十五十六十七十八十九二十廿一廿二廿三廿四廿五廿六廿七廿八廿九三十"
  30. set "农历月份表=正二三四五六七八九十⑾腊"
  31. set "公历月天数=0,31,59,90,120,151,181,212,243,273,304,334"
  32. for %%i in (%info%) do set /a num+=1&set "info_!num!=%%i"
  33. ::处理日期,如果有误,请根据自己的日期格式修改。
  34. set temp=%temp:-0=-%
  35. for /f "tokens=1,2,3 delims=- " %%1 in ("%temp%") do set /a curYear=%%1,curMonth=%%2,curDay=%%3
  36. set "公历日期=!curYear!年!curMonth!月!curDay!日"
  37. ::获取公历星期 Ritchie Lawrence日期函数
  38. setlocal
  39. set /a z=14-curMonth,z/=12,y=curYear+4800-z,m=curMonth+12*z-3,dow=153*curMonth+2
  40. set /a dow=dow/5+curDay+y*365+y/4-y/100+y/400-2472630,dow%%=7
  41. endlocal&set week=%dow%
  42. for %%i in (!week!) do set 公历日期=!公历日期! 星期!weeks:~%%i,1!
  43. ::计算到初始时间1921年2月8日的天数:1921-2-8(正月初一) 最多到 2021年
  44. set temp=for /f "tokens=!curMonth! delims=," %%i in ("%公历月天数%") do set "MonthAdd=%%i"
  45. %temp%
  46. set /a TheDate= (curYear - 1921) * 365 + (curYear - 1921) / 4 + curDay + MonthAdd - 38
  47. if !curMonth! gtr 2 (
  48.     set/a temp=curYear %% 4
  49.     if !temp! equ 0 set /a TheDate+=1
  50. )
  51. ::计算农历天干、地支、月、日
  52. set /a isEnd=0,m=0
  53. for %%m in (%info%) do (
  54.     if !isEnd! equ 0 (
  55.         if %%m lss 4095 ( set k=11 )  else ( set k=12 )
  56.         set /a n=k
  57.         for /l %%n in (!n!,-1,0) do (
  58.             if !isEnd! equ 0 (
  59.                 set /a bit=%%m,n=%%n,bit=bit">>"n,bit=bit %% 2,temp=bit+29
  60.                 if !TheDate! leq !temp! set /a isEnd=1
  61.                 if !isEnd!  equ 0 set /a TheDate= TheDate - 29 - bit
  62.          ))
  63.          set /a m+=1
  64.          if !isEnd! equ 1 set /a m-=1
  65. ))
  66. set /a curYear=1921 + m,curMonth=k - n + 1,curDay=TheDate
  67. If !k! equ 12 (
  68.     set /a temp=info_!m! / 65536 + 1
  69.     if !curMonth! equ !temp! set /a curMonth= 1 - curMonth
  70.     if !curMonth! gtr !temp! set /a curMonth-=1
  71. )
  72. ::生成农历天干、地支、属相
  73. set /a tof=((curYear - 4) %% 60) %% 10,dof=((curYear - 4) %% 60) %% 12
  74. for /f "tokens=1,2" %%a in ("!tof! !dof!") do set 农历日期=农历!天干表:~%%a,1!!地支表:~%%b,1!年(!生肖表:~%%b,1!)
  75. ::生成农历月、日
  76. set /a cof=curMonth-1,tof=(curMonth-1) * -1,dof=(curDay -1) * 2,ecode=curYear*10000 + curMonth * 100 + curDay
  77. for /f "tokens=1,2,3" %%a in ("!tof! !cof! !dof!") do (
  78.     If !curMonth! lss 1 (
  79.         set 农历日期=!农历日期! 闰!农历月份表:~%%a,1!月!农历日期表:~%%c,2!
  80.         set /a ecode*=-1
  81.     ) Else (
  82.         set 农历日期=!农历日期! !农历月份表:~%%b,1!月!农历日期表:~%%c,2!
  83. ))
  84. set "农历日期=!农历日期:⑾=十一!"
  85. endlocal&set "%var_name%=%公历日期%  %农历日期%" & exit /b %ecode%
复制代码

作者: batman    时间: 2011-5-24 23:15

这东东费力不讨好啊,批不适合做这样的工作。。。
作者: plp626    时间: 2011-5-24 23:16

这个我从来明白算法,也没研究过;

如果能讲下算法,那比给代码更让我受益;
作者: plp626    时间: 2011-5-24 23:20

本帖最后由 plp626 于 2011-5-24 23:23 编辑

2# batman


算法和语言无关,,,,,!

批适合的究竟是是什么,,各人的答案不同。。。
作者: caruko    时间: 2011-5-25 00:00

算法更新了...
作者: Batcher    时间: 2011-5-25 00:46

一般是这样吧:
阳历 vs 阴历
公历 vs 农历
作者: 狱渊    时间: 2013-5-1 10:46

我看得头都晕了  不过就是代码都了点  很好用  谢谢了  这么费心




欢迎光临 批处理之家 (http://bathome.net./) Powered by Discuz! 7.2