Improved Remaining TimeCalculator
This commit is contained in:
parent
f52a6e3d99
commit
f2e5771019
@ -56,6 +56,10 @@ public class TimeZone {
|
||||
public static boolean isTimeZoneIDValid(String timeZoneID) {
|
||||
return listOfTimeZones.contains(timeZoneID);
|
||||
}
|
||||
|
||||
public static TimeZone getDefaultTimeZone() {
|
||||
return new TimeZone(java.util.TimeZone.getDefault().getID());
|
||||
}
|
||||
private final String timeZoneID;
|
||||
|
||||
/**
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// power-framework: Java library with many purposes of usage.
|
||||
// Copyright (C) 2016-2022 the original author or authors.
|
||||
@ -17,23 +16,43 @@
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
package org.nanoboot.powerframework.time.utils;
|
||||
|
||||
import org.nanoboot.powerframework.time.duration.Duration;
|
||||
import org.nanoboot.powerframework.time.moment.TimeZone;
|
||||
import org.nanoboot.powerframework.time.moment.UniversalDateTime;
|
||||
import org.nanoboot.powerframework.utils.functions.ThreeArgFunction;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*
|
||||
* @author <a href="mailto:robertvokac@nanoboot.org">Robert Vokac</a>
|
||||
* @since 0.0.0
|
||||
*/
|
||||
public class RemainingTimeCalculator {
|
||||
|
||||
private long startNanoTime = 0;
|
||||
private long total;
|
||||
private long done = 0;
|
||||
|
||||
public static void main(String[] args) {
|
||||
//Test
|
||||
RemainingTimeCalculator rtc = new RemainingTimeCalculator(1000);
|
||||
for(int i = 0;i< 1000;i++) {
|
||||
try {
|
||||
Thread.sleep((long) (Math.random() * 500));
|
||||
} catch (InterruptedException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
rtc.nextDone();
|
||||
System.out.println(rtc.currentStatus());
|
||||
}
|
||||
}
|
||||
public RemainingTimeCalculator(final int total) {
|
||||
this.total = total;
|
||||
this.start();
|
||||
}
|
||||
|
||||
private void start() {
|
||||
this.startNanoTime = System.nanoTime();
|
||||
}
|
||||
@ -41,7 +60,8 @@ public class RemainingTimeCalculator {
|
||||
private boolean started() {
|
||||
return this.startNanoTime != 0;
|
||||
}
|
||||
public long elapsedSecondSinceStart() {
|
||||
|
||||
public long getElapsedSecondsSinceStart() {
|
||||
return (System.nanoTime() - this.startNanoTime) / 1000000000;
|
||||
}
|
||||
|
||||
@ -52,18 +72,99 @@ public class RemainingTimeCalculator {
|
||||
}
|
||||
}
|
||||
|
||||
public long remainingSecondsUntilEnd() {
|
||||
long remains = this.total - this.done;
|
||||
double elapsedSecondSinceStartDouble = (double) elapsedSecondSinceStart();
|
||||
long remainsSeconds = (long)((elapsedSecondSinceStartDouble / ((double)this.done)) * remains);
|
||||
return remainsSeconds;
|
||||
public String getProgressAsPrettyString() {
|
||||
return String.format("%,.2f", getProgress()) + "%";
|
||||
}
|
||||
|
||||
public double getProgress() {
|
||||
return ((double) getDoneCount()) / ((double) getTotalCount());
|
||||
}
|
||||
|
||||
public int getProgressInt() {
|
||||
return (int) getProgress();
|
||||
}
|
||||
|
||||
public long getRemainsCount() {
|
||||
return getTotalCount() - getDoneCount();
|
||||
}
|
||||
|
||||
public double getSecondsPerTask() {
|
||||
return ((double) getElapsedSecondsSinceStart()) / ((double) getDoneCount());
|
||||
}
|
||||
|
||||
public double getTasksPerSecond() {
|
||||
return ((double) getDoneCount()) / ((double) getElapsedSecondsSinceStart());
|
||||
}
|
||||
|
||||
public String getTasksPerSecondAsPrettyString() {
|
||||
return String.format("%,.1f", getTasksPerSecond()) + " tasks/s";
|
||||
}
|
||||
|
||||
public long getRemainingSecondsUntilEnd() {
|
||||
return (long) (getSecondsPerTask() * getRemainsCount());
|
||||
}
|
||||
|
||||
public long getDoneCount() {
|
||||
return this.done;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return "Elapsed=" + this.elapsedSecondSinceStart() + " seconds Left=" + this.remainingSecondsUntilEnd() + " seconds Done=" + this.getDoneCount() + " tasks.";
|
||||
public long getTotalCount() {
|
||||
return this.total;
|
||||
}
|
||||
|
||||
private static final String PLACEHOLDER_DONE = "{DONE}";
|
||||
private static final String PLACEHOLDER_TOTAL = "{TOTAL}";
|
||||
private static final String PLACEHOLDER_PROGRESS = "{PROGRESS}";
|
||||
private static final String PLACEHOLDER_PROGRESS_BAR = "{PROGRESS_BAR}";
|
||||
private static final String PLACEHOLDER_ELAPSED = "{ELAPSED}";
|
||||
private static final String PLACEHOLDER_LEFT = "{LEFT}";
|
||||
private static final String PLACEHOLDER_TASKS_PER_SECOND = "{TASKS_PER_SECOND}";
|
||||
private static final String PLACEHOLDER_TIME_OF_COMPLETION = "{TIME_OF_COMPLETION}";
|
||||
private static final String PLACEHOLDER_ELAPSED_LONG = "{ELAPSED_LONG}";
|
||||
private static final String PLACEHOLDER_LEFT_LONG = "{LEFT_LONG}";
|
||||
private static final String DEFAULT_STATUS_TEMPLATE = "Done {DONE}/{TOTAL} {PROGRESS} {PROGRESS_BAR} Elapsed={ELAPSED_LONG} LEFT={LEFT_LONG} PERFORMANCE={TASKS_PER_SECOND} Will finish at={TIME_OF_COMPLETION}";
|
||||
|
||||
public String currentStatus() {
|
||||
return currentStatus(null);
|
||||
}
|
||||
|
||||
public String currentStatus(String statusTemplate) {
|
||||
String returnThis = statusTemplate == null ? DEFAULT_STATUS_TEMPLATE : statusTemplate;
|
||||
ThreeArgFunction<String, String, Object, String> replaceIfNeeded = (result, placeholder, value) -> result.contains(placeholder) ? result.replace(placeholder, String.valueOf(value)) : result;
|
||||
returnThis = replaceIfNeeded.apply(returnThis, PLACEHOLDER_DONE, getDoneCount());
|
||||
returnThis = replaceIfNeeded.apply(returnThis, PLACEHOLDER_TOTAL, getTotalCount());
|
||||
returnThis = replaceIfNeeded.apply(returnThis, PLACEHOLDER_PROGRESS, getProgressAsPrettyString());
|
||||
returnThis = replaceIfNeeded.apply(returnThis, PLACEHOLDER_PROGRESS_BAR, getProgressBar());
|
||||
returnThis = replaceIfNeeded.apply(returnThis, PLACEHOLDER_ELAPSED, Duration.of(getElapsedSecondsSinceStart(), TimeUnit.SECOND).toString());
|
||||
Duration remainsDuration = Duration.of(getRemainingSecondsUntilEnd(), TimeUnit.SECOND);
|
||||
returnThis = replaceIfNeeded.apply(returnThis, PLACEHOLDER_LEFT, remainsDuration.toString());
|
||||
returnThis = replaceIfNeeded.apply(returnThis, PLACEHOLDER_TASKS_PER_SECOND, getTasksPerSecondAsPrettyString());
|
||||
String timeOfCompletion = getTimeOfCompletion();
|
||||
returnThis = replaceIfNeeded.apply(returnThis, PLACEHOLDER_TIME_OF_COMPLETION, timeOfCompletion);
|
||||
returnThis = replaceIfNeeded.apply(returnThis, PLACEHOLDER_ELAPSED_LONG, "\"" + Duration.of(getElapsedSecondsSinceStart(), TimeUnit.SECOND).toHumanString() + "\"");
|
||||
returnThis = replaceIfNeeded.apply(returnThis, PLACEHOLDER_LEFT_LONG, "\"" + Duration.of(getRemainingSecondsUntilEnd(), TimeUnit.SECOND).toHumanString() + "\"");
|
||||
if (returnThis.contains("{") || returnThis.contains("}")) {
|
||||
throw new TimeException("Cannot use built template. It is not valid (It still contains '{' or '}'): " + returnThis);
|
||||
}
|
||||
return returnThis;
|
||||
}
|
||||
/**
|
||||
* Returns text representation of progress.
|
||||
* @return text representation of progress
|
||||
*/
|
||||
public String getProgressBar() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("[");
|
||||
int percentProgress = getProgressInt() / 10;
|
||||
for (int i = 1; i <= (100 / 10); i++) {
|
||||
sb.append(i <= percentProgress ? "#" : " ");
|
||||
}
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String getTimeOfCompletion() {
|
||||
Duration remainsDuration = Duration.of(getRemainingSecondsUntilEnd(), TimeUnit.SECOND);
|
||||
return UniversalDateTime.now().plusDuration(remainsDuration).convertToZonedDateTimeWithUniversalTimeZone().toZonedDateTime(TimeZone.getDefaultTimeZone()).toString();
|
||||
}
|
||||
}
|
||||
|
@ -33,4 +33,5 @@ module powerframework.utils {
|
||||
exports org.nanoboot.powerframework.utils;
|
||||
exports org.nanoboot.powerframework.utils.annotations;
|
||||
exports org.nanoboot.powerframework.utils.dependencies;
|
||||
exports org.nanoboot.powerframework.utils.functions;
|
||||
}
|
||||
|
@ -0,0 +1,31 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// power-framework: Java library with many purposes of usage.
|
||||
// Copyright (C) 2016-2023 the original author or authors.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation;
|
||||
// version 2.1 of the License only.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
package org.nanoboot.powerframework.utils.functions;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author <a href="mailto:robertvokac@nanoboot.org">Robert Vokac</a>
|
||||
* @since 2.0.1
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ThreeArgFunction<T, U, V, R> {
|
||||
|
||||
R apply(T t, U u, V v);
|
||||
}
|
Reference in New Issue
Block a user