1.

Solve : VBScripting?

Answer»

Win XP SP.3

I'm using the following VBScript as part of a batch script to return the time in HOURS Mins Secs. I haven't been able to find instructions on adding M/Secs to the script, is it possible to return m/secs in such a script?

Code: [Select](
echo ThisTime=Time
echo WScript.Echo Hour(ThisTime^) ^&" "^& ^
Minute(ThisTime^) ^&" "^& ^
Second(ThisTime^)
)Unless you are building a .wsf or .wsc file, you cannot mix languages within the same script. You can however run an EXTERNAL VBScript from a batch file and return the values.

VBScript:
Code: [Select] WScript.Echo Hour(Time) & " " & Minute(Time) & " " & Second(Time)

Batch Code:
Code: [Select]@echo off
for /f "tokens=1-3" %%i in ('cscript //nologo time.vbs') do (
echo Hour: %%i
echo Minute: %%j
echo Second: %%k
)

Save the first script with a vbs extension, the second with a bat extension. The name of the vbs script must match the reference in the batch file. I used time.vbs but anything is OK as long as they match.

Run the batch file from the command prompt. Both scripts should be in the same directory unless you add path information.

Quote from: Valerie on May 22, 2010, 04:01:49 AM

Win XP SP.3

I'm using the following VBScript as part of a batch script to return the time in Hours Mins Secs.


C:\>time /t
08:48 AM

C:\>echo %TIME%
8:48:54.84

C:\>You can get time to seconds and hundredths of 1 second (i.e. with RESOLUTION of 10 msec) by using the VBscript timer function.

Code: [Select]'timer returns seconds since midnight local time
Seconds=Timer
Hours=Int(Seconds/3600)
Minsecs=Seconds-(Hours * 3600)
Minutes=Int(Minsecs/60)
Seconds=Minsecs-(Minutes*60)
WholeSeconds=Int(Seconds)
PartSeconds=Seconds-WholeSeconds
Milliseconds=Int(PartSeconds*1000)

If Hours<10 Then
TimeString="0" & Hours
Else
Timestring=Hours
End If

TimeString=TimeString & ":"

If Minutes<10 Then
TimeString=TimeString & "0" & Minutes
Else
TimeString=TimeString & Minutes
End If

TimeString=TimeString & ":"

If WholeSeconds<10 Then
TimeString=TimeString & "0" & WholeSeconds
Else
TimeString=TimeString & WholeSeconds
End If

TimeString=TimeString & "."

If milliseconds<100 Then
MsecString="0" & Milliseconds
Else
MsecString=Milliseconds
End If

If milliseconds<10 Then
MsecString="0" & MSecString
End If

TimeString=TimeString & MsecString
wscript.echo TimeString

Thank you all.

S.T. - Timer is exactly what I was looking for and would have used instead of Time had I known it existed. Thanks.

V.Quote from: Valerie on May 22, 2010, 06:45:43 PM
Thank you all.

S.T. - Timer is exactly what I was looking for and would have used instead of Time had I known it existed. Thanks.

V.

Details in the Windows Scripting Host help file, script56.chm. Mine is in C:\Windows\Help, if you don't have it you can get it here:

http://www.microsoft.com/downloads/details.aspx?familyid=01592c48-207d-4be1-8a76-1c4099d7bbb9&displaylang=en

It is a chm (compiled help format file) so you just double click on it. It also covers Jscript.

Note that the script I wrote above, actually shows 3 places of decimals for the parts of seconds, i.e. down to milliseconds, but I read somewhere that the 3rd digit is not to be relied upon. In any case there will be system overheads involved in using Timer from VBScript. especially if the script is called from a batch file.
I'm experimenting with Timer and Eval using the script below but get confusing results from Eval. The inputs have only two decimal places yet eval produces many more. Any explanation please?

Code: [Select]@echo off
cls
setlocal enabledelayedexpansion

:: Create .vbs file for use in :getsecs
set vbs=%temp%\vbs.vbs
echo wscript.echo timer>%vbs%

:: Create .vbs file for use in :calc
set evaluate=%temp%\evaluate.vbs
echo wscript.echo eval(wscript.arguments(0))>%evaluate%

call :getsecs startsecs

pause
cls

call :getsecs stopsecs

: Calculate elapsed seconds
set c=!stopsecs!-!startsecs!
call :calc elsecs

echo Stop secs=!stopsecs!
echo Start secs=!startsecs!
echo.
echo Elapsed secs=!elsecs!

exit /b

:calc
setlocal
for /f %%1 in ('cscript //nologo evaluate.vbs "%c%"') do (
set result=%%1
)
endlocal&set %1=%result%&goto :eof

:getsecs
setlocal
for /f "tokens=*" %%1 in ('cscript //nologo %vbs%') do (
set secs=%%1
)
endlocal&set %1=%secs%&goto :eof

Sample outputs are:
Quote

Stop secs=50975.08
Start secs=50924.97

Elapsed secs=50.1100000000006

and

Quote

Stop secs=51174.05
Start secs=51088.63

Elapsed secs=85.4200000000055
Floating point error.

Actually, I might point out that your script didn't work for me until made a change to this line:

Code: [Select]for /f %%1 in ('cscript //nologo evaluate.vbs "%c%"') do (
to read
Code: [Select]for /f %%1 in ('cscript //nologo %evaluate% "%c%"') do (

If it works for you it's probably because you have evaluate.vbs available- I imagine your intention was to create the temp file and use that variable to refer to it though

Anyway, back to the floating point error ISSUE. By default VBScript represents numbers using a single precision floating point value. I'll spare too many details, but due to the way that floating point numbers are implemented some operations introduce slight errors in calculation. This is one of those instances.

One way of circumventing this particular issue is to force the script to handle the numbers as another Variant subtype- instead of Single, one might use the "Currency" type. In this case, we just need to change the actual calculation:

Code: [Select]set c=!stopsecs!-!startsecs!

So, if you change that to:

Code: [Select]set c=CCur(!stopsecs!)-CCur(!startsecs!)

it will use the Currency type:

Code: [Select] Stop secs=73032.27
Start secs=73031.72

Elapsed secs=0.55


No errant digits!

The Wikipedia article on floating point is pretty thorough on the subject- particularly relevant to this case would be the section titled "Representable numbers, conversion and rounding".
Thank you BC_Prog. You are perfectly correct re the %evaluate% vs evaluate.vbs, serves me right for not cleaning up before the script ends.

Thanks too for the Wiki link.

V.


Discussion

No Comment Found