142

Is there a stopwatch in Java?
On Google I only found code of stopwatches that don't work - they always return 0 milliseconds.

This code I found doesn't work and I don't see why.

public class StopWatch {
  
  private long startTime = 0;
  private long stopTime = 0;
  private boolean running = false;
  
  
  public void start() {
    this.startTime = System.currentTimeMillis();
    this.running = true;
  }
  
  
  public void stop() {
    this.stopTime = System.currentTimeMillis();
    this.running = false;
  }
  
  
  //elaspsed time in milliseconds
  public long getElapsedTime() {
    long elapsed;
    if (running) {
      elapsed = (System.currentTimeMillis() - startTime);
    } else {
      elapsed = (stopTime - startTime);
    }
    return elapsed;
  }
  
  
  //elaspsed time in seconds
  public long getElapsedTimeSecs() {
    long elapsed;
    if (running) {
      elapsed = ((System.currentTimeMillis() - startTime) / 1000);
    } else {
      elapsed = ((stopTime - startTime) / 1000);
    }
    return elapsed;
  }
}
Ola Ström
  • 4,136
  • 5
  • 22
  • 41
user1007522
  • 7,858
  • 17
  • 69
  • 113
  • 10
    And how do you determin it didn't work ? (perhaps you're measuring something that takes less time to execute than the accuracy of System.currentTimeMillis()) – nos Nov 24 '11 at 10:44
  • 5
    Please post the code how you are testing this class... – DXTR66 Nov 24 '11 at 10:45
  • 2
    Just wanted to note that this is one of the textbook questions in "Introduction to Java Programming, Comprehensive Version (9th Edition)". – Sam Sep 23 '16 at 02:35
  • 4
    Please don't use `currentTimeMillis()` for production, as it's **tied to system date/time and is not guaranteed to be monotonous** (e.g. you can get negative elapsed time). For measuring time use `nanoTime()` – it's guaranteed to be monotonous and intended exactly for measuring purpose. See https://docs.oracle.com/javase/8/docs/api/java/lang/System.html#nanoTime-- – Nikita Bosik Feb 20 '18 at 15:02

18 Answers18

108

You'll find one in

http://commons.apache.org/lang/

It's called

org.apache.commons.lang.time.StopWatch

But it roughly does the same as yours. If you're in for more precision, use

System.nanoTime()

See also this question here:

Time measuring overhead in Java

Community
  • 1
  • 1
Lukas Eder
  • 211,314
  • 129
  • 689
  • 1,509
100

Use Guava's Stopwatch class.

An object that measures elapsed time in nanoseconds. It is useful to measure elapsed time using this class instead of direct calls to System.nanoTime() for a few reasons:

  • An alternate time source can be substituted, for testing or performance reasons.
  • As documented by nanoTime, the value returned has no absolute meaning, and can only be interpreted as relative to another timestamp returned by nanoTime at a different time. Stopwatch is a more effective abstraction because it exposes only these relative values, not the absolute ones.
Stopwatch stopwatch = Stopwatch.createStarted();
doSomething();
stopwatch.stop(); // optional

long millis = stopwatch.elapsed(TimeUnit.MILLISECONDS);

log.info("that took: " + stopwatch); // formatted string like "12.3 ms"
Mohammed H
  • 6,880
  • 16
  • 81
  • 127
helpermethod
  • 59,493
  • 71
  • 188
  • 276
  • 4
    guavas stopwatch is missing `getStartTime()`, apache is missing `isRunning()` ahhhh – To Kra Dec 01 '15 at 13:57
  • 3
    @ToKra What would you do with the start time anyway? Since it's nano time, you can't use it for anything meaningful anyway, as described in the docs. – Hakanai Apr 07 '17 at 04:37
  • 1
    Now you use this to get the milliseconds: long stopWatch = stopWatch.elapsed(TimeUnit.MILLISECONDS); – PHPGuru Mar 14 '18 at 17:41
  • Which guava version is it? I used 1.8 and it didn't find the Stopwatch class – Laser Infinite Feb 10 '20 at 23:28
85

Now you can try something like:

Instant starts = Instant.now();
Thread.sleep(10);
Instant ends = Instant.now();
System.out.println(Duration.between(starts, ends));

Output is in ISO 8601.

Valtoni Boaventura
  • 1,519
  • 12
  • 13
58

Spring provides an elegant org.springframework.util.StopWatch class (spring-core module).

StopWatch stopWatch = new StopWatch();

stopWatch.start();
// Do something
stopWatch.stop();

System.out.println(stopWatch.getTotalTimeMillis());
informatik01
  • 16,038
  • 10
  • 74
  • 104
Larsen
  • 764
  • 1
  • 7
  • 13
8

The code doesn't work because elapsed variable in getElapsedTimeSecs() is not a float or double.

KristofMols
  • 3,487
  • 2
  • 38
  • 48
asfer
  • 3,525
  • 1
  • 21
  • 16
8

There's no built in Stopwatch utility but as of JSR-310 (Java 8 Time) you can do this simply.

ZonedDateTime now = ZonedDateTime.now();
// Do stuff
long seconds = now.until(ZonedDateTime.now(), ChronoUnit.SECONDS);

I haven't benchmarked this properly but I would guess using Guava's Stopwatch is more effective.

matsa
  • 346
  • 5
  • 16
6

Use System.currentTimeMillis() to get the start time and the end time and calculate the difference.

class TimeTest1 {
  public static void main(String[] args) {

    long startTime = System.currentTimeMillis();

    long total = 0;
    for (int i = 0; i < 10000000; i++) {
      total += i;
    }

    long stopTime = System.currentTimeMillis();
    long elapsedTime = stopTime - startTime;
    System.out.println(elapsedTime);
  }
} 

More info at this tutorial

user2374612
  • 115
  • 1
  • 4
  • 1
    As said elsewhere, currentTimeMillis() is tied to system date/time and is not guaranteed to be monotonous (e.g. you can get negative elapsed time). – oligofren Jun 06 '19 at 09:31
  • Do not use System.currentTimeMillis() to measure elapsed time. – Valdemar Feb 20 '23 at 11:47
3

Try this:

/*
 * calculates elapsed time in the form hrs:mins:secs
 */
public class StopWatch
{ 
    private Date startTime;

    public void startTiming()
    {
        startTime = new Date();
    }

    public String stopTiming()
    {
        Date stopTime = new Date();
        long timediff = (stopTime.getTime() - startTime.getTime())/1000L;
        return(DateUtils.formatElapsedTime(timediff));
    }

}

Use:

StopWatch sw = new StopWatch();
...
sw.startTiming();
...
String interval = sw.stopTiming();
Oke Uwechue
  • 479
  • 5
  • 4
  • 2
    DateUtils is part of Apache Commons, why not just use their StopWatch? – Bill Effin Murray Oct 29 '14 at 22:56
  • In most cases you'll use some common library like mentioned in other answers (Apache Commons for instance). You can even take only parts of the library with if you don't need everything. – Guy Mar 15 '16 at 12:29
3

use : com.google.common.base.Stopwatch, its simple and easy.

<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>23.0</version>
</dependency>

example:

Stopwatch stopwatch = new Stopwatch();
stopwatch.start();

"Do something"

logger.debug("this task took " + stopwatch.stop().elapsedTime(TimeUnit.MILLISECONDS) + " mills");

this task took 112 mills

Luke_P
  • 659
  • 2
  • 7
  • 23
2

try this

import java.awt.event.*;

import java.awt.*;

import javax.swing.*;

public class millis extends JFrame implements ActionListener, Runnable
    {

     private long startTime;
     private final static java.text.SimpleDateFormat timerFormat = new java.text.SimpleDateFormat("mm : ss.SSS");
     private final JButton startStopButton= new JButton("Start/stop");
     private Thread updater;
     private boolean isRunning= false;
     private final Runnable displayUpdater= new Runnable()
         {
         public void run()
             {
             displayElapsedTime(System.currentTimeMillis() - millis.this.startTime);
         }
     };
     public void actionPerformed(ActionEvent ae)
         {
         if(isRunning)
             {
             long elapsed= System.currentTimeMillis() - startTime;
             isRunning= false;
             try
                 {
                 updater.join();
                 // Wait for updater to finish
             }
             catch(InterruptedException ie) {}
             displayElapsedTime(elapsed);
             // Display the end-result
         }
         else
             {
             startTime= System.currentTimeMillis();
             isRunning= true;
             updater= new Thread(this);
             updater.start();
         }
     }
     private void displayElapsedTime(long elapsedTime)
         {
         startStopButton.setText(timerFormat.format(new java.util.Date(elapsedTime)));
     }
     public void run()
         {
         try
             {
             while(isRunning)
                 {
                 SwingUtilities.invokeAndWait(displayUpdater);
                 Thread.sleep(50);
             }
         }
         catch(java.lang.reflect.InvocationTargetException ite)
             {
             ite.printStackTrace(System.err);
             // Should never happen!
         }
         catch(InterruptedException ie) {}
         // Ignore and return!
     }
     public millis()
         {
         startStopButton.addActionListener(this);
         getContentPane().add(startStopButton);
         setSize(100,50);
         setVisible(true);
     }
     public static void main(String[] arg)
         {
         new Stopwatch().addWindowListener(new WindowAdapter()
             {
             public void windowClosing(WindowEvent e)
                 {
                 System.exit(0);
             }
         });
         millis s=new millis();
         s.run();
     }
}
andrewsi
  • 10,807
  • 132
  • 35
  • 51
  • 1
    As said elsewhere, currentTimeMillis() is tied to system date/time and is not guaranteed to be monotonous (e.g. you can get negative elapsed time). – oligofren Jun 06 '19 at 09:31
2

try this http://introcs.cs.princeton.edu/java/stdlib/Stopwatch.java.html

that's very easy

Stopwatch st = new Stopwatch();
// Do smth. here
double time = st.elapsedTime(); // the result in millis

This class is a part of stdlib.jar

ikos23
  • 4,879
  • 10
  • 41
  • 60
2

Simple out of the box Stopwatch class:

import java.time.Duration;
import java.time.Instant;

public class StopWatch {

    Instant startTime, endTime;
    Duration duration;
    boolean isRunning = false;

    public void start() {
        if (isRunning) {
            throw new RuntimeException("Stopwatch is already running.");
        }
        this.isRunning = true;
        startTime = Instant.now();
    }

    public Duration stop() {
        this.endTime = Instant.now();
        if (!isRunning) {
            throw new RuntimeException("Stopwatch has not been started yet");
        }
        isRunning = false;
        Duration result = Duration.between(startTime, endTime);
        if (this.duration == null) {
            this.duration = result;
        } else {
            this.duration = duration.plus(result);
        }

        return this.getElapsedTime();
    }

    public Duration getElapsedTime() {
        return this.duration;
    }

    public void reset() {
        if (this.isRunning) {
            this.stop();
        }
        this.duration = null;
    }
}

Usage:

StopWatch sw = new StopWatch();
sw.start();
    // doWork()
sw.stop();
System.out.println( sw.getElapsedTime().toMillis() + "ms");
Jonas_Hess
  • 1,874
  • 1
  • 22
  • 32
2

Try this.

public class StopWatch { 

      private long startTime = 0;
      private long stopTime = 0;

      public StopWatch()
      {
            startTime = System.currentTimeMillis();
      }

      public void start() {
        startTime = System.currentTimeMillis();
      }

      public void stop() {
        stopTime = System.currentTimeMillis();
        System.out.println("StopWatch: " + getElapsedTime() + " milliseconds.");
        System.out.println("StopWatch: " + getElapsedTimeSecs() + " seconds.");
      }

      /**
       * @param process_name
       */
      public void stop(String process_name) {
            stopTime = System.currentTimeMillis();
            System.out.println(process_name + " StopWatch: " + getElapsedTime() + " milliseconds.");
            System.out.println(process_name + " StopWatch: " + getElapsedTimeSecs() + " seconds.");
      }      

      //elaspsed time in milliseconds
      public long getElapsedTime() {
          return stopTime - startTime;
      }

      //elaspsed time in seconds
      public double getElapsedTimeSecs() {
        double elapsed;
          elapsed = ((double)(stopTime - startTime)) / 1000;
        return elapsed;
      }
} 

Usage:

StopWatch watch = new StopWatch();
// do something
watch.stop();

Console:

StopWatch: 143 milliseconds.
StopWatch: 0.143 seconds.
K.S
  • 105
  • 1
  • 4
  • Although this may or may not be what was being asked for in the question, your answer helped me with my problem. Thank you. – Toiletduck Oct 16 '18 at 06:51
  • 1
    `currentTimeMillis()` is tied to system date/time and is not guaranteed to be monotonous (e.g. you can get negative elapsed time). – oligofren Jun 06 '19 at 09:29
  • 1
    If you decide to build your own, just use `System.nanoTime()` to always get correct results. – oligofren Jun 06 '19 at 09:40
2

Performetrics provides a convenient Stopwatch class, just the way you need. It can measure wall-clock time and more: it also measures CPU time (user time and system time) if you need. It's small, free and you can download from Maven Central. More information and examples can be found here: https://obvj.net/performetrics

Stopwatch sw = new Stopwatch();
sw.start();

// Your code

sw.stop();
sw.printStatistics(System.out);

// Sample output:
// +-----------------+----------------------+--------------+
// | Counter         |         Elapsed time | Time unit    |
// +-----------------+----------------------+--------------+
// | Wall clock time |             85605718 | nanoseconds  |
// | CPU time        |             78000500 | nanoseconds  |
// | User time       |             62400400 | nanoseconds  |
// | System time     |             15600100 | nanoseconds  |
// +-----------------+----------------------+--------------+

You can convert the metrics to any time unit (nanoseconds, milliseconds, seconds, etc...)

PS: I am the author of the tool.

Oswaldo Junior
  • 116
  • 1
  • 5
1

You can find a convenient one here:

https://github.com/varra4u/utils4j/blob/master/src/main/java/com/varra/util/StopWatch.java

Usage:

final StopWatch timer = new StopWatch();
System.out.println("Timer: " + timer);
System.out.println("ElapsedTime: " + timer.getElapsedTime());
varra
  • 164
  • 8
1

Try this.

Java Stopwatch Fully Working Solution

Here you will get a fully working solution.

Just a snippet from the above-linked solution:

You can create a class like below code and use this class' start and stop method before and after the code section, you want to measure the time taken.

public class Stopwatch{
  private long startTime;
  private long stopTime;

  /**
   starting the stop watch.
  */
  public void start(){
        startTime = System.nanoTime();
  }

  /**
   stopping the stop watch.
  */
  public void stop()
  {     stopTime = System.nanoTime(); }

  /**
  elapsed time in nanoseconds.
  */
  public long time(){
        return (stopTime - startTime);
  }

  public String toString(){
      return "elapsed time: " + time() + " nanoseconds.";
  }

}

Thank you.

  • 1
    While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. – AS Mackay Jul 18 '19 at 07:05
  • Thanks @ASMackay for your suggestion. I completely agree with you. – Sukriti Sarkar Jul 22 '19 at 12:57
0

Try this...

import java.util.concurrent.TimeUnit;
import com.google.common.base.Stopwatch;

public class StopwatchTest {
     
    public static void main(String[] args) throws Exception {
        Stopwatch stopwatch = Stopwatch.createStarted();
        Thread.sleep(1000 * 60);
        stopwatch.stop(); // optional
        long millis = stopwatch.elapsed(TimeUnit.MILLISECONDS);
        System.out.println("Time in milliseconds "+millis);
        System.out.println("that took: " + stopwatch);
    }
}
0

I have created a Stopwatch that has everything you might need in it.

I even documented it!

And I also compiled it for faster usage.

Here's an example:

//...
  //For demo only!
  public static void main(String[]a){
    final Stopwatch stopwatch=new Stopwatch();
    stopwatch.start();
    try{
      java.lang.Thread.sleep(1000);
    }catch(Exception e){}
    stopwatch.split();
    System.out.println("Time elapsed in nanoseconds: "+stopwatch.getTimeElapsed());
    System.out.println("Time elapsed in milliseconds: "+stopwatch.getTimeElapsed(Stopwatch.millis));
    System.out.println("Time elapsed in seconds: "+stopwatch.getTimeElapsed(Stopwatch.seconds));
    try{
      java.lang.Thread.sleep(1000);
    }catch(Exception e){}
    stopwatch.split();
    final long[][] laps=stopwatch.getLaps();
    for(long[] lap:laps){
      System.out.println(java.util.Arrays.toString(lap));
    }
  }
//...

This is not for promotion, made this to help people not waste their time in coding classes themselves!

JumperBot_
  • 551
  • 1
  • 6
  • 19