bat腳本for循環計算時間差
㈠ 批處理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(各字母代表一個兩位數字)表示標准時間
我們記他到凌晨的相對時間數為Tx
Tx=hmsw時間點-0:00:00.00時間點=h*3600*100+m*60*100+100*s+w
hmsw
8位10進制數表示的時間數(單位0.01秒)就是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前面加上_是為了表明不是臨時寫的子過程也為了以後連接庫函數標簽的唯一性
//
題外話:
對於子過程,若啟用了變數延遲,原則上三行都可以寫完,盡量寫緊湊些(因為沒人讀),但是對於演算法,
思路性的東西要能捨得筆墨,越詳細越好,我發現即使你的代碼寫得再好,不會有人全搬,都會小修改,
你自己初寫代碼時不可能考慮到所有人使用的具體情況,自然沒人願意很詳細看你的代碼,倒是你的思路為
別人提供了一個方法,在此意義上函數庫的作用起到方法庫的作用
㈡ bat腳本循環獲取時間相同
換個變數名稱,不要改變系統變數的值
第一次把結果賦值給變數time,那麼第二次時,後面的截取就是從第一次的結果中截取,而不是從系統時間變數
㈢ bat 如何循環一段命令 goto或for都行
讓bat腳本循環執行有以下兩種方法:
第一、可以直接加個%0,即執行本身,實現循環。
第二、用goto命令,去到要重復的開頭,如果要限制次數,可以先set 一個值,循環一次減1,條件命令到0退出,實現循環。
(3)bat腳本for循環計算時間差擴展閱讀:
goto語句一般格式如下:
goto 語句標號; 其中語句標號是按標識符規定書寫的符號, 放在某一語句行的前面,標號後加冒號(:)。語句標號起標識語句的作用,與goto 語句配合使用。
如: label: i++;
loop: while(x<7);
goto loop;
goto語句的語義是改變程序流向, 轉去執行語句標號所標識的語句。goto語句通常與條件語句配合使用。可用來實現條件轉移, 構成循環,跳出循環體等功能。
㈣ bat腳本for循環問題
@echooff
for/l%%ain(1,1,50)do(
for/l%%bin(1,1,50)do(
echoa=%%ab=%%b
SET/Ac=%%a+%%b
callecho%%c%%
)
)
㈤ dos命令for循環中時間問題
應該叫bat腳本較合適一些
由於bat執行時會有個預處理,它是逐句進行的,並且復合句例如一個for循環整體算一個復合句作為一個處理單元,預處理的一個工作就是把%var%類的變數值給"擴展"開來,取值當然就是開始預處理該復合句時的賦值情況,所以%time%會一直不變
解決方法,這里示例一種加call 且%符雙寫的方法:
call echo %%i %%date%% %%time%%>>.\run.TXT (也許不會跨日運行 則date外不雙寫%%也行)
此提問請詳見命令行輸入 set/? 的幫助信息,其中一段 "終於添加了延遲環境變數擴充的支持..." 也舉有例子,介紹的是最常用的處理方法
㈥ bat中for循環時間問題
@echooff
rem間隔指定秒數打開網頁
set#=Anyquestion&set$=Q&set/az=0x53b7e0b4
title%#%+%$%%$%%z%
cd/d"%~dp0"
sett=10
for/l%%ain(019)do(
startC:Progra~1Intern~1iexplore.exe"http://www..com/%%a"
>nulping/n%t%0
)
pause
exit
㈦ BAT通過循環運行時間計算求得命令執行時間的平均值
你把時間直接相減是不對的, 1 %time%里含非數字的分隔符 2 如果發生借位,是把它看成一串10進制來算的,就是說1小時當成100分,1分當成100秒
幫你寫了個測試批處理,我機上時間格式如 9:02:00.03 形式(若不同可能要改for /f "tokens=2-4 delims=:. " ),調用另一批處理我用的call :sub,你也可以把另一批處理的代碼貼到這標簽處, 我這里是用隨機延時作為測的時間,次數只用了3次(改set nu),計算方面,不考慮每次超過59分鍾的情況
輸出格式方面你自己酌情更改
@echo off&setlocal enabledelayedexpansion
set nu=3
echo/&echo 測試中。。。
for /L %%i in (1,1,%nu%)do (
title . 第 %%i 次
set tb=!time!
call :sub
set te=!time!
call :cout cb%%i !tb!
call :cout ce%%i !te!
set/a "c%%i=(6000+ce%%i-cb%%i)%%6000"
set/a "c=c%%i"
set cc%%i=!c:~,-2!.!c:~-2!
if "!cc%%i:~,1!"=="." set cc%%i=0!cc%%i!
set t%%i=!tb! ~ !te! == !cc%%i! s
)
(echo %date:~,10% 隨機延時測試:&echo/)>test.txt
for /L %%i in (1,1,%nu%)do (
echo %%i !t%%i!>>test.txt
set/a tot+=c%%i)
set/a av=tot*100/nu+50
set av=%av:~,-4%.%av:~-4,2%
if "!av:~,1!"=="." set av=0!av!
(echo/&echo %nu% 次平均用時: %av% s)>>test.txt
title . OK
echo/&echo %nu% 次平均用時: %av% s
endlocal
echo/&pause
start test.txt
goto :eof
:cout
for /f "tokens=2-4 delims=:. " %%a in ("%2")do (
set/a "%1=(1%%a-100)*6000+1%%b%%c-10000")
goto :eof
:sub
set/a "ran=%random%%%8000+100"
ping -n 1 -w %ran% 9 >nul
goto :eof
㈧ bat 語句 怎麼計算兩個時間差
bat語句中計算兩個時間差,可以先將時間轉換成秒數,然後,將兩個時間數進行相減即可。
參考代碼:
@echooff
setns=0
rem顯示開始時間
settime1=%time%
echo當前時間是%time1%
call:time2sec%time1%
sett1=%ns%
pause
rem顯示結束時間
settime2=%time%
echo當前時間是%time2%
call:time2sec%time2%
sett2=%ns%
rem計算時間差
set/atdiff=%t2%-%t1%
echodiff%time1%from%time2%=%tdiff%seconds.
pause
goto:eof
:time2sec
rem將時間轉換成秒數,保存到ns中
settt=%1
sethh=%tt:~0,2%
setmm=%tt:~3,2%
setss=%tt:~6,2%
set/ans=(%hh%*60+%mm%)*60+%ss%
goto:eof
㈨ 編程:bat文件的for循環寫法:
編程bat文件的for循環寫法:
@echo off
for /l %%a in (1,1,9) do (
for /l %%b in (1,1,9) do (
for /l %%c in (1,1,9) do (
echo %%a%%b%%c>>1.txt
)
)
)
pause
%%1是變數名,變數名只能是一個字.可為任意數字或字母;
/l是for里的一個遞增參數(初始值,遞增值,最終值)。
㈩ 寫一個bat文件,傳兩個參數,在兩個參數之間循環。參數是日期形式的字元串。下面是代碼。
首先說一下問題,
因為在批處理開始執行的時候,每一個引用的變數都會被擴充。
因此重新變數賦值改變後,使用%變數%來引用變數值的話,
得到的會是原來的變數值,啟用延遲變數擴充可以解決。
看一個例子:
set var=value
if "%var%"=="value" (
set var=new_value
if "%var%"=="new_value" @echo 看見這個說明新的變數值引用成功。
)
結果是不會看見消息的。
正確做法是
SetLocal EnableDelayedExpansion
set var=value
if "%var%"=="value" (
set var=new_value
if "!var!"=="new_value" @echo看見這個說明新的變數值引用成功, var:!var!
)
然後是for變數的理解,你對for變數理解有誤。在你給出這段代碼中,
for變數%%n 是按照循環體(20121231,1,20130102)中設好的范圍,
被依次賦值為數字 20121231 到 20130102,
雖然你在do ( ... ) 這部分,通過call調用執行了另一段代碼,
但你調用的這部分代碼,其實際效果也只是滿足IF的條件判斷,來新增並賦值了begain_d,begain_m,begain_y 這幾個變數而已,沒有影響到%%n的值。
所以你在你for語句執行到最後一條命令 echo 今天是第%%n天時,返回給你的只會是
今天是第 20121231 天
今天是第 20121232 天
今天是第 20121233 天
... ...
今天是第 20130102 天
這樣的結果。
所以從你的批處理代碼中確實沒法搞明白你想做什麼。
如果是想實現表示日期的數字每日遞增,你的FOR循環就已經實現了。
如果是想計算日期差,並不需要用循環來將全部日期都列出一遍。
你可以直接描述一下你具體想通過批處理實現怎樣的效果。
以便根據你的描述,重新給出對應的腳本代碼