Files
JavaUtils/zeitlaeufer/src/main/java/de/szimnau/DrinkingBar.java
2025-08-11 10:50:27 +02:00

96 lines
4.3 KiB
Java

package de.szimnau;
import de.szimnau.tools.CommonTools;
import de.szimnau.tools.FormatTools;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
import static de.szimnau.tools.CommonTools.print;
public class DrinkingBar extends AbstractLoadingBar {
private static final int MINS_PER_HALF_HOUR = CommonTools.MINS_PER_HOUR / 2;
private static final int MINUTES_BEFORE_PAUSE = 4 * CommonTools.MINS_PER_HOUR + MINS_PER_HALF_HOUR;
private static final int MINUTES_WITH_PAUSE = 6 * CommonTools.MINS_PER_HOUR;
private static final int DEFAULT_TOTAL_TIME = 8 * CommonTools.MINS_PER_HOUR + MINS_PER_HALF_HOUR;
private static final BigDecimal DEFAULT_TOTAL_TIME_BD = BigDecimal.valueOf(DEFAULT_TOTAL_TIME);
private static final BigDecimal DEFAULT_TOTAL_LITRES = BigDecimal.valueOf(2.0);
private static final BigDecimal QUARTER_LITRE = BigDecimal.valueOf(0.25);
private static final DecimalFormat LITRE_FORMAT = new DecimalFormat("0.00");
private BigDecimal totalLitres;
public static void main(String[] args) throws IOException {
var br = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8));
print("Ankunftszeit: ");
var startTime = LocalTime.parse(br.readLine(), FormatTools.TIME_FORMATTER).truncatedTo(ChronoUnit.MINUTES);
var db = new DrinkingBar(startTime);
db.showLoadingBar();
}
protected DrinkingBar(LocalTime startTime) {
super(startTime, DEFAULT_TOTAL_TIME);
this.totalLitres = DEFAULT_TOTAL_LITRES;
}
@Override
protected void extraInitEndTimeTotalMinutes() {
// correct necessary litres to drink based on the end time.
// lower the volume in quarter litre steps
BigDecimal calcTotalLitres = DEFAULT_TOTAL_LITRES;
BigDecimal totalLitresFromMinutes = DEFAULT_TOTAL_LITRES
.multiply(getTotalMinutesBD()) // reverse dreisatz
.divide(DEFAULT_TOTAL_TIME_BD, MathContext.DECIMAL64);
do {
calcTotalLitres = calcTotalLitres.subtract(QUARTER_LITRE);
} while (calcTotalLitres.compareTo(totalLitresFromMinutes) >= 0);
// add quarter since we always did a step "too many", due to the do ... while loop
this.totalLitres = calcTotalLitres.add(QUARTER_LITRE);
}
@Override
protected String fillLoadingBar(long passedMinutes, boolean progressive) {
long effectivePassedMinutes = passedMinutes < 0 ? 0 : passedMinutes;
if (getTotalMinutes() > MINUTES_WITH_PAUSE && passedMinutes > MINUTES_BEFORE_PAUSE && passedMinutes <= MINUTES_WITH_PAUSE) {
effectivePassedMinutes = MINUTES_BEFORE_PAUSE;
}
var effectivePassedMinutesBD = BigDecimal.valueOf(effectivePassedMinutes);
BigDecimal currentLitres = totalLitres
.multiply(effectivePassedMinutesBD) // reverse dreisatz
.divide(getTotalMinutesBD(), MathContext.DECIMAL64)
.add(QUARTER_LITRE);
BigDecimal printedLitres = currentLitres.subtract(currentLitres.remainder(QUARTER_LITRE, MathContext.DECIMAL64));
/* BigDecimal currentProgressToNextStep = ONE_HUNDRED_PERCENT
.multiply(currentLitres.subtract(printedLitres)) // reverse dreisatz
.divide(QUARTER_LITRE, MathContext.DECIMAL64); */
BigDecimal minutesToNextStep = getMinutesToNextStep(currentLitres);
String progressivePart = progressive ? "\r" : "";
return progressivePart + "Aktuelles Volumen: " + LITRE_FORMAT.format(printedLitres) + "L - "
// + FormatTools.PERCENTAGE_FORMAT.format(currentProgressToNextStep) + "% - "
+ FormatTools.minutesToTimeString(minutesToNextStep);
}
private BigDecimal getMinutesToNextStep(BigDecimal currentLitres) {
// berechne Liter benötigt bis zum nächsten 0.25er Schritt
BigDecimal litresToNextStep = QUARTER_LITRE.subtract(currentLitres.remainder(QUARTER_LITRE));
// berechne Minuten benötigt für 1 Liter
BigDecimal minutesPerLitre = getTotalMinutesBD().divide(totalLitres, MathContext.DECIMAL64);
// berechne Minuten benötigt bis zum nächsten 0.25er Schritt
return minutesPerLitre.multiply(litresToNextStep).setScale(0, RoundingMode.HALF_EVEN);
}
}