|
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日。
后来人们将这一新的历法称为“格里高利历”,也就是今天世界上所通用的历法,简称格里历或公历。
|
|
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
状态 离线
|
|
2007-9-29 17:32 |
|
|
knoppix7
银牌会员
积分 1287
发帖 634
注册 2007-5-2 来自 cmd.exe
状态 离线
|
|
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显然是闰年
|
|
2007-9-29 23:01 |
|
|
lipu721
新手上路
积分 4
发帖 2
注册 2007-9-29
状态 离线
|
『第
6 楼』:
头晕晕的............
|
|
2007-9-29 23:50 |
|
|
lipu721
新手上路
积分 4
发帖 2
注册 2007-9-29
状态 离线
|
|
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 |
|