Skip to content

Instantly share code, notes, and snippets.

@dtonhofer
Created July 19, 2022 19:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dtonhofer/e2a0603a2eff556b37f4c07b20d193d3 to your computer and use it in GitHub Desktop.
Save dtonhofer/e2a0603a2eff556b37f4c07b20d193d3 to your computer and use it in GitHub Desktop.
A simple printer for the Java "Duration" type
// Licensed under "The Unlicense" - https://unlicense.org/
package backup.helpers;
import org.jetbrains.annotations.NotNull;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.*;
public abstract class DurationPrinter {
private final static Map<ChronoUnit, StringSet> stringsOfChronoUnit;
static {
Map<ChronoUnit, StringSet> tmp = new HashMap<>();
tmp.put(ChronoUnit.DAYS, new StringSet("day", "days"));
tmp.put(ChronoUnit.HOURS, new StringSet("hour", "hours"));
tmp.put(ChronoUnit.MINUTES, new StringSet("min", "mins"));
tmp.put(ChronoUnit.SECONDS, new StringSet("s", "s"));
tmp.put(ChronoUnit.MILLIS, new StringSet("ms", "ms"));
stringsOfChronoUnit = Collections.unmodifiableMap(tmp);
}
private static class StringSet {
private final String usual;
private final String mono;
public StringSet(@NotNull String mono, @NotNull String usual) {
this.mono = mono;
this.usual = usual;
}
public String of(int count) {
if (count == 1) {
return mono;
} else {
return usual;
}
}
}
private static void stringify(@NotNull List<String> res, int count, @NotNull ChronoUnit unit) {
if (count == 0 && res.isEmpty() && !ChronoUnit.MILLIS.equals(unit)) {
// suppress adding anything unless something already exists and this is not "seconds" (because
// we print at least seconds)
} else {
StringSet ss = stringsOfChronoUnit.get(unit);
if (!res.isEmpty()) {
res.add(", "); // separator
}
res.add(Integer.toString(count));
res.add(" ");
if (ss == null) {
// missing chrono unit!?!
res.add(unit.toString());
} else {
res.add(ss.of(count));
}
}
}
// ---
// Simple helper to print duration
// https://stackoverflow.com/questions/3471397/how-can-i-pretty-print-a-duration-in-java
// ---
public static String formatDuration(Duration duration) {
List<String> parts = new ArrayList<>(10);
stringify(parts, (int) (duration.toDaysPart()), ChronoUnit.DAYS);
stringify(parts, duration.toHoursPart(), ChronoUnit.HOURS);
stringify(parts, duration.toMinutesPart(), ChronoUnit.MINUTES);
stringify(parts, duration.toSecondsPart(), ChronoUnit.SECONDS);
stringify(parts, duration.toMillisPart(), ChronoUnit.MILLIS);
return String.join("", parts);
}
}
// Licensed under "The Unlicense" - https://unlicense.org/
package backup;
import backup.helpers.DurationPrinter;
import org.junit.jupiter.api.Test;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.SortedMap;
import java.util.TreeMap;
import static org.assertj.core.api.Assertions.assertThat;
public class TestDurationPrinter {
@Test
void testDurationPrinter() {
SortedMap<Duration,String> durs = new TreeMap<>();
durs.put(Duration.of(0, ChronoUnit.MILLIS),"0 ms");
durs.put(Duration.of(1000, ChronoUnit.MILLIS),"1 s, 0 ms");
durs.put(Duration.of(1500, ChronoUnit.MILLIS),"1 s, 500 ms");
durs.put(Duration.of(60000, ChronoUnit.MILLIS),"1 min, 0 s, 0 ms");
durs.put(Duration.of(120000, ChronoUnit.MILLIS),"2 mins, 0 s, 0 ms");
durs.put(Duration.of(122222, ChronoUnit.MILLIS),"2 mins, 2 s, 222 ms");
durs.put(Duration.of(5677821, ChronoUnit.MILLIS),"1 hour, 34 mins, 37 s, 821 ms");
durs.put(Duration.of(861862066L, ChronoUnit.MILLIS),"9 days, 23 hours, 24 mins, 22 s, 66 ms");
durs.put(Duration.of(9877461771L, ChronoUnit.MILLIS),"114 days, 7 hours, 44 mins, 21 s, 771 ms");
durs.keySet().forEach( dur -> assertThat(DurationPrinter.formatDuration(dur)).isEqualTo(durs.get(dur)));
/*
for (long l = 0; l < 9877461771L; l += 533) {
System.out.println(l + " == " + DurationPrinter.formatDuration(Duration.of(l, ChronoUnit.MILLIS)));
}
*/
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment