544

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

Anthony
  • 34,084
  • 23
  • 90
  • 154
Kuroki Kaze
  • 7,142
  • 3
  • 34
  • 48
  • https://stackoverflow.com/questions/15831197/ffmpeg-calculate-time-to-convert-images-and-mp3-to-a-video/52627198#52627198 – Sanjay Hadiya Nov 22 '18 at 04:29

31 Answers31

531

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
...

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.

M. Dudley
  • 26,519
  • 30
  • 137
  • 228
Casey.K
  • 5,351
  • 2
  • 12
  • 2
  • 23
    This is the best solution for Windows 7 users as timeit.exe doesn't appear to support Windows 7 – Michael La Voie Oct 25 '11 at 00:08
  • 15
    In case you want to use internal dos commands (eg.: dir, echo, del, etc.) don't forget to insert "cmd /c": Measure-Command { cmd /c dir /s c:\windows > nul } – LietKynes Jan 10 '12 at 10:49
  • How to execute it from external application that can execute shell commands? – Simon Sep 07 '13 at 01:40
  • 8
    If you're benchmarking an `.exe` in the current directory, use this: `Measure-Command { .\your.exe }`. PowerShell apparently doesn't run things from `pwd` unless explicitly told to. – Cristian Diaconescu Sep 10 '13 at 15:02
  • @Simon: create a file called `mc.ps1`, containing text `Measure-Command {echo hi}` or whatever command you're timing, and from the command line run `powershell -File mc.ps1`. – twasbrillig Dec 03 '14 at 03:27
  • 14
    Annoyingly it hides stdout though. – Zitrax Aug 19 '15 at 08:17
  • 15
    This is ***NOT AT ALL*** a tool *'similar to Bash's time command'*. It's nice to know though... but: it does not execute ***and return to ``*** the results of the command enclosed in the curly brackets! – Kurt Pfeifle Oct 25 '15 at 20:58
  • 3
    Please note that vladimir veljkovic's answer shows how to keep stdout. – BenMaddox Jul 24 '16 at 17:56
  • 3
    Use this ```powershell -Command Measure-Command { YOUR_COMMAND }``` this does not hide the `stdout`. – Behrouz.M Aug 19 '16 at 11:34
  • 1
    I think Powershell is the way to go. There are a lot of variations on `Measure-Command`, including keeping the results of stdout, at http://stackoverflow.com/questions/3513650/timing-a-commands-execution-in-powershell/24617500, worth taking a look. – Ehtesh Choudhury Oct 24 '16 at 23:27
  • Usage Example needs to be added to this answer: PS S:\T> Measure-Command { S:\T\r.bat } > rlog.txt – Alex S Jun 15 '17 at 12:03
  • 5
    Ray pixar misquoted vladimir. It should be ``Measure-Command { YOUR_COMMAND | Out-Default}`` – Corey Levinson Jul 27 '17 at 17:41
  • Result for `"Measure-Command {mysql my_db_name < 2017-08-21_my_db_dump.sql}` was `"Operator < is reserved for a future usage"` I didn't test further than this, and might speak too quickly, but... this just doesn't work, right ? (using Win7 x64) – Balmipour Aug 21 '17 at 14:18
  • I can't figure out how to use this with a command that requires a path including a space such as `C:\Program files\foo.exe` – hippietrail Feb 02 '19 at 17:00
  • Just for clarity, this measures elapsed time (wall time), not CPU time (execution time) – john v kumpf Jan 07 '20 at 22:34
  • [`Measure-Command`](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/measure-command?view=powershell-7) returns a [`TimeSpan`](https://docs.microsoft.com/en-us/dotnet/api/system.timespan?view=netcore-3.1). You can use `ToString()` on the return value to get a more readable format: `00:00:03.1731060`. – MakotoE Sep 05 '20 at 18:50
313

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.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Luke Sampson
  • 7,804
  • 3
  • 35
  • 43
  • 9
    replacing **cmd /c %*** with **%*** works unless your command is another batch file. Then you'd have to do **timecmd call other.bat** – Jesse Chisholm Mar 27 '13 at 16:50
  • 2
    @JesseChisholm In Windows 8 (and I've read in Windows 7 as well) you don't need the call for .bat – Brian J Aug 21 '13 at 19:37
  • 4
    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
  • Before I use it, I will rewrite it into a function like `:print_time_since `, to use it multiple times in a script from inside of it. BTW, nice string splitting and use of `cmd`'s `FOR` hacks taken to the extreme! – Tomasz Gandor Sep 11 '14 at 10:33
  • 10
    @CamiloMartin & others who had this (like me) - you may have a locale, which uses COMMA instead of DOT for decimal. So, in this scrpit, change `delims=:.` to `delims=:.,`, and then it should work "across the board". – Tomasz Gandor Sep 11 '14 at 11:19
  • 1
    @TomaszGandor Ah, that was it, then! To be honest, it pisses me off how Windows even has output from core commands localized, and it frequently breaks naive batch files. – Camilo Martin Sep 11 '14 at 18:25
  • 5
    There's a serious arithmetic error in that script: Try it with: `set start=10:10:10.10` `set end=10:11:10.09` And it'll output: `command took 0:1:-1.99 (59.99s total)` You should reverse the order of the 4 lines that do "lss 0" comparisons, so that the carry progresses correctly from low to high sexagesimal digits. Then the output becomes: `command took 0:0:59.99 (59.99s total)` – Jean-François Larvoire Dec 02 '14 at 16:04
  • It seem not be able to handle spaces between 'command' with arguments. I had to quote everything like `timeit "scala -J-Xmx33m ProxyDemo 15 1 > console"`. Probably it is worth noticing. – Valentin Tihomirov Dec 01 '15 at 19:02
  • Cool script. Note that once you disable echoing (`@echo off`), you no longer need to prefix `setlocal` with `@`. – thdoan Jul 09 '16 at 16:19
  • Observation for others not to dismiss too quickly any output. For me, even with a warning output, i.e. 'cmd' is not recognised as an internal or external command... , there is a response back. For me, it measures pause as 0.01s total. – Nasri Najib Nov 09 '16 at 07:28
  • Cool but does not expose process time in any way. – Euri Pinhollow Apr 06 '17 at 20:24
  • works even better with `%COMSPEC% /c %*` instead of `cmd /c %*` (9th line) (cmd (C:\windows\system32) may not be in %PATH%) – mugiseyebrows Jun 09 '17 at 12:25
  • Utilities like this one should never turn echo off. It does not compose well, particularly when one is diagnosing script failures. Better to use `@` prefix everywhere and let developers pin-hole enable echo within the script when/where needed. – jwdonahue Nov 08 '17 at 22:54
  • I have a more composable version of this script. Should I edit the answer or add another to the thread? – jwdonahue Nov 09 '17 at 03:40
  • 1
    That's super useful. The only thing I felt I needed to add was zero-padding minutes, seconds and milliseconds, like so: `:: Mission accomplished set /a totalsecs = %hours%*3600 + %mins%*60 + %secs% set "mins=0%mins%" set "mins=%mins:~-2%" set "secs=0%secs%" set "secs=%secs:~-2%" set "ms=00%ms%" set "ms=%secs:~-3%" echo Operation took %hours%:%mins%:%secs%.%ms% (%totalsecs%.%ms%s total)` – Jashan Feb 22 '19 at 08:47
  • 2
    For anyone wondering: the fixes by TomaszGandor and Jean-FrançoisLarvoire have been edited into the script above. Also @Jashan: there's a buggy bug in your milliseconds padding (it's actually hundredths, and you're using the `secs` var instead of `ms`), so it should be: `set "ms=0%ms%"` and `set "ms=%ms:~-2%"`. But other than that, I like this! – Paul Jun 23 '19 at 18:01
251

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%
Antonio
  • 17,405
  • 10
  • 78
  • 178
LietKynes
  • 2,682
  • 1
  • 13
  • 8
  • 176
    Are you crazy?! That involves doing math, like, in your brain. This is why we invented computers, so we could avoid doing stuff like that. – Luke Sampson Jun 02 '11 at 01:31
  • 2
    brilliant! Even though, for CPU time it doesn't really help – Ilya Saunkin Jun 10 '11 at 06:55
  • 12
    Even better (if your app spits output to the console): `set startTime=%time% \n YourApp.exe \n echo Start Time: %startTime% \n echo Finish Time: %time%` (Sorry, couldn't get newlines in the comment) – Jono Jun 03 '12 at 15:52
  • 1
    @LukeSampson, you can use `set` to do the math. `;-)` Oh wait, nevermind, you already did that below. – Synetech Apr 21 '13 at 14:56
  • 4
    No, this is a bad option. This tells you the wall-clock time, not the CPU time. So, even though your command line might take only 100ms, if there's another application hogging the CPU, your application may take seconds (off by 100x or more). In fact, if your machine is thrashing, you could even wait a minute for your little 100ms app to run. Track CPU time, not wall clock time! – Ryan Shillington Oct 20 '14 at 16:32
  • This method cannot be used to quickly launch a command in one line. – Mykhaylo Kopytonenko Oct 27 '16 at 08:13
  • 1
    @MykhayloKopytonenko Yes it can: `echo %time% && YourCmd --with -- -params && echo %time%` – DaJunkie May 03 '18 at 10:10
  • @DaJunkie unless `YourCmd` does not succeed: the last `echo %time%` won't be called. – Matthieu Oct 09 '18 at 09:34
  • I know that my answer does not compute the execution time. However please take into consideration that when I wrote the answer in March 2010, the most common Windows operating system was Windows XP/Server 2003, which didn't have PowerShell installed by default. The above solution worked out of the box, without installing additional software (which is especially helpful in a corporate environment). – LietKynes Aug 17 '20 at 10:11
116

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 arhive.org - Windows Server 2003 Resource Kit Tools.

LietKynes
  • 2,682
  • 1
  • 13
  • 8
  • 7
    This kit has issues with windows 2008 64bit and does not work on 2008 R2 – Artem Nov 12 '09 at 02:29
  • is there any way to also measure kernel time and/or the time used by spawned sub processes? – rogerdpack Feb 21 '11 at 22:55
  • 41
    FYI - I don't think timeit works on Windows 7 64-bit. You get the error "Unable to query system performance data (c0000004). Instead, use PowerShell's "Measure-Command" like Casey.K suggests: http://stackoverflow.com/questions/673523/how-to-measure-execution-time-of-command-in-windows-command-line/4801509#4801509 – Michael La Voie Oct 25 '11 at 00:05
  • 7
    In Windows 7 I see "'timeit' is not recognized as an internal or external command, operable program or batch file." – Colonel Panic Sep 12 '13 at 15:11
  • 4
    I don't see the command in Windows 10, nor do I easily find a Resource Kit for Win 10. Does anyone know how to get this for 10? – Jay Imerman Jan 25 '18 at 14:35
112

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.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Vladimir Veljkovic
  • 1,277
  • 1
  • 8
  • 4
  • 2
    What if the command we want to measure has quotes? Can can this be turned into a .bat script in that case? For example `measureTime.bat "c:\program files\some dir\program.exe"` – GetFree Sep 10 '18 at 22:31
53

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.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Nathan Herring
  • 927
  • 8
  • 16
  • This also won't work for the "spam" batches, which overwrite the first time label and implies that you replace the computer doing the computation, as noted in http://stackoverflow.com/questions/673523/how-to-measure-execution-time-of-command-in-windows-command-line#comment7229148_2417604 – Val Jul 11 '13 at 18:01
  • Usually you can escape quotes by `^` in cmd (like `^"`) – n611x007 Oct 24 '13 at 15:30
  • 2
    If you repeat the cmd /v:on for the second timing, we can even have _mycommand_ contain quotes. Example: `cmd /v:on /c echo !TIME! & echo "Quoted mycommand" & cmd /v:on /c echo !TIME!`. – Maarten Pennings Feb 19 '15 at 09:35
  • 8
    Simpler: `echo %time% & *mycommand* & call echo %^time%`. See also [this answer](http://stackoverflow.com/a/42603985/778560). – Aacini Mar 07 '17 at 02:39
  • If your command outputs too much, maybe it's easier just put the 2 time together: `cmd /v:on /c "mycommand & echo begin=%time% endtime=!time!"` – ZHANG Zikai Feb 11 '20 at 02:03
51

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
Community
  • 1
  • 1
Treb
  • 19,065
  • 6
  • 50
  • 83
  • 5
    Thought I'd drop in a couple years behind the discussion to thank you for sharing the prompt command. I've seen a lot of CMD tricks (more of a bash guy), but this one escaped my notice. – Steve Howard Dec 05 '11 at 14:40
  • 2
    Simple, elegant, no install and no writing a batch files for a one shot command and can time every step in a batch file. – Matt Apr 16 '19 at 08:56
27

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.

Abe Voelker
  • 25,576
  • 13
  • 76
  • 95
  • 42
    When answering Windows questions, Cygwin is considered cheating :-) – mivk Dec 13 '11 at 22:08
  • 15
    He has stipulated that ResourceKit, TimeMem, ptime.exe, PowerShell and other utilities users started to cheat first. Therefore, author has made your comment inappropriate before you wrote it. – Val Jul 11 '13 at 17:59
  • I have also upvoted this since I found it the easiest solution since the free program Cmder includes bash! http://cmder.net/ Just remember that if you need to escape spaces in bash, use a blackslash \ just before the space, instead of "quotes". eg, cd /c/Program\ Files/ – lukescammell Jun 01 '17 at 15:52
24

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:
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
JohnW
  • 2,872
  • 1
  • 24
  • 29
  • 2
    Assuming you don't need portability across different languages you can also put a findstr "current" or something like that after the "time < nul" (nice usage of nul by the way; I've always used echo.|time, but that doesn't look as elegant :)). And use "for" to extract only the time, not the text. – Joey Mar 23 '09 at 18:24
  • 2
    If command extensions are enabled (that is, the default), the Win XP version of `time` has a `/t` option which just displays the current system time, without prompting you to enter a new time. However when you do that it only displays hours and minutes, which might not be good enough for some usages. (See John Snow's answer to this question.) – martineau Jan 23 '11 at 18:34
  • 3
    `time /T` is usable only if the process runs for several minutes! `time < nul` is uglier but more precise. – PhiLho Jun 04 '13 at 10:59
  • 6
    You could also use `echo %time%` which provides the same format and precision as `time < nul`, but you avoid the `Enter the new time:` output... – aschipfl Sep 01 '15 at 23:55
  • for locale-independent amd more precise time use [`wmic os get LocalDateTime`](https://stackoverflow.com/q/15378719/995714) – phuclv Jul 11 '17 at 02:34
18

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.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
pepoluan
  • 4,819
  • 3
  • 32
  • 60
  • 4
    I don't think using a third party application could be considered doing it "with standard means". – martineau Jan 23 '11 at 18:37
  • 4
    The questioner meant "without installing additional software", but then the top (accepted) answer also requires installing a whole Windows 2003 Resource Kit! Anyway, timer.exe was perfect for what I was just looking for, thanks! – Hugo May 27 '11 at 10:32
  • 1
    This is a planted link. SoftPedia is a click farm. – Tom A Sep 04 '12 at 23:47
  • @Tom please explain, what do you mean "planted link"? – pepoluan Sep 06 '12 at 08:26
  • @pepoluan: Every link on that page just opens another window with more ads. None of them start an actual download. It was a very frustrating waste of time for me. I think one of the second-page links even tried to install a download manager exe -- like I would trust software from a site like that! – Tom A Sep 07 '12 at 20:27
  • @Tom something is *very* wrong with your computer. I just tried, and within 4 clicks, I already got the file. Either some plugin messes up your browser, or a trojan messes up your DNS, or your ISP fscking you up. – pepoluan Sep 08 '12 at 02:39
  • @pepoluan. I am using IE 10 n Win 8. I get the same experience with compatibility mode.The word "download" appears 4 times on the page at your link. NONE of them start a download, NONE of them take you to a page where you download with one click. Every instance of a "download" link is actually an AD. Why would it take 4 clicks? – Tom A Sep 09 '12 at 00:10
  • @Tom the page I linked to is the description page of the utility. There's a big blue "Download" button there. Click that, and it brings you to the "mirrors" page, where one can choose which mirror to use. Click on a mirror, and the download dialog box of Firefox appears. Another click to choose DownThemAll, another click on OK. Done. Four clicks total. – pepoluan Sep 09 '12 at 04:47
  • @pepoluan, when *I* click the big, blue download button it takes me to a page that *appears* generally to be a download page, but the text on the page indicates it is about to install a PDF Reader, not the GS Timer app I am looking for. There is quite a bit of text on the page. Here is how it starts: "Click Download to begin" (Sounds good), then "Easy & Secure, Instant download, Installs in seconds". (Huh?) Then, "Clicking this Download button starts InstallQ ™ it manages your Expert PDF Reader installation..." Then more PDF Reader description. Maybe *your* browser is different. – Tom A Sep 09 '12 at 05:37
  • @Tom *my* browser is different? I *just* tried using Firefox, Chrome, and Internet Explorer... and I even tried using Dolphin on my Android phone. And **ALL** of them gave the same result, i.e., Desc page --> Mirror page --> Download. Stop blaming me for your apparent inability to download from your system! ... PS: I'll gladly upload screenshots on how I *successfully* downloaded using all 4 browsers, if you want. – pepoluan Sep 09 '12 at 11:04
  • @Tom on second thought... here's an album containing the screencaps of all 4 browsers: http://www.xs.to/u/pepoluan/albums/11689 . Firefox has NoScript and AdBlockPlus, so ads do not show. My Android phone has a tweaked `/etc/hosts` file to block ads. IE has Symantec plugin. Chrome is vanilla. All of them goes through the same ISP (Three) and the same DNS Provider (GoogleDNS) – pepoluan Sep 09 '12 at 11:32
  • @pepoluan: Wow, an ad blocker makes a big difference -- you should see the page without one, then imagine you are visiting the site for the first time and haven't memorized the location of the genuine download button. Most of the ads contain download buttons. – Tom A Sep 09 '12 at 14:17
  • @Tom hahaha... yeah, that's the annoying part of Softpedia... it's gotta be one of the most ad-infested software review site I've ever visited... but I can't complain with their collection... – pepoluan Sep 11 '12 at 01:40
  • 10
    Here's a direct link to the developer's own page: http://www.gammadyne.com/cmdline.htm#timer – Hugo Jan 15 '14 at 10:07
  • This also works for anyone using cmder out-of-the-box I believe – youngrrrr Nov 03 '17 at 01:49
15

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 <jberkes@pc-tools.net>

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 <jberkes@pc-tools.net>

===  cd ===
C:\

Execution time: 0.015 s
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Murali Krishnan
  • 175
  • 1
  • 2
11

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.
driblio
  • 127
  • 1
  • 2
  • 5
    Impressive, but I don't think it works if there's an 08 or 09 in the start or end times because these are interpreted as octals. My answer handles that :) – Luke Sampson Jun 02 '11 at 01:26
10

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.

Martin Moene
  • 901
  • 11
  • 17
8

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

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Nadu
  • 2,058
  • 1
  • 20
  • 27
6

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
Rainer
  • 685
  • 7
  • 8
6

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.

Saddam M
  • 71
  • 1
  • 2
4

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).

aschipfl
  • 28,946
  • 10
  • 45
  • 77
3

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
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
ilko
  • 39
  • 2
2

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)

phuclv
  • 27,258
  • 11
  • 104
  • 360
  • I commented just that before scrolling down to your answer. Anyway, Luke's script could zero-pad hours, minutes and seconds, not just the subseconds (which are **centiseconds**, and not milliseconds, BTW). See here: http://en.wiktionary.org/wiki/centisecond – Tomasz Gandor Sep 11 '14 at 11:32
2

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.

Jeff Pratt
  • 1,483
  • 1
  • 12
  • 19
  • 3
    It doesn't look like too much work to download a little C program that would start the command, make this call (and much more advance measurements), and return the process times. – Elazar Leibovich Sep 28 '11 at 07:24
  • @ElazarLeibovich powershell? You can call it from C#. – Peter Badida Apr 10 '17 at 07:12
  • @KeyWeeUsr you can use Windows API IIRC from PS https://blogs.technet.microsoft.com/heyscriptingguy/2013/06/25/use-powershell-to-interact-with-the-windows-api-part-1/ – Elazar Leibovich Apr 11 '17 at 18:48
1
  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.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
  • 7
    time /t only gives you time in HH:MM. To time an executable, you usually needs more accuracy... Is it anything you can setup to get down to fractions of a second? I tested the sollution from JohnW (time < nul), and that actually gives the time down to 1/100s: HH:MM:SS.XX – awe Aug 17 '09 at 06:03
1
@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.
MikeM
  • 9,855
  • 2
  • 27
  • 42
1

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
  • Well instead of **recursive calling** the script, consider doing it like this `call :calc`. I did that here. [link](http://stackoverflow.com/a/34386663/3135511) Code get's some what nicer this way. :D – Nadu Dec 20 '15 at 22:51
  • **Bug #1** Will fail at the 12'th hour. Example: " **0**:23:19,42" **Bug #2** Will fail if decimal point is anything else than . same example: " 0:23:19 **,** 42" here decimal point is , <__________> Well tried to edit however that dumb**** in the 'edit approval commission' rejected it - 3 of 5 voted "This edit changes too much of the authors original intent." so if feel like try your luck editing or just keep the bugs in - so the 'authors original intent stays intact'. *facepalm* – Nadu Dec 21 '15 at 00:02
  • Can't output milliseconds when the resolution of your clock is barely capable of 1/100 second resolution. – jwdonahue Nov 09 '17 at 01:13
1

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.

Community
  • 1
  • 1
Alexander
  • 341
  • 3
  • 11
1

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.

robotik
  • 1,478
  • 1
  • 18
  • 20
1

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;
1

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.

npocmaka
  • 51,748
  • 17
  • 123
  • 166
0

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
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
bvj
  • 2,846
  • 27
  • 26
0

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
Antoni Gual Via
  • 634
  • 1
  • 6
  • 12
0

"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

Community
  • 1
  • 1
AveYo
  • 151
  • 4
0

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

mvorisek
  • 2,758
  • 1
  • 12
  • 46