中国DOS联盟论坛

中国DOS联盟

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

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

游客:  注册 | 登录 | 命令行 | 会员 | 搜索 | 上传 | 帮助 »
« [1] [2] [3] »
作者:
标题: 批处理版万年历 上一主题 | 下一主题
Michael
钻石会员





积分 10046
发帖 3039
注册 2002-11-11
状态 离线
『第 16 楼』:  



  Quote:
Originally posted by qzwqzw at 2007-5-27 06:14 PM:
农历这个东西,也许有不查表的办法

听我父亲说,原来家乡有一个二楞子

平时疯疯颠颠的

但唯独掌握一门“神技”十分让人佩服

那就是它可 ...

唯一的办法就是教会你家乡的“二愣子”学会批处理。呵呵。



简单就是美
2007-6-3 11:16
查看资料  发短消息 网志   编辑帖子  回复  引用回复
namejm
荣誉版主

batch fan


积分 5226
发帖 1737
注册 2006-3-10
来自 成都
状态 离线
『第 17 楼』:  

  发个使用更加方便一点的代码,对日历多余的空行做删除处理,修正了15楼代码中查询2007年7月份时只有30天的错误,此错误是由于当月1日正好是星期日、而37次循环只能扫描到30日引起的,更多的改变请看代码说明。
@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来代入公式计算。

:: 输入的日期格式为:年-月-日(-可以替换为:、/,可以混用)
:: 在日历里面,★=当天

:: 支持多种格式的日期输入:
:: ① 若只输入一个数,则认为是查询当年月份,自动截取后两位数字查询,★标在1日上;
:: ② 若输入两个数,则认为是查询年和月,★标在1日上;
:: ③ 输全的话,★标在指定日期上

:: 关于年份的转换:
:: ① 若年份上输入的是两位数,则作如下转换:
::     50~99判定为19xx
::     00~49判定为20xx
:: ② 若输入的年份不是两位的,则把年份前面的所有0去掉之后,
::    计算该年份的日期;

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)
)
if not defined sd set sd=1
if not defined sm set sm=%sy%& set sy=%date:~0,4%
(set sm=10%sm%) && (set sd=10%sd%)
(set sm=%sm:~-2%) && (set sd=%sd:~-2%)
set y=%sy%
set /a m=1%sm%-100, d=1%sd%-100
if not "%sy:~2%"=="" goto check
if "%sy:~1%"=="" goto check
set sy=00%sy%
set sy=%sy:~-2%
set /a y=1%sy%-100
if %y% lss 50 (set /a y+=2000) else (set /a y+=1900)
set sy=%y%
:check
for %%i in (%y% %m% %d%) do (
    if %%i equ 0 echo.错误的日期.&pause>nul&set sdate=%date%&goto Main
)
for /f "delims=0 tokens=*" %%i in ("%sy%") do set /a sy=%%i,y=%%i
if %m% geq 13 (echo.错误的日期.&pause>nul&set sdate=%date%&goto Main)
if %d% geq 32 (echo.错误的日期.&pause>nul&set sdate=%date%&goto Main)

:: 计算每个月的天数
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
::set /a w=(%d%+2*%m%+3*(%m%+1)/5+%y%+%y%/4-%y%/100+%y%/400+1)%%7

set prmt=当天
if "%sy%-%sm%-%sd%"=="%date%" set prmt=今天
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
if %wb% equ 6 (set begin=7) else set begin=0
for /l %%i in (%begin%,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
    if !day! gtr !days! goto end
    set /a "wm=(%%i+1)%%7"
    if !wm! equ 0 echo.&echo.&set /p= <nul
)
:end
echo.
echo  ━━━━━━━━━━━━━━━━━━━
echo. 输入日期可以看当月日历及显示当日星期
echo.
set sdate=
set /p sdate= 格式如:07-02-03,[回车]退出:
if defined sdate goto Main
[ Last edited by namejm on 2007-6-3 at 02:50 PM ]



尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。
2007-6-3 13:32
查看资料  发短消息 网志   编辑帖子  回复  引用回复
qzwqzw
银牌会员

天的白色影子


积分 2342
发帖 635
注册 2004-3-6
状态 离线
『第 18 楼』:  

2007年7月的问题我注意到了

不过那时已没有时间改了
----------------------------------

空行的删除会让提示信息和输入日期为止频繁变动

对排版效果的改善起不到积极作用

所以我没有考虑
----------------------------------
日期格式化检查部分的改动比较乱

输入7-6-3得到的是7-06-03(年份没有格式化)

输入0得到的是2007-00-01(月份没有校验)

月与日的缺省值原本是10月/10日

只是考虑到实现起来比较简单
----------------------------------
当日/今日的显示

现在觉得意义不大

尤其是与带星期的%date%比较

[ Last edited by qzwqzw on 2007-6-3 at 02:33 PM ]

2007-6-3 14:25
查看资料  发短消息 网志   编辑帖子  回复  引用回复
namejm
荣誉版主

batch fan


积分 5226
发帖 1737
注册 2006-3-10
来自 成都
状态 离线
『第 19 楼』:  



  Quote:
Originally posted by qzwqzw at 2007-6-3 14:25:
输入7-6-3得到的是7-06-03(年份没有格式化)

  想把这个代码做成万年历,7年表示公元7年,所以没法格式化。

  Quote:
输入0得到的是2007-00-01(月份没有校验)

  17楼的代码已经添加了对日期和月份为0时的检测。

  Quote:
当日/今日的显示
现在觉得意义不大
尤其是与带星期的%date%比较

  碰到带星期格式的%date%,确实比较令人头痛,提取时间的代码很难做到完全兼容。另外,日期分隔符也可以人为指定,这就更难以兼容了。



尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。
2007-6-3 14:57
查看资料  发短消息 网志   编辑帖子  回复  引用回复
qzwqzw
银牌会员

天的白色影子


积分 2342
发帖 635
注册 2004-3-6
状态 离线
『第 20 楼』:  

已经说过了,万年历没有太多意义

有谁会查公元元年的星期呢?

那时候都甚至没有格里高利历法

如果真想做专业的年表

那就需要连公元前一起考虑

谁知道这个公式在公元前是否仍然适用

而且你的代码也已经加入了0~55的判断

那就说明也默认了0~55是+了2000年的
----------------------------------------------------

将日期格式化校验代码简化后如下
:: 月历查询工具 中国DOS联盟专用版 转载请注明版权
:: 原创:zjl5  更新:namejm, qzwqzw 2007-06-03

:: 算法:基姆拉尔森计算公式
:: W= (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400) mod 7
:: 把一月和二月看成是上一年的十三月和十四月
:: 例:如果是2004-1-10则换算成:2003-13-10来代入公式计算。

:: 输入的日期格式为:年-月-日(-可以替换为:、/,可以混用)
:: 在日历里面,★=当天

:: 支持多种格式的日期输入:
:: ① 若只输入一个数,则认为是查询当年月份,自动截取后两位数字查询,★标在1日上;
:: ② 若输入两个数,则认为是查询年和月,★标在1日上;
:: ③ 输全的话,★标在指定日期上

:: 关于年份的转换:
:: ① 若年份上输入的数字少于三位,则作如下转换:
::     50~99判定为19xx
::     0~49判定为20xx
:: ② 若输入的年份数字超过两位,则截取后四位字符(不足部分在高位补0),
::    按 ① 的规则计算该年份的日期;

@echo off
color 3F
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%)
cd.
set /a y=1%sy%-10000, m=1%sm%-100, d=1%sd%-100 2>nul
if errorlevel 1 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
set sdate=%date%
goto Main

:Calc
:: 计算每个月的天数
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=  格式如:07-02-03,[回车]退出:
if defined sdate goto Main
[ Last edited by qzwqzw on 2007-8-5 at 06:48 PM ]

2007-6-3 15:36
查看资料  发短消息 网志   编辑帖子  回复  引用回复
namejm
荣誉版主

batch fan


积分 5226
发帖 1737
注册 2006-3-10
来自 成都
状态 离线
『第 21 楼』:  



  Quote:
Originally posted by qzwqzw at 2007-6-3 15:36:
已经说过了,万年历没有太多意义
有谁会查公元元年的星期呢?
那时候都甚至没有格里高利历法

  呵呵,万年历确实没太多的意义,我就把它当作游戏来做吧^_^。

  Quote:
而且你的代码也已经加入了0~55的判断
那就说明也默认了0~55是+了2000年的

  实际上,在我的代码里,我加的是00~55的判断,并非0~55,所以,如果要让脚本自动加上19或20的前缀的话,就要输入两位数的年份。

  20楼的代码充分考虑了大众的阅读习惯和查询习惯,并对日期做了格式化处理,已经非常完善了。只是关于年份转换的那部分说明,直接从我那段代码里复制过来,所描述的效果和你的代码功能不完全吻合,建议把它改成这样:

  Quote:
:: 关于年份的转换:
:: ① 若年份上输入的数字少于三位,则作如下转换:
::     50~99判定为19xx
::     0~49判定为20xx
:: ② 若输入的年份数字超过两位,则截取后四位字符(不足部分在高位补0),
::    按 ① 的规则计算该年份的日期;





尺有所短,寸有所长,学好CMD没商量。
考虑问题复杂化,解决问题简洁化。
2007-6-3 16:10
查看资料  发短消息 网志   编辑帖子  回复  引用回复
qzwqzw
银牌会员

天的白色影子


积分 2342
发帖 635
注册 2004-3-6
状态 离线
『第 22 楼』:  

多谢指出

已经修正

2007-6-3 22:16
查看资料  发短消息 网志   编辑帖子  回复  引用回复
zjl5
初级用户





积分 82
发帖 15
注册 2007-5-26
状态 离线
『第 23 楼』:  

还是找不到算农历的方法,只能算出生肖和农历干支年.
@echo off&setlocal enabledelayedexpansion
set sx=猴鸡狗猪鼠牛虎兔龙蛇马羊
set tg=庚辛壬癸甲乙丙丁戊己
set dz=申酉戌亥子丑寅卯辰巳午未
set /p year=请输入农历年:
set /a sxnum=%year% %% 12
set /a tgnum=%year:~-1%
echo/&echo %year%年生肖是:!sx:~%sxnum%,1!    农历 !tg:~%tgnum%,1!!dz:~%sxnum%,1! 年
echo/&echo 按任意键算出从1800-2500年中属!sx:~%sxnum%,1!的年份.
pause>nul&set n=1799&echo/
:a
set /a n+=1
set /a ynum=!n! %% 12
set /a tgnum=!n:~-1!
if !n! equ 2500 ECHO -结束,按任意键退出.&pause>nul&exit
if !ynum! equ !sxnum! (echo 属!sx:~%sxnum%,1!的年份还有 !n! 年    农历 !tg:~%tgnum%,1!!dz:~%ynum%,1! 年&goto :a) else (goto :a)


2007-6-16 03:05
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
whswbiori
新手上路





积分 10
发帖 5
注册 2007-8-1
状态 离线
『第 24 楼』:  

气氛真好 你们2个好活跃啊 看了3,4个帖子 都有你们
]

2007-8-1 05:00
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
kidzgy
中级用户





积分 262
发帖 129
注册 2007-7-11
状态 离线
『第 25 楼』:  

到底最完美一点的是拿一个啊?

2007-8-1 09:17
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
kidzgy
中级用户





积分 262
发帖 129
注册 2007-7-11
状态 离线
『第 26 楼』:  

20楼的,如果日期输入错误,会出现死循环。一直都是错误。

2007-8-1 09:21
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
qzwqzw
银牌会员

天的白色影子


积分 2342
发帖 635
注册 2004-3-6
状态 离线
『第 27 楼』:  

请说详细些
输入什么样的错误日期?
在什么地方死循环?

2007-8-1 10:15
查看资料  发短消息 网志   编辑帖子  回复  引用回复
youxi01
高级用户




积分 846
发帖 247
注册 2006-10-27
来自 湖南==》广东
状态 离线
『第 28 楼』:  

namejm兄和qzwqzw兄还有这么高的兴致啊,佩服ing

2007-8-1 12:33
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
kidzgy
中级用户





积分 262
发帖 129
注册 2007-7-11
状态 离线
『第 29 楼』:  



  Quote:
Originally posted by qzwqzw at 2007-8-1 10:15 AM:
请说详细些
输入什么样的错误日期?
在什么地方死循环?

我复制你的代码到bat中,不管输入什么,字母也好,按照你的格式输入也好,07-02-03都没有用,回车之后提示错误,此时按任意键回不了主菜单,造成一个死循环,一直停留在错误界面内,若不关闭的话。

2007-8-1 18:04
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
qzwqzw
银牌会员

天的白色影子


积分 2342
发帖 635
注册 2004-3-6
状态 离线
『第 30 楼』:  

无法复现的你的错误
如果你懂得简单的批处理调试技巧的话
可以在代码的错误提示前
插入一条语句查看此时变量接受输入的结果

echo [%OS%][%date%][%sDate%][%y%=%m%=%d%]

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


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



论坛跳转: