Board logo

标题: [数值计算] 计算两个时间点差的函数批处理etime [打印本页]

作者: plp626    时间: 2009-5-30 05:29     标题: 计算两个时间点差的函数批处理etime

本帖最后由 plp626 于 2011-5-19 10:50 编辑

上面的那个算法复杂,代码实现也不是很精简,下面的代码皆用如下算法
etime=([h2,m2,swf2]-[h1,m1,swf1])*[360000;6000;1]  // 这里的*表示两个向量的矩阵乘法,如果还不是很理解请看14楼

思考了下跨天时间的情行:

首先因为没有日期参与运算,参数必须规定顺序【否则会出现混乱】,比如规定开始时间在前,结束时间在后,
然后我们分析两个时间点不在一天的情行,我们使用这个代码【这个代码也是批处理写的】
只为了测试批处理任务的运行时间,或者借助批处理测试一些任务的花费时间,这一点勿容置疑
那么有什么批处理的运行时间会超过一天?没有,如果有,那么一定是毫无意义的批处理!//关于此,后面还有个偷工减料的代码
那么在保证开始时间在前,结束时间在后,出现跨天的两个时间点,虽然时间差是负数,但是只要给这个负数
再加上1天的时间就能正确表示这两个时间点的差,所以就出现了 -8640000*("c>>31") 这样的代码

以下代码经过本人多次测试,皆兼容跨天情形,只要所执行的任务不超过时限,都能正确计算!大家根据个人喜好选择代码风格
  1. :: etime -- 求%1--%2 的时间差,时间跨度在24小时内可调用之;
  2. :etime <beginTimeVar> <endTimeVar> <retVar> // code by plp626
  3. if "!OS!" neq "%OS%" (echo %0 需要再开启变量延迟后调用&goto:eof)
  4. Set/a "%3=(!%2:~,2!-!%1:~,2!)*360000+(1!%2:~3,2!-1!%1:~3,2!)*6000+1!%2:~-5,2!!%2:~-2!-1!%1:~-5,2!!%1:~-2!,%3+=-8640000*(%3>>31)"&goto:eof
复制代码
如果仅是用于测试一般的bat代码运行时间,推荐:etM
  1. :: etM --求 %1--%2 时间差,时间跨度在1分钟内可调用之;用于测试一般bat运行时间
  2. :etM <beginTimeVar> <endTimeVar> <retVar> // code by plp626
  3. setlocal enabledelayedexpansion
  4. set/a "c=1!%2:~-5,2!!%2:~-2!-1!%1:~-5,2!!%1:~-2!,c+=-6000*(c>>31)"
  5. (endlocal&if %3.==. (echo %c%) else set %3=%c%)&goto:eof
复制代码
附注:如何读子过程上的参数标签选项

比如说
:etime <begin_time> <end_time> [return]
:etime 就是子过程的标签
后面的 begin_time end_time 是对参数要求的描述,即第一个参数是开始时间,第二个参数是结束时间
return 就是接收返回值的参数,//用return单词,它只是为了可读性
<> 表示该参数不能缺省(必选的意思)
[]表示该参数可以缺省

[ 本帖最后由 plp626 于 2009-10-10 13:17 编辑 ]
作者: 随风    时间: 2009-5-30 06:50

不愧是喜欢数学的,算法看的我头晕^_^
作者: plp626    时间: 2009-5-30 07:57

改了不少笔误,现在可以了
作者: netbenton    时间: 2009-10-6 19:50

bug

call :etime 19:13:11.10 19:15:11.11

结果:
1.21
作者: netbenton    时间: 2009-10-6 22:09

我也来一个:
  1. @echo off
  2. rem 计算两点的时间差:etime=time2-time1
  3. rem 保持24小时时间格式: hh:mm:ss:vv
  4. call :etime 23:21:03:09 01:30:23:01
  5. goto :eof
  6. ::前面为演示用
  7. :etime <begin_time> <end_time> [return]
  8. setlocal enabledelayedexpansion
  9. set a=%~1
  10. set b=%~2
  11. set c=24:60:60:00
  12. set z=1&set e=
  13. for /l %%a in (2,3,11)do (
  14.         set/a v=2!b:~-%%a,2!-1!a:~-%%a,2!-1+z,k=!c:~-%%a,2!,j=k+v
  15.         set z=!v:~-3,-2!
  16.         set/a j=j-z*k
  17.         set e=:!j:~-2!!e!
  18. )
  19. endlocal&(if %3.==. (echo %e:~1%) else set %3=%e:~1%)&exit/b
复制代码

[ 本帖最后由 netbenton 于 2009-10-6 22:16 编辑 ]
作者: plp626    时间: 2009-10-7 02:50

原帖由 netbenton 于 2009-10-6 19:50 发表
bug

call :etime 19:13:11.10 19:15:11.11

结果:
1.21



已修改,少了俩零
作者: Batcher    时间: 2009-10-7 09:26

对09这样的非法8进制数的处理用到了一些技巧,还有两个时间参数不分先后顺序,可可点,

笔误
作者: netbenton    时间: 2009-10-7 17:28

小bug
call :etime 23:58:11.10 00:11:12.10

结果:
-85619.00
作者: plp626    时间: 2009-10-7 17:56

原帖由 netbenton 于 2009-10-7 17:28 发表
小bug
call :etime 23:58:11.10 00:11:12.10

结果:
-85619.00


这个不算bug,这个算法专门为cmd下特殊的time值而设计,对于 00:11:12.10 这种时间格式
cmd下没有这样的%time%值

0点11分12秒10在time下的值其实是
" 0:11:12.10“

[ 本帖最后由 plp626 于 2009-10-10 12:00 编辑 ]
作者: 523066680    时间: 2009-10-7 17:57

蛋黄里挖骨头,开个玩笑:
昨晚的23:00 到今晚的 22:00

[ 本帖最后由 523066680 于 2009-10-7 17:59 编辑 ]
作者: plp626    时间: 2009-10-7 18:24

原帖由 523066680 于 2009-10-7 17:57 发表
蛋黄里挖骨头,开个玩笑:
昨晚的23:00 到今晚的 22:00


已经考虑,代码已经完善

[ 本帖最后由 plp626 于 2009-10-10 12:00 编辑 ]
作者: zhouyongjun    时间: 2009-10-7 19:42

对netbenton的代码赞一个,思路很妙
%time%小时前没有0
对a,b赋值时前面要加0才行哦
作者: netbenton    时间: 2009-10-7 21:38

re 12 楼 zhouyongjun
真够细心,我改。:
  1. :etime <begin_time> <end_time> [return]  
  2. setlocal enabledelayedexpansion
  3. set a=0%~1
  4. set b=0%~2
  5. set c=24:60:60:00
  6. set z=1
  7. for /l %%a in (2,3,11)do (
  8.         set/a v=2!b:~-%%a,2!-1!a:~-%%a,2!-1+z,k=!c:~-%%a,2!,j=k+v
  9.         set z=!v:~-3,-2!
  10.         set/a j=j-z*k
  11.         set e=:!j:~-2!!e!
  12. )
  13. endlocal&(if %3.==. (echo %e:~1%) else set %3=%e:~1%)&exit/b
复制代码

[ 本帖最后由 netbenton 于 2009-10-7 21:39 编辑 ]
作者: plp626    时间: 2009-10-10 12:24

从命令行运行复制下来的

用这个看算法一目了然:


>> set t1=%time%
>> pause
请按任意键继续. . .

>> set t2=%time%
>> etime %t1% %t2% 时间差

>> rem 所测试任务的执行时间不超过1天 // 骨瘦如柴版
>> setlocal & set be=12:50:09.40:12:50:27.78  & 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 ("12:50:0940:12:50:2778") do endlocal & set/a 时间差=(%d-%a)*360000+(1%e-1%b)*6000
+1%f-1%c,时间差+=-8640000*("时间差>>31")  & exit/b

>> endlocal & set/a 时间差=(12-12)*360000+(150-150)*6000+12778-10940,时间差+=-8640000*("时间差>>31")  & exit/b
>> echo %时间差%
1838


这个是脚本代码[保存为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


[ 本帖最后由 plp626 于 2009-10-10 12:49 编辑 ]




欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2