Rework time parsing utils
This commit is contained in:
parent
d2f00c781e
commit
5acd900857
@ -1,29 +1,49 @@
|
|||||||
package wtf.beatrice.hidekobot.util;
|
package wtf.beatrice.hidekobot.util;
|
||||||
|
|
||||||
import wtf.beatrice.hidekobot.Cache;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
|
import java.time.Instant;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
|
import java.time.temporal.TemporalAccessor;
|
||||||
|
import java.time.temporal.TemporalUnit;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public class FormatUtil
|
public class FormatUtil
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a nicely formatted uptime String that omits unnecessary data
|
* Generate a nicely formatted time-diff String that omits unnecessary data
|
||||||
* (e.g. 0 days, 0 hours, 4 minutes, 32 seconds -> 4m 32s)
|
* (e.g. 0 days, 0 hours, 4 minutes, 32 seconds -> 4m 32s)
|
||||||
*
|
*
|
||||||
* @return the formatter String
|
* @return the formatted String
|
||||||
*/
|
*/
|
||||||
public static String getNiceTimeDiff(LocalDateTime start)
|
public static String getNiceTimeDiff(LocalDateTime start)
|
||||||
{
|
{
|
||||||
LocalDateTime now = LocalDateTime.now();
|
LocalDateTime now = LocalDateTime.now();
|
||||||
long uptimeSeconds = ChronoUnit.SECONDS.between(start, now);
|
long uptimeSeconds = ChronoUnit.SECONDS.between(start, now);
|
||||||
|
|
||||||
Duration uptime = Duration.ofSeconds(uptimeSeconds);
|
Duration uptime = Duration.ofSeconds(uptimeSeconds);
|
||||||
long seconds = uptime.toSecondsPart();
|
|
||||||
long minutes = uptime.toMinutesPart();
|
return getNiceDuration(uptime);
|
||||||
long hours = uptime.toHoursPart();
|
}
|
||||||
long days = uptime.toDays();
|
|
||||||
|
/**
|
||||||
|
* Generate a nicely formatted duration String that omits unnecessary data
|
||||||
|
* (e.g. 0 days, 0 hours, 4 minutes, 32 seconds -> 4m 32s)
|
||||||
|
*
|
||||||
|
* @return the formatted String
|
||||||
|
*/
|
||||||
|
public static String getNiceDuration(Duration duration)
|
||||||
|
{
|
||||||
|
long seconds = duration.toSecondsPart();
|
||||||
|
long minutes = duration.toMinutesPart();
|
||||||
|
long hours = duration.toHoursPart();
|
||||||
|
long days = duration.toDays();
|
||||||
|
|
||||||
StringBuilder uptimeStringBuilder = new StringBuilder();
|
StringBuilder uptimeStringBuilder = new StringBuilder();
|
||||||
if(days == 0)
|
if(days == 0)
|
||||||
@ -47,4 +67,81 @@ public class FormatUtil
|
|||||||
|
|
||||||
return uptimeStringBuilder.toString();
|
return uptimeStringBuilder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to parse a string into a duration.
|
||||||
|
* Warning: this only supports up to days; months and longer timeframes are unsupported.
|
||||||
|
*
|
||||||
|
* @param duration the String to parse.
|
||||||
|
* @return a Duration of the parsed timeframe, or null if parsing failed.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public static Duration parseDuration(String duration)
|
||||||
|
{
|
||||||
|
// sanitize a bit to avoid cluttering with garbled strings
|
||||||
|
if(duration.length() > 16) duration = duration.substring(0, 16);
|
||||||
|
duration = duration.replaceAll("[^\\w]", ""); //only keep digits and word characters
|
||||||
|
duration = duration.toLowerCase();
|
||||||
|
|
||||||
|
/* the following regex matches any number followed by any amount of characters, any amount of times.
|
||||||
|
eg: 3d, 33hours, 32048dojg, 3d2h5m22s.
|
||||||
|
it does not match if the [digits and characters] blocks are missing.
|
||||||
|
eg: 33, asd, 3g5hj, 4 asd.
|
||||||
|
*/
|
||||||
|
if(!duration.matches("(\\d+[a-zA-Z]+)+"))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
String[] durationTimes = duration.split("[a-zA-Z]+");
|
||||||
|
String[] durationUnits = duration.split("\\d+");
|
||||||
|
|
||||||
|
// remove first element, because it will always be empty (there's nothing before the first character)
|
||||||
|
durationUnits = Arrays.copyOfRange(durationUnits, 1, durationUnits.length);
|
||||||
|
|
||||||
|
Duration fullDuration = Duration.ZERO;
|
||||||
|
|
||||||
|
for(int i = 0; i < durationTimes.length; i++)
|
||||||
|
{
|
||||||
|
String durationTimeStr = durationTimes[i];
|
||||||
|
String durationUnitStr = durationUnits[i];
|
||||||
|
|
||||||
|
int durationValue = Integer.parseInt(durationTimeStr);
|
||||||
|
TemporalUnit unit = parseTimeUnit(durationUnitStr);
|
||||||
|
|
||||||
|
if(unit != null)
|
||||||
|
fullDuration = fullDuration.plus(durationValue, unit);
|
||||||
|
else return null; // if we failed finding the time unit, instantly quit with failed parsing.
|
||||||
|
}
|
||||||
|
|
||||||
|
return fullDuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private static TemporalUnit parseTimeUnit(@NotNull String unitName)
|
||||||
|
{
|
||||||
|
// we won't do any sanitization, because this is a private method, and
|
||||||
|
// we are only accessing it with things that we know for sure are already sanitized.
|
||||||
|
unitName = unitName.toLowerCase();
|
||||||
|
TemporalUnit timeUnit = null;
|
||||||
|
|
||||||
|
/*
|
||||||
|
parsing table
|
||||||
|
s, se, sec, second, seconds -> SECOND
|
||||||
|
m, mi, min, minute, minutes -> MINUTE
|
||||||
|
h, ho, hr, hour, hours -> HOUR
|
||||||
|
d, day, days -> DAY
|
||||||
|
|
||||||
|
(months and longer timeframes are unsupported due to Discord restrictions)
|
||||||
|
*/
|
||||||
|
|
||||||
|
switch (unitName)
|
||||||
|
{
|
||||||
|
case "s", "se", "sec", "second", "seconds" -> timeUnit = ChronoUnit.SECONDS;
|
||||||
|
case "m", "mi", "min", "minute", "minutes" -> timeUnit = ChronoUnit.MINUTES;
|
||||||
|
case "h", "ho", "hr", "hour", "hours" -> timeUnit = ChronoUnit.HOURS;
|
||||||
|
case "d", "day", "days" -> timeUnit = ChronoUnit.DAYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return timeUnit;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user