批处理bat计算两个时间差----使用call调用函数

这篇文章主要介绍了批处理bat中计算两个时间差的实现代码,需要的朋友可以参考下

这个是脚本代码[保存为etime.bat放在当前路径下即可:

 代码如下:

:etime <begin_time> <end_time> <return>
rem 所测试任务的执行时间不超过1天 // 骨瘦如柴版 
setlocal&set be=%~1:%~2&set cc=(%%d-%%a)*360000+(1%%e-1%%b)*6000+1%%f-1%%c&set dy=-8640000
for /f "delims=: tokens=1-6" %%a in ("%be:.=%")do endlocal&set/a %3=%cc%,%3+=%dy%*("%3>>31")&exit/b

  

计算两个时间点差的函数批处理etime

今天兴趣大法思考了好多bat的问题,以至于通宵
在论坛逛看到有个求时间差的"函数"被打搅调用地方不少(大都是测试代码执行效率的)

 代码如下:

:time0
::计算时间差(封装)
@echo off&setlocal&set /a n=0&rem code 随风 @bbs.bathome.cn
for /f "tokens=1-8 delims=.: " %%a in ("%~1:%~2") do (
set /a n+=10%%a%%100*360000+10%%b%%100*6000+10%%c%%100*100+10%%d%%100
set /a n-=10%%e%%100*360000+10%%f%%100*6000+10%%g%%100*100+10%%h%%100)
set /a s=n/360000,n=n%%360000,f=n/6000,n=n%%6000,m=n/100,n=n%%100
set "ok=%s% 小时 %f% 分钟 %m% 秒 %n% 毫秒"
endlocal&set %~3=%ok:-=%&goto :EOF

这个代码的算法是统一找时间点凌晨0:00:00.00然后计算任何一个时间点到凌晨的时间差(单位跑秒)
然后任意两个时间点求时间差就是他们相对凌晨时间点的时间数的差
对09这样的非法8进制数的处理用到了一些技巧,还有两个时间参数不分先后顺序,可全可点,
但是这个代码一行是可以省去的(既然是常被人掉用自然体积越小越好):

代码如下:

@echo off&setlocal&set/a n=0&set "s=+:%~1^&echo -:%~2"
for /f "tokens=1-5 delims=.:" %%a in ('echo %s%') do (rem code 随风 @bbs.bathome.cn
set/a n%%a=10%%b%%100*360000+10%%c%%100*6000+10%%d%%100*100+10%%e%%100)
set /a s=n/360000,n=n%%360000,f=n/6000,n=n%%6000,m=n/100,n=n%%100
set "ok=%s% 小时 %f% 分钟 %m% 秒 %n% 毫秒"
endlocal&(if %3. equ . (echo %ok:-=%) else set %~3=%ok:-=%)&exit/b

再研究下,有更简短的版本
这个代码是我在cn-dos写过的,今天再优化了下更简短
代码的算法深入一层:
用hmsw(各字母代表一个两位数字)表示标准时间,单位是0.01秒,这里我们称为:厘秒
具体可参考:百科时间单位
我们记他到凌晨的相对时间数为Tx
Tx=hmsw时间点-0:00:00.00,某固定时间点的Tx=h*3600*100+m*60*100+100*s+w
hmsw(单位是厘秒) 如果Tx的8个数字按10进制数表示的时间数转换成hmsw(单位0.01秒)就是hmsw跑秒数
hmsw(跑秒数)只需要把时间字符串中的冒号和小数点删除,就是跑秒数。
hmsw=w+100*s+10000*m+1000000*h
hmsw-Tx=640000*h+4000*m
所以Tx=hmsw-(640000*h+4000*m)=hmsw-4000*(160*h+m)
那么Tx_2-Tx_1=hmsw_2-hmsw_1-4000*(160*(h_2-h_1)+(m_2-m_1))
两个时间之间有了这样的关系我们就好办了。
再解决对与09这样的非法8进制数我们给他们每个前面加上1就可以保证是十进制数又能保证差值不变
对于非同一天的时间(这种情况较少,除非你在接近0晨时调用)我们把用8640000-去替换负号,再用set/a赋值
就是下面代码用到的算法
Tx_2-Tx_1=hmsw_2-hmsw_1-4000*(160*(1h_2-1h_1)+(1m_2-1m_1))

代码如下:

rem  兼容时间点跨天的情行,时间格式00:00:00.00 或者 0:00:00.00 皆可
:_difftime <Begin_Time> <End_Time> [ret] //返回两个时间点的差值(单位0.01秒)
Setlocal enabledelayedexpansion&set b=0%1&set e=0%2&set c=1!e:~-11!-1!b:~-11!&set c=!c::=!
set/a c=%c:.=%-4000*(160*(1%e:~-11,-9%-1%b:~-11,-9%)+1%e:~-8,-6%-1%b:~-8,-6%)
endlocal & (if %3.==. (echo %c:-=8640000-%) else set/a %3=%c:-=8640000-%)&exit/b

给difftime前面加上_是为了表明不是临时写的子过程也为了以后连接库函数标签的唯一性,最后一个else如果有多个语句可以加括号,如:

(if %3.==. (echo %c:-=8640000-%) else (set/a %3=%c:-=8640000-%))&exit/b

// 题外话:
对于子过程,若启用了变量延迟,原则上三行都可以写完,尽量写紧凑些(因为没人读),但是对于算法,
思路性的东西要能舍得笔墨,越详细越好,我发现即使你的代码写得再好,不会有人全搬,都会小修改,
你自己初写代码时不可能考虑到所有人使用的具体情况,自然没人愿意很详细看你的代码,倒是你的思路为
别人提供了一个方法,在此意义上函数库的作用起到方法库的作用

 

出处:https://www.jb51.net/article/53014.htm

=======================================================================================

上面都没有提供调用方法,我这里提供一个简单的调用方式:

call :_difftime %t1% %t2% t3

至于Call的用法,就自己度娘吧!~

我也给出一个简单的调用方式:

@echo off

set t1=999
call :test2 12321 t4
echo t1=%t1%
echo t4=%t4%
goto :eof

:test2 <var> <ret> //接收%1的值并修改后设置到变量t1中,并返回t1的值
Setlocal enabledelayedexpansion
echo received data = %1
set/a t1=%1+9
endlocal&(if not %2.==. (set %2=%t1%))&exit/b

如果不是数值计算,在set的时候可以不使用/a参数

=======================================================================

 今天在网上看使用bat计算大数的时候,发现一个,并且还提供了计算时差的,

参考出处:http://www.bathome.net/viewthread.php?tid=3372

http://bbs.bathome.net/thread-4701-1-1.html

拿过来研究研究,这里参数最少2个,最多3个,需要自己仔细辨认,如下代码

::计算时差函数
:etime [return]  // By plp626 On 09-7-20
setlocal enabledelayedexpansion&set be=%~1;%~2&set be=!be::=;1!&set n=
for %%a in (%be:.=%)do set/a n+=1&set t!n!=%%a
set/a n=((t4-t1)*60+t5-t2)*6000+t6-t3,s=n/100,w=n%%100/10,f=n%%100%%10
endlocal&(if %3.==. (echo %s%.%w%%f%) else set %3=%n:-=%)&exit/b

 

根据上面的代码,我稍微调整了下代码,如下:

1)支持时间格式00:00:00.00 或者 0:00:00.00 皆可

2)可只指定开始时间,结束时间默认为当前时间

::计算时差绝对值函数,返回值单位:厘秒(centisecond)
:etime <time1> [time2] [return]  // By jack 20210901:<>为必选参数,[]为可选参数
setlocal enabledelayedexpansion&set bt=0%~1&set et=0%~2&(if %~2.==. set et=!et!%time%)
set be=1%bt:~-11%;1%et:~-11%&set be=!be::=;1!&set n=0
for %%a in (%be:.=%)do set/a n+=1&set t!n!=%%a
set/a n=((t4-t1)*60+t5-t2)*6000+t6-t3 &(if !n! lss 0 set/a n*=-1)&set/a s=n/100,w=n%%100/10,f=n%%100%%10
endlocal&(if %3.==. (echo %s%.%w%%f%s^(%n%cs^)) else set %3=%n%)&exit/b

 

posted on 2020-12-16 16:35  jack_Meng  阅读(2161)  评论(0编辑  收藏  举报

导航