Skip to content

Commit

Permalink
Add possibility to parse days and milliseconds with config DurationCo…
Browse files Browse the repository at this point in the history
…nverter
  • Loading branch information
manofthepeace committed May 16, 2023
1 parent f7af2e5 commit a6f898b
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,18 @@
@Priority(DEFAULT_QUARKUS_CONVERTER_PRIORITY)
public class DurationConverter implements Converter<Duration>, Serializable {
private static final long serialVersionUID = 7499347081928776532L;
private static final String PERIOD = "P";
private static final String PERIOD_OF_TIME = "PT";
private static final Pattern DIGITS = Pattern.compile("^[-+]?\\d+$");
private static final Pattern START_WITH_DIGITS = Pattern.compile("^[-+]?\\d+.*");
private static final Pattern DIGITS_AND_UNIT = Pattern.compile("^[-+]?\\d+(?:\\.\\d+)?(?i)[hms]$");
private static final Pattern DAYS = Pattern.compile("^[-+]?\\d+(?i)d$");
private static final Pattern MILLIS = Pattern.compile("^[-+]?\\d+(?i)ms$");

public DurationConverter() {
}

/**
* The converter accepts a value which start with a number by implicitly appending `PT` to it.
* The converter accepts a value which start with a number by implicitly appending `PT` to it or `P` for days.
* If the value consists only of a number, it implicitly treats the value as seconds.
* Otherwise, tries to convert the value assuming that it is in the accepted ISO-8601 duration format.
*
Expand All @@ -38,7 +41,7 @@ public Duration convert(String value) {
}

/**
* Converts a value which start with a number by implicitly appending `PT` to it.
* Converts a value which start with a number by implicitly appending `PT` to it or `P` for days.
* If the value consists only of a number, it implicitly treats the value as seconds.
* Otherwise, tries to convert the value assuming that it is in the accepted ISO-8601 duration format.
*
Expand All @@ -52,11 +55,15 @@ public static Duration parseDuration(String value) {
}
if (DIGITS.asPredicate().test(value)) {
return Duration.ofSeconds(Long.parseLong(value));
} else if (MILLIS.asPredicate().test(value)) {
return Duration.ofMillis(Long.parseLong(value.substring(0, value.length() - 2)));
}

try {
if (START_WITH_DIGITS.asPredicate().test(value)) {
if (DIGITS_AND_UNIT.asPredicate().test(value)) {
return Duration.parse(PERIOD_OF_TIME + value);
} else if (DAYS.asPredicate().test(value)) {
return Duration.parse(PERIOD + value);
}

return Duration.parse(value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,25 @@ public void testValueInCorrectFormatProvided() {
public void testValueNotInCorrectFormatProvided() {
assertThrows(IllegalArgumentException.class, () -> durationConverter.convert("PT"));
}

@Test
public void testValueIsInDays() {
Duration expectedDuration = Duration.ofDays(3);
Duration actualDuration = durationConverter.convert("3d");
assertEquals(expectedDuration, actualDuration);
}

@Test
public void testValueIsInMillis() {
Duration expectedDuration = Duration.ofMillis(25);
Duration actualDuration = durationConverter.convert("25ms");
assertEquals(expectedDuration, actualDuration);
}

@Test
public void testValueIsInSec() {
Duration expectedDuration = Duration.ofSeconds(2);
Duration actualDuration = durationConverter.convert("2s");
assertEquals(expectedDuration, actualDuration);
}
}
3 changes: 2 additions & 1 deletion docs/src/main/asciidoc/_includes/duration-format-note.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ You can learn more about it in the link:https://docs.oracle.com/javase/8/docs/ap
You can also provide duration values starting with a number.
In this case, if the value consists only of a number, the converter treats the value as seconds.
Otherwise, `PT` is implicitly prepended to the value to obtain a standard `java.time.Duration` format.
Otherwise, `PT` for seconds, minute and hours or `P` for days are implicitly prepended to the value to obtain a standard `java.time.Duration` format.
Milliseconds are also supported by implicitly using `Duration.ofMillis()`
====

0 comments on commit a6f898b

Please sign in to comment.