Skip to content

Commit 2b82829

Browse files
author
michaldo
committed
Implement StopWatch lap
Example: StopWatch watch = StopWatch.createStarted(); sleep(30ms) watch.lap() // returns 30 sleep(10ms) watch.lap() // returns 10
1 parent a149529 commit 2b82829

File tree

2 files changed

+64
-1
lines changed

2 files changed

+64
-1
lines changed

src/main/java/org/apache/commons/lang3/time/StopWatch.java

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,11 @@ public static StopWatch createStarted() {
228228
*/
229229
private long stopTimeNanos;
230230

231+
/**
232+
* The lap time in nanoseconds.
233+
*/
234+
private long lapStartTimeNanos;
235+
231236
/**
232237
* <p>
233238
* Constructor.
@@ -483,7 +488,9 @@ public void resume() {
483488
if (this.runningState != State.SUSPENDED) {
484489
throw new IllegalStateException("Stopwatch must be suspended to resume. ");
485490
}
486-
this.startTimeNanos += System.nanoTime() - this.stopTimeNanos;
491+
long offset = System.nanoTime() - this.stopTimeNanos;
492+
this.startTimeNanos += offset;
493+
this.lapStartTimeNanos += offset;
487494
this.runningState = State.RUNNING;
488495
}
489496

@@ -508,6 +515,47 @@ public void split() {
508515
this.splitState = SplitState.SPLIT;
509516
}
510517

518+
519+
/**
520+
* <p>
521+
* Gets the time of current lap in the specified TimeUnit. Closes current lap and opens new one.
522+
* </p>
523+
*
524+
* <p>
525+
* First lap is opened on start.
526+
* </p>
527+
*
528+
* <p>
529+
* The resulting time will be expressed in the desired TimeUnit with any remainder rounded down.
530+
* </p>
531+
*
532+
* @param timeUnit the unit of time, not null
533+
* @return the time in the specified TimeUnit, rounded down
534+
* @since 3.12
535+
*/
536+
public long lap(final TimeUnit timeUnit) {
537+
if (this.runningState != State.RUNNING) {
538+
throw new IllegalStateException("Stopwatch is not running. ");
539+
}
540+
long now = System.nanoTime();
541+
long lap = now - this.lapStartTimeNanos;
542+
this.lapStartTimeNanos = now;
543+
return timeUnit.convert(lap, TimeUnit.NANOSECONDS);
544+
}
545+
546+
/**
547+
* <p>
548+
* Shortcut for lap(TimeUnit.MILLISECONDS)
549+
* </p>
550+
*
551+
* @see StopWatch#lap(TimeUnit)
552+
* @return the lap time in milliseconds
553+
* @since 3.12
554+
*/
555+
public long lap() {
556+
return lap(TimeUnit.MILLISECONDS);
557+
}
558+
511559
/**
512560
* <p>
513561
* Starts the stopwatch.
@@ -528,6 +576,7 @@ public void start() {
528576
throw new IllegalStateException("Stopwatch already started. ");
529577
}
530578
this.startTimeNanos = System.nanoTime();
579+
this.lapStartTimeNanos = startTimeNanos;
531580
this.startTimeMillis = System.currentTimeMillis();
532581
this.runningState = State.RUNNING;
533582
}

src/test/java/org/apache/commons/lang3/time/StopWatchTest.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,4 +359,18 @@ public void testToStringWithMessage() throws InterruptedException {
359359
final String splitStr = watch.toString();
360360
assertEquals(splitStr.length(), 12 + MESSAGE.length() + 1, "Formatted split string not the correct length");
361361
}
362+
363+
@Test
364+
public void testStopWatchLap() throws InterruptedException {
365+
final StopWatch watch = StopWatch.createStarted();
366+
sleepQuietly(550);
367+
final long lap550 = watch.lap();
368+
sleepQuietly(250);
369+
final long lap250 = watch.lap();
370+
371+
assertTrue(lap550 >= 500);
372+
assertTrue(lap550 < 700);
373+
assertTrue(lap250 >= 200);
374+
assertTrue(lap250 < 400);
375+
}
362376
}

0 commit comments

Comments
 (0)