找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 41247|回复: 13

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

[复制链接]
发表于 2009-5-30 05:29:00 | 显示全部楼层 |阅读模式
本帖最后由 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 编辑 ]

评分

参与人数 3PB +52 技术 +2 收起 理由
523066680 + 12 + 1 感谢分享
pusofalse + 20 + 1 学习了!
Batcher + 20 感谢分享

查看全部评分

发表于 2009-5-30 06:50:55 | 显示全部楼层
不愧是喜欢数学的,算法看的我头晕^_^
 楼主| 发表于 2009-5-30 07:57:12 | 显示全部楼层
改了不少笔误,现在可以了
发表于 2009-10-6 19:50:04 | 显示全部楼层
bug

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

结果:
1.21
发表于 2009-10-6 22:09:52 | 显示全部楼层
我也来一个:
  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 编辑 ]
 楼主| 发表于 2009-10-7 02:50:34 | 显示全部楼层
原帖由 netbenton 于 2009-10-6 19:50 发表
bug

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

结果:
1.21



已修改,少了俩零
发表于 2009-10-7 09:26:21 | 显示全部楼层
对09这样的非法8进制数的处理用到了一些技巧,还有两个时间参数不分先后顺序,可可点,

笔误
发表于 2009-10-7 17:28:15 | 显示全部楼层
小bug
call :etime 23:58:11.10 00:11:12.10

结果:
-85619.00
 楼主| 发表于 2009-10-7 17:56:05 | 显示全部楼层
原帖由 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 编辑 ]
发表于 2009-10-7 17:57:47 | 显示全部楼层
蛋黄里挖骨头,开个玩笑:
昨晚的23:00 到今晚的 22:00

[ 本帖最后由 523066680 于 2009-10-7 17:59 编辑 ]
 楼主| 发表于 2009-10-7 18:24:17 | 显示全部楼层
原帖由 523066680 于 2009-10-7 17:57 发表
蛋黄里挖骨头,开个玩笑:
昨晚的23:00 到今晚的 22:00


已经考虑,代码已经完善

[ 本帖最后由 plp626 于 2009-10-10 12:00 编辑 ]
发表于 2009-10-7 19:42:40 | 显示全部楼层
对netbenton的代码赞一个,思路很妙
%time%小时前没有0
对a,b赋值时前面要加0才行哦
发表于 2009-10-7 21:38:01 | 显示全部楼层
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 编辑 ]
 楼主| 发表于 2009-10-10 12:24:21 | 显示全部楼层
从命令行运行复制下来的

用这个看算法一目了然:


>> 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 编辑 ]

评分

参与人数 2PB +30 技术 +2 收起 理由
netbenton + 30 + 1 用得巧妙
zqz0012005 + 1 果然“骨瘦如柴”

查看全部评分

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-16 23:21 , Processed in 0.023181 second(s), 8 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表