diff --git a/src/main/java/org/apache/commons/lang3/time/StopWatch.java b/src/main/java/org/apache/commons/lang3/time/StopWatch.java index d3b939832b4..0c53260af35 100644 --- a/src/main/java/org/apache/commons/lang3/time/StopWatch.java +++ b/src/main/java/org/apache/commons/lang3/time/StopWatch.java @@ -228,6 +228,11 @@ public static StopWatch createStarted() { */ private long stopTimeNanos; + /** + * The lap time in nanoseconds. + */ + private long lapStartTimeNanos; + /** *
* Constructor. @@ -483,7 +488,9 @@ public void resume() { if (this.runningState != State.SUSPENDED) { throw new IllegalStateException("Stopwatch must be suspended to resume. "); } - this.startTimeNanos += System.nanoTime() - this.stopTimeNanos; + long offset = System.nanoTime() - this.stopTimeNanos; + this.startTimeNanos += offset; + this.lapStartTimeNanos += offset; this.runningState = State.RUNNING; } @@ -508,6 +515,47 @@ public void split() { this.splitState = SplitState.SPLIT; } + + /** + *
+ * Gets the time of current lap in the specified TimeUnit. Closes current lap and opens new one. + *
+ * + *+ * First lap is opened on start. + *
+ * + *+ * The resulting time will be expressed in the desired TimeUnit with any remainder rounded down. + *
+ * + * @param timeUnit the unit of time, not null + * @return the time in the specified TimeUnit, rounded down + * @since 3.12 + */ + public long lap(final TimeUnit timeUnit) { + if (this.runningState != State.RUNNING) { + throw new IllegalStateException("Stopwatch is not running. "); + } + long now = System.nanoTime(); + long lap = now - this.lapStartTimeNanos; + this.lapStartTimeNanos = now; + return timeUnit.convert(lap, TimeUnit.NANOSECONDS); + } + + /** + *+ * Shortcut for lap(TimeUnit.MILLISECONDS) + *
+ * + * @see StopWatch#lap(TimeUnit) + * @return the lap time in milliseconds + * @since 3.12 + */ + public long lap() { + return lap(TimeUnit.MILLISECONDS); + } + /** ** Starts the stopwatch. @@ -528,6 +576,7 @@ public void start() { throw new IllegalStateException("Stopwatch already started. "); } this.startTimeNanos = System.nanoTime(); + this.lapStartTimeNanos = startTimeNanos; this.startTimeMillis = System.currentTimeMillis(); this.runningState = State.RUNNING; } diff --git a/src/test/java/org/apache/commons/lang3/time/StopWatchTest.java b/src/test/java/org/apache/commons/lang3/time/StopWatchTest.java index 60d309072b7..8ad8632d0da 100644 --- a/src/test/java/org/apache/commons/lang3/time/StopWatchTest.java +++ b/src/test/java/org/apache/commons/lang3/time/StopWatchTest.java @@ -359,4 +359,18 @@ public void testToStringWithMessage() throws InterruptedException { final String splitStr = watch.toString(); assertEquals(splitStr.length(), 12 + MESSAGE.length() + 1, "Formatted split string not the correct length"); } + + @Test + public void testStopWatchLap() throws InterruptedException { + final StopWatch watch = StopWatch.createStarted(); + sleepQuietly(550); + final long lap550 = watch.lap(); + sleepQuietly(250); + final long lap250 = watch.lap(); + + assertTrue(lap550 >= 500); + assertTrue(lap550 < 700); + assertTrue(lap250 >= 200); + assertTrue(lap250 < 400); + } }