package pluginbase.util.time;
import org.jetbrains.annotations.NotNull;
import java.text.ParseException;
/**
* Several utility methods for converting amounts of times from seconds to human readable string representations
* and back.
* <p/>
* It is recommended that you generally use {@link Duration} for these purposes however.
*/
public class TimeTools {
private TimeTools() {
throw new AssertionError();
}
/**
* Returns the amount of time the given amount of seconds represents as a short, concise human-readable String.
* <p/>
* Example: {@code 5d 1h 15m 32s}
*
* @param second the amount of seconds to stringify.
* @return the amount of time the given amount of seconds represents as a short, concise human-readable String.
*/
@NotNull
public static String toShortForm(long second) {
if (second == 0) {
return "0s";
}
long minute = second / 60;
second = second % 60;
long hour = minute / 60;
minute = minute % 60;
long day = hour / 24;
hour = hour % 24;
StringBuilder time = new StringBuilder();
if (day != 0) {
time.append(day).append("d ");
}
if (hour != 0) {
time.append(hour).append("h ");
}
if (minute != 0) {
time.append(minute).append("m ");
}
if (second != 0) {
time.append(second).append("s");
}
return time.toString().trim();
}
/**
* Returns the amount of time the given amount of seconds represents as a verbose human-readable String.
* <p/>
* Example: {@code 5 days 1 hour 15 minutes 32 seconds}
*
* @param second the amount of seconds to stringify.
* @return the amount of time the given amount of seconds represents as a verbose human-readable String.
*/
@NotNull
public static String toLongForm(long second) {
if (second == 0) {
return "0 seconds";
}
long minute = second / 60;
second = second % 60;
long hour = minute / 60;
minute = minute % 60;
long day = hour / 24;
hour = hour % 24;
StringBuilder time = new StringBuilder();
if (day != 0) {
time.append(day);
}
if (day == 1) {
time.append(" day ");
} else if (day > 1) {
time.append(" days ");
}
if (hour != 0) {
time.append(hour);
}
if (hour == 1) {
time.append(" hour ");
} else if (hour > 1) {
time.append(" hours ");
}
if (minute != 0) {
time.append(minute);
}
if (minute == 1) {
time.append(" minute ");
} else if (minute > 1) {
time.append(" minutes ");
}
if (second!= 0) {
time.append(second);
}
if (second == 1) {
time.append(" second");
} else if (second > 1) {
time.append(" seconds");
}
return time.toString().trim();
}
/**
* Converts a string that represents a length of time into an amount of seconds.
* <p/>
* The string form must be:
* <p/>
* <b>Short form: </b>{@code DDd HHh MMm SSs}
* <p/>
* {@code DD} - an amount of days
* <br/>
* {@code HH} - an amount of hours
* <br/>
* {@code MM} - an amount of minutes
* <br/>
* {@code SS} - an amount of seconds
* <p/>
* Spaces in the string will not affect the parsing.
* <br/>
* In the short form, any of the time intervals may be omitted as long as one is present.
* However, the order must remain consistent as given in the examples. For instance, the minutes may not
* come before the hours in the string.
*
* @param dhms the length of time in one of the allowed string forms.
* @return an amount of seconds representing on the given length of time.
* @throws ParseException in case the string is formatted incorrectly and the time cannot be interpreted from it.
*/
public static long fromShortForm(@NotNull String dhms) throws ParseException {
long seconds = 0, minutes = 0, hours = 0, days = 0;
boolean valid = false;
if (dhms.contains("d")) {
try {
days = Integer.parseInt(dhms.split("d")[0].replaceAll(" ", ""));
valid = true;
} catch (NumberFormatException ignore) { }
if (dhms.contains("h") || dhms.contains("m") || dhms.contains("s")) {
dhms = dhms.split("d")[1];
}
}
if (dhms.contains("h")) {
try {
hours = Integer.parseInt(dhms.split("d")[0].replaceAll(" ", ""));
valid = true;
} catch (NumberFormatException ignore) { }
if (dhms.contains("m") || dhms.contains("s")) {
dhms = dhms.split("h")[1];
}
}
if (dhms.contains("m")) {
try {
minutes = Integer.parseInt(dhms.split("m")[0].replaceAll(" ", ""));
valid = true;
} catch (NumberFormatException ignore) { }
if (dhms.contains("s")) {
dhms = dhms.split("m")[1];
}
}
if (dhms.contains("s")) {
try {
seconds = Integer.parseInt(dhms.split("s")[0].replaceAll(" ", ""));
valid = true;
} catch (NumberFormatException ignore) { }
}
if (!valid) {
throw new ParseException("'" + dhms + "' is not a valid duration format!", 0);
}
return (days * 86400) + (hours * 3600) + (minutes * 60) + seconds;
}
/**
* Converts a string that represents a length of time into an amount of seconds.
* <p/>
* The string form must be:
* <p/>
* <b>Long form: </b>{@code DD day(s) HH hour(s) MM minute(s) SS second(s)}
* <p/>
* {@code DD} - an amount of days
* <br/>
* {@code HH} - an amount of hours
* <br/>
* {@code MM} - an amount of minutes
* <br/>
* {@code SS} - an amount of seconds
* <br/>
* {@code (s)} - this "s" is optional
* <p/>
* Spaces in the string will not affect the parsing.
* <br/>
* In the long form, any of the time intervals may be omitted as long as one is present.
* However, the order must remain consistent as given in the examples. For instance, the minutes may not
* come before the hours in the string.
*
* @param dhms the length of time in one of the allowed string forms.
* @return an amount of seconds representing on the given length of time.
* @throws ParseException in case the string is formatted incorrectly and the time cannot be interpreted from it.
*/
public static long fromLongForm(@NotNull String dhms) throws ParseException {
long seconds = 0, minutes = 0, hours = 0, days = 0;
boolean valid = false;
if (dhms.contains("days")) {
try {
days = Integer.parseInt(dhms.split("days")[0].replaceAll(" ", ""));
valid = true;
} catch (NumberFormatException ignore) { }
if (dhms.contains("hours") || dhms.contains("hour") || dhms.contains("minutes") || dhms.contains("seconds") || dhms.contains("minute") || dhms.contains("second")) {
dhms = dhms.split("days")[1];
}
} else if (dhms.contains("day")) {
try {
days = Integer.parseInt(dhms.split("day")[0].replaceAll(" ", ""));
valid = true;
} catch (NumberFormatException ignore) { }
if (dhms.contains("hours") || dhms.contains("hour") || dhms.contains("minutes") || dhms.contains("seconds") || dhms.contains("minute") || dhms.contains("second")) {
dhms = dhms.split("day")[1];
}
}
if (dhms.contains("hours")) {
try {
hours = Integer.parseInt(dhms.split("hours")[0].replaceAll(" ", ""));
valid = true;
} catch (NumberFormatException ignore) { }
if (dhms.contains("minutes") || dhms.contains("seconds") || dhms.contains("minute") || dhms.contains("second")) {
dhms = dhms.split("hours")[1];
}
} else if (dhms.contains("hour")) {
try {
hours = Integer.parseInt(dhms.split("hour")[0].replaceAll(" ", ""));
valid = true;
} catch (NumberFormatException ignore) { }
if (dhms.contains("minutes") || dhms.contains("seconds") || dhms.contains("minute") || dhms.contains("second")) {
dhms = dhms.split("hour")[1];
}
}
if (dhms.contains("minutes")) {
try {
minutes = Integer.parseInt(dhms.split("minutes")[0].replaceAll(" ", ""));
valid = true;
} catch (NumberFormatException ignore) { }
if (dhms.contains("seconds") || dhms.contains("second")) {
dhms = dhms.split("minutes")[1];
}
} else if (dhms.contains("minute")) {
try {
minutes = Integer.parseInt(dhms.split("minute")[0].replaceAll(" ", ""));
valid = true;
} catch (NumberFormatException ignore) { }
if (dhms.contains("seconds") || dhms.contains("second")) {
dhms = dhms.split("minute")[1];
}
}
if (dhms.contains("seconds")) {
try {
seconds = Integer.parseInt(dhms.split("seconds")[0].replaceAll(" ", ""));
valid = true;
} catch (NumberFormatException ignore) { }
} else if (dhms.contains("second")) {
try {
seconds = Integer.parseInt(dhms.split("second")[0].replaceAll(" ", ""));
valid = true;
} catch (NumberFormatException ignore) { }
}
if (!valid) {
throw new ParseException("'" + dhms + "' is not a valid duration format!", 0);
}
return (days * 86400) + (hours * 3600) + (minutes * 60) + seconds;
}
}