|
yovie
初级用户
积分 92
发帖 42
注册 2007-8-14 来自 重庆市巫山县
状态 离线
|
『楼 主』:
[原创]发一个查询农历日期的批处理
本来想做一个带二十四节气的。但是批处理SET /A的精确度太低了,数据也只能大了,没那么大的范围. 而如果使用查表法我手头又没有数据.所以只好先放着,等以后再搞.
不知道原先有人搞过这个类似的没有,如果有了的话斑竹就将我的删除吧.
[修正了一下BUG,重新发一下]
[感谢qw,修改了一下日期显示不对的BUG,重新发一下]
[至于月份,暂时我也不改了。好像看网上也有从正月初一开始计算的。毕竟没有节气。以后去网上找下节气的数据。]
Quote: |
- @ECHO off
- setlocal
- ::chcp 437>nul&&graftabl 936>nul|| SET err=3&&GOTO :err
- ::先以 H2B 函数还原成长度为 18 的字符串,其定义如下:
- ::前12个字节代表1-12月:1为大月,0为小月;压缩成十六进制(1-3位)
- ::第13位为闰月的情况,1为大月30天,0为小月29天;(4位)
- ::第14位为闰月的月份,如果不是闰月为0,否则给出月份(5位)
- ::最后4位为当年农历新年的公历日期,如0131代表1月31日;当作数值转十六进制(6-7位)
- ::农历常量(1899~2100,共202年)
- ::公历转农历模块
- ::原创:互联网
- ::数据来源:阿勇 2005/1/12
- ::// 农历数据定义 //
- :::::尊重他人劳动成果,请保留以上信息:::::
- ::批处理完成:Yovie ver:2.0 20080119
- SET ylData0=AB500D2,4BD0883,
- SET ylData1=4AE00DB,A5700D0,54D0581,D2600D8,D9500CC,655147D,56A00D5,9AD00CA,55D027A,4AE00D2,
- SET ylData1=%ylData1%,A5B0682,A4D00DA,D2500CE,D25157E,B5500D6,56A00CC,ADA027B,95B00D3,49717C9,49B00DC
- SET ylData2=A4B00D0,B4B0580,6A500D8,6D400CD,AB5147C,2B600D5,95700CA,52F027B,49700D2,6560682,
- SET ylData2=%ylData2%,D4A00D9,EA500CE,6A9157E,5AD00D6,2B600CC,86E137C,92E00D3,C8D1783,C9500DB,D4A00D0
- SET ylData3=D8A167F,B5500D7,56A00CD,A5B147D,25D00D5,92D00CA,D2B027A,A9500D2,B550781,6CA00D9,
- SET ylData3=%ylData3%,B5500CE,535157F,4DA00D6,A5B00CB,457037C,52B00D4,A9A0883,E9500DA,6AA00D0,AEA0680
- SET ylData4=AB500D7,4B600CD,AAE047D,A5700D5,52600CA,F260379,D9500D1,5B50782,56A00D9,96D00CE,
- SET ylData4=%ylData4%,4DD057F,4AD00D7,A4D00CB,D4D047B,D2500D3,D550883,B5400DA,B6A00CF,95A1680,95B00D8
- SET ylData5=49B00CD,A97047D,A4B00D5,B270ACA,6A500DC,6D400D1,AF40681,AB600D9,93700CE,4AF057F,
- SET ylData5=%ylData5%,49700D7,64B00CC,74A037B,EA500D2,6B50883,5AC00DB,AB600CF,96D0580,92E00D8,C9600CD
- SET ylData6=D95047C,D4A00D4,DA500C9,755027A,56A00D1,ABB0781,25D00DA,92D00CF,CAB057E,A9500D6,
- SET ylData6=%ylData6%,B4A00CB,BAA047B,B5500D2,55D0983,4BA00DB,A5B00D0,5171680,52B00D8,A9300CD,795047D
- SET ylData7=6AA00D4,AD500C9,5B5027A,4B600D2,96E0681,A4E00D9,D2600CE,EA6057E,D5300D5,5AA00CB,
- SET ylData7=%ylData7%,76A037B,96D00D3,4AB0B83,4AD00DB,A4D00D0,D0B1680,D2500D7,D5200CC,DD4057C,B5A00D4
- SET ylData8=56D00C9,55B027A,49B00D2,A570782,A4B00D9,AA500CE,B25157E,6D200D6,ADA00CA,4B6137B,
- SET ylData8=%ylData8%,93700D3,49F08C9,49700DB,64B00D0,68A1680,EA500D7,6AA00CC,A6C147C,AAE00D4,92E00CA
- SET ylData9=D2E0379,C9600D1,D550781,D4A00D9,DA400CD,5D5057E,56A00D6,A6C00CB,55D047B,52D00D3,
- SET ylData9=%ylData9%,A9B0883,A9500DB,B4A00CF,B6A067F,AD500D7,55A00CD,ABA047C,A5A00D4,52B00CA,B27037A
- SET ylData10=69300D1,7330781,6AA00D9,AD500CE,4B5157E,4B600D6,A5700CB,54E047C,D1600D2,E960882,
- SET ylData10=%ylData10%,D5200DA,DAA00CF,6AA167F,56D00D7,4AE00CD,A9D047D,A2D00D4,D1500C9,F250279,D5200D1
- SET ylMd0=初一初二初三初四初五初六初七初八初九初十十一十二十三十四十五十六十七十八十九二十廿一廿二廿三廿四廿五廿六廿七廿八廿九三十
- SET ylMn0=正二三四五六七八九十冬腊
- SET ylTianGan0=甲乙丙丁戊已庚辛壬癸
- SET ylDiZhi0=子丑寅卯辰巳午未申酉戌亥
- SET ylShu0=鼠牛虎兔龙蛇马羊猴鸡狗猪
- SET festData=正初一,正初二,正初三,正十五,五初五,七初七,八十五,九初九,腊初八,腊三十,保留
- SET fest=春节,春节,春节,元宵,端午,七夕,中秋,重阳,腊八,除夕
- ::从屏幕得到公历年月日
- ::没有错误检测
- :getdate
- CLS
- SETLOCAL Enabledelayedexpansion
- TITLE 批处理版农历日期查询
- SET gldate=<nul
- SET /p gldate=请输入公历的日期,如(20080808),为空则为今日:
- if "%gldate%"=="" SET gldate=%date:~0,4%%date:~5,2%%date:~8,2%&&SET now=%time:~0,2%
- ::计算年份
- SET glyear=%gldate:~0,4%
- SET year=%glyear%
- if %glyear% lss 1901 SET err=1&&GOTO :err
- if %glyear% gtr 2100 SET err=1&&GOTO :err
- ::得到月份
- SET glmon=%gldate:~4,2%
- if %glmon% lss 01 SET err=2&&GOTO :err
- if %glmon% gtr 12 SET err=2&&GOTO :err
- ::得到日期
- SET gltday=%gldate:~6%
- if %gltday% lss 01 SET err=2&&GOTO :err
- if %gltday% gtr 31 SET err=2&&GOTO :err
- SET glmd=%glmon%%gltday%
- GOTO :gettable
- :gettable
- ::计算是表中的第几位
- SET /a nlyear=glyear-1900
- SET /a nly=nlyear%%20
- if %nly% equ 0 SET nly=20
- set /a nllast=nly-1
- SET /a nl=nlyear/21+1
- if %nllast% == 0 (SET nllast=20&&SET /a nllasty=nl-1) else (
- SET nllasty=%nl%
- )
- ::得到该位的数据
- for /f "tokens=%nly% delims=," %%a in ("!ylData%nl%!") do SET thisData=%%a
- for /f "tokens=%nllast% delims=," %%a in ("!ylData%nllasty%!") do SET lastData=%%a
- if not defined lastData SET lastData=%thisData%
- ::取出第四位,看闰月的天数
- :start
- SET leapd=%thisData:~3,1%
- if %leapd%==1 (SET leapday=30) else SET leapday=29
- ::取出第五位,看是否闰月
- SET isleap=%thisData:~4,1%
- SET isleap=%isleap:A=10%
- SET isleap=%isleap:B=11%
- SET isleap=%isleap:C=12%
- SET /a isleap-=1
- :H2B
- ::SET hStr=0123456789ABCDEF
- SET bStr=0000000100100011010001010110011110001001101010111100110111101111
- SET hStr=0 1 2 3 4 5 6 7 8 9 A B C D E F
- SET n=0
- for %%i in (%hStr%) do (
- CALL SET x%%i=%%bStr:~!n!,4%%
- SET /a n+=4
- )
- CALL :gethead3
- GOTO :getlast2
- ::取得前三位
- :gethead3
- for /l %%i in (0,1,2) do (
- SET mon=!thisData:~%%i,1!
- CALL SET month%%i=%%x!mon!%%
- )
- SET month=%month0%%month1%%month2%
- for /l %%i in (0,1,11) do SET month%%i=!month:~%%i,1!
- GOTO :eof
- ::取得最后两位并转化为十进制
- :getlast2
- SET /a A=10,B=11,C=12,D=13,E=14,F=15
- CALL SET newy1=%%!thisData:~5,1!%%
- if "%newy1%"=="" SET newy1=!thisData:~5,1!
- CALL :h2d %newy1%
- SET /a newy1=no*16
- CALL SET newy2=%%!thisData:~6,1!%%
- if "%newy2%"=="" SET newy2=!thisData:~6,1!
- CALL :h2d %newy2%
- SET /a newy=newy1+no
- SET newy2=%newy:~0,-2%
- SET newy1=%newy:~-2%
- ::计算公历天数之差,关键部分了.
- :newalgr
- if "%glmon%" lss "1" SET glmon=%glmon:~-1%
- SET glmd=%glmon%%gltday%
- if "%gltday%" lss "1" SET gltday=%gltday:~-1%
- if "%newy1%" lss "1" SET newy1=%newy1:~-1%
- if %glmon% equ %newy2% (
- if %gltday% lss %newy1% (
- SET before=1
- SET mc=11,-1,0
- ) else (
- SET mc=0,1,11
- )
- SET /a days=gltday-newy1
- if !days! lss 0 (
- SET thisData=%lastData%
- CALL :gethead3
- )
- SET days=!days:-=!
- GOTO :out
- )
- SET mon=1,-2,1,0,1,0,1,1,0,1,0,1
- set /a leap="^!(glyear%%4) & ^!(^!(glyear%%100)) | ^!(glyear%%400)"
- rem if %glmon% lss 3 if %newy2% lss 3 SET leap=0
- if %glmon% lss %newy2% (
- SET mc=11,-1,0
- SET max=%newy2%
- SET min=%glmon%
- SET before=1) else (
- SET max=%glmon%
- SET min=%newy2%
- SET mc=0,1,11
- )
- SET /a max-=1
- SET /a xiuzheng=0,y=0
- for %%i in (%mon%) do (
- SET /a y+=1
- if !y! gtr %max% GOTO :days
- if !y! geq %min% (
- SET xiu=%%i
- SET /a xiuzheng+=xiu
- if %%i==-2 SET /a xiuzheng+=leap
- ))
- :days
- SET /a days=glmd-newy
- if !days! lss 0 (
- SET thisData=%lastData%
- CALL :gethead3
- )
- SET days=%days:-=%
- SET /a days-=70
- SET /a days=days/100*30+xiuzheng+days%%100
- :out
- SET yltian=0
- SET glmon= <nul
- for /l %%i in (%mc%) do (
- SET m=%%i
- SET n=!month%%i!
- SET /a yltian+=29+n
- if !yltian! gtr %days% GOTO :next
- if %%i == %isleap% (
- SET /a yltian+=leapday
- if !yltian! gtr %days% SET glmon=闰&&GOTO :next
- )
- )
- SET err=2&&GOTO :err
- ::计算干支
- :next
- if %glmd% lss %newy% SET /a glyear-=1
- SET /a tiangan=(glyear-4)%%10
- SET /a dizhi=(glyear-4)%%12
- SET ganzhi=!ylTianGan0:~%tiangan%,1!!ylDiZhi0:~%dizhi%,1!
- ::计算生肖
- ::SET /a shu=(glyear-4)%%12
- SET shuxiang=!ylShu0:~%dizhi%,1!
- :getmon
- ::计算月份
- CALL SET glmon=!glmon!%%ylMn0:~!m!,1%%
- SET /a yue=((tiangan%%5+1)*2%%10+m)%%10
- SET /a fen=(2+m)%%12
- SET yuefen=!ylTianGan0:~%yue%,1!!ylDiZhi0:~%fen%,1!
- ::计算日子
- CALL SET x=%%month!m!%%
- if "%glmon:~0,1%"=="闰" SET x=%leapd%&&SET run=1
- SET /a gldat=(29+x-(yltian-days))*2
- if defined before SET /a gldat=-gldat
- if %x%==0 SET ylMd0=%ylMd0:~0,-2%
- CALL SET gldat=%%ylMd0:~!gldat!,2%%
- SET /a year-=1900
- SET xiuzheng=0
- SET xiuzhengzhi=1,2,0,1,1,2,2,3,4,4,5,5
- SET glyue=%glmd:~0,-2%
- for /f "tokens=%glyue% delims=," %%i in ("%xiuzhengzhi%") do SET xiuzheng=%%i
- SET /a leap="(^!(year%%4))&(^!(glyue/2))"
- SET /a ri=year*5+year/4+9+gltday+(glyue-1)%%2*30
- SET /a qi=(ri-leap+xiuzheng)%%60-1
- SET /a qigan=qi%%10
- SET /a qizhi=qi%%12
- SET riqi=!ylTianGan0:~%qigan%,1!!ylDiZhi0:~%qizhi%,1!
- ::若为今日则计算时辰
- SET shijian= <nul
- if not defined now GOTO :fest
- SET /a jian=(now+1)/2%%12
- SET /a shi=(qigan%%5*2+jian)%%10
- SET shijian=!ylTianGan0:~%shi%,1!!ylDiZhi0:~%jian%,1!时
- ::计算节日
- :fest
- SET fs= <nul
- if defined run GOTO :workout
- SET gl=%glmon:~-1%%gldat%
- SET n=0
- for %%i in (%festData%) do (
- SET /a n+=1
- if "%gl%"=="%%i" GOTO :countf
- )
- :countf
- if [%n%]==[11] (
- if "%gl%"=="腊廿九" if %x%==0 SET fs=除夕
- GOTO :workout
- )
- for /f "tokens=%n% delims=," %%i in ("%fest%") do SET fs=%%i
- ::最后结果
- :workout
- SET head=%ganzhi%(%shuxiang%)年%glmon%月%gldat%
- SET tail=%yuefen%月%riqi%日┋%shijian%
- ECHO ┏━━━━━━━━━━┳━━┳━━━━━━━━━━┓
- ECHO ┃%head%┃%fs%┃%tail%┃
- ECHO ┗━━━━━━━━━━┻━━┻━━━━━━━━━━┛
- GOTO :end
- :h2d
- SET no=%1
- for %%i in (A B C D E F) do if %1 equ %%i SET no=!%%i!
- GOTO :eof
- ::错误
- :err
- if %err%==1 ECHO 对不起,暂不支持!
- if %err%==2 ECHO 对不起,日期有误!
- if %err%==3 ECHO Sorry,your Operation System is unsupportted!
- :end
- endlocal
- SET /p a=输入[Q]退出,继续查询请按回车:
- if /i not "%a%"=="Q" GOTO :getdate
- endlocal
Yovie发表于: 2008-01-22 12:26 |
|
[ Last edited by yovie on 2008-1-22 at 12:47 PM ]
|
拾人牙慧者! |
|
2008-1-19 18:59 |
|
|
plp626
银牌会员
钻石会员
积分 2278
发帖 1020
注册 2007-11-19
状态 离线
|
『第
2 楼』:
我再转一个
Quote: | :: 月历查询工具 最初发表于CN-DOS
:: 原创:foxjl 更新:namejm, qzwqzw,foxjl
:: 计算农历日期部分思路及算法来自"趣味东"
:: 输入的日期格式为:年-月-日(-可以替换为:、/,可以混用)
:: 在日历里面,★=当天
:: 支持多种格式的日期输入:
:: ① 若只输入一个数,则认为是查询当年月份,自动截取后两位数字查询,★标在1日上;
:: ② 若输入两个数,则认为是查询年和月,★标在1日上;
:: ③ 输全的话,★标在指定日期上
:: 关于年份的转换:
:: ① 若年份上输入的数字少于三位,则作如下转换:
:: 50~99判定为19xx
:: 0~49判定为20xx
:: ② 若输入的年份数字超过两位,则截取后四位字符(不足部分在高位补0),
:: 按 ① 的规则计算该年份的日期;
:: 07-08-04 增加针对农历的生肖及干支年计算;修改错误日期循环提示的BUG.
:: 08-01-13 增加推算农历日期的功能.
@echo off
color 1f
mode con cols=40 lines=20
setlocal enabledelayedexpansion
set str=日一二三四五六七八九
set sdate=%date%
:Main
cls&echo.
:: 日期提取、格式化与校验
for /f "tokens=1,2,3 delims=-/: " %%i in ("%sdate%") do (
(set sy=%%i) && (set sm=%%j) && (set sd=%%k)
)
if not defined sd set sd=1
if not defined sm set sm=%sy%&set sy=%date:~0,4%
(set sy=0000%sy%) && (set sm=00%sm%) && (set sd=00%sd%)
(set sy=%sy:~-4%) && (set sm=%sm:~-2%) && (set sd=%sd:~-2%)
set /a y=1%sy%-10000, m=1%sm%-100, d=1%sd%-100 2>nul
if errorlevel 9167 goto Error
if %y% lss 100 (
if %y% lss 50 (set /a y+=2000) else (set /a y+=1900)
set sy=!y!
)
if %m% lss 13 if %d% lss 32 goto Calc
:Error
echo.错误的日期.
pause>nul
cd.
set sdate=%date%
goto Main
:Calc
::计算农历部分
set/a Q=(y-1901)/4
set/a R=y-1901-4*Q
set n=0
for %%i in (0,31,59,90,120,151,181,212,243,273,304,334) do (
set /a n+=1
if %m% equ !n! set z=%%i)
set /a leap="^!(y%%4) & ^!(^!(y%%100)) | ^!(y%%400)"
if %m% gtr 2 (if %leap% equ 0 (set /a z-=1) else (set /a z+=leap))
set/a n=(140*Q+106*(R+1)+z*10+d*10)/295,H=(140*Q+106*(R+1)+z*10+d*10-295*n)/10
if %h% equ 0 set h=29
if %h% leq 10 (if %h% equ 10 (set h=初十) else (set h=初%h%)) else (set h=%h:~0,1%十%h:~-1%号)
for /l %%i in (1,1,9) do (call set h=%%h:%%i=!str:~%%i,1!%%)
set h=%h:0=%
:: 计算生肖及干支年
set sx=猴鸡狗猪鼠牛虎兔龙蛇马羊
set tg=庚辛壬癸甲乙丙丁戊己
set dz=申酉戌亥子丑寅卯辰巳午未
set /a sxnum=%sy% %% 12
set /a tgnum=%sy:~-1%
title 农历!tg:~%tgnum%,1!!dz:~%sxnum%,1!年 生肖:!sx:~%sxnum%,1! 农历:%h%
:: 计算每个月的天数
set days=31
for %%i in (4 6 9 11) do if %m% equ %%i set days=30
:: 计算2月份的偏差
set /a leap="^!(y%%4) & ^!(^!(y%%100)) | ^!(y%%400)"
if %m% equ 2 set /a days=28+%leap%
if %m% leq 2 (set /a y-=1& set /a m+=12)
:: 计算指定日期的星期数
set /a w=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400+1)%%7
echo. %sy%年%sm%月 日期:%sy%-%sm%-%sd%,星期!str:~%w%,1!
echo.
:: 生成月历
set /a wb=(w+35-d) %% 7, we=wb+days+1, day=1
echo. 日 一 二 三 四 五 六
echo. ━━━━━━━━━━━━━━━━━━━
set /p= <nul
for /l %%i in (0,1,37) do (
set "temp= "
if %%i GTR %wb% if %%i LSS %we% (
set temp= !day!
set temp=!temp:~-2!
if !d! EQU !day! set temp=★
set /a day+=1
)
set /p= !temp!<nul
set /a "wm=(%%i+1)%%7"
if !wm! equ 0 echo.&echo.&set /p= <nul
)
echo.
echo ━━━━━━━━━━━━━━━━━━━
echo. 输入日期可查询当日星期并显示当月月历
echo.
set sdate=
set /p sdate= 格式如:2007-02-03,[回车]退出:
if defined sdate goto Main
以下是各计算部分算法:
复制内容到剪贴板代码:
计算星期:
基姆拉尔森计算公式
W= (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400) mod 7
在公式中d表示日期中的日数+1,m表示月份数,y表示年数。
注意:在公式中有个与其他公式不同的地方:
把一月和二月看成是上一年的十三月和十四月,
例:如果是2004-1-10则换算成:2003-13-10来代入公式计算。
复制内容到剪贴板代码:
生肖及干支年计算方法是:
出生公元年数÷12,然后根据除得的商的余数,对照生肖排列就马上可以知道。
生肖排列是:猴(0)、鸡(1)、狗(2)、猪(3)、鼠(4)、牛(5)、虎(6)、兔(7)、龙(8)、蛇(9)、马(10)、羊(11)。
天干地支算法:
首先要能记住十大天干和十二地支,
十天干:甲、乙、丙、丁、戊、己、庚、辛、壬、癸;
十二地支:子、丑、寅、卯、辰、巳、午、未、申、酉、戌、亥;
天干地支纪年法首先是天干在前,地支在后,比如今年2005就为-乙酉年,先来算算天干,有个公式:
4、 5、 6、 7、 8、 9、 0、 1、 2、 3 对应的十天干就是
甲、乙、丙、丁、戊、己、庚、辛、壬、癸,
数字为年代的最后的一位数字,比如今年是2005,最后一位是5,对应的天干就是乙;
地支的算法:用年代数除以12,后面的余数就代表某个地支,余数分别为:
4、 5、 6、 7、 8、 9、 10、 11、 0、 1、 2、 3,
代表地支为:子、丑、寅、卯、辰、巳、午、 未、 申、酉、戌、亥,
比如2005年为例:年代末尾数为5,对应的天干为乙,2005除以12,余数为1,对应的地支为酉,所以2005年为乙酉年。 |
|
来自批处理之家
[ Last edited by plp626 on 2008-1-19 at 08:34 PM ]
|
|
2008-1-19 20:32 |
|
|
plp626
银牌会员
钻石会员
积分 2278
发帖 1020
注册 2007-11-19
状态 离线
|
『第
3 楼』:
比较一下,研究一下,学习一下,千万别删!!!
|
|
2008-1-19 20:43 |
|
|
yovie
初级用户
积分 92
发帖 42
注册 2007-8-14 来自 重庆市巫山县
状态 离线
|
『第
4 楼』:
呵呵,我试了一下。下面发的那个计算出来的有误差哦。
比如:1984-01-19
其实应该是癸亥(猪)年腊月十七,但这个显示为甲子(鼠)年 十六号
年份和日期都错了。连月份都没有~~~
估计是计算日期时使用的算法有误差.
[ Last edited by yovie on 2008-1-21 at 11:00 AM ]
|
拾人牙慧者! |
|
2008-1-21 10:49 |
|
|
qzwqzw
银牌会员
天的白色影子
积分 2342
发帖 635
注册 2004-3-6
状态 离线
|
『第
5 楼』:
难得看到有这许多人
愿意做这吃力不讨好的事情
首先对二位的精神表示钦佩
从作者的算法来看
余数既然出现小数
那么误差就在所难免
另外你的算法也有问题
从你1月21PM5:33的版本测试
19800101的转换结果是农历冬月十五
但实际上十一月十四
另外关于天干地支纪年的起始日
你与二楼的代码都有问题
天干地支纪年是二十四节气的立春的起始日
而不是农历或公历的起始日
二十四节气的数表并不难找
仔细查一查应该可以找到
另外,最近也打算再更新一下那个月历程序
如果有兴趣一起做如何?
Quote: | 农历日期部分的算法是:
阴历日期是以月亮的圆缺为计月单位,其以逢朔为初一,以月望为十五(大月为十六日),以月晦为二十 九日(大月为三十日)。然而目前记时通常用阳历日期表达,如欲将阳历日期换算成阴历日期可以用以下两种方法:其一是查《新编万年历》,如查1984年6月8日是阴历几日?翻开万年历6月10日是阴历十一,则逆推6月8日是阴历初九。其二可以利用公式推算阴历日期:
设:公元年数-1977(或1901)=4Q+R
则:阴历日期=14Q+10.6(R+1)+年内日期序数-29.5n
(注:式中Q、R、n均为自然数,R<4)
例:1994年5月7日的阴历日期为:
1994-1977=17=4×4+1
故:Q=4,R=1 则:5月7日的阴历日期为:
14×4+10.6(1+1)+(31+28+31+30+7)-29.5n
=204.2- 29.5n
然后用29.5去除204.2得商数6......27.2,6即是n值,余数27即是阴历二十七日。 |
|
|
|
2008-1-21 18:24 |
|
|
qzwqzw
银牌会员
天的白色影子
积分 2342
发帖 635
注册 2004-3-6
状态 离线
|
『第
6 楼』:
[ Last edited by yovie on 2008-1-22 at 12:47 PM ]
的算法仍然有问题
比如1981-01-01
应该还是Days的计算问题
|
|
2008-1-22 23:29 |
|
|
knoppix7
银牌会员
积分 1287
发帖 634
注册 2007-5-2 来自 cmd.exe
状态 离线
|
『第
7 楼』:
习惯用NC下网页。然后分析得出农历日期.
|
|
2008-1-23 12:20 |
|
|
yovie
初级用户
积分 92
发帖 42
注册 2007-8-14 来自 重庆市巫山县
状态 离线
|
『第
8 楼』:
多谢6楼.不是计算days出了问题.而是前面取值取错了。
[干脆等把计算节气的弄好了一起重发吧]
[ Last edited by yovie on 2008-1-23 at 02:11 PM ]
|
拾人牙慧者! |
|
2008-1-23 13:42 |
|
|
yovie
初级用户
积分 92
发帖 42
注册 2007-8-14 来自 重庆市巫山县
状态 离线
|
『第
9 楼』:
修正了上面的错误,并加上了24节气.重新发一下,不过可能又有了其它的BUG
Quote: |
- @ECHO off
- setlocal
- chcp 437>nul&&graftabl 936>nul 2>nul|| SET err=3&&GOTO :err
- ::先以 H2B 函数还原成长度为 18 的字符串,其定义如下:
- ::前12个字节代表1-12月:1为大月,0为小月;压缩成十六进制(1-3位)
- ::第13位为闰月的情况,1为大月30天,0为小月29天;(4位)
- ::第14位为闰月的月份,如果不是闰月为0,否则给出月份(5位)
- ::最后4位为当年农历新年的公历日期,如0131代表1月31日;当作数值转十六进制(6-7位)
- ::农历常量(1899~2100,共202年)
- ::公历转农历模块
- ::
- ::数据来源:阿勇 2005/1/12
- ::// 农历数据定义 //
- :::::尊重他人劳动成果,请保留以上信息:::::
- ::批处理完成:Yovie ver:3.3 20080119
- SET ylData0=AB500D2,4BD0883,
- SET ylData1=4AE00DB,A5700D0,54D0581,D2600D8,D9500CC,655147D,56A00D5,9AD00CA,55D027A,4AE00D2,
- SET ylData1=%ylData1%,A5B0682,A4D00DA,D2500CE,D25157E,B5500D6,56A00CC,ADA027B,95B00D3,49717C9,49B00DC
- SET ylData2=A4B00D0,B4B0580,6A500D8,6D400CD,AB5147C,2B600D5,95700CA,52F027B,49700D2,6560682,
- SET ylData2=%ylData2%,D4A00D9,EA500CE,6A9157E,5AD00D6,2B600CC,86E137C,92E00D3,C8D1783,C9500DB,D4A00D0
- SET ylData3=D8A167F,B5500D7,56A00CD,A5B147D,25D00D5,92D00CA,D2B027A,A9500D2,B550781,6CA00D9,
- SET ylData3=%ylData3%,B5500CE,535157F,4DA00D6,A5B00CB,457037C,52B00D4,A9A0883,E9500DA,6AA00D0,AEA0680
- SET ylData4=AB500D7,4B600CD,AAE047D,A5700D5,52600CA,F260379,D9500D1,5B50782,56A00D9,96D00CE,
- SET ylData4=%ylData4%,4DD057F,4AD00D7,A4D00CB,D4D047B,D2500D3,D550883,B5400DA,B6A00CF,95A1680,95B00D8
- SET ylData5=49B00CD,A97047D,A4B00D5,B270ACA,6A500DC,6D400D1,AF40681,AB600D9,93700CE,4AF057F,
- SET ylData5=%ylData5%,49700D7,64B00CC,74A037B,EA500D2,6B50883,5AC00DB,AB600CF,96D0580,92E00D8,C9600CD
- SET ylData6=D95047C,D4A00D4,DA500C9,755027A,56A00D1,ABB0781,25D00DA,92D00CF,CAB057E,A9500D6,
- SET ylData6=%ylData6%,B4A00CB,BAA047B,B5500D2,55D0983,4BA00DB,A5B00D0,5171680,52B00D8,A9300CD,795047D
- SET ylData7=6AA00D4,AD500C9,5B5027A,4B600D2,96E0681,A4E00D9,D2600CE,EA6057E,D5300D5,5AA00CB,
- SET ylData7=%ylData7%,76A037B,96D00D3,4AB0B83,4AD00DB,A4D00D0,D0B1680,D2500D7,D5200CC,DD4057C,B5A00D4
- SET ylData8=56D00C9,55B027A,49B00D2,A570782,A4B00D9,AA500CE,B25157E,6D200D6,ADA00CA,4B6137B,
- SET ylData8=%ylData8%,93700D3,49F08C9,49700DB,64B00D0,68A1680,EA500D7,6AA00CC,A6C147C,AAE00D4,92E00CA
- SET ylData9=D2E0379,C9600D1,D550781,D4A00D9,DA400CD,5D5057E,56A00D6,A6C00CB,55D047B,52D00D3,
- SET ylData9=%ylData9%,A9B0883,A9500DB,B4A00CF,B6A067F,AD500D7,55A00CD,ABA047C,A5A00D4,52B00CA,B27037A
- SET ylData10=69300D1,7330781,6AA00D9,AD500CE,4B5157E,4B600D6,A5700CB,54E047C,D1600D2,E960882,
- SET ylData10=%ylData10%,D5200DA,DAA00CF,6AA167F,56D00D7,4AE00CD,A9D047D,A2D00D4,D1500C9,F250279,D5200D1
- SET ylMd0=初一初二初三初四初五初六初七初八初九初十十一十二十三十四十五十六十七十八十九二十廿一廿二廿三廿四廿五廿六廿七廿八廿九三十
- SET ylMn0=正二三四五六七八九十冬腊
- SET ylTianGan0=甲乙丙丁戊已庚辛壬癸
- SET ylDiZhi0=子丑寅卯辰巳午未申酉戌亥
- SET ylShu0=鼠牛虎兔龙蛇马羊猴鸡狗猪
- SET festData=正初一,正初二,正初三,正十五,五初五,七初七,八十五,九初九,腊初八,腊三十,保留
- SET fest=春节,春节,春节,元宵,端午,七夕,中秋,重阳,腊八,除夕
- set solarTerm=小寒大寒立春雨水惊蛰春分清明谷雨立夏小满芒种夏至小暑大暑立秋处暑白露秋分寒露霜降立冬小雪大雪冬至
- set sTermInfo=0,21208,42467,63836,85337,107014,128867,150921,173149,195551,218072,240693,263343,285989,308563,331033,353350,375494,397447,419210,440795,462224,483532,504758,525949
- SET jieqinian=525948
- SET jieqinianyu=766245
- SET xiaohanstart=1900-01-06
- SET timestart=0205
- SET fs= <nul
- ::从屏幕得到公历年月日
- ::没有错误检测
- :getdate
- SETLOCAL Enabledelayedexpansion
- TITLE 批处理版农历日期查询
- cls
- SET gldate=<nul
- SET /p gldate=请输入公历的日期,如(20080808),为空则为今日:
- if "%gldate%"=="" SET gldate=%date:~0,4%%date:~5,2%%date:~8,2%&&SET now=%time:~0,2%
- if /i "%gldate%"=="Q" GOTO :eof
- ::计算年份
- SET glyear=%gldate:~0,4%
- SET year=%glyear%
- if %glyear% lss 1901 SET err=1&&GOTO :err
- if %glyear% gtr 2100 SET err=1&&GOTO :err
- ::得到月份
- SET glmon=%gldate:~4,2%
- if %glmon% lss 01 SET err=2&&GOTO :err
- if %glmon% gtr 12 SET err=2&&GOTO :err
- ::得到日期
- SET gltday=%gldate:~6%
- if %gltday% lss 01 SET err=2&&GOTO :err
- if %gltday% gtr 31 SET err=2&&GOTO :err
- SET glmd=%glmon%%gltday%
- GOTO :gettable
- :gettable
- ::计算是表中的第几位
- SET /a nlyear=glyear-1900
- SET /a nly=nlyear%%20
- if %nly% equ 0 SET nly=20
- set /a nllast=nly-1
- SET /a nl=(nlyear-1)/20+1
- if %nllast% == 0 (SET nllast=20&&SET /a nllasty=nl-1) else (
- SET nllasty=%nl%
- )
- ::得到该位的数据
- for /f "tokens=%nly% delims=," %%a in ("!ylData%nl%!") do SET thisData=%%a
- for /f "tokens=%nllast% delims=," %%a in ("!ylData%nllasty%!") do SET lastData=%%a
- if not defined lastData SET lastData=4BD0883
- ::取出第四位,看闰月的天数
- :start
- SET leapd=%thisData:~3,1%
- if %leapd%==1 (SET leapday=30) else SET leapday=29
- ::取出第五位,看是否闰月
- SET isleap=%thisData:~4,1%
- SET isleap=%isleap:A=10%
- SET isleap=%isleap:B=11%
- SET isleap=%isleap:C=12%
- SET /a isleap-=1
- :H2B
- ::SET hStr=0123456789ABCDEF
- SET bStr=0000000100100011010001010110011110001001101010111100110111101111
- SET hStr=0 1 2 3 4 5 6 7 8 9 A B C D E F
- SET n=0
- for %%i in (%hStr%) do (
- CALL SET x%%i=%%bStr:~!n!,4%%
- SET /a n+=4
- )
- CALL :gethead3
- GOTO :getlast2
- ::取得前三位
- :gethead3
- for /l %%i in (0,1,2) do (
- SET mon=!thisData:~%%i,1!
- CALL SET month%%i=%%x!mon!%%
- )
- SET month=%month0%%month1%%month2%
- for /l %%i in (0,1,11) do SET month%%i=!month:~%%i,1!
- GOTO :eof
- ::取得最后两位并转化为十进制
- :getlast2
- SET /a A=10,B=11,C=12,D=13,E=14,F=15
- CALL SET newy1=%%!thisData:~5,1!%%
- if "%newy1%"=="" SET newy1=!thisData:~5,1!
- CALL :h2d %newy1%
- SET /a newy1=no*16
- CALL SET newy2=%%!thisData:~6,1!%%
- if "%newy2%"=="" SET newy2=!thisData:~6,1!
- CALL :h2d %newy2%
- SET /a newy=newy1+no
- SET newy=0%newy%
- SET newy2=%newy:~-4,2%
- SET newy1=%newy:~-2%
- :days
- ::计算公历天数之差,由于自己的算法不够通用::
- ::因此采用他人算法::
- CALL :Date2Day %glyear%-%glmon%-%gltday% sdays
- CALL :Date2Day %glyear%-%newy2%-%newy1% tdays
- SET /a days=sdays-tdays
- if !days! lss 0 (
- SET before=1
- SET mc=11,-1,0
- SET days=!days:-=!
- SET thisData=%lastData%
- CALL :gethead3
- ) else (
- SET mc=0,1,11
- )
- :out
- SET yltian=0
- SET glmon= <nul
- for /l %%i in (%mc%) do (
- SET m=%%i
- SET n=!month%%i!
- SET /a yltian+=29+n
- if !yltian! gtr %days% GOTO :next
- if %%i == %isleap% (
- SET /a yltian+=leapday
- if !yltian! gtr %days% SET glmon=闰&&GOTO :next
- )
- )
- SET err=2&&GOTO :err
- ::计算干支
- :next
- CALL :jieqi jieqi
- if !jq! gtr 3 (GOTO xxx)
- if not defined lichun (SET /a glyear-=1) else (
- if defined before SET /a m+=1,m%%=12
- )
- :xxx
- SET /a tiangan=(glyear-4)%%10
- SET /a dizhi=(glyear-4)%%12
- SET ganzhi=!ylTianGan0:~%tiangan%,1!!ylDiZhi0:~%dizhi%,1!
- ::计算生肖
- SET shuxiang=!ylShu0:~%dizhi%,1!
- :getmon
- ::计算月份
- CALL SET glmon=!glmon!%%ylMn0:~!m!,1%%
- SET /a yue=((tiangan%%5+1)*2%%10+m)%%10
- SET /a fen=(2+m)%%12
- SET yuefen=!ylTianGan0:~%yue%,1!!ylDiZhi0:~%fen%,1!
- ::计算日子
- CALL SET x=%%month!m!%%
- if "%glmon:~0,1%"=="闰" SET x=%leapd%&&SET run=1
- SET /a gldat=(29+x-(yltian-days))*2
- if defined before SET /a gldat=-gldat
- if %x%==0 SET ylMd0=%ylMd0:~0,-2%
- CALL SET gldat=%%ylMd0:~!gldat!,2%%
- SET /a year-=1900
- SET xiuzheng=0
- SET xiuzhengzhi=1,2,0,1,1,2,2,3,4,4,5,5
- SET glyue=%glmd:~0,-2%
- if "%glyue%" lss "1" SET glyue=%glyue:~-1%
- for /f "tokens=%glyue% delims=," %%i in ("%xiuzhengzhi%") do SET xiuzheng=%%i
- SET /a leap="(^!(year%%4))&(^!(glyue/3))"
- SET /a ri=year*5+year/4+9+gltday+(glyue-1)%%2*30
- SET /a qi=(ri-leap+xiuzheng)%%60-1
- SET /a qigan=qi%%10
- SET /a qizhi=qi%%12
- SET riqi=!ylTianGan0:~%qigan%,1!!ylDiZhi0:~%qizhi%,1!
- ::若为今日则计算时辰
- SET shijian= <nul
- if not defined now GOTO :fest
- SET /a jian=(now+1)/2%%12
- SET /a shi=(qigan%%5*2+jian)%%10
- SET shijian=!ylTianGan0:~%shi%,1!!ylDiZhi0:~%jian%,1!时
- ::计算节日
- :fest
- if defined jieqi (
- SET /a jieqi*=2
- CALL SET fs=%%solarTerm:~!jieqi!,2%%
- )
- if not "%fs%"==" " SET shijian=%fs% <nul&&SET "fs= "
- if defined run GOTO :workout
- SET gl=%glmon:~-1%%gldat%
- SET n=0
- for %%i in (%festData%) do (
- SET /a n+=1
- if "%gl%"=="%%i" GOTO :countf
- )
- :countf
- if [%n%]==[11] (
- if "%gl%"=="腊廿九" if %x%==0 SET fs=除夕
- GOTO :workout
- )
- for /f "tokens=%n% delims=," %%i in ("%fest%") do SET fs=%%i
- ::最后结果
- :workout
- SET head=%ganzhi%(%shuxiang%)年%glmon%月%gldat%
- SET tail=%yuefen%月%riqi%日┋%shijian%
- ECHO ┏━━━━━━━━━━┳━━┳━━━━━━━━━━┓
- ECHO ┃%head%┃%fs%┃%tail%┃
- ECHO ┗━━━━━━━━━━┻━━┻━━━━━━━━━━┛
- GOTO :end
- :h2d
- SET no=%1
- for %%i in (A B C D E F) do if %1 equ %%i SET no=!%%i!
- GOTO :eof
- ::错误
- :err
- if %err%==1 ECHO 对不起,暂不支持!
- if %err%==2 ECHO 对不起,日期有误!
- if %err%==3 ECHO Sorry,your Operation System is unsupportted!&ENDLOCAL&GOTO :EXIT
- :end
- ENDLOCAL
- PAUSE>nul
- GOTO :getdate
- :EXIT
- ping -n 3 127.1>nul
- ENDLOCAL
- GOTO :eof
- :jieqi
- ::24节气采用近似算法,可能会有误差
- ::但是2008年的节气已经验证没有错误.
- CALL :Date2Day %xiaohanstart% sdays
- SET thisyear=%gldate:~0,4%-%gldate:~4,2%-%gldate:~6,2%
- CALL :Date2Day %thisyear% tdays
- SET /a tdays-=sdays
- SET /a min=tdays*1440+125
- SET /a min+=min/63871
- SET /a Nnian=min/jieqinian
- SET /a minjie=Nnian*jieqinianyu/1000000+Nnian*jieqinian
- SET /a minjie=min-minjie
- if !minjie! geq 41850 (SET lichun=1)
- SET jq=0
- SET temp=0
- for %%i in (%sTermInfo%) do (
- SET tmp=%%i
- if !minjie! leq %%i if !minjie! geq !temp! GOTO :jieqiyes
- SET temp=%%i
- SET /a jq+=1
- )
- :jieqiyes
- SET /a jq%%=24
- SET /a jie=minjie-temp
- if %jie% lss 0 (
- SET jie=%jie:-=%
- if !jie! leq 125 (
- SET /a jq-=1&&SET %1=!jq!&&GOTO :eof
- )
- ) else (
- if !jie! leq 1315 (
- SET /a jq-=1&&SET %1=!jq!&&GOTO :eof
- )
- )
- SET /a jie=minjie-tmp
- if %jie% lss 0 (
- SET jie=%jie:-=%
- if !jie! leq 125 (
- SET %1=!jq!&&GOTO :eof
- )
- ) else (
- if !jie! leq 1315 (
- SET %1=!jq!&&GOTO :eof
- )
- )
- GOTO :eof
- :Date2Day
- ::算法:Ritchie Lawrence, updated 2002-08-13. Version 1.1.
- setlocal ENABLEEXTENSIONS
- for /f "tokens=1-3 delims=/-, " %%a in ('echo/%1') do (
- set yy=%%a & set mm=%%b & set dd=%%c
- )
- set /a dd=100%dd%%%100,mm=100%mm%%%100
- set /a z=14-mm,z/=12,y=yy+4800-z,m=mm+12*z-3,j=153*m+2
- set /a j=j/5+dd+y*365+y/4-y/100+y/400-2472633
- endlocal&set %2=%j%&goto :EOF
- :Day2Date
- ::暂时不使用
- setlocal ENABLEEXTENSIONS
- set /a i=%1,a=i+2472632,b=4*a+3,b/=146097,c=-b*146097,c/=4,c+=a
- set /a d=4*c+3,d/=1461,e=-1461*d,e/=4,e+=c,m=5*e+2,m/=153,dd=153*m+2,dd/=5
- set /a dd=-dd+e+1,mm=-m/10,mm*=12,mm+=m+3,yy=b*100+d-4800+m/10
- (if %mm% LSS 10 set mm=0%mm%)&(if %dd% LSS 10 set dd=0%dd%)
- endlocal&set %2=%yy%-%mm%-%dd%&goto :EOF
Yovie发表于: 2008-01-26 13:06 |
|
|
拾人牙慧者! |
|
2008-1-26 14:15 |
|
|
wxcute
中级用户
积分 458
发帖 211
注册 2006-7-26
状态 离线
|
『第
10 楼』:
生肖有错。
比如84年元旦生的,其实是属猪的,显示是鼠。
|
|
2008-2-4 04:40 |
|
|
plp626
银牌会员
钻石会员
积分 2278
发帖 1020
注册 2007-11-19
状态 离线
|
『第
11 楼』:
凭楼主的这个精神都该加分!!!
|
|
2008-2-4 05:55 |
|
|
qq43142691
中级用户
积分 327
发帖 152
注册 2007-5-4
状态 离线
|
『第
12 楼』:
。。。崇拜死你了哇。。。那么多。。看得眼睛绿了哇。。
|
|
2008-2-4 06:58 |
|
|
xmi
初级用户
积分 125
发帖 56
注册 2008-2-20
状态 离线
|
『第
13 楼』:
用了九楼那个, 它只出了错误
"Sorry,your Operation System is unsupportted"
|
|
2008-2-24 15:30 |
|
|
523066680
银牌会员
SuperCleaner
积分 2362
发帖 1133
注册 2008-2-2
状态 离线
|
|
2008-2-24 15:34 |
|
|
knoppix7
银牌会员
积分 1287
发帖 634
注册 2007-5-2 来自 cmd.exe
状态 离线
|
|
2008-2-24 17:30 |
|
|