diff --git a/bundles/org.openhab.core.automation/src/main/java/org/openhab/core/automation/util/ActionInputsHelper.java b/bundles/org.openhab.core.automation/src/main/java/org/openhab/core/automation/util/ActionInputsHelper.java index c7949cd90..3234a0f37 100644 --- a/bundles/org.openhab.core.automation/src/main/java/org/openhab/core/automation/util/ActionInputsHelper.java +++ b/bundles/org.openhab.core.automation/src/main/java/org/openhab/core/automation/util/ActionInputsHelper.java @@ -13,8 +13,6 @@ package org.openhab.core.automation.util; import java.math.BigDecimal; -import java.text.ParseException; -import java.text.SimpleDateFormat; import java.time.Duration; import java.time.LocalDate; import java.time.LocalDateTime; @@ -24,6 +22,7 @@ import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; import java.time.temporal.TemporalAccessor; import java.util.ArrayList; +import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -293,9 +292,6 @@ public class ActionInputsHelper { // Accepted format is: 2007-12-03T10:15:30 LocalDateTime.parse(valueString); case "java.util.Date" -> - // Accepted format is: 2007-12-03T10:15:30 - new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").parse(valueString); - case "java.time.ZonedDateTime" -> { /* * Accepted format is one of: * - 2007-12-03T10:15:30 @@ -303,14 +299,8 @@ public class ActionInputsHelper { * - 2007-12-03T10:15:30+01:00 * - 2007-12-03T10:15:30+01:00[Europe/Paris] */ - TemporalAccessor dt = DateTimeFormatter.ISO_DATE_TIME.parseBest(valueString, - ZonedDateTime::from, LocalDateTime::from); - if (dt instanceof ZonedDateTime zdt) { - yield zdt; - } - yield ((LocalDateTime) dt).atZone(timeZoneProvider.getTimeZone()); - } - case "java.time.Instant" -> { + Date.from(parseAsIsoDateTime(valueString).toInstant()); + case "java.time.ZonedDateTime" -> /* * Accepted format is one of: * - 2007-12-03T10:15:30 @@ -318,13 +308,16 @@ public class ActionInputsHelper { * - 2007-12-03T10:15:30+01:00 * - 2007-12-03T10:15:30+01:00[Europe/Paris] */ - TemporalAccessor dt = DateTimeFormatter.ISO_DATE_TIME.parseBest(valueString, - ZonedDateTime::from, LocalDateTime::from); - if (dt instanceof ZonedDateTime zdt) { - yield zdt.toInstant(); - } - yield ((LocalDateTime) dt).atZone(timeZoneProvider.getTimeZone()).toInstant(); - } + parseAsIsoDateTime(valueString); + case "java.time.Instant" -> + /* + * Accepted format is one of: + * - 2007-12-03T10:15:30 + * - 2007-12-03T09:15:30Z + * - 2007-12-03T10:15:30+01:00 + * - 2007-12-03T10:15:30+01:00[Europe/Paris] + */ + parseAsIsoDateTime(valueString).toInstant(); case "java.time.Duration" -> // Accepted format is: P2DT17H25M30.5S Duration.parse(valueString); @@ -333,7 +326,7 @@ public class ActionInputsHelper { } } return argument; - } catch (IllegalArgumentException | DateTimeParseException | ParseException e) { + } catch (IllegalArgumentException | DateTimeParseException e) { throw new IllegalArgumentException("Input parameter '" + input.getName() + "': converting value '" + argument.toString() + "' into type " + input.getType() + " failed!"); } @@ -346,4 +339,13 @@ public class ActionInputsHelper { } return unitProvider.getUnit((Class) dimension); } + + private ZonedDateTime parseAsIsoDateTime(String valueString) { + TemporalAccessor dt = DateTimeFormatter.ISO_DATE_TIME.parseBest(valueString, ZonedDateTime::from, + LocalDateTime::from); + if (dt instanceof ZonedDateTime zdt) { + return zdt; + } + return ((LocalDateTime) dt).atZone(timeZoneProvider.getTimeZone()); + } } diff --git a/bundles/org.openhab.core.automation/src/test/java/org/openhab/core/automation/util/ActionInputHelperTest.java b/bundles/org.openhab.core.automation/src/test/java/org/openhab/core/automation/util/ActionInputHelperTest.java index 9506efe2b..79ae66c96 100644 --- a/bundles/org.openhab.core.automation/src/test/java/org/openhab/core/automation/util/ActionInputHelperTest.java +++ b/bundles/org.openhab.core.automation/src/test/java/org/openhab/core/automation/util/ActionInputHelperTest.java @@ -17,8 +17,6 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.*; import java.math.BigDecimal; -import java.text.ParseException; -import java.text.SimpleDateFormat; import java.time.Duration; import java.time.Instant; import java.time.LocalDate; @@ -456,19 +454,28 @@ public class ActionInputHelperTest { @Test public void testMapSerializedInputToActionInputWhenDate() { - String valAsString = "2024-11-05T09:45:12"; - Date val; - try { - val = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").parse(valAsString); - } catch (IllegalArgumentException | ParseException e) { - val = null; - } - assertNotNull(val); + String valAsString = "2024-11-05T08:45:12Z"; + Date val = Date.from(Instant.parse(valAsString)); Input input = buildInput("java.util.Date"); assertThat(helper.mapSerializedInputToActionInput(input, val), is(val)); assertThat(helper.mapSerializedInputToActionInput(input, valAsString), is(val)); - assertThrows(IllegalArgumentException.class, - () -> helper.mapSerializedInputToActionInput(input, valAsString.replace("T", " "))); + + valAsString = "2024-11-05T09:45:12"; + val = Date.from(LocalDateTime.parse(valAsString).atZone(timeZoneProvider.getTimeZone()).toInstant()); + assertThat(helper.mapSerializedInputToActionInput(input, val), is(val)); + assertThat(helper.mapSerializedInputToActionInput(input, valAsString), is(val)); + String s1 = valAsString.replace("T", " "); + assertThrows(IllegalArgumentException.class, () -> helper.mapSerializedInputToActionInput(input, s1)); + + valAsString = "2024-11-05T09:45:12+04:00"; + val = Date.from(ZonedDateTime.parse(valAsString, DateTimeFormatter.ISO_DATE_TIME).toInstant()); + assertThat(helper.mapSerializedInputToActionInput(input, val), is(val)); + assertThat(helper.mapSerializedInputToActionInput(input, valAsString), is(val)); + + valAsString = "2024-11-05T09:45:12+04:00[Europe/Kyiv]"; + val = Date.from(ZonedDateTime.parse(valAsString, DateTimeFormatter.ISO_DATE_TIME).toInstant()); + assertThat(helper.mapSerializedInputToActionInput(input, val), is(val)); + assertThat(helper.mapSerializedInputToActionInput(input, valAsString), is(val)); } @Test