From b15dab6f71a692f626ab3d2a74f6e945844b991e Mon Sep 17 00:00:00 2001 From: Rollczi Date: Sun, 17 Aug 2025 00:34:29 +0200 Subject: [PATCH] Expand time API --- .../commons/time/TemporalAmountParser.java | 66 ++++++++++++------- .../eternalcode/commons/time/TimePart.java | 11 ++++ .../eternalcode/commons/time/TimeResult.java | 9 +++ 3 files changed, 61 insertions(+), 25 deletions(-) create mode 100644 eternalcode-commons-shared/src/main/java/com/eternalcode/commons/time/TimePart.java create mode 100644 eternalcode-commons-shared/src/main/java/com/eternalcode/commons/time/TimeResult.java diff --git a/eternalcode-commons-shared/src/main/java/com/eternalcode/commons/time/TemporalAmountParser.java b/eternalcode-commons-shared/src/main/java/com/eternalcode/commons/time/TemporalAmountParser.java index f9f40d9..8aa8d8d 100644 --- a/eternalcode-commons-shared/src/main/java/com/eternalcode/commons/time/TemporalAmountParser.java +++ b/eternalcode-commons-shared/src/main/java/com/eternalcode/commons/time/TemporalAmountParser.java @@ -295,33 +295,15 @@ public ChronoUnit getUnit() { } } - /** - * Formats the given estimated temporal amount to a string. - *

- * Examples: - *

- * - * - * @param temporalAmount the temporal amount to format. Must not be null. - * @return the formatted string - */ - public String format(T temporalAmount) { - StringBuilder builder = new StringBuilder(); + public TimeResult prepare(T temporalAmount) { + List parts = new ArrayList<>(); Duration duration = this.toDuration(this.baseForTimeEstimation, temporalAmount); for (TimeModifier modifier : this.modifiers) { duration = modifier.modify(duration); } + boolean isNegative = duration.isNegative(); if (duration.isNegative()) { - builder.append('-'); duration = duration.negated(); } @@ -345,18 +327,52 @@ public String format(T temporalAmount) { BigInteger nanosCountCleared = count.multiply(nanosInOneUnit); - builder.append(count).append(key); + parts.add(new TimePart(count, key, unit)); duration = duration.minusNanos(nanosCountCleared.longValue()); } - String result = builder.toString(); + return new TimeResult(parts, isNegative); + } - if (result.isEmpty()) { + /** + * Formats the given estimated temporal amount to a string. + *

+ * Examples: + *

+ * + * + * @param temporalAmount the temporal amount to format. Must not be null. + * @return the formatted string + */ + public String format(T temporalAmount) { + TimeResult result = this.prepare(temporalAmount); + if (result.parts().isEmpty()) { String defaultSymbol = this.defaultZeroSymbol.get(); return "0" + defaultSymbol; } - return result; + StringBuilder builder = new StringBuilder(); + if (result.isNegative()) { + builder.append('-'); + } + + for (TimePart part : result.parts()) { + if (part.count().equals(BigInteger.ZERO)) { + continue; + } + + builder.append(part.count()).append(part.name()); + } + + return builder.toString(); } protected abstract Duration toDuration(LocalDateTimeProvider baseForTimeEstimation, T temporalAmount); diff --git a/eternalcode-commons-shared/src/main/java/com/eternalcode/commons/time/TimePart.java b/eternalcode-commons-shared/src/main/java/com/eternalcode/commons/time/TimePart.java new file mode 100644 index 0000000..76ab857 --- /dev/null +++ b/eternalcode-commons-shared/src/main/java/com/eternalcode/commons/time/TimePart.java @@ -0,0 +1,11 @@ +package com.eternalcode.commons.time; + +import java.math.BigInteger; +import java.time.temporal.ChronoUnit; + +public record TimePart( + BigInteger count, + String name, + ChronoUnit unit +) { +} diff --git a/eternalcode-commons-shared/src/main/java/com/eternalcode/commons/time/TimeResult.java b/eternalcode-commons-shared/src/main/java/com/eternalcode/commons/time/TimeResult.java new file mode 100644 index 0000000..eca640c --- /dev/null +++ b/eternalcode-commons-shared/src/main/java/com/eternalcode/commons/time/TimeResult.java @@ -0,0 +1,9 @@ +package com.eternalcode.commons.time; + +import java.util.List; + +public record TimeResult( + List parts, + boolean isNegative +) { +}