中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 会员 | 搜索 | 上传 | 帮助 »
中国DOS联盟论坛 » DOS批处理 & 脚本技术(批处理室) » [原创]********简单万年历********
« [1] [2] »
作者:
标题: [原创]********简单万年历******** 上一主题 | 下一主题
s11ss
银牌会员





积分 2098
发帖 566
注册 2007-9-11
状态 离线
『楼 主』:  [原创]********简单万年历********


@echo off
setlocal enabledelayedexpansion
::::::::简单万年历 {s11ss 2007-9-29}::::::::
::原理:求出某月1日是星期几,由此得出其它天对应于星期几,最后分行显示各天。
echo Please input a year and a month,like 2007-9:
echo.
set/p str=            
for /f "delims=- tokens=1*" %%a in ('echo %str%') do (
        set/a year=%%a
        set/a month=%%b
        if %%b leq 2 (set/a year-=1 && set/a month+=12)
        set y=!year:~-2!
        set is0=!y:~0,1!
        if !is0! equ 0 set y=!y:~1,1!
        set c=!year:~0,-2!
        set m=!month!
        set d=1
        if %%b leq 2 (set/a year+=1 && set/a month-=12)       
)
set/a w=(!y!+!y!/4+%c%/4-2*%c%+26*(%m%+1)/10+%d%-1)
::上面这个源于蔡勒公式,是算出1号是星期几的关键。
set/a ?=!w!%%7
if !?! lss 0 set/a ?+=7
set/a r4=!year!%%4,r100=!year!%%100,r400=!year!%%400
set/a feb=28
if !r4! equ 0 (if not !r100! equ 0 set/a feb=29)
if !r400! equ 0 set/a feb=29
set/a mseq=1
for %%a in (31,!feb!,31,30,31,30,31,31,30,31,30,31) do (
        if !mseq! equ !month! (set/a day=%%a && goto :e)
        set/a mseq+=1
)
:e
set s1= 1
for /l %%a in (1,1,!?!) do set s1=     !s1!
set/a row=1
set x=!s1!
for /l %%a in (2,1,!day!) do (
        if %%a lss 10 (set dseq= %%a) else (set dseq=%%a)
        set/a ?+=1
        if !?! equ 7 (
                set/a ?=0
                set s!row!=!x!
                set/a row+=1
                set x=!dseq!
        ) else (
                        set x=!x!   !dseq!
          )
)
set s!row!=!x!
echo 日   一   二   三   四   五   六
for /l %%a in (1,1,!row!) do echo !s%%a!
echo.
echo Press Any Key To Exit...
pause>nul
goto :eof
蔡勒公式
蔡勒(Zeller)公式:是一个计算星期的公式。
随便给一个日期,就能用这个公式推算出是星期几。

蔡勒公式如下:
w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1

公式中的符号含义如下:
w:星期; w对7取模得:0-星期日,1-星期一,2-星期二,3-星期三,4-星期四,5-星期五,6-星期六
c:世纪(前两位数)
y:年(后两位数)
m:月(m大于等于3,小于等于14,即在蔡勒公式中,某年的1、2月要看作上一年的13、14月来计算,比如2003年1月1日要看作2002年的13月1日来计算)
d:日
[ ]代表取整,即只要整数部分。

下面以中华人民共和国成立100周年纪念日那天(2049年10月1日)来计算是星期几,过程如下:
w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1
=49+[49/4]+[20/4]-2×20+[26×(10+1)/10]+1-1
=49+[12.25]+5-40+[28.6]
=49+12+5-40+28
=54 (除以7余5)
即2049年10月1日(100周年国庆)是星期五。

再比如计算2006年4月4日,过程如下:
w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1
=6+[6/4]+[20/4]-2*20+[26*(4+1)/10]+4-1
=-12 (除以7余2,注意对负数的取模运算!)

不过,以上的公式都只适合于1582年(我国明朝万历十年)10月15日之后的情形。罗马教皇格里高利十三世在1582年组织了一批天文学家,根据哥白尼日心说计算出来的数据,对儒略历作了修改。将1582年10月5日到14日之间的10天宣布撤销,继10月4日之后为10月15日。
后来人们将这一新的历法称为“格里高利历”,也就是今天世界上所通用的历法,简称格里历或公历。  


   此帖被 +9 点积分       点击查看详情   
评分人:【 wudixin96 分数: +9  时间:2007-9-29 16:12


2007-9-29 16:01
查看资料  发短消息 网志   编辑帖子  回复  引用回复
knoppix7
银牌会员





积分 1287
发帖 634
注册 2007-5-2
来自 cmd.exe
状态 离线
『第 2 楼』:  

我也写过一个~~~~~~~~~~~~~


@echo off
setlocal enabledelayedexpansion
:{
://处理月数
set Y=%date:~0,4%
set M=%date:~5,2%
set D=%date:~8,2%
if %M:~0,1%==0 set M=%M:~1,1%
if %D:~0,1%==0 set D=%D:~1,1%
FOR %%i IN (4 400) DO (
        set /a T1=%y%%%%%i
        if !T1!==0 (set runnian=1) ELSE set runnian=0
)
call :checkmouth %runnian%
set T1=%Y:~0,2%
set T2=%Y:~2,2%
if %T2:~0,1%==0 set T2=%T2:~1,1%
set /a T1=%T1%%%4
set /a T1=T1/-2+5
set /a T2=((%T2%-%t2%%%4)/4+%T2%)%%7
call :yueyushu
set /a T4=(%T1%+%T2%+%T3%+1)%%7
rem T4=星期数,0=>日 1=>一 ....
set T1=&set T2=&set T3=&set Y=
:}

:{
://显示准备
call :setdateend %M%
set /a dateend=%dateend%+%T4%-1
set T1=1
for /L %%i IN (0,1,38) DO (
        if %%i GEQ %T4% IF %%i LEQ %dateend% (
                if !T1! LEQ 9 (set W%%i= !T1! ) ELSE set W%%i=!T1!
                if !T1! EQU %D% set W%%i=!T1!*
                call set T5=%%js9!T1!%%
                if NOT "!T5!"=="" (
                        if !T1! LEQ 9 (set W%%i= !T1!$) ELSE set W%%i=!T1!$
                        if !T1! EQU %D% (
                                if !T1! LEQ 9 (set W%%i= !T1!#) ELSE set W%%i=!T1!#
                        )
                )
                set /a T1=!T1!+1
                )
        if %%i LSS %T4% set "W%%i=   "
        if %%i GTR %dateend% set "W%%i= "
)
set T1=
echo 今天是:%date%
echo 日  一  二  三  四  五  六
echo %W0% %W1% %W2% %W3% %W4% %W5% %W6%
echo %W7% %W8% %W9% %W10% %W11% %W12% %W13%
echo %W14% %W15% %W16% %W17% %W18% %W19% %W20%
echo %W21% %W22% %W23% %W24% %W25% %W26% %W27%
echo %W28% %W29% %W30% %W31% %W32% %W33% %W34%
echo %W35% %W36% %W37% %W38% 
GOTO :EOF
:}

:{
://子区块部分
:setdateend
for %%i IN (1 3 5 7 8 10 12) DO (
        if %1==%%i (set dateend=31) ELSE set dateend=30
)

if %1==2 (
        If %runnian%==1 (set dateend=29) ELSE set dateend=28
)
GOTO :EOF
:yueyushu
set T3=!%m%y!
goto :EOF
:checkmouth
if %1==0 (
set 1y=1
set 2y=4
) ELSE (
set 1y=0
set 2y=3
)
set 3y=4
set 4y=0
set 5y=2
set 6y=5
set 7y=0
set 8y=3
set 9y=6
set 10y=1
set 11y=4
set 12y=8
GOTO :EOF
:}

2007-9-29 17:30
查看资料  发短消息 网志   编辑帖子  回复  引用回复
wudixin96
银牌会员





积分 1928
发帖 931
注册 2007-1-6
状态 离线
『第 3 楼』:  

高手对决啊,激出火花

2007-9-29 17:32
查看资料  发短消息 网志   编辑帖子  回复  引用回复
knoppix7
银牌会员





积分 1287
发帖 634
注册 2007-5-2
来自 cmd.exe
状态 离线
『第 4 楼』:  

可惜他的方法比我的简单多了~~

2007-9-29 17:55
查看资料  发短消息 网志   编辑帖子  回复  引用回复
s11ss
银牌会员





积分 2098
发帖 566
注册 2007-9-11
状态 离线
『第 5 楼』:  



  Quote:
Originally posted by knoppix7 at 2007-9-29 05:55 PM:
可惜他的方法比我的简单多了~~

knoppix7,你的闰年判断好像有问题啊.
你的意思是能被400整除的才是闰年?
可以用2004-2-29来测试一下.........2004显然是闰年

   此帖被 +4 点积分        点击查看详情   
评分人:【 knoppix7 分数: +4  时间:2007-9-30 16:46


2007-9-29 23:01
查看资料  发短消息 网志   编辑帖子  回复  引用回复
lipu721
新手上路





积分 4
发帖 2
注册 2007-9-29
状态 离线
『第 6 楼』:  

头晕晕的............

2007-9-29 23:50
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
lipu721
新手上路





积分 4
发帖 2
注册 2007-9-29
状态 离线
『第 7 楼』:  

看了就头晕,太多了。我晕

2007-9-29 23:50
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
knoppix7
银牌会员





积分 1287
发帖 634
注册 2007-5-2
来自 cmd.exe
状态 离线
『第 8 楼』:  

被4或400整除才是.
明白了.计算程序错了...
要把
FOR %%i IN (4 400) DO (
        set /a T1=%y%%%%%i
        if !T1!==0 (set runnian=1) ELSE set runnian=0
)


修改成
set runnian=0
FOR %%i IN (4 400) DO (
        set /a T1=%y%%%%%i
        if !T1!==0 (set runnian=1)
)

[ Last edited by knoppix7 on 2007-9-30 at 04:45 PM ]

2007-9-30 12:36
查看资料  发短消息 网志   编辑帖子  回复  引用回复
knoppix7
银牌会员





积分 1287
发帖 634
注册 2007-5-2
来自 cmd.exe
状态 离线
『第 9 楼』:  

作为DEBUG的回报。加4点吧.

2007-9-30 16:46
查看资料  发短消息 网志   编辑帖子  回复  引用回复
s11ss
银牌会员





积分 2098
发帖 566
注册 2007-9-11
状态 离线
『第 10 楼』:  

knoppix7,
你判断闰年的算法有问题.对于闰年的判断我过去也一直是一头雾水。

能被4或400整除的是闰年,这句话就相当于说能被4整除的是闰年,因为一个数能被400整除是这个数能被4整除的充分条件。

就好比说:
大眼睛的或大眼睛长头发的女人是美女。其实就是说大眼睛的女人是美女。

正确的算法应该是:
能被4整除,且不能被100整除的是闰年;或者能被400整除的是闰年。
比如2100年按你的算法是闰年,但其实不是,因为它上面两个条件都不满足。

但其实能被3200整除的不是闰年,不过这离现在太远了。一般就是按上面的算法判断闰年的。

关于闰年的判断早在几年前学C语言的时候我就没弄明白,最近写这个万年历的时候才总算彻底搞懂了。

2007-9-30 17:23
查看资料  发短消息 网志   编辑帖子  回复  引用回复
slore
铂金会员





积分 5212
发帖 2478
注册 2007-2-8
状态 离线
『第 11 楼』:  

其实能被3200整除的不是闰年……这个说法太……不要说的让人产生反面是闰年的说法……

能被4整除,且不能被100整除的是闰年;或者能被400整除的是闰年。
这个是对的。

原因:
阳历究竟哪一年算是闰年,只要做一次简单的计算就知道,用4去除阳历的年份,除尽的就是闰年,象1964年、1968年等等都是闰年,这几年的二月都有29天。
    又因为阳历一年的确实天数应该是365天5小时48分46秒,比常年365天多出5小时48分46秒,四年一共只多出23小时15分4秒。每4年一闰加一天的话,又多加了44分56秒,400年差不多就会多加出3天来,所以,每400年得扣去3天才行,于是,又定了一一条补充规定:每逢阳历年份是整白的那一年,比如公元l800年、1900年、2000年等,能被400除尽的才算是闰年。这样公元1800年和1900年尽管能被4除尽,但是不能被400除尽,所以不算是闰年,而公元2000年才是闰年,它的二月才有29天。有了这样一条补充规定,每四百年就可以从中扣去那多加出来的3天了。虽然这样调整以后,也还会有微小的误差,但要经过3000年后才会差一天,我们日常应用就算很准确了。

2007-9-30 17:31
查看资料  发短消息 网志   编辑帖子  回复  引用回复
knoppix7
银牌会员





积分 1287
发帖 634
注册 2007-5-2
来自 cmd.exe
状态 离线
『第 12 楼』:  



  Quote:
Originally posted by s11ss at 2007-9-30 05:23 PM:
knoppix7,
你判断闰年的算法有问题.对于闰年的判断我过去也一直是一头雾水。

能被4或400整除的是闰年,这句话就相当于说能被4整除的是闰年,因为 ...

对不起。具体方法我是copy网上的.不过。我发现WXP的时间根本到不了2100年。
所以没算进去.

2007-9-30 17:59
查看资料  发短消息 网志   编辑帖子  回复  引用回复
knoppix7
银牌会员





积分 1287
发帖 634
注册 2007-5-2
来自 cmd.exe
状态 离线
『第 13 楼』:  



  Quote:
Originally posted by slore at 2007-9-30 05:31 PM:
其实能被3200整除的不是闰年……这个说法太……不要说的让人产生反面是闰年的说法……

能被4整除,且不能被100整除的是闰年;或者能被400整除的 ...

哪计算方法是什么。。。。。
又不可能人工指定时间...

2007-9-30 18:04
查看资料  发短消息 网志   编辑帖子  回复  引用回复
knoppix7
银牌会员





积分 1287
发帖 634
注册 2007-5-2
来自 cmd.exe
状态 离线
『第 14 楼』:  

我想到了。
用date命令判断。
事例:
C:\Documents and Settings\lenovo>date 2007-02-29(非闰年,所以...)
系统无法接受输入的日期。
输入新日期: (年月日)

C:\Documents and Settings\lenovo>date 2100-02-29(超过WXP的年数限制)
系统无法接受输入的日期。
输入新日期: (年月日)


C:\Documents and Settings\lenovo>date 2004-02-29(成功)

[ Last edited by knoppix7 on 2007-10-1 at 02:11 PM ]

2007-9-30 18:07
查看资料  发短消息 网志   编辑帖子  回复  引用回复
knoppix7
银牌会员





积分 1287
发帖 634
注册 2007-5-2
来自 cmd.exe
状态 离线
『第 15 楼』:  

我想到的办法:
@echo off
set DD=%date:~0,10%
set runnian=0
date %y%-2-29|find "系统无法接受输入的日期。" >nul ||set runnian=1
date %DD%


不过我没有测试...

2007-10-1 14:13
查看资料  发短消息 网志   编辑帖子  回复  引用回复
« [1] [2] »
请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: