How do I measure execution time of a command on the Windows command line?

WindowsBatch FileTimeCmdWindows Server-2003

Windows Problem Overview


Is there a built-in way to measure execution time of a command on the Windows command line?

Windows Solutions


Solution 1 - Windows

PowerShell has a cmdlet for this called Measure-Command. You'll have to ensure that PowerShell is available on the machine that runs it.

PS> Measure-Command { echo hi }

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 0
Milliseconds      : 0
Ticks             : 1318
TotalDays         : 1.52546296296296E-09
TotalHours        : 3.66111111111111E-08
TotalMinutes      : 2.19666666666667E-06
TotalSeconds      : 0.0001318
TotalMilliseconds : 0.1318

Measure-Command captures the command's output. You can redirect the output back to your console using Out-Default:

PS> Measure-Command { echo hi | Out-Default }
hi

Days              : 0
...

As Makotoe commented, Measure-Command returns a TimeSpan object, so the measured time is printed as a bunch of fields. You can format the object into a timestamp string using ToString():

PS> (Measure-Command { echo hi | Out-Default }).ToString()
hi
00:00:00.0001318

If the command inside Measure-Command changes your console text color, use [Console]::ResetColor() to reset it back to normal.

Solution 2 - Windows

If you want

  1. To measure execution time down to the hundredth of a second in (hh:mm:ss.ff format)
  2. To not have to download and install a resource pack
  3. To look like a huge DOS nerd (who doesn't)

Try copying the following script into a new batch file (e.g. timecmd.bat):

@echo off
@setlocal

set start=%time%

:: Runs your command
cmd /c %*

set end=%time%
set options="tokens=1-4 delims=:.,"
for /f %options% %%a in ("%start%") do set start_h=%%a&set /a start_m=100%%b %% 100&set /a start_s=100%%c %% 100&set /a start_ms=100%%d %% 100
for /f %options% %%a in ("%end%") do set end_h=%%a&set /a end_m=100%%b %% 100&set /a end_s=100%%c %% 100&set /a end_ms=100%%d %% 100

set /a hours=%end_h%-%start_h%
set /a mins=%end_m%-%start_m%
set /a secs=%end_s%-%start_s%
set /a ms=%end_ms%-%start_ms%
if %ms% lss 0 set /a secs = %secs% - 1 & set /a ms = 100%ms%
if %secs% lss 0 set /a mins = %mins% - 1 & set /a secs = 60%secs%
if %mins% lss 0 set /a hours = %hours% - 1 & set /a mins = 60%mins%
if %hours% lss 0 set /a hours = 24%hours%
if 1%ms% lss 100 set ms=0%ms%

:: Mission accomplished
set /a totalsecs = %hours%*3600 + %mins%*60 + %secs%
echo command took %hours%:%mins%:%secs%.%ms% (%totalsecs%.%ms%s total)

Usage

If you put timecmd.bat in a directory in your path, you can call it from anywhere like this:

timecmd [your command]

E.g.

C:\>timecmd pause
Press any key to continue . . .
command took 0:0:1.18

If you want to do output redirection, you can quote the command like this:

timecmd "dir c:\windows /s > nul"

This should handle commands that run from before- to after-midnight, but the output will be wrong if your command runs for 24 hours or more.

Solution 3 - Windows

Hehe, the most simple solution might be this:

echo %time%
YourApp.exe
echo %time%

This works on every Windows out of the box.


In case of an application using console output, it might be convenient to store the starting time in a temporary variable:

set startTime=%time%
YourApp.exe
echo Start Time: %startTime%
echo Finish Time: %time%

Solution 4 - Windows

Just a little expansion of the answer from Casey.K about using the Measure-Command from PowerShell:

  1. You can invoke PowerShell from the standard command prompt, like this:

     powershell -Command "Measure-Command {echo hi}"
    
  2. This will eat the standard output, but you can prevent that by adding | Out-Default like this from PowerShell:

     Measure-Command {echo hi | Out-Default}
    

    Or from a command prompt:

     powershell -Command "Measure-Command {echo hi | Out-Default}"
    

Of course, you're free to wrap this in a script file *.ps1 or *.bat.

Solution 5 - Windows

If you are using Windows 2003 (note that windows server 2008 and later are not supported) you can use The Windows Server 2003 Resource Kit, which contains timeit.exe that displays detailed execution stats. Here is an example, timing the command "timeit -?":

C:\>timeit timeit -?
Invalid switch -?
Usage: TIMEIT [-f filename] [-a] [-c] [-i] [-d] [-s] [-t] [-k keyname | -r keyname] [-m mask] [commandline...]
where:        -f specifies the name of the database file where TIMEIT
                 keeps a history of previous timings.  Default is .\timeit.dat
              -k specifies the keyname to use for this timing run
              -r specifies the keyname to remove from the database.  If
                 keyname is followed by a comma and a number then it will
                 remove the slowest (positive number) or fastest (negative)
                 times for that keyname.
              -a specifies that timeit should display average of all timings
                 for the specified key.
              -i specifies to ignore non-zero return codes from program
              -d specifies to show detail for average
              -s specifies to suppress system wide counters
              -t specifies to tabular output
              -c specifies to force a resort of the data base
              -m specifies the processor affinity mask

Version Number:   Windows NT 5.2 (Build 3790)
Exit Time:        7:38 am, Wednesday, April 15 2009
Elapsed Time:     0:00:00.000
Process Time:     0:00:00.015
System Calls:     731
Context Switches: 299
Page Faults:      515
Bytes Read:       0
Bytes Written:    0
Bytes Other:      298

You can get TimeIt in the Windows 2003 Resource Kit. It's not available for direct download from the Microsoft Download Center, but one can still get it from the [archive.org - Windows Server 2003 Resource Kit Tools][1].

[1]: http://web.archive.org/web/20150327014146/http://www.microsoft.com/en-us/download/details.aspx?id=17657 "Windows 2003 Resource Kit"

Solution 6 - Windows

The one-liner I use in Windows Server 2008 R2 is:

cmd /v:on /c "echo !TIME! & *mycommand* & echo !TIME!"

So long as mycommand doesn't require quotes (which screws with cmd's quote processing). The /v:on is to allow for the two different TIME values to be evaluated independently rather than once at the execution of the command.

Solution 7 - Windows

If you have a command window open and call the commands manually, you can display a timestamp on each prompt, e.g.

prompt $d $t $_$P$G

It gives you something like:

> 23.03.2009 15:45:50,77 > > C:\>

If you have a small batch script that executes your commands, have an empty line before each command, e.g.

> (empty line) > > myCommand.exe > > (next empty line) > > myCommand2.exe

You can calculate the execution time for each command by the time information in the prompt. The best would probably be to pipe the output to a textfile for further analysis:

MyBatchFile.bat > output.txt

Solution 8 - Windows

Since others are recommending installing things like freeware and PowerShell, you could also install Cygwin, which would give you access to many basic Unix commands like time:

abe@abe-PC:~$ time sleep 5

real	0m5.012s
user	0m0.000s
sys	0m0.000s

Not sure how much overhead Cygwin adds.

Solution 9 - Windows

Not quite as elegant as some of the functionality on Unix, but create a cmd file which looks like:

@echo off
time < nul
yourexecutable.exe > c:\temp\output.txt
time < nul
rem on newer windows system you can try time /T

That will display the start and stop times like so:

The current time is: 10:31:57.92
Enter the new time:
The current time is: 10:32:05.94
Enter the new time:

Solution 10 - Windows

I use freeware called "GS Timer".

Just make a batch file like this:

timer
yourapp.exe
timer /s

If you need a set of times, just pipe the output of timer /s into a .txt file.

You can get it here: Gammadyne's Free DOS Utilities


The resolution is 0.1 seconds.

Solution 11 - Windows

I'm using Windows XP and for some reason timeit.exe does not work for me. I found another alternative - PTIME. This works very well.

http://www.pc-tools.net/win32/ptime/

Example -

C:\> ptime

ptime 1.0 for Win32, Freeware - http://www.pc-tools.net/
Copyright(C) 2002, Jem Berkes <[email protected]>

Syntax: ptime command [arguments ...]

ptime will run the specified command and measure the execution time
(run time) in seconds, accurate to 5 millisecond or better. It is an
automatic process timer, or program timer.


C:\> ptime cd

ptime 1.0 for Win32, Freeware - http://www.pc-tools.net/
Copyright(C) 2002, Jem Berkes <[email protected]>

===  cd ===
C:\

Execution time: 0.015 s

Solution 12 - Windows

As long as it doesn't last longer than 24hours...

@echo off

set starttime=%TIME%
set startcsec=%STARTTIME:~9,2%
set startsecs=%STARTTIME:~6,2%
set startmins=%STARTTIME:~3,2%
set starthour=%STARTTIME:~0,2%
set /a starttime=(%starthour%*60*60*100)+(%startmins%*60*100)+(%startsecs%*100)+(%startcsec%)

:TimeThis
ping localhost 

set endtime=%time%
set endcsec=%endTIME:~9,2%
set endsecs=%endTIME:~6,2%
set endmins=%endTIME:~3,2%
set endhour=%endTIME:~0,2%
if %endhour% LSS %starthour% set /a endhour+=24
set /a endtime=(%endhour%*60*60*100)+(%endmins%*60*100)+(%endsecs%*100)+(%endcsec%)

set /a timetaken= ( %endtime% - %starttime% )
set /a timetakens= %timetaken% / 100
set timetaken=%timetakens%.%timetaken:~-2%

echo.
echo Took: %timetaken% sec.

Solution 13 - Windows

There's also TimeMem (March 2012):

> This is a Windows utility which executes a program and displays its > execution time, memory usage, and IO statistics. It is similar in > functionality to the Unix time utility.

Solution 14 - Windows

Here is a

Postfix timer version:

Usage example:

timeout 1 | TimeIt.cmd

Execution took  ~969 milliseconds.

Copy & paste this into some editor like for example Notepad++ and save it as TimeIt.cmd:

:: --- TimeIt.cmd ----
    @echo off
    setlocal enabledelayedexpansion

    call :ShowHelp

    :: Set pipeline initialization time
    set t1=%time%

    :: Wait for stdin
    more

    :: Set time at which stdin was ready
    set t2=!time!


    :: Calculate difference
    Call :GetMSeconds Tms1 t1
    Call :GetMSeconds Tms2 t2

    set /a deltaMSecs=%Tms2%-%Tms1%
    echo Execution took ~ %deltaMSecs% milliseconds.

    endlocal
goto :eof

:GetMSeconds
    Call :Parse        TimeAsArgs %2
    Call :CalcMSeconds %1 %TimeAsArgs%

goto :eof

:CalcMSeconds
    set /a %1= (%2 * 3600*1000) + (%3 * 60*1000) + (%4 * 1000) + (%5)
goto :eof

:Parse

    :: Mask time like " 0:23:29,12"
    set %1=!%2: 0=0!

    :: Replace time separators with " "
    set %1=!%1::= !
    set %1=!%1:.= !
    set %1=!%1:,= !

    :: Delete leading zero - so it'll not parsed as octal later
    set %1=!%1: 0= !
goto :eof

:ShowHelp
    echo %~n0 V1.0 [Dez 2015]
    echo.
    echo Usage: ^<Command^> ^| %~nx0
    echo.
    echo Wait for pipe getting ready... :)
    echo  (Press Ctrl+Z ^<Enter^> to Cancel)
goto :eof

^ - Based on 'Daniel Sparks' Version

Solution 15 - Windows

Depending on the version of Windows you're using, just running bash will put you into Bash mode. This will allow you to use a bunch of commands that are not available on PowerShell directly (like the time command). Timing your command is now as easy as executing:

# The clause <your-command> (without the angle brackets) denotes the command you want to run.
$ time <your-command>

> Note: You can easily quit from Bash mode and return back into your mainstream shell by running exit while in Bash mode.

This worked for me perfectly (Windows 10) after trying out other methods (like Measure-Command) which sometimes produce undesired stats. Hope this works for you as well.

Solution 16 - Windows

An alternative to measure-time is simply "Get-Date". You don't have that hassle with forwarding output and so on.

$start = Get-Date
[System.Threading.Thread]::Sleep(1500)
$(Get-Date) - $start

Output:

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 1
Milliseconds      : 506
Ticks             : 15060003
TotalDays         : 1.74305590277778E-05
TotalHours        : 0.000418333416666667
TotalMinutes      : 0.025100005
TotalSeconds      : 1.5060003
TotalMilliseconds : 1506.0003

Solution 17 - Windows

This is a one-liner which avoids delayed expansion, which could disturb certain commands:

cmd /E /C "prompt $T$$ & echo.%TIME%$ & COMMAND_TO_MEASURE & for %Z in (.) do rem/ "

The output is something like:

> 14:30:27.58$ > ... > 14:32:43.17$ rem/

For long-term tests replace $T by $D, $T and %TIME% by %DATE%, %TIME% to include the date.

To use this inside of a batch file, replace %Z by %%Z.


Update

Here is an improved one-liner (without delayed expansion too):

cmd /E /C "prompt $D, $T$$ & (for %# in (.) do rem/ ) & COMMAND_TO_MEASURE & for %# in (.) do prompt"

The output looks similar to this:

> 2015/09/01, 14:30:27.58$ rem/ > ... > 2015/09/01, 14:32:43.17$ prompt

This approach does not include the process of instancing a new cmd in the result, nor does it include the prompt command(s).

Solution 18 - Windows

In case anyone else has come here looking for an answer to this question, there's a Windows API function called GetProcessTimes(). It doesn't look like too much work to write a little C program that would start the command, make this call, and return the process times.

Solution 19 - Windows

Here is my method, no conversion and no ms. It is useful to determine encoding durations (limited to 24 hours though):

@echo off

:start
REM Start time storage
set ST=%time%
echo Process started at %ST%
echo.
echo.

REM Your commands
REM Your commands
REM Your commands

:end
REM Start Time Definition
for /f "tokens=1-3 delims=:" %%a in ("%ST%") do set /a h1=%%a & set /a m1=%%b & set /a s1=%%c

REM End Time Definition
for /f "tokens=1-3 delims=:" %%a in ("%TIME%") do set /a h2=%%a & set /a m2=%%b & set /a s2=%%c

REM Difference
set /a h3=%h2%-%h1% & set /a m3=%m2%-%m1% & set /a s3=%s2%-%s1%

REM Time Adjustment
if %h3% LSS 0 set /a h3=%h3%+24
if %m3% LSS 0 set /a m3=%m3%+60 & set /a h3=%h3%-1
if %s3% LSS 0 set /a s3=%s3%+60 & set /a m3=%m3%-1

echo Start    :    %ST%
echo End    :    %time%
echo.
echo Total    :    %h3%:%m3%:%s3%
echo.
pause

Solution 20 - Windows

my code gives you the running time in milliseconds, up to 24 hrs, it is locale insensitive, and accounts for negative values if code runs through midnight. it uses delayed expansion, and should be saved in a cmd/bat file.

before your code:

SETLOCAL EnableDelayedExpansion

for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /format:list') do set t=%%I
set /a t1 = %t:~8,1%*36000 + %t:~9,1%*3600 + %t:~10,1%*600 + %t:~11,1%*60 + %t:~12,1%*10 + %t:~13,1% && set t1=!t1!%t:~15,3%

after your code:

for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /format:list') do set t=%%I
set /a t2 = %t:~8,1%*36000 + %t:~9,1%*3600 + %t:~10,1%*600 + %t:~11,1%*60 + %t:~12,1%*10 + %t:~13,1% && set t2=!t2!%t:~15,3%
set /a t2-=t1 && if !t2! lss 0 set /a t2+=24*3600000

if you want running time in HH:mm:ss.000 format, add:

set /a "h=t2/3600000,t2%%=3600000,m=t2/60000,t2%%=60000" && set t2=00000!t2!&& set t2=!t2:~-5!
if %h% leq 9 (set h=0%h%) && if %m% leq 9 (set m=0%m%)
set t2=%h%:%m%:%t2:~0,2%.%t2:~2,3%

ENDLOCAL

variable t2 holds your running time, you can echo %t2% to display it.

Solution 21 - Windows

  1. In the directory where your program is, type notepad mytimer.bat, click 'yes' to create a new file.

  2. Paste the code below, replacing YourApp.exe with your program, then save.

    @echo off
    date /t
    time /t
    YourApp.exe
    date /t
    time /t
    
  3. Type mytimer.bat in the command line then press Enter.

Solution 22 - Windows

This is a comment/edit to Luke Sampson's nice timecmd.bat and reply to

>For some reason this only gives me output in whole seconds... which for me is useless. I mean that I run timecmd pause, and it always results in 1.00 sec, 2.00 sec, 4.00 sec... even 0.00 sec! Windows 7. – Camilo Martin Sep 25 '13 at 16:00 "

On some configurations the delimiters may differ. The following change should cover atleast most western countries.

set options="tokens=1-4 delims=:,." (added comma)

The %time% milliseconds work on my system after adding that ','

(*because site doesn't allow anon comment and doesn't keep good track of identity even though I always use same guest email which combined with ipv6 ip and browser fingerprint should be enough to uniquely identify without password)

Solution 23 - Windows

@echo off & setlocal

set start=%time%

REM Do stuff to be timed here.
REM Alternatively, uncomment the line below to be able to
REM pass in the command to be timed when running this script.
REM cmd /c %*

set end=%time%

REM Calculate time taken in seconds, to the hundredth of a second.
REM Assumes start time and end time will be on the same day.

set options="tokens=1-4 delims=:."

for /f %options% %%a in ("%start%") do (
    set /a start_s="(100%%a %% 100)*3600 + (100%%b %% 100)*60 + (100%%c %% 100)"
    set /a start_hs=100%%d %% 100
)

for /f %options% %%a in ("%end%") do (
    set /a end_s="(100%%a %% 100)*3600 + (100%%b %% 100)*60 + (100%%c %% 100)"
    set /a end_hs=100%%d %% 100
)

set /a s=%end_s%-%start_s%
set /a hs=%end_hs%-%start_hs%

if %hs% lss 0 (
    set /a s=%s%-1
    set /a hs=100%hs%
)
if 1%hs% lss 100 set hs=0%hs%

echo.
echo  Time taken: %s%.%hs% secs
echo.

Solution 24 - Windows

The following script uses only "cmd.exe" and outputs the number of milliseconds from the time a pipeline is created to the time that the process preceding the script exits. i.e., Type your command, and pipe the to the script. Example: "timeout 3 | runtime.cmd" should yield something like "2990." If you need both the runtime output and the stdin output, redirect stdin before the pipe - ex: "dir /s 1>temp.txt | runtime.cmd" would dump the output of the "dir" command to "temp.txt" and would print the runtime to the console.

:: --- runtime.cmd ----
@echo off
setlocal enabledelayedexpansion

:: find target for recursive calls
if not "%1"=="" (
	shift /1
	goto :%1
    exit /b
)

:: set pipeline initialization time
set t1=%time%

:: wait for stdin
more > nul

:: set time at which stdin was ready
set t2=!time!

::parse t1
set t1=!t1::= !
set t1=!t1:.= !
set t1=!t1: 0= !

:: parse t2
set t2=!t2::= !
set t2=!t2:.= !
set t2=!t2: 0= !

:: calc difference
pushd %~dp0
for /f %%i in ('%0 calc !t1!') do for /f %%j in ('%0 calc !t2!') do (
	set /a t=%%j-%%i
	echo !t!
)
popd
exit /b
goto :eof

:calc
set /a t=(%1*(3600*1000))+(%2*(60*1000))+(%3*1000)+(%4)
echo !t!
goto :eof

endlocal

Solution 25 - Windows

The answer of driblio can be made a little shorter (though not much readable)

@echo off

:: Calculate the start timestamp
set _time=%time%
set /a _hours=100%_time:~0,2%%%100,_min=100%_time:~3,2%%%100,_sec=100%_time:~6,2%%%100,_cs=%_time:~9,2%
set /a _started=_hours*60*60*100+_min*60*100+_sec*100+_cs


:: yourCommandHere


:: Calculate the difference in cSeconds
set _time=%time%
set /a _hours=100%_time:~0,2%%%100,_min=100%_time:~3,2%%%100,_sec=100%_time:~6,2%%%100,_cs=%_time:~9,2%
set /a _duration=_hours*60*60*100+_min*60*100+_sec*100+_cs-_started

:: Populate variables for rendering (100+ needed for padding)
set /a _hours=_duration/60/60/100,_min=100+_duration/60/100%%60,_sec=100+(_duration/100%%60%%60),_cs=100+_duration%%100

echo Done at: %_time% took : %_hours%:%_min:~-2%:%_sec:~-2%.%_cs:~-2%

::prints something like:
::Done at: 12:37:53,70 took: 0:02:03.55

To the remark of Luke Sampson this version is octal safe, though the task should be completed in 24 hours.

Solution 26 - Windows

Having Perl installed the hires solution available, run:

C:\BATCH>time.pl "echo Fine result"
0.01063
Fine result

STDERR comes before measured seconds

#!/usr/bin/perl -w

use Time::HiRes qw();
my $T0 = [ Time::HiRes::gettimeofday ];

my $stdout = `@ARGV`;

my $time_elapsed = Time::HiRes::tv_interval( $T0 );

print $time_elapsed, "\n";
print $stdout;

Solution 27 - Windows

Another approach with powershell:

@echo off
for /f %%t in ('powershell "(get-date).tofiletime()"') do set mst=%%t

rem some commands

powershell ((get-date).tofiletime() - %mst%)

this will print the execution time in milliseconds.

Solution 28 - Windows

The following script emulates *nix epoch time, but it is local and regional. It should handle calender edge cases including leap years. If Cygwin is available, epoch values can be compared by specifying the Cygwin option.

I'm in EST and the difference reported is 4 hours which is relatively correct. There are some interesting solutions to remove the TZ and regional dependencies, but nothing trivial that I noticed.

@ECHO off
SETLOCAL EnableDelayedExpansion

::
::  Emulates local epoch seconds
::

:: Call passing local date and time
CALL :SECONDS "%DATE%" "%TIME%"
IF !SECONDS! LEQ 0 GOTO END

:: Not testing - print and exit
IF NOT "%~1"=="cygwin" (
    ECHO !SECONDS!
    GOTO END
)

:: Call on Cygwin to get epoch time
FOR /F %%c IN ('C:\cygwin\bin\date +%%s') DO SET EPOCH=%%c

:: Show the results
ECHO Local Seconds: !SECONDS!
ECHO Epoch Seconds: !EPOCH!

:: Calculate difference between script and Cygwin
SET /A HOURS=(!EPOCH!-!SECONDS!)/3600
SET /A FRAC=(!EPOCH!-!SECONDS!)%%3600

:: Delta hours shown reflect TZ
ECHO Delta Hours: !HOURS! Remainder: !FRAC!

GOTO END

:SECONDS
SETLOCAL  EnableDelayedExpansion

    :: Expecting values from caller
    SET DATE=%~1
    SET TIME=%~2

    :: Emulate Unix epoch time without considering TZ
    SET "SINCE_YEAR=1970"

    :: Regional constraint! Expecting date and time in the following formats:
    ::   Sun 03/08/2015   Day MM/DD/YYYY
    ::   20:04:53.64         HH:MM:SS
    SET VALID_DATE=0
    ECHO !DATE! | FINDSTR /R /C:"^... [0-9 ][0-9]/[0-9 ][0-9]/[0-9][0-9][0-9][0-9]" > nul && SET VALID_DATE=1
    SET VALID_TIME=0
    ECHO !TIME! | FINDSTR /R /C:"^[0-9 ][0-9]:[0-9 ][0-9]:[0-9 ][0-9]" > nul && SET VALID_TIME=1
    IF NOT "!VALID_DATE!!VALID_TIME!"=="11" (
        IF !VALID_DATE! EQU 0  ECHO Unsupported Date value: !DATE! 1>&2
        IF !VALID_TIME! EQU 0  ECHO Unsupported Time value: !TIME! 1>&2
        SET SECONDS=0
        GOTO SECONDS_END
    )

    :: Parse values
    SET "YYYY=!DATE:~10,4!"
    SET "MM=!DATE:~4,2!"
    SET "DD=!DATE:~7,2!"
    SET "HH=!TIME:~0,2!"
    SET "NN=!TIME:~3,2!"
    SET "SS=!TIME:~6,2!"
    SET /A YEARS=!YYYY!-!SINCE_YEAR!
    SET /A DAYS=!YEARS!*365

    :: Bump year if after February  - want leading zeroes for this test
    IF "!MM!!DD!" GEQ "0301" SET /A YEARS+=1

    :: Remove leading zeros that can cause octet probs for SET /A
    FOR %%r IN (MM,DD,HH,NN,SS) DO (
        SET "v=%%r"
        SET "t=!%%r!"
        SET /A N=!t:~0,1!0
        IF 0 EQU !N! SET "!v!=!t:~1!"
    )

    :: Increase days according to number of leap years
    SET /A DAYS+=(!YEARS!+3)/4-(!SINCE_YEAR!%%4+3)/4

    :: Increase days by preceding months of current year
    FOR %%n IN (31:1,28:2,31:3,30:4,31:5,30:6,31:7,31:8,30:9,31:10,30:11) DO (
        SET "n=%%n"
        IF !MM! GTR !n:~3! SET /A DAYS+=!n:~0,2!
    )

    :: Multiply and add it all together
    SET /A SECONDS=(!DAYS!+!DD!-1)*86400+!HH!*3600+!NN!*60+!SS!

:SECONDS_END
ENDLOCAL & SET "SECONDS=%SECONDS%"
GOTO :EOF

:END
ENDLOCAL

Solution 29 - Windows

Using a sub to return time in hundredths of second

::tiemeit.cmd
@echo off
Setlocal EnableDelayedExpansion

call :clock 

::call your_command  or more > null to pipe this batch after your_command

call :clock

echo %timed%
pause
goto:eof

:clock
if not defined timed set timed=0
for /F "tokens=1-4 delims=:.," %%a in ("%time%") do ( 
set /A timed = "(((1%%a - 100) * 60 + (1%%b - 100)) * 60 + (1%%c - 100))  * 100 + (1%%d - 100)- %timed%"
)
goto:eof

Solution 30 - Windows

"Lean and Mean" TIMER with Regional format, 24h and mixed input support
Adapting Aacini's substitution method body, no IF's, just one FOR (my regional fix)

1: File timer.bat placed somewhere in %PATH% or the current dir

@echo off & rem :AveYo: compact timer function with Regional format, 24-hours and mixed input support
if not defined timer_set (if not "%~1"=="" (call set "timer_set=%~1") else set "timer_set=%TIME: =0%") & goto :eof
(if not "%~1"=="" (call set "timer_end=%~1") else set "timer_end=%TIME: =0%") & setlocal EnableDelayedExpansion
for /f "tokens=1-6 delims=0123456789" %%i in ("%timer_end%%timer_set%") do (set CE=%%i&set DE=%%k&set CS=%%l&set DS=%%n)
set "TE=!timer_end:%DE%=%%100)*100+1!"     & set "TS=!timer_set:%DS%=%%100)*100+1!"
set/A "T=((((10!TE:%CE%=%%100)*60+1!%%100)-((((10!TS:%CS%=%%100)*60+1!%%100)" & set/A "T=!T:-=8640000-!"
set/A "cc=T%%100+100,T/=100,ss=T%%60+100,T/=60,mm=T%%60+100,hh=T/60+100"
set "value=!hh:~1!%CE%!mm:~1!%CE%!ss:~1!%DE%!cc:~1!" & if "%~2"=="" echo/!value!
endlocal & set "timer_end=%value%" & set "timer_set=" & goto :eof

Usage:
timer & echo start_cmds & timeout /t 3 & echo end_cmds & timer
timer & timer "23:23:23,00"
timer "23:23:23,00" & timer
timer "13.23.23,00" & timer "03:03:03.00"
timer & timer "0:00:00.00" no & cmd /v:on /c echo until midnight=!timer_end!
Input can now be mixed, for those unlikely, but possible time format changes during execution

2: Function :timer bundled with the batch script (sample usage below):

@echo off
set "TIMER=call :timer" & rem short macro
echo.
echo EXAMPLE:
call :timer
timeout /t 3 >nul & rem Any process here..
call :timer
echo.
echo SHORT MACRO:
%TIMER% & timeout /t 1 & %TIMER% 
echo.
echo TEST INPUT:
set "start=22:04:04.58"
set "end=04.22.44,22"
echo %start% ~ start & echo %end% ~ end
call :timer "%start%"
call :timer "%end%"
echo.
%TIMER% & %TIMER% "00:00:00.00" no 
echo UNTIL MIDNIGHT: %timer_end%
echo.
pause 
exit /b

:: to test it, copy-paste both above and below code sections

rem :AveYo: compact timer function with Regional format, 24-hours and mixed input support 
:timer Usage " call :timer [input - optional] [no - optional]" :i Result printed on second call, saved to timer_end 
if not defined timer_set (if not "%~1"=="" (call set "timer_set=%~1") else set "timer_set=%TIME: =0%") & goto :eof
(if not "%~1"=="" (call set "timer_end=%~1") else set "timer_end=%TIME: =0%") & setlocal EnableDelayedExpansion
for /f "tokens=1-6 delims=0123456789" %%i in ("%timer_end%%timer_set%") do (set CE=%%i&set DE=%%k&set CS=%%l&set DS=%%n)
set "TE=!timer_end:%DE%=%%100)*100+1!"     & set "TS=!timer_set:%DS%=%%100)*100+1!"
set/A "T=((((10!TE:%CE%=%%100)*60+1!%%100)-((((10!TS:%CS%=%%100)*60+1!%%100)" & set/A "T=!T:-=8640000-!"
set/A "cc=T%%100+100,T/=100,ss=T%%60+100,T/=60,mm=T%%60+100,hh=T/60+100"
set "value=!hh:~1!%CE%!mm:~1!%CE%!ss:~1!%DE%!cc:~1!" & if "%~2"=="" echo/!value!
endlocal & set "timer_end=%value%" & set "timer_set=" & goto :eof

CE,DE and CS,DS stand for colon end, dot end and colon set, dot set - used for mixed format support

Solution 31 - Windows

A solution using pure PHP for cmd and one env. variable:
@echo off
setlocal enableextensions

REM set start time env var
FOR /F "tokens=* USEBACKQ" %%F IN (`php -r "echo microtime(true);"`) DO ( SET start_time=%%F )

## PUT_HERE_THE_COMMAND_TO_RUN ##

REM echo elapsed time
php -r "echo 'elapsed: ' . (round(microtime(true) - trim(getenv('start_time')), 2)) . ' seconds' . mb_convert_encoding('&#13;&#10;', 'UTF-8', 'HTML-ENTITIES');"
  • no need for cygwin or non-trusted utilities. Usefull when PHP is locally available

  • precision and output format can be easily tweaked

  • the same idea can be ported for PowerShell

Solution 32 - Windows

If you have CMake installed, you can just run following command.

cmake -E time <the_command_to_measure_run_time>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKuroki KazeView Question on Stackoverflow
Solution 1 - WindowsCasey.KView Answer on Stackoverflow
Solution 2 - Windowsuser87453View Answer on Stackoverflow
Solution 3 - WindowsLietKynesView Answer on Stackoverflow
Solution 4 - WindowsVladimir VeljkovicView Answer on Stackoverflow
Solution 5 - WindowsMikeAView Answer on Stackoverflow
Solution 6 - WindowsNathan HerringView Answer on Stackoverflow
Solution 7 - WindowsTrebView Answer on Stackoverflow
Solution 8 - WindowsAbe VoelkerView Answer on Stackoverflow
Solution 9 - WindowsJohnWView Answer on Stackoverflow
Solution 10 - WindowspepoluanView Answer on Stackoverflow
Solution 11 - WindowsMurali KrishnanView Answer on Stackoverflow
Solution 12 - WindowsdriblioView Answer on Stackoverflow
Solution 13 - WindowsMartin MoeneView Answer on Stackoverflow
Solution 14 - WindowsNaduView Answer on Stackoverflow
Solution 15 - WindowsSaddam MView Answer on Stackoverflow
Solution 16 - WindowsRainerView Answer on Stackoverflow
Solution 17 - WindowsaschipflView Answer on Stackoverflow
Solution 18 - WindowsJeff PrattView Answer on Stackoverflow
Solution 19 - WindowsilkoView Answer on Stackoverflow
Solution 20 - WindowsrobotikView Answer on Stackoverflow
Solution 21 - WindowsJohn SnowView Answer on Stackoverflow
Solution 22 - WindowsAnonymous CowardView Answer on Stackoverflow
Solution 23 - WindowsMikeMView Answer on Stackoverflow
Solution 24 - WindowsDaniel SparksView Answer on Stackoverflow
Solution 25 - WindowsAlexanderView Answer on Stackoverflow
Solution 26 - WindowsVictor MironovView Answer on Stackoverflow
Solution 27 - WindowsnpocmakaView Answer on Stackoverflow
Solution 28 - WindowsbvjView Answer on Stackoverflow
Solution 29 - WindowsAntoni Gual ViaView Answer on Stackoverflow
Solution 30 - WindowsAveYoView Answer on Stackoverflow
Solution 31 - WindowsmvorisekView Answer on Stackoverflow
Solution 32 - WindowsThomsonView Answer on Stackoverflow