Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 42 additions & 19 deletions sdk/src/main/java/io/dapr/utils/DurationUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,32 +26,56 @@ public class DurationUtils {
public static Duration convertDurationFromDaprFormat(String valueString) {
// Convert the format returned by the Dapr runtime into Duration
// An example of the format is: 4h15m50s60ms. It does not include days.
if (valueString == null) {
throw new IllegalArgumentException("duration string cannot be null");
}
Duration parsedDuration = Duration.ZERO;
int hourIndex = valueString.indexOf('h');
// Get first occurrence of "m"
int minuteIndex = valueString.indexOf('m');
// Check if that is not "ms"
if (minuteIndex != -1 && valueString.length() > minuteIndex + 1 && valueString.charAt(minuteIndex + 1) == 's') {
// condition satisfied when "m" is part of the string "ms"
minuteIndex = -1;
}
// Get first occurrence of "s"
int secondIndex = valueString.indexOf('s');
int milliIndex = valueString.indexOf("ms");
if (secondIndex != -1 && valueString.charAt(secondIndex - 1) == 'm') {
// condition satisfied when "s" is part of the string "ms"
secondIndex = -1;
}
// Declaring it final to skip checkstyle issues
final int milliIndex = valueString.indexOf("ms");

String hoursSpan = valueString.substring(0, hourIndex);
if (hourIndex != -1) {
String hoursSpan = valueString.substring(0, hourIndex);

int hours = Integer.parseInt(hoursSpan);
int days = hours / 24;
hours = hours % 24;
int hours = Integer.parseInt(hoursSpan);
int days = hours / 24;
hours = hours % 24;
parsedDuration = parsedDuration.plusDays(days)
.plusHours(hours);
}

String minutesSpan = valueString.substring(hourIndex + 1, minuteIndex);
int minutes = Integer.parseInt(minutesSpan);
if (minuteIndex != -1) {
String minutesSpan = valueString.substring(hourIndex + 1, minuteIndex);
int minutes = Integer.parseInt(minutesSpan);
parsedDuration = parsedDuration.plusMinutes(minutes);
}

String secondsSpan = valueString.substring(minuteIndex + 1, secondIndex);
int seconds = Integer.parseInt(secondsSpan);
if (secondIndex != -1) {
String secondsSpan = valueString.substring(minuteIndex + 1, secondIndex);
int seconds = Integer.parseInt(secondsSpan);
parsedDuration = parsedDuration.plusSeconds(seconds);
}

String millisecondsSpan = valueString.substring(secondIndex + 1, milliIndex);
int milliseconds = Integer.parseInt(millisecondsSpan);
if (milliIndex != -1) {
String millisecondsSpan = valueString.substring(secondIndex + 1, milliIndex);
int milliseconds = Integer.parseInt(millisecondsSpan);
parsedDuration = parsedDuration.plusMillis(milliseconds);
}

return Duration.ZERO
.plusDays(days)
.plusHours(hours)
.plusMinutes(minutes)
.plusSeconds(seconds)
.plusMillis(milliseconds);
return parsedDuration;
}

/**
Expand All @@ -65,8 +89,7 @@ public static String convertDurationToDaprFormat(Duration value) {

// return empty string for anything negative, it'll only happen for reminder "periods", not dueTimes. A
// negative "period" means fire once only.
if (value == Duration.ZERO
|| (value.compareTo(Duration.ZERO) == 1)) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

compareTo can produce any value greater than 1, by contract any positive value means the value is greater. This failed the test when only milliseconds were given ...

if (value == Duration.ZERO || (value.compareTo(Duration.ZERO) > 0)) {
long hours = getDaysPart(value) * 24 + getHoursPart(value);

StringBuilder sb = new StringBuilder();
Expand Down
70 changes: 70 additions & 0 deletions sdk/src/test/java/io/dapr/utils/DurationUtilsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,76 @@ public void convertTimeBothWays() {
Assert.assertEquals(s, t);
}

@Test
public void testParsePartialDurationMillis(){
String s = "0h0m0s101ms";
String partial = "101ms";
Duration d1 = DurationUtils.convertDurationFromDaprFormat(partial);

String t = DurationUtils.convertDurationToDaprFormat(d1);
Assert.assertEquals(s, t);
}

@Test
public void testParsePartialDurationSeconds(){
String s = "0h0m42s0ms";
String partial = "42s";
Duration d1 = DurationUtils.convertDurationFromDaprFormat(partial);

String t = DurationUtils.convertDurationToDaprFormat(d1);
Assert.assertEquals(s, t);
}

@Test
public void testParsePartialDurationMinutes(){
String s = "0h29m0s0ms";
String partial = "29m";
Duration d1 = DurationUtils.convertDurationFromDaprFormat(partial);

String t = DurationUtils.convertDurationToDaprFormat(d1);
Assert.assertEquals(s, t);
}

@Test
public void testParsePartialDurationHours(){
String s = "17h0m0s0ms";
String partial = "17h";
Duration d1 = DurationUtils.convertDurationFromDaprFormat(partial);

String t = DurationUtils.convertDurationToDaprFormat(d1);
Assert.assertEquals(s, t);
}

@Test
public void testZeroDurationString(){
String s = "0h0m0s0ms";
String partial = "0";
Duration d1 = DurationUtils.convertDurationFromDaprFormat(partial);

String t = DurationUtils.convertDurationToDaprFormat(d1);
Assert.assertEquals(s, t);
}

@Test
public void testZeroDuration(){
String s = "0h0m0s0ms";
String t = DurationUtils.convertDurationToDaprFormat(Duration.ZERO);
Assert.assertEquals(s, t);
}

@Test
public void testNullString() {
Assert.assertThrows(IllegalArgumentException.class, () ->{
DurationUtils.convertDurationFromDaprFormat(null);
});
}

@Test
public void testEmptyString() {
Duration d = DurationUtils.convertDurationFromDaprFormat("");
Assert.assertEquals(Duration.ZERO, d);
}

@Test
public void largeHours() {
// hours part is larger than 24
Expand Down