中国DOS联盟论坛

中国DOS联盟

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

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

游客:  注册 | 登录 | 命令行 | 会员 | 搜索 | 上传 | 帮助 »
« [1] [2] [3] »
作者:
标题: 批处理版万年历 上一主题 | 下一主题
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
状态 离线
『第 5 楼』:  

这个日历也不错
http://www.cn-dos.net/forum/viewthread.php?tid=27739&fpage=11

还可以支持任意年包括闰年
http://www.cn-dos.net/forum/view ... mp;page=2#pid195566

[ Last edited by my3439955 on 2007-5-27 at 04:20 PM ]



X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*
2007-5-27 16:13
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
my3439955
中级用户




积分 272
发帖 99
注册 2006-6-2
状态 离线
『第 6 楼』:  



  Quote:
Originally posted by ieutk at 2007-5-27 14:30:
要是能查到农历就更好啦!哈~

农历没有规则的公式,只能推算出一段时间然后进行查表
不信的话看看那些支持农历的万年历
农历的支持一般不会超过200年
公历的话就没有这个限制
可以到任意年



X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*
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
状态 离线
『第 11 楼』:  

谢谢,,这样才够完美.

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


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



论坛跳转: