Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package org.codefilarete.tool.trace;
import javax.annotation.Nonnegative;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Set;
import org.codefilarete.tool.StringAppender;
import org.codefilarete.tool.Duo;
import org.codefilarete.tool.VisibleForTesting;
/**
* Class aimed at measuring time between 2 events.
* Basic implementation and use case : start it (done at instantiation time), then printing through {@link #toString()}.
* One can reset it with {@link #start()}.
*
* @author Guillaume Mary
*/
public class Chrono {
@VisibleForTesting
static final int MILLIS_MAX = 1000;
@VisibleForTesting
static final int SEC_MAX = 60 * MILLIS_MAX;
@VisibleForTesting
static final int MIN_MAX = 60 * SEC_MAX;
@VisibleForTesting
static final int H_MAX = 24 * MIN_MAX;
private enum TimeConstant {
DAY(H_MAX, "d"),
HOUR(MIN_MAX, "h"),
MINUTE(SEC_MAX, "min"),
SECOND(MILLIS_MAX, "s"),
MILLIS(1, "ms");
private final int millisCount;
private final String timeUnit;
TimeConstant(int millisCount, String timeUnit) {
this.millisCount = millisCount;
this.timeUnit = timeUnit;
}
private static final Set MILLIS_TIME = Collections.unmodifiableSet(EnumSet.of(MILLIS));
private static final Set SECOND_TIME = Collections.unmodifiableSet(EnumSet.of(SECOND, MILLIS));
private static final Set MINUTE_TIME = Collections.unmodifiableSet(EnumSet.of(MINUTE, SECOND, MILLIS));
private static final Set HOUR_TIME = Collections.unmodifiableSet(EnumSet.of(HOUR, MINUTE, SECOND, MILLIS));
private static final Set DAY_TIME = Collections.unmodifiableSet(EnumSet.of(DAY, HOUR, MINUTE, SECOND, MILLIS));
/**
* Gives constants (in decreasing order) necessary to format given milliseconds.
*
* @param millis any (non-null) millisecond
* @return a set of {@link TimeConstant} in decreasing order (from the biggest unit to smallest)
*/
private static Set getTimeConstantsToUse(@Nonnegative long millis) {
Set constantsToUse;
if (millis < MILLIS_MAX) {
constantsToUse = TimeConstant.MILLIS_TIME;
} else if (millis < SEC_MAX) {
constantsToUse = TimeConstant.SECOND_TIME;
} else if (millis < MIN_MAX) {
constantsToUse = TimeConstant.MINUTE_TIME;
} else if (millis < H_MAX) {
constantsToUse = TimeConstant.HOUR_TIME;
} else {
constantsToUse = TimeConstant.DAY_TIME;
}
return constantsToUse;
}
}
/**
* Formats an instant such as "1:02min 24s 103ms" (each value is optional)
*
* @param millis any (non-null) millisecond
* @return a printable representation of {@code millis}
*/
public static String format(long millis) {
if (millis == 0) { // corner case not handled by algorithm below
return "0ms";
}
StringAppender result = new StringAppender();
Set constantsToUse = TimeConstant.getTimeConstantsToUse(millis);
for (TimeConstant timeConstant : constantsToUse) {
Duo divide = divide(millis, timeConstant.millisCount);
long quotient = divide.getLeft();
// we print only what's necessary
result.catIf(quotient != 0, Long.toString(quotient), timeConstant.timeUnit, " ");
millis = divide.getRight();
}
// removing last space before returning
return result.cutTail(1).toString();
}
private static Duo divide(long millis, int divisor) {
return new Duo<>(millis / divisor, millis%divisor);
}
/**
* Gives current instant
*
* @return current time in millisecond (see {@link System#currentTimeMillis()}
*/
public static long now() {
return System.currentTimeMillis();
}
private long startTime;
/** Creates a new instance that starts immediately */
public Chrono () {
start();
}
/**
* Returns start time
* @return start time (in milliseconds)
*/
public long getStartTime() {
return this.startTime;
}
/**
* Starts this chronometer
* @return start time (which means now !)
*/
public long start() {
return startTime = now();
}
/**
* Gives spent time since this chronometer starts
* @return the difference between start time and now, in millis
*/
public long getElapsedTime() {
return now() - startTime;
}
/**
* Format spent time since this chronometer's start time
* @see Chrono#format
* @see Chrono#getElapsedTime
*/
@Override
public String toString() {
return format(getElapsedTime());
}
}