When setting issue estimates in JIRA, you can enter a string like "1d 2h 30m"
and JIRA will translate this (I'm assuming) into a corresponding number of milliseconds.
Is there an available Java library that does this?
I'm using a Spring managed bean that takes a property indicating how often a directory ought to be purged, and I'd like to allow the configuration to take a human-readable string rather than an explicit number of milliseconds.
Alternatively, if there's a better approach I'm not thinking of, I'd love to hear it.
The parser is not too complex:
public static long parse(String input) {
long result = 0;
String number = "";
for (int i = 0; i < input.length(); i++) {
char c = input.charAt(i);
if (Character.isDigit(c)) {
number += c;
} else if (Character.isLetter(c) && !number.isEmpty()) {
result += convert(Integer.parseInt(number), c);
number = "";
}
}
return result;
}
private static long convert(int value, char unit) {
switch(unit) {
case 'd' : return value * 1000*60*60*24;
case 'h' : return value * 1000*60*60;
case 'm' : return value * 1000*60;
case 's' : return value * 1000;
}
return 0;
}
The code is pretty fault tolerant, it just ignores almost anything it can't decode (and it ignores any whitspace, so it accepts "1d 1s", "1s 1d", "1d20m300s" and so on).
Here's another solution, this one's configurable:
public class TimeReader{
private final Map<String, Long> units = new HashMap<String, Long>();
private static final String UNIT_PATTERN = "\\w+";
private static final Pattern ITEM_PATTERN = Pattern.compile("(\\d+)\\s*("
+ UNIT_PATTERN + ")");
/**
* Add a new time unit.
*
* @param unit
* the unit, e.g. "s"
* @param value
* the unit's modifier value (multiplier from milliseconds, e.g.
* 1000)
* @return self reference for chaining
*/
public TimeReader addUnit(final String unit, final long value){
if(value < 0 || !unit.matches(UNIT_PATTERN)){
throw new IllegalArgumentException();
}
units.put(unit, Long.valueOf(value));
return this;
}
/**
* Parse a string using the defined units.
*
* @return the resulting number of milliseconds
*/
public long parse(final String input){
long value = 0l;
final Matcher matcher = ITEM_PATTERN.matcher(input);
while(matcher.find()){
final long modifier = Long.parseLong(matcher.group(1));
final String unit = matcher.group(2);
if(!units.containsKey(unit)){
throw new IllegalArgumentException("Unrecognized token: "
+ unit);
}
value += units.get(unit).longValue() * modifier;
}
return value;
}
}
Sample Usage:
public static void main(final String[] args){
final TimeReader timeReader =
new TimeReader()
.addUnit("h", 3600000l)
.addUnit("m", 60000l)
.addUnit("s", 1000l);
System.out.println(timeReader.parse("3h, 2m 25 s"));
}
Output:
10945000
Take a look at joda-time's PeriodConverter. I have never used this part of the joda-time library myself, but it looks like it does what you need.
In general, for date/time stuff, look at joda-time first :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With