Windows命令提示符计算错误

时间:2013-04-16 13:19:30

标签: command-line windows-8

我使用的是Windows 8,并希望将bat文件写入记录任务运行的时间。所以我写这个:

@echo off
setlocal

SET STARTTIME=%TIME%

.....do sth. smart.....

SET ENDTIME=%TIME%
SET /A DURATION=%ENDTIME%-%STARTTIME%
SET /A DURATIONH=%DURATION%/360000
SET /A DURATIONM=(%DURATION%-%DURATIONH%*360000)/6000
SET /A DURATIONS=(%DURATION%-%DURATIONH%*360000-%DURATIONM%*6000)/100
SET /A DURATIONHS=(%DURATION%-%DURATIONH%*360000-%DURATIONM%*6000-%DURATIONS%*100)
if %DURATIONH% LSS 10 SET DURATIONH=0%DURATIONH%
if %DURATIONM% LSS 10 SET DURATIONM=0%DURATIONM%
if %DURATIONS% LSS 10 SET DURATIONS=0%DURATIONS%
if %DURATIONHS% LSS 10 SET DURATIONHS=0%DURATIONHS%
echo ------------------------------------------------------------------------------------------
echo task start time : %STARTTIME%
echo task end time : %ENDTIME%
echo task end in time : %DURATIONH%:%DURATIONM%:%DURATIONS%,%DURATIONHS%
echo ------------------------------------------------------------------------------------------

endlocal

C:
PAUSE

我运行它并且它通过但是日志时间是(f.e。):

task start time 14:35:36,24
task end time 14:39:43,55
task end in time : 00:00:00,14

并且还显示错误运算符:

SET /A DURATION=%ENDTIME%-%STARTTIME%
你可以帮帮我吗?我正在搜索这个问题,但我找不到什么可以解决我的问题

感谢您的帮助

3 个答案:

答案 0 :(得分:1)

你需要将你的时间轴转换为秒 - 这并不容易。

幸运的是,因为你正在使用一个24小时制 - 这使得它变得更容易,但编写数学增强功能的程序员决定用一些奇怪的理由来定义一个带有前导零的字符串作为OCTAL所以'08'或'子串中的09'将生成错误,因为08/09不是有效的八进制数...

SO - 克服这种情况的标准方法是在字符串前面串起一个'1'然后减去100。

接下来的复杂情况是你使用,作为小数分隔符 - 这就解决了我们只能使用INTEGER数学的问题......

幸运的是,之前见过这样的事情。解决方案是 UGLY + ,但它确实有效。

@ECHO OFF
SETLOCAL
:: simply setting the start and end time to your posted values...
SET starttime=14:35:36,24
SET endtime=14:39:43,55
:: Here are some other value-pairs of interest (1) - elapsed = 8399,04
:: SET starttime=14:35:36,24
:: SET endtime=14:35:35,28
:: Here are some other value-pairs of interest (2) - elapsed = 0,04
:: SET starttime=14:35:36,24
:: SET endtime=14:35:36,28
:: Here are some other value-pairs of interest (3) - elapsed = 0,31
:: SET starttime=14:35:36,24
:: SET endtime=14:35:36,55
:: Here are some other value-pairs of interest (4) - elapsed = 7,31
:: SET starttime=14:35:36,24
:: SET endtime=14:35:43,55
CALL :CONVERT startsecs "%starttime%"
CALL :CONVERT endsecs "%endtime%"
ECHO SET /a elapsed=%endsecs% - %startsecs%
SET /a elapsed=endsecs - startsecs
IF %elapsed% lss 0 SET /a elapsed=%elapsed% + (24*360000)
IF %elapsed% lss 100 (IF %elapsed% lss 10 (SET elapsed=00%elapsed%) ELSE (SET elapsed=0%elapsed%))
ECHO elapsed TIME : %elapsed:~0,-2%,%elapsed:~-2%
::
GOTO :eof
en
:CONVERT
SET hundredths=%~2
SET /a %1=((((((1%hundredths:~0,2%) * 60) + 1%hundredths:~3,2%) * 60) + 1%hundredths:~6,2%) * 100) + 1%hundredths:~9,2% - 36610100
SET /a hundredths=((((((1%hundredths:~0,2% - 100) * 60) + 1%hundredths:~3,2% - 100) * 60) + 1%hundredths:~6,2% - 100) * 100) + 1%hundredths:~9,2% - 100
ECHO %2 %hundredths%
GOTO :eof

为了便于测试,我已经包含了一些价值对,以及使用您的约定对已用时间的评论。

排名第一的出租车是处理逗号。逗号是默认分隔符,因此简单的方法是引用传递给:convert例程的时间参数。第一个参数是放置计算结果的变量的名称。

在例程中,变量hundredths设置为第二个参数(引用的时间字符串)和删除的引号(%~2

然后完成计算。暂时跳过SET /a %1=...行,所需的计算显示在随后的set hundredths=行中。将所提供时间的每个子字符串用前导1字符串,减去100并依次乘以60,60,100来计算从午夜开始的百分之几秒。然后简单地显示计算结果。

我包含了完整的计算,因为它是分配给%1的简化计算的祖先。神奇的数字36610100只是八进制保护咒语计算中常量的总和。

完整版的计算可以被注释掉,因为它不参与转换机制。最好删除结果的ECHO - 只是在评估期间显示结果。

一旦开始和结束时间转换为百分之一 - 从午夜开始,减去以获得经过的时间。如果结果小于100,则决定要添加多少个前导零,并显示“好像来自PIC 9的V99”

答案 1 :(得分:0)

您无法减去时间字符串,您需要先将%STARTTIME%%ENDTIME%转换为秒,然后再计算%DURATION%。只是给你一个提示:

set STARTTIME=%TIME%
set /A STARTTIME=%STARTTIME:~0,2%*3600+%STARTTIME:~3,2%*60+%STARTTIME:~6,2%

答案 2 :(得分:0)

试试这个,它计算24小时(也是午夜的1倍):

@echo off&setlocal
for /f "tokens=1-3delims=:," %%a in ("%time%") do (
    set /a "shr=(1%%a)-100"
    set /a "smin=(1%%b)-100"
    set /a "ssec=(1%%c)-100"
)
set /a startsec=%shr%*3600+%smin%*60+%ssec%
echo start at sec: %startsec%

ping -n 20 localhost >nul &rem .....do sth. smart.....

for /f "tokens=1-3delims=:," %%a in ("%time%") do (
    set /a "ehr=(1%%a)-100"
    set /a "emin=(1%%b)-100"
    set /a "esec=(1%%c)-100"
)
set /a endsec=%ehr%*3600+%emin%*60+%esec%
echo stop  at sec: %endsec%
if %startsec% leq %endsec% (set /a diffsec=%endsec%-%startsec%) else set /a diffsec=%endsec%+86400-%startsec%
echo running %diffsec% second(s^)
set /a ehr=(%diffsec%/3600)
set /a emin=(%diffsec%-(%ehr%*3600))/60
set /a esec=(%diffsec%-(%ehr%*3600)-(%emin%*60))
echo running for %ehr%h %emin%min %esec%sec