Commit 32b31ca0 authored by Greg Messner's avatar Greg Messner
Browse files

Initial check-in.

parent 978c6380
package org.gitlab4j.api.models;
import org.gitlab4j.api.utils.DurationUtils;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
/**
* This class represents a duration in time.
*/
public class Duration {
private int seconds;
private String durationString;
/**
* Create a Duration instance from a human readable string. e.g: 3h30m
*
* @param durationString a duration in human readable format
*/
public Duration(String durationString) {
seconds = DurationUtils.parse(durationString);
this.durationString = (seconds == 0 ? "0m" : DurationUtils.toString(seconds));
}
/**
* Create a Duration instance from a number of seconds.
*
* @param seconds the number of seconds for this Duration instance to represent
*/
public Duration(int seconds) {
this.seconds = seconds;
durationString = (seconds == 0 ? "0m" : DurationUtils.toString(seconds));
}
/**
* Get the number of seconds this duration represents.
*
* @return the number of seconds this duration represents
*/
public int getSeconds() {
return (seconds);
}
/**
* Set the number of seconds this duration represents.
*
* @param seconds the number of seconds this duration represents
*/
public void setSeconds(int seconds) {
this.seconds = seconds;
}
@JsonValue
@Override
public String toString() {
return (durationString);
}
@JsonCreator
public static Duration forValue(String value) {
return new Duration(value);
}
}
package org.gitlab4j.api.utils;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class DurationUtils {
private static char[] TIME_UNITS = { 'd', 'h', 'm', 's'};
private static int[] TIME_UNIT_MULTIPLIERS = { 60 * 60 * 24, 60 * 60, 60, 1 };
private static Pattern durationPattern = Pattern.compile("(\\s*(\\d+)([a-z]))");
/**
* Create a human readable duration string from seconds.
*
* @param durationSeconds the total number of seconds in the duration
* @return a human readable string representing the duration
*/
public static final String toString(int durationSeconds) {
int days = durationSeconds / TIME_UNIT_MULTIPLIERS[0];
int seconds = durationSeconds - (days * TIME_UNIT_MULTIPLIERS[0]);
int hours = seconds / 3600;
int minutes = (seconds % 3600) / 60;
seconds = seconds % 60;
StringBuilder buf = new StringBuilder();
if (days > 0) {
buf.append(days).append('d');
if (seconds > 0) {
buf.append(hours).append('h').append(minutes).append('m').append(seconds).append('s');
} else if (minutes > 0) {
buf.append(hours).append('h').append(minutes).append('m');
} else if (hours > 0) {
buf.append(hours).append('h');
}
} else if (hours > 0) {
buf.append(hours).append('h');
if (seconds > 0) {
buf.append(minutes).append('m').append(seconds).append('s');
} else if (minutes > 0) {
buf.append(minutes).append('m');
}
} else if (minutes > 0) {
buf.append(minutes).append('m');
if (seconds > 0) {
buf.append(seconds).append('s');
}
} else {
buf.append(' ').append(seconds).append('s');
}
return (buf.toString());
}
/**
* Parses a human readable duration string and calculates the number of seconds it represents.
*
* @param durationString the human readable duration
* @return the total number of seconds in the duration
*/
public static final int parse(String durationString) {
durationString = durationString.toLowerCase();
Matcher matcher = durationPattern.matcher(durationString);
int currentUnitIndex = -1;
int seconds = 0;
Boolean validDuration = null;
while (matcher.find() && validDuration != Boolean.FALSE) {
validDuration = true;
int numGroups = matcher.groupCount();
if (numGroups == 3) {
char unit = matcher.group(3).charAt(0);
int nextUnitIndex = getUnitIndex(unit);
if (nextUnitIndex > currentUnitIndex) {
currentUnitIndex = nextUnitIndex;
try {
seconds += Long.parseLong(matcher.group(2)) * TIME_UNIT_MULTIPLIERS[nextUnitIndex];
} catch (NumberFormatException nfe) {
validDuration = false;
}
} else {
validDuration = false;
}
} else {
validDuration = false;
}
}
if (validDuration != Boolean.TRUE) {
throw new IllegalArgumentException(String.format("'%s' is not a valid duration", durationString));
}
return (seconds);
}
private static final int getUnitIndex(char unit) {
for (int i = 0; i < TIME_UNITS.length; i++) {
if (unit == TIME_UNITS[i])
return (i);
}
return (-1);
}
}
package org.gitlab4j.api;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import org.gitlab4j.api.utils.DurationUtils;
import org.junit.Test;
public class TestDuration {
@Test
public void testParse() {
int seconds = DurationUtils.parse("1d1h1m1s");
assertEquals(60 * 60 * 24 + 60 * 60 + 60 + 1, seconds);
seconds = DurationUtils.parse("60m");
assertEquals(60 * 60, seconds);
seconds = DurationUtils.parse("1h");
assertEquals(60 * 60, seconds);
}
@Test
public void testBadParse() {
try {
DurationUtils.parse("1m1h");
fail("Should have received an exception for the bad duration");
} catch (IllegalArgumentException iae) {
System.out.println("Recieved expected exception: " + iae.getMessage());
}
try {
DurationUtils.parse("1z");
fail("Should have received an exception for the bad duration");
} catch (IllegalArgumentException iae) {
System.out.println("Recieved expected exception: " + iae.getMessage());
}
try {
DurationUtils.parse("2d2h2s2m");
fail("Should have received an exception for the bad duration");
} catch (IllegalArgumentException iae) {
System.out.println("Recieved expected exception: " + iae.getMessage());
}
try {
DurationUtils.parse("2d2h2m2m");
fail("Should have received an exception for the bad duration");
} catch (IllegalArgumentException iae) {
System.out.println("Recieved expected exception: " + iae.getMessage());
}
}
@Test
public void testToString() {
String duration = DurationUtils.toString(60 + 1);
assertEquals("1m1s", duration);
duration = DurationUtils.toString(60 * 60 + 60 + 1);
assertEquals("1h1m1s", duration);
duration = DurationUtils.toString(60 * 60 * 24 + 60 * 60 * 2 + 60 * 3 + 4);
assertEquals("1d2h3m4s", duration);
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment