From 58365cda6a9ce3ac2c6cd85335bf1d8a52c8a42e Mon Sep 17 00:00:00 2001 From: Leon Mai Date: Mon, 16 Dec 2019 15:18:50 -0800 Subject: [PATCH] Add ConverterUtils class (#49) * Add ConverterUtils + unit test --- .../dapr/actors/runtime/ConverterUtils.java | 136 ++++++++++++++++++ .../actors/runtime/ConverterUtilsTest.java | 101 +++++++++++++ 2 files changed, 237 insertions(+) create mode 100644 sdk/src/main/java/io/dapr/actors/runtime/ConverterUtils.java create mode 100644 sdk/src/test/java/io/dapr/actors/runtime/ConverterUtilsTest.java diff --git a/sdk/src/main/java/io/dapr/actors/runtime/ConverterUtils.java b/sdk/src/main/java/io/dapr/actors/runtime/ConverterUtils.java new file mode 100644 index 000000000..0b666c51e --- /dev/null +++ b/sdk/src/main/java/io/dapr/actors/runtime/ConverterUtils.java @@ -0,0 +1,136 @@ +// ------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// ------------------------------------------------------------ + +package io.dapr.actors.runtime; + +import java.time.*; + +public class ConverterUtils { + + /** + * Converts time from the String format used by Dapr into a Duration. + * @param valueString A String representing time in the Dapr runtime's format (e.g. 4h15m50s60ms). + * @return A Duration + */ + 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. + int hIndex = valueString.indexOf('h'); + int mIndex = valueString.indexOf('m'); + int sIndex = valueString.indexOf('s'); + int msIndex = valueString.indexOf("ms"); + + String hoursSpan = valueString.substring(0, hIndex); + + int hours = Integer.parseInt(hoursSpan); + int days = hours / 24; + hours = hours % 24; + + String minutesSpan = valueString.substring(hIndex + 1, mIndex); + int minutes = Integer.parseInt(minutesSpan); + + String secondsSpan = valueString.substring(mIndex + 1, sIndex); + int seconds = Integer.parseInt(secondsSpan); + + String millisecondsSpan = valueString.substring(sIndex + 1, msIndex); + int milliseconds = Integer.parseInt(millisecondsSpan); + + return Duration.ZERO + .plusDays(days) + .plusHours(hours) + .plusMinutes(minutes) + .plusSeconds(seconds) + .plusMillis(milliseconds); + } + + /** + * Converts a Duration to the format used by the Dapr runtime. + * @param value Duration + * @return The Duration formatted as a String in the format the Dapr runtime uses (e.g. 4h15m50s60ms) + */ + public static String ConvertDurationToDaprFormat(Duration value) { + String stringValue = ""; + + // 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)) + { + long hours = getDaysPart(value) * 24 + getHoursPart(value); + + StringBuilder sb = new StringBuilder(); + + sb.append(hours); + sb.append("h"); + + sb.append(getMinutesPart((value))); + sb.append("m"); + + sb.append(getSecondsPart((value))); + sb.append("s"); + + sb.append(getMilliSecondsPart((value))); + sb.append("ms"); + + return sb.toString(); + } + + return stringValue; + } + + /** + * Helper to get the "days" part of the Duration. For example if the duration is 26 hours, this returns 1. + * @param d + * @return + */ + static long getDaysPart(Duration d) { + long t = d.getSeconds() / 60 / 60 / 24; + return t; + } + + /** + * Helper to get the "hours" part of the Duration. For example if the duration is 26 hours, this is 1 day, 2 hours, so this returns 2. + * @param The duration to parse + * @return the hour part of the duration + */ + static long getHoursPart(Duration d) { + long u = (d.getSeconds() / 60 / 60) % 24; + + return u; + } + + /** + * Helper to get the "minutes" part of the Duration. + * @param The duration to parse + * @return the minutes part of the duration + */ + static long getMinutesPart(Duration d) { + long u = (d.getSeconds() / 60) % 60; + + return u; + } + + /** + * Helper to get the "seconds" part of the Duration. + * @param The duration to parse + * @return the seconds part of the duration + */ + static long getSecondsPart(Duration d) { + long u = d.getSeconds() % 60; + + return u; + } + + /** + * Helper to get the "millis" part of the Duration. + * @param The duration to parse + * @return the milliseconds part of the duration + */ + static long getMilliSecondsPart(Duration d) { + long u = d.toMillis() % 1000; + + return u; + } +} diff --git a/sdk/src/test/java/io/dapr/actors/runtime/ConverterUtilsTest.java b/sdk/src/test/java/io/dapr/actors/runtime/ConverterUtilsTest.java new file mode 100644 index 000000000..dd7e850ae --- /dev/null +++ b/sdk/src/test/java/io/dapr/actors/runtime/ConverterUtilsTest.java @@ -0,0 +1,101 @@ +package io.dapr.actors.runtime; + +import org.junit.Assert; +import org.junit.Test; + +import java.time.Duration; + +public class ConverterUtilsTest { + + @Test + public void convertTimeBothWays() { + String s = "4h15m50s60ms"; + Duration d1 = ConverterUtils.ConvertDurationFromDaprFormat(s); + + String t = ConverterUtils.ConvertDurationToDaprFormat(d1); + Assert.assertEquals(s, t); + } + + @Test + public void largeHours() { + // hours part is larger than 24 + String s = "31h15m50s60ms"; + Duration d1 = ConverterUtils.ConvertDurationFromDaprFormat(s); + + String t = ConverterUtils.ConvertDurationToDaprFormat(d1); + Assert.assertEquals(s, t); + } + + @Test + public void negativeDuration() { + Duration d = Duration.ofSeconds(-99); + String t = ConverterUtils.ConvertDurationToDaprFormat(d); + Assert.assertEquals("", t); + } + + @Test + public void testGetHoursPart() { + Duration d1 = Duration.ZERO.plusHours(26); + Assert.assertEquals(2, ConverterUtils.getHoursPart(d1)); + + Duration d2 = Duration.ZERO.plusHours(23); + Assert.assertEquals(23, ConverterUtils.getHoursPart(d2)); + + Duration d3 = Duration.ZERO.plusHours(24); + Assert.assertEquals(0, ConverterUtils.getHoursPart(d3)); + } + + @Test + public void testGetMinutesPart() { + Duration d1 = Duration.ZERO.plusMinutes(61); + Assert.assertEquals(1, ConverterUtils.getMinutesPart(d1)); + + Duration d2 = Duration.ZERO.plusMinutes(60); + Assert.assertEquals(0, ConverterUtils.getMinutesPart(d2)); + + Duration d3 = Duration.ZERO.plusMinutes(59); + Assert.assertEquals(59, ConverterUtils.getMinutesPart(d3)); + + Duration d4 = Duration.ZERO.plusMinutes(3600); + Assert.assertEquals(0, ConverterUtils.getMinutesPart(d4)); + } + + @Test + public void testGetSecondsPart() { + Duration d1 = Duration.ZERO.plusSeconds(61); + Assert.assertEquals(1, ConverterUtils.getSecondsPart(d1)); + + Duration d2 = Duration.ZERO.plusSeconds(60); + Assert.assertEquals(0, ConverterUtils.getSecondsPart(d2)); + + Duration d3 = Duration.ZERO.plusSeconds(59); + Assert.assertEquals(59, ConverterUtils.getSecondsPart(d3)); + + Duration d4 = Duration.ZERO.plusSeconds(3600); + Assert.assertEquals(0, ConverterUtils.getSecondsPart(d4)); + } + + @Test + public void testGetMillisecondsPart() { + Duration d1 = Duration.ZERO.plusMillis(61); + Assert.assertEquals(61, ConverterUtils.getMilliSecondsPart(d1)); + + Duration d2 = Duration.ZERO.plusMillis(60); + Assert.assertEquals(60, ConverterUtils.getMilliSecondsPart(d2)); + + Duration d3 = Duration.ZERO.plusMillis(59); + Assert.assertEquals(59, ConverterUtils.getMilliSecondsPart(d3)); + + Duration d4 = Duration.ZERO.plusMillis(999); + Assert.assertEquals(999, ConverterUtils.getMilliSecondsPart(d4)); + + Duration d5 = Duration.ZERO.plusMillis(1001); + Assert.assertEquals(1, ConverterUtils.getMilliSecondsPart(d5)); + + Duration d6 = Duration.ZERO.plusMillis(1000); + Assert.assertEquals(0, ConverterUtils.getMilliSecondsPart(d6)); + + Duration d7 = Duration.ZERO.plusMillis(10000); + Assert.assertEquals(0, ConverterUtils.getMilliSecondsPart(d7)); + } +}