5 个计算天数的批处理
发现很多人需要计算 n 天前后的天数,
但是计算天数要考虑到大月小月,平年闰年。及其麻烦。
于是把我的收集整理后发出来给大家共享一下。
说明:
收集整理: 随风 @bbs.bathome.net 2008-04-15
第一个代码 作者:Will Sort 出自:cn-dos
第二、三、四、个代码 作者:namejm 出自:cn-dos
第五个为 bat 结合 vbs 代码,作者及出处都不详。
其中第一及第五个代码,输入负数为:追溯指定日期以后的天数。
第二、三、四个代码,未作测试,但输入正整数是可以的。也就是追溯指定日期以前的天数。
===========================================================================
代码一、
作者:Will Sort
- :: DateDel2.bat - 删除指定路径下指定日数以前修改的文件
- :: 作者:Will Sort - 2005-9-2 - CMD@WinXP 出自:cn-dos
- :: 注意事项:变量 tian 为指定日数,昨天为1,前天为2,依次类推
- :: 核心算法:Ritchie Lawrence, updated 2002-08-13. Version 1.1
- ::
- @echo off & setlocal ENABLEEXTENSIONS
- call :Date2Day %date:~0,10% sdays
- rem 下行的%tian%代表天数.
- set /p tian= 请指定要追溯的天数:
- set /a sdays-=tian
- call :Day2Date %sdays% difdate
- echo.&echo.
- echo 指定的日期是: %date:~0,10%
- echo.
- echo %tian% 天前的日期是:%difdate%
- echo.&pause
- exit
- :Date2Day
- setlocal ENABLEEXTENSIONS
- for /f "tokens=1-3 delims=/-, " %%a in ('echo/%1') do (
- set yy=%%a & set mm=%%b & set dd=%%c
- )
- set /a dd=100%dd%%%100,mm=100%mm%%%100
- set /a z=14-mm,z/=12,y=yy+4800-z,m=mm+12*z-3,j=153*m+2
- set /a j=j/5+dd+y*365+y/4-y/100+y/400-2472633
- endlocal&set %2=%j%&goto :EOF
- :Day2Date
- setlocal ENABLEEXTENSIONS
- set /a i=%1,a=i+2472632,b=4*a+3,b/=146097,c=-b*146097,c/=4,c+=a
- set /a d=4*c+3,d/=1461,e=-1461*d,e/=4,e+=c,m=5*e+2,m/=153,dd=153*m+2,dd/=5
- set /a dd=-dd+e+1,mm=-m/10,mm*=12,mm+=m+3,yy=b*100+d-4800+m/10
- (if %mm% LSS 10 set mm=0%mm%)&(if %dd% LSS 10 set dd=0%dd%)
- endlocal&set %2=%yy%-%mm%-%dd%&goto :EOF
复制代码
===========================================================================
代码二、
以下三个代码作者全是 namejm
- :: 作者: namejm 荣誉版主 出自:cn-dos
- @echo off
- :: 求N天前的日期
- :: 思路:
- :: 模拟手工运算,用日期数减去天数,差值为负时向高位借1。
- :: 特点:
- :: 代码简洁,容易理解,速度快慢取决于指定的天数大小
- :: 日期可以带星期,但是,必须以年月日的顺序排列
- :: 年份必须是四位,否则会出错
- @echo off
- :Main
- cls
- set day=%date%
- set days=0
- echo.&echo.
- echo 指定的日期是:%day%
- echo.
- set /p input= 请指定要追溯的天数:
- setlocal enabledelayedexpansion
- :: 提取日期
- for /f "tokens=1-3 delims=-/. " %%i in ("%day%") do (
- set /a sy=%%i, sm=100%%j %% 100, sd=100%%k %% 100
- )
- set /a sd-=input
- if %sd% leq 0 call :count
- cls
- echo.&echo.
- echo 指定的日期是:%day%
- echo.
- set sm=0%sm%
- set sd=0%sd%
- echo %input% 天前的日期是:%sy%-%sm:~-2%-%sd:~-2%
- pause>nul
- goto Main
- :count
- set /a sm-=1
- if !sm! equ 0 set /a sm=12, sy-=1
- call :days
- set /a sd+=days
- if %sd% leq 0 goto count
- goto :eof
- :days
- :: 获取指定月份的总天数
- set /a leap="^!(sy %% 4) & ^!(^!(sy %% 100)) | ^!(sy %% 400)"
- set /a max=28+leap
- set num=0
- set str=31 %max% 31 30 31 30 31 31 30 31 30 31
- for %%i in (%str%) do (
- set /a num+=1
- if %sm% equ !num! set days=%%i&goto :eof
- )
- goto :eof
复制代码
===========================================================================
代码三、
- @echo off
- :: 作者: namejm 荣誉版主 出自:cn-dos
- :: 求N天前的日期
- :: 思路:
- :: 把当前日期转换为天数
- :: 用当前天数减去N天
- :: 把结果再转换为日期
- :: 具体操作是:
- :: 逐年计算天数
- :: 特点:
- :: 代码简洁,容易理解,速度较慢,但是不受指定天数大小的影响
- setlocal enabledelayedexpansion
- :Main
- cls
- :: 日期可以带星期,但是,必须以年月日的顺序排列
- :: 年份必须是四位,否则会出错
- set day=%date%
- set days=0
- echo.&echo.
- echo 指定的日期是:%day%
- echo.
- set /p input= 请指定要追溯的天数:
- rem ========把指定日期转换为天数========
- :: 提取日期
- for /f "tokens=1-3 delims=-/. " %%i in ("%day%") do (
- set /a sy=%%i, sm=100%%j %% 100, sd=100%%k %% 100
- )
- :: 把年份转化为天数
- for /l %%i in (1,1,%sy%) do (
- set /a leap="^!(%%i %% 4) & ^!(^!(%%i %% 100)) | ^!(%%i %% 400)"
- set /a days=days+365+leap
- )
- :: 把月份转化为天数
- set /a num=0, mday=0, max=28+leap
- set str=0 31 %max% 31 30 31 30 31 31 30 31 30
- for %%i in (%str%) do (
- set /a num+=1
- if !num! leq !sm! set /a mday+=%%i
- )
- set /a days=days+mday+sd
- set /a days-=input
-
- rem ========把天数转换为日期========
- :: 获取年份
- for /l %%i in (1,1,%sy%) do (
- set /a leap="^!(%%i %% 4) & ^!(^!(%%i %% 100)) | ^!(%%i %% 400)"
- set /a days_tmp=365+leap
- if !days! gtr !days_tmp! (
- set /a days-=days_tmp
- set y=%%i
- )
- )
- :: 获取月份及日期
- set /a m=1, max=28+%leap%
- set str=31 %max% 31 30 31 30 31 31 30 31 30
- for %%i in (%str%) do (
- if !days! gtr %%i (
- set /a days-=%%i
- set /a m+=1
- ) else goto next
- )
- :next
- set m=0%m%
- set d=0%days%
- cls
- echo.&echo.
- echo 指定的日期是:%day%
- echo.
- echo %input% 天前的日期是:%y%-%m:~-2%-%d:~-2%
- pause>nul
- goto Main
复制代码
===========================================================================
代码四、
- @echo off
- :: 作者: namejm 荣誉版主 出自:cn-dos
- :: 求N天前的日期
- :: 思路:
- :: 把当前日期转换为天数
- :: 用当前天数减去N天
- :: 把结果再转换为日期
- :: 具体操作是:
- : 先按照每年365天计算,然后再计算闰年的个数
- :: 最后再做转换
- :: 特点:
- :: 代码复杂,不便于理解,但是速度很快
- :: 计算上还存在bug,可以用 11111 来和头两个做对比测试,暂时没时间更新
- setlocal enabledelayedexpansion
- :Main
- cls
- :: 日期可以带星期,但是,必须以年月日的顺序排列
- :: 年份必须是四位,否则会出错
- set day=2007-01-02
- set /a days=0, sum=0
- echo.&echo.
- echo 指定的日期是:%day%
- echo.
- set /p input= 请指定要追溯的天数:
- rem =======把日期转换为天数=======
- :: 提取日期
- for /f "tokens=1-3 delims=/-. " %%i in ("%day%") do (
- set /a sy=%%i, sm=100%%j %% 100, sd=100%%k %% 100, y=%%i
- )
- :: 把年份抓换为天数
- set num=0
- if %sy% lss 400 goto next1
- call :leap_num
- :next1
- set /a leap_num=sy/4-num
- :: 把月份转换为天数
- set /a leap="^!(sy %% 4) & ^!(^!(sy %% 100)) | ^!(sy %% 400)"
- set /a max=28+leap
- set num=0
- set str=31 %max% 31 30 31 30 31 31 30 31 30 31
- for %%i in (%str%) do (
- set /a num+=1
- if !num! lss %sm% set /a sum+=%%i
- )
- set /a days=365*sy+leap_num+sum+sd
- set /a days-=input
- rem =======把天数转换为日期=======
- :: 获取年份
- set /a y=days/365
- set /a mod1=days %% 365
- call :leap_num
- set /a mod2=mod1-leap_num
- :loop2
- if %mod2% lss 0 (
- set /a y-=1
- set /a mod2=365+mod2
- ) else goto next2
- goto loop2
- :: 获取月份及日期
- :next2
- set /a m=1, days=mod2+1, max=28+%leap%
- set str=31 %max% 31 30 31 30 31 31 30 31 30
- for %%i in (%str%) do (
- if !days! gtr %%i (
- set /a days-=%%i
- set /a m+=1
- ) else goto next3
- )
- :next3
- set m=0%m%
- set d=0%days%
- cls
- echo.&echo.
- echo 指定的日期是:%day%
- echo.
- echo %input% 天前的日期是:%y%-%m:~-2%-%d:~-2%
- pause>nul
- goto Main
- :leap_num
- :: 计算能被100整除但是不能被400整除的年次
- set /a y_tmp=(%y:~0,1%%y%-%y%)/10
- set num=0
- :loop1
- set /a mod=y_tmp %% 400
- if %mod% neq 0 set /a num+=1
- set /a y_tmp-=100
- if %y_tmp% geq 100 goto loop1
- set /a leap_num=y/4-num
- goto :eof
复制代码
===========================================================================
代码五、
用 vbs 代码可以更简单。但是需创建 tmptmp.vbs 临时文件。
- @echo off
- set /p _tian= 请指定要追溯的天数:
- >tmptmp.vbs echo wscript.echo dateadd("d",-%_tian%,date)
- for /f "tokens=1,2,3* delims=-" %%i in ('cscript /nologo tmptmp.vbs') do (
- set /a y=%%i,m=100%%j%%100,d=100%%k%%100
- )
- set "difdate=%y%-%m%-%d%"
- del/q tmptmp.vbs
- cls&echo.&echo.
- echo 指定的日期是: %date:~0,10%
- echo.
- echo %_tian% 天前的日期是:%difdate%
- echo.&pause&exit
复制代码
[ 本帖最后由 随风 于 2008-4-15 22:32 编辑 ] |