X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=org.argeo.util%2Fsrc%2Forg%2Fargeo%2Futil%2FLangUtils.java;h=779adb01eb4a204dd2dc07d27bee06be386d6083;hb=1233dcea2383bfe5c83e5ec33d0c502afff22601;hp=fae6312343d0b99c267298bbecdf8567c6228fc8;hpb=029a84fb1a01e9877736db2693b8a3013b1e72a1;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.util/src/org/argeo/util/LangUtils.java b/org.argeo.util/src/org/argeo/util/LangUtils.java index fae631234..779adb01e 100644 --- a/org.argeo.util/src/org/argeo/util/LangUtils.java +++ b/org.argeo.util/src/org/argeo/util/LangUtils.java @@ -7,9 +7,14 @@ import java.io.Writer; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardOpenOption; +import java.time.ZonedDateTime; +import java.time.temporal.ChronoUnit; +import java.time.temporal.Temporal; import java.util.Dictionary; import java.util.Enumeration; +import java.util.HashMap; import java.util.Hashtable; +import java.util.Map; import java.util.Properties; import javax.naming.InvalidNameException; @@ -35,17 +40,37 @@ public class LangUtils { */ /** - * Creates a new {@link Dictionary} with one key-value pair (neither key not - * value should be null) + * Creates a new {@link Dictionary} with one key-value pair. Key should not be + * null, but if the value is null, it returns an empty {@link Dictionary}. */ - public static Dictionary dico(String key, Object value) { + public static Dictionary dict(String key, Object value) { assert key != null; - assert value != null; Hashtable props = new Hashtable<>(); - props.put(key, value); + if (value != null) + props.put(key, value); return props; } + /** @deprecated Use {@link #dict(String, Object)} instead. */ + @Deprecated + public static Dictionary dico(String key, Object value) { + return dict(key, value); + } + + /** Converts a {@link Dictionary} to a {@link Map} of strings. */ + public static Map dictToStringMap(Dictionary properties) { + if (properties == null) { + return null; + } + Map res = new HashMap<>(properties.size()); + Enumeration keys = properties.keys(); + while (keys.hasMoreElements()) { + String key = keys.nextElement(); + res.put(key, properties.get(key).toString()); + } + return res; + } + /** * Wraps the keys of the provided {@link Dictionary} as an {@link Iterable}. */ @@ -157,6 +182,30 @@ public class LangUtils { chainCauseMessage(buf, t.getCause()); } + /* + * TIME + */ + /** Formats time elapsed since start. */ + public static String since(ZonedDateTime start) { + ZonedDateTime now = ZonedDateTime.now(); + return duration(start, now); + } + + /** Formats a duration. */ + public static String duration(Temporal start, Temporal end) { + long count = ChronoUnit.DAYS.between(start, end); + if (count != 0) + return count > 1 ? count + " days" : count + " day"; + count = ChronoUnit.HOURS.between(start, end); + if (count != 0) + return count > 1 ? count + " hours" : count + " hours"; + count = ChronoUnit.MINUTES.between(start, end); + if (count != 0) + return count > 1 ? count + " minutes" : count + " minute"; + count = ChronoUnit.SECONDS.between(start, end); + return count > 1 ? count + " seconds" : count + " second"; + } + /** Singleton constructor. */ private LangUtils() {