|
zjl5
初级用户
积分 82
发帖 15
注册 2007-5-26
状态 离线
|
『楼 主』:
批处理版万年历
────────── 版主提示 ──────────
完善后的代码请看20楼 qzwqzw 的脚本
────────── 版主提示 ──────────
::算法:基姆拉尔森计算公式
::W= (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400) mod 7
::在日历里面★=当天
::还没有加入闰年的计算.所以所有的2月都是28天
@echo off& color 27 & mode con cols=40 lines=20 & title 日历,泛滥棏慌°制作.QQ:173459058&&setlocal enabledelayedexpansion
set dated=%date%
:home
cls&echo/
set zdate=%date%
set y=%zdate:~0,4%
set m=%zdate:~5,2%
set d=%date:~8,2%
if %d% geq 32 (echo 错误的日期.&pause>nul&exit)
set d1=01
if "%m%"=="01" (set /a y-=1& set /a m+=12)
if "%m%"=="02" (set /a y-=1& set /a m+=12)
::计算星期公式
set /a w=(%d1%+2*%m%+3*(%m%+1)/5+%y%+%y%/4-%y%/100+%y%/400)%%7+1
set /a ww=(%d%+2*%m%+3*(%m%+1)/5+%y%+%y%/4-%y%/100+%y%/400)%%7+1
set 1=一&set 2=二&set 3=三&set 4=四&set 5=五&set 6=六&set 7=日
if "%date%"=="%dated%" (
echo 这是%date:~0,4%年%date:~5,2%月日历 今天:%dated:~0,4%!-%dated:~5,2%-%dated:~8,2%
) else (
echo 这是%date:~0,4%年%date:~5,2%月日历 ★=当天
echo 你查询的日期是:%date%,星期!%ww%!
)
::还没有加入闰年的计算.所以所有的2月都是28天
set %m%m=31&set %m%m=28&set %m%m=31&set %m%m=30&set %m%m=31&set %m%m=30
set %m%m=31&set %m%m=31&set %m%m=30&set %m%m=31&set %m%m=30&set %m%m=31
set /a cyc=!%m%m!+%w%-1
set n=0
for /l %%i in (0,1,40) do (set w%%i= )
for /l %%i in (%w%,1,%cyc%) do (
set /a n+=1
set w%%i=0!n!
if !n! GEQ 10 set w%%i=!n!
if !n! EQU !d! set w%%i=★
)
echo/
echo 日 一 二 三 四 五 六
echo ━━━━━━━━━━━━━━━━━━━━
echo %w0% %w1% %w2% %w3% %w4% %w5% %w6%
echo.
echo %w7% %w8% %w9% %w10% %w11% %w12% %w13%
echo.
echo %w14% %w15% %w16% %w17% %w18% %w19% %w20%
echo.
echo %w21% %w22% %w23% %w24% %w25% %w26% %w27%
echo.
echo %w28% %w29% %w30% %w31% %w32% %w33% %w34%
echo ━━━━━━━━━━━━━━━━━━━━
echo 输入年月日,可以看当月日历及显示当日星期
set /p date=格式如(2007-02-03)-[E]退出:
if /i "%date%"=="E" exit
goto :home [ Last edited by bjsh on 2007-7-31 at 02:36 PM ]
此帖被 +25 点积分 点击查看详情 评分人:【 lxmxn 】 | 分数: +12 | 时间:2007-5-26 20:50 | 评分人:【 huzixuan 】 | 分数: +4 | 时间:2007-5-27 15:39 | 评分人:【 qzwqzw 】 | 分数: +3 | 时间:2007-5-27 16:18 | 评分人:【 Vampire 】 | 分数: +2 | 时间:2007-6-2 23:50 | 评分人:【 AlexZhang 】 | 分数: +4 | 时间:2007-8-1 18:42 |
|
|
|
2007-5-26 20:43 |
|
|
lxmxn
版主
积分 11386
发帖 4938
注册 2006-7-23
状态 离线
|
『第
2 楼』:
不错,加上判断是否闰年的功能就更加完美了。
|
|
2007-5-26 20:51 |
|
|
ieutk
初级用户
积分 107
发帖 48
注册 2006-11-30
状态 离线
|
『第
3 楼』:
要是能查到农历就更好啦!哈~
|
她希望我把粪土变黄金,我希望她视黄金如粪土! |
|
2007-5-27 14:30 |
|
|
qzwqzw
银牌会员
天的白色影子
积分 2342
发帖 635
注册 2004-3-6
状态 离线
|
『第
4 楼』:
试了试
除了2006-12这样的31天月份显示30天之外
其它月份都显示31天
问题出在这句
set %m%m=31&set %m%m=28&set %m%m=31&set %m%m=30&set %m%m=31&set %m%m=30
set %m%m=31&set %m%m=31&set %m%m=30&set %m%m=31&set %m%m=30&set %m%m=31 还需要继续努力啊
|
|
2007-5-27 15:12 |
|
|
my3439955
中级用户
积分 272
发帖 99
注册 2006-6-2
状态 离线
|
|
2007-5-27 16:13 |
|
|
my3439955
中级用户
积分 272
发帖 99
注册 2006-6-2
状态 离线
|
|
2007-5-27 16:23 |
|
|
zjl5
初级用户
积分 82
发帖 15
注册 2007-5-26
状态 离线
|
『第
7 楼』:
Quote: | Originally posted by qzwqzw at 2007-5-27 03:12 PM:
试了试
除了2006-12这样的31天月份显示30天之外
其它月份都显示31天
问题出在这句
[code]
set %m%m=31&set %m%m=28&set %m%m=31&set %m%m=30&set %m%m ... |
|
谢谢qzwqzw大哥帮忙测试,我考虑好了把修改后的再发上来.
|
|
2007-5-27 17:45 |
|
|
qzwqzw
银牌会员
天的白色影子
积分 2342
发帖 635
注册 2004-3-6
状态 离线
|
『第
8 楼』:
农历这个东西,也许有不查表的办法
听我父亲说,原来家乡有一个二楞子
平时疯疯颠颠的
但唯独掌握一门“神技”十分让人佩服
那就是它可以将古往今来五百年来的老皇历默熟于心
农历大小月以及闰月等问题对他根本不是问题
我未见其人,至今不知道他采用的是什么办法
---------------------------------------------------------
从理性角度考虑
现如今所使用的农历
虽然是经过多少朝代历次修订而最终成制的
但最终仍然来源于最早的夏历
而夏历的修订和完善主要依赖于天文学的研究成果
除此而外,应该有纯数学的办法可以计算和预期
[ Last edited by qzwqzw on 2007-5-27 at 06:17 PM ]
|
|
2007-5-27 18:14 |
|
|
zjl5
初级用户
积分 82
发帖 15
注册 2007-5-26
状态 离线
|
『第
9 楼』:
qzwqzw兄,我把中间的一部分
set %m%m=31&set %m%m=28&set %m%m=31&set %m%m=30&set %m%m=31&set %m%m=30
set %m%m=31&set %m%m=31&set %m%m=30&set %m%m=31&set %m%m=30&set %m%m=31
set /a cyc=!%m%m!+%w%-1 改成了
for %%i in (04 06 09 11) do if "%m%"=="%%i" set flag=1
if defined flag (set cyc1=30) else (set cyc1=31)
set /a leap=%y%%%4
if %m% equ 2 set cyc1=28
if %leap% EQU 0 (if %m% EQU 2 set cyc1=29)
set /a cyc=%cyc1%+%w%-1 效果没有得到太大改善,更大的问题似乎出在for /l %%i in (%w%,1,%cyc%)
我实在想不出.请帮忙改善.
|
|
2007-5-27 19:50 |
|
|
qzwqzw
银牌会员
天的白色影子
积分 2342
发帖 635
注册 2004-3-6
状态 离线
|
『第
10 楼』:
主要问题在于公式计算的星期顺序和日历显示的星期顺序并不一致
公式计算以星期一起始,星期日结束
日历显示则恰好相反
解决的办法很简单
将公式计算顺序或者日历显示顺序任意调换一个即可
调换公式的星期顺序,只要那句+1移到括号中即可
------------------------------------
另外,2006-12月的问题解决
需要再加一行显示,并同时再增加两个变量
-------------------------------------
其它还有一些问题
比如 if %d% geq 32 中的裸露变量
比如变量 m / d的0前缀问题
再就是变量的命名规范问题
---------------------------------------------
下面是我的代码
@echo off& color 27 & mode con cols=40 lines=20 && setlocal enabledelayedexpansion
set sdate=%date%
:home
cls&echo.
for /f "tokens=1,2,3 delims=-/: " %%i in ("%sdate%") do (
(set sy=%%i) && (set sm=%%j) && (set sd=%%k)
)
(set sm=10%sm%) && (set sd=10%sd%)
(set sm=%sm:~-2%) && (set sd=%sd:~-2%)
set /a m=1%sm%-100, d=1%sd%-100
if %m% geq 13 (echo.错误的日期.&pause>nul&goto :eof)
if %d% geq 32 (echo.错误的日期.&pause>nul&goto :eof)
set fd=01
set y=%sy%
set /a leap="^!(y %% 4) & ^!(^!(y %% 100)) | ^!(y %% 400)"
::计算星期公式
if 1%m% leq 12 (set /a y-=1& set /a m+=12)
set /a begin=(fd+2*m+3*(m+1)/5+y+y/4-y/100+y/400+1)%%7
set /a week=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400+1)%%7
set weektbl=日一二三四五六七
set prmt=当天
if "%sdate%"=="%date%" set prmt=今天
echo. %sy%年%sm%月 %prmt%:%sy%-%sm%-%sd%, 星期!weektbl:~%week%,1!
set /a flag=0, n=0
for %%i in (4 6 9 11) do if "%m%"=="%%i" set flag=1
set /a len=31 - flag
if "%m%"=="14" set /a len=28+leap
for /l %%i in (0,1,36) do (set w%%i= )
set /a end=%len%+%begin%-1
for /l %%i in (%begin%,1,%end%) do (
set /a n+=1
set temp=0!n!
set w%%i=!temp:~-2!
if !n! EQU !d! set w%%i=★
)
echo.
echo. 日 一 二 三 四 五 六
echo.━━━━━━━━━━━━━━━━━━━━
echo. %w0% %w1% %w2% %w3% %w4% %w5% %w6%
echo.
echo. %w7% %w8% %w9% %w10% %w11% %w12% %w13%
echo.
echo. %w14% %w15% %w16% %w17% %w18% %w19% %w20%
echo.
echo. %w21% %w22% %w23% %w24% %w25% %w26% %w27%
echo.
echo. %w28% %w29% %w30% %w31% %w32% %w33% %w34%
echo.
echo. %w35% %w36%
echo.━━━━━━━━━━━━━━━━━━━━
echo.输入年月日,可以看当月日历及显示当日星期
set sdate=
set /p sdate=格式如(2007-02-03)-[回车]退出:
if /i "%sdate%"=="" goto :eof
goto :home
|
|
2007-5-28 00:29 |
|
|
zjl5
初级用户
积分 82
发帖 15
注册 2007-5-26
状态 离线
|
|
2007-5-28 00:57 |
|
|
namejm
荣誉版主
batch fan
积分 5226
发帖 1737
注册 2006-3-10 来自 成都
状态 离线
|
『第
12 楼』:
在10楼的基础上,修改了一下,得到如下代码,效果的改变如下:
1、日期数位置固定,星期数序列动态变化;
2、10以内的日期前面不带0;
3、再次输入当天日期的话,会一直显示“今天”而不是“当天”;
@echo off
:: 算法:基姆拉尔森计算公式
:: W= (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400) mod 7
:: 把一月和二月看成是上一年的十三月和十四月
:: 例:如果是2004-1-10则换算成:2003-13-10来代入公式计算。
color 27
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)
)
(set sm=10%sm%) && (set sd=10%sd%)
(set sm=%sm:~-2%) && (set sd=%sd:~-2%)
set /a m=1%sm%-100, d=1%sd%-100
if %m% geq 13 (echo.错误的日期.&pause>nul&goto :eof)
if %d% geq 32 (echo.错误的日期.&pause>nul&goto :eof)
:: 计算每个月的日期数
set max=31
for %%i in (4 6 9 11) do if %m% equ %%i set max=30
:: 计算2月份的偏差
if %m% leq 2 (set /a y-=1& set /a m+=12)
set /a leap="^!(y%%4) & ^!(^!(y%%100)) | ^!(y%%400)"
if %m% equ 14 set /a max=28+%leap%
:: 计算指定日期的星期数
set /a w=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)%%7
:: 计算动态星期数序列
set /a num=w-(d%%7-1)
set var=!str:~%num%,1!
for /l %%i in (0,1,6) do (
set var_tmp=!str:~%%i,1!
if "!var!"=="!var_tmp!" set var=!str:~%%i,7!
)
set prmt=当天
if "%sy%-%sm%-%sd%"=="%date%" set prmt=今天
echo. %sy%年%sm%月 %prmt%:%sy%-%sm%-%sd%,星期!str:~%w%,1!
echo.
:: 生成表头的星期数序列
for /l %%i in (0,1,6) do set /p= !var:~%%i,1!<nul
:: 生成日期数序列
echo.
echo ━━━━━━━━━━━━━━━━━━━━
for /l %%i in (1,1,%max%) do (
set /a num=%%i%%7
set var= %%i
set var=!var:~-2!
if %d% equ %%i (
set /p= ★<nul
) else set /p= !var!<nul
if !num! equ 0 echo.&echo.
)
echo.
echo ━━━━━━━━━━━━━━━━━━━━
echo.输入年月日,可以看当月日历及显示当日星期
set sdate=
set /p sdate=格式如(2007-02-03)-[回车]退出:
if not defined sdate exit
goto Main [ Last edited by namejm on 2007-6-2 at 11:50 PM ]
|
尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。 |
|
2007-6-2 23:38 |
|
|
qzwqzw
银牌会员
天的白色影子
积分 2342
发帖 635
注册 2004-3-6
状态 离线
|
『第
13 楼』:
这种显示方式并不符合日常习惯
估计很难被人接受
如果不想使用过多的变量
可以使用for将日期顺序输出
只要控制好换行的时机就没有什么问题
另外最好可以控制一下年份的范围和格式
最多只需输入两位年份数
50~99判定为19xx
00~49判定为20xx
计算太远的星期没有太多意义
|
|
2007-6-3 00:07 |
|
|
namejm
荣誉版主
batch fan
积分 5226
发帖 1737
注册 2006-3-10 来自 成都
状态 离线
|
『第
14 楼』:
动态显示星期序列的做法确实是不太合乎习惯,刚才觉得这个很有意思,就拿来改编了一下,呵呵,仅作为一种新效果而推出。
"计算太远的星期没有太多意义" 这句话不知道指的是什么,暂时没有什么过多的想法,若有什么有意思的想法的话,我也想听听^_^。
|
尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。 |
|
2007-6-3 00:15 |
|
|
qzwqzw
银牌会员
天的白色影子
积分 2342
发帖 635
注册 2004-3-6
状态 离线
|
『第
15 楼』:
例如以下代码的效果
@echo off
:: 算法:基姆拉尔森计算公式
:: W= (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400) mod 7
:: 把一月和二月看成是上一年的十三月和十四月
:: 例:如果是2004-1-10则换算成:2003-13-10来代入公式计算。
color 27
mode con cols=40 lines=20
setlocal enabledelayedexpansion
set str=日一二三四五六
set prmt=今天
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)
)
(set sy=00%sy%) && (set sm=10%sm%) && (set sd=10%sd%)
(set sy=%sy:~-2%) && (set sm=%sm:~-2%) && (set sd=%sd:~-2%)
set /a y=1%sy%-100, m=1%sm%-100, d=1%sd%-100
if %y% lss 50 (set /a y+=2000) else (set /a y+=1900)
set sy=%y%
if %m% geq 13 (echo.错误的日期.&pause>nul&goto :eof)
if %d% geq 32 (echo.错误的日期.&pause>nul&goto :eof)
:: 计算每个月的天数
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%月 %prmt%:%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,36) do (
set "temp= "
if %%i GTR %wb% if %%i LSS %we% (
set temp=0!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= 格式如:07-02-03,[回车]退出:
set prmt=当天
if defined sdate goto Main
|
|
2007-6-3 02:16 |
|